ObjFW
|
00001 /* 00002 * Copyright (c) 2008, 2009, 2010, 2011 00003 * Jonathan Schleifer <js@webkeks.org> 00004 * 00005 * All rights reserved. 00006 * 00007 * This file is part of ObjFW. It may be distributed under the terms of the 00008 * Q Public License 1.0, which can be found in the file LICENSE.QPL included in 00009 * the packaging of this file. 00010 * 00011 * Alternatively, it may be distributed under the terms of the GNU General 00012 * Public License, either version 2 or 3, which can be found in the file 00013 * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this 00014 * file. 00015 */ 00016 00017 #import "objfw-defs.h" 00018 00019 #ifndef __STDC_LIMIT_MACROS 00020 # define __STDC_LIMIT_MACROS 00021 #endif 00022 #ifndef __STDC_CONSTANT_MACROS 00023 # define __STDC_CONSTANT_MACROS 00024 #endif 00025 00026 #include <stddef.h> 00027 #include <stdint.h> 00028 00029 #ifdef _PSP 00030 # define INTMAX_MAX LONG_LONG_MAX 00031 #endif 00032 00033 #ifdef __GNUC__ 00034 # define OF_INLINE inline __attribute__((always_inline)) 00035 # define OF_LIKELY(cond) __builtin_expect(!!(cond), 1) 00036 # define OF_UNLIKELY(cond) __builtin_expect(!!(cond), 0) 00037 # define OF_CONST_FUNC __attribute__((const)) 00038 #else 00039 # define OF_INLINE inline 00040 # define OF_LIKELY(cond) cond 00041 # define OF_UNLIKELY(cond) cond 00042 # define OF_CONST_FUNC 00043 #endif 00044 00045 /* Required to build universal binaries on OS X */ 00046 #if __BIG_ENDIAN__ || __LITTLE_ENDIAN__ 00047 # if __BIG_ENDIAN__ && __LITTLE_ENDIAN__ 00048 # error __BIG_ENDIAN__ and __LITTLE_ENDIAN__ defined! 00049 # endif 00050 # undef OF_BIG_ENDIAN 00051 # if __BIG_ENDIAN__ 00052 # define OF_BIG_ENDIAN 00053 # endif 00054 #endif 00055 00056 #ifdef __GNUC__ 00057 # if defined(__amd64__) || defined(__x86_64__) 00058 # define OF_AMD64_ASM 00059 # elif defined(__i386__) 00060 # define OF_X86_ASM 00061 # elif defined(__ppc__) || defined(__PPC__) 00062 # define OF_PPC_ASM 00063 # elif defined(__arm__) || defined(__ARM__) 00064 # define OF_ARM_ASM 00065 # endif 00066 #endif 00067 00068 #ifndef _WIN32 00069 # define OF_PATH_DELIM '/' 00070 #else 00071 # define OF_PATH_DELIM '\\' 00072 #endif 00073 00074 #define OF_IVAR_OFFSET(ivar) ((intptr_t)&ivar - (intptr_t)self) 00075 #define OF_GETTER(ivar, atomic) \ 00076 return objc_getProperty(self, _cmd, OF_IVAR_OFFSET(ivar), atomic); 00077 #define OF_SETTER(ivar, value, atomic, copy) \ 00078 objc_setProperty(self, _cmd, OF_IVAR_OFFSET(ivar), value, atomic, copy); 00079 00080 static OF_INLINE uint16_t OF_CONST_FUNC 00081 of_bswap16_const(uint16_t i) 00082 { 00083 return (i & UINT16_C(0xFF00)) >> 8 | 00084 (i & UINT16_C(0x00FF)) << 8; 00085 } 00086 00087 static OF_INLINE uint32_t OF_CONST_FUNC 00088 of_bswap32_const(uint32_t i) 00089 { 00090 return (i & UINT32_C(0xFF000000)) >> 24 | 00091 (i & UINT32_C(0x00FF0000)) >> 8 | 00092 (i & UINT32_C(0x0000FF00)) << 8 | 00093 (i & UINT32_C(0x000000FF)) << 24; 00094 } 00095 00096 static OF_INLINE uint64_t OF_CONST_FUNC 00097 of_bswap64_const(uint64_t i) 00098 { 00099 return (i & UINT64_C(0xFF00000000000000)) >> 56 | 00100 (i & UINT64_C(0x00FF000000000000)) >> 40 | 00101 (i & UINT64_C(0x0000FF0000000000)) >> 24 | 00102 (i & UINT64_C(0x000000FF00000000)) >> 8 | 00103 (i & UINT64_C(0x00000000FF000000)) << 8 | 00104 (i & UINT64_C(0x0000000000FF0000)) << 24 | 00105 (i & UINT64_C(0x000000000000FF00)) << 40 | 00106 (i & UINT64_C(0x00000000000000FF)) << 56; 00107 } 00108 00109 static OF_INLINE uint16_t OF_CONST_FUNC 00110 of_bswap16_nonconst(uint16_t i) 00111 { 00112 #if defined(OF_X86_ASM) || defined(OF_AMD64_ASM) 00113 __asm__ ( 00114 "xchgb %h0, %b0" 00115 : "=Q"(i) 00116 : "0"(i) 00117 ); 00118 #elif defined(OF_PPC_ASM) 00119 __asm__ ( 00120 "lhbrx %0, 0, %1" 00121 : "=r"(i) 00122 : "r"(&i), "m"(i) 00123 ); 00124 #elif defined(OF_ARM_ASM) 00125 __asm__ ( 00126 "rev16 %0, %0" 00127 : "=r"(i) 00128 : "0"(i) 00129 ); 00130 #else 00131 i = (i & UINT16_C(0xFF00)) >> 8 | 00132 (i & UINT16_C(0x00FF)) << 8; 00133 #endif 00134 return i; 00135 } 00136 00137 static OF_INLINE uint32_t OF_CONST_FUNC 00138 of_bswap32_nonconst(uint32_t i) 00139 { 00140 #if defined(OF_X86_ASM) || defined(OF_AMD64_ASM) 00141 __asm__ ( 00142 "bswap %0" 00143 : "=q"(i) 00144 : "0"(i) 00145 ); 00146 #elif defined(OF_PPC_ASM) 00147 __asm__ ( 00148 "lwbrx %0, 0, %1" 00149 : "=r"(i) 00150 : "r"(&i), "m"(i) 00151 ); 00152 #elif defined(OF_ARM_ASM) 00153 __asm__ ( 00154 "rev %0, %0" 00155 : "=r"(i) 00156 : "0"(i) 00157 ); 00158 #else 00159 i = (i & UINT32_C(0xFF000000)) >> 24 | 00160 (i & UINT32_C(0x00FF0000)) >> 8 | 00161 (i & UINT32_C(0x0000FF00)) << 8 | 00162 (i & UINT32_C(0x000000FF)) << 24; 00163 #endif 00164 return i; 00165 } 00166 00167 static OF_INLINE uint64_t OF_CONST_FUNC 00168 of_bswap64_nonconst(uint64_t i) 00169 { 00170 #if defined(OF_AMD64_ASM) 00171 __asm__ ( 00172 "bswap %0" 00173 : "=r"(i) 00174 : "0"(i) 00175 ); 00176 #elif defined(OF_X86_ASM) 00177 __asm__ ( 00178 "bswap %%eax\n\t" 00179 "bswap %%edx\n\t" 00180 "xchgl %%eax, %%edx" 00181 : "=A"(i) 00182 : "0"(i) 00183 ); 00184 #else 00185 i = (uint64_t)of_bswap32_nonconst((uint32_t)(i & 0xFFFFFFFF)) << 32 | 00186 of_bswap32_nonconst((uint32_t)(i >> 32)); 00187 #endif 00188 return i; 00189 } 00190 00191 #ifdef __GNUC__ 00192 # define of_bswap16(i) \ 00193 (__builtin_constant_p(i) ? of_bswap16_const(i) : of_bswap16_nonconst(i)) 00194 # define of_bswap32(i) \ 00195 (__builtin_constant_p(i) ? of_bswap32_const(i) : of_bswap32_nonconst(i)) 00196 # define of_bswap64(i) \ 00197 (__builtin_constant_p(i) ? of_bswap64_const(i) : of_bswap64_nonconst(i)) 00198 #else 00199 # define of_bswap16(i) of_bswap16_const(i) 00200 # define of_bswap32(i) of_bswap32_const(i) 00201 # define of_bswap64(i) of_bswap64_const(i) 00202 #endif 00203 00204 static OF_INLINE void 00205 of_bswap32_vec(uint32_t *buf, size_t len) 00206 { 00207 while (len--) { 00208 *buf = of_bswap32(*buf); 00209 buf++; 00210 } 00211 } 00212 00213 #ifdef OF_BIG_ENDIAN 00214 # define of_bswap16_if_be(i) of_bswap16(i) 00215 # define of_bswap32_if_be(i) of_bswap32(i) 00216 # define of_bswap64_if_be(i) of_bswap64(i) 00217 # define of_bswap16_if_le(i) (i) 00218 # define of_bswap32_if_le(i) (i) 00219 # define of_bswap64_if_le(i) (i) 00220 # define of_bswap32_vec_if_be(buf, len) of_bswap32_vec(buf, len) 00221 #else 00222 # define of_bswap16_if_be(i) (i) 00223 # define of_bswap32_if_be(i) (i) 00224 # define of_bswap64_if_be(i) (i) 00225 # define of_bswap16_if_le(i) of_bswap16(i) 00226 # define of_bswap32_if_le(i) of_bswap32(i) 00227 # define of_bswap64_if_le(i) of_bswap64(i) 00228 # define of_bswap32_vec_if_be(buf, len) 00229 #endif 00230 00231 /* 00232 * We define it here and not in objfw-defs.h, as it would be theoretically 00233 * possible to build a universal binary for Mac OS X and iOS. 00234 */ 00235 #if defined(__MACH__) && defined(__arm__) 00236 # define OF_IOS 00237 #endif 00238 00239 #define OF_ROL(val, bits) \ 00240 (((val) << ((bits) % (sizeof(val) * 8))) | \ 00241 (val) >> (sizeof(val) * 8 - ((bits) % (sizeof(val) * 8)))) 00242 00243 #define OF_HASH_INIT(hash) hash = 0 00244 #define OF_HASH_ADD(hash, byte) \ 00245 { \ 00246 hash += (uint8_t)byte; \ 00247 hash += (hash << 10); \ 00248 hash ^= (hash >> 6); \ 00249 } 00250 #define OF_HASH_FINALIZE(hash) \ 00251 { \ 00252 hash += (hash << 3); \ 00253 hash ^= (hash >> 11); \ 00254 hash += (hash << 15); \ 00255 }