1/* 2 * Stack-less Just-In-Time compiler 3 * 4 * Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without modification, are 7 * permitted provided that the following conditions are met: 8 * 9 * 1. Redistributions of source code must retain the above copyright notice, this list of 10 * conditions and the following disclaimer. 11 * 12 * 2. Redistributions in binary form must reproduce the above copyright notice, this list 13 * of conditions and the following disclaimer in the documentation and/or other materials 14 * provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY 17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 19 * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 21 * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 22 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 23 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 24 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 */ 26 27#ifndef _SLJIT_CONFIG_INTERNAL_H_ 28#define _SLJIT_CONFIG_INTERNAL_H_ 29 30/* 31 SLJIT defines the following macros depending on the target architecture: 32 33 Feature detection (boolean) macros: 34 SLJIT_32BIT_ARCHITECTURE : 32 bit architecture 35 SLJIT_64BIT_ARCHITECTURE : 64 bit architecture 36 SLJIT_WORD_SHIFT : the shift required to apply when accessing a sljit_w/sljit_uw array by index 37 SLJIT_FLOAT_SHIFT : the shift required to apply when accessing a double array by index 38 SLJIT_LITTLE_ENDIAN : little endian architecture 39 SLJIT_BIG_ENDIAN : big endian architecture 40 SLJIT_UNALIGNED : allows unaligned memory accesses for non-fpu operations (only!) 41 SLJIT_INDIRECT_CALL : see SLJIT_FUNC_OFFSET() for more information 42 43 Types and useful macros: 44 sljit_b, sljit_ub : signed and unsigned 8 bit byte 45 sljit_h, sljit_uh : signed and unsigned 16 bit half-word (short) type 46 sljit_i, sljit_ui : signed and unsigned 32 bit integer type 47 sljit_w, sljit_uw : signed and unsigned machine word, enough to store a pointer (same as intptr_t) 48 SLJIT_CALL : C calling convention define for both calling JIT form C and C callbacks for JIT 49 SLJIT_W(number) : defining 64 bit constants on 64 bit architectures (compiler independent helper) 50*/ 51 52#if !((defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) \ 53 || (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) \ 54 || (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) \ 55 || (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) \ 56 || (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2) \ 57 || (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) \ 58 || (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) \ 59 || (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) \ 60 || (defined SLJIT_CONFIG_AUTO && SLJIT_CONFIG_AUTO) \ 61 || (defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED)) 62#error "An architecture must be selected" 63#endif 64 65/* Sanity check. */ 66#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) \ 67 + (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) \ 68 + (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) \ 69 + (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) \ 70 + (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2) \ 71 + (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) \ 72 + (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) \ 73 + (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) \ 74 + (defined SLJIT_CONFIG_AUTO && SLJIT_CONFIG_AUTO) \ 75 + (defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED) >= 2 76#error "Multiple architectures are selected" 77#endif 78 79/* Auto select option (requires compiler support) */ 80#if (defined SLJIT_CONFIG_AUTO && SLJIT_CONFIG_AUTO) 81 82#ifndef _WIN32 83 84#if defined(__i386__) || defined(__i386) 85#define SLJIT_CONFIG_X86_32 1 86#elif defined(__x86_64__) 87#define SLJIT_CONFIG_X86_64 1 88#elif defined(__arm__) || defined(__ARM__) 89#ifdef __thumb2__ 90#define SLJIT_CONFIG_ARM_THUMB2 1 91#elif defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7R__) 92#define SLJIT_CONFIG_ARM_V7 1 93#else 94#define SLJIT_CONFIG_ARM_V5 1 95#endif 96#elif defined(__ppc64__) || defined(__powerpc64__) 97#define SLJIT_CONFIG_PPC_64 1 98#elif defined(__ppc__) || defined(__powerpc__) 99#define SLJIT_CONFIG_PPC_32 1 100#elif defined(__mips__) 101#define SLJIT_CONFIG_MIPS_32 1 102#else 103/* Unsupported architecture */ 104#define SLJIT_CONFIG_UNSUPPORTED 1 105#endif 106 107#else /* !_WIN32 */ 108 109#if defined(_M_X64) || defined(__x86_64__) 110#define SLJIT_CONFIG_X86_64 1 111#elif defined(_ARM_) 112#define SLJIT_CONFIG_ARM_V5 1 113#else 114#define SLJIT_CONFIG_X86_32 1 115#endif 116 117#endif /* !WIN32 */ 118#endif /* SLJIT_CONFIG_AUTO */ 119 120#if (defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED) 121#undef SLJIT_EXECUTABLE_ALLOCATOR 122#endif 123 124#if !(defined SLJIT_STD_MACROS_DEFINED && SLJIT_STD_MACROS_DEFINED) 125 126/* These libraries are needed for the macros below. */ 127#include <stdlib.h> 128#include <string.h> 129 130#endif /* STD_MACROS_DEFINED */ 131 132/* General macros: 133 Note: SLJIT is designed to be independent from them as possible. 134 135 In release mode (SLJIT_DEBUG is not defined) only the following macros are needed: 136*/ 137 138#ifndef SLJIT_MALLOC 139#define SLJIT_MALLOC(size) malloc(size) 140#endif 141 142#ifndef SLJIT_FREE 143#define SLJIT_FREE(ptr) free(ptr) 144#endif 145 146#ifndef SLJIT_MEMMOVE 147#define SLJIT_MEMMOVE(dest, src, len) memmove(dest, src, len) 148#endif 149 150#ifndef SLJIT_ZEROMEM 151#define SLJIT_ZEROMEM(dest, len) memset(dest, 0, len) 152#endif 153 154#if !defined(SLJIT_LIKELY) && !defined(SLJIT_UNLIKELY) 155 156#if defined(__GNUC__) && (__GNUC__ >= 3) 157#define SLJIT_LIKELY(x) __builtin_expect((x), 1) 158#define SLJIT_UNLIKELY(x) __builtin_expect((x), 0) 159#else 160#define SLJIT_LIKELY(x) (x) 161#define SLJIT_UNLIKELY(x) (x) 162#endif 163 164#endif /* !defined(SLJIT_LIKELY) && !defined(SLJIT_UNLIKELY) */ 165 166#ifndef SLJIT_INLINE 167/* Inline functions. */ 168#define SLJIT_INLINE __inline 169#endif 170 171#ifndef SLJIT_CONST 172/* Const variables. */ 173#define SLJIT_CONST const 174#endif 175 176#ifndef SLJIT_UNUSED_ARG 177/* Unused arguments. */ 178#define SLJIT_UNUSED_ARG(arg) (void)arg 179#endif 180 181#if (defined SLJIT_CONFIG_STATIC && SLJIT_CONFIG_STATIC) 182/* Static ABI functions. For all-in-one programs. */ 183 184#if defined(__GNUC__) 185/* Disable unused warnings in gcc. */ 186#define SLJIT_API_FUNC_ATTRIBUTE static __attribute__((unused)) 187#else 188#define SLJIT_API_FUNC_ATTRIBUTE static 189#endif 190 191#else 192#define SLJIT_API_FUNC_ATTRIBUTE 193#endif /* (defined SLJIT_CONFIG_STATIC && SLJIT_CONFIG_STATIC) */ 194 195#ifndef SLJIT_CACHE_FLUSH 196 197#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) || (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) 198 199/* Not required to implement on archs with unified caches. */ 200#define SLJIT_CACHE_FLUSH(from, to) 201 202#elif defined __APPLE__ 203 204/* Supported by all macs since Mac OS 10.5. 205 However, it does not work on non-jailbroken iOS devices, 206 although the compilation is successful. */ 207 208#define SLJIT_CACHE_FLUSH(from, to) \ 209 sys_icache_invalidate((char*)(from), (char*)(to) - (char*)(from)) 210 211#elif (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) || (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) 212 213/* The __clear_cache() implementation of GCC is a dummy function on PowerPC. */ 214#define SLJIT_CACHE_FLUSH(from, to) \ 215 ppc_cache_flush((from), (to)) 216 217#else 218 219/* Calls __ARM_NR_cacheflush on ARM-Linux. */ 220#define SLJIT_CACHE_FLUSH(from, to) \ 221 __clear_cache((char*)(from), (char*)(to)) 222 223#endif 224 225#endif /* !SLJIT_CACHE_FLUSH */ 226 227/* 8 bit byte type. */ 228typedef unsigned char sljit_ub; 229typedef signed char sljit_b; 230 231/* 16 bit half-word type. */ 232typedef unsigned short int sljit_uh; 233typedef signed short int sljit_h; 234 235/* 32 bit integer type. */ 236typedef unsigned int sljit_ui; 237typedef signed int sljit_i; 238 239/* Machine word type. Can encapsulate a pointer. 240 32 bit for 32 bit machines. 241 64 bit for 64 bit machines. */ 242#if (defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED) 243/* Just to have something. */ 244#define SLJIT_WORD_SHIFT 0 245typedef unsigned long int sljit_uw; 246typedef long int sljit_w; 247#elif !(defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) && !(defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) 248#define SLJIT_32BIT_ARCHITECTURE 1 249#define SLJIT_WORD_SHIFT 2 250typedef unsigned int sljit_uw; 251typedef int sljit_w; 252#else 253#define SLJIT_64BIT_ARCHITECTURE 1 254#define SLJIT_WORD_SHIFT 3 255#ifdef _WIN32 256typedef unsigned __int64 sljit_uw; 257typedef __int64 sljit_w; 258#else 259typedef unsigned long int sljit_uw; 260typedef long int sljit_w; 261#endif 262#endif 263 264/* Double precision. */ 265#define SLJIT_FLOAT_SHIFT 3 266 267#ifndef SLJIT_W 268 269/* Defining long constants. */ 270#if (defined SLJIT_64BIT_ARCHITECTURE && SLJIT_64BIT_ARCHITECTURE) 271#define SLJIT_W(w) (w##ll) 272#else 273#define SLJIT_W(w) (w) 274#endif 275 276#endif /* !SLJIT_W */ 277 278#ifndef SLJIT_CALL 279 280/* ABI (Application Binary Interface) types. */ 281#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) 282 283#if defined(__GNUC__) 284 285#define SLJIT_CALL __attribute__ ((fastcall)) 286#define SLJIT_X86_32_FASTCALL 1 287 288#elif defined(_WIN32) 289 290#ifdef __BORLANDC__ 291#define SLJIT_CALL __msfastcall 292#else /* __BORLANDC__ */ 293#define SLJIT_CALL __fastcall 294#endif /* __BORLANDC__ */ 295#define SLJIT_X86_32_FASTCALL 1 296 297#else /* defined(_WIN32) */ 298#define SLJIT_CALL __stdcall 299#endif 300 301#else /* Other architectures. */ 302 303#define SLJIT_CALL 304 305#endif /* SLJIT_CONFIG_X86_32 */ 306 307#endif /* !SLJIT_CALL */ 308 309#if !defined(SLJIT_BIG_ENDIAN) && !defined(SLJIT_LITTLE_ENDIAN) 310 311/* These macros are useful for the application. */ 312#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) || (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) 313#define SLJIT_BIG_ENDIAN 1 314 315#elif (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) 316 317#ifdef __MIPSEL__ 318#define SLJIT_LITTLE_ENDIAN 1 319#else 320#define SLJIT_BIG_ENDIAN 1 321#endif 322 323#else 324#define SLJIT_LITTLE_ENDIAN 1 325#endif 326 327#endif /* !defined(SLJIT_BIG_ENDIAN) && !defined(SLJIT_LITTLE_ENDIAN) */ 328 329/* Sanity check. */ 330#if (defined SLJIT_BIG_ENDIAN && SLJIT_BIG_ENDIAN) && (defined SLJIT_LITTLE_ENDIAN && SLJIT_LITTLE_ENDIAN) 331#error "Exactly one endianness must be selected" 332#endif 333 334#if !(defined SLJIT_BIG_ENDIAN && SLJIT_BIG_ENDIAN) && !(defined SLJIT_LITTLE_ENDIAN && SLJIT_LITTLE_ENDIAN) 335#error "Exactly one endianness must be selected" 336#endif 337 338#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) 339/* It seems ppc64 compilers use an indirect addressing for functions. 340 It makes things really complicated. */ 341#define SLJIT_INDIRECT_CALL 1 342#endif 343 344#ifndef SLJIT_SSE2 345 346#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) || (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) 347/* Turn on SSE2 support on x86. */ 348#define SLJIT_SSE2 1 349 350#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) 351/* Auto detect SSE2 support using CPUID. 352 On 64 bit x86 cpus, sse2 must be present. */ 353#define SLJIT_DETECT_SSE2 1 354#endif 355 356#endif /* (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) || (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) */ 357 358#endif /* !SLJIT_SSE2 */ 359 360#ifndef SLJIT_UNALIGNED 361 362#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) \ 363 || (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) \ 364 || (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) \ 365 || (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2) \ 366 || (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) \ 367 || (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) 368#define SLJIT_UNALIGNED 1 369#endif 370 371#endif /* !SLJIT_UNALIGNED */ 372 373#if (defined SLJIT_EXECUTABLE_ALLOCATOR && SLJIT_EXECUTABLE_ALLOCATOR) 374SLJIT_API_FUNC_ATTRIBUTE void* sljit_malloc_exec(sljit_uw size); 375SLJIT_API_FUNC_ATTRIBUTE void sljit_free_exec(void* ptr); 376#define SLJIT_MALLOC_EXEC(size) sljit_malloc_exec(size) 377#define SLJIT_FREE_EXEC(ptr) sljit_free_exec(ptr) 378#endif 379 380#if (defined SLJIT_DEBUG && SLJIT_DEBUG) || (defined SLJIT_VERBOSE && SLJIT_VERBOSE) 381#include <stdio.h> 382#endif 383 384#if (defined SLJIT_DEBUG && SLJIT_DEBUG) 385 386/* Feel free to redefine these two macros. */ 387#ifndef SLJIT_ASSERT 388 389#define SLJIT_HALT_PROCESS() \ 390 *((int*)0) = 0 391 392#define SLJIT_ASSERT(x) \ 393 do { \ 394 if (SLJIT_UNLIKELY(!(x))) { \ 395 printf("Assertion failed at " __FILE__ ":%d\n", __LINE__); \ 396 SLJIT_HALT_PROCESS(); \ 397 } \ 398 } while (0) 399 400#endif /* !SLJIT_ASSERT */ 401 402#ifndef SLJIT_ASSERT_STOP 403 404#define SLJIT_ASSERT_STOP() \ 405 do { \ 406 printf("Should never been reached " __FILE__ ":%d\n", __LINE__); \ 407 SLJIT_HALT_PROCESS(); \ 408 } while (0) 409 410#endif /* !SLJIT_ASSERT_STOP */ 411 412#else /* (defined SLJIT_DEBUG && SLJIT_DEBUG) */ 413 414#undef SLJIT_ASSERT 415#undef SLJIT_ASSERT_STOP 416 417#define SLJIT_ASSERT(x) \ 418 do { } while (0) 419#define SLJIT_ASSERT_STOP() \ 420 do { } while (0) 421 422#endif /* (defined SLJIT_DEBUG && SLJIT_DEBUG) */ 423 424#ifndef SLJIT_COMPILE_ASSERT 425 426/* Should be improved eventually. */ 427#define SLJIT_COMPILE_ASSERT(x, description) \ 428 SLJIT_ASSERT(x) 429 430#endif /* !SLJIT_COMPILE_ASSERT */ 431 432#endif 433