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.
5 *
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
11
12 extern void __get_unaligned_bad_length(void);
13 extern void __put_unaligned_bad_length(void);
14
15 /*
16 * Load quad unaligned.
17 */
18 extern inline unsigned long __ldq_u(const unsigned long * __addr)
19 {
20 unsigned long __res;
21
22 __asm__("uld\t%0,%1"
23 : "=&r" (__res)
24 : "m" (*__addr));
25
26 return __res;
27 }
28
29 /*
30 * Load long unaligned.
31 */
32 extern inline unsigned long __ldl_u(const unsigned int * __addr)
33 {
34 unsigned long __res;
35
36 __asm__("ulw\t%0,%1"
37 : "=&r" (__res)
38 : "m" (*__addr));
39
40 return __res;
41 }
42
43 /*
44 * Load word unaligned.
45 */
46 extern inline unsigned long __ldw_u(const unsigned short * __addr)
47 {
48 unsigned long __res;
49
50 __asm__("ulh\t%0,%1"
51 : "=&r" (__res)
52 : "m" (*__addr));
53
54 return __res;
55 }
56
57 /*
58 * Store quad ununaligned.
59 */
60 extern inline void __stq_u(unsigned long __val, unsigned long * __addr)
61 {
62 __asm__("usd\t%1, %0"
63 : "=m" (*__addr)
64 : "r" (__val));
65 }
66
67 /*
68 * Store long ununaligned.
69 */
70 extern inline void __stl_u(unsigned long __val, unsigned int * __addr)
71 {
72 __asm__("usw\t%1, %0"
73 : "=m" (*__addr)
74 : "r" (__val));
75 }
76
77 /*
78 * Store word ununaligned.
79 */
80 extern inline void __stw_u(unsigned long __val, unsigned short * __addr)
81 {
82 __asm__("ush\t%1, %0"
83 : "=m" (*__addr)
84 : "r" (__val));
85 }
86
87 /*
88 * The main single-value unaligned transfer routines.
89 */
90 #define get_unaligned(ptr) \
91 ({ \
92 __typeof__(*(ptr)) __val; \
93 \
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; \
110 } \
111 \
112 __val; \
113 })
114
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; \
133 } \
134 } while(0)
135
136 #endif /* _ASM_UNALIGNED_H */
137
This page was automatically generated by the
LXR engine.
Visit the LXR main site for more
information.