| 1 |
/* |
/* |
| 2 |
* Stack-less Just-In-Time compiler |
* Stack-less Just-In-Time compiler |
| 3 |
* |
* |
| 4 |
* Copyright 2009-2010 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved. |
* 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 |
* Redistribution and use in source and binary forms, with or without modification, are |
| 7 |
* permitted provided that the following conditions are met: |
* permitted provided that the following conditions are met: |
| 28 |
#define _SLJIT_CONFIG_INTERNAL_H_ |
#define _SLJIT_CONFIG_INTERNAL_H_ |
| 29 |
|
|
| 30 |
/* |
/* |
| 31 |
SLJIT defines the following variables itself depending on the configuration: |
SLJIT defines the following macros depending on the target architecture: |
| 32 |
sljit_b, sljit_ub : signed and unsigned 8 bit byte |
|
| 33 |
sljit_h, sljit_uh : signed and unsigned 16 bit half-word (short) type |
Feature detection (boolean) macros: |
|
sljit_i, sljit_ui : signed and unsigned 32 bit integer type |
|
|
sljit_w, sljit_uw : signed and unsigned machine word, enough to store a pointer (same as intptr_t) |
|
|
SLJIT_CALL : C calling convention for both calling JIT and C callbacks from JIT |
|
| 34 |
SLJIT_32BIT_ARCHITECTURE : 32 bit architecture |
SLJIT_32BIT_ARCHITECTURE : 32 bit architecture |
| 35 |
SLJIT_64BIT_ARCHITECTURE : 64 bit architecture |
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 |
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 |
SLJIT_FLOAT_SHIFT : the shift required to apply when accessing a double array by index |
|
SLJIT_BIG_ENDIAN : big endian architecture |
|
| 38 |
SLJIT_LITTLE_ENDIAN : little endian architecture |
SLJIT_LITTLE_ENDIAN : little endian architecture |
| 39 |
SLJIT_INDIRECT_CALL : see SLJIT_FUNC_OFFSET() |
SLJIT_BIG_ENDIAN : big endian architecture |
| 40 |
SLJIT_W : for defining 64 bit constants on 64 bit architectures (compiler workaround) |
SLJIT_UNALIGNED : allows unaligned memory accesses for non-fpu operations (only!) |
| 41 |
SLJIT_UNALIGNED : allows unaligned memory accesses for integer arithmetic (only!) |
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) \ |
#if !((defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) \ |
| 123 |
|
|
| 124 |
#if !(defined SLJIT_STD_MACROS_DEFINED && SLJIT_STD_MACROS_DEFINED) |
#if !(defined SLJIT_STD_MACROS_DEFINED && SLJIT_STD_MACROS_DEFINED) |
| 125 |
|
|
| 126 |
|
/* These libraries are needed for the macros below. */ |
| 127 |
#include <stdlib.h> |
#include <stdlib.h> |
| 128 |
#include <string.h> |
#include <string.h> |
| 129 |
|
|
| 130 |
/* General libraries: |
#endif /* STD_MACROS_DEFINED */ |
| 131 |
|
|
| 132 |
|
/* General macros: |
| 133 |
Note: SLJIT is designed to be independent from them as possible. |
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: */ |
In release mode (SLJIT_DEBUG is not defined) only the following macros are needed: |
| 136 |
|
*/ |
| 137 |
|
|
| 138 |
/* General allocation. */ |
#ifndef SLJIT_MALLOC |
| 139 |
#define SLJIT_MALLOC(size) malloc(size) |
#define SLJIT_MALLOC(size) malloc(size) |
| 140 |
|
#endif |
| 141 |
|
|
| 142 |
|
#ifndef SLJIT_FREE |
| 143 |
#define SLJIT_FREE(ptr) free(ptr) |
#define SLJIT_FREE(ptr) free(ptr) |
| 144 |
|
#endif |
| 145 |
|
|
| 146 |
|
#ifndef SLJIT_MEMMOVE |
| 147 |
#define SLJIT_MEMMOVE(dest, src, len) memmove(dest, src, len) |
#define SLJIT_MEMMOVE(dest, src, len) memmove(dest, src, len) |
| 148 |
|
#endif |
| 149 |
|
|
| 150 |
#endif /* STD_MACROS_DEFINED */ |
#ifndef SLJIT_ZEROMEM |
| 151 |
|
#define SLJIT_ZEROMEM(dest, len) memset(dest, 0, len) |
| 152 |
|
#endif |
| 153 |
|
|
| 154 |
#if !defined(SLJIT_LIKELY) && !defined(SLJIT_UNLIKELY) |
#if !defined(SLJIT_LIKELY) && !defined(SLJIT_UNLIKELY) |
| 155 |
|
|
| 178 |
#define SLJIT_UNUSED_ARG(arg) (void)arg |
#define SLJIT_UNUSED_ARG(arg) (void)arg |
| 179 |
#endif |
#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 |
#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) |
#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) || (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) |
| 198 |
/* Just call __ARM_NR_cacheflush on Linux. */ |
|
| 199 |
|
/* The __clear_cache() implementation of GCC is a dummy function on PowerPC. */ |
| 200 |
#define SLJIT_CACHE_FLUSH(from, to) \ |
#define SLJIT_CACHE_FLUSH(from, to) \ |
| 201 |
__clear_cache((char*)(from), (char*)(to)) |
ppc_cache_flush((from), (to)) |
| 202 |
#else |
|
| 203 |
/* Not required to implement on archs with unified caches. */ |
#elif (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) || (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) |
| 204 |
|
|
| 205 |
|
/* Not required to implement on archs with unified caches. */ |
| 206 |
#define SLJIT_CACHE_FLUSH(from, to) |
#define SLJIT_CACHE_FLUSH(from, to) |
| 207 |
|
|
| 208 |
|
#else |
| 209 |
|
|
| 210 |
|
/* Calls __ARM_NR_cacheflush on ARM-Linux. */ |
| 211 |
|
#define SLJIT_CACHE_FLUSH(from, to) \ |
| 212 |
|
__clear_cache((char*)(from), (char*)(to)) |
| 213 |
|
|
| 214 |
#endif |
#endif |
| 215 |
|
|
| 216 |
#endif /* !SLJIT_CACHE_FLUSH */ |
#endif /* !SLJIT_CACHE_FLUSH */ |
| 230 |
/* Machine word type. Can encapsulate a pointer. |
/* Machine word type. Can encapsulate a pointer. |
| 231 |
32 bit for 32 bit machines. |
32 bit for 32 bit machines. |
| 232 |
64 bit for 64 bit machines. */ |
64 bit for 64 bit machines. */ |
| 233 |
#if !(defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) && !(defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) |
#if (defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED) |
| 234 |
|
/* Just to have something. */ |
| 235 |
|
#define SLJIT_WORD_SHIFT 0 |
| 236 |
|
typedef unsigned long int sljit_uw; |
| 237 |
|
typedef long int sljit_w; |
| 238 |
|
#elif !(defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) && !(defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) |
| 239 |
#define SLJIT_32BIT_ARCHITECTURE 1 |
#define SLJIT_32BIT_ARCHITECTURE 1 |
| 240 |
#define SLJIT_WORD_SHIFT 2 |
#define SLJIT_WORD_SHIFT 2 |
| 241 |
typedef unsigned int sljit_uw; |
typedef unsigned int sljit_uw; |
| 335 |
#ifndef SLJIT_SSE2 |
#ifndef SLJIT_SSE2 |
| 336 |
|
|
| 337 |
#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) || (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) |
#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) || (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) |
| 338 |
/* Turn on SSE2 support on x86 (operating on doubles). |
/* Turn on SSE2 support on x86. */ |
|
(Better performance than legacy fpu instructions). */ |
|
| 339 |
#define SLJIT_SSE2 1 |
#define SLJIT_SSE2 1 |
| 340 |
|
|
| 341 |
#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) |
#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) |
| 342 |
/* Auto detect SSE2 support using CPUID. |
/* Auto detect SSE2 support using CPUID. |
| 343 |
On 64 bit x86 cpus, sse2 must be present. */ |
On 64 bit x86 cpus, sse2 must be present. */ |
| 344 |
#define SLJIT_SSE2_AUTO 1 |
#define SLJIT_DETECT_SSE2 1 |
| 345 |
#endif |
#endif |
| 346 |
|
|
| 347 |
#endif /* (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) || (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) */ |
#endif /* (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) || (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) */ |
| 362 |
#endif /* !SLJIT_UNALIGNED */ |
#endif /* !SLJIT_UNALIGNED */ |
| 363 |
|
|
| 364 |
#if (defined SLJIT_EXECUTABLE_ALLOCATOR && SLJIT_EXECUTABLE_ALLOCATOR) |
#if (defined SLJIT_EXECUTABLE_ALLOCATOR && SLJIT_EXECUTABLE_ALLOCATOR) |
| 365 |
void* sljit_malloc_exec(sljit_uw size); |
SLJIT_API_FUNC_ATTRIBUTE void* sljit_malloc_exec(sljit_uw size); |
| 366 |
void sljit_free_exec(void* ptr); |
SLJIT_API_FUNC_ATTRIBUTE void sljit_free_exec(void* ptr); |
| 367 |
#define SLJIT_MALLOC_EXEC(size) sljit_malloc_exec(size) |
#define SLJIT_MALLOC_EXEC(size) sljit_malloc_exec(size) |
| 368 |
#define SLJIT_FREE_EXEC(ptr) sljit_free_exec(ptr) |
#define SLJIT_FREE_EXEC(ptr) sljit_free_exec(ptr) |
| 369 |
#endif |
#endif |
| 377 |
/* Feel free to redefine these two macros. */ |
/* Feel free to redefine these two macros. */ |
| 378 |
#ifndef SLJIT_ASSERT |
#ifndef SLJIT_ASSERT |
| 379 |
|
|
| 380 |
|
#define SLJIT_HALT_PROCESS() \ |
| 381 |
|
*((int*)0) = 0 |
| 382 |
|
|
| 383 |
#define SLJIT_ASSERT(x) \ |
#define SLJIT_ASSERT(x) \ |
| 384 |
do { \ |
do { \ |
| 385 |
if (SLJIT_UNLIKELY(!(x))) { \ |
if (SLJIT_UNLIKELY(!(x))) { \ |
| 386 |
printf("Assertion failed at " __FILE__ ":%d\n", __LINE__); \ |
printf("Assertion failed at " __FILE__ ":%d\n", __LINE__); \ |
| 387 |
*((int*)0) = 0; \ |
SLJIT_HALT_PROCESS(); \ |
| 388 |
} \ |
} \ |
| 389 |
} while (0) |
} while (0) |
| 390 |
|
|
| 395 |
#define SLJIT_ASSERT_STOP() \ |
#define SLJIT_ASSERT_STOP() \ |
| 396 |
do { \ |
do { \ |
| 397 |
printf("Should never been reached " __FILE__ ":%d\n", __LINE__); \ |
printf("Should never been reached " __FILE__ ":%d\n", __LINE__); \ |
| 398 |
*((int*)0) = 0; \ |
SLJIT_HALT_PROCESS(); \ |
| 399 |
} while (0) |
} while (0) |
| 400 |
|
|
| 401 |
#endif /* !SLJIT_ASSERT_STOP */ |
#endif /* !SLJIT_ASSERT_STOP */ |
| 412 |
|
|
| 413 |
#endif /* (defined SLJIT_DEBUG && SLJIT_DEBUG) */ |
#endif /* (defined SLJIT_DEBUG && SLJIT_DEBUG) */ |
| 414 |
|
|
| 415 |
|
#ifndef SLJIT_COMPILE_ASSERT |
| 416 |
|
|
| 417 |
|
/* Should be improved eventually. */ |
| 418 |
|
#define SLJIT_COMPILE_ASSERT(x, description) \ |
| 419 |
|
SLJIT_ASSERT(x) |
| 420 |
|
|
| 421 |
|
#endif /* !SLJIT_COMPILE_ASSERT */ |
| 422 |
|
|
| 423 |
#endif |
#endif |