source: trunk/packages/xen-3.1/xen-3.1/xen/include/asm-ia64/linux/asm-generic/unaligned.h @ 34

Last change on this file since 34 was 34, checked in by hartmans, 17 years ago

Add xen and xen-common

File size: 2.8 KB
Line 
1#ifndef _ASM_GENERIC_UNALIGNED_H_
2#define _ASM_GENERIC_UNALIGNED_H_
3
4/*
5 * For the benefit of those who are trying to port Linux to another
6 * architecture, here are some C-language equivalents.
7 *
8 * This is based almost entirely upon Richard Henderson's
9 * asm-alpha/unaligned.h implementation.  Some comments were
10 * taken from David Mosberger's asm-ia64/unaligned.h header.
11 */
12
13#include <linux/types.h>
14
15/*
16 * The main single-value unaligned transfer routines.
17 */
18#define get_unaligned(ptr) \
19        ((__typeof__(*(ptr)))__get_unaligned((ptr), sizeof(*(ptr))))
20#define put_unaligned(x,ptr) \
21        __put_unaligned((unsigned long)(x), (ptr), sizeof(*(ptr)))
22
23/*
24 * This function doesn't actually exist.  The idea is that when
25 * someone uses the macros below with an unsupported size (datatype),
26 * the linker will alert us to the problem via an unresolved reference
27 * error.
28 */
29extern void bad_unaligned_access_length(void) __attribute__((noreturn));
30
31struct __una_u64 { __u64 x __attribute__((packed)); };
32struct __una_u32 { __u32 x __attribute__((packed)); };
33struct __una_u16 { __u16 x __attribute__((packed)); };
34
35/*
36 * Elemental unaligned loads
37 */
38
39static inline unsigned long __uldq(const __u64 *addr)
40{
41        const struct __una_u64 *ptr = (const struct __una_u64 *) addr;
42        return ptr->x;
43}
44
45static inline unsigned long __uldl(const __u32 *addr)
46{
47        const struct __una_u32 *ptr = (const struct __una_u32 *) addr;
48        return ptr->x;
49}
50
51static inline unsigned long __uldw(const __u16 *addr)
52{
53        const struct __una_u16 *ptr = (const struct __una_u16 *) addr;
54        return ptr->x;
55}
56
57/*
58 * Elemental unaligned stores
59 */
60
61static inline void __ustq(__u64 val, __u64 *addr)
62{
63        struct __una_u64 *ptr = (struct __una_u64 *) addr;
64        ptr->x = val;
65}
66
67static inline void __ustl(__u32 val, __u32 *addr)
68{
69        struct __una_u32 *ptr = (struct __una_u32 *) addr;
70        ptr->x = val;
71}
72
73static inline void __ustw(__u16 val, __u16 *addr)
74{
75        struct __una_u16 *ptr = (struct __una_u16 *) addr;
76        ptr->x = val;
77}
78
79#define __get_unaligned(ptr, size) ({           \
80        const void *__gu_p = ptr;               \
81        unsigned long val;                      \
82        switch (size) {                         \
83        case 1:                                 \
84                val = *(const __u8 *)__gu_p;    \
85                break;                          \
86        case 2:                                 \
87                val = __uldw(__gu_p);           \
88                break;                          \
89        case 4:                                 \
90                val = __uldl(__gu_p);           \
91                break;                          \
92        case 8:                                 \
93                val = __uldq(__gu_p);           \
94                break;                          \
95        default:                                \
96                bad_unaligned_access_length();  \
97        };                                      \
98        val;                                    \
99})
100
101#define __put_unaligned(val, ptr, size)         \
102do {                                            \
103        void *__gu_p = ptr;                     \
104        switch (size) {                         \
105        case 1:                                 \
106                *(__u8 *)__gu_p = val;          \
107                break;                          \
108        case 2:                                 \
109                __ustw(val, __gu_p);            \
110                break;                          \
111        case 4:                                 \
112                __ustl(val, __gu_p);            \
113                break;                          \
114        case 8:                                 \
115                __ustq(val, __gu_p);            \
116                break;                          \
117        default:                                \
118                bad_unaligned_access_length();  \
119        };                                      \
120} while(0)
121
122#endif /* _ASM_GENERIC_UNALIGNED_H */
Note: See TracBrowser for help on using the repository browser.