/* [<][>][^][v][top][bottom][index][help] */
DEFINITIONS
This source file includes following definitions.
- bswap16
- bswap32
- bswap64
- TO
- split64to32
1 /*
2 * Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
3 * The President and Fellows of Harvard College.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. Neither the name of the University nor the names of its contributors
14 * may be used to endorse or promote products derived from this software
15 * without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 */
29
30 #include <types.h>
31 #include <endian.h>
32
33 /*
34 * Unconditional byte-swap functions.
35 *
36 * bswap16, 32, and 64 unconditionally swap byte order of integers of
37 * the respective bitsize.
38 *
39 * The advantage of writing them out like this is that the bit
40 * patterns are easily validated by inspection. Also, this form is
41 * more likely to be picked up by the compiler and converted into
42 * byte-swap machine instructions (if those exist) than something
43 * loop-based.
44 */
45
46 uint16_t
47 bswap16(uint16_t val)
48 {
49 return ((val & 0x00ff) << 8)
50 | ((val & 0xff00) >> 8);
51 }
52
53 uint32_t
54 bswap32(uint32_t val)
55 {
56 return ((val & 0x000000ff) << 24)
57 | ((val & 0x0000ff00) << 8)
58 | ((val & 0x00ff0000) >> 8)
59 | ((val & 0xff000000) >> 24);
60 }
61
62 uint64_t
63 bswap64(uint64_t val)
64 {
65 return ((val & 0x00000000000000ff) << 56)
66 | ((val & 0x000000000000ff00) << 40)
67 | ((val & 0x0000000000ff0000) << 24)
68 | ((val & 0x00000000ff000000) << 8)
69 | ((val & 0x000000ff00000000) << 8)
70 | ((val & 0x0000ff0000000000) << 24)
71 | ((val & 0x00ff000000000000) >> 40)
72 | ((val & 0xff00000000000000) >> 56);
73 }
74
75 /*
76 * Network byte order byte-swap functions.
77 *
78 * For ntoh* and hton*:
79 * *s are for "short" (16-bit)
80 * *l are for "long" (32-bit)
81 * *ll are for "long long" (64-bit)
82 *
83 * hton* convert from host byte order to network byte order.
84 * ntoh* convert from network byte order to host byte order.
85 *
86 * Network byte order is big-endian.
87 *
88 * Note that right now the only platforms OS/161 runs on are
89 * big-endian, so these functions are actually all empty.
90 *
91 * These should maybe be made inline.
92 */
93
94 #if _BYTE_ORDER == _LITTLE_ENDIAN
95 #define TO(tag, bits, type) \
96 type ntoh##tag(type val) { return bswap##bits(val); } \
97 type hton##tag(type val) { return bswap##bits(val); }
98 #endif
99
100 /*
101 * Use a separate #if, so if the header file defining the symbols gets
102 * omitted or messed up the build will fail instead of silently choosing
103 * the wrong option.
104 */
105 #if _BYTE_ORDER == _BIG_ENDIAN
106 #define TO(tag, bits, type) \
107 type ntoh##tag(type val) { return val; } \
108 type hton##tag(type val) { return val; }
109 #endif
110
111 #if _BYTE_ORDER == _PDP_ENDIAN
112 #error "You lose."
113 #endif
114
115 #ifndef TO
116 #error "_BYTE_ORDER not set"
117 #endif
118
119 TO(s, 16, uint16_t)
120 TO(l, 32, uint32_t)
121 TO(ll, 64, uint64_t)
122
123
124 /*
125 * Some utility functions for handling 64-bit values.
126 *
127 * join32to64 pastes two adjoining 32-bit values together in the right
128 * way to treat them as a 64-bit value, depending on endianness.
129 * split64to32 is the inverse operation.
130 *
131 * The 32-bit arguments should be passed in the order they appear in
132 * memory, not as high word and low word; the whole point of these
133 * functions is to know which is the high word and which is the low
134 * word.
135 */
136
137 void
138 join32to64(uint32_t x1, uint32_t x2, uint64_t *y2)
139 {
140 #if _BYTE_ORDER == _BIG_ENDIAN
141 *y2 = ((uint64_t)x1 << 32) | (uint64_t)x2;
142 #elif _BYTE_ORDER == _LITTLE_ENDIAN
143 *y2 = (uint64_t)x1 | ((uint64_t)x2 << 32);
144 #else
145 #error "Eh?"
146 #endif
147 }
148
149 void
150 split64to32(uint64_t x, uint32_t *y1, uint32_t *y2)
151 {
152 #if _BYTE_ORDER == _BIG_ENDIAN
153 *y1 = x >> 32;
154 *y2 = x & 0xffffffff;
155 #elif _BYTE_ORDER == _LITTLE_ENDIAN
156 *y1 = x & 0xffffffff;
157 *y2 = x >> 32;
158 #else
159 #error "Eh?"
160 #endif
161 }