18dffb485Schristos /* Interface to byteswapping functions. 2*12989c96Schristos Copyright (C) 2006-2024 Free Software Foundation, Inc. 38dffb485Schristos 48dffb485Schristos This file is part of libctf. 58dffb485Schristos 68dffb485Schristos libctf is free software; you can redistribute it and/or modify it under 78dffb485Schristos the terms of the GNU General Public License as published by the Free 88dffb485Schristos Software Foundation; either version 3, or (at your option) any later 98dffb485Schristos version. 108dffb485Schristos 118dffb485Schristos This program is distributed in the hope that it will be useful, but 128dffb485Schristos WITHOUT ANY WARRANTY; without even the implied warranty of 138dffb485Schristos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 148dffb485Schristos See the GNU General Public License for more details. 158dffb485Schristos 168dffb485Schristos You should have received a copy of the GNU General Public License 178dffb485Schristos along with this program; see the file COPYING. If not see 188dffb485Schristos <http://www.gnu.org/licenses/>. */ 198dffb485Schristos 208dffb485Schristos #ifndef _CTF_SWAP_H 218dffb485Schristos #define _CTF_SWAP_H 228dffb485Schristos 238dffb485Schristos #include "config.h" 248dffb485Schristos #include <stdint.h> 254b169a6bSchristos #include <assert.h> 268dffb485Schristos 278dffb485Schristos #ifdef HAVE_BYTESWAP_H 288dffb485Schristos #include <byteswap.h> 298dffb485Schristos #endif /* defined(HAVE_BYTESWAP_H) */ 308dffb485Schristos 318dffb485Schristos /* Provide our own versions of the byteswap functions. */ 328dffb485Schristos 338dffb485Schristos #if !HAVE_DECL_BSWAP_16 348dffb485Schristos static inline uint16_t 358dffb485Schristos bswap_16 (uint16_t v) 368dffb485Schristos { 378dffb485Schristos return ((v >> 8) & 0xff) | ((v & 0xff) << 8); 388dffb485Schristos } 398dffb485Schristos #endif /* !HAVE_DECL_BSWAP16 */ 408dffb485Schristos 418dffb485Schristos #if !HAVE_DECL_BSWAP_32 428dffb485Schristos static inline uint32_t 438dffb485Schristos bswap_32 (uint32_t v) 448dffb485Schristos { 458dffb485Schristos return ( ((v & 0xff000000) >> 24) 468dffb485Schristos | ((v & 0x00ff0000) >> 8) 478dffb485Schristos | ((v & 0x0000ff00) << 8) 488dffb485Schristos | ((v & 0x000000ff) << 24)); 498dffb485Schristos } 508dffb485Schristos #endif /* !HAVE_DECL_BSWAP32 */ 518dffb485Schristos 528dffb485Schristos #if !HAVE_DECL_BSWAP_64 538dffb485Schristos static inline uint64_t 548dffb485Schristos bswap_64 (uint64_t v) 558dffb485Schristos { 568dffb485Schristos return ( ((v & 0xff00000000000000ULL) >> 56) 578dffb485Schristos | ((v & 0x00ff000000000000ULL) >> 40) 588dffb485Schristos | ((v & 0x0000ff0000000000ULL) >> 24) 598dffb485Schristos | ((v & 0x000000ff00000000ULL) >> 8) 608dffb485Schristos | ((v & 0x00000000ff000000ULL) << 8) 618dffb485Schristos | ((v & 0x0000000000ff0000ULL) << 24) 628dffb485Schristos | ((v & 0x000000000000ff00ULL) << 40) 638dffb485Schristos | ((v & 0x00000000000000ffULL) << 56)); 648dffb485Schristos } 658dffb485Schristos #endif /* !HAVE_DECL_BSWAP64 */ 668dffb485Schristos 674b169a6bSchristos /* < C11? define away static assertions. */ 684b169a6bSchristos 694b169a6bSchristos #if !defined (__STDC_VERSION__) || __STDC_VERSION__ < 201112L 70*12989c96Schristos #ifndef _Static_assert 714b169a6bSchristos #define _Static_assert(cond, err) 724b169a6bSchristos #endif 73*12989c96Schristos #endif 744b169a6bSchristos 754b169a6bSchristos /* Swap the endianness of something. */ 764b169a6bSchristos 774b169a6bSchristos #define swap_thing(x) \ 784b169a6bSchristos do \ 794b169a6bSchristos { \ 804b169a6bSchristos _Static_assert (sizeof (x) == 1 || (sizeof (x) % 2 == 0 \ 814b169a6bSchristos && sizeof (x) <= 8), \ 824b169a6bSchristos "Invalid size, update endianness code"); \ 834b169a6bSchristos switch (sizeof (x)) { \ 844b169a6bSchristos case 2: x = bswap_16 (x); break; \ 854b169a6bSchristos case 4: x = bswap_32 (x); break; \ 864b169a6bSchristos case 8: x = bswap_64 (x); break; \ 874b169a6bSchristos case 1: /* Nothing needs doing */ \ 884b169a6bSchristos break; \ 894b169a6bSchristos } \ 904b169a6bSchristos } \ 914b169a6bSchristos while (0); 924b169a6bSchristos 934b169a6bSchristos 948dffb485Schristos #endif /* !defined(_CTF_SWAP_H) */ 95