github.com/cilium/cilium@v1.16.2/bpf/include/linux/swab.h (about)

     1  /* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
     2  /* Copyright Authors of the Linux kernel */
     3  #pragma once
     4  
     5  #include <linux/types.h>
     6  
     7  /*
     8   * casts are necessary for constants, because we never know how for sure
     9   * how U/UL/ULL map to __u16, __u32, __u64. At least not in a portable way.
    10   */
    11  #define ___constant_swab16(x) ((__u16)(				\
    12  	(((__u16)(x) & (__u16)0x00ffU) << 8) |			\
    13  	(((__u16)(x) & (__u16)0xff00U) >> 8)))
    14  
    15  #define ___constant_swab32(x) ((__u32)(				\
    16  	(((__u32)(x) & (__u32)0x000000ffUL) << 24) |		\
    17  	(((__u32)(x) & (__u32)0x0000ff00UL) <<  8) |		\
    18  	(((__u32)(x) & (__u32)0x00ff0000UL) >>  8) |		\
    19  	(((__u32)(x) & (__u32)0xff000000UL) >> 24)))
    20  
    21  #define ___constant_swab64(x) ((__u64)(				\
    22  	(((__u64)(x) & (__u64)0x00000000000000ffULL) << 56) |	\
    23  	(((__u64)(x) & (__u64)0x000000000000ff00ULL) << 40) |	\
    24  	(((__u64)(x) & (__u64)0x0000000000ff0000ULL) << 24) |	\
    25  	(((__u64)(x) & (__u64)0x00000000ff000000ULL) <<  8) |	\
    26  	(((__u64)(x) & (__u64)0x000000ff00000000ULL) >>  8) |	\
    27  	(((__u64)(x) & (__u64)0x0000ff0000000000ULL) >> 24) |	\
    28  	(((__u64)(x) & (__u64)0x00ff000000000000ULL) >> 40) |	\
    29  	(((__u64)(x) & (__u64)0xff00000000000000ULL) >> 56)))
    30  
    31  #define ___constant_swahw32(x) ((__u32)(			\
    32  	(((__u32)(x) & (__u32)0x0000ffffUL) << 16) |		\
    33  	(((__u32)(x) & (__u32)0xffff0000UL) >> 16)))
    34  
    35  #define ___constant_swahb32(x) ((__u32)(			\
    36  	(((__u32)(x) & (__u32)0x00ff00ffUL) << 8) |		\
    37  	(((__u32)(x) & (__u32)0xff00ff00UL) >> 8)))
    38  
    39  /*
    40   * Implement the following as inlines, but define the interface using
    41   * macros to allow constant folding when possible:
    42   * ___swab16, ___swab32, ___swab64, ___swahw32, ___swahb32
    43   */
    44  
    45  static __inline__  __u16 __fswab16(__u16 val)
    46  {
    47  #ifdef __HAVE_BUILTIN_BSWAP16__
    48  	return __builtin_bswap16(val);
    49  #elif defined (__arch_swab16)
    50  	return __arch_swab16(val);
    51  #else
    52  	return ___constant_swab16(val);
    53  #endif
    54  }
    55  
    56  static __inline__  __u32 __fswab32(__u32 val)
    57  {
    58  #ifdef __HAVE_BUILTIN_BSWAP32__
    59  	return __builtin_bswap32(val);
    60  #elif defined(__arch_swab32)
    61  	return __arch_swab32(val);
    62  #else
    63  	return ___constant_swab32(val);
    64  #endif
    65  }
    66  
    67  static __inline__  __u64 __fswab64(__u64 val)
    68  {
    69  #ifdef __HAVE_BUILTIN_BSWAP64__
    70  	return __builtin_bswap64(val);
    71  #elif defined (__arch_swab64)
    72  	return __arch_swab64(val);
    73  #elif defined(__SWAB_64_THRU_32__)
    74  	__u32 h = val >> 32;
    75  	__u32 l = val & ((1ULL << 32) - 1);
    76  	return (((__u64)__fswab32(l)) << 32) | ((__u64)(__fswab32(h)));
    77  #else
    78  	return ___constant_swab64(val);
    79  #endif
    80  }
    81  
    82  static __inline__  __u32 __fswahw32(__u32 val)
    83  {
    84  #ifdef __arch_swahw32
    85  	return __arch_swahw32(val);
    86  #else
    87  	return ___constant_swahw32(val);
    88  #endif
    89  }
    90  
    91  static __inline__  __u32 __fswahb32(__u32 val)
    92  {
    93  #ifdef __arch_swahb32
    94  	return __arch_swahb32(val);
    95  #else
    96  	return ___constant_swahb32(val);
    97  #endif
    98  }
    99  
   100  /**
   101   * __swab16 - return a byteswapped 16-bit value
   102   * @x: value to byteswap
   103   */
   104  #define __swab16(x)				\
   105  	(__builtin_constant_p((__u16)(x)) ?	\
   106  	___constant_swab16(x) :			\
   107  	__fswab16(x))
   108  
   109  /**
   110   * __swab32 - return a byteswapped 32-bit value
   111   * @x: value to byteswap
   112   */
   113  #define __swab32(x)				\
   114  	(__builtin_constant_p((__u32)(x)) ?	\
   115  	___constant_swab32(x) :			\
   116  	__fswab32(x))
   117  
   118  /**
   119   * __swab64 - return a byteswapped 64-bit value
   120   * @x: value to byteswap
   121   */
   122  #define __swab64(x)				\
   123  	(__builtin_constant_p((__u64)(x)) ?	\
   124  	___constant_swab64(x) :			\
   125  	__fswab64(x))
   126  
   127  /**
   128   * __swahw32 - return a word-swapped 32-bit value
   129   * @x: value to wordswap
   130   *
   131   * __swahw32(0x12340000) is 0x00001234
   132   */
   133  #define __swahw32(x)				\
   134  	(__builtin_constant_p((__u32)(x)) ?	\
   135  	___constant_swahw32(x) :		\
   136  	__fswahw32(x))
   137  
   138  /**
   139   * __swahb32 - return a high and low byte-swapped 32-bit value
   140   * @x: value to byteswap
   141   *
   142   * __swahb32(0x12345678) is 0x34127856
   143   */
   144  #define __swahb32(x)				\
   145  	(__builtin_constant_p((__u32)(x)) ?	\
   146  	___constant_swahb32(x) :		\
   147  	__fswahb32(x))
   148  
   149  /**
   150   * __swab16p - return a byteswapped 16-bit value from a pointer
   151   * @p: pointer to a naturally-aligned 16-bit value
   152   */
   153  static __inline__ __u16 __swab16p(const __u16 *p)
   154  {
   155  #ifdef __arch_swab16p
   156  	return __arch_swab16p(p);
   157  #else
   158  	return __swab16(*p);
   159  #endif
   160  }
   161  
   162  /**
   163   * __swab32p - return a byteswapped 32-bit value from a pointer
   164   * @p: pointer to a naturally-aligned 32-bit value
   165   */
   166  static __inline__ __u32 __swab32p(const __u32 *p)
   167  {
   168  #ifdef __arch_swab32p
   169  	return __arch_swab32p(p);
   170  #else
   171  	return __swab32(*p);
   172  #endif
   173  }
   174  
   175  /**
   176   * __swab64p - return a byteswapped 64-bit value from a pointer
   177   * @p: pointer to a naturally-aligned 64-bit value
   178   */
   179  static __inline__ __u64 __swab64p(const __u64 *p)
   180  {
   181  #ifdef __arch_swab64p
   182  	return __arch_swab64p(p);
   183  #else
   184  	return __swab64(*p);
   185  #endif
   186  }
   187  
   188  /**
   189   * __swahw32p - return a wordswapped 32-bit value from a pointer
   190   * @p: pointer to a naturally-aligned 32-bit value
   191   *
   192   * See __swahw32() for details of wordswapping.
   193   */
   194  static __inline__ __u32 __swahw32p(const __u32 *p)
   195  {
   196  #ifdef __arch_swahw32p
   197  	return __arch_swahw32p(p);
   198  #else
   199  	return __swahw32(*p);
   200  #endif
   201  }
   202  
   203  /**
   204   * __swahb32p - return a high and low byteswapped 32-bit value from a pointer
   205   * @p: pointer to a naturally-aligned 32-bit value
   206   *
   207   * See __swahb32() for details of high/low byteswapping.
   208   */
   209  static __inline__ __u32 __swahb32p(const __u32 *p)
   210  {
   211  #ifdef __arch_swahb32p
   212  	return __arch_swahb32p(p);
   213  #else
   214  	return __swahb32(*p);
   215  #endif
   216  }
   217  
   218  /**
   219   * __swab16s - byteswap a 16-bit value in-place
   220   * @p: pointer to a naturally-aligned 16-bit value
   221   */
   222  static __inline__ void __swab16s(__u16 *p)
   223  {
   224  #ifdef __arch_swab16s
   225  	__arch_swab16s(p);
   226  #else
   227  	*p = __swab16p(p);
   228  #endif
   229  }
   230  /**
   231   * __swab32s - byteswap a 32-bit value in-place
   232   * @p: pointer to a naturally-aligned 32-bit value
   233   */
   234  static __inline__ void __swab32s(__u32 *p)
   235  {
   236  #ifdef __arch_swab32s
   237  	__arch_swab32s(p);
   238  #else
   239  	*p = __swab32p(p);
   240  #endif
   241  }
   242  
   243  /**
   244   * __swab64s - byteswap a 64-bit value in-place
   245   * @p: pointer to a naturally-aligned 64-bit value
   246   */
   247  static __inline__ void __swab64s(__u64 *p)
   248  {
   249  #ifdef __arch_swab64s
   250  	__arch_swab64s(p);
   251  #else
   252  	*p = __swab64p(p);
   253  #endif
   254  }
   255  
   256  /**
   257   * __swahw32s - wordswap a 32-bit value in-place
   258   * @p: pointer to a naturally-aligned 32-bit value
   259   *
   260   * See __swahw32() for details of wordswapping
   261   */
   262  static __inline__ void __swahw32s(__u32 *p)
   263  {
   264  #ifdef __arch_swahw32s
   265  	__arch_swahw32s(p);
   266  #else
   267  	*p = __swahw32p(p);
   268  #endif
   269  }
   270  
   271  /**
   272   * __swahb32s - high and low byteswap a 32-bit value in-place
   273   * @p: pointer to a naturally-aligned 32-bit value
   274   *
   275   * See __swahb32() for details of high and low byte swapping
   276   */
   277  static __inline__ void __swahb32s(__u32 *p)
   278  {
   279  #ifdef __arch_swahb32s
   280  	__arch_swahb32s(p);
   281  #else
   282  	*p = __swahb32p(p);
   283  #endif
   284  }