ObjFW
src/macros.h
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         }
 All Classes Functions Variables