LCOV - code coverage report
Current view: top level - ccan/endian - endian.h (source / functions) Hit Total Coverage
Test: skiboot.info Lines: 24 24 100.0 %
Date: 2024-09-10 18:37:41 Functions: 12 12 100.0 %
Branches: 0 0 -

           Branch data     Line data    Source code
       1                 :            : /* CC0 (Public domain) - see LICENSE file for details */
       2                 :            : #ifndef CCAN_ENDIAN_H
       3                 :            : #define CCAN_ENDIAN_H
       4                 :            : #include <stdint.h>
       5                 :            : #include "config.h"
       6                 :            : 
       7                 :            : /**
       8                 :            :  * BSWAP_16 - reverse bytes in a constant uint16_t value.
       9                 :            :  * @val: constant value whose bytes to swap.
      10                 :            :  *
      11                 :            :  * Designed to be usable in constant-requiring initializers.
      12                 :            :  *
      13                 :            :  * Example:
      14                 :            :  *      struct mystruct {
      15                 :            :  *              char buf[BSWAP_16(0x1234)];
      16                 :            :  *      };
      17                 :            :  */
      18                 :            : #define BSWAP_16(val)                           \
      19                 :            :         ((((uint16_t)(val) & 0x00ff) << 8)    \
      20                 :            :          | (((uint16_t)(val) & 0xff00) >> 8))
      21                 :            : 
      22                 :            : /**
      23                 :            :  * BSWAP_32 - reverse bytes in a constant uint32_t value.
      24                 :            :  * @val: constant value whose bytes to swap.
      25                 :            :  *
      26                 :            :  * Designed to be usable in constant-requiring initializers.
      27                 :            :  *
      28                 :            :  * Example:
      29                 :            :  *      struct mystruct {
      30                 :            :  *              char buf[BSWAP_32(0xff000000)];
      31                 :            :  *      };
      32                 :            :  */
      33                 :            : #define BSWAP_32(val)                                   \
      34                 :            :         ((((uint32_t)(val) & 0x000000ff) << 24)               \
      35                 :            :          | (((uint32_t)(val) & 0x0000ff00) << 8)              \
      36                 :            :          | (((uint32_t)(val) & 0x00ff0000) >> 8)              \
      37                 :            :          | (((uint32_t)(val) & 0xff000000) >> 24))
      38                 :            : 
      39                 :            : /**
      40                 :            :  * BSWAP_64 - reverse bytes in a constant uint64_t value.
      41                 :            :  * @val: constantvalue whose bytes to swap.
      42                 :            :  *
      43                 :            :  * Designed to be usable in constant-requiring initializers.
      44                 :            :  *
      45                 :            :  * Example:
      46                 :            :  *      struct mystruct {
      47                 :            :  *              char buf[BSWAP_64(0xff00000000000000ULL)];
      48                 :            :  *      };
      49                 :            :  */
      50                 :            : #define BSWAP_64(val)                                           \
      51                 :            :         ((((uint64_t)(val) & 0x00000000000000ffULL) << 56)    \
      52                 :            :          | (((uint64_t)(val) & 0x000000000000ff00ULL) << 40)  \
      53                 :            :          | (((uint64_t)(val) & 0x0000000000ff0000ULL) << 24)  \
      54                 :            :          | (((uint64_t)(val) & 0x00000000ff000000ULL) << 8)   \
      55                 :            :          | (((uint64_t)(val) & 0x000000ff00000000ULL) >> 8)   \
      56                 :            :          | (((uint64_t)(val) & 0x0000ff0000000000ULL) >> 24)  \
      57                 :            :          | (((uint64_t)(val) & 0x00ff000000000000ULL) >> 40)  \
      58                 :            :          | (((uint64_t)(val) & 0xff00000000000000ULL) >> 56))
      59                 :            : 
      60                 :            : #if HAVE_BYTESWAP_H
      61                 :            : #include <byteswap.h>
      62                 :            : #else
      63                 :            : /**
      64                 :            :  * bswap_16 - reverse bytes in a uint16_t value.
      65                 :            :  * @val: value whose bytes to swap.
      66                 :            :  *
      67                 :            :  * Example:
      68                 :            :  *      // Output contains "1024 is 4 as two bytes reversed"
      69                 :            :  *      printf("1024 is %u as two bytes reversed\n", bswap_16(1024));
      70                 :            :  */
      71                 :            : static inline uint16_t bswap_16(uint16_t val)
      72                 :            : {
      73                 :            :         return BSWAP_16(val);
      74                 :            : }
      75                 :            : 
      76                 :            : /**
      77                 :            :  * bswap_32 - reverse bytes in a uint32_t value.
      78                 :            :  * @val: value whose bytes to swap.
      79                 :            :  *
      80                 :            :  * Example:
      81                 :            :  *      // Output contains "1024 is 262144 as four bytes reversed"
      82                 :            :  *      printf("1024 is %u as four bytes reversed\n", bswap_32(1024));
      83                 :            :  */
      84                 :            : static inline uint32_t bswap_32(uint32_t val)
      85                 :            : {
      86                 :            :         return BSWAP_32(val);
      87                 :            : }
      88                 :            : #endif /* !HAVE_BYTESWAP_H */
      89                 :            : 
      90                 :            : #if !HAVE_BSWAP_64
      91                 :            : /**
      92                 :            :  * bswap_64 - reverse bytes in a uint64_t value.
      93                 :            :  * @val: value whose bytes to swap.
      94                 :            :  *
      95                 :            :  * Example:
      96                 :            :  *      // Output contains "1024 is 1125899906842624 as eight bytes reversed"
      97                 :            :  *      printf("1024 is %llu as eight bytes reversed\n",
      98                 :            :  *              (unsigned long long)bswap_64(1024));
      99                 :            :  */
     100                 :            : static inline uint64_t bswap_64(uint64_t val)
     101                 :            : {
     102                 :            :         return BSWAP_64(val);
     103                 :            : }
     104                 :            : #endif
     105                 :            : 
     106                 :            : /* Needed for Glibc like endiness check */
     107                 :            : #define __LITTLE_ENDIAN 1234
     108                 :            : #define __BIG_ENDIAN    4321
     109                 :            : 
     110                 :            : /* Sanity check the defines.  We don't handle weird endianness. */
     111                 :            : #if !HAVE_LITTLE_ENDIAN && !HAVE_BIG_ENDIAN
     112                 :            : #error "Unknown endian"
     113                 :            : #elif HAVE_LITTLE_ENDIAN && HAVE_BIG_ENDIAN
     114                 :            : #error "Can't compile for both big and little endian."
     115                 :            : #elif HAVE_LITTLE_ENDIAN
     116                 :            : #ifndef __BYTE_ORDER
     117                 :            : #define __BYTE_ORDER    __LITTLE_ENDIAN
     118                 :            : #elif __BYTE_ORDER != __LITTLE_ENDIAN
     119                 :            : #error "__BYTE_ORDER already defined, but not equal to __LITTLE_ENDIAN"
     120                 :            : #endif
     121                 :            : #elif HAVE_BIG_ENDIAN
     122                 :            : #ifndef __BYTE_ORDER
     123                 :            : #define __BYTE_ORDER    __BIG_ENDIAN
     124                 :            : #elif __BYTE_ORDER != __BIG_ENDIAN
     125                 :            : #error "__BYTE_ORDER already defined, but not equal to __BIG_ENDIAN"
     126                 :            : #endif
     127                 :            : #endif
     128                 :            : 
     129                 :            : 
     130                 :            : #ifdef __CHECKER__
     131                 :            : /* sparse needs forcing to remove bitwise attribute from ccan/short_types */
     132                 :            : #define ENDIAN_CAST __attribute__((force))
     133                 :            : #define ENDIAN_TYPE __attribute__((bitwise))
     134                 :            : #else
     135                 :            : #define ENDIAN_CAST
     136                 :            : #define ENDIAN_TYPE
     137                 :            : #endif
     138                 :            : 
     139                 :            : typedef uint64_t ENDIAN_TYPE leint64_t;
     140                 :            : typedef uint64_t ENDIAN_TYPE beint64_t;
     141                 :            : typedef uint32_t ENDIAN_TYPE leint32_t;
     142                 :            : typedef uint32_t ENDIAN_TYPE beint32_t;
     143                 :            : typedef uint16_t ENDIAN_TYPE leint16_t;
     144                 :            : typedef uint16_t ENDIAN_TYPE beint16_t;
     145                 :            : 
     146                 :            : #if HAVE_LITTLE_ENDIAN
     147                 :            : /**
     148                 :            :  * CPU_TO_LE64 - convert a constant uint64_t value to little-endian
     149                 :            :  * @native: constant to convert
     150                 :            :  */
     151                 :            : #define CPU_TO_LE64(native) ((ENDIAN_CAST leint64_t)(native))
     152                 :            : 
     153                 :            : /**
     154                 :            :  * CPU_TO_LE32 - convert a constant uint32_t value to little-endian
     155                 :            :  * @native: constant to convert
     156                 :            :  */
     157                 :            : #define CPU_TO_LE32(native) ((ENDIAN_CAST leint32_t)(native))
     158                 :            : 
     159                 :            : /**
     160                 :            :  * CPU_TO_LE16 - convert a constant uint16_t value to little-endian
     161                 :            :  * @native: constant to convert
     162                 :            :  */
     163                 :            : #define CPU_TO_LE16(native) ((ENDIAN_CAST leint16_t)(native))
     164                 :            : 
     165                 :            : /**
     166                 :            :  * LE64_TO_CPU - convert a little-endian uint64_t constant
     167                 :            :  * @le_val: little-endian constant to convert
     168                 :            :  */
     169                 :            : #define LE64_TO_CPU(le_val) ((ENDIAN_CAST uint64_t)(le_val))
     170                 :            : 
     171                 :            : /**
     172                 :            :  * LE32_TO_CPU - convert a little-endian uint32_t constant
     173                 :            :  * @le_val: little-endian constant to convert
     174                 :            :  */
     175                 :            : #define LE32_TO_CPU(le_val) ((ENDIAN_CAST uint32_t)(le_val))
     176                 :            : 
     177                 :            : /**
     178                 :            :  * LE16_TO_CPU - convert a little-endian uint16_t constant
     179                 :            :  * @le_val: little-endian constant to convert
     180                 :            :  */
     181                 :            : #define LE16_TO_CPU(le_val) ((ENDIAN_CAST uint16_t)(le_val))
     182                 :            : 
     183                 :            : #else /* ... HAVE_BIG_ENDIAN */
     184                 :            : #define CPU_TO_LE64(native) ((ENDIAN_CAST leint64_t)BSWAP_64(native))
     185                 :            : #define CPU_TO_LE32(native) ((ENDIAN_CAST leint32_t)BSWAP_32(native))
     186                 :            : #define CPU_TO_LE16(native) ((ENDIAN_CAST leint16_t)BSWAP_16(native))
     187                 :            : #define LE64_TO_CPU(le_val) BSWAP_64((ENDIAN_CAST uint64_t)le_val)
     188                 :            : #define LE32_TO_CPU(le_val) BSWAP_32((ENDIAN_CAST uint32_t)le_val)
     189                 :            : #define LE16_TO_CPU(le_val) BSWAP_16((ENDIAN_CAST uint16_t)le_val)
     190                 :            : #endif /* HAVE_BIG_ENDIAN */
     191                 :            : 
     192                 :            : #if HAVE_BIG_ENDIAN
     193                 :            : /**
     194                 :            :  * CPU_TO_BE64 - convert a constant uint64_t value to big-endian
     195                 :            :  * @native: constant to convert
     196                 :            :  */
     197                 :            : #define CPU_TO_BE64(native) ((ENDIAN_CAST beint64_t)(native))
     198                 :            : 
     199                 :            : /**
     200                 :            :  * CPU_TO_BE32 - convert a constant uint32_t value to big-endian
     201                 :            :  * @native: constant to convert
     202                 :            :  */
     203                 :            : #define CPU_TO_BE32(native) ((ENDIAN_CAST beint32_t)(native))
     204                 :            : 
     205                 :            : /**
     206                 :            :  * CPU_TO_BE16 - convert a constant uint16_t value to big-endian
     207                 :            :  * @native: constant to convert
     208                 :            :  */
     209                 :            : #define CPU_TO_BE16(native) ((ENDIAN_CAST beint16_t)(native))
     210                 :            : 
     211                 :            : /**
     212                 :            :  * BE64_TO_CPU - convert a big-endian uint64_t constant
     213                 :            :  * @le_val: big-endian constant to convert
     214                 :            :  */
     215                 :            : #define BE64_TO_CPU(le_val) ((ENDIAN_CAST uint64_t)(le_val))
     216                 :            : 
     217                 :            : /**
     218                 :            :  * BE32_TO_CPU - convert a big-endian uint32_t constant
     219                 :            :  * @le_val: big-endian constant to convert
     220                 :            :  */
     221                 :            : #define BE32_TO_CPU(le_val) ((ENDIAN_CAST uint32_t)(le_val))
     222                 :            : 
     223                 :            : /**
     224                 :            :  * BE16_TO_CPU - convert a big-endian uint16_t constant
     225                 :            :  * @le_val: big-endian constant to convert
     226                 :            :  */
     227                 :            : #define BE16_TO_CPU(le_val) ((ENDIAN_CAST uint16_t)(le_val))
     228                 :            : 
     229                 :            : #else /* ... HAVE_LITTLE_ENDIAN */
     230                 :            : #define CPU_TO_BE64(native) ((ENDIAN_CAST beint64_t)BSWAP_64(native))
     231                 :            : #define CPU_TO_BE32(native) ((ENDIAN_CAST beint32_t)BSWAP_32(native))
     232                 :            : #define CPU_TO_BE16(native) ((ENDIAN_CAST beint16_t)BSWAP_16(native))
     233                 :            : #define BE64_TO_CPU(le_val) BSWAP_64((ENDIAN_CAST uint64_t)le_val)
     234                 :            : #define BE32_TO_CPU(le_val) BSWAP_32((ENDIAN_CAST uint32_t)le_val)
     235                 :            : #define BE16_TO_CPU(le_val) BSWAP_16((ENDIAN_CAST uint16_t)le_val)
     236                 :            : #endif /* HAVE_LITTE_ENDIAN */
     237                 :            : 
     238                 :            : 
     239                 :            : /**
     240                 :            :  * cpu_to_le64 - convert a uint64_t value to little-endian
     241                 :            :  * @native: value to convert
     242                 :            :  */
     243                 :          2 : static inline leint64_t cpu_to_le64(uint64_t native)
     244                 :            : {
     245                 :          2 :         return CPU_TO_LE64(native);
     246                 :            : }
     247                 :            : 
     248                 :            : /**
     249                 :            :  * cpu_to_le32 - convert a uint32_t value to little-endian
     250                 :            :  * @native: value to convert
     251                 :            :  */
     252                 :         40 : static inline leint32_t cpu_to_le32(uint32_t native)
     253                 :            : {
     254                 :         40 :         return CPU_TO_LE32(native);
     255                 :            : }
     256                 :            : 
     257                 :            : /**
     258                 :            :  * cpu_to_le16 - convert a uint16_t value to little-endian
     259                 :            :  * @native: value to convert
     260                 :            :  */
     261                 :       1070 : static inline leint16_t cpu_to_le16(uint16_t native)
     262                 :            : {
     263                 :       1070 :         return CPU_TO_LE16(native);
     264                 :            : }
     265                 :            : 
     266                 :            : /**
     267                 :            :  * le64_to_cpu - convert a little-endian uint64_t value
     268                 :            :  * @le_val: little-endian value to convert
     269                 :            :  */
     270                 :          2 : static inline uint64_t le64_to_cpu(leint64_t le_val)
     271                 :            : {
     272                 :          2 :         return LE64_TO_CPU(le_val);
     273                 :            : }
     274                 :            : 
     275                 :            : /**
     276                 :            :  * le32_to_cpu - convert a little-endian uint32_t value
     277                 :            :  * @le_val: little-endian value to convert
     278                 :            :  */
     279                 :        371 : static inline uint32_t le32_to_cpu(leint32_t le_val)
     280                 :            : {
     281                 :        371 :         return LE32_TO_CPU(le_val);
     282                 :            : }
     283                 :            : 
     284                 :            : /**
     285                 :            :  * le16_to_cpu - convert a little-endian uint16_t value
     286                 :            :  * @le_val: little-endian value to convert
     287                 :            :  */
     288                 :       2241 : static inline uint16_t le16_to_cpu(leint16_t le_val)
     289                 :            : {
     290                 :       2241 :         return LE16_TO_CPU(le_val);
     291                 :            : }
     292                 :            : 
     293                 :            : /**
     294                 :            :  * cpu_to_be64 - convert a uint64_t value to big endian.
     295                 :            :  * @native: value to convert
     296                 :            :  */
     297                 :   15005900 : static inline beint64_t cpu_to_be64(uint64_t native)
     298                 :            : {
     299                 :   15005900 :         return CPU_TO_BE64(native);
     300                 :            : }
     301                 :            : 
     302                 :            : /**
     303                 :            :  * cpu_to_be32 - convert a uint32_t value to big endian.
     304                 :            :  * @native: value to convert
     305                 :            :  */
     306                 :   28693577 : static inline beint32_t cpu_to_be32(uint32_t native)
     307                 :            : {
     308                 :   28693577 :         return CPU_TO_BE32(native);
     309                 :            : }
     310                 :            : 
     311                 :            : /**
     312                 :            :  * cpu_to_be16 - convert a uint16_t value to big endian.
     313                 :            :  * @native: value to convert
     314                 :            :  */
     315                 :   13430909 : static inline beint16_t cpu_to_be16(uint16_t native)
     316                 :            : {
     317                 :   13430909 :         return CPU_TO_BE16(native);
     318                 :            : }
     319                 :            : 
     320                 :            : /**
     321                 :            :  * be64_to_cpu - convert a big-endian uint64_t value
     322                 :            :  * @be_val: big-endian value to convert
     323                 :            :  */
     324                 :  117640649 : static inline uint64_t be64_to_cpu(beint64_t be_val)
     325                 :            : {
     326                 :  117640649 :         return BE64_TO_CPU(be_val);
     327                 :            : }
     328                 :            : 
     329                 :            : /**
     330                 :            :  * be32_to_cpu - convert a big-endian uint32_t value
     331                 :            :  * @be_val: big-endian value to convert
     332                 :            :  */
     333                 :   37449896 : static inline uint32_t be32_to_cpu(beint32_t be_val)
     334                 :            : {
     335                 :   37449869 :         return BE32_TO_CPU(be_val);
     336                 :            : }
     337                 :            : 
     338                 :            : /**
     339                 :            :  * be16_to_cpu - convert a big-endian uint16_t value
     340                 :            :  * @be_val: big-endian value to convert
     341                 :            :  */
     342                 :   21469896 : static inline uint16_t be16_to_cpu(beint16_t be_val)
     343                 :            : {
     344                 :   21469896 :         return BE16_TO_CPU(be_val);
     345                 :            : }
     346                 :            : 
     347                 :            : /* Whichever they include first, they get these definitions. */
     348                 :            : #ifdef CCAN_SHORT_TYPES_H
     349                 :            : /**
     350                 :            :  * be64/be32/be16 - 64/32/16 bit big-endian representation.
     351                 :            :  */
     352                 :            : typedef beint64_t be64;
     353                 :            : typedef beint32_t be32;
     354                 :            : typedef beint16_t be16;
     355                 :            : 
     356                 :            : /**
     357                 :            :  * le64/le32/le16 - 64/32/16 bit little-endian representation.
     358                 :            :  */
     359                 :            : typedef leint64_t le64;
     360                 :            : typedef leint32_t le32;
     361                 :            : typedef leint16_t le16;
     362                 :            : #endif
     363                 :            : #endif /* CCAN_ENDIAN_H */

Generated by: LCOV version 1.14