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
14OS_INLINE
15uint16_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
24OS_INLINE
25uint32_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
40OS_INLINE
41uint64_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
65OS_INLINE
66uint16_t
67OSReadSwapInt16(
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
78OS_INLINE
79uint32_t
80OSReadSwapInt32(
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
91OS_INLINE
92uint64_t
93OSReadSwapInt64(
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
114OS_INLINE
115void
116OSWriteSwapInt16(
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
125OS_INLINE
126void
127OSWriteSwapInt32(
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
136OS_INLINE
137void
138OSWriteSwapInt64(
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