btcs

bitcoin script parser/evaluator/compiler/decompiler
git clone git://jb55.com/btcs
Log | Files | Refs | README | LICENSE

endian.h (9535B)


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