patch-2.1.73 linux/include/asm-mips/unaligned.h

Next file: linux/include/asm-mips/usioctl.h
Previous file: linux/include/asm-mips/uaccess.h
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.1.72/linux/include/asm-mips/unaligned.h linux/include/asm-mips/unaligned.h
@@ -15,7 +15,7 @@
 /*
  * Load quad unaligned.
  */
-extern __inline__ unsigned long ldq_u(unsigned long long * __addr)
+extern __inline__ unsigned long ldq_u(const unsigned long long * __addr)
 {
 	unsigned long long __res;
 
@@ -29,7 +29,7 @@
 /*
  * Load long unaligned.
  */
-extern __inline__ unsigned long ldl_u(unsigned int * __addr)
+extern __inline__ unsigned long ldl_u(const unsigned int * __addr)
 {
 	unsigned long __res;
 
@@ -43,7 +43,7 @@
 /*
  * Load word unaligned.
  */
-extern __inline__ unsigned long ldw_u(unsigned short * __addr)
+extern __inline__ unsigned long ldw_u(const unsigned short * __addr)
 {
 	unsigned long __res;
 
@@ -90,12 +90,50 @@
 		 "r" (__addr));
 }
 
-#define get_unaligned(ptr) \
-  ({ __typeof__(*(ptr)) __tmp; memcpy(&__tmp, (ptr), sizeof(*(ptr))); __tmp; })
+extern inline unsigned long __get_unaligned(const void *ptr, size_t size)
+{
+	unsigned long val;
+	switch (size) {
+	      case 1:
+		val = *(const unsigned char *)ptr;
+		break;
+	      case 2:
+		val = ldw_u((const unsigned short *)ptr);
+		break;
+	      case 4:
+		val = ldl_u((const unsigned int *)ptr);
+		break;
+	      case 8:
+		val = ldq_u((const unsigned long long *)ptr);
+		break;
+	}
+	return val;
+}
+
+extern inline void __put_unaligned(unsigned long val, void *ptr, size_t size)
+{
+	switch (size) {
+	      case 1:
+		*(unsigned char *)ptr = (val);
+	        break;
+	      case 2:
+		stw_u(val, (unsigned short *)ptr);
+		break;
+	      case 4:
+		stl_u(val, (unsigned int *)ptr);
+		break;
+	      case 8:
+		stq_u(val, (unsigned long long *)ptr);
+		break;
+	}
+}
 
-#define put_unaligned(val, ptr)				\
-  ({ __typeof__(*(ptr)) __tmp = (val);			\
-     memcpy((ptr), &__tmp, sizeof(*(ptr)));		\
-     (void)0; })
+/* 
+ * The main single-value unaligned transfer routines.
+ */
+#define get_unaligned(ptr) \
+	((__typeof__(*(ptr)))__get_unaligned((ptr), sizeof(*(ptr))))
+#define put_unaligned(x,ptr) \
+	__put_unaligned((unsigned long)(x), (ptr), sizeof(*(ptr)))
 
 #endif /* __ASM_MIPS_UNALIGNED_H */

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov