1 #ifndef _ASM_IA64_UNALIGNED_H
2 #define _ASM_IA64_UNALIGNED_H
3
4 /*
5 * The main single-value unaligned transfer routines. Derived from
6 * the Linux/Alpha version.
7 *
8 * Copyright (C) 1998, 1999 Hewlett-Packard Co
9 * Copyright (C) 1998, 1999 David Mosberger-Tang <davidm@hpl.hp.com>
10 */
11 #define get_unaligned(ptr) \
12 ((__typeof__(*(ptr)))ia64_get_unaligned((ptr), sizeof(*(ptr))))
13
14 #define put_unaligned(x,ptr) \
15 ia64_put_unaligned((unsigned long)(x), (ptr), sizeof(*(ptr)))
16
17 /*
18 * EGCS 1.1 knows about arbitrary unaligned loads. Define some
19 * packed structures to talk about such things with.
20 */
21 struct __una_u64 { __u64 x __attribute__((packed)); };
22 struct __una_u32 { __u32 x __attribute__((packed)); };
23 struct __una_u16 { __u16 x __attribute__((packed)); };
24
25 static inline unsigned long
26 __uldq (const unsigned long * r11)
27 {
28 const struct __una_u64 *ptr = (const struct __una_u64 *) r11;
29 return ptr->x;
30 }
31
32 static inline unsigned long
33 __uldl (const unsigned int * r11)
34 {
35 const struct __una_u32 *ptr = (const struct __una_u32 *) r11;
36 return ptr->x;
37 }
38
39 static inline unsigned long
40 __uldw (const unsigned short * r11)
41 {
42 const struct __una_u16 *ptr = (const struct __una_u16 *) r11;
43 return ptr->x;
44 }
45
46 static inline void
47 __ustq (unsigned long r5, unsigned long * r11)
48 {
49 struct __una_u64 *ptr = (struct __una_u64 *) r11;
50 ptr->x = r5;
51 }
52
53 static inline void
54 __ustl (unsigned long r5, unsigned int * r11)
55 {
56 struct __una_u32 *ptr = (struct __una_u32 *) r11;
57 ptr->x = r5;
58 }
59
60 static inline void
61 __ustw (unsigned long r5, unsigned short * r11)
62 {
63 struct __una_u16 *ptr = (struct __una_u16 *) r11;
64 ptr->x = r5;
65 }
66
67
68 /*
69 * This function doesn't actually exist. The idea is that when
70 * someone uses the macros below with an unsupported size (datatype),
71 * the linker will alert us to the problem via an unresolved reference
72 * error.
73 */
74 extern unsigned long ia64_bad_unaligned_access_length (void);
75
76 #define ia64_get_unaligned(_ptr,size) \
77 ({ \
78 const void *ptr = (_ptr); \
79 unsigned long val; \
80 \
81 switch (size) { \
82 case 1: \
83 val = *(const unsigned char *) ptr; \
84 break; \
85 case 2: \
86 val = __uldw((const unsigned short *)ptr); \
87 break; \
88 case 4: \
89 val = __uldl((const unsigned int *)ptr); \
90 break; \
91 case 8: \
92 val = __uldq((const unsigned long *)ptr); \
93 break; \
94 default: \
95 val = ia64_bad_unaligned_access_length(); \
96 } \
97 val; \
98 })
99
100 #define ia64_put_unaligned(_val,_ptr,size) \
101 do { \
102 const void *ptr = (_ptr); \
103 unsigned long val = (_val); \
104 \
105 switch (size) { \
106 case 1: \
107 *(unsigned char *)ptr = (val); \
108 break; \
109 case 2: \
110 __ustw(val, (unsigned short *)ptr); \
111 break; \
112 case 4: \
113 __ustl(val, (unsigned int *)ptr); \
114 break; \
115 case 8: \
116 __ustq(val, (unsigned long *)ptr); \
117 break; \
118 default: \
119 ia64_bad_unaligned_access_length(); \
120 } \
121 } while (0)
122
123 #endif /* _ASM_IA64_UNALIGNED_H */
124
This page was automatically generated by the
LXR engine.
Visit the LXR main site for more
information.