Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
script3r
GitHub Repository: script3r/os161
Path: blob/master/kern/lib/bswap.c
2093 views
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
}
162
163