1/* $OpenBSD: _endian.h,v 1.8 2018/01/11 23:13:37 dlg Exp $ */ 2 3/*- 4 * Copyright (c) 1997 Niklas Hallqvist. All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 */ 26 27/* 28 * Internal endianness macros. This pulls in <machine/endian.h> to 29 * get the correct setting direction for the platform and sets internal 30 * ('__' prefix) macros appropriately. 31 */ 32 33#ifndef _SYS__ENDIAN_H_ 34#define _SYS__ENDIAN_H_ 35 36#include <sys/_types.h> 37 38#define __FROM_SYS__ENDIAN 39#include <machine/endian.h> 40#undef __FROM_SYS__ENDIAN 41 42#define _LITTLE_ENDIAN 1234 43#define _BIG_ENDIAN 4321 44#define _PDP_ENDIAN 3412 45 46/* Note that these macros evaluate their arguments several times. */ 47 48#define __swap16gen(x) \ 49 (__uint16_t)(((__uint16_t)(x) & 0xffU) << 8 | ((__uint16_t)(x) & 0xff00U) >> 8) 50 51#define __swap32gen(x) \ 52 (__uint32_t)(((__uint32_t)(x) & 0xff) << 24 | \ 53 ((__uint32_t)(x) & 0xff00) << 8 | ((__uint32_t)(x) & 0xff0000) >> 8 |\ 54 ((__uint32_t)(x) & 0xff000000) >> 24) 55 56#define __swap64gen(x) \ 57 (__uint64_t)((((__uint64_t)(x) & 0xff) << 56) | \ 58 ((__uint64_t)(x) & 0xff00ULL) << 40 | \ 59 ((__uint64_t)(x) & 0xff0000ULL) << 24 | \ 60 ((__uint64_t)(x) & 0xff000000ULL) << 8 | \ 61 ((__uint64_t)(x) & 0xff00000000ULL) >> 8 | \ 62 ((__uint64_t)(x) & 0xff0000000000ULL) >> 24 | \ 63 ((__uint64_t)(x) & 0xff000000000000ULL) >> 40 | \ 64 ((__uint64_t)(x) & 0xff00000000000000ULL) >> 56) 65 66#ifndef __HAVE_MD_SWAP 67static __inline __uint16_t 68__swap16md(__uint16_t x) 69{ 70 return (__swap16gen(x)); 71} 72 73static __inline __uint32_t 74__swap32md(__uint32_t x) 75{ 76 return (__swap32gen(x)); 77} 78 79static __inline __uint64_t 80__swap64md(__uint64_t x) 81{ 82 return (__swap64gen(x)); 83} 84#endif 85 86#define __swap16(x) \ 87 (__uint16_t)(__builtin_constant_p(x) ? __swap16gen(x) : __swap16md(x)) 88#define __swap32(x) \ 89 (__uint32_t)(__builtin_constant_p(x) ? __swap32gen(x) : __swap32md(x)) 90#define __swap64(x) \ 91 (__uint64_t)(__builtin_constant_p(x) ? __swap64gen(x) : __swap64md(x)) 92 93#if _BYTE_ORDER == _LITTLE_ENDIAN 94 95#define _QUAD_HIGHWORD 1 96#define _QUAD_LOWWORD 0 97 98#define __htobe16 __swap16 99#define __htobe32 __swap32 100#define __htobe64 __swap64 101#define __htole16(x) ((__uint16_t)(x)) 102#define __htole32(x) ((__uint32_t)(x)) 103#define __htole64(x) ((__uint64_t)(x)) 104 105#ifdef _KERNEL 106#ifdef __HAVE_MD_SWAPIO 107 108#define __bemtoh16(_x) __mswap16(_x) 109#define __bemtoh32(_x) __mswap32(_x) 110#define __bemtoh64(_x) __mswap64(_x) 111 112#define __htobem16(_x, _v) __swapm16((_x), (_v)) 113#define __htobem32(_x, _v) __swapm32((_x), (_v)) 114#define __htobem64(_x, _v) __swapm64((_x), (_v)) 115 116#endif /* __HAVE_MD_SWAPIO */ 117#endif /* _KERNEL */ 118#endif /* _BYTE_ORDER == _LITTLE_ENDIAN */ 119 120#if _BYTE_ORDER == _BIG_ENDIAN 121 122#define _QUAD_HIGHWORD 0 123#define _QUAD_LOWWORD 1 124 125#define __htobe16(x) ((__uint16_t)(x)) 126#define __htobe32(x) ((__uint32_t)(x)) 127#define __htobe64(x) ((__uint64_t)(x)) 128#define __htole16 __swap16 129#define __htole32 __swap32 130#define __htole64 __swap64 131 132#ifdef _KERNEL 133#ifdef __HAVE_MD_SWAPIO 134 135#define __lemtoh16(_x) __mswap16(_x) 136#define __lemtoh32(_x) __mswap32(_x) 137#define __lemtoh64(_x) __mswap64(_x) 138 139#define __htolem16(_x, _v) __swapm16((_x), (_v)) 140#define __htolem32(_x, _v) __swapm32((_x), (_v)) 141#define __htolem64(_x, _v) __swapm64((_x), (_v)) 142 143#endif /* __HAVE_MD_SWAPIO */ 144#endif /* _KERNEL */ 145#endif /* _BYTE_ORDER == _BIG_ENDIAN */ 146 147 148#ifdef _KERNEL 149/* 150 * Fill in the __hto[bl]em{16,32,64} and __[bl]emtoh{16,32,64} macros 151 * that haven't been defined yet 152 */ 153 154#ifndef __bemtoh16 155#define __bemtoh16(_x) __htobe16(*(__uint16_t *)(_x)) 156#define __bemtoh32(_x) __htobe32(*(__uint32_t *)(_x)) 157#define __bemtoh64(_x) __htobe64(*(__uint64_t *)(_x)) 158#endif 159 160#ifndef __htobem16 161#define __htobem16(_x, _v) (*(__uint16_t *)(_x) = __htobe16(_v)) 162#define __htobem32(_x, _v) (*(__uint32_t *)(_x) = __htobe32(_v)) 163#define __htobem64(_x, _v) (*(__uint64_t *)(_x) = __htobe64(_v)) 164#endif 165 166#ifndef __lemtoh16 167#define __lemtoh16(_x) __htole16(*(__uint16_t *)(_x)) 168#define __lemtoh32(_x) __htole32(*(__uint32_t *)(_x)) 169#define __lemtoh64(_x) __htole64(*(__uint64_t *)(_x)) 170#endif 171 172#ifndef __htolem16 173#define __htolem16(_x, _v) (*(__uint16_t *)(_x) = __htole16(_v)) 174#define __htolem32(_x, _v) (*(__uint32_t *)(_x) = __htole32(_v)) 175#define __htolem64(_x, _v) (*(__uint64_t *)(_x) = __htole64(_v)) 176#endif 177#endif /* _KERNEL */ 178 179#endif /* _SYS__ENDIAN_H_ */ 180