00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #import "objfw-defs.h"
00013
00014 #include <stddef.h>
00015 #include <stdint.h>
00016
00017 #ifdef __GNUC__
00018 # define OF_INLINE inline __attribute__((always_inline))
00019 # define OF_LIKELY(cond) __builtin_expect(!!(cond), 1)
00020 # define OF_UNLIKELY(cond) __builtin_expect(!!(cond), 0)
00021 #else
00022 # define OF_INLINE inline
00023 # define OF_LIKELY(cond) cond
00024 # define OF_UNLIKELY(cond) cond
00025 #endif
00026
00027
00028 #if __BIG_ENDIAN__ || __LITTLE_ENDIAN__
00029 # if __BIG_ENDIAN__ && __LITTLE_ENDIAN__
00030 # error __BIG_ENDIAN__ and __LITTLE_ENDIAN__ defined!
00031 # endif
00032 # undef OF_BIG_ENDIAN
00033 # if __BIG_ENDIAN__
00034 # define OF_BIG_ENDIAN
00035 # endif
00036 #endif
00037
00038 #ifdef __GNUC__
00039 # if defined(__amd64__) || defined(__x86_64__)
00040 # define OF_AMD64_ASM
00041 # elif defined(__i386__)
00042 # define OF_X86_ASM
00043 # elif defined(__ppc__) || defined(__PPC__)
00044 # define OF_PPC_ASM
00045 # elif defined(__arm__) || defined(__ARM__)
00046 # define OF_ARM_ASM
00047 # endif
00048 #endif
00049
00050 #define OF_BSWAP16_CONST(i) \
00051 (((uint16_t)i & UINT16_C(0xFF00)) >> 8 | \
00052 ((uint16_t)i & UINT16_C(0x00FF)) << 8)
00053 #define OF_BSWAP32_CONST(i) \
00054 (((uint32_t)i & UINT32_C(0xFF000000)) >> 24 | \
00055 ((uint32_t)i & UINT32_C(0x00FF0000)) >> 8 | \
00056 ((uint32_t)i & UINT32_C(0x0000FF00)) << 8 | \
00057 ((uint32_t)i & UINT32_C(0x000000FF)) << 24)
00058 #define OF_BSWAP64_CONST(i) \
00059 (((uint64_t)i & UINT64_C(0xFF00000000000000)) >> 56 | \
00060 ((uint64_t)i & UINT64_C(0x00FF000000000000)) >> 40 | \
00061 ((uint64_t)i & UINT64_C(0x0000FF0000000000)) >> 24 | \
00062 ((uint64_t)i & UINT64_C(0x000000FF00000000)) >> 8 | \
00063 ((uint64_t)i & UINT64_C(0x00000000FF000000)) << 8 | \
00064 ((uint64_t)i & UINT64_C(0x0000000000FF0000)) << 24 | \
00065 ((uint64_t)i & UINT64_C(0x000000000000FF00)) << 40 | \
00066 ((uint64_t)i & UINT64_C(0x00000000000000FF)) << 56)
00067
00068 static OF_INLINE uint16_t
00069 OF_BSWAP16_NONCONST(uint16_t i)
00070 {
00071 #if defined(OF_X86_ASM) || defined(OF_AMD64_ASM)
00072 asm("xchgb %h0, %b0" : "=Q"(i) : "0"(i));
00073 #elif defined(OF_PPC_ASM)
00074 asm("lhbrx %0, 0, %1" : "=r"(i) : "r"(&i), "m"(i));
00075 #elif defined(OF_ARM_ASM)
00076 asm("rev16 %0, %0" : "=r"(i) : "0"(i));
00077 #else
00078 i = (i & UINT16_C(0xFF00)) >> 8 |
00079 (i & UINT16_C(0x00FF)) << 8;
00080 #endif
00081 return i;
00082 }
00083
00084 static OF_INLINE uint32_t
00085 OF_BSWAP32_NONCONST(uint32_t i)
00086 {
00087 #if defined(OF_X86_ASM) || defined(OF_AMD64_ASM)
00088 asm("bswap %0" : "=q"(i) : "0"(i));
00089 #elif defined(OF_PPC_ASM)
00090 asm("lwbrx %0, 0, %1" : "=r"(i) : "r"(&i), "m"(i));
00091 #elif defined(OF_ARM_ASM)
00092 asm("rev %0, %0" : "=r"(i) : "0"(i));
00093 #else
00094 i = (i & UINT32_C(0xFF000000)) >> 24 |
00095 (i & UINT32_C(0x00FF0000)) >> 8 |
00096 (i & UINT32_C(0x0000FF00)) << 8 |
00097 (i & UINT32_C(0x000000FF)) << 24;
00098 #endif
00099 return i;
00100 }
00101
00102 static OF_INLINE uint64_t
00103 OF_BSWAP64_NONCONST(uint64_t i)
00104 {
00105 #if defined(OF_AMD64_ASM)
00106 asm("bswap %0" : "=r"(i) : "0"(i));
00107 #elif defined(OF_X86_ASM)
00108 asm("bswap %%eax\n\t"
00109 "bswap %%edx\n\t"
00110 "xchgl %%eax, %%edx" : "=A"(i): "0"(i));
00111 #else
00112 i = (uint64_t)OF_BSWAP32_NONCONST(i & 0xFFFFFFFF) << 32 |
00113 OF_BSWAP32_NONCONST(i >> 32);
00114 #endif
00115 return i;
00116 }
00117
00118 #ifdef __GNUC__
00119 # define OF_BSWAP16(i) \
00120 (__builtin_constant_p(i) ? OF_BSWAP16_CONST(i) : OF_BSWAP16_NONCONST(i))
00121 # define OF_BSWAP32(i) \
00122 (__builtin_constant_p(i) ? OF_BSWAP32_CONST(i) : OF_BSWAP32_NONCONST(i))
00123 # define OF_BSWAP64(i) \
00124 (__builtin_constant_p(i) ? OF_BSWAP64_CONST(i) : OF_BSWAP64_NONCONST(i))
00125 #else
00126 # define OF_BSWAP16(i) OF_BSWAP16_CONST(i)
00127 # define OF_BSWAP32(i) OF_BSWAP32_CONST(i)
00128 # define OF_BSWAP64(i) OF_BSWAP64_CONST(i)
00129 #endif
00130
00131 static OF_INLINE void
00132 OF_BSWAP32_V(uint32_t *buf, size_t len)
00133 {
00134 while (len--) {
00135 *buf = OF_BSWAP32(*buf);
00136 buf++;
00137 }
00138 }
00139
00140 #ifdef OF_BIG_ENDIAN
00141 # define OF_BSWAP16_IF_BE(i) OF_BSWAP16(i)
00142 # define OF_BSWAP32_IF_BE(i) OF_BSWAP32(i)
00143 # define OF_BSWAP64_IF_BE(i) OF_BSWAP64(i)
00144 # define OF_BSWAP16_IF_LE(i) i
00145 # define OF_BSWAP32_IF_LE(i) i
00146 # define OF_BSWAP64_IF_LE(i) i
00147 # define OF_BSWAP32_V_IF_BE(buf, len) OF_BSWAP32_V(buf, len)
00148 #else
00149 # define OF_BSWAP16_IF_BE(i) i
00150 # define OF_BSWAP32_IF_BE(i) i
00151 # define OF_BSWAP64_IF_BE(i) i
00152 # define OF_BSWAP16_IF_LE(i) OF_BSWAP16(i)
00153 # define OF_BSWAP32_IF_LE(i) OF_BSWAP32(i)
00154 # define OF_BSWAP64_IF_LE(i) OF_BSWAP64(i)
00155 # define OF_BSWAP32_V_IF_BE(buf, len)
00156 #endif
00157
00158 #define OF_ROL(val, bits) \
00159 (((val) << (bits)) | ((val) >> (32 - (bits))))
00160
00161 #define OF_HASH_INIT(hash) hash = 0
00162 #define OF_HASH_ADD(hash, byte) \
00163 { \
00164 hash += byte; \
00165 hash += (hash << 10); \
00166 hash ^= (hash >> 6); \
00167 }
00168 #define OF_HASH_FINALIZE(hash) \
00169 { \
00170 hash += (hash << 3); \
00171 hash ^= (hash >> 11); \
00172 hash += (hash << 15); \
00173 }