- Linus: more PageDirty / swapcache handling
[davej-history.git] / include / asm-mips64 / unaligned.h
blob5f5ca8de3bd7c5dce7845ec6594e7231072848a3
1 /*
2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details.
6 * Copyright (C) 1996, 1999, 2000 by Ralf Baechle
7 * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
8 */
9 #ifndef _ASM_UNALIGNED_H
10 #define _ASM_UNALIGNED_H
12 extern void __get_unaligned_bad_length(void);
13 extern void __put_unaligned_bad_length(void);
16 * Load quad unaligned.
18 extern inline unsigned long __ldq_u(const unsigned long * __addr)
20 unsigned long __res;
22 __asm__("uld\t%0,%1"
23 : "=&r" (__res)
24 : "m" (*__addr));
26 return __res;
30 * Load long unaligned.
32 extern inline unsigned long __ldl_u(const unsigned int * __addr)
34 unsigned long __res;
36 __asm__("ulw\t%0,%1"
37 : "=&r" (__res)
38 : "m" (*__addr));
40 return __res;
44 * Load word unaligned.
46 extern inline unsigned long __ldw_u(const unsigned short * __addr)
48 unsigned long __res;
50 __asm__("ulh\t%0,%1"
51 : "=&r" (__res)
52 : "m" (*__addr));
54 return __res;
58 * Store quad ununaligned.
60 extern inline void __stq_u(unsigned long __val, unsigned long * __addr)
62 __asm__("usd\t%1, %0"
63 : "=m" (*__addr)
64 : "r" (__val));
68 * Store long ununaligned.
70 extern inline void __stl_u(unsigned long __val, unsigned int * __addr)
72 __asm__("usw\t%1, %0"
73 : "=m" (*__addr)
74 : "r" (__val));
78 * Store word ununaligned.
80 extern inline void __stw_u(unsigned long __val, unsigned short * __addr)
82 __asm__("ush\t%1, %0"
83 : "=m" (*__addr)
84 : "r" (__val));
87 /*
88 * The main single-value unaligned transfer routines.
90 #define get_unaligned(ptr) \
91 ({ \
92 __typeof__(*(ptr)) __val; \
94 switch (sizeof(*(ptr))) { \
95 case 1: \
96 __val = *(const unsigned char *)(ptr); \
97 break; \
98 case 2: \
99 __val = __ldw_u((const unsigned short *)(ptr)); \
100 break; \
101 case 4: \
102 __val = __ldl_u((const unsigned int *)(ptr)); \
103 break; \
104 case 8: \
105 __val = __ldq_u((const unsigned long long *)(ptr)); \
106 break; \
107 default: \
108 __get_unaligned_bad_length(); \
109 break; \
112 __val; \
115 #define put_unaligned(val,ptr) \
116 do { \
117 switch (sizeof(*(ptr))) { \
118 case 1: \
119 *(unsigned char *)(ptr) = (val); \
120 break; \
121 case 2: \
122 __stw_u((val), (unsigned short *)(ptr)); \
123 break; \
124 case 4: \
125 __stl_u((val), (unsigned int *)(ptr)); \
126 break; \
127 case 8: \
128 __stq_u((val), (unsigned long long *)(ptr)); \
129 break; \
130 default: \
131 __put_unaligned_bad_length(); \
132 break; \
134 } while(0)
136 #endif /* _ASM_UNALIGNED_H */