1 | /* |
---|---|
2 | * Copyright (c) 1999-2007 Apple Inc. All rights reserved. |
3 | */ |
4 | |
5 | #ifndef _OS_OSBYTEORDERARM_H |
6 | #define _OS_OSBYTEORDERARM_H |
7 | |
8 | #include <stdint.h> |
9 | #include <arm/arch.h> /* for _ARM_ARCH_6 */ |
10 | #include <sys/_types/_os_inline.h> |
11 | |
12 | /* Generic byte swapping functions. */ |
13 | |
14 | OS_INLINE |
15 | uint16_t |
16 | _OSSwapInt16( |
17 | uint16_t data |
18 | ) |
19 | { |
20 | /* Reduces to 'rev16' with clang */ |
21 | return (uint16_t)(data << 8 | data >> 8); |
22 | } |
23 | |
24 | OS_INLINE |
25 | uint32_t |
26 | _OSSwapInt32( |
27 | uint32_t data |
28 | ) |
29 | { |
30 | #if defined(__llvm__) |
31 | data = __builtin_bswap32(data); |
32 | #else |
33 | /* This actually generates the best code */ |
34 | data = (((data ^ (data >> 16 | (data << 16))) & 0xFF00FFFF) >> 8) ^ (data >> 8 | data << 24); |
35 | #endif |
36 | |
37 | return data; |
38 | } |
39 | |
40 | OS_INLINE |
41 | uint64_t |
42 | _OSSwapInt64( |
43 | uint64_t data |
44 | ) |
45 | { |
46 | #if defined(__llvm__) |
47 | return __builtin_bswap64(data); |
48 | #else |
49 | union { |
50 | uint64_t ull; |
51 | uint32_t ul[2]; |
52 | } u; |
53 | |
54 | /* This actually generates the best code */ |
55 | u.ul[0] = (uint32_t)(data >> 32); |
56 | u.ul[1] = (uint32_t)(data & 0xffffffff); |
57 | u.ul[0] = _OSSwapInt32(u.ul[0]); |
58 | u.ul[1] = _OSSwapInt32(u.ul[1]); |
59 | return u.ull; |
60 | #endif |
61 | } |
62 | |
63 | /* Functions for byte reversed loads. */ |
64 | |
65 | OS_INLINE |
66 | uint16_t |
67 | OSReadSwapInt16( |
68 | const volatile void * base, |
69 | uintptr_t offset |
70 | ) |
71 | { |
72 | uint16_t result; |
73 | |
74 | result = *(volatile uint16_t *)((volatile uintptr_t)base + offset); |
75 | return _OSSwapInt16(result); |
76 | } |
77 | |
78 | OS_INLINE |
79 | uint32_t |
80 | OSReadSwapInt32( |
81 | const volatile void * base, |
82 | uintptr_t offset |
83 | ) |
84 | { |
85 | uint32_t result; |
86 | |
87 | result = *(volatile uint32_t *)((volatile uintptr_t)base + offset); |
88 | return _OSSwapInt32(result); |
89 | } |
90 | |
91 | OS_INLINE |
92 | uint64_t |
93 | OSReadSwapInt64( |
94 | const volatile void * base, |
95 | uintptr_t offset |
96 | ) |
97 | { |
98 | volatile uint32_t * inp; |
99 | union ullc { |
100 | uint64_t ull; |
101 | uint32_t ul[2]; |
102 | } outv; |
103 | |
104 | inp = (volatile uint32_t *)((volatile uintptr_t)base + offset); |
105 | outv.ul[0] = inp[1]; |
106 | outv.ul[1] = inp[0]; |
107 | outv.ul[0] = _OSSwapInt32(outv.ul[0]); |
108 | outv.ul[1] = _OSSwapInt32(outv.ul[1]); |
109 | return outv.ull; |
110 | } |
111 | |
112 | /* Functions for byte reversed stores. */ |
113 | |
114 | OS_INLINE |
115 | void |
116 | OSWriteSwapInt16( |
117 | volatile void * base, |
118 | uintptr_t offset, |
119 | uint16_t data |
120 | ) |
121 | { |
122 | *(volatile uint16_t *)((volatile uintptr_t)base + offset) = _OSSwapInt16(data); |
123 | } |
124 | |
125 | OS_INLINE |
126 | void |
127 | OSWriteSwapInt32( |
128 | volatile void * base, |
129 | uintptr_t offset, |
130 | uint32_t data |
131 | ) |
132 | { |
133 | *(volatile uint32_t *)((volatile uintptr_t)base + offset) = _OSSwapInt32(data); |
134 | } |
135 | |
136 | OS_INLINE |
137 | void |
138 | OSWriteSwapInt64( |
139 | volatile void * base, |
140 | uintptr_t offset, |
141 | uint64_t data |
142 | ) |
143 | { |
144 | *(volatile uint64_t *)((volatile uintptr_t)base + offset) = _OSSwapInt64(data); |
145 | } |
146 | |
147 | #endif /* ! _OS_OSBYTEORDERARM_H */ |
148 |