1 #ifndef __ALPHA_UNALIGNED_H
2 #define __ALPHA_UNALIGNED_H
5 * The main single-value unaligned transfer routines.
7 #define get_unaligned(ptr) \
8 ((__typeof__(*(ptr)))__get_unaligned((ptr), sizeof(*(ptr))))
9 #define put_unaligned(x,ptr) \
10 __put_unaligned((unsigned long)(x), (ptr), sizeof(*(ptr)))
13 * This is a silly but good way to make sure that
14 * the get/put functions are indeed always optimized,
15 * and that we use the correct sizes.
17 extern void bad_unaligned_access_length(void);
20 * EGCS 1.1 knows about arbitrary unaligned loads. Define some
21 * packed structures to talk about such things with.
24 struct __una_u64
{ __u64 x
__attribute__((packed
)); };
25 struct __una_u32
{ __u32 x
__attribute__((packed
)); };
26 struct __una_u16
{ __u16 x
__attribute__((packed
)); };
29 * Elemental unaligned loads
32 extern inline unsigned long __uldq(const unsigned long * r11
)
34 #if __GNUC__ > 2 || __GNUC_MINOR__ >= 91
35 const struct __una_u64
*ptr
= (const struct __una_u64
*) r11
;
39 __asm__("ldq_u %0,%3\n\t"
43 :"=&r" (r1
), "=&r" (r2
)
46 "m" (*(const unsigned long *)(7+(char *) r11
)));
51 extern inline unsigned long __uldl(const unsigned int * r11
)
53 #if __GNUC__ > 2 || __GNUC_MINOR__ >= 91
54 const struct __una_u32
*ptr
= (const struct __una_u32
*) r11
;
58 __asm__("ldq_u %0,%3\n\t"
62 :"=&r" (r1
), "=&r" (r2
)
65 "m" (*(const unsigned long *)(3+(char *) r11
)));
70 extern inline unsigned long __uldw(const unsigned short * r11
)
72 #if __GNUC__ > 2 || __GNUC_MINOR__ >= 91
73 const struct __una_u16
*ptr
= (const struct __una_u16
*) r11
;
77 __asm__("ldq_u %0,%3\n\t"
81 :"=&r" (r1
), "=&r" (r2
)
84 "m" (*(const unsigned long *)(1+(char *) r11
)));
90 * Elemental unaligned stores
93 extern inline void __ustq(unsigned long r5
, unsigned long * r11
)
95 #if __GNUC__ > 2 || __GNUC_MINOR__ >= 91
96 struct __una_u64
*ptr
= (struct __una_u64
*) r11
;
99 unsigned long r1
,r2
,r3
,r4
;
101 __asm__("ldq_u %3,%1\n\t"
112 "=m" (*(unsigned long *)(7+(char *) r11
)),
113 "=&r" (r1
), "=&r" (r2
), "=&r" (r3
), "=&r" (r4
)
114 :"r" (r5
), "r" (r11
));
118 extern inline void __ustl(unsigned long r5
, unsigned int * r11
)
120 #if __GNUC__ > 2 || __GNUC_MINOR__ >= 91
121 struct __una_u32
*ptr
= (struct __una_u32
*) r11
;
124 unsigned long r1
,r2
,r3
,r4
;
126 __asm__("ldq_u %3,%1\n\t"
137 "=m" (*(unsigned long *)(3+(char *) r11
)),
138 "=&r" (r1
), "=&r" (r2
), "=&r" (r3
), "=&r" (r4
)
139 :"r" (r5
), "r" (r11
));
143 extern inline void __ustw(unsigned long r5
, unsigned short * r11
)
145 #if __GNUC__ > 2 || __GNUC_MINOR__ >= 91
146 struct __una_u16
*ptr
= (struct __una_u16
*) r11
;
149 unsigned long r1
,r2
,r3
,r4
;
151 __asm__("ldq_u %3,%1\n\t"
162 "=m" (*(unsigned long *)(1+(char *) r11
)),
163 "=&r" (r1
), "=&r" (r2
), "=&r" (r3
), "=&r" (r4
)
164 :"r" (r5
), "r" (r11
));
168 extern inline unsigned long __get_unaligned(const void *ptr
, size_t size
)
173 val
= *(const unsigned char *)ptr
;
176 val
= __uldw((const unsigned short *)ptr
);
179 val
= __uldl((const unsigned int *)ptr
);
182 val
= __uldq((const unsigned long *)ptr
);
185 bad_unaligned_access_length();
190 extern inline void __put_unaligned(unsigned long val
, void *ptr
, size_t size
)
194 *(unsigned char *)ptr
= (val
);
197 __ustw(val
, (unsigned short *)ptr
);
200 __ustl(val
, (unsigned int *)ptr
);
203 __ustq(val
, (unsigned long *)ptr
);
206 bad_unaligned_access_length();