rsys

Basic data structures and low-level features
git clone git://git.meso-star.fr/rsys.git
Log | Files | Refs | README | LICENSE

endianness.h (3783B)


      1 /* Copyright (C) 2013-2023, 2025 Vincent Forest (vaplv@free.fr)
      2  *
      3  * The RSys library is free software: you can redistribute it and/or modify
      4  * it under the terms of the GNU General Public License as published
      5  * by the Free Software Foundation, either version 3 of the License, or
      6  * (at your option) any later version.
      7  *
      8  * The RSys library is distributed in the hope that it will be useful,
      9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
     11  * GNU General Public License for more details.
     12  *
     13  * You should have received a copy of the GNU General Public License
     14  * along with the RSys library. If not, see <http://www.gnu.org/licenses/>. */
     15 
     16 #ifndef ENDIANNESS_H
     17 #define ENDIANNESS_H
     18 
     19 #include "rsys.h"
     20 
     21 #if defined(COMPILER_GCC)
     22   #define BYTE_ORDER __BYTE_ORDER__
     23   #define LITTLE_ENDIAN __ORDER_LITTLE_ENDIAN__
     24   #define BIG_ENDIAN __ORDER_BIG_ENDIAN__
     25   #include <byteswap.h>
     26 #else
     27   #error "Undefined byte ordering macros"
     28 #endif
     29 
     30 static FINLINE uint16_t
     31 byte_swap_16(const uint16_t ui)
     32 {
     33   union { uint16_t ui; uint8_t bytes[2]; } ucast;
     34   ucast.ui = ui;
     35   SWAP(uint8_t, ucast.bytes[0], ucast.bytes[1]);
     36   return ucast.ui;
     37 }
     38 
     39 static FINLINE uint32_t
     40 byte_swap_32(const uint32_t ui)
     41 {
     42   union { uint32_t ui; uint8_t bytes[4]; } ucast;
     43   ucast.ui = ui;
     44   SWAP(uint8_t, ucast.bytes[0], ucast.bytes[3]);
     45   SWAP(uint8_t, ucast.bytes[1], ucast.bytes[2]);
     46   return ucast.ui;
     47 }
     48 static FINLINE uint64_t
     49 byte_swap_64(const uint64_t ui)
     50 {
     51   union { uint64_t ui; uint8_t bytes[8]; } ucast;
     52   ucast.ui = ui;
     53   SWAP(uint8_t, ucast.bytes[0], ucast.bytes[7]);
     54   SWAP(uint8_t, ucast.bytes[1], ucast.bytes[6]);
     55   SWAP(uint8_t, ucast.bytes[2], ucast.bytes[5]);
     56   SWAP(uint8_t, ucast.bytes[3], ucast.bytes[4]);
     57   return ucast.ui;
     58 }
     59 
     60 static FINLINE uint16_t
     61 little_endian_16(const uint16_t ui)
     62 {
     63   union { uint16_t ui; uint8_t bytes[2]; } ucast;
     64   ucast.ui = ui;
     65   return ((uint16_t)ucast.bytes[0] << 0)
     66        | ((uint16_t)ucast.bytes[1] << 8);
     67 }
     68 
     69 static FINLINE uint32_t
     70 little_endian_32(const uint32_t ui)
     71 {
     72   union { uint32_t ui; uint8_t bytes[4]; } ucast;
     73   ucast.ui = ui;
     74   return ((uint32_t)ucast.bytes[0] << 0)
     75        | ((uint32_t)ucast.bytes[1] << 8)
     76        | ((uint32_t)ucast.bytes[2] << 16)
     77        | ((uint32_t)ucast.bytes[3] << 24);
     78 }
     79 
     80 static FINLINE uint64_t
     81 little_endian_64(const uint64_t ui)
     82 {
     83   union { uint64_t ui; uint8_t bytes[8]; } ucast;
     84   ucast.ui = ui;
     85   return ((uint64_t)ucast.bytes[0] << 0)
     86        | ((uint64_t)ucast.bytes[1] << 8)
     87        | ((uint64_t)ucast.bytes[2] << 16)
     88        | ((uint64_t)ucast.bytes[3] << 24)
     89        | ((uint64_t)ucast.bytes[4] << 32)
     90        | ((uint64_t)ucast.bytes[5] << 40)
     91        | ((uint64_t)ucast.bytes[6] << 48)
     92        | ((uint64_t)ucast.bytes[7] << 56);
     93 }
     94 
     95 static FINLINE uint16_t
     96 big_endian_16(const uint16_t ui)
     97 {
     98   union { uint16_t ui; uint8_t bytes[2]; } ucast;
     99   ucast.ui = ui;
    100   return ((uint16_t)ucast.bytes[0] << 8)
    101        | ((uint16_t)ucast.bytes[1] << 0);
    102 }
    103 
    104 static FINLINE uint32_t
    105 big_endian_32(const uint32_t ui)
    106 {
    107   union { uint32_t ui; uint8_t bytes[2]; } ucast;
    108   ucast.ui = ui;
    109   return ((uint32_t)ucast.bytes[0] << 24)
    110        | ((uint32_t)ucast.bytes[1] << 16)
    111        | ((uint32_t)ucast.bytes[2] << 8)
    112        | ((uint32_t)ucast.bytes[3] << 0);
    113 }
    114 
    115 static FINLINE uint64_t
    116 big_endian_64(const uint64_t ui)
    117 {
    118   union { uint64_t ui; uint8_t bytes[8]; } ucast;
    119   ucast.ui = ui;
    120   return ((uint64_t)ucast.bytes[0] << 56)
    121        | ((uint64_t)ucast.bytes[1] << 48)
    122        | ((uint64_t)ucast.bytes[2] << 40)
    123        | ((uint64_t)ucast.bytes[3] << 32)
    124        | ((uint64_t)ucast.bytes[4] << 24)
    125        | ((uint64_t)ucast.bytes[5] << 16)
    126        | ((uint64_t)ucast.bytes[6] << 8)
    127        | ((uint64_t)ucast.bytes[7] << 0);
    128 }
    129 
    130 #endif /* ENDIANNESS_H */