summaryrefslogtreecommitdiffstats
path: root/src/3rdparty/pcre2/src/sljit/sljitLir.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/3rdparty/pcre2/src/sljit/sljitLir.c')
-rw-r--r--src/3rdparty/pcre2/src/sljit/sljitLir.c1350
1 files changed, 896 insertions, 454 deletions
diff --git a/src/3rdparty/pcre2/src/sljit/sljitLir.c b/src/3rdparty/pcre2/src/sljit/sljitLir.c
index 86772cc1a5..abafe1add9 100644
--- a/src/3rdparty/pcre2/src/sljit/sljitLir.c
+++ b/src/3rdparty/pcre2/src/sljit/sljitLir.c
@@ -28,7 +28,6 @@
#ifdef _WIN32
-/* For SLJIT_CACHE_FLUSH, which can expand to FlushInstructionCache. */
#include <windows.h>
#endif /* _WIN32 */
@@ -91,26 +90,28 @@
#if !(defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED)
+#define SSIZE_OF(type) ((sljit_s32)sizeof(sljit_ ## type))
+
#define VARIABLE_FLAG_SHIFT (10)
#define VARIABLE_FLAG_MASK (0x3f << VARIABLE_FLAG_SHIFT)
#define GET_FLAG_TYPE(op) ((op) >> VARIABLE_FLAG_SHIFT)
#define GET_OPCODE(op) \
- ((op) & ~(SLJIT_I32_OP | SLJIT_SET_Z | VARIABLE_FLAG_MASK))
+ ((op) & ~(SLJIT_32 | SLJIT_SET_Z | VARIABLE_FLAG_MASK))
#define HAS_FLAGS(op) \
((op) & (SLJIT_SET_Z | VARIABLE_FLAG_MASK))
#define GET_ALL_FLAGS(op) \
- ((op) & (SLJIT_I32_OP | SLJIT_SET_Z | VARIABLE_FLAG_MASK))
+ ((op) & (SLJIT_32 | SLJIT_SET_Z | VARIABLE_FLAG_MASK))
#if (defined SLJIT_64BIT_ARCHITECTURE && SLJIT_64BIT_ARCHITECTURE)
#define TYPE_CAST_NEEDED(op) \
((op) >= SLJIT_MOV_U8 && (op) <= SLJIT_MOV_S32)
-#else
+#else /* !SLJIT_64BIT_ARCHITECTURE */
#define TYPE_CAST_NEEDED(op) \
((op) >= SLJIT_MOV_U8 && (op) <= SLJIT_MOV_S16)
-#endif
+#endif /* SLJIT_64BIT_ARCHITECTURE */
#define BUF_SIZE 4096
@@ -127,11 +128,18 @@
#define TO_OFFS_REG(reg) ((reg) << 8)
/* When reg cannot be unused. */
#define FAST_IS_REG(reg) ((reg) <= REG_MASK)
-/* When reg can be unused. */
-#define SLOW_IS_REG(reg) ((reg) > 0 && (reg) <= REG_MASK)
/* Mask for argument types. */
-#define SLJIT_DEF_MASK ((1 << SLJIT_DEF_SHIFT) - 1)
+#define SLJIT_ARG_MASK 0x7
+#define SLJIT_ARG_FULL_MASK (SLJIT_ARG_MASK | SLJIT_ARG_TYPE_SCRATCH_REG)
+
+/* Mask for sljit_emit_mem. */
+#define REG_PAIR_MASK 0xff00
+#define REG_PAIR_FIRST(reg) ((reg) & 0xff)
+#define REG_PAIR_SECOND(reg) ((reg) >> 8)
+
+/* Mask for sljit_emit_enter. */
+#define SLJIT_KEPT_SAVEDS_COUNT(options) ((options) & 0x3)
/* Jump flags. */
#define JUMP_LABEL 0x1
@@ -145,16 +153,16 @@
# define PATCH_MD 0x10
#endif
# define TYPE_SHIFT 13
-#endif
+#endif /* SLJIT_CONFIG_X86 */
#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) || (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7)
# define IS_BL 0x4
# define PATCH_B 0x8
-#endif
+#endif /* SLJIT_CONFIG_ARM_V5 || SLJIT_CONFIG_ARM_V7 */
#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
# define CPOOL_SIZE 512
-#endif
+#endif /* SLJIT_CONFIG_ARM_V5 */
#if (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2)
# define IS_COND 0x04
@@ -172,7 +180,7 @@
/* BL + imm24 */
# define PATCH_BL 0x60
/* 0xf00 cc code for branches */
-#endif
+#endif /* SLJIT_CONFIG_ARM_THUMB2 */
#if (defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64)
# define IS_COND 0x004
@@ -182,7 +190,7 @@
# define PATCH_COND 0x040
# define PATCH_ABS48 0x080
# define PATCH_ABS64 0x100
-#endif
+#endif /* SLJIT_CONFIG_ARM_64 */
#if (defined SLJIT_CONFIG_PPC && SLJIT_CONFIG_PPC)
# define IS_COND 0x004
@@ -192,9 +200,9 @@
#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
# define PATCH_ABS32 0x040
# define PATCH_ABS48 0x080
-#endif
+#endif /* SLJIT_CONFIG_PPC_64 */
# define REMOVE_COND 0x100
-#endif
+#endif /* SLJIT_CONFIG_PPC */
#if (defined SLJIT_CONFIG_MIPS && SLJIT_CONFIG_MIPS)
# define IS_MOVABLE 0x004
@@ -212,7 +220,7 @@
#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
# define PATCH_ABS32 0x400
# define PATCH_ABS48 0x800
-#endif
+#endif /* SLJIT_CONFIG_MIPS_64 */
/* instruction types */
# define MOVABLE_INS 0
@@ -221,43 +229,34 @@
# define UNMOVABLE_INS 32
/* FPU status register */
# define FCSR_FCC 33
-#endif
-
-#if (defined SLJIT_CONFIG_TILEGX && SLJIT_CONFIG_TILEGX)
-# define IS_JAL 0x04
-# define IS_COND 0x08
+#endif /* SLJIT_CONFIG_MIPS */
-# define PATCH_B 0x10
-# define PATCH_J 0x20
-#endif
-
-#if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32)
-# define IS_MOVABLE 0x04
-# define IS_COND 0x08
-# define IS_CALL 0x10
-
-# define PATCH_B 0x20
-# define PATCH_CALL 0x40
-
- /* instruction types */
-# define MOVABLE_INS 0
- /* 1 - 31 last destination register */
- /* no destination (i.e: store) */
-# define UNMOVABLE_INS 32
-
-# define DST_INS_MASK 0xff
+#if (defined SLJIT_CONFIG_RISCV && SLJIT_CONFIG_RISCV)
+# define IS_COND 0x004
+# define IS_CALL 0x008
- /* ICC_SET is the same as SET_FLAGS. */
-# define ICC_IS_SET (1 << 23)
-# define FCC_IS_SET (1 << 24)
-#endif
+# define PATCH_B 0x010
+# define PATCH_J 0x020
+
+#if (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64)
+# define PATCH_REL32 0x040
+# define PATCH_ABS32 0x080
+# define PATCH_ABS44 0x100
+# define PATCH_ABS52 0x200
+#else /* !SLJIT_CONFIG_RISCV_64 */
+# define PATCH_REL32 0x0
+#endif /* SLJIT_CONFIG_RISCV_64 */
+#endif /* SLJIT_CONFIG_RISCV */
/* Stack management. */
#define GET_SAVED_REGISTERS_SIZE(scratches, saveds, extra) \
(((scratches < SLJIT_NUMBER_OF_SCRATCH_REGISTERS ? 0 : (scratches - SLJIT_NUMBER_OF_SCRATCH_REGISTERS)) + \
- (saveds < SLJIT_NUMBER_OF_SAVED_REGISTERS ? saveds : SLJIT_NUMBER_OF_SAVED_REGISTERS) + \
- extra) * sizeof(sljit_sw))
+ (saveds) + (sljit_s32)(extra)) * (sljit_s32)sizeof(sljit_sw))
+
+#define GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, size) \
+ (((fscratches < SLJIT_NUMBER_OF_SCRATCH_FLOAT_REGISTERS ? 0 : (fscratches - SLJIT_NUMBER_OF_SCRATCH_FLOAT_REGISTERS)) + \
+ (fsaveds)) * (sljit_s32)(size))
#define ADJUST_LOCAL_OFFSET(p, i) \
if ((p) == (SLJIT_MEM1(SLJIT_SP))) \
@@ -274,6 +273,8 @@
#if (defined SLJIT_PROT_EXECUTABLE_ALLOCATOR && SLJIT_PROT_EXECUTABLE_ALLOCATOR)
#include "sljitProtExecAllocator.c"
+#elif (defined SLJIT_WX_EXECUTABLE_ALLOCATOR && SLJIT_WX_EXECUTABLE_ALLOCATOR)
+#include "sljitWXExecAllocator.c"
#else
#include "sljitExecAllocator.c"
#endif
@@ -286,6 +287,10 @@
#define SLJIT_ADD_EXEC_OFFSET(ptr, exec_offset) ((sljit_u8 *)(ptr))
#endif
+#ifndef SLJIT_UPDATE_WX_FLAGS
+#define SLJIT_UPDATE_WX_FLAGS(from, to, enable_exec)
+#endif
+
/* Argument checking features. */
#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
@@ -366,7 +371,7 @@ static sljit_s32 compiler_initialized = 0;
static void init_compiler(void);
#endif
-SLJIT_API_FUNC_ATTRIBUTE struct sljit_compiler* sljit_create_compiler(void *allocator_data)
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_compiler* sljit_create_compiler(void *allocator_data, void *exec_allocator_data)
{
struct sljit_compiler *compiler = (struct sljit_compiler*)SLJIT_MALLOC(sizeof(struct sljit_compiler), allocator_data);
if (!compiler)
@@ -382,17 +387,16 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_compiler* sljit_create_compiler(void *allo
&& (sizeof(sljit_sw) == 4 || sizeof(sljit_sw) == 8)
&& (sizeof(sljit_uw) == 4 || sizeof(sljit_uw) == 8),
invalid_integer_types);
- SLJIT_COMPILE_ASSERT(SLJIT_I32_OP == SLJIT_F32_OP,
- int_op_and_single_op_must_be_the_same);
- SLJIT_COMPILE_ASSERT(SLJIT_REWRITABLE_JUMP != SLJIT_F32_OP,
+ SLJIT_COMPILE_ASSERT(SLJIT_REWRITABLE_JUMP != SLJIT_32,
rewritable_jump_and_single_op_must_not_be_the_same);
- SLJIT_COMPILE_ASSERT(!(SLJIT_EQUAL & 0x1) && !(SLJIT_LESS & 0x1) && !(SLJIT_EQUAL_F64 & 0x1) && !(SLJIT_JUMP & 0x1),
+ SLJIT_COMPILE_ASSERT(!(SLJIT_EQUAL & 0x1) && !(SLJIT_LESS & 0x1) && !(SLJIT_F_EQUAL & 0x1) && !(SLJIT_JUMP & 0x1),
conditional_flags_must_be_even_numbers);
/* Only the non-zero members must be set. */
compiler->error = SLJIT_SUCCESS;
compiler->allocator_data = allocator_data;
+ compiler->exec_allocator_data = exec_allocator_data;
compiler->buf = (struct sljit_memory_fragment*)SLJIT_MALLOC(BUF_SIZE, allocator_data);
compiler->abuf = (struct sljit_memory_fragment*)SLJIT_MALLOC(ABUF_SIZE, allocator_data);
@@ -417,7 +421,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_compiler* sljit_create_compiler(void *allo
compiler->local_size = -1;
#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
- compiler->args = -1;
+ compiler->args_size = -1;
#endif
#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
@@ -437,8 +441,11 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_compiler* sljit_create_compiler(void *allo
compiler->delay_slot = UNMOVABLE_INS;
#endif
-#if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32)
- compiler->delay_slot = UNMOVABLE_INS;
+#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) \
+ || (defined SLJIT_DEBUG && SLJIT_DEBUG)
+ compiler->last_flags = 0;
+ compiler->last_return = -1;
+ compiler->logical_local_size = 0;
#endif
#if (defined SLJIT_NEEDS_COMPILER_INIT && SLJIT_NEEDS_COMPILER_INIT)
@@ -485,29 +492,35 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_set_compiler_memory_error(struct sljit_compi
}
#if (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2)
-SLJIT_API_FUNC_ATTRIBUTE void sljit_free_code(void* code)
+SLJIT_API_FUNC_ATTRIBUTE void sljit_free_code(void* code, void *exec_allocator_data)
{
+ SLJIT_UNUSED_ARG(exec_allocator_data);
+
/* Remove thumb mode flag. */
- SLJIT_FREE_EXEC((void*)((sljit_uw)code & ~0x1));
+ SLJIT_FREE_EXEC((void*)((sljit_uw)code & ~(sljit_uw)0x1), exec_allocator_data);
}
#elif (defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL)
-SLJIT_API_FUNC_ATTRIBUTE void sljit_free_code(void* code)
+SLJIT_API_FUNC_ATTRIBUTE void sljit_free_code(void* code, void *exec_allocator_data)
{
+ SLJIT_UNUSED_ARG(exec_allocator_data);
+
/* Resolve indirection. */
code = (void*)(*(sljit_uw*)code);
- SLJIT_FREE_EXEC(code);
+ SLJIT_FREE_EXEC(code, exec_allocator_data);
}
#else
-SLJIT_API_FUNC_ATTRIBUTE void sljit_free_code(void* code)
+SLJIT_API_FUNC_ATTRIBUTE void sljit_free_code(void* code, void *exec_allocator_data)
{
- SLJIT_FREE_EXEC(code);
+ SLJIT_UNUSED_ARG(exec_allocator_data);
+
+ SLJIT_FREE_EXEC(code, exec_allocator_data);
}
#endif
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_label(struct sljit_jump *jump, struct sljit_label* label)
{
if (SLJIT_LIKELY(!!jump) && SLJIT_LIKELY(!!label)) {
- jump->flags &= ~JUMP_ADDR;
+ jump->flags &= (sljit_uw)~JUMP_ADDR;
jump->flags |= JUMP_LABEL;
jump->u.label = label;
}
@@ -516,7 +529,7 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_set_label(struct sljit_jump *jump, struct sl
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_target(struct sljit_jump *jump, sljit_uw target)
{
if (SLJIT_LIKELY(!!jump)) {
- jump->flags &= ~JUMP_LABEL;
+ jump->flags &= (sljit_uw)~JUMP_LABEL;
jump->flags |= JUMP_ADDR;
jump->u.target = target;
}
@@ -528,14 +541,22 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_set_put_label(struct sljit_put_label *put_la
put_label->label = label;
}
+#define SLJIT_CURRENT_FLAGS_ALL \
+ (SLJIT_CURRENT_FLAGS_32 | SLJIT_CURRENT_FLAGS_ADD | SLJIT_CURRENT_FLAGS_SUB | SLJIT_CURRENT_FLAGS_COMPARE)
+
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_current_flags(struct sljit_compiler *compiler, sljit_s32 current_flags)
{
SLJIT_UNUSED_ARG(compiler);
SLJIT_UNUSED_ARG(current_flags);
+#if (defined SLJIT_HAS_STATUS_FLAGS_STATE && SLJIT_HAS_STATUS_FLAGS_STATE)
+ compiler->status_flags_state = current_flags;
+#endif
+
#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
- if ((current_flags & ~(VARIABLE_FLAG_MASK | SLJIT_I32_OP | SLJIT_SET_Z)) == 0) {
- compiler->last_flags = GET_FLAG_TYPE(current_flags) | (current_flags & (SLJIT_I32_OP | SLJIT_SET_Z));
+ compiler->last_flags = 0;
+ if ((current_flags & ~(VARIABLE_FLAG_MASK | SLJIT_SET_Z | SLJIT_CURRENT_FLAGS_ALL)) == 0) {
+ compiler->last_flags = GET_FLAG_TYPE(current_flags) | (current_flags & (SLJIT_32 | SLJIT_SET_Z));
}
#endif
}
@@ -595,7 +616,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_alloc_memory(struct sljit_compiler *compile
return NULL;
size = (size + 3) & ~3;
#endif
- return ensure_abuf(compiler, size);
+ return ensure_abuf(compiler, (sljit_uw)size);
}
static SLJIT_INLINE void reverse_buf(struct sljit_compiler *compiler)
@@ -614,20 +635,9 @@ static SLJIT_INLINE void reverse_buf(struct sljit_compiler *compiler)
compiler->buf = prev;
}
-static SLJIT_INLINE sljit_s32 get_arg_count(sljit_s32 arg_types)
-{
- sljit_s32 arg_count = 0;
-
- arg_types >>= SLJIT_DEF_SHIFT;
- while (arg_types) {
- arg_count++;
- arg_types >>= SLJIT_DEF_SHIFT;
- }
-
- return arg_count;
-}
-
-#if !(defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86)
+/* Only used in RISC architectures where the instruction size is constant */
+#if !(defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86) \
+ && !(defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X)
static SLJIT_INLINE sljit_uw compute_next_addr(struct sljit_label *label, struct sljit_jump *jump,
struct sljit_const *const_, struct sljit_put_label *put_label)
@@ -649,7 +659,7 @@ static SLJIT_INLINE sljit_uw compute_next_addr(struct sljit_label *label, struct
return result;
}
-#endif /* !SLJIT_CONFIG_X86 */
+#endif /* !SLJIT_CONFIG_X86 && !SLJIT_CONFIG_S390X */
static SLJIT_INLINE void set_emit_enter(struct sljit_compiler *compiler,
sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds,
@@ -664,6 +674,7 @@ static SLJIT_INLINE void set_emit_enter(struct sljit_compiler *compiler,
compiler->fscratches = fscratches;
compiler->fsaveds = fsaveds;
#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
+ compiler->last_return = args & SLJIT_ARG_MASK;
compiler->logical_local_size = local_size;
#endif
}
@@ -681,6 +692,7 @@ static SLJIT_INLINE void set_set_context(struct sljit_compiler *compiler,
compiler->fscratches = fscratches;
compiler->fsaveds = fsaveds;
#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
+ compiler->last_return = args & SLJIT_ARG_MASK;
compiler->logical_local_size = local_size;
#endif
}
@@ -696,7 +708,7 @@ static SLJIT_INLINE void set_label(struct sljit_label *label, struct sljit_compi
compiler->last_label = label;
}
-static SLJIT_INLINE void set_jump(struct sljit_jump *jump, struct sljit_compiler *compiler, sljit_s32 flags)
+static SLJIT_INLINE void set_jump(struct sljit_jump *jump, struct sljit_compiler *compiler, sljit_u32 flags)
{
jump->next = NULL;
jump->flags = flags;
@@ -736,6 +748,58 @@ static SLJIT_INLINE void set_put_label(struct sljit_put_label *put_label, struct
#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
+static sljit_s32 function_check_arguments(sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds, sljit_s32 fscratches)
+{
+ sljit_s32 word_arg_count, scratch_arg_end, saved_arg_count, float_arg_count, curr_type;
+
+ curr_type = (arg_types & SLJIT_ARG_FULL_MASK);
+
+ if (curr_type >= SLJIT_ARG_TYPE_F64) {
+ if (curr_type > SLJIT_ARG_TYPE_F32 || fscratches == 0)
+ return 0;
+ } else if (curr_type >= SLJIT_ARG_TYPE_W) {
+ if (scratches == 0)
+ return 0;
+ }
+
+ arg_types >>= SLJIT_ARG_SHIFT;
+
+ word_arg_count = 0;
+ scratch_arg_end = 0;
+ saved_arg_count = 0;
+ float_arg_count = 0;
+ while (arg_types != 0) {
+ if (word_arg_count + float_arg_count >= 4)
+ return 0;
+
+ curr_type = (arg_types & SLJIT_ARG_MASK);
+
+ if (arg_types & SLJIT_ARG_TYPE_SCRATCH_REG) {
+ if (saveds == -1 || curr_type < SLJIT_ARG_TYPE_W || curr_type > SLJIT_ARG_TYPE_P)
+ return 0;
+
+ word_arg_count++;
+ scratch_arg_end = word_arg_count;
+ } else {
+ if (curr_type < SLJIT_ARG_TYPE_W || curr_type > SLJIT_ARG_TYPE_F32)
+ return 0;
+
+ if (curr_type < SLJIT_ARG_TYPE_F64) {
+ word_arg_count++;
+ saved_arg_count++;
+ } else
+ float_arg_count++;
+ }
+
+ arg_types >>= SLJIT_ARG_SHIFT;
+ }
+
+ if (saveds == -1)
+ return (word_arg_count <= scratches && float_arg_count <= fscratches);
+
+ return (saved_arg_count <= saveds && scratch_arg_end <= scratches && float_arg_count <= fscratches);
+}
+
#define FUNCTION_CHECK_IS_REG(r) \
(((r) >= SLJIT_R0 && (r) < (SLJIT_R0 + compiler->scratches)) \
|| ((r) > (SLJIT_S0 - compiler->saveds) && (r) <= SLJIT_S0))
@@ -758,14 +822,17 @@ static sljit_s32 function_check_src_mem(struct sljit_compiler *compiler, sljit_s
if (!(p & SLJIT_MEM))
return 0;
- if (!((p & REG_MASK) == SLJIT_UNUSED || FUNCTION_CHECK_IS_REG(p & REG_MASK)))
+ if (p == SLJIT_MEM1(SLJIT_SP))
+ return (i >= 0 && i < compiler->logical_local_size);
+
+ if (!(!(p & REG_MASK) || FUNCTION_CHECK_IS_REG(p & REG_MASK)))
return 0;
if (CHECK_IF_VIRTUAL_REGISTER(p & REG_MASK))
return 0;
if (p & OFFS_REG_MASK) {
- if ((p & REG_MASK) == SLJIT_UNUSED)
+ if (!(p & REG_MASK))
return 0;
if (!(FUNCTION_CHECK_IS_REG(OFFS_REG(p))))
@@ -795,31 +862,25 @@ static sljit_s32 function_check_src(struct sljit_compiler *compiler, sljit_s32 p
if (p == SLJIT_IMM)
return 1;
- if (p == SLJIT_MEM1(SLJIT_SP))
- return (i >= 0 && i < compiler->logical_local_size);
-
return function_check_src_mem(compiler, p, i);
}
#define FUNCTION_CHECK_SRC(p, i) \
CHECK_ARGUMENT(function_check_src(compiler, p, i));
-static sljit_s32 function_check_dst(struct sljit_compiler *compiler, sljit_s32 p, sljit_sw i, sljit_s32 unused)
+static sljit_s32 function_check_dst(struct sljit_compiler *compiler, sljit_s32 p, sljit_sw i)
{
if (compiler->scratches == -1 || compiler->saveds == -1)
return 0;
- if (FUNCTION_CHECK_IS_REG(p) || ((unused) && (p) == SLJIT_UNUSED))
+ if (FUNCTION_CHECK_IS_REG(p))
return (i == 0);
- if (p == SLJIT_MEM1(SLJIT_SP))
- return (i >= 0 && i < compiler->logical_local_size);
-
return function_check_src_mem(compiler, p, i);
}
-#define FUNCTION_CHECK_DST(p, i, unused) \
- CHECK_ARGUMENT(function_check_dst(compiler, p, i, unused));
+#define FUNCTION_CHECK_DST(p, i) \
+ CHECK_ARGUMENT(function_check_dst(compiler, p, i));
static sljit_s32 function_fcheck(struct sljit_compiler *compiler, sljit_s32 p, sljit_sw i)
{
@@ -829,9 +890,6 @@ static sljit_s32 function_fcheck(struct sljit_compiler *compiler, sljit_s32 p, s
if (FUNCTION_CHECK_IS_FREG(p))
return (i == 0);
- if (p == SLJIT_MEM1(SLJIT_SP))
- return (i >= 0 && i < compiler->logical_local_size);
-
return function_check_src_mem(compiler, p, i);
}
@@ -849,7 +907,11 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_compiler_verbose(struct sljit_compiler *comp
#if (defined SLJIT_64BIT_ARCHITECTURE && SLJIT_64BIT_ARCHITECTURE)
#ifdef _WIN64
+#ifdef __GNUC__
+# define SLJIT_PRINT_D "ll"
+#else
# define SLJIT_PRINT_D "I64"
+#endif
#else
# define SLJIT_PRINT_D "l"
#endif
@@ -895,10 +957,8 @@ static void sljit_verbose_param(struct sljit_compiler *compiler, sljit_s32 p, sl
}
else
fprintf(compiler->verbose, "[#%" SLJIT_PRINT_D "d]", (i));
- } else if (p)
+ } else
sljit_verbose_reg(compiler, p);
- else
- fprintf(compiler->verbose, "unused");
}
static void sljit_verbose_fparam(struct sljit_compiler *compiler, sljit_s32 p, sljit_sw i)
@@ -925,64 +985,64 @@ static void sljit_verbose_fparam(struct sljit_compiler *compiler, sljit_s32 p, s
}
static const char* op0_names[] = {
- (char*)"breakpoint", (char*)"nop", (char*)"lmul.uw", (char*)"lmul.sw",
- (char*)"divmod.u", (char*)"divmod.s", (char*)"div.u", (char*)"div.s",
- (char*)"endbr", (char*)"skip_frames_before_return"
+ "breakpoint", "nop", "lmul.uw", "lmul.sw",
+ "divmod.u", "divmod.s", "div.u", "div.s",
+ "endbr", "skip_frames_before_return"
};
static const char* op1_names[] = {
- (char*)"", (char*)".u8", (char*)".s8", (char*)".u16",
- (char*)".s16", (char*)".u32", (char*)".s32", (char*)".p",
- (char*)"", (char*)".u8", (char*)".s8", (char*)".u16",
- (char*)".s16", (char*)".u32", (char*)".s32", (char*)".p",
- (char*)"not", (char*)"neg", (char*)"clz",
+ "", ".u8", ".s8", ".u16",
+ ".s16", ".u32", ".s32", "32",
+ ".p", "not", "clz", "ctz"
};
static const char* op2_names[] = {
- (char*)"add", (char*)"addc", (char*)"sub", (char*)"subc",
- (char*)"mul", (char*)"and", (char*)"or", (char*)"xor",
- (char*)"shl", (char*)"lshr", (char*)"ashr",
+ "add", "addc", "sub", "subc",
+ "mul", "and", "or", "xor",
+ "shl", "mshl", "lshr", "mlshr",
+ "ashr", "mashr", "rotl", "rotr"
};
static const char* op_src_names[] = {
- (char*)"fast_return", (char*)"skip_frames_before_fast_return",
- (char*)"prefetch_l1", (char*)"prefetch_l2",
- (char*)"prefetch_l3", (char*)"prefetch_once",
+ "fast_return", "skip_frames_before_fast_return",
+ "prefetch_l1", "prefetch_l2",
+ "prefetch_l3", "prefetch_once",
};
static const char* fop1_names[] = {
- (char*)"mov", (char*)"conv", (char*)"conv", (char*)"conv",
- (char*)"conv", (char*)"conv", (char*)"cmp", (char*)"neg",
- (char*)"abs",
+ "mov", "conv", "conv", "conv",
+ "conv", "conv", "cmp", "neg",
+ "abs",
};
static const char* fop2_names[] = {
- (char*)"add", (char*)"sub", (char*)"mul", (char*)"div"
+ "add", "sub", "mul", "div"
};
-#define JUMP_POSTFIX(type) \
- ((type & 0xff) <= SLJIT_MUL_NOT_OVERFLOW ? ((type & SLJIT_I32_OP) ? "32" : "") \
- : ((type & 0xff) <= SLJIT_ORDERED_F64 ? ((type & SLJIT_F32_OP) ? ".f32" : ".f64") : ""))
-
-static char* jump_names[] = {
- (char*)"equal", (char*)"not_equal",
- (char*)"less", (char*)"greater_equal",
- (char*)"greater", (char*)"less_equal",
- (char*)"sig_less", (char*)"sig_greater_equal",
- (char*)"sig_greater", (char*)"sig_less_equal",
- (char*)"overflow", (char*)"not_overflow",
- (char*)"mul_overflow", (char*)"mul_not_overflow",
- (char*)"carry", (char*)"",
- (char*)"equal", (char*)"not_equal",
- (char*)"less", (char*)"greater_equal",
- (char*)"greater", (char*)"less_equal",
- (char*)"unordered", (char*)"ordered",
- (char*)"jump", (char*)"fast_call",
- (char*)"call", (char*)"call.cdecl"
+static const char* jump_names[] = {
+ "equal", "not_equal",
+ "less", "greater_equal",
+ "greater", "less_equal",
+ "sig_less", "sig_greater_equal",
+ "sig_greater", "sig_less_equal",
+ "overflow", "not_overflow",
+ "carry", "",
+ "f_equal", "f_not_equal",
+ "f_less", "f_greater_equal",
+ "f_greater", "f_less_equal",
+ "unordered", "ordered",
+ "ordered_equal", "unordered_or_not_equal",
+ "ordered_less", "unordered_or_greater_equal",
+ "ordered_greater", "unordered_or_less_equal",
+ "unordered_or_equal", "ordered_not_equal",
+ "unordered_or_less", "ordered_greater_equal",
+ "unordered_or_greater", "ordered_less_equal",
+ "jump", "fast_call",
+ "call", "call_reg_arg"
};
-static char* call_arg_names[] = {
- (char*)"void", (char*)"sw", (char*)"uw", (char*)"s32", (char*)"u32", (char*)"f32", (char*)"f64"
+static const char* call_arg_names[] = {
+ "void", "w", "32", "p", "f64", "f32"
};
#endif /* SLJIT_VERBOSE */
@@ -994,6 +1054,8 @@ static char* call_arg_names[] = {
#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) \
|| (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
+#define SLJIT_SKIP_CHECKS(compiler) (compiler)->skip_checks = 1
+
static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_generate_code(struct sljit_compiler *compiler)
{
#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
@@ -1018,48 +1080,53 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_enter(struct sljit_compil
sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds,
sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size)
{
-#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
- sljit_s32 types, arg_count, curr_type;
-#endif
-
SLJIT_UNUSED_ARG(compiler);
#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
- CHECK_ARGUMENT(!(options & ~SLJIT_F64_ALIGNMENT));
+ if (options & SLJIT_ENTER_REG_ARG) {
+ CHECK_ARGUMENT(!(options & ~(0x3 | SLJIT_ENTER_REG_ARG)));
+ } else {
+ CHECK_ARGUMENT(options == 0);
+ }
+ CHECK_ARGUMENT(SLJIT_KEPT_SAVEDS_COUNT(options) <= 3 && SLJIT_KEPT_SAVEDS_COUNT(options) <= saveds);
CHECK_ARGUMENT(scratches >= 0 && scratches <= SLJIT_NUMBER_OF_REGISTERS);
- CHECK_ARGUMENT(saveds >= 0 && saveds <= SLJIT_NUMBER_OF_REGISTERS);
+ CHECK_ARGUMENT(saveds >= 0 && saveds <= SLJIT_NUMBER_OF_SAVED_REGISTERS);
CHECK_ARGUMENT(scratches + saveds <= SLJIT_NUMBER_OF_REGISTERS);
CHECK_ARGUMENT(fscratches >= 0 && fscratches <= SLJIT_NUMBER_OF_FLOAT_REGISTERS);
- CHECK_ARGUMENT(fsaveds >= 0 && fsaveds <= SLJIT_NUMBER_OF_FLOAT_REGISTERS);
+ CHECK_ARGUMENT(fsaveds >= 0 && fsaveds <= SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS);
CHECK_ARGUMENT(fscratches + fsaveds <= SLJIT_NUMBER_OF_FLOAT_REGISTERS);
CHECK_ARGUMENT(local_size >= 0 && local_size <= SLJIT_MAX_LOCAL_SIZE);
- CHECK_ARGUMENT((arg_types & SLJIT_DEF_MASK) == 0);
-
- types = (arg_types >> SLJIT_DEF_SHIFT);
- arg_count = 0;
- while (types != 0 && arg_count < 3) {
- curr_type = (types & SLJIT_DEF_MASK);
- CHECK_ARGUMENT(curr_type == SLJIT_ARG_TYPE_SW || curr_type == SLJIT_ARG_TYPE_UW);
- arg_count++;
- types >>= SLJIT_DEF_SHIFT;
- }
- CHECK_ARGUMENT(arg_count <= saveds && types == 0);
+ CHECK_ARGUMENT((arg_types & SLJIT_ARG_FULL_MASK) <= SLJIT_ARG_TYPE_F32);
+ CHECK_ARGUMENT(function_check_arguments(arg_types, scratches, (options & SLJIT_ENTER_REG_ARG) ? 0 : saveds, fscratches));
compiler->last_flags = 0;
#endif
#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
if (SLJIT_UNLIKELY(!!compiler->verbose)) {
- fprintf(compiler->verbose, " enter options:%s args[", (options & SLJIT_F64_ALIGNMENT) ? "f64_align" : "");
-
- arg_types >>= SLJIT_DEF_SHIFT;
- while (arg_types) {
- fprintf(compiler->verbose, "%s", call_arg_names[arg_types & SLJIT_DEF_MASK]);
- arg_types >>= SLJIT_DEF_SHIFT;
- if (arg_types)
- fprintf(compiler->verbose, ",");
+ fprintf(compiler->verbose, " enter ret[%s", call_arg_names[arg_types & SLJIT_ARG_MASK]);
+
+ arg_types >>= SLJIT_ARG_SHIFT;
+ if (arg_types) {
+ fprintf(compiler->verbose, "], args[");
+ do {
+ fprintf(compiler->verbose, "%s%s", call_arg_names[arg_types & SLJIT_ARG_MASK],
+ (arg_types & SLJIT_ARG_TYPE_SCRATCH_REG) ? "_r" : "");
+ arg_types >>= SLJIT_ARG_SHIFT;
+ if (arg_types)
+ fprintf(compiler->verbose, ",");
+ } while (arg_types);
}
- fprintf(compiler->verbose, "] scratches:%d saveds:%d fscratches:%d fsaveds:%d local_size:%d\n",
+ fprintf(compiler->verbose, "],");
+
+ if (options & SLJIT_ENTER_REG_ARG) {
+ fprintf(compiler->verbose, " enter:reg_arg,");
+
+ if (SLJIT_KEPT_SAVEDS_COUNT(options) > 0)
+ fprintf(compiler->verbose, " keep:%d,", SLJIT_KEPT_SAVEDS_COUNT(options));
+ }
+
+ fprintf(compiler->verbose, "scratches:%d, saveds:%d, fscratches:%d, fsaveds:%d, local_size:%d\n",
scratches, saveds, fscratches, fsaveds, local_size);
}
#endif
@@ -1070,74 +1137,141 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_set_context(struct sljit_compi
sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds,
sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size)
{
-#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
- sljit_s32 types, arg_count, curr_type;
-#endif
-
SLJIT_UNUSED_ARG(compiler);
#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
- CHECK_ARGUMENT(!(options & ~SLJIT_F64_ALIGNMENT));
+ if (options & SLJIT_ENTER_REG_ARG) {
+ CHECK_ARGUMENT(!(options & ~(0x3 | SLJIT_ENTER_REG_ARG)));
+ } else {
+ CHECK_ARGUMENT(options == 0);
+ }
+ CHECK_ARGUMENT(SLJIT_KEPT_SAVEDS_COUNT(options) <= 3 && SLJIT_KEPT_SAVEDS_COUNT(options) <= saveds);
CHECK_ARGUMENT(scratches >= 0 && scratches <= SLJIT_NUMBER_OF_REGISTERS);
- CHECK_ARGUMENT(saveds >= 0 && saveds <= SLJIT_NUMBER_OF_REGISTERS);
+ CHECK_ARGUMENT(saveds >= 0 && saveds <= SLJIT_NUMBER_OF_SAVED_REGISTERS);
CHECK_ARGUMENT(scratches + saveds <= SLJIT_NUMBER_OF_REGISTERS);
CHECK_ARGUMENT(fscratches >= 0 && fscratches <= SLJIT_NUMBER_OF_FLOAT_REGISTERS);
- CHECK_ARGUMENT(fsaveds >= 0 && fsaveds <= SLJIT_NUMBER_OF_FLOAT_REGISTERS);
+ CHECK_ARGUMENT(fsaveds >= 0 && fsaveds <= SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS);
CHECK_ARGUMENT(fscratches + fsaveds <= SLJIT_NUMBER_OF_FLOAT_REGISTERS);
CHECK_ARGUMENT(local_size >= 0 && local_size <= SLJIT_MAX_LOCAL_SIZE);
-
- types = (arg_types >> SLJIT_DEF_SHIFT);
- arg_count = 0;
- while (types != 0 && arg_count < 3) {
- curr_type = (types & SLJIT_DEF_MASK);
- CHECK_ARGUMENT(curr_type == SLJIT_ARG_TYPE_SW || curr_type == SLJIT_ARG_TYPE_UW);
- arg_count++;
- types >>= SLJIT_DEF_SHIFT;
- }
- CHECK_ARGUMENT(arg_count <= saveds && types == 0);
+ CHECK_ARGUMENT((arg_types & SLJIT_ARG_FULL_MASK) < SLJIT_ARG_TYPE_F64);
+ CHECK_ARGUMENT(function_check_arguments(arg_types, scratches, (options & SLJIT_ENTER_REG_ARG) ? 0 : saveds, fscratches));
compiler->last_flags = 0;
#endif
#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
if (SLJIT_UNLIKELY(!!compiler->verbose)) {
- fprintf(compiler->verbose, " set_context options:%s args[", (options & SLJIT_F64_ALIGNMENT) ? "f64_align" : "");
-
- arg_types >>= SLJIT_DEF_SHIFT;
- while (arg_types) {
- fprintf(compiler->verbose, "%s", call_arg_names[arg_types & SLJIT_DEF_MASK]);
- arg_types >>= SLJIT_DEF_SHIFT;
- if (arg_types)
- fprintf(compiler->verbose, ",");
+ fprintf(compiler->verbose, " set_context ret[%s", call_arg_names[arg_types & SLJIT_ARG_MASK]);
+
+ arg_types >>= SLJIT_ARG_SHIFT;
+ if (arg_types) {
+ fprintf(compiler->verbose, "], args[");
+ do {
+ fprintf(compiler->verbose, "%s%s", call_arg_names[arg_types & SLJIT_ARG_MASK],
+ (arg_types & SLJIT_ARG_TYPE_SCRATCH_REG) ? "_r" : "");
+ arg_types >>= SLJIT_ARG_SHIFT;
+ if (arg_types)
+ fprintf(compiler->verbose, ",");
+ } while (arg_types);
}
- fprintf(compiler->verbose, "] scratches:%d saveds:%d fscratches:%d fsaveds:%d local_size:%d\n",
+ fprintf(compiler->verbose, "],");
+
+ if (options & SLJIT_ENTER_REG_ARG) {
+ fprintf(compiler->verbose, " enter:reg_arg,");
+
+ if (SLJIT_KEPT_SAVEDS_COUNT(options) > 0)
+ fprintf(compiler->verbose, " keep:%d,", SLJIT_KEPT_SAVEDS_COUNT(options));
+ }
+
+ fprintf(compiler->verbose, " scratches:%d, saveds:%d, fscratches:%d, fsaveds:%d, local_size:%d\n",
scratches, saveds, fscratches, fsaveds, local_size);
}
#endif
CHECK_RETURN_OK;
}
+static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_return_void(struct sljit_compiler *compiler)
+{
+ if (SLJIT_UNLIKELY(compiler->skip_checks)) {
+ compiler->skip_checks = 0;
+ CHECK_RETURN_OK;
+ }
+
+#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
+ CHECK_ARGUMENT(compiler->last_return == SLJIT_ARG_TYPE_VOID);
+#endif
+
+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
+ if (SLJIT_UNLIKELY(!!compiler->verbose)) {
+ fprintf(compiler->verbose, " return_void\n");
+ }
+#endif
+ CHECK_RETURN_OK;
+}
+
static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_return(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 src, sljit_sw srcw)
{
#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
CHECK_ARGUMENT(compiler->scratches >= 0);
- if (op != SLJIT_UNUSED) {
- CHECK_ARGUMENT(op >= SLJIT_MOV && op <= SLJIT_MOV_P);
+
+ switch (compiler->last_return) {
+ case SLJIT_ARG_TYPE_W:
+ CHECK_ARGUMENT(op >= SLJIT_MOV && op <= SLJIT_MOV_S32);
+ break;
+ case SLJIT_ARG_TYPE_32:
+ CHECK_ARGUMENT(op == SLJIT_MOV32 || (op >= SLJIT_MOV32_U8 && op <= SLJIT_MOV32_S16));
+ break;
+ case SLJIT_ARG_TYPE_P:
+ CHECK_ARGUMENT(op == SLJIT_MOV_P);
+ break;
+ case SLJIT_ARG_TYPE_F64:
+ CHECK_ARGUMENT(sljit_has_cpu_feature(SLJIT_HAS_FPU));
+ CHECK_ARGUMENT(op == SLJIT_MOV_F64);
+ break;
+ case SLJIT_ARG_TYPE_F32:
+ CHECK_ARGUMENT(sljit_has_cpu_feature(SLJIT_HAS_FPU));
+ CHECK_ARGUMENT(op == SLJIT_MOV_F32);
+ break;
+ default:
+ /* Context not initialized, void, etc. */
+ CHECK_ARGUMENT(0);
+ break;
+ }
+
+ if (GET_OPCODE(op) < SLJIT_MOV_F64) {
FUNCTION_CHECK_SRC(src, srcw);
+ } else {
+ FUNCTION_FCHECK(src, srcw);
}
- else
- CHECK_ARGUMENT(src == 0 && srcw == 0);
compiler->last_flags = 0;
#endif
#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
if (SLJIT_UNLIKELY(!!compiler->verbose)) {
- if (op == SLJIT_UNUSED)
- fprintf(compiler->verbose, " return\n");
- else {
- fprintf(compiler->verbose, " return%s ", op1_names[op - SLJIT_OP1_BASE]);
+ if (GET_OPCODE(op) < SLJIT_MOV_F64) {
+ fprintf(compiler->verbose, " return%s%s ", !(op & SLJIT_32) ? "" : "32",
+ op1_names[GET_OPCODE(op) - SLJIT_OP1_BASE]);
sljit_verbose_param(compiler, src, srcw);
- fprintf(compiler->verbose, "\n");
+ } else {
+ fprintf(compiler->verbose, " return%s ", !(op & SLJIT_32) ? ".f64" : ".f32");
+ sljit_verbose_fparam(compiler, src, srcw);
}
+ fprintf(compiler->verbose, "\n");
+ }
+#endif
+ CHECK_RETURN_OK;
+}
+
+static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_return_to(struct sljit_compiler *compiler,
+ sljit_s32 src, sljit_sw srcw)
+{
+#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
+ FUNCTION_CHECK_SRC(src, srcw);
+#endif
+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
+ if (SLJIT_UNLIKELY(!!compiler->verbose)) {
+ fprintf(compiler->verbose, " return_to ");
+ sljit_verbose_param(compiler, src, srcw);
+ fprintf(compiler->verbose, "\n");
}
#endif
CHECK_RETURN_OK;
@@ -1146,7 +1280,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_return(struct sljit_compi
static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw)
{
#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
- FUNCTION_CHECK_DST(dst, dstw, 0);
+ FUNCTION_CHECK_DST(dst, dstw);
compiler->last_flags = 0;
#endif
#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
@@ -1163,7 +1297,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op0(struct sljit_compiler
{
#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
CHECK_ARGUMENT((op >= SLJIT_BREAKPOINT && op <= SLJIT_LMUL_SW)
- || ((op & ~SLJIT_I32_OP) >= SLJIT_DIVMOD_UW && (op & ~SLJIT_I32_OP) <= SLJIT_DIV_SW)
+ || ((op & ~SLJIT_32) >= SLJIT_DIVMOD_UW && (op & ~SLJIT_32) <= SLJIT_DIV_SW)
|| (op >= SLJIT_ENDBR && op <= SLJIT_SKIP_FRAMES_BEFORE_RETURN));
CHECK_ARGUMENT(GET_OPCODE(op) < SLJIT_LMUL_UW || GET_OPCODE(op) >= SLJIT_ENDBR || compiler->scratches >= 2);
if ((GET_OPCODE(op) >= SLJIT_LMUL_UW && GET_OPCODE(op) <= SLJIT_DIV_SW) || op == SLJIT_SKIP_FRAMES_BEFORE_RETURN)
@@ -1174,7 +1308,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op0(struct sljit_compiler
{
fprintf(compiler->verbose, " %s", op0_names[GET_OPCODE(op) - SLJIT_OP0_BASE]);
if (GET_OPCODE(op) >= SLJIT_DIVMOD_UW && GET_OPCODE(op) <= SLJIT_DIV_SW) {
- fprintf(compiler->verbose, (op & SLJIT_I32_OP) ? "32" : "w");
+ fprintf(compiler->verbose, (op & SLJIT_32) ? "32" : "w");
}
fprintf(compiler->verbose, "\n");
}
@@ -1192,47 +1326,43 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op1(struct sljit_compiler
}
#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
- CHECK_ARGUMENT(GET_OPCODE(op) >= SLJIT_MOV && GET_OPCODE(op) <= SLJIT_CLZ);
+ CHECK_ARGUMENT(GET_OPCODE(op) >= SLJIT_MOV && GET_OPCODE(op) <= SLJIT_CTZ);
switch (GET_OPCODE(op)) {
case SLJIT_NOT:
- /* Only SLJIT_I32_OP and SLJIT_SET_Z are allowed. */
+ /* Only SLJIT_32 and SLJIT_SET_Z are allowed. */
CHECK_ARGUMENT(!(op & VARIABLE_FLAG_MASK));
break;
- case SLJIT_NEG:
- CHECK_ARGUMENT(!(op & VARIABLE_FLAG_MASK)
- || GET_FLAG_TYPE(op) == SLJIT_OVERFLOW);
- break;
case SLJIT_MOV:
case SLJIT_MOV_U32:
case SLJIT_MOV_P:
/* Nothing allowed */
- CHECK_ARGUMENT(!(op & (SLJIT_I32_OP | SLJIT_SET_Z | VARIABLE_FLAG_MASK)));
+ CHECK_ARGUMENT(!(op & (SLJIT_32 | SLJIT_SET_Z | VARIABLE_FLAG_MASK)));
break;
default:
- /* Only SLJIT_I32_OP is allowed. */
+ /* Only SLJIT_32 is allowed. */
CHECK_ARGUMENT(!(op & (SLJIT_SET_Z | VARIABLE_FLAG_MASK)));
break;
}
- FUNCTION_CHECK_DST(dst, dstw, HAS_FLAGS(op));
+ FUNCTION_CHECK_DST(dst, dstw);
FUNCTION_CHECK_SRC(src, srcw);
if (GET_OPCODE(op) >= SLJIT_NOT) {
CHECK_ARGUMENT(src != SLJIT_IMM);
- compiler->last_flags = GET_FLAG_TYPE(op) | (op & (SLJIT_I32_OP | SLJIT_SET_Z));
+ compiler->last_flags = GET_FLAG_TYPE(op) | (op & (SLJIT_32 | SLJIT_SET_Z));
}
#endif
#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
if (SLJIT_UNLIKELY(!!compiler->verbose)) {
if (GET_OPCODE(op) <= SLJIT_MOV_P)
{
- fprintf(compiler->verbose, " mov%s%s ", !(op & SLJIT_I32_OP) ? "" : "32",
- (op != SLJIT_MOV32) ? op1_names[GET_OPCODE(op) - SLJIT_OP1_BASE] : "");
+ fprintf(compiler->verbose, " mov%s%s ", !(op & SLJIT_32) ? "" : "32",
+ op1_names[GET_OPCODE(op) - SLJIT_OP1_BASE]);
}
else
{
- fprintf(compiler->verbose, " %s%s%s%s%s ", op1_names[GET_OPCODE(op) - SLJIT_OP1_BASE], !(op & SLJIT_I32_OP) ? "" : "32",
+ fprintf(compiler->verbose, " %s%s%s%s%s ", op1_names[GET_OPCODE(op) - SLJIT_OP1_BASE], !(op & SLJIT_32) ? "" : "32",
!(op & SLJIT_SET_Z) ? "" : ".z", !(op & VARIABLE_FLAG_MASK) ? "" : ".",
!(op & VARIABLE_FLAG_MASK) ? "" : jump_names[GET_FLAG_TYPE(op)]);
}
@@ -1246,7 +1376,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op1(struct sljit_compiler
CHECK_RETURN_OK;
}
-static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op2(struct sljit_compiler *compiler, sljit_s32 op,
+static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op2(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 unset,
sljit_s32 dst, sljit_sw dstw,
sljit_s32 src1, sljit_sw src1w,
sljit_s32 src2, sljit_sw src2w)
@@ -1257,21 +1387,24 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op2(struct sljit_compiler
}
#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
- CHECK_ARGUMENT(GET_OPCODE(op) >= SLJIT_ADD && GET_OPCODE(op) <= SLJIT_ASHR);
+ CHECK_ARGUMENT(GET_OPCODE(op) >= SLJIT_ADD && GET_OPCODE(op) <= SLJIT_ROTR);
switch (GET_OPCODE(op)) {
case SLJIT_AND:
case SLJIT_OR:
case SLJIT_XOR:
case SLJIT_SHL:
+ case SLJIT_MSHL:
case SLJIT_LSHR:
+ case SLJIT_MLSHR:
case SLJIT_ASHR:
+ case SLJIT_MASHR:
CHECK_ARGUMENT(!(op & VARIABLE_FLAG_MASK));
break;
case SLJIT_MUL:
CHECK_ARGUMENT(!(op & SLJIT_SET_Z));
CHECK_ARGUMENT(!(op & VARIABLE_FLAG_MASK)
- || GET_FLAG_TYPE(op) == SLJIT_MUL_OVERFLOW);
+ || GET_FLAG_TYPE(op) == SLJIT_OVERFLOW);
break;
case SLJIT_ADD:
CHECK_ARGUMENT(!(op & VARIABLE_FLAG_MASK)
@@ -1288,24 +1421,64 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op2(struct sljit_compiler
CHECK_ARGUMENT(!(op & VARIABLE_FLAG_MASK)
|| GET_FLAG_TYPE(op) == GET_FLAG_TYPE(SLJIT_SET_CARRY));
CHECK_ARGUMENT((compiler->last_flags & 0xff) == GET_FLAG_TYPE(SLJIT_SET_CARRY));
- CHECK_ARGUMENT((op & SLJIT_I32_OP) == (compiler->last_flags & SLJIT_I32_OP));
+ CHECK_ARGUMENT((op & SLJIT_32) == (compiler->last_flags & SLJIT_32));
+ break;
+ case SLJIT_ROTL:
+ case SLJIT_ROTR:
+ CHECK_ARGUMENT(!(op & (SLJIT_SET_Z | VARIABLE_FLAG_MASK)));
break;
default:
SLJIT_UNREACHABLE();
break;
}
- FUNCTION_CHECK_DST(dst, dstw, HAS_FLAGS(op));
+ if (unset) {
+ CHECK_ARGUMENT(HAS_FLAGS(op));
+ } else {
+ FUNCTION_CHECK_DST(dst, dstw);
+ }
FUNCTION_CHECK_SRC(src1, src1w);
FUNCTION_CHECK_SRC(src2, src2w);
- compiler->last_flags = GET_FLAG_TYPE(op) | (op & (SLJIT_I32_OP | SLJIT_SET_Z));
+ compiler->last_flags = GET_FLAG_TYPE(op) | (op & (SLJIT_32 | SLJIT_SET_Z));
#endif
#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
if (SLJIT_UNLIKELY(!!compiler->verbose)) {
- fprintf(compiler->verbose, " %s%s%s%s%s ", op2_names[GET_OPCODE(op) - SLJIT_OP2_BASE], !(op & SLJIT_I32_OP) ? "" : "32",
+ fprintf(compiler->verbose, " %s%s%s%s%s ", op2_names[GET_OPCODE(op) - SLJIT_OP2_BASE], !(op & SLJIT_32) ? "" : "32",
!(op & SLJIT_SET_Z) ? "" : ".z", !(op & VARIABLE_FLAG_MASK) ? "" : ".",
!(op & VARIABLE_FLAG_MASK) ? "" : jump_names[GET_FLAG_TYPE(op)]);
- sljit_verbose_param(compiler, dst, dstw);
+ if (unset)
+ fprintf(compiler->verbose, "unset");
+ else
+ sljit_verbose_param(compiler, dst, dstw);
+ fprintf(compiler->verbose, ", ");
+ sljit_verbose_param(compiler, src1, src1w);
+ fprintf(compiler->verbose, ", ");
+ sljit_verbose_param(compiler, src2, src2w);
+ fprintf(compiler->verbose, "\n");
+ }
+#endif
+ CHECK_RETURN_OK;
+}
+
+static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_shift_into(struct sljit_compiler *compiler, sljit_s32 op,
+ sljit_s32 src_dst,
+ sljit_s32 src1, sljit_sw src1w,
+ sljit_s32 src2, sljit_sw src2w)
+{
+#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
+ CHECK_ARGUMENT(GET_OPCODE(op) == SLJIT_SHL || GET_OPCODE(op) == SLJIT_LSHR
+ || GET_OPCODE(op) == SLJIT_MSHL || GET_OPCODE(op) == SLJIT_MLSHR);
+ CHECK_ARGUMENT((op & ~(0xff | SLJIT_32 | SLJIT_SHIFT_INTO_NON_ZERO)) == 0);
+ CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(src_dst));
+ FUNCTION_CHECK_SRC(src1, src1w);
+ FUNCTION_CHECK_SRC(src2, src2w);
+#endif
+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
+ if (SLJIT_UNLIKELY(!!compiler->verbose)) {
+ fprintf(compiler->verbose, " %s%s.into%s ", op2_names[GET_OPCODE(op) - SLJIT_OP2_BASE], !(op & SLJIT_32) ? "" : "32",
+ (op & SLJIT_SHIFT_INTO_NON_ZERO) ? ".nz" : "");
+
+ sljit_verbose_reg(compiler, src_dst);
fprintf(compiler->verbose, ", ");
sljit_verbose_param(compiler, src1, src1w);
fprintf(compiler->verbose, ", ");
@@ -1362,10 +1535,10 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_get_float_register_index(sljit
}
static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op_custom(struct sljit_compiler *compiler,
- void *instruction, sljit_s32 size)
+ void *instruction, sljit_u32 size)
{
#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
- int i;
+ sljit_u32 i;
#endif
SLJIT_UNUSED_ARG(compiler);
@@ -1378,6 +1551,8 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op_custom(struct sljit_co
#elif (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2)
CHECK_ARGUMENT((size == 2 && (((sljit_sw)instruction) & 0x1) == 0)
|| (size == 4 && (((sljit_sw)instruction) & 0x3) == 0));
+#elif (defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X)
+ CHECK_ARGUMENT(size == 2 || size == 4 || size == 6);
#else
CHECK_ARGUMENT(size == 4 && (((sljit_sw)instruction) & 0x3) == 0);
#endif
@@ -1415,10 +1590,10 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fop1(struct sljit_compile
if (SLJIT_UNLIKELY(!!compiler->verbose)) {
if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_F32)
fprintf(compiler->verbose, " %s%s ", fop1_names[SLJIT_CONV_F64_FROM_F32 - SLJIT_FOP1_BASE],
- (op & SLJIT_F32_OP) ? ".f32.from.f64" : ".f64.from.f32");
+ (op & SLJIT_32) ? ".f32.from.f64" : ".f64.from.f32");
else
fprintf(compiler->verbose, " %s%s ", fop1_names[GET_OPCODE(op) - SLJIT_FOP1_BASE],
- (op & SLJIT_F32_OP) ? ".f32" : ".f64");
+ (op & SLJIT_32) ? ".f32" : ".f64");
sljit_verbose_fparam(compiler, dst, dstw);
fprintf(compiler->verbose, ", ");
@@ -1434,7 +1609,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fop1_cmp(struct sljit_com
sljit_s32 src2, sljit_sw src2w)
{
#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
- compiler->last_flags = GET_FLAG_TYPE(op) | (op & (SLJIT_I32_OP | SLJIT_SET_Z));
+ compiler->last_flags = GET_FLAG_TYPE(op) | (op & SLJIT_32);
#endif
if (SLJIT_UNLIKELY(compiler->skip_checks)) {
@@ -1447,15 +1622,15 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fop1_cmp(struct sljit_com
CHECK_ARGUMENT(GET_OPCODE(op) == SLJIT_CMP_F64);
CHECK_ARGUMENT(!(op & SLJIT_SET_Z));
CHECK_ARGUMENT((op & VARIABLE_FLAG_MASK)
- || (GET_FLAG_TYPE(op) >= SLJIT_EQUAL_F64 && GET_FLAG_TYPE(op) <= SLJIT_ORDERED_F64));
+ || (GET_FLAG_TYPE(op) >= SLJIT_F_EQUAL && GET_FLAG_TYPE(op) <= SLJIT_ORDERED_LESS_EQUAL));
FUNCTION_FCHECK(src1, src1w);
FUNCTION_FCHECK(src2, src2w);
#endif
#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
if (SLJIT_UNLIKELY(!!compiler->verbose)) {
- fprintf(compiler->verbose, " %s%s", fop1_names[SLJIT_CMP_F64 - SLJIT_FOP1_BASE], (op & SLJIT_F32_OP) ? ".f32" : ".f64");
+ fprintf(compiler->verbose, " %s%s", fop1_names[SLJIT_CMP_F64 - SLJIT_FOP1_BASE], (op & SLJIT_32) ? ".f32" : ".f64");
if (op & VARIABLE_FLAG_MASK) {
- fprintf(compiler->verbose, ".%s_f", jump_names[GET_FLAG_TYPE(op)]);
+ fprintf(compiler->verbose, ".%s", jump_names[GET_FLAG_TYPE(op)]);
}
fprintf(compiler->verbose, " ");
sljit_verbose_fparam(compiler, src1, src1w);
@@ -1481,13 +1656,13 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fop1_conv_sw_from_f64(str
CHECK_ARGUMENT(GET_OPCODE(op) >= SLJIT_CONV_SW_FROM_F64 && GET_OPCODE(op) <= SLJIT_CONV_S32_FROM_F64);
CHECK_ARGUMENT(!(op & (SLJIT_SET_Z | VARIABLE_FLAG_MASK)));
FUNCTION_FCHECK(src, srcw);
- FUNCTION_CHECK_DST(dst, dstw, 0);
+ FUNCTION_CHECK_DST(dst, dstw);
#endif
#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
if (SLJIT_UNLIKELY(!!compiler->verbose)) {
fprintf(compiler->verbose, " %s%s.from%s ", fop1_names[GET_OPCODE(op) - SLJIT_FOP1_BASE],
(GET_OPCODE(op) == SLJIT_CONV_S32_FROM_F64) ? ".s32" : ".sw",
- (op & SLJIT_F32_OP) ? ".f32" : ".f64");
+ (op & SLJIT_32) ? ".f32" : ".f64");
sljit_verbose_param(compiler, dst, dstw);
fprintf(compiler->verbose, ", ");
sljit_verbose_fparam(compiler, src, srcw);
@@ -1516,7 +1691,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fop1_conv_f64_from_sw(str
#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
if (SLJIT_UNLIKELY(!!compiler->verbose)) {
fprintf(compiler->verbose, " %s%s.from%s ", fop1_names[GET_OPCODE(op) - SLJIT_FOP1_BASE],
- (op & SLJIT_F32_OP) ? ".f32" : ".f64",
+ (op & SLJIT_32) ? ".f32" : ".f64",
(GET_OPCODE(op) == SLJIT_CONV_F64_FROM_S32) ? ".s32" : ".sw");
sljit_verbose_fparam(compiler, dst, dstw);
fprintf(compiler->verbose, ", ");
@@ -1542,7 +1717,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fop2(struct sljit_compile
#endif
#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
if (SLJIT_UNLIKELY(!!compiler->verbose)) {
- fprintf(compiler->verbose, " %s%s ", fop2_names[GET_OPCODE(op) - SLJIT_FOP2_BASE], (op & SLJIT_F32_OP) ? ".f32" : ".f64");
+ fprintf(compiler->verbose, " %s%s ", fop2_names[GET_OPCODE(op) - SLJIT_FOP2_BASE], (op & SLJIT_32) ? ".f32" : ".f64");
sljit_verbose_fparam(compiler, dst, dstw);
fprintf(compiler->verbose, ", ");
sljit_verbose_fparam(compiler, src1, src1w);
@@ -1574,6 +1749,17 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_label(struct sljit_compil
CHECK_RETURN_OK;
}
+#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
+#if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86) \
+ || (defined SLJIT_CONFIG_ARM && SLJIT_CONFIG_ARM)
+#define CHECK_UNORDERED(type, last_flags) \
+ ((((type) & 0xff) == SLJIT_UNORDERED || ((type) & 0xff) == SLJIT_ORDERED) && \
+ ((last_flags) & 0xff) >= SLJIT_UNORDERED && ((last_flags) & 0xff) <= SLJIT_ORDERED_LESS_EQUAL)
+#else
+#define CHECK_UNORDERED(type, last_flags) 0
+#endif
+#endif /* SLJIT_ARGUMENT_CHECKS */
+
static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_jump(struct sljit_compiler *compiler, sljit_s32 type)
{
if (SLJIT_UNLIKELY(compiler->skip_checks)) {
@@ -1582,25 +1768,25 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_jump(struct sljit_compile
}
#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
- CHECK_ARGUMENT(!(type & ~(0xff | SLJIT_REWRITABLE_JUMP | SLJIT_I32_OP)));
- CHECK_ARGUMENT((type & 0xff) != GET_FLAG_TYPE(SLJIT_SET_CARRY) && (type & 0xff) != (GET_FLAG_TYPE(SLJIT_SET_CARRY) + 1));
+ CHECK_ARGUMENT(!(type & ~(0xff | SLJIT_REWRITABLE_JUMP)));
CHECK_ARGUMENT((type & 0xff) >= SLJIT_EQUAL && (type & 0xff) <= SLJIT_FAST_CALL);
- CHECK_ARGUMENT((type & 0xff) < SLJIT_JUMP || !(type & SLJIT_I32_OP));
if ((type & 0xff) < SLJIT_JUMP) {
if ((type & 0xff) <= SLJIT_NOT_ZERO)
CHECK_ARGUMENT(compiler->last_flags & SLJIT_SET_Z);
- else
+ else if ((compiler->last_flags & 0xff) == SLJIT_CARRY) {
+ CHECK_ARGUMENT((type & 0xff) == SLJIT_CARRY || (type & 0xff) == SLJIT_NOT_CARRY);
+ compiler->last_flags = 0;
+ } else
CHECK_ARGUMENT((type & 0xff) == (compiler->last_flags & 0xff)
|| ((type & 0xff) == SLJIT_NOT_OVERFLOW && (compiler->last_flags & 0xff) == SLJIT_OVERFLOW)
- || ((type & 0xff) == SLJIT_MUL_NOT_OVERFLOW && (compiler->last_flags & 0xff) == SLJIT_MUL_OVERFLOW));
- CHECK_ARGUMENT((type & SLJIT_I32_OP) == (compiler->last_flags & SLJIT_I32_OP));
+ || CHECK_UNORDERED(type, compiler->last_flags));
}
#endif
#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
if (SLJIT_UNLIKELY(!!compiler->verbose))
- fprintf(compiler->verbose, " jump%s %s%s\n", !(type & SLJIT_REWRITABLE_JUMP) ? "" : ".r",
- jump_names[type & 0xff], JUMP_POSTFIX(type));
+ fprintf(compiler->verbose, " jump%s %s\n", !(type & SLJIT_REWRITABLE_JUMP) ? "" : ".r",
+ jump_names[type & 0xff]);
#endif
CHECK_RETURN_OK;
}
@@ -1609,49 +1795,33 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_call(struct sljit_compile
sljit_s32 arg_types)
{
#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
- sljit_s32 i, types, curr_type, scratches, fscratches;
+ CHECK_ARGUMENT(!(type & ~(0xff | SLJIT_REWRITABLE_JUMP | SLJIT_CALL_RETURN)));
+ CHECK_ARGUMENT((type & 0xff) >= SLJIT_CALL && (type & 0xff) <= SLJIT_CALL_REG_ARG);
+ CHECK_ARGUMENT(function_check_arguments(arg_types, compiler->scratches, -1, compiler->fscratches));
- CHECK_ARGUMENT(!(type & ~(0xff | SLJIT_REWRITABLE_JUMP)));
- CHECK_ARGUMENT((type & 0xff) == SLJIT_CALL || (type & 0xff) == SLJIT_CALL_CDECL);
-
- types = arg_types;
- scratches = 0;
- fscratches = 0;
- for (i = 0; i < 5; i++) {
- curr_type = (types & SLJIT_DEF_MASK);
- CHECK_ARGUMENT(curr_type <= SLJIT_ARG_TYPE_F64);
- if (i > 0) {
- if (curr_type == 0) {
- break;
- }
- if (curr_type >= SLJIT_ARG_TYPE_F32)
- fscratches++;
- else
- scratches++;
+ if (type & SLJIT_CALL_RETURN) {
+ CHECK_ARGUMENT((arg_types & SLJIT_ARG_MASK) == compiler->last_return);
+
+ if (compiler->options & SLJIT_ENTER_REG_ARG) {
+ CHECK_ARGUMENT((type & 0xff) == SLJIT_CALL_REG_ARG);
} else {
- if (curr_type >= SLJIT_ARG_TYPE_F32) {
- CHECK_ARGUMENT(compiler->fscratches > 0);
- } else if (curr_type >= SLJIT_ARG_TYPE_SW) {
- CHECK_ARGUMENT(compiler->scratches > 0);
- }
+ CHECK_ARGUMENT((type & 0xff) != SLJIT_CALL_REG_ARG);
}
- types >>= SLJIT_DEF_SHIFT;
}
- CHECK_ARGUMENT(compiler->scratches >= scratches);
- CHECK_ARGUMENT(compiler->fscratches >= fscratches);
- CHECK_ARGUMENT(types == 0);
#endif
#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
if (SLJIT_UNLIKELY(!!compiler->verbose)) {
- fprintf(compiler->verbose, " %s%s ret[%s", jump_names[type & 0xff],
- !(type & SLJIT_REWRITABLE_JUMP) ? "" : ".r", call_arg_names[arg_types & SLJIT_DEF_MASK]);
+ fprintf(compiler->verbose, " %s%s%s ret[%s", jump_names[type & 0xff],
+ !(type & SLJIT_REWRITABLE_JUMP) ? "" : ".r",
+ !(type & SLJIT_CALL_RETURN) ? "" : ".ret",
+ call_arg_names[arg_types & SLJIT_ARG_MASK]);
- arg_types >>= SLJIT_DEF_SHIFT;
+ arg_types >>= SLJIT_ARG_SHIFT;
if (arg_types) {
fprintf(compiler->verbose, "], args[");
do {
- fprintf(compiler->verbose, "%s", call_arg_names[arg_types & SLJIT_DEF_MASK]);
- arg_types >>= SLJIT_DEF_SHIFT;
+ fprintf(compiler->verbose, "%s", call_arg_names[arg_types & SLJIT_ARG_MASK]);
+ arg_types >>= SLJIT_ARG_SHIFT;
if (arg_types)
fprintf(compiler->verbose, ",");
} while (arg_types);
@@ -1667,7 +1837,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_cmp(struct sljit_compiler
sljit_s32 src2, sljit_sw src2w)
{
#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
- CHECK_ARGUMENT(!(type & ~(0xff | SLJIT_REWRITABLE_JUMP | SLJIT_I32_OP)));
+ CHECK_ARGUMENT(!(type & ~(0xff | SLJIT_REWRITABLE_JUMP | SLJIT_32)));
CHECK_ARGUMENT((type & 0xff) >= SLJIT_EQUAL && (type & 0xff) <= SLJIT_SIG_LESS_EQUAL);
FUNCTION_CHECK_SRC(src1, src1w);
FUNCTION_CHECK_SRC(src2, src2w);
@@ -1675,8 +1845,8 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_cmp(struct sljit_compiler
#endif
#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
if (SLJIT_UNLIKELY(!!compiler->verbose)) {
- fprintf(compiler->verbose, " cmp%s %s%s, ", !(type & SLJIT_REWRITABLE_JUMP) ? "" : ".r",
- jump_names[type & 0xff], (type & SLJIT_I32_OP) ? "32" : "");
+ fprintf(compiler->verbose, " cmp%s%s %s, ", (type & SLJIT_32) ? "32" : "",
+ !(type & SLJIT_REWRITABLE_JUMP) ? "" : ".r", jump_names[type & 0xff]);
sljit_verbose_param(compiler, src1, src1w);
fprintf(compiler->verbose, ", ");
sljit_verbose_param(compiler, src2, src2w);
@@ -1692,16 +1862,17 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fcmp(struct sljit_compile
{
#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
CHECK_ARGUMENT(sljit_has_cpu_feature(SLJIT_HAS_FPU));
- CHECK_ARGUMENT(!(type & ~(0xff | SLJIT_REWRITABLE_JUMP | SLJIT_F32_OP)));
- CHECK_ARGUMENT((type & 0xff) >= SLJIT_EQUAL_F64 && (type & 0xff) <= SLJIT_ORDERED_F64);
+ CHECK_ARGUMENT(!(type & ~(0xff | SLJIT_REWRITABLE_JUMP | SLJIT_32)));
+ CHECK_ARGUMENT((type & 0xff) >= SLJIT_F_EQUAL && (type & 0xff) <= SLJIT_ORDERED_LESS_EQUAL
+ && ((type & 0xff) <= SLJIT_ORDERED || sljit_cmp_info(type & 0xff)));
FUNCTION_FCHECK(src1, src1w);
FUNCTION_FCHECK(src2, src2w);
compiler->last_flags = 0;
#endif
#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
if (SLJIT_UNLIKELY(!!compiler->verbose)) {
- fprintf(compiler->verbose, " fcmp%s %s%s, ", !(type & SLJIT_REWRITABLE_JUMP) ? "" : ".r",
- jump_names[type & 0xff], (type & SLJIT_F32_OP) ? ".f32" : ".f64");
+ fprintf(compiler->verbose, " fcmp%s%s %s, ", (type & SLJIT_32) ? ".f32" : ".f64",
+ !(type & SLJIT_REWRITABLE_JUMP) ? "" : ".r", jump_names[type & 0xff]);
sljit_verbose_fparam(compiler, src1, src1w);
fprintf(compiler->verbose, ", ");
sljit_verbose_fparam(compiler, src2, src2w);
@@ -1738,49 +1909,33 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_icall(struct sljit_compil
sljit_s32 src, sljit_sw srcw)
{
#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
- sljit_s32 i, types, curr_type, scratches, fscratches;
-
- CHECK_ARGUMENT(type == SLJIT_CALL || type == SLJIT_CALL_CDECL);
+ CHECK_ARGUMENT(!(type & ~(0xff | SLJIT_CALL_RETURN)));
+ CHECK_ARGUMENT((type & 0xff) >= SLJIT_CALL && (type & 0xff) <= SLJIT_CALL_REG_ARG);
+ CHECK_ARGUMENT(function_check_arguments(arg_types, compiler->scratches, -1, compiler->fscratches));
FUNCTION_CHECK_SRC(src, srcw);
- types = arg_types;
- scratches = 0;
- fscratches = 0;
- for (i = 0; i < 5; i++) {
- curr_type = (types & SLJIT_DEF_MASK);
- CHECK_ARGUMENT(curr_type <= SLJIT_ARG_TYPE_F64);
- if (i > 0) {
- if (curr_type == 0) {
- break;
- }
- if (curr_type >= SLJIT_ARG_TYPE_F32)
- fscratches++;
- else
- scratches++;
+ if (type & SLJIT_CALL_RETURN) {
+ CHECK_ARGUMENT((arg_types & SLJIT_ARG_MASK) == compiler->last_return);
+
+ if (compiler->options & SLJIT_ENTER_REG_ARG) {
+ CHECK_ARGUMENT((type & 0xff) == SLJIT_CALL_REG_ARG);
} else {
- if (curr_type >= SLJIT_ARG_TYPE_F32) {
- CHECK_ARGUMENT(compiler->fscratches > 0);
- } else if (curr_type >= SLJIT_ARG_TYPE_SW) {
- CHECK_ARGUMENT(compiler->scratches > 0);
- }
+ CHECK_ARGUMENT((type & 0xff) != SLJIT_CALL_REG_ARG);
}
- types >>= SLJIT_DEF_SHIFT;
}
- CHECK_ARGUMENT(compiler->scratches >= scratches);
- CHECK_ARGUMENT(compiler->fscratches >= fscratches);
- CHECK_ARGUMENT(types == 0);
#endif
#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
if (SLJIT_UNLIKELY(!!compiler->verbose)) {
fprintf(compiler->verbose, " i%s%s ret[%s", jump_names[type & 0xff],
- !(type & SLJIT_REWRITABLE_JUMP) ? "" : ".r", call_arg_names[arg_types & SLJIT_DEF_MASK]);
+ !(type & SLJIT_CALL_RETURN) ? "" : ".ret",
+ call_arg_names[arg_types & SLJIT_ARG_MASK]);
- arg_types >>= SLJIT_DEF_SHIFT;
+ arg_types >>= SLJIT_ARG_SHIFT;
if (arg_types) {
fprintf(compiler->verbose, "], args[");
do {
- fprintf(compiler->verbose, "%s", call_arg_names[arg_types & SLJIT_DEF_MASK]);
- arg_types >>= SLJIT_DEF_SHIFT;
+ fprintf(compiler->verbose, "%s", call_arg_names[arg_types & SLJIT_ARG_MASK]);
+ arg_types >>= SLJIT_ARG_SHIFT;
if (arg_types)
fprintf(compiler->verbose, ",");
} while (arg_types);
@@ -1798,33 +1953,32 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op_flags(struct sljit_com
sljit_s32 type)
{
#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
- CHECK_ARGUMENT(!(type & ~(0xff | SLJIT_I32_OP)));
- CHECK_ARGUMENT((type & 0xff) >= SLJIT_EQUAL && (type & 0xff) <= SLJIT_ORDERED_F64);
- CHECK_ARGUMENT((type & 0xff) != GET_FLAG_TYPE(SLJIT_SET_CARRY) && (type & 0xff) != (GET_FLAG_TYPE(SLJIT_SET_CARRY) + 1));
+ CHECK_ARGUMENT(type >= SLJIT_EQUAL && type <= SLJIT_ORDERED_LESS_EQUAL);
CHECK_ARGUMENT(op == SLJIT_MOV || op == SLJIT_MOV32
|| (GET_OPCODE(op) >= SLJIT_AND && GET_OPCODE(op) <= SLJIT_XOR));
CHECK_ARGUMENT(!(op & VARIABLE_FLAG_MASK));
- if ((type & 0xff) <= SLJIT_NOT_ZERO)
+ if (type <= SLJIT_NOT_ZERO)
CHECK_ARGUMENT(compiler->last_flags & SLJIT_SET_Z);
else
- CHECK_ARGUMENT((type & 0xff) == (compiler->last_flags & 0xff)
- || ((type & 0xff) == SLJIT_NOT_OVERFLOW && (compiler->last_flags & 0xff) == SLJIT_OVERFLOW)
- || ((type & 0xff) == SLJIT_MUL_NOT_OVERFLOW && (compiler->last_flags & 0xff) == SLJIT_MUL_OVERFLOW));
+ CHECK_ARGUMENT(type == (compiler->last_flags & 0xff)
+ || (type == SLJIT_NOT_CARRY && (compiler->last_flags & 0xff) == SLJIT_CARRY)
+ || (type == SLJIT_NOT_OVERFLOW && (compiler->last_flags & 0xff) == SLJIT_OVERFLOW)
+ || CHECK_UNORDERED(type, compiler->last_flags));
- FUNCTION_CHECK_DST(dst, dstw, 0);
+ FUNCTION_CHECK_DST(dst, dstw);
if (GET_OPCODE(op) >= SLJIT_ADD)
- compiler->last_flags = GET_FLAG_TYPE(op) | (op & (SLJIT_I32_OP | SLJIT_SET_Z));
+ compiler->last_flags = GET_FLAG_TYPE(op) | (op & (SLJIT_32 | SLJIT_SET_Z));
#endif
#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
if (SLJIT_UNLIKELY(!!compiler->verbose)) {
- fprintf(compiler->verbose, " flags%s %s%s, ",
- !(op & SLJIT_SET_Z) ? "" : ".z",
+ fprintf(compiler->verbose, " flags.%s%s%s ",
GET_OPCODE(op) < SLJIT_OP2_BASE ? "mov" : op2_names[GET_OPCODE(op) - SLJIT_OP2_BASE],
- GET_OPCODE(op) < SLJIT_OP2_BASE ? op1_names[GET_OPCODE(op) - SLJIT_OP1_BASE] : ((op & SLJIT_I32_OP) ? "32" : ""));
+ GET_OPCODE(op) < SLJIT_OP2_BASE ? op1_names[GET_OPCODE(op) - SLJIT_OP1_BASE] : ((op & SLJIT_32) ? "32" : ""),
+ !(op & SLJIT_SET_Z) ? "" : ".z");
sljit_verbose_param(compiler, dst, dstw);
- fprintf(compiler->verbose, ", %s%s\n", jump_names[type & 0xff], JUMP_POSTFIX(type));
+ fprintf(compiler->verbose, ", %s\n", jump_names[type]);
}
#endif
CHECK_RETURN_OK;
@@ -1835,29 +1989,31 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_cmov(struct sljit_compile
sljit_s32 src, sljit_sw srcw)
{
#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
- CHECK_ARGUMENT(!(type & ~(0xff | SLJIT_I32_OP)));
- CHECK_ARGUMENT((type & 0xff) >= SLJIT_EQUAL && (type & 0xff) <= SLJIT_ORDERED_F64);
+ sljit_s32 cond = type & ~SLJIT_32;
+
+ CHECK_ARGUMENT(cond >= SLJIT_EQUAL && cond <= SLJIT_ORDERED_LESS_EQUAL);
CHECK_ARGUMENT(compiler->scratches != -1 && compiler->saveds != -1);
- CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(dst_reg & ~SLJIT_I32_OP));
+ CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(dst_reg));
if (src != SLJIT_IMM) {
CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(src));
CHECK_ARGUMENT(srcw == 0);
}
- if ((type & 0xff) <= SLJIT_NOT_ZERO)
+ if (cond <= SLJIT_NOT_ZERO)
CHECK_ARGUMENT(compiler->last_flags & SLJIT_SET_Z);
else
- CHECK_ARGUMENT((type & 0xff) == (compiler->last_flags & 0xff)
- || ((type & 0xff) == SLJIT_NOT_OVERFLOW && (compiler->last_flags & 0xff) == SLJIT_OVERFLOW)
- || ((type & 0xff) == SLJIT_MUL_NOT_OVERFLOW && (compiler->last_flags & 0xff) == SLJIT_MUL_OVERFLOW));
+ CHECK_ARGUMENT(cond == (compiler->last_flags & 0xff)
+ || (cond == SLJIT_NOT_CARRY && (compiler->last_flags & 0xff) == SLJIT_CARRY)
+ || (cond == SLJIT_NOT_OVERFLOW && (compiler->last_flags & 0xff) == SLJIT_OVERFLOW)
+ || CHECK_UNORDERED(cond, compiler->last_flags));
#endif
#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
if (SLJIT_UNLIKELY(!!compiler->verbose)) {
- fprintf(compiler->verbose, " cmov%s %s%s, ",
- !(dst_reg & SLJIT_I32_OP) ? "" : "32",
- jump_names[type & 0xff], JUMP_POSTFIX(type));
- sljit_verbose_reg(compiler, dst_reg & ~SLJIT_I32_OP);
+ fprintf(compiler->verbose, " cmov%s %s, ",
+ !(type & SLJIT_32) ? "" : "32",
+ jump_names[type & ~SLJIT_32]);
+ sljit_verbose_reg(compiler, dst_reg);
fprintf(compiler->verbose, ", ");
sljit_verbose_param(compiler, src, srcw);
fprintf(compiler->verbose, "\n");
@@ -1870,28 +2026,123 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_mem(struct sljit_compiler
sljit_s32 reg,
sljit_s32 mem, sljit_sw memw)
{
+ if (SLJIT_UNLIKELY(compiler->skip_checks)) {
+ compiler->skip_checks = 0;
+ CHECK_RETURN_OK;
+ }
+
#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
- CHECK_ARGUMENT((type & 0xff) >= SLJIT_MOV && (type & 0xff) <= SLJIT_MOV_P);
- CHECK_ARGUMENT(!(type & SLJIT_I32_OP) || ((type & 0xff) != SLJIT_MOV && (type & 0xff) != SLJIT_MOV_U32 && (type & 0xff) != SLJIT_MOV_P));
- CHECK_ARGUMENT((type & SLJIT_MEM_PRE) || (type & SLJIT_MEM_POST));
- CHECK_ARGUMENT((type & (SLJIT_MEM_PRE | SLJIT_MEM_POST)) != (SLJIT_MEM_PRE | SLJIT_MEM_POST));
- CHECK_ARGUMENT((type & ~(0xff | SLJIT_I32_OP | SLJIT_MEM_STORE | SLJIT_MEM_SUPP | SLJIT_MEM_PRE | SLJIT_MEM_POST)) == 0);
+ sljit_s32 allowed_flags;
+
+ if (type & SLJIT_MEM_UNALIGNED) {
+ CHECK_ARGUMENT(!(type & (SLJIT_MEM_UNALIGNED_16 | SLJIT_MEM_UNALIGNED_32)));
+ } else if (type & SLJIT_MEM_UNALIGNED_16) {
+ CHECK_ARGUMENT(!(type & SLJIT_MEM_UNALIGNED_32));
+ } else {
+ CHECK_ARGUMENT((reg & REG_PAIR_MASK) || (type & SLJIT_MEM_UNALIGNED_32));
+ }
+
+ allowed_flags = SLJIT_MEM_UNALIGNED;
+
+ switch (type & 0xff) {
+ case SLJIT_MOV_U32:
+ case SLJIT_MOV_S32:
+ case SLJIT_MOV32:
+ allowed_flags = SLJIT_MEM_UNALIGNED | SLJIT_MEM_UNALIGNED_16;
+ break;
+ case SLJIT_MOV:
+ case SLJIT_MOV_P:
+ allowed_flags = SLJIT_MEM_UNALIGNED | SLJIT_MEM_UNALIGNED_16 | SLJIT_MEM_UNALIGNED_32;
+ break;
+ }
+
+ CHECK_ARGUMENT((type & ~(0xff | SLJIT_32 | SLJIT_MEM_STORE | allowed_flags)) == 0);
+
+ if (reg & REG_PAIR_MASK) {
+ CHECK_ARGUMENT((type & 0xff) == SLJIT_MOV);
+ CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(REG_PAIR_FIRST(reg)));
+ CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(REG_PAIR_SECOND(reg)));
+ CHECK_ARGUMENT(REG_PAIR_FIRST(reg) != REG_PAIR_SECOND(reg));
+ } else {
+ CHECK_ARGUMENT((type & 0xff) >= SLJIT_MOV && (type & 0xff) <= SLJIT_MOV_P);
+ CHECK_ARGUMENT(!(type & SLJIT_32) || ((type & 0xff) >= SLJIT_MOV_U8 && (type & 0xff) <= SLJIT_MOV_S16));
+ CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(reg));
+ }
FUNCTION_CHECK_SRC_MEM(mem, memw);
- CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(reg));
+#endif
+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
+ if (SLJIT_UNLIKELY(!!compiler->verbose)) {
+ if ((type & 0xff) == SLJIT_MOV32)
+ fprintf(compiler->verbose, " %s32",
+ (type & SLJIT_MEM_STORE) ? "store" : "load");
+ else
+ fprintf(compiler->verbose, " %s%s%s",
+ (type & SLJIT_MEM_STORE) ? "store" : "load",
+ !(type & SLJIT_32) ? "" : "32",
+ op1_names[(type & 0xff) - SLJIT_OP1_BASE]);
+
+ if (type & SLJIT_MEM_UNALIGNED)
+ printf(".un");
+ else if (type & SLJIT_MEM_UNALIGNED_16)
+ printf(".un16");
+ else if (type & SLJIT_MEM_UNALIGNED_32)
+ printf(".un32");
+
+ if (reg & REG_PAIR_MASK) {
+ fprintf(compiler->verbose, " {");
+ sljit_verbose_reg(compiler, REG_PAIR_FIRST(reg));
+ fprintf(compiler->verbose, ", ");
+ sljit_verbose_reg(compiler, REG_PAIR_SECOND(reg));
+ fprintf(compiler->verbose, "}, ");
+ } else {
+ fprintf(compiler->verbose, " ");
+ sljit_verbose_reg(compiler, reg);
+ fprintf(compiler->verbose, ", ");
+ }
+ sljit_verbose_param(compiler, mem, memw);
+ fprintf(compiler->verbose, "\n");
+ }
+#endif
+ CHECK_RETURN_OK;
+}
+
+static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_mem_update(struct sljit_compiler *compiler, sljit_s32 type,
+ sljit_s32 reg,
+ sljit_s32 mem, sljit_sw memw)
+{
+ if (SLJIT_UNLIKELY(compiler->skip_checks)) {
+ compiler->skip_checks = 0;
+ CHECK_RETURN_OK;
+ }
- CHECK_ARGUMENT((mem & REG_MASK) != SLJIT_UNUSED && (mem & REG_MASK) != reg);
+#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
+ CHECK_ARGUMENT((type & 0xff) >= SLJIT_MOV && (type & 0xff) <= SLJIT_MOV_P);
+ CHECK_ARGUMENT((type & ~(0xff | SLJIT_32 | SLJIT_MEM_STORE | SLJIT_MEM_SUPP | SLJIT_MEM_POST)) == 0);
+ CHECK_ARGUMENT((mem & REG_MASK) != 0 && (mem & REG_MASK) != reg);
+
+ FUNCTION_CHECK_SRC_MEM(mem, memw);
#endif
#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
- if (!(type & SLJIT_MEM_SUPP) && SLJIT_UNLIKELY(!!compiler->verbose)) {
- if (sljit_emit_mem(compiler, type | SLJIT_MEM_SUPP, reg, mem, memw) == SLJIT_ERR_UNSUPPORTED)
- fprintf(compiler->verbose, " //");
-
- fprintf(compiler->verbose, " mem%s.%s%s%s ",
- !(type & SLJIT_I32_OP) ? "" : "32",
- (type & SLJIT_MEM_STORE) ? "st" : "ld",
- op1_names[(type & 0xff) - SLJIT_OP1_BASE],
- (type & SLJIT_MEM_PRE) ? ".pre" : ".post");
+ if (SLJIT_UNLIKELY(!!compiler->verbose)) {
+ if (type & SLJIT_MEM_SUPP)
+ CHECK_RETURN_OK;
+ if (sljit_emit_mem_update(compiler, type | SLJIT_MEM_SUPP, reg, mem, memw) == SLJIT_ERR_UNSUPPORTED) {
+ fprintf(compiler->verbose, " # mem: unsupported form, no instructions are emitted\n");
+ CHECK_RETURN_OK;
+ }
+
+ if ((type & 0xff) == SLJIT_MOV32)
+ fprintf(compiler->verbose, " %s32.%s ",
+ (type & SLJIT_MEM_STORE) ? "store" : "load",
+ (type & SLJIT_MEM_POST) ? "post" : "pre");
+ else
+ fprintf(compiler->verbose, " %s%s%s.%s ",
+ (type & SLJIT_MEM_STORE) ? "store" : "load",
+ !(type & SLJIT_32) ? "" : "32",
+ op1_names[(type & 0xff) - SLJIT_OP1_BASE],
+ (type & SLJIT_MEM_POST) ? "post" : "pre");
+
sljit_verbose_reg(compiler, reg);
fprintf(compiler->verbose, ", ");
sljit_verbose_param(compiler, mem, memw);
@@ -1907,22 +2158,67 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fmem(struct sljit_compile
{
#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
CHECK_ARGUMENT((type & 0xff) == SLJIT_MOV_F64);
- CHECK_ARGUMENT((type & SLJIT_MEM_PRE) || (type & SLJIT_MEM_POST));
- CHECK_ARGUMENT((type & (SLJIT_MEM_PRE | SLJIT_MEM_POST)) != (SLJIT_MEM_PRE | SLJIT_MEM_POST));
- CHECK_ARGUMENT((type & ~(0xff | SLJIT_I32_OP | SLJIT_MEM_STORE | SLJIT_MEM_SUPP | SLJIT_MEM_PRE | SLJIT_MEM_POST)) == 0);
+ if (type & SLJIT_MEM_UNALIGNED) {
+ CHECK_ARGUMENT(!(type & (SLJIT_MEM_UNALIGNED_16 | SLJIT_MEM_UNALIGNED_32)));
+ } else if (type & SLJIT_MEM_UNALIGNED_16) {
+ CHECK_ARGUMENT(!(type & SLJIT_MEM_UNALIGNED_32));
+ } else {
+ CHECK_ARGUMENT(type & SLJIT_MEM_UNALIGNED_32);
+ CHECK_ARGUMENT(!(type & SLJIT_32));
+ }
+
+ CHECK_ARGUMENT(!(type & ~(0xff | SLJIT_32 | SLJIT_MEM_STORE | SLJIT_MEM_UNALIGNED | SLJIT_MEM_UNALIGNED_16 | SLJIT_MEM_UNALIGNED_32)));
+ CHECK_ARGUMENT(FUNCTION_CHECK_IS_FREG(freg));
+ FUNCTION_CHECK_SRC_MEM(mem, memw);
+#endif
+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
+ if (SLJIT_UNLIKELY(!!compiler->verbose)) {
+ fprintf(compiler->verbose, " %s.%s",
+ (type & SLJIT_MEM_STORE) ? "store" : "load",
+ !(type & SLJIT_32) ? "f64" : "f32");
+
+ if (type & SLJIT_MEM_UNALIGNED)
+ printf(".un");
+ else if (type & SLJIT_MEM_UNALIGNED_16)
+ printf(".un16");
+ else if (type & SLJIT_MEM_UNALIGNED_32)
+ printf(".un32");
+
+ fprintf(compiler->verbose, " ");
+ sljit_verbose_freg(compiler, freg);
+ fprintf(compiler->verbose, ", ");
+ sljit_verbose_param(compiler, mem, memw);
+ fprintf(compiler->verbose, "\n");
+ }
+#endif
+ CHECK_RETURN_OK;
+}
+
+static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fmem_update(struct sljit_compiler *compiler, sljit_s32 type,
+ sljit_s32 freg,
+ sljit_s32 mem, sljit_sw memw)
+{
+#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
+ CHECK_ARGUMENT((type & 0xff) == SLJIT_MOV_F64);
+ CHECK_ARGUMENT((type & ~(0xff | SLJIT_32 | SLJIT_MEM_STORE | SLJIT_MEM_SUPP | SLJIT_MEM_POST)) == 0);
FUNCTION_CHECK_SRC_MEM(mem, memw);
CHECK_ARGUMENT(FUNCTION_CHECK_IS_FREG(freg));
#endif
#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
- if (!(type & SLJIT_MEM_SUPP) && SLJIT_UNLIKELY(!!compiler->verbose)) {
- if (sljit_emit_fmem(compiler, type | SLJIT_MEM_SUPP, freg, mem, memw) == SLJIT_ERR_UNSUPPORTED)
- fprintf(compiler->verbose, " //");
-
- fprintf(compiler->verbose, " fmem.%s%s%s ",
- (type & SLJIT_MEM_STORE) ? "st" : "ld",
- !(type & SLJIT_I32_OP) ? ".f64" : ".f32",
- (type & SLJIT_MEM_PRE) ? ".pre" : ".post");
+ if (SLJIT_UNLIKELY(!!compiler->verbose)) {
+ if (type & SLJIT_MEM_SUPP)
+ CHECK_RETURN_OK;
+ if (sljit_emit_fmem_update(compiler, type | SLJIT_MEM_SUPP, freg, mem, memw) == SLJIT_ERR_UNSUPPORTED) {
+ fprintf(compiler->verbose, " # fmem: unsupported form, no instructions are emitted\n");
+ CHECK_RETURN_OK;
+ }
+
+ fprintf(compiler->verbose, " %s.%s.%s ",
+ (type & SLJIT_MEM_STORE) ? "store" : "load",
+ !(type & SLJIT_32) ? "f64" : "f32",
+ (type & SLJIT_MEM_POST) ? "post" : "pre");
+
sljit_verbose_freg(compiler, freg);
fprintf(compiler->verbose, ", ");
sljit_verbose_param(compiler, mem, memw);
@@ -1930,6 +2226,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fmem(struct sljit_compile
}
#endif
CHECK_RETURN_OK;
+
}
static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_get_local_base(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw offset)
@@ -1938,7 +2235,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_get_local_base(struct sljit_co
SLJIT_UNUSED_ARG(offset);
#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
- FUNCTION_CHECK_DST(dst, dstw, 0);
+ FUNCTION_CHECK_DST(dst, dstw);
#endif
#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
if (SLJIT_UNLIKELY(!!compiler->verbose)) {
@@ -1955,7 +2252,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_const(struct sljit_compil
SLJIT_UNUSED_ARG(init_value);
#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
- FUNCTION_CHECK_DST(dst, dstw, 0);
+ FUNCTION_CHECK_DST(dst, dstw);
#endif
#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
if (SLJIT_UNLIKELY(!!compiler->verbose)) {
@@ -1970,7 +2267,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_const(struct sljit_compil
static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_put_label(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw)
{
#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
- FUNCTION_CHECK_DST(dst, dstw, 0);
+ FUNCTION_CHECK_DST(dst, dstw);
#endif
#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
if (SLJIT_UNLIKELY(!!compiler->verbose)) {
@@ -1982,6 +2279,10 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_put_label(struct sljit_co
CHECK_RETURN_OK;
}
+#else /* !SLJIT_ARGUMENT_CHECKS && !SLJIT_VERBOSE */
+
+#define SLJIT_SKIP_CHECKS(compiler)
+
#endif /* SLJIT_ARGUMENT_CHECKS || SLJIT_VERBOSE */
#define SELECT_FOP1_OPERATION_WITH_CHECKS(compiler, op, dst, dstw, src, srcw) \
@@ -2009,32 +2310,11 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_put_label(struct sljit_co
ADJUST_LOCAL_OFFSET(dst, dstw); \
ADJUST_LOCAL_OFFSET(src, srcw);
-static SLJIT_INLINE sljit_s32 emit_mov_before_return(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 src, sljit_sw srcw)
-{
- /* Return if don't need to do anything. */
- if (op == SLJIT_UNUSED)
- return SLJIT_SUCCESS;
-
-#if (defined SLJIT_64BIT_ARCHITECTURE && SLJIT_64BIT_ARCHITECTURE)
- /* At the moment the pointer size is always equal to sljit_sw. May be changed in the future. */
- if (src == SLJIT_RETURN_REG && (op == SLJIT_MOV || op == SLJIT_MOV_P))
- return SLJIT_SUCCESS;
-#else
- if (src == SLJIT_RETURN_REG && (op == SLJIT_MOV || op == SLJIT_MOV_U32 || op == SLJIT_MOV_S32 || op == SLJIT_MOV_P))
- return SLJIT_SUCCESS;
-#endif
-
-#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) \
- || (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
- compiler->skip_checks = 1;
-#endif
- return sljit_emit_op1(compiler, op, SLJIT_RETURN_REG, 0, src, srcw);
-}
-
#if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86) \
|| (defined SLJIT_CONFIG_PPC && SLJIT_CONFIG_PPC) \
- || (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32) \
- || ((defined SLJIT_CONFIG_MIPS && SLJIT_CONFIG_MIPS) && !(defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1))
+ || ((defined SLJIT_CONFIG_MIPS && SLJIT_CONFIG_MIPS) && !(defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1 && SLJIT_MIPS_REV < 6)) \
+ || (defined SLJIT_CONFIG_RISCV && SLJIT_CONFIG_RISCV) \
+ || (defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X)
static SLJIT_INLINE sljit_s32 sljit_emit_cmov_generic(struct sljit_compiler *compiler, sljit_s32 type,
sljit_s32 dst_reg,
@@ -2042,33 +2322,57 @@ static SLJIT_INLINE sljit_s32 sljit_emit_cmov_generic(struct sljit_compiler *com
{
struct sljit_label *label;
struct sljit_jump *jump;
- sljit_s32 op = (dst_reg & SLJIT_I32_OP) ? SLJIT_MOV32 : SLJIT_MOV;
+ sljit_s32 op = (type & SLJIT_32) ? SLJIT_MOV32 : SLJIT_MOV;
-#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \
- || (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
- compiler->skip_checks = 1;
-#endif
- jump = sljit_emit_jump(compiler, type ^ 0x1);
+ SLJIT_SKIP_CHECKS(compiler);
+ jump = sljit_emit_jump(compiler, (type & ~SLJIT_32) ^ 0x1);
FAIL_IF(!jump);
-#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \
- || (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
- compiler->skip_checks = 1;
-#endif
- FAIL_IF(sljit_emit_op1(compiler, op, dst_reg & ~SLJIT_I32_OP, 0, src, srcw));
+ SLJIT_SKIP_CHECKS(compiler);
+ FAIL_IF(sljit_emit_op1(compiler, op, dst_reg, 0, src, srcw));
-#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \
- || (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
- compiler->skip_checks = 1;
-#endif
+ SLJIT_SKIP_CHECKS(compiler);
label = sljit_emit_label(compiler);
FAIL_IF(!label);
+
sljit_set_label(jump, label);
return SLJIT_SUCCESS;
}
#endif
+#if (!(defined SLJIT_CONFIG_MIPS && SLJIT_CONFIG_MIPS) || (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)) \
+ && !(defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
+
+static sljit_s32 sljit_emit_mem_unaligned(struct sljit_compiler *compiler, sljit_s32 type,
+ sljit_s32 reg,
+ sljit_s32 mem, sljit_sw memw)
+{
+ SLJIT_SKIP_CHECKS(compiler);
+
+ if (type & SLJIT_MEM_STORE)
+ return sljit_emit_op1(compiler, type & (0xff | SLJIT_32), mem, memw, reg, 0);
+ return sljit_emit_op1(compiler, type & (0xff | SLJIT_32), reg, 0, mem, memw);
+}
+
+#endif /* (!SLJIT_CONFIG_MIPS || SLJIT_MIPS_REV >= 6) && !SLJIT_CONFIG_ARM_V5 */
+
+#if (!(defined SLJIT_CONFIG_MIPS && SLJIT_CONFIG_MIPS) || (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)) \
+ && !(defined SLJIT_CONFIG_ARM_32 && SLJIT_CONFIG_ARM_32)
+
+static sljit_s32 sljit_emit_fmem_unaligned(struct sljit_compiler *compiler, sljit_s32 type,
+ sljit_s32 freg,
+ sljit_s32 mem, sljit_sw memw)
+{
+ SLJIT_SKIP_CHECKS(compiler);
+
+ if (type & SLJIT_MEM_STORE)
+ return sljit_emit_fop1(compiler, type & (0xff | SLJIT_32), mem, memw, freg, 0);
+ return sljit_emit_fop1(compiler, type & (0xff | SLJIT_32), freg, 0, mem, memw);
+}
+
+#endif /* (!SLJIT_CONFIG_MIPS || SLJIT_MIPS_REV >= 6) && !SLJIT_CONFIG_ARM */
+
/* CPU description section */
#if (defined SLJIT_32BIT_ARCHITECTURE && SLJIT_32BIT_ARCHITECTURE)
@@ -2109,13 +2413,58 @@ static SLJIT_INLINE sljit_s32 sljit_emit_cmov_generic(struct sljit_compiler *com
# include "sljitNativePPC_common.c"
#elif (defined SLJIT_CONFIG_MIPS && SLJIT_CONFIG_MIPS)
# include "sljitNativeMIPS_common.c"
-#elif (defined SLJIT_CONFIG_SPARC && SLJIT_CONFIG_SPARC)
-# include "sljitNativeSPARC_common.c"
-#elif (defined SLJIT_CONFIG_TILEGX && SLJIT_CONFIG_TILEGX)
-# include "sljitNativeTILEGX_64.c"
+#elif (defined SLJIT_CONFIG_RISCV && SLJIT_CONFIG_RISCV)
+# include "sljitNativeRISCV_common.c"
+#elif (defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X)
+# include "sljitNativeS390X.c"
+#endif
+
+static SLJIT_INLINE sljit_s32 emit_mov_before_return(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 src, sljit_sw srcw)
+{
+#if (defined SLJIT_64BIT_ARCHITECTURE && SLJIT_64BIT_ARCHITECTURE)
+ /* At the moment the pointer size is always equal to sljit_sw. May be changed in the future. */
+ if (src == SLJIT_RETURN_REG && (op == SLJIT_MOV || op == SLJIT_MOV_P))
+ return SLJIT_SUCCESS;
+#else
+ if (src == SLJIT_RETURN_REG && (op == SLJIT_MOV || op == SLJIT_MOV_U32 || op == SLJIT_MOV_S32 || op == SLJIT_MOV_P))
+ return SLJIT_SUCCESS;
#endif
-#if !(defined SLJIT_CONFIG_MIPS && SLJIT_CONFIG_MIPS)
+ SLJIT_SKIP_CHECKS(compiler);
+ return sljit_emit_op1(compiler, op, SLJIT_RETURN_REG, 0, src, srcw);
+}
+
+#if !(defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) \
+ && !((defined SLJIT_CONFIG_ARM_32 && SLJIT_CONFIG_ARM_32) && defined __SOFTFP__)
+
+static SLJIT_INLINE sljit_s32 emit_fmov_before_return(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 src, sljit_sw srcw)
+{
+ if (src == SLJIT_FR0)
+ return SLJIT_SUCCESS;
+
+ SLJIT_SKIP_CHECKS(compiler);
+ return sljit_emit_fop1(compiler, op, SLJIT_RETURN_FREG, 0, src, srcw);
+}
+
+#endif /* !SLJIT_CONFIG_X86_32 && !(SLJIT_CONFIG_ARM_32 && __SOFTFP__) */
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 src, sljit_sw srcw)
+{
+ CHECK_ERROR();
+ CHECK(check_sljit_emit_return(compiler, op, src, srcw));
+
+ if (GET_OPCODE(op) < SLJIT_MOV_F64) {
+ FAIL_IF(emit_mov_before_return(compiler, op, src, srcw));
+ } else {
+ FAIL_IF(emit_fmov_before_return(compiler, op, src, srcw));
+ }
+
+ SLJIT_SKIP_CHECKS(compiler);
+ return sljit_emit_return_void(compiler);
+}
+
+#if !(defined SLJIT_CONFIG_MIPS && SLJIT_CONFIG_MIPS) \
+ && !(defined SLJIT_CONFIG_RISCV && SLJIT_CONFIG_RISCV)
SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_cmp(struct sljit_compiler *compiler, sljit_s32 type,
sljit_s32 src1, sljit_sw src1w,
@@ -2143,7 +2492,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_cmp(struct sljit_compiler
#endif
if (SLJIT_UNLIKELY((src1 & SLJIT_IMM) && !(src2 & SLJIT_IMM))) {
- /* Immediate is prefered as second argument by most architectures. */
+ /* Immediate is preferred as second argument by most architectures. */
switch (condition) {
case SLJIT_LESS:
condition = SLJIT_GREATER;
@@ -2171,7 +2520,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_cmp(struct sljit_compiler
break;
}
- type = condition | (type & (SLJIT_I32_OP | SLJIT_REWRITABLE_JUMP));
+ type = condition | (type & (SLJIT_32 | SLJIT_REWRITABLE_JUMP));
tmp_src = src1;
src1 = src2;
src2 = tmp_src;
@@ -2185,20 +2534,33 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_cmp(struct sljit_compiler
else
flags = condition << VARIABLE_FLAG_SHIFT;
-#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \
- || (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
- compiler->skip_checks = 1;
-#endif
- PTR_FAIL_IF(sljit_emit_op2(compiler, SLJIT_SUB | flags | (type & SLJIT_I32_OP),
- SLJIT_UNUSED, 0, src1, src1w, src2, src2w));
-#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \
- || (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
- compiler->skip_checks = 1;
-#endif
- return sljit_emit_jump(compiler, condition | (type & (SLJIT_REWRITABLE_JUMP | SLJIT_I32_OP)));
+ SLJIT_SKIP_CHECKS(compiler);
+ PTR_FAIL_IF(sljit_emit_op2u(compiler,
+ SLJIT_SUB | flags | (type & SLJIT_32), src1, src1w, src2, src2w));
+
+ SLJIT_SKIP_CHECKS(compiler);
+ return sljit_emit_jump(compiler, condition | (type & (SLJIT_REWRITABLE_JUMP | SLJIT_32)));
}
-#endif
+#endif /* !SLJIT_CONFIG_MIPS */
+
+#if (defined SLJIT_CONFIG_ARM && SLJIT_CONFIG_ARM)
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_cmp_info(sljit_s32 type)
+{
+ if (type < SLJIT_UNORDERED || type > SLJIT_ORDERED_LESS_EQUAL)
+ return 0;
+
+ switch (type) {
+ case SLJIT_UNORDERED_OR_EQUAL:
+ case SLJIT_ORDERED_NOT_EQUAL:
+ return 0;
+ }
+
+ return 1;
+}
+
+#endif /* SLJIT_CONFIG_ARM */
SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_fcmp(struct sljit_compiler *compiler, sljit_s32 type,
sljit_s32 src1, sljit_sw src1w,
@@ -2207,61 +2569,65 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_fcmp(struct sljit_compile
CHECK_ERROR_PTR();
CHECK_PTR(check_sljit_emit_fcmp(compiler, type, src1, src1w, src2, src2w));
-#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \
- || (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
- compiler->skip_checks = 1;
-#endif
- sljit_emit_fop1(compiler, SLJIT_CMP_F64 | ((type & 0xff) << VARIABLE_FLAG_SHIFT) | (type & SLJIT_I32_OP), src1, src1w, src2, src2w);
+ SLJIT_SKIP_CHECKS(compiler);
+ sljit_emit_fop1(compiler, SLJIT_CMP_F64 | ((type & 0xff) << VARIABLE_FLAG_SHIFT) | (type & SLJIT_32), src1, src1w, src2, src2w);
-#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \
- || (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
- compiler->skip_checks = 1;
-#endif
+ SLJIT_SKIP_CHECKS(compiler);
return sljit_emit_jump(compiler, type);
}
-#if !(defined SLJIT_CONFIG_ARM_32 && SLJIT_CONFIG_ARM_32) \
- && !(defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64) \
+#if !(defined SLJIT_CONFIG_ARM && SLJIT_CONFIG_ARM) \
&& !(defined SLJIT_CONFIG_PPC && SLJIT_CONFIG_PPC)
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_mem(struct sljit_compiler *compiler, sljit_s32 type,
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_mem_update(struct sljit_compiler *compiler, sljit_s32 type,
sljit_s32 reg,
sljit_s32 mem, sljit_sw memw)
{
- SLJIT_UNUSED_ARG(compiler);
+ CHECK_ERROR();
+ CHECK(check_sljit_emit_mem_update(compiler, type, reg, mem, memw));
SLJIT_UNUSED_ARG(type);
SLJIT_UNUSED_ARG(reg);
SLJIT_UNUSED_ARG(mem);
SLJIT_UNUSED_ARG(memw);
+ return SLJIT_ERR_UNSUPPORTED;
+}
+
+#endif /* !SLJIT_CONFIG_ARM && !SLJIT_CONFIG_PPC */
+
+#if !(defined SLJIT_CONFIG_ARM_32 && SLJIT_CONFIG_ARM_32) \
+ && !(defined SLJIT_CONFIG_MIPS && SLJIT_CONFIG_MIPS)
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fmem(struct sljit_compiler *compiler, sljit_s32 type,
+ sljit_s32 freg,
+ sljit_s32 mem, sljit_sw memw)
+{
CHECK_ERROR();
- CHECK(check_sljit_emit_mem(compiler, type, reg, mem, memw));
+ CHECK(check_sljit_emit_fmem(compiler, type, freg, mem, memw));
- return SLJIT_ERR_UNSUPPORTED;
+ return sljit_emit_fmem_unaligned(compiler, type, freg, mem, memw);
}
-#endif
+#endif /* !SLJIT_CONFIG_ARM_32 && !SLJIT_CONFIG_MIPS */
#if !(defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64) \
&& !(defined SLJIT_CONFIG_PPC && SLJIT_CONFIG_PPC)
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fmem(struct sljit_compiler *compiler, sljit_s32 type,
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fmem_update(struct sljit_compiler *compiler, sljit_s32 type,
sljit_s32 freg,
sljit_s32 mem, sljit_sw memw)
{
- SLJIT_UNUSED_ARG(compiler);
+ CHECK_ERROR();
+ CHECK(check_sljit_emit_fmem_update(compiler, type, freg, mem, memw));
SLJIT_UNUSED_ARG(type);
SLJIT_UNUSED_ARG(freg);
SLJIT_UNUSED_ARG(mem);
SLJIT_UNUSED_ARG(memw);
- CHECK_ERROR();
- CHECK(check_sljit_emit_fmem(compiler, type, freg, mem, memw));
-
return SLJIT_ERR_UNSUPPORTED;
}
-#endif
+#endif /* !SLJIT_CONFIG_ARM_64 && !SLJIT_CONFIG_PPC */
#if !(defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86) \
&& !(defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64)
@@ -2272,10 +2638,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_local_base(struct sljit_compiler *c
CHECK(check_sljit_get_local_base(compiler, dst, dstw, offset));
ADJUST_LOCAL_OFFSET(SLJIT_MEM1(SLJIT_SP), offset);
-#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \
- || (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
- compiler->skip_checks = 1;
-#endif
+
+ SLJIT_SKIP_CHECKS(compiler);
+
if (offset != 0)
return sljit_emit_op2(compiler, SLJIT_ADD, dst, dstw, SLJIT_SP, 0, SLJIT_IMM, offset);
return sljit_emit_op1(compiler, SLJIT_MOV, dst, dstw, SLJIT_SP, 0);
@@ -2292,9 +2657,10 @@ SLJIT_API_FUNC_ATTRIBUTE const char* sljit_get_platform_name(void)
return "unsupported";
}
-SLJIT_API_FUNC_ATTRIBUTE struct sljit_compiler* sljit_create_compiler(void *allocator_data)
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_compiler* sljit_create_compiler(void *allocator_data, void *exec_allocator_data)
{
SLJIT_UNUSED_ARG(allocator_data);
+ SLJIT_UNUSED_ARG(exec_allocator_data);
SLJIT_UNREACHABLE();
return NULL;
}
@@ -2342,9 +2708,17 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type)
return 0;
}
-SLJIT_API_FUNC_ATTRIBUTE void sljit_free_code(void* code)
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_cmp_info(sljit_s32 type)
+{
+ SLJIT_UNUSED_ARG(type);
+ SLJIT_UNREACHABLE();
+ return 0;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE void sljit_free_code(void* code, void *exec_allocator_data)
{
SLJIT_UNUSED_ARG(code);
+ SLJIT_UNUSED_ARG(exec_allocator_data);
SLJIT_UNREACHABLE();
}
@@ -2380,6 +2754,13 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_set_context(struct sljit_compiler *comp
return SLJIT_ERR_UNSUPPORTED;
}
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return_void(struct sljit_compiler *compiler)
+{
+ SLJIT_UNUSED_ARG(compiler);
+ SLJIT_UNREACHABLE();
+ return SLJIT_ERR_UNSUPPORTED;
+}
+
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 src, sljit_sw srcw)
{
SLJIT_UNUSED_ARG(compiler);
@@ -2390,6 +2771,15 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return(struct sljit_compiler *comp
return SLJIT_ERR_UNSUPPORTED;
}
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return_to(struct sljit_compiler *compiler, sljit_s32 src, sljit_sw srcw)
+{
+ SLJIT_UNUSED_ARG(compiler);
+ SLJIT_UNUSED_ARG(src);
+ SLJIT_UNUSED_ARG(srcw);
+ SLJIT_UNREACHABLE();
+ return SLJIT_ERR_UNSUPPORTED;
+}
+
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw)
{
SLJIT_UNUSED_ARG(compiler);
@@ -2438,6 +2828,36 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compile
return SLJIT_ERR_UNSUPPORTED;
}
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2u(struct sljit_compiler *compiler, sljit_s32 op,
+ sljit_s32 src1, sljit_sw src1w,
+ sljit_s32 src2, sljit_sw src2w)
+{
+ SLJIT_UNUSED_ARG(compiler);
+ SLJIT_UNUSED_ARG(op);
+ SLJIT_UNUSED_ARG(src1);
+ SLJIT_UNUSED_ARG(src1w);
+ SLJIT_UNUSED_ARG(src2);
+ SLJIT_UNUSED_ARG(src2w);
+ SLJIT_UNREACHABLE();
+ return SLJIT_ERR_UNSUPPORTED;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_shift_into(struct sljit_compiler *compiler, sljit_s32 op,
+ sljit_s32 src_dst,
+ sljit_s32 src1, sljit_sw src1w,
+ sljit_s32 src2, sljit_sw src2w)
+{
+ SLJIT_UNUSED_ARG(compiler);
+ SLJIT_UNUSED_ARG(op);
+ SLJIT_UNUSED_ARG(src_dst);
+ SLJIT_UNUSED_ARG(src1);
+ SLJIT_UNUSED_ARG(src1w);
+ SLJIT_UNUSED_ARG(src2);
+ SLJIT_UNUSED_ARG(src2w);
+ SLJIT_UNREACHABLE();
+ return SLJIT_ERR_UNSUPPORTED;
+}
+
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_src(struct sljit_compiler *compiler, sljit_s32 op,
sljit_s32 src, sljit_sw srcw)
{
@@ -2456,7 +2876,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 reg)
}
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_custom(struct sljit_compiler *compiler,
- void *instruction, sljit_s32 size)
+ void *instruction, sljit_u32 size)
{
SLJIT_UNUSED_ARG(compiler);
SLJIT_UNUSED_ARG(instruction);
@@ -2636,6 +3056,17 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_mem(struct sljit_compiler *compile
return SLJIT_ERR_UNSUPPORTED;
}
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_mem_update(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 reg, sljit_s32 mem, sljit_sw memw)
+{
+ SLJIT_UNUSED_ARG(compiler);
+ SLJIT_UNUSED_ARG(type);
+ SLJIT_UNUSED_ARG(reg);
+ SLJIT_UNUSED_ARG(mem);
+ SLJIT_UNUSED_ARG(memw);
+ SLJIT_UNREACHABLE();
+ return SLJIT_ERR_UNSUPPORTED;
+}
+
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fmem(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 freg, sljit_s32 mem, sljit_sw memw)
{
SLJIT_UNUSED_ARG(compiler);
@@ -2647,6 +3078,17 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fmem(struct sljit_compiler *compil
return SLJIT_ERR_UNSUPPORTED;
}
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fmem_update(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 freg, sljit_s32 mem, sljit_sw memw)
+{
+ SLJIT_UNUSED_ARG(compiler);
+ SLJIT_UNUSED_ARG(type);
+ SLJIT_UNUSED_ARG(freg);
+ SLJIT_UNUSED_ARG(mem);
+ SLJIT_UNUSED_ARG(memw);
+ SLJIT_UNREACHABLE();
+ return SLJIT_ERR_UNSUPPORTED;
+}
+
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_local_base(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw offset)
{
SLJIT_UNUSED_ARG(compiler);