1 /** $MirOS: src/sys/sys/endian.h,v 1.4 2008/11/08 23:04:24 tg Exp $ */ 2 /* $OpenBSD: endian.h,v 1.14 2004/01/11 19:17:31 brad Exp $ */ 3 4 /*- 5 * Copyright (c) 2004, 2006 6 * Thorsten "mirabilos" Glaser <tg@mirbsd.org> 7 * Copyright (c) 1997 Niklas Hallqvist. All rights reserved. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 */ 29 30 /* 31 * Generic definitions for little- and big-endian systems. Other endianesses 32 * has to be dealt with in the specific machine/endian.h file for that port. 33 * 34 * This file is meant to be included from a little- or big-endian port's 35 * machine/endian.h after setting BYTE_ORDER to either 1234 for little endian 36 * or 4321 for big.. 37 */ 38 39 #ifndef _SYS_ENDIAN_H_ 40 #define _SYS_ENDIAN_H_ 41 42 #ifndef _POSIX_SOURCE 43 44 #include <sys/cdefs.h> 45 46 #define LITTLE_ENDIAN 1234 47 #define BIG_ENDIAN 4321 48 #define PDP_ENDIAN 3412 49 50 #ifdef __GNUC__ 51 52 #define __swap16gen(x) __extension__({ \ 53 u_int16_t __swap16gen_x = (x); \ 54 \ 55 (u_int16_t)((__swap16gen_x & 0xff) << 8 | \ 56 (__swap16gen_x & 0xff00) >> 8); \ 57 }) 58 59 #define __swap32gen(x) __extension__({ \ 60 u_int32_t __swap32gen_x = (x); \ 61 \ 62 (u_int32_t)((__swap32gen_x & 0xff) << 24 | \ 63 (__swap32gen_x & 0xff00) << 8 | \ 64 (__swap32gen_x & 0xff0000) >> 8 | \ 65 (__swap32gen_x & 0xff000000) >> 24); \ 66 }) 67 68 #define __swap64gen(x) __extension__({ \ 69 u_int64_t __swap64gen_x = (x); \ 70 \ 71 (u_int64_t)((__swap64gen_x & 0xff) << 56 | \ 72 (__swap64gen_x & 0xff00ULL) << 40 | \ 73 (__swap64gen_x & 0xff0000ULL) << 24 | \ 74 (__swap64gen_x & 0xff000000ULL) << 8 | \ 75 (__swap64gen_x & 0xff00000000ULL) >> 8 | \ 76 (__swap64gen_x & 0xff0000000000ULL) >> 24 | \ 77 (__swap64gen_x & 0xff000000000000ULL) >> 40 | \ 78 (__swap64gen_x & 0xff00000000000000ULL) >> 56); \ 79 }) 80 81 #else /* __GNUC__ */ 82 83 /* Note that these macros evaluate their arguments several times. */ 84 #define __swap16gen(x) \ 85 (u_int16_t)(((u_int16_t)(x) & 0xff) << 8 | ((u_int16_t)(x) & 0xff00) >> 8) 86 87 #define __swap32gen(x) \ 88 (u_int32_t)(((u_int32_t)(x) & 0xff) << 24 | \ 89 ((u_int32_t)(x) & 0xff00) << 8 | ((u_int32_t)(x) & 0xff0000) >> 8 | \ 90 ((u_int32_t)(x) & 0xff000000) >> 24) 91 92 #define __swap64gen(x) \ 93 (u_int64_t)((((u_int64_t)(x) & 0xff) << 56) | \ 94 ((u_int64_t)(x) & 0xff00ULL) << 40 | \ 95 ((u_int64_t)(x) & 0xff0000ULL) << 24 | \ 96 ((u_int64_t)(x) & 0xff000000ULL) << 8 | \ 97 ((u_int64_t)(x) & 0xff00000000ULL) >> 8 | \ 98 ((u_int64_t)(x) & 0xff0000000000ULL) >> 24 | \ 99 ((u_int64_t)(x) & 0xff000000000000ULL) >> 40 | \ 100 ((u_int64_t)(x) & 0xff00000000000000ULL) >> 56) 101 102 #endif /* __GNUC__ */ 103 104 /* 105 * Define MD_SWAP if you provide swap{16,32}md functions/macros that are 106 * optimized for your architecture, These will be used for swap{16,32} 107 * unless the argument is a constant and we are using GCC, where we can 108 * take advantage of the CSE phase much better by using the generic version. 109 */ 110 #ifdef MD_SWAP 111 #if __GNUC__ 112 113 #define swap16(x) __extension__({ \ 114 u_int16_t __swap16_x = (x); \ 115 \ 116 __builtin_constant_p(x) ? __swap16gen(__swap16_x) : \ 117 __swap16md(__swap16_x); \ 118 }) 119 120 #define swap32(x) __extension__({ \ 121 u_int32_t __swap32_x = (x); \ 122 \ 123 __builtin_constant_p(x) ? __swap32gen(__swap32_x) : \ 124 __swap32md(__swap32_x); \ 125 }) 126 127 #define swap64(x) __extension__({ \ 128 u_int64_t __swap64_x = (x); \ 129 \ 130 __builtin_constant_p(x) ? __swap64gen(__swap64_x) : \ 131 __swap64md(__swap64_x); \ 132 }) 133 134 #endif /* __GNUC__ */ 135 136 #else /* MD_SWAP */ 137 #define swap16 __swap16gen 138 #define swap32 __swap32gen 139 #define swap64 __swap64gen 140 #endif /* MD_SWAP */ 141 142 #define swap16_multi(v, n) do { \ 143 size_t __swap16_multi_n = (n); \ 144 u_int16_t *__swap16_multi_v = (v); \ 145 \ 146 while (__swap16_multi_n) { \ 147 *__swap16_multi_v = swap16(*__swap16_multi_v); \ 148 __swap16_multi_v++; \ 149 __swap16_multi_n--; \ 150 } \ 151 } while (0) 152 153 __BEGIN_DECLS 154 u_int64_t htobe64(u_int64_t); 155 u_int32_t htobe32(u_int32_t); 156 u_int16_t htobe16(u_int16_t); 157 u_int64_t betoh64(u_int64_t); 158 u_int32_t betoh32(u_int32_t); 159 u_int16_t betoh16(u_int16_t); 160 161 u_int64_t htole64(u_int64_t); 162 u_int32_t htole32(u_int32_t); 163 u_int16_t htole16(u_int16_t); 164 u_int64_t letoh64(u_int64_t); 165 u_int32_t letoh32(u_int32_t); 166 u_int16_t letoh16(u_int16_t); 167 __END_DECLS 168 169 #if BYTE_ORDER == LITTLE_ENDIAN 170 171 /* Can be overridden by machine/endian.h before inclusion of this file. */ 172 #ifndef _QUAD_HIGHWORD 173 #define _QUAD_HIGHWORD 1 174 #endif 175 #ifndef _QUAD_LOWWORD 176 #define _QUAD_LOWWORD 0 177 #endif 178 179 #define htobe16 swap16 180 #define htobe32 swap32 181 #define htobe64 swap64 182 #define betoh16 swap16 183 #define betoh32 swap32 184 #define betoh64 swap64 185 186 #define htole16(x) ((uint16_t)(x)) 187 #define htole32(x) ((uint32_t)(x)) 188 #define htole64(x) ((uint64_t)(x)) 189 #define letoh16(x) ((uint16_t)(x)) 190 #define letoh32(x) ((uint32_t)(x)) 191 #define letoh64(x) ((uint64_t)(x)) 192 193 #endif /* BYTE_ORDER */ 194 195 #if BYTE_ORDER == BIG_ENDIAN 196 197 /* Can be overridden by machine/endian.h before inclusion of this file. */ 198 #ifndef _QUAD_HIGHWORD 199 #define _QUAD_HIGHWORD 0 200 #endif 201 #ifndef _QUAD_LOWWORD 202 #define _QUAD_LOWWORD 1 203 #endif 204 205 #define htole16 swap16 206 #define htole32 swap32 207 #define htole64 swap64 208 #define letoh16 swap16 209 #define letoh32 swap32 210 #define letoh64 swap64 211 212 #define htobe16(x) ((uint16_t)(x)) 213 #define htobe32(x) ((uint32_t)(x)) 214 #define htobe64(x) ((uint64_t)(x)) 215 #define betoh16(x) ((uint16_t)(x)) 216 #define betoh32(x) ((uint32_t)(x)) 217 #define betoh64(x) ((uint64_t)(x)) 218 219 #endif /* BYTE_ORDER */ 220 221 #if BYTE_ORDER == PDP_ENDIAN 222 #error You are crazy. Go away. 223 #endif /* BYTE_ORDER */ 224 225 #define bswap16 swap16 226 #define bswap32 swap32 227 #define bswap64 swap64 228 229 #define htons htobe16 230 #define htonl htobe32 231 #define ntohs betoh16 232 #define ntohl betoh32 233 234 #define be16toh betoh16 235 #define be32toh betoh32 236 #define be64toh betoh64 237 #define le16toh letoh16 238 #define le32toh letoh32 239 #define le64toh letoh64 240 241 #define NTOHL(x) (x) = ntohl((u_int32_t)(x)) 242 #define NTOHS(x) (x) = ntohs((u_int16_t)(x)) 243 #define HTONL(x) (x) = htonl((u_int32_t)(x)) 244 #define HTONS(x) (x) = htons((u_int16_t)(x)) 245 246 #define BE16TOH(x) (x) = be16toh((u_int16_t)(x)) 247 #define BE32TOH(x) (x) = be32toh((u_int32_t)(x)) 248 #define BE64TOH(x) (x) = be64toh((u_int64_t)(x)) 249 #define HTOBE16(x) (x) = htobe16((u_int16_t)(x)) 250 #define HTOBE32(x) (x) = htobe32((u_int32_t)(x)) 251 #define HTOBE64(x) (x) = htobe64((u_int64_t)(x)) 252 #define LE16TOH(x) (x) = le16toh((u_int16_t)(x)) 253 #define LE32TOH(x) (x) = le32toh((u_int32_t)(x)) 254 #define LE64TOH(x) (x) = le64toh((u_int64_t)(x)) 255 #define HTOLE16(x) (x) = htole16((u_int16_t)(x)) 256 #define HTOLE32(x) (x) = htole32((u_int32_t)(x)) 257 #define HTOLE64(x) (x) = htole64((u_int64_t)(x)) 258 259 #endif /* _POSIX_SOURCE */ 260 #endif /* _SYS_ENDIAN_H_ */ 261