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