5454 SLJIT_UPPER_BITS_ZERO_EXTENDED : 32 bit operations clears the upper bits of destination registers
5555 SLJIT_UPPER_BITS_SIGN_EXTENDED : 32 bit operations replicates the sign bit in the upper bits of destination registers
5656 SLJIT_UPPER_BITS_PRESERVED : 32 bit operations preserves the upper bits of destination registers
57+ SLJIT_SUBC_SETS_SIGNED : SLJIT_SUBC[32] operation always sets the signed result, so setting
58+ the following status flags after a subtract with carry operation is valid:
59+ sljit_set_current_flags(..., SLJIT_CURRENT_FLAGS_SUB | SLJIT_SET_SIG_LESS)
60+ sljit_set_current_flags(..., SLJIT_CURRENT_FLAGS_SUB | SLJIT_SET_SIG_GREATER)
61+ SLJIT_SHARED_COMPARISON_FLAGS: the cpu has different instructions for signed and unsigned
62+ comparisons, which sets the same status flags, so passing SLJIT_LESS
63+ or SLJIT_SIG_LESS as an argument has the same effect, and this is true
64+ for all other signed/unsigned comparison type pairs
5765
5866 Constants:
5967 SLJIT_NUMBER_OF_REGISTERS : number of available registers
97105 SLJIT_TMP_FR(i) : accessing temporary floating point registers
98106 SLJIT_TMP_VR0 .. VR9 : accessing temporary vector registers
99107 SLJIT_TMP_VR(i) : accessing temporary vector registers
100- SLJIT_TMP_DEST_REG : a temporary register for results
101- SLJIT_TMP_MEM_REG : a temporary base register for accessing memory
102- (can be the same as SLJIT_TMP_DEST_REG)
103- SLJIT_TMP_DEST_FREG : a temporary register for float results
104- SLJIT_TMP_DEST_VREG : a temporary register for vector results
108+ SLJIT_TMP_DEST_REG : a temporary register for results, see the rules below
109+ SLJIT_TMP_DEST_FREG : a temporary register for float results, see the rules below
110+ SLJIT_TMP_DEST_VREG : a temporary register for vector results, see the rules below
111+ SLJIT_TMP_OPT_REG : an optional temporary register, see the rules below
112+ SLJIT_TMP_FLAG_REG : an optional temporary register for storing the value of a flag
105113 SLJIT_FUNC : calling convention attribute for both calling JIT from C and C calling back from JIT
106114 SLJIT_W(number) : defining 64 bit constants on 64 bit architectures (platform independent helper)
107115 SLJIT_F64_SECOND(reg) : provides the register index of the second 32 bit part of a 64 bit
108116 floating point register when SLJIT_HAS_F64_AS_F32_PAIR returns non-zero
117+
118+ Temporary register rules (e.g. SLJIT_TMP_DEST_REG / SLJIT_TMP_OPT_REG):
119+ The sljit compiler avoids using temporary registers, but certain instruction
120+ forms cannot be generated without them. The number of temporary registers
121+ reserved by the compiler depends on the target architecture. An SLJIT_TMP_*
122+ name is assigned to some of these registers, which represents their
123+ SLJIT_TMP_R(i) index. When such register is optional, it might not be
124+ defined on all architectures. For example, the x86-32 code generator does
125+ not use any optional temporary registers.
109126*/
110127
111128#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \
118135#include < stdlib.h>
119136#endif
120137
138+ #ifdef __APPLE__
139+ #include < AvailabilityMacros.h>
140+ #if MAC_OS_X_VERSION_MIN_REQUIRED >= 1050
141+ #include < libkern/OSCacheControl.h>
142+ #endif
143+ #endif
144+
121145#ifdef __cplusplus
122146extern " C" {
123147#endif
@@ -236,10 +260,6 @@ extern "C" {
236260/* Instruction cache flush. */
237261/* ***************************/
238262
239- #ifdef __APPLE__
240- #include <AvailabilityMacros.h>
241- #endif
242-
243263/*
244264 * TODO:
245265 *
@@ -285,7 +305,6 @@ extern "C" {
285305/* Supported by all macs since Mac OS 10.5.
286306 However, it does not work on non-jailbroken iOS devices,
287307 although the compilation is successful. */
288- #include <libkern/OSCacheControl.h>
289308#define SLJIT_CACHE_FLUSH (from, to ) \
290309 sys_icache_invalidate ((void *)(from), (size_t )((char *)(to) - (char *)(from)))
291310
@@ -603,14 +622,14 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_sw sljit_exec_offset(void *code);
603622#define SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS 0
604623#define SLJIT_NUMBER_OF_TEMPORARY_FLOAT_REGISTERS 1
605624#define SLJIT_TMP_DEST_REG SLJIT_TMP_R0
606- #define SLJIT_TMP_MEM_REG SLJIT_TMP_R0
607625#define SLJIT_TMP_DEST_FREG SLJIT_TMP_FR0
608626#define SLJIT_LOCALS_OFFSET_BASE (8 * (sljit_s32)sizeof (sljit_sw))
609627#define SLJIT_PREF_SHIFT_REG SLJIT_R2
610628#define SLJIT_MASKED_SHIFT 1
611629#define SLJIT_MASKED_SHIFT32 1
612630#define SLJIT_UPPER_BITS_IGNORED 1
613631#define SLJIT_UPPER_BITS_ZERO_EXTENDED 1
632+ #define SLJIT_SUBC_SETS_SIGNED 1
614633
615634#elif (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
616635
@@ -628,13 +647,14 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_sw sljit_exec_offset(void *code);
628647#define SLJIT_LOCALS_OFFSET_BASE (4 * (sljit_s32)sizeof (sljit_sw))
629648#endif /* !_WIN64 */
630649#define SLJIT_TMP_DEST_REG SLJIT_TMP_R0
631- #define SLJIT_TMP_MEM_REG SLJIT_TMP_R0
650+ #define SLJIT_TMP_OPT_REG SLJIT_TMP_R1
632651#define SLJIT_TMP_DEST_FREG SLJIT_TMP_FR0
633652#define SLJIT_PREF_SHIFT_REG SLJIT_R3
634653#define SLJIT_MASKED_SHIFT 1
635654#define SLJIT_MASKED_SHIFT32 1
636655#define SLJIT_UPPER_BITS_IGNORED 1
637656#define SLJIT_UPPER_BITS_ZERO_EXTENDED 1
657+ #define SLJIT_SUBC_SETS_SIGNED 1
638658
639659#elif (defined SLJIT_CONFIG_ARM_32 && SLJIT_CONFIG_ARM_32)
640660
@@ -645,9 +665,10 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_sw sljit_exec_offset(void *code);
645665#define SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS 8
646666#define SLJIT_NUMBER_OF_TEMPORARY_FLOAT_REGISTERS 2
647667#define SLJIT_TMP_DEST_REG SLJIT_TMP_R1
648- #define SLJIT_TMP_MEM_REG SLJIT_TMP_R1
668+ #define SLJIT_TMP_OPT_REG SLJIT_TMP_R0
649669#define SLJIT_TMP_DEST_FREG SLJIT_TMP_FR0
650670#define SLJIT_LOCALS_OFFSET_BASE 0
671+ #define SLJIT_SUBC_SETS_SIGNED 1
651672
652673#elif (defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64)
653674
@@ -658,13 +679,14 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_sw sljit_exec_offset(void *code);
658679#define SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS 8
659680#define SLJIT_NUMBER_OF_TEMPORARY_FLOAT_REGISTERS 2
660681#define SLJIT_TMP_DEST_REG SLJIT_TMP_R0
661- #define SLJIT_TMP_MEM_REG SLJIT_TMP_R0
682+ #define SLJIT_TMP_OPT_REG SLJIT_TMP_R1
662683#define SLJIT_TMP_DEST_FREG SLJIT_TMP_FR0
663684#define SLJIT_LOCALS_OFFSET_BASE (2 * (sljit_s32)sizeof (sljit_sw))
664685#define SLJIT_MASKED_SHIFT 1
665686#define SLJIT_MASKED_SHIFT32 1
666687#define SLJIT_UPPER_BITS_IGNORED 1
667688#define SLJIT_UPPER_BITS_ZERO_EXTENDED 1
689+ #define SLJIT_SUBC_SETS_SIGNED 1
668690
669691#elif (defined SLJIT_CONFIG_PPC && SLJIT_CONFIG_PPC)
670692
@@ -675,7 +697,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_sw sljit_exec_offset(void *code);
675697#define SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS 18
676698#define SLJIT_NUMBER_OF_TEMPORARY_FLOAT_REGISTERS 2
677699#define SLJIT_TMP_DEST_REG SLJIT_TMP_R1
678- #define SLJIT_TMP_MEM_REG SLJIT_TMP_R1
700+ #define SLJIT_TMP_OPT_REG SLJIT_TMP_R0
679701#define SLJIT_TMP_DEST_FREG SLJIT_TMP_FR0
680702#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) || (defined _AIX)
681703#define SLJIT_LOCALS_OFFSET_BASE ((6 + 8 ) * (sljit_s32)sizeof (sljit_sw))
@@ -686,6 +708,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_sw sljit_exec_offset(void *code);
686708#define SLJIT_LOCALS_OFFSET_BASE (3 * (sljit_s32)sizeof (sljit_sw))
687709#endif /* SLJIT_CONFIG_PPC_64 || _AIX */
688710#define SLJIT_UPPER_BITS_IGNORED 1
711+ #define SLJIT_SHARED_COMPARISON_FLAGS 1
689712
690713#elif (defined SLJIT_CONFIG_MIPS && SLJIT_CONFIG_MIPS)
691714
@@ -703,11 +726,13 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_sw sljit_exec_offset(void *code);
703726#define SLJIT_NUMBER_OF_TEMPORARY_REGISTERS 5
704727#define SLJIT_NUMBER_OF_TEMPORARY_FLOAT_REGISTERS 3
705728#define SLJIT_TMP_DEST_REG SLJIT_TMP_R1
706- #define SLJIT_TMP_MEM_REG SLJIT_TMP_R1
729+ #define SLJIT_TMP_OPT_REG SLJIT_TMP_R0
730+ #define SLJIT_TMP_FLAG_REG SLJIT_TMP_R3
707731#define SLJIT_TMP_DEST_FREG SLJIT_TMP_FR0
708732#define SLJIT_MASKED_SHIFT 1
709733#define SLJIT_MASKED_SHIFT32 1
710734#define SLJIT_UPPER_BITS_SIGN_EXTENDED 1
735+ #define SLJIT_SHARED_COMPARISON_FLAGS 1
711736
712737#elif (defined SLJIT_CONFIG_RISCV && SLJIT_CONFIG_RISCV)
713738
@@ -722,14 +747,16 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_sw sljit_exec_offset(void *code);
722747#define SLJIT_NUMBER_OF_SAVED_VECTOR_REGISTERS 0
723748#define SLJIT_NUMBER_OF_TEMPORARY_VECTOR_REGISTERS 2
724749#define SLJIT_TMP_DEST_REG SLJIT_TMP_R1
725- #define SLJIT_TMP_MEM_REG SLJIT_TMP_R1
750+ #define SLJIT_TMP_OPT_REG SLJIT_TMP_R0
751+ #define SLJIT_TMP_FLAG_REG SLJIT_TMP_R3
726752#define SLJIT_TMP_DEST_FREG SLJIT_TMP_FR0
727753#define SLJIT_TMP_DEST_VREG SLJIT_TMP_VR0
728754#define SLJIT_LOCALS_OFFSET_BASE 0
729755#define SLJIT_MASKED_SHIFT 1
730756#define SLJIT_MASKED_SHIFT32 1
731757#define SLJIT_UPPER_BITS_IGNORED 1
732758#define SLJIT_UPPER_BITS_SIGN_EXTENDED 1
759+ #define SLJIT_SHARED_COMPARISON_FLAGS 1
733760
734761#elif (defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X)
735762
@@ -760,13 +787,14 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_sw sljit_exec_offset(void *code);
760787#define SLJIT_NUMBER_OF_FLOAT_REGISTERS 15
761788#define SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS 8
762789#define SLJIT_NUMBER_OF_TEMPORARY_FLOAT_REGISTERS 1
763- #define SLJIT_TMP_DEST_REG SLJIT_TMP_R0
764- #define SLJIT_TMP_MEM_REG SLJIT_TMP_R2
790+ #define SLJIT_TMP_DEST_REG SLJIT_TMP_R2
791+ #define SLJIT_TMP_OPT_REG SLJIT_TMP_R1
765792#define SLJIT_TMP_DEST_FREG SLJIT_TMP_FR0
766793#define SLJIT_LOCALS_OFFSET_BASE SLJIT_S390X_DEFAULT_STACK_FRAME_SIZE
767794#define SLJIT_MASKED_SHIFT 1
768795#define SLJIT_UPPER_BITS_IGNORED 1
769796#define SLJIT_UPPER_BITS_PRESERVED 1
797+ #define SLJIT_SHARED_COMPARISON_FLAGS 1
770798
771799#elif (defined SLJIT_CONFIG_LOONGARCH && SLJIT_CONFIG_LOONGARCH)
772800
@@ -777,12 +805,14 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_sw sljit_exec_offset(void *code);
777805#define SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS 12
778806#define SLJIT_NUMBER_OF_TEMPORARY_FLOAT_REGISTERS 2
779807#define SLJIT_TMP_DEST_REG SLJIT_TMP_R1
780- #define SLJIT_TMP_MEM_REG SLJIT_TMP_R1
808+ #define SLJIT_TMP_OPT_REG SLJIT_TMP_R0
809+ #define SLJIT_TMP_FLAG_REG SLJIT_TMP_R3
781810#define SLJIT_TMP_DEST_FREG SLJIT_TMP_FR0
782811#define SLJIT_LOCALS_OFFSET_BASE 0
783812#define SLJIT_MASKED_SHIFT 1
784813#define SLJIT_MASKED_SHIFT32 1
785814#define SLJIT_UPPER_BITS_SIGN_EXTENDED 1
815+ #define SLJIT_SHARED_COMPARISON_FLAGS 1
786816
787817#elif (defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED)
788818
@@ -794,7 +824,6 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_sw sljit_exec_offset(void *code);
794824#define SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS 0
795825#define SLJIT_NUMBER_OF_TEMPORARY_FLOAT_REGISTERS 0
796826#define SLJIT_TMP_DEST_REG 0
797- #define SLJIT_TMP_MEM_REG 0
798827#define SLJIT_TMP_DEST_FREG 0
799828#define SLJIT_LOCALS_OFFSET_BASE 0
800829
@@ -966,6 +995,37 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_sw sljit_exec_offset(void *code);
966995
967996#endif /* !SLJIT_COMPILE_ASSERT */
968997
998+ #ifndef SLJIT_FALLTHROUGH
999+
1000+ #if defined(__cplusplus) && __cplusplus >= 202002L && \
1001+ defined (__has_cpp_attribute)
1002+ /* Standards-compatible C++ variant. */
1003+ #if __has_cpp_attribute(fallthrough)
1004+ #define SLJIT_FALLTHROUGH [[fallthrough]];
1005+ #endif
1006+ #elif !defined(__cplusplus) && \
1007+ defined (__STDC_VERSION__) && __STDC_VERSION__ >= 202311L && \
1008+ defined(__has_c_attribute)
1009+ /* Standards-compatible C variant. */
1010+ #if __has_c_attribute(fallthrough)
1011+ #define SLJIT_FALLTHROUGH [[fallthrough]];
1012+ #endif
1013+ #elif ((defined(__clang__) && __clang_major__ >= 10) || \
1014+ (defined (__GNUC__) && __GNUC__ >= 7 )) && \
1015+ defined (__has_attribute)
1016+ /* Clang and GCC syntax. Rule out old versions because apparently Clang at
1017+ least has a broken implementation of __has_attribute. */
1018+ #if __has_attribute(fallthrough)
1019+ #define SLJIT_FALLTHROUGH __attribute__ ((fallthrough));
1020+ #endif
1021+ #endif
1022+
1023+ #ifndef SLJIT_FALLTHROUGH
1024+ #define SLJIT_FALLTHROUGH
1025+ #endif
1026+
1027+ #endif /* !SLJIT_FALLTHROUGH */
1028+
9691029#ifdef __cplusplus
9701030} /* extern "C" */
9711031#endif
0 commit comments