1 /* $Id$
2 *
3 * This file is subject to the terms and conditions of the GNU General Public
4 * License. See the file "COPYING" in the main directory of this archive
5 * for more details.
6 *
7 * Copyright (C) 1996, 1999 by Ralf Baechle
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 long * __addr)
19 {
20 unsigned long long __res;
21
22 __asm__("uld\t%0,(%1)"
23 :"=&r" (__res)
24 :"r" (__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 :"r" (__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 :"r" (__addr));
53
54 return __res;
55 }
56
57 /*
58 * Store quad ununaligned.
59 */
60 extern __inline__ void stq_u(unsigned long __val, unsigned long long * __addr)
61 {
62 __asm__ __volatile__(
63 "usd\t%0,(%1)"
64 : /* No results */
65 :"r" (__val),
66 "r" (__addr));
67 }
68
69 /*
70 * Store long ununaligned.
71 */
72 extern __inline__ void stl_u(unsigned long __val, unsigned int * __addr)
73 {
74 __asm__ __volatile__(
75 "usw\t%0,(%1)"
76 : /* No results */
77 :"r" (__val),
78 "r" (__addr));
79 }
80
81 /*
82 * Store word ununaligned.
83 */
84 extern __inline__ void stw_u(unsigned long __val, unsigned short * __addr)
85 {
86 __asm__ __volatile__(
87 "ush\t%0,(%1)"
88 : /* No results */
89 :"r" (__val),
90 "r" (__addr));
91 }
92
93 extern inline unsigned long __get_unaligned(const void *ptr, size_t size)
94 {
95 unsigned long val;
96 switch (size) {
97 case 1:
98 val = *(const unsigned char *)ptr;
99 break;
100 case 2:
101 val = ldw_u((const unsigned short *)ptr);
102 break;
103 case 4:
104 val = ldl_u((const unsigned int *)ptr);
105 break;
106 case 8:
107 val = ldq_u((const unsigned long long *)ptr);
108 break;
109 default:
110 __get_unaligned_bad_length();
111 break;
112 }
113 return val;
114 }
115
116 extern inline void __put_unaligned(unsigned long val, void *ptr, size_t size)
117 {
118 switch (size) {
119 case 1:
120 *(unsigned char *)ptr = (val);
121 break;
122 case 2:
123 stw_u(val, (unsigned short *)ptr);
124 break;
125 case 4:
126 stl_u(val, (unsigned int *)ptr);
127 break;
128 case 8:
129 stq_u(val, (unsigned long long *)ptr);
130 break;
131 default:
132 __put_unaligned_bad_length();
133 break;
134 }
135 }
136
137 /*
138 * The main single-value unaligned transfer routines.
139 */
140 #define get_unaligned(ptr) \
141 ((__typeof__(*(ptr)))__get_unaligned((ptr), sizeof(*(ptr))))
142 #define put_unaligned(x,ptr) \
143 __put_unaligned((unsigned long)(x), (ptr), sizeof(*(ptr)))
144
145 #endif /* _ASM_UNALIGNED_H */
146
This page was automatically generated by the
LXR engine.
Visit the LXR main site for more
information.