Initial revision
[LeanCalc.git] / calc / calc / byteswap.h
1 /*
2  * byteswap - byte swapping macros
3  *
4  * Copyright (C) 1999  Landon Curt Noll
5  *
6  * Calc is open software; you can redistribute it and/or modify it under
7  * the terms of the version 2.1 of the GNU Lesser General Public License
8  * as published by the Free Software Foundation.
9  *
10  * Calc is distributed in the hope that it will be useful, but WITHOUT
11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General
13  * Public License for more details.
14  *
15  * A copy of version 2.1 of the GNU Lesser General Public License is
16  * distributed with calc under the filename COPYING-LGPL.  You should have
17  * received a copy with calc; if not, write to Free Software Foundation, Inc.
18  * 59 Temple Place, Suite 330, Boston, MA  02111-1307, USA.
19  *
20  * @(#) $Revision$
21  * @(#) $Id$
22  * @(#) $Source$
23  *
24  * Under source code control:   1995/10/11 04:44:01
25  * File existed as early as:    1995
26  *
27  * chongo <was here> /\oo/\     http://www.isthe.com/chongo/
28  * Share and enjoy!  :-)        http://www.isthe.com/chongo/tech/comp/calc/
29  */
30
31
32 #if !defined(__BYTESWAP_H__)
33 #define __BYTESWAP_H__
34
35
36 #if defined(CALC_SRC)   /* if we are building from the calc source tree */
37 # include "calc/longbits.h"
38 #else
39 # include <calc/longbits.h>
40 #endif
41
42
43 /*
44  * SWAP_B8_IN_B16 - swap 8 bits in 16 bits
45  *
46  *      dest    - pointer to where the swapped src wil be put
47  *      src     - pointer to a 16 bit value to swap
48  *
49  * This macro will either switch to the opposite byte sex (Big Endian vs.
50  * Little Endian) a 16 bit value.
51  */
52 #define SWAP_B8_IN_B16(dest, src) (                                     \
53         *((USB16*)(dest)) =                                             \
54           (((*((USB16*)(src))) << 8) | ((*((USB16*)(src))) >> 8))       \
55 )
56
57 /*
58  * SWAP_B16_IN_B32 - swap 16 bits in 32 bits
59  *
60  *      dest    - pointer to where the swapped src wil be put
61  *      src     - pointer to a 32 bit value to swap
62  */
63 #define SWAP_B16_IN_B32(dest, src) (                                    \
64         *((USB32*)(dest)) =                                             \
65           (((*((USB32*)(src))) << 16) | ((*((USB32*)(src))) >> 16))     \
66 )
67
68 /*
69  * SWAP_B8_IN_B32 - swap 8 & 16 bits in 32 bits
70  *
71  *      dest    - pointer to where the swapped src wil be put
72  *      src     - pointer to a 32 bit value to swap
73  *
74  * This macro will either switch to the opposite byte sex (Big Endian vs.
75  * Little Endian) a 32 bit value.
76  */
77 #define SWAP_B8_IN_B32(dest, src) (                                     \
78         SWAP_B16_IN_B32(dest, src),                                     \
79         (*((USB32*)(dest)) =                                            \
80           ((((*((USB32*)(dest))) & (USB32)0xff00ff00) >> 8) |           \
81           (((*((USB32*)(dest))) & (USB32)0x00ff00ff) << 8)))            \
82 )
83
84 #if defined(HAVE_B64)
85
86 /*
87  * SWAP_B32_IN_B64 - swap 32 bits in 64 bits
88  *
89  *      dest    - pointer to where the swapped src wil be put
90  *      src     - pointer to a 64 bit value to swap
91  */
92 #define SWAP_B32_IN_B64(dest, src) (                                    \
93         *((USB64*)(dest)) =                                             \
94           (((*((USB64*)(src))) << 32) | ((*((USB64*)(src))) >> 32))     \
95 )
96
97 /*
98  * SWAP_B16_IN_B64 - swap 16 & 32 bits in 64 bits
99  *
100  *      dest    - pointer to where the swapped src wil be put
101  *      src     - pointer to a 64 bit value to swap
102  */
103 #define SWAP_B16_IN_B64(dest, src) (                                    \
104         SWAP_B32_IN_B64(dest, src),                                     \
105         (*((USB64*)(dest)) =                                            \
106           ((((*((USB64*)(dest))) & (USB64)0xffff0000ffff0000) >> 16) |  \
107           (((*((USB64*)(dest))) & (USB64)0x0000ffff0000ffff) << 16)))   \
108 )
109
110 /*
111  * SWAP_B8_IN_B64 - swap 16 & 32 bits in 64 bits
112  *
113  *      dest    - pointer to where the swapped src wil be put
114  *      src     - pointer to a 64 bit value to swap
115  *
116  * This macro will either switch to the opposite byte sex (Big Endian vs.
117  * Little Endian) a 64 bit value.
118  */
119 #define SWAP_B8_IN_B64(dest, src) (                                     \
120         SWAP_B16_IN_B64(dest, src),                                     \
121         (*((USB64*)(dest)) =                                            \
122           ((((*((USB64*)(dest))) & (USB64)0xff00ff00ff00ff00) >> 8) |   \
123           (((*((USB64*)(dest))) & (USB64)0x00ff00ff00ff00ff) << 8)))    \
124 )
125
126 #else /* HAVE_B64 */
127
128 /*
129  * SWAP_B32_IN_B64 - swap 32 bits in 64 bits (simulated by 2 32 bit values)
130  *
131  *      dest    - pointer to where the swapped src wil be put
132  *      src     - pointer to a 64 bit value to swap
133  */
134 #define SWAP_B32_IN_B64(dest, src) (                                    \
135         ((USB32*)(dest))[1] = ((USB32*)(dest))[0],                      \
136         ((USB32*)(dest))[0] = ((USB32*)(dest))[1]                       \
137 )
138
139 /*
140  * SWAP_B16_IN_B64 - swap 16 & 32 bits in 64 bits (simulated by 2 32 bit vals)
141  *
142  *      dest    - pointer to where the swapped src wil be put
143  *      src     - pointer to a 64 bit value to swap
144  */
145 #define SWAP_B16_IN_B64(dest, src) (                                    \
146         SWAP_B16_IN_B32(((USB32*)dest)+1, ((USB32*)src)),               \
147         SWAP_B16_IN_B32(((USB32*)dest), ((USB32*)src)+1)                \
148 )
149
150 /*
151  * SWAP_B8_IN_B64 - swap 16 & 32 bits in 64 bits (simulated by 2 32 bit vals)
152  *
153  *      dest    - pointer to where the swapped src wil be put
154  *      src     - pointer to a 64 bit value to swap
155  *
156  * This macro will either switch to the opposite byte sex (Big Endian vs.
157  * Little Endian) a 64 bit value.
158  */
159 #define SWAP_B8_IN_B64(dest, src) (                                     \
160         SWAP_B8_IN_B32(((USB32*)dest)+1, ((USB32*)src)),                \
161         SWAP_B8_IN_B32(((USB32*)dest), ((USB32*)src)+1)                 \
162 )
163
164 #endif /* HAVE_B64 */
165
166 #if LONG_BITS == 64
167
168 #define SWAP_B32_IN_LONG(dest, src)     SWAP_B32_IN_B64(dest, src)
169 #define SWAP_B16_IN_LONG(dest, src)     SWAP_B16_IN_B64(dest, src)
170 #define SWAP_B8_IN_LONG(dest, src)      SWAP_B8_IN_B64(dest, src)
171
172 #else /* LONG_BITS == 64 */
173
174 #define SWAP_B32_IN_LONG(dest, src)     SWAP_B32_IN_B32(dest, src)
175 #define SWAP_B16_IN_LONG(dest, src)     SWAP_B16_IN_B32(dest, src)
176 #define SWAP_B8_IN_LONG(dest, src)      SWAP_B8_IN_B32(dest, src)
177
178 #endif /* LONG_BITS == 64 */
179
180
181 #endif /* !__BYTESWAP_H__ */