1/*
2 * Stack-less Just-In-Time compiler
3 *
4 * Copyright 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#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \
31 || (defined SLJIT_DEBUG && SLJIT_DEBUG && (!defined(SLJIT_ASSERT) || !defined(SLJIT_UNREACHABLE)))
32#include <stdio.h>
33#endif
34
35#if (defined SLJIT_DEBUG && SLJIT_DEBUG \
36 && (!defined(SLJIT_ASSERT) || !defined(SLJIT_UNREACHABLE) || !defined(SLJIT_HALT_PROCESS)))
37#include <stdlib.h>
38#endif
39
40#ifdef __cplusplus
41extern "C" {
42#endif
43
44/*
45 SLJIT defines the following architecture dependent types and macros:
46
47 Types:
48 sljit_s8, sljit_u8 : signed and unsigned 8 bit integer type
49 sljit_s16, sljit_u16 : signed and unsigned 16 bit integer type
50 sljit_s32, sljit_u32 : signed and unsigned 32 bit integer type
51 sljit_sw, sljit_uw : signed and unsigned machine word, enough to store a pointer
52 sljit_p : unsgined pointer value (usually the same as sljit_uw, but
53 some 64 bit ABIs may use 32 bit pointers)
54 sljit_f32 : 32 bit single precision floating point value
55 sljit_f64 : 64 bit double precision floating point value
56
57 Macros for feature detection (boolean):
58 SLJIT_32BIT_ARCHITECTURE : 32 bit architecture
59 SLJIT_64BIT_ARCHITECTURE : 64 bit architecture
60 SLJIT_LITTLE_ENDIAN : little endian architecture
61 SLJIT_BIG_ENDIAN : big endian architecture
62 SLJIT_UNALIGNED : unaligned memory accesses for non-fpu operations are supported
63 SLJIT_FPU_UNALIGNED : unaligned memory accesses for fpu operations are supported
64 SLJIT_INDIRECT_CALL : see SLJIT_FUNC_ADDR() for more information
65
66 Constants:
67 SLJIT_NUMBER_OF_REGISTERS : number of available registers
68 SLJIT_NUMBER_OF_SCRATCH_REGISTERS : number of available scratch registers
69 SLJIT_NUMBER_OF_SAVED_REGISTERS : number of available saved registers
70 SLJIT_NUMBER_OF_FLOAT_REGISTERS : number of available floating point registers
71 SLJIT_NUMBER_OF_SCRATCH_FLOAT_REGISTERS : number of available floating point scratch registers
72 SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS : number of available floating point saved registers
73 SLJIT_WORD_SHIFT : the shift required to apply when accessing a sljit_sw/sljit_uw array by index
74 SLJIT_F32_SHIFT : the shift required to apply when accessing
75 a single precision floating point array by index
76 SLJIT_F64_SHIFT : the shift required to apply when accessing
77 a double precision floating point array by index
78 SLJIT_PREF_SHIFT_REG : x86 systems prefers ecx for shifting by register
79 the scratch register index of ecx is stored in this variable
80 SLJIT_LOCALS_OFFSET : local space starting offset (SLJIT_SP + SLJIT_LOCALS_OFFSET)
81 SLJIT_RETURN_ADDRESS_OFFSET : a return instruction always adds this offset to the return address
82
83 Other macros:
84 SLJIT_FUNC : calling convention attribute for both calling JIT from C and C calling back from JIT
85 SLJIT_W(number) : defining 64 bit constants on 64 bit architectures (platform independent helper)
86*/
87
88/*****************/
89/* Sanity check. */
90/*****************/
91
92#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) \
93 + (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) \
94 + (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) \
95 + (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) \
96 + (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2) \
97 + (defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64) \
98 + (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) \
99 + (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) \
100 + (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) \
101 + (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64) \
102 + (defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32) \
103 + (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64) \
104 + (defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X) \
105 + (defined SLJIT_CONFIG_AUTO && SLJIT_CONFIG_AUTO) \
106 + (defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED) >= 2
107#error "Multiple architectures are selected"
108#endif
109
110#if !(defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) \
111 && !(defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) \
112 && !(defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) \
113 && !(defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) \
114 && !(defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2) \
115 && !(defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64) \
116 && !(defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) \
117 && !(defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) \
118 && !(defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) \
119 && !(defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64) \
120 && !(defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32) \
121 && !(defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64) \
122 && !(defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X) \
123 && !(defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED) \
124 && !(defined SLJIT_CONFIG_AUTO && SLJIT_CONFIG_AUTO)
125#if defined SLJIT_CONFIG_AUTO && !SLJIT_CONFIG_AUTO
126#error "An architecture must be selected"
127#else /* SLJIT_CONFIG_AUTO */
128#define SLJIT_CONFIG_AUTO 1
129#endif /* !SLJIT_CONFIG_AUTO */
130#endif /* !SLJIT_CONFIG */
131
132/********************************************************/
133/* Automatic CPU detection (requires compiler support). */
134/********************************************************/
135
136#if (defined SLJIT_CONFIG_AUTO && SLJIT_CONFIG_AUTO)
137
138#ifndef _WIN32
139
140#if defined(__i386__) || defined(__i386)
141#define SLJIT_CONFIG_X86_32 1
142#elif defined(__x86_64__)
143#define SLJIT_CONFIG_X86_64 1
144#elif defined(__arm__) || defined(__ARM__)
145#ifdef __thumb2__
146#define SLJIT_CONFIG_ARM_THUMB2 1
147#elif defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7R__)
148#define SLJIT_CONFIG_ARM_V7 1
149#else
150#define SLJIT_CONFIG_ARM_V5 1
151#endif
152#elif defined (__aarch64__)
153#define SLJIT_CONFIG_ARM_64 1
154#elif defined(__ppc64__) || defined(__powerpc64__) || (defined(_ARCH_PPC64) && defined(__64BIT__)) || (defined(_POWER) && defined(__64BIT__))
155#define SLJIT_CONFIG_PPC_64 1
156#elif defined(__ppc__) || defined(__powerpc__) || defined(_ARCH_PPC) || defined(_ARCH_PWR) || defined(_ARCH_PWR2) || defined(_POWER)
157#define SLJIT_CONFIG_PPC_32 1
158#elif defined(__mips__) && !defined(_LP64)
159#define SLJIT_CONFIG_MIPS_32 1
160#elif defined(__mips64)
161#define SLJIT_CONFIG_MIPS_64 1
162#elif defined (__riscv_xlen) && (__riscv_xlen == 32)
163#define SLJIT_CONFIG_RISCV_32 1
164#elif defined (__riscv_xlen) && (__riscv_xlen == 64)
165#define SLJIT_CONFIG_RISCV_64 1
166#elif defined(__s390x__)
167#define SLJIT_CONFIG_S390X 1
168#else
169/* Unsupported architecture */
170#define SLJIT_CONFIG_UNSUPPORTED 1
171#endif
172
173#else /* _WIN32 */
174
175#if defined(_M_X64) || defined(__x86_64__)
176#define SLJIT_CONFIG_X86_64 1
177#elif (defined(_M_ARM) && _M_ARM >= 7 && defined(_M_ARMT)) || defined(__thumb2__)
178#define SLJIT_CONFIG_ARM_THUMB2 1
179#elif (defined(_M_ARM) && _M_ARM >= 7)
180#define SLJIT_CONFIG_ARM_V7 1
181#elif defined(_ARM_)
182#define SLJIT_CONFIG_ARM_V5 1
183#elif defined(_M_ARM64) || defined(__aarch64__)
184#define SLJIT_CONFIG_ARM_64 1
185#else
186#define SLJIT_CONFIG_X86_32 1
187#endif
188
189#endif /* !_WIN32 */
190#endif /* SLJIT_CONFIG_AUTO */
191
192#if (defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED)
193#undef SLJIT_EXECUTABLE_ALLOCATOR
194#endif
195
196/******************************/
197/* CPU family type detection. */
198/******************************/
199
200#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) || (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) \
201 || (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2)
202#define SLJIT_CONFIG_ARM_32 1
203#endif
204
205#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) || (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
206#define SLJIT_CONFIG_X86 1
207#elif (defined SLJIT_CONFIG_ARM_32 && SLJIT_CONFIG_ARM_32) || (defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64)
208#define SLJIT_CONFIG_ARM 1
209#elif (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) || (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
210#define SLJIT_CONFIG_PPC 1
211#elif (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) || (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
212#define SLJIT_CONFIG_MIPS 1
213#elif (defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32) || (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64)
214#define SLJIT_CONFIG_RISCV 1
215#endif
216
217/***********************************************************/
218/* Intel Control-flow Enforcement Technology (CET) spport. */
219/***********************************************************/
220
221#ifdef SLJIT_CONFIG_X86
222
223#if defined(__CET__) && !(defined SLJIT_CONFIG_X86_CET && SLJIT_CONFIG_X86_CET)
224#define SLJIT_CONFIG_X86_CET 1
225#endif
226
227#if (defined SLJIT_CONFIG_X86_CET && SLJIT_CONFIG_X86_CET) && defined(__GNUC__)
228#include <x86intrin.h>
229#endif
230
231#endif /* SLJIT_CONFIG_X86 */
232
233/**********************************/
234/* External function definitions. */
235/**********************************/
236
237/* General macros:
238 Note: SLJIT is designed to be independent from them as possible.
239
240 In release mode (SLJIT_DEBUG is not defined) only the following
241 external functions are needed:
242*/
243
244#ifndef SLJIT_MALLOC
245#define SLJIT_MALLOC(size, allocator_data) malloc(size)
246#endif
247
248#ifndef SLJIT_FREE
249#define SLJIT_FREE(ptr, allocator_data) free(ptr)
250#endif
251
252#ifndef SLJIT_MEMCPY
253#define SLJIT_MEMCPY(dest, src, len) memcpy(dest, src, len)
254#endif
255
256#ifndef SLJIT_MEMMOVE
257#define SLJIT_MEMMOVE(dest, src, len) memmove(dest, src, len)
258#endif
259
260#ifndef SLJIT_ZEROMEM
261#define SLJIT_ZEROMEM(dest, len) memset(dest, 0, len)
262#endif
263
264/***************************/
265/* Compiler helper macros. */
266/***************************/
267
268#if !defined(SLJIT_LIKELY) && !defined(SLJIT_UNLIKELY)
269
270#if defined(__GNUC__) && (__GNUC__ >= 3)
271#define SLJIT_LIKELY(x) __builtin_expect((x), 1)
272#define SLJIT_UNLIKELY(x) __builtin_expect((x), 0)
273#else
274#define SLJIT_LIKELY(x) (x)
275#define SLJIT_UNLIKELY(x) (x)
276#endif
277
278#endif /* !defined(SLJIT_LIKELY) && !defined(SLJIT_UNLIKELY) */
279
280#ifndef SLJIT_INLINE
281/* Inline functions. Some old compilers do not support them. */
282#ifdef __SUNPRO_C
283#if __SUNPRO_C < 0x560
284#define SLJIT_INLINE
285#else
286#define SLJIT_INLINE inline
287#endif /* __SUNPRO_C */
288#else
289#define SLJIT_INLINE __inline
290#endif
291#endif /* !SLJIT_INLINE */
292
293#ifndef SLJIT_NOINLINE
294/* Not inline functions. */
295#if defined(__GNUC__)
296#define SLJIT_NOINLINE __attribute__ ((noinline))
297#else
298#define SLJIT_NOINLINE
299#endif
300#endif /* !SLJIT_INLINE */
301
302#ifndef SLJIT_UNUSED_ARG
303/* Unused arguments. */
304#define SLJIT_UNUSED_ARG(arg) (void)arg
305#endif
306
307/*********************************/
308/* Type of public API functions. */
309/*********************************/
310
311#ifndef SLJIT_API_FUNC_ATTRIBUTE
312#if (defined SLJIT_CONFIG_STATIC && SLJIT_CONFIG_STATIC)
313/* Static ABI functions. For all-in-one programs. */
314
315#if defined(__GNUC__)
316/* Disable unused warnings in gcc. */
317#define SLJIT_API_FUNC_ATTRIBUTE static __attribute__((unused))
318#else
319#define SLJIT_API_FUNC_ATTRIBUTE static
320#endif
321
322#else
323#define SLJIT_API_FUNC_ATTRIBUTE
324#endif /* (defined SLJIT_CONFIG_STATIC && SLJIT_CONFIG_STATIC) */
325#endif /* defined SLJIT_API_FUNC_ATTRIBUTE */
326
327/****************************/
328/* Instruction cache flush. */
329/****************************/
330
331/*
332 * TODO:
333 *
334 * clang >= 15 could be safe to enable below
335 * older versions are known to abort in some targets
336 * https://github.com/PhilipHazel/pcre2/issues/92
337 *
338 * beware some vendors (ex: Microsoft, Apple) are known to have
339 * removed the code to support this builtin even if the call for
340 * __has_builtin reports it is available.
341 *
342 * make sure linking doesn't fail because __clear_cache() is
343 * missing before changing it or add an exception so that the
344 * system provided method that should be defined below is used
345 * instead.
346 */
347#if (!defined SLJIT_CACHE_FLUSH && defined __has_builtin)
348#if __has_builtin(__builtin___clear_cache) && !defined(__clang__)
349
350/*
351 * https://gcc.gnu.org/bugzilla//show_bug.cgi?id=91248
352 * https://gcc.gnu.org/bugzilla//show_bug.cgi?id=93811
353 * gcc's clear_cache builtin for power is broken
354 */
355#if !defined(SLJIT_CONFIG_PPC)
356#define SLJIT_CACHE_FLUSH(from, to) \
357 __builtin___clear_cache((char*)(from), (char*)(to))
358#endif
359
360#endif /* gcc >= 10 */
361#endif /* (!defined SLJIT_CACHE_FLUSH && defined __has_builtin) */
362
363#ifndef SLJIT_CACHE_FLUSH
364
365#if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86) \
366 || (defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X)
367
368/* Not required to implement on archs with unified caches. */
369#define SLJIT_CACHE_FLUSH(from, to)
370
371#elif defined __APPLE__
372
373/* Supported by all macs since Mac OS 10.5.
374 However, it does not work on non-jailbroken iOS devices,
375 although the compilation is successful. */
376#include <libkern/OSCacheControl.h>
377#define SLJIT_CACHE_FLUSH(from, to) \
378 sys_icache_invalidate((void*)(from), (size_t)((char*)(to) - (char*)(from)))
379
380#elif (defined SLJIT_CONFIG_PPC && SLJIT_CONFIG_PPC)
381
382/* The __clear_cache() implementation of GCC is a dummy function on PowerPC. */
383#define SLJIT_CACHE_FLUSH(from, to) \
384 ppc_cache_flush((from), (to))
385#define SLJIT_CACHE_FLUSH_OWN_IMPL 1
386
387#elif defined(_WIN32)
388
389#define SLJIT_CACHE_FLUSH(from, to) \
390 FlushInstructionCache(GetCurrentProcess(), (void*)(from), (char*)(to) - (char*)(from))
391
392#elif (defined(__GNUC__) && (__GNUC__ >= 5 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3))) || defined(__clang__)
393
394#define SLJIT_CACHE_FLUSH(from, to) \
395 __builtin___clear_cache((char*)(from), (char*)(to))
396
397#elif defined __ANDROID__
398
399/* Android ARMv7 with gcc lacks __clear_cache; use cacheflush instead. */
400#include <sys/cachectl.h>
401#define SLJIT_CACHE_FLUSH(from, to) \
402 cacheflush((long)(from), (long)(to), 0)
403
404#else
405
406/* Call __ARM_NR_cacheflush on ARM-Linux or the corresponding MIPS syscall. */
407#define SLJIT_CACHE_FLUSH(from, to) \
408 __clear_cache((char*)(from), (char*)(to))
409
410#endif
411
412#endif /* !SLJIT_CACHE_FLUSH */
413
414/******************************************************/
415/* Integer and floating point type definitions. */
416/******************************************************/
417
418/* 8 bit byte type. */
419typedef unsigned char sljit_u8;
420typedef signed char sljit_s8;
421
422/* 16 bit half-word type. */
423typedef unsigned short int sljit_u16;
424typedef signed short int sljit_s16;
425
426/* 32 bit integer type. */
427typedef unsigned int sljit_u32;
428typedef signed int sljit_s32;
429
430/* Machine word type. Enough for storing a pointer.
431 32 bit for 32 bit machines.
432 64 bit for 64 bit machines. */
433#if (defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED)
434/* Just to have something. */
435#define SLJIT_WORD_SHIFT 0
436typedef unsigned long int sljit_uw;
437typedef long int sljit_sw;
438#elif !(defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) \
439 && !(defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64) \
440 && !(defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) \
441 && !(defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64) \
442 && !(defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64) \
443 && !(defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X)
444#define SLJIT_32BIT_ARCHITECTURE 1
445#define SLJIT_WORD_SHIFT 2
446typedef unsigned int sljit_uw;
447typedef int sljit_sw;
448#else
449#define SLJIT_64BIT_ARCHITECTURE 1
450#define SLJIT_WORD_SHIFT 3
451#ifdef _WIN32
452#ifdef __GNUC__
453/* These types do not require windows.h */
454typedef unsigned long long sljit_uw;
455typedef long long sljit_sw;
456#else
457typedef unsigned __int64 sljit_uw;
458typedef __int64 sljit_sw;
459#endif
460#else /* !_WIN32 */
461typedef unsigned long int sljit_uw;
462typedef long int sljit_sw;
463#endif /* _WIN32 */
464#endif
465
466typedef sljit_uw sljit_p;
467
468/* Floating point types. */
469typedef float sljit_f32;
470typedef double sljit_f64;
471
472/* Shift for pointer sized data. */
473#define SLJIT_POINTER_SHIFT SLJIT_WORD_SHIFT
474
475/* Shift for double precision sized data. */
476#define SLJIT_F32_SHIFT 2
477#define SLJIT_F64_SHIFT 3
478
479#ifndef SLJIT_W
480
481/* Defining long constants. */
482#if (defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED)
483#define SLJIT_W(w) (w##l)
484#elif (defined SLJIT_64BIT_ARCHITECTURE && SLJIT_64BIT_ARCHITECTURE)
485#ifdef _WIN64
486#define SLJIT_W(w) (w##ll)
487#else /* !windows */
488#define SLJIT_W(w) (w##l)
489#endif /* windows */
490#else /* 32 bit */
491#define SLJIT_W(w) (w)
492#endif /* unknown */
493
494#endif /* !SLJIT_W */
495
496/*************************/
497/* Endianness detection. */
498/*************************/
499
500#if !defined(SLJIT_BIG_ENDIAN) && !defined(SLJIT_LITTLE_ENDIAN)
501
502/* These macros are mostly useful for the applications. */
503#if (defined SLJIT_CONFIG_PPC && SLJIT_CONFIG_PPC)
504
505#ifdef __LITTLE_ENDIAN__
506#define SLJIT_LITTLE_ENDIAN 1
507#else
508#define SLJIT_BIG_ENDIAN 1
509#endif
510
511#elif (defined SLJIT_CONFIG_MIPS && SLJIT_CONFIG_MIPS)
512
513#ifdef __MIPSEL__
514#define SLJIT_LITTLE_ENDIAN 1
515#else
516#define SLJIT_BIG_ENDIAN 1
517#endif
518
519#ifndef SLJIT_MIPS_REV
520
521/* Auto detecting mips revision. */
522#if (defined __mips_isa_rev) && (__mips_isa_rev >= 6)
523#define SLJIT_MIPS_REV 6
524#elif (defined __mips_isa_rev && __mips_isa_rev >= 1) \
525 || (defined __clang__ && defined _MIPS_ARCH_OCTEON) \
526 || (defined __clang__ && defined _MIPS_ARCH_P5600)
527/* clang either forgets to define (clang-7) __mips_isa_rev at all
528 * or sets it to zero (clang-8,-9) for -march=octeon (MIPS64 R2+)
529 * and -march=p5600 (MIPS32 R5).
530 * It also sets the __mips macro to 64 or 32 for -mipsN when N <= 5
531 * (should be set to N exactly) so we cannot rely on this too.
532 */
533#define SLJIT_MIPS_REV 1
534#endif
535
536#endif /* !SLJIT_MIPS_REV */
537
538#elif (defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X)
539
540#define SLJIT_BIG_ENDIAN 1
541
542#else
543#define SLJIT_LITTLE_ENDIAN 1
544#endif
545
546#endif /* !defined(SLJIT_BIG_ENDIAN) && !defined(SLJIT_LITTLE_ENDIAN) */
547
548/* Sanity check. */
549#if (defined SLJIT_BIG_ENDIAN && SLJIT_BIG_ENDIAN) && (defined SLJIT_LITTLE_ENDIAN && SLJIT_LITTLE_ENDIAN)
550#error "Exactly one endianness must be selected"
551#endif
552
553#if !(defined SLJIT_BIG_ENDIAN && SLJIT_BIG_ENDIAN) && !(defined SLJIT_LITTLE_ENDIAN && SLJIT_LITTLE_ENDIAN)
554#error "Exactly one endianness must be selected"
555#endif
556
557#ifndef SLJIT_UNALIGNED
558
559#if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86) \
560 || (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) \
561 || (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2) \
562 || (defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64) \
563 || (defined SLJIT_CONFIG_PPC && SLJIT_CONFIG_PPC) \
564 || (defined SLJIT_CONFIG_RISCV && SLJIT_CONFIG_RISCV) \
565 || (defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X)
566#define SLJIT_UNALIGNED 1
567#endif
568
569#endif /* !SLJIT_UNALIGNED */
570
571#ifndef SLJIT_FPU_UNALIGNED
572
573#if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86) \
574 || (defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64) \
575 || (defined SLJIT_CONFIG_PPC && SLJIT_CONFIG_PPC) \
576 || (defined SLJIT_CONFIG_RISCV && SLJIT_CONFIG_RISCV) \
577 || (defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X)
578#define SLJIT_FPU_UNALIGNED 1
579#endif
580
581#endif /* !SLJIT_FPU_UNALIGNED */
582
583#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
584/* Auto detect SSE2 support using CPUID.
585 On 64 bit x86 cpus, sse2 must be present. */
586#define SLJIT_DETECT_SSE2 1
587#endif
588
589/*****************************************************************************************/
590/* Calling convention of functions generated by SLJIT or called from the generated code. */
591/*****************************************************************************************/
592
593#ifndef SLJIT_FUNC
594#define SLJIT_FUNC
595#endif /* !SLJIT_FUNC */
596
597#ifndef SLJIT_INDIRECT_CALL
598#if ((defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) && (!defined _CALL_ELF || _CALL_ELF == 1)) \
599 || ((defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) && defined _AIX)
600/* It seems certain ppc compilers use an indirect addressing for functions
601 which makes things complicated. */
602#define SLJIT_INDIRECT_CALL 1
603#endif
604#endif /* SLJIT_INDIRECT_CALL */
605
606/* The offset which needs to be subtracted from the return address to
607determine the next executed instruction after return. */
608#ifndef SLJIT_RETURN_ADDRESS_OFFSET
609#define SLJIT_RETURN_ADDRESS_OFFSET 0
610#endif /* SLJIT_RETURN_ADDRESS_OFFSET */
611
612/***************************************************/
613/* Functions of the built-in executable allocator. */
614/***************************************************/
615
616#if (defined SLJIT_EXECUTABLE_ALLOCATOR && SLJIT_EXECUTABLE_ALLOCATOR)
617SLJIT_API_FUNC_ATTRIBUTE void* sljit_malloc_exec(sljit_uw size);
618SLJIT_API_FUNC_ATTRIBUTE void sljit_free_exec(void* ptr);
619SLJIT_API_FUNC_ATTRIBUTE void sljit_free_unused_memory_exec(void);
620#define SLJIT_BUILTIN_MALLOC_EXEC(size, exec_allocator_data) sljit_malloc_exec(size)
621#define SLJIT_BUILTIN_FREE_EXEC(ptr, exec_allocator_data) sljit_free_exec(ptr)
622
623#ifndef SLJIT_MALLOC_EXEC
624#define SLJIT_MALLOC_EXEC(size, exec_allocator_data) SLJIT_BUILTIN_MALLOC_EXEC((size), (exec_allocator_data))
625#endif /* SLJIT_MALLOC_EXEC */
626
627#ifndef SLJIT_FREE_EXEC
628#define SLJIT_FREE_EXEC(ptr, exec_allocator_data) SLJIT_BUILTIN_FREE_EXEC((ptr), (exec_allocator_data))
629#endif /* SLJIT_FREE_EXEC */
630
631#if (defined SLJIT_PROT_EXECUTABLE_ALLOCATOR && SLJIT_PROT_EXECUTABLE_ALLOCATOR)
632SLJIT_API_FUNC_ATTRIBUTE sljit_sw sljit_exec_offset(void* ptr);
633#define SLJIT_EXEC_OFFSET(ptr) sljit_exec_offset(ptr)
634#else
635#define SLJIT_EXEC_OFFSET(ptr) 0
636#endif
637
638#endif /* SLJIT_EXECUTABLE_ALLOCATOR */
639
640/**********************************************/
641/* Registers and locals offset determination. */
642/**********************************************/
643
644#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
645
646#define SLJIT_NUMBER_OF_REGISTERS 12
647#define SLJIT_NUMBER_OF_SAVED_REGISTERS 7
648#define SLJIT_NUMBER_OF_FLOAT_REGISTERS 7
649#define SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS 0
650#define SLJIT_LOCALS_OFFSET_BASE (8 * SSIZE_OF(sw))
651#define SLJIT_PREF_SHIFT_REG SLJIT_R2
652
653#elif (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
654
655#define SLJIT_NUMBER_OF_REGISTERS 13
656#define SLJIT_NUMBER_OF_FLOAT_REGISTERS 15
657#ifndef _WIN64
658#define SLJIT_NUMBER_OF_SAVED_REGISTERS 6
659#define SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS 0
660#define SLJIT_LOCALS_OFFSET_BASE 0
661#else /* _WIN64 */
662#define SLJIT_NUMBER_OF_SAVED_REGISTERS 8
663#define SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS 10
664#define SLJIT_LOCALS_OFFSET_BASE (4 * SSIZE_OF(sw))
665#endif /* !_WIN64 */
666#define SLJIT_PREF_SHIFT_REG SLJIT_R3
667
668#elif (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) || (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7)
669
670#define SLJIT_NUMBER_OF_REGISTERS 12
671#define SLJIT_NUMBER_OF_SAVED_REGISTERS 8
672#define SLJIT_NUMBER_OF_FLOAT_REGISTERS 14
673#define SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS 8
674#define SLJIT_LOCALS_OFFSET_BASE 0
675
676#elif (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2)
677
678#define SLJIT_NUMBER_OF_REGISTERS 12
679#define SLJIT_NUMBER_OF_SAVED_REGISTERS 8
680#define SLJIT_NUMBER_OF_FLOAT_REGISTERS 14
681#define SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS 8
682#define SLJIT_LOCALS_OFFSET_BASE 0
683
684#elif (defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64)
685
686#define SLJIT_NUMBER_OF_REGISTERS 26
687#define SLJIT_NUMBER_OF_SAVED_REGISTERS 10
688#define SLJIT_NUMBER_OF_FLOAT_REGISTERS 30
689#define SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS 8
690#define SLJIT_LOCALS_OFFSET_BASE (2 * (sljit_s32)sizeof(sljit_sw))
691
692#elif (defined SLJIT_CONFIG_PPC && SLJIT_CONFIG_PPC)
693
694#define SLJIT_NUMBER_OF_REGISTERS 23
695#define SLJIT_NUMBER_OF_SAVED_REGISTERS 17
696#define SLJIT_NUMBER_OF_FLOAT_REGISTERS 30
697#define SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS 18
698#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) || (defined _AIX)
699#define SLJIT_LOCALS_OFFSET_BASE ((6 + 8) * (sljit_s32)sizeof(sljit_sw))
700#elif (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
701/* Add +1 for double alignment. */
702#define SLJIT_LOCALS_OFFSET_BASE ((3 + 1) * (sljit_s32)sizeof(sljit_sw))
703#else
704#define SLJIT_LOCALS_OFFSET_BASE (3 * (sljit_s32)sizeof(sljit_sw))
705#endif /* SLJIT_CONFIG_PPC_64 || _AIX */
706
707#elif (defined SLJIT_CONFIG_MIPS && SLJIT_CONFIG_MIPS)
708
709#define SLJIT_NUMBER_OF_REGISTERS 21
710#define SLJIT_NUMBER_OF_SAVED_REGISTERS 8
711#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
712#define SLJIT_LOCALS_OFFSET_BASE (4 * (sljit_s32)sizeof(sljit_sw))
713#define SLJIT_NUMBER_OF_FLOAT_REGISTERS 13
714#define SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS 6
715#else
716#define SLJIT_LOCALS_OFFSET_BASE 0
717#define SLJIT_NUMBER_OF_FLOAT_REGISTERS 29
718#define SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS 8
719#endif
720
721#elif (defined SLJIT_CONFIG_RISCV && SLJIT_CONFIG_RISCV)
722
723#define SLJIT_NUMBER_OF_REGISTERS 23
724#define SLJIT_NUMBER_OF_SAVED_REGISTERS 12
725#define SLJIT_LOCALS_OFFSET_BASE 0
726#define SLJIT_NUMBER_OF_FLOAT_REGISTERS 30
727#define SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS 12
728
729#elif (defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X)
730
731/*
732 * https://refspecs.linuxbase.org/ELF/zSeries/lzsabi0_zSeries.html#STACKFRAME
733 *
734 * 160
735 * .. FR6
736 * .. FR4
737 * .. FR2
738 * 128 FR0
739 * 120 R15 (used for SP)
740 * 112 R14
741 * 104 R13
742 * 96 R12
743 * ..
744 * 48 R6
745 * ..
746 * 16 R2
747 * 8 RESERVED
748 * 0 SP
749 */
750#define SLJIT_S390X_DEFAULT_STACK_FRAME_SIZE 160
751
752#define SLJIT_NUMBER_OF_REGISTERS 12
753#define SLJIT_NUMBER_OF_SAVED_REGISTERS 8
754#define SLJIT_NUMBER_OF_FLOAT_REGISTERS 15
755#define SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS 8
756#define SLJIT_LOCALS_OFFSET_BASE SLJIT_S390X_DEFAULT_STACK_FRAME_SIZE
757
758#elif (defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED)
759
760#define SLJIT_NUMBER_OF_REGISTERS 0
761#define SLJIT_NUMBER_OF_SAVED_REGISTERS 0
762#define SLJIT_NUMBER_OF_FLOAT_REGISTERS 0
763#define SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS 0
764#define SLJIT_LOCALS_OFFSET_BASE 0
765
766#endif
767
768#define SLJIT_LOCALS_OFFSET (SLJIT_LOCALS_OFFSET_BASE)
769
770#define SLJIT_NUMBER_OF_SCRATCH_REGISTERS \
771 (SLJIT_NUMBER_OF_REGISTERS - SLJIT_NUMBER_OF_SAVED_REGISTERS)
772
773#define SLJIT_NUMBER_OF_SCRATCH_FLOAT_REGISTERS \
774 (SLJIT_NUMBER_OF_FLOAT_REGISTERS - SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS)
775
776/********************************/
777/* CPU status flags management. */
778/********************************/
779
780#if (defined SLJIT_CONFIG_ARM && SLJIT_CONFIG_ARM) \
781 || (defined SLJIT_CONFIG_PPC && SLJIT_CONFIG_PPC) \
782 || (defined SLJIT_CONFIG_MIPS && SLJIT_CONFIG_MIPS) \
783 || (defined SLJIT_CONFIG_RISCV && SLJIT_CONFIG_RISCV) \
784 || (defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X)
785#define SLJIT_HAS_STATUS_FLAGS_STATE 1
786#endif
787
788/*************************************/
789/* Debug and verbose related macros. */
790/*************************************/
791
792#if (defined SLJIT_DEBUG && SLJIT_DEBUG)
793
794#if !defined(SLJIT_ASSERT) || !defined(SLJIT_UNREACHABLE)
795
796/* SLJIT_HALT_PROCESS must halt the process. */
797#ifndef SLJIT_HALT_PROCESS
798#define SLJIT_HALT_PROCESS() \
799 abort();
800#endif /* !SLJIT_HALT_PROCESS */
801
802#endif /* !SLJIT_ASSERT || !SLJIT_UNREACHABLE */
803
804/* Feel free to redefine these two macros. */
805#ifndef SLJIT_ASSERT
806
807#define SLJIT_ASSERT(x) \
808 do { \
809 if (SLJIT_UNLIKELY(!(x))) { \
810 printf("Assertion failed at " __FILE__ ":%d\n", __LINE__); \
811 SLJIT_HALT_PROCESS(); \
812 } \
813 } while (0)
814
815#endif /* !SLJIT_ASSERT */
816
817#ifndef SLJIT_UNREACHABLE
818
819#define SLJIT_UNREACHABLE() \
820 do { \
821 printf("Should never been reached " __FILE__ ":%d\n", __LINE__); \
822 SLJIT_HALT_PROCESS(); \
823 } while (0)
824
825#endif /* !SLJIT_UNREACHABLE */
826
827#else /* (defined SLJIT_DEBUG && SLJIT_DEBUG) */
828
829/* Forcing empty, but valid statements. */
830#undef SLJIT_ASSERT
831#undef SLJIT_UNREACHABLE
832
833#define SLJIT_ASSERT(x) \
834 do { } while (0)
835#define SLJIT_UNREACHABLE() \
836 do { } while (0)
837
838#endif /* (defined SLJIT_DEBUG && SLJIT_DEBUG) */
839
840#ifndef SLJIT_COMPILE_ASSERT
841
842#define SLJIT_COMPILE_ASSERT(x, description) \
843 switch(0) { case 0: case ((x) ? 1 : 0): break; }
844
845#endif /* !SLJIT_COMPILE_ASSERT */
846
847#ifdef __cplusplus
848} /* extern "C" */
849#endif
850
851#endif /* SLJIT_CONFIG_INTERNAL_H_ */
852