Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement proper argument checks for float/simd registers #280

Merged
merged 1 commit into from
Nov 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
131 changes: 71 additions & 60 deletions sljit_src/sljitLir.c
Original file line number Diff line number Diff line change
Expand Up @@ -505,10 +505,12 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_compiler* sljit_create_compiler(void *allo
compiler->saveds = -1;
compiler->fscratches = -1;
compiler->fsaveds = -1;
#if (defined SLJIT_SEPARATE_VECTOR_REGISTERS && SLJIT_SEPARATE_VECTOR_REGISTERS)
#if (defined SLJIT_SEPARATE_VECTOR_REGISTERS && SLJIT_SEPARATE_VECTOR_REGISTERS) \
|| (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) \
|| (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
compiler->vscratches = -1;
compiler->vsaveds = -1;
#endif /* SLJIT_SEPARATE_VECTOR_REGISTERS */
#endif /* SLJIT_SEPARATE_VECTOR_REGISTERS || SLJIT_ARGUMENT_CHECKS || SLJIT_VERBOSE */
compiler->local_size = -1;

#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
Expand All @@ -534,11 +536,19 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_compiler* sljit_create_compiler(void *allo

#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) \
|| (defined SLJIT_DEBUG && SLJIT_DEBUG)
compiler->last_flags = 0;
SLJIT_ASSERT(compiler->last_flags == 0 && compiler->logical_local_size == 0);
compiler->last_return = -1;
compiler->logical_local_size = 0;
#endif /* SLJIT_ARGUMENT_CHECKS || SLJIT_DEBUG */

#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) \
|| (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
#if !(defined SLJIT_SEPARATE_VECTOR_REGISTERS && SLJIT_SEPARATE_VECTOR_REGISTERS)
compiler->real_fscratches = -1;
compiler->real_fsaveds = -1;
#endif /* !SLJIT_SEPARATE_VECTOR_REGISTERS */
SLJIT_ASSERT(compiler->skip_checks == 0);
#endif /* SLJIT_ARGUMENT_CHECKS || SLJIT_VERBOSE */

#if (defined SLJIT_NEEDS_COMPILER_INIT && SLJIT_NEEDS_COMPILER_INIT)
if (!compiler_initialized) {
init_compiler();
Expand Down Expand Up @@ -789,36 +799,20 @@ static SLJIT_INLINE void set_emit_enter(struct sljit_compiler *compiler,
compiler->options = options;
compiler->scratches = ENTER_GET_REGS(scratches);
compiler->saveds = ENTER_GET_REGS(saveds);
/* These members may be copied to real_* members below. */
compiler->fscratches = ENTER_GET_FLOAT_REGS(scratches);
compiler->fsaveds = ENTER_GET_FLOAT_REGS(saveds);
#if (defined SLJIT_SEPARATE_VECTOR_REGISTERS && SLJIT_SEPARATE_VECTOR_REGISTERS)
compiler->vscratches = ENTER_GET_VECTOR_REGS(scratches);
compiler->vsaveds = ENTER_GET_VECTOR_REGS(saveds);
#else /* !SLJIT_SEPARATE_VECTOR_REGISTERS */
update_float_register_count(compiler, scratches, saveds);
#endif /* SLJIT_SEPARATE_VECTOR_REGISTERS */
#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
compiler->last_return = args & SLJIT_ARG_MASK;
compiler->logical_local_size = local_size;
#endif /* SLJIT_ARGUMENT_CHECKS */
}

static SLJIT_INLINE void set_set_context(struct sljit_compiler *compiler,
sljit_s32 options, sljit_s32 args,
sljit_s32 scratches, sljit_s32 saveds, sljit_s32 local_size)
{
SLJIT_UNUSED_ARG(args);
SLJIT_UNUSED_ARG(local_size);

compiler->options = options;
compiler->scratches = ENTER_GET_REGS(scratches);
compiler->saveds = ENTER_GET_REGS(saveds);
compiler->fscratches = ENTER_GET_FLOAT_REGS(scratches);
compiler->fsaveds = ENTER_GET_FLOAT_REGS(saveds);
#if (defined SLJIT_SEPARATE_VECTOR_REGISTERS && SLJIT_SEPARATE_VECTOR_REGISTERS)
#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) \
|| (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
compiler->real_fscratches = compiler->fscratches;
compiler->real_fsaveds = compiler->fsaveds;
compiler->vscratches = ENTER_GET_VECTOR_REGS(scratches);
compiler->vsaveds = ENTER_GET_VECTOR_REGS(saveds);
#else /* !SLJIT_SEPARATE_VECTOR_REGISTERS */
#endif /* SLJIT_ARGUMENT_CHECKS || SLJIT_VERBOSE */
update_float_register_count(compiler, scratches, saveds);
#endif /* SLJIT_SEPARATE_VECTOR_REGISTERS */
#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
Expand Down Expand Up @@ -1033,17 +1027,47 @@ static sljit_s32 function_fcheck(struct sljit_compiler *compiler, sljit_s32 p, s
return function_check_src_mem(compiler, p, i);
}

static sljit_s32 function_check_is_vreg(struct sljit_compiler *compiler, sljit_s32 vr, sljit_s32 type);

#define FUNCTION_CHECK_IS_VREG(vr, type) \
function_check_is_vreg(compiler, (vr), (type))

#define FUNCTION_VCHECK(p, i, type) \
CHECK_ARGUMENT(function_vcheck(compiler, (p), (i), (type)))

static sljit_s32 function_vcheck(struct sljit_compiler *compiler, sljit_s32 p, sljit_sw i, sljit_s32 type)
{
if (compiler->scratches == -1)
return 0;

if (FUNCTION_CHECK_IS_VREG(p, type))
return (i == 0);

return function_check_src_mem(compiler, p, i);
}

#else /* !SLJIT_CONFIG_ARM_32 && !SLJIT_CONFIG_MIPS_32 */

#define FUNCTION_CHECK_IS_FREG(fr, is_32) \
function_check_is_freg(compiler, (fr))

static sljit_s32 function_check_is_freg(struct sljit_compiler *compiler, sljit_s32 fr)
{
sljit_s32 fscratches, fsaveds;

if (compiler->scratches == -1)
return 0;

return (fr >= SLJIT_FR0 && fr < (SLJIT_FR0 + compiler->fscratches))
|| (fr > (SLJIT_FS0 - compiler->fsaveds) && fr <= SLJIT_FS0)
#if (defined SLJIT_SEPARATE_VECTOR_REGISTERS && SLJIT_SEPARATE_VECTOR_REGISTERS)
fscratches = compiler->fscratches;
fsaveds = compiler->fsaveds;
#else /* SLJIT_SEPARATE_VECTOR_REGISTERS */
fscratches = compiler->real_fscratches;
fsaveds = compiler->real_fsaveds;
#endif /* !SLJIT_SEPARATE_VECTOR_REGISTERS */

return (fr >= SLJIT_FR0 && fr < (SLJIT_FR0 + fscratches))
|| (fr > (SLJIT_FS0 - fsaveds) && fr <= SLJIT_FS0)
|| (fr >= SLJIT_TMP_FREGISTER_BASE && fr < (SLJIT_TMP_FREGISTER_BASE + SLJIT_NUMBER_OF_TEMPORARY_FLOAT_REGISTERS));
}

Expand All @@ -1055,19 +1079,13 @@ static sljit_s32 function_fcheck(struct sljit_compiler *compiler, sljit_s32 p, s
if (compiler->scratches == -1)
return 0;

if ((p >= SLJIT_FR0 && p < (SLJIT_FR0 + compiler->fscratches))
|| (p > (SLJIT_FS0 - compiler->fsaveds) && p <= SLJIT_FS0)
|| (p >= SLJIT_TMP_FREGISTER_BASE && p < (SLJIT_TMP_FREGISTER_BASE + SLJIT_NUMBER_OF_TEMPORARY_FLOAT_REGISTERS)))
if (function_check_is_freg(compiler, p))
return (i == 0);

return function_check_src_mem(compiler, p, i);
}

#endif /* SLJIT_CONFIG_ARM_32 || SLJIT_CONFIG_MIPS_32 */

#if (defined SLJIT_SEPARATE_VECTOR_REGISTERS && SLJIT_SEPARATE_VECTOR_REGISTERS)

#define FUNCTION_CHECK_IS_VREG(vr) \
#define FUNCTION_CHECK_IS_VREG(vr, type) \
function_check_is_vreg(compiler, (vr))

static sljit_s32 function_check_is_vreg(struct sljit_compiler *compiler, sljit_s32 vr)
Expand All @@ -1080,28 +1098,21 @@ static sljit_s32 function_check_is_vreg(struct sljit_compiler *compiler, sljit_s
|| (vr >= SLJIT_TMP_VREGISTER_BASE && vr < (SLJIT_TMP_VREGISTER_BASE + SLJIT_NUMBER_OF_TEMPORARY_VECTOR_REGISTERS));
}

#define FUNCTION_VCHECK(p, i) \
#define FUNCTION_VCHECK(p, i, type) \
CHECK_ARGUMENT(function_vcheck(compiler, (p), (i)))

static sljit_s32 function_vcheck(struct sljit_compiler *compiler, sljit_s32 p, sljit_sw i)
{
if (compiler->scratches == -1)
return 0;

if ((p >= SLJIT_VR0 && p < SLJIT_VR0 + compiler->vscratches)
|| (p > (SLJIT_VS0 - compiler->vsaveds) && p <= SLJIT_VS0)
|| (p >= SLJIT_TMP_VREGISTER_BASE && p < (SLJIT_TMP_VREGISTER_BASE + SLJIT_NUMBER_OF_TEMPORARY_VECTOR_REGISTERS)))
return (i==0);
if (function_check_is_vreg(compiler, p))
return (i == 0);

return function_check_src_mem(compiler, p, i);
}

#else /* !SLJIT_SEPARATE_VECTOR_REGISTERS */

#define FUNCTION_CHECK_IS_VREG(vr) FUNCTION_CHECK_IS_FREG((vr), 0)
#define FUNCTION_VCHECK(p, i) FUNCTION_FCHECK((p), (i), 0)

#endif /* SLJIT_SEPARATE_VECTOR_REGISTERS */
#endif /* SLJIT_CONFIG_ARM_32 || SLJIT_CONFIG_MIPS_32 */

#endif /* SLJIT_ARGUMENT_CHECKS */

Expand Down Expand Up @@ -1166,7 +1177,7 @@ static void sljit_verbose_vreg(struct sljit_compiler *compiler, sljit_s32 r)
}
#endif /* SLJIT_CONFIG_ARM_32 || SLJIT_CONFIG_MIPS_32 */

if (r < (SLJIT_VR0 + compiler->fscratches))
if (r < (SLJIT_VR0 + compiler->vscratches))
fprintf(compiler->verbose, "vr%d", r - SLJIT_VR0);
else if (r < SLJIT_TMP_VREGISTER_BASE)
fprintf(compiler->verbose, "vs%d", SLJIT_NUMBER_OF_VECTOR_REGISTERS - r);
Expand Down Expand Up @@ -2860,8 +2871,8 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_simd_mov(struct sljit_com
CHECK_ARGUMENT(SLJIT_SIMD_CHECK_REG(type));
CHECK_ARGUMENT(SLJIT_SIMD_GET_ELEM_SIZE(type) <= SLJIT_SIMD_GET_REG_SIZE(type));
CHECK_ARGUMENT(SLJIT_SIMD_GET_ELEM2_SIZE(type) <= (srcdst & SLJIT_MEM) ? SLJIT_SIMD_GET_REG_SIZE(type) : 0);
CHECK_ARGUMENT(FUNCTION_CHECK_IS_VREG(vreg));
FUNCTION_VCHECK(srcdst, srcdstw);
CHECK_ARGUMENT(FUNCTION_CHECK_IS_VREG(vreg, type));
FUNCTION_VCHECK(srcdst, srcdstw, type);
#endif /* SLJIT_ARGUMENT_CHECKS */
#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
if (SLJIT_UNLIKELY(!!compiler->verbose)) {
Expand Down Expand Up @@ -2901,7 +2912,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_simd_replicate(struct slj
CHECK_ARGUMENT((type & SLJIT_SIMD_TYPE_MASK(0)) == 0);
CHECK_ARGUMENT(SLJIT_SIMD_CHECK_REG(type));
CHECK_ARGUMENT(SLJIT_SIMD_GET_ELEM_SIZE(type) < SLJIT_SIMD_GET_REG_SIZE(type));
CHECK_ARGUMENT(FUNCTION_CHECK_IS_VREG(vreg));
CHECK_ARGUMENT(FUNCTION_CHECK_IS_VREG(vreg, type));

if (type & SLJIT_SIMD_FLOAT) {
if (src == SLJIT_IMM) {
Expand Down Expand Up @@ -2952,7 +2963,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_simd_lane_mov(struct slji
CHECK_ARGUMENT(SLJIT_SIMD_CHECK_REG(type));
CHECK_ARGUMENT(SLJIT_SIMD_GET_ELEM_SIZE(type) < SLJIT_SIMD_GET_REG_SIZE(type));
CHECK_ARGUMENT(!(type & SLJIT_32) || SLJIT_SIMD_GET_ELEM_SIZE(type) <= 2);
CHECK_ARGUMENT(FUNCTION_CHECK_IS_VREG(vreg));
CHECK_ARGUMENT(FUNCTION_CHECK_IS_VREG(vreg, type));
CHECK_ARGUMENT(lane_index >= 0 && lane_index < (1 << (SLJIT_SIMD_GET_REG_SIZE(type) - SLJIT_SIMD_GET_ELEM_SIZE(type))));

if (type & SLJIT_SIMD_FLOAT) {
Expand Down Expand Up @@ -3000,8 +3011,8 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_simd_lane_replicate(struc
CHECK_ARGUMENT((type & SLJIT_SIMD_TYPE_MASK(0)) == 0);
CHECK_ARGUMENT(SLJIT_SIMD_CHECK_REG(type));
CHECK_ARGUMENT(SLJIT_SIMD_GET_ELEM_SIZE(type) < SLJIT_SIMD_GET_REG_SIZE(type));
CHECK_ARGUMENT(FUNCTION_CHECK_IS_VREG(vreg));
CHECK_ARGUMENT(FUNCTION_CHECK_IS_VREG(src));
CHECK_ARGUMENT(FUNCTION_CHECK_IS_VREG(vreg, type));
CHECK_ARGUMENT(FUNCTION_CHECK_IS_VREG(src, type));
CHECK_ARGUMENT(src_lane_index >= 0 && src_lane_index < (1 << (SLJIT_SIMD_GET_REG_SIZE(type) - SLJIT_SIMD_GET_ELEM_SIZE(type))));
#endif /* SLJIT_ARGUMENT_CHECKS */
#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
Expand Down Expand Up @@ -3038,8 +3049,8 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_simd_extend(struct sljit_
CHECK_ARGUMENT(SLJIT_SIMD_CHECK_REG(type));
CHECK_ARGUMENT(SLJIT_SIMD_GET_ELEM2_SIZE(type) < SLJIT_SIMD_GET_REG_SIZE(type));
CHECK_ARGUMENT(SLJIT_SIMD_GET_ELEM_SIZE(type) < SLJIT_SIMD_GET_ELEM2_SIZE(type));
CHECK_ARGUMENT(FUNCTION_CHECK_IS_VREG(vreg));
FUNCTION_VCHECK(src, srcw);
CHECK_ARGUMENT(FUNCTION_CHECK_IS_VREG(vreg, type));
FUNCTION_VCHECK(src, srcw, type);
#endif /* SLJIT_ARGUMENT_CHECKS */
#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
if (SLJIT_UNLIKELY(!!compiler->verbose)) {
Expand Down Expand Up @@ -3076,7 +3087,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_simd_sign(struct sljit_co
CHECK_ARGUMENT((type & SLJIT_SIMD_TYPE_MASK(SLJIT_32)) == SLJIT_SIMD_STORE);
CHECK_ARGUMENT(SLJIT_SIMD_CHECK_REG(type));
CHECK_ARGUMENT(SLJIT_SIMD_GET_ELEM_SIZE(type) < SLJIT_SIMD_GET_REG_SIZE(type));
CHECK_ARGUMENT(FUNCTION_CHECK_IS_VREG(vreg));
CHECK_ARGUMENT(FUNCTION_CHECK_IS_VREG(vreg, type));
FUNCTION_CHECK_DST(dst, dstw);
#endif /* SLJIT_ARGUMENT_CHECKS */
#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
Expand Down Expand Up @@ -3113,9 +3124,9 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_simd_op2(struct sljit_com
CHECK_ARGUMENT(SLJIT_SIMD_GET_ELEM_SIZE(type) <= SLJIT_SIMD_GET_REG_SIZE(type));
CHECK_ARGUMENT(SLJIT_SIMD_GET_OPCODE(type) != SLJIT_SIMD_OP2_SHUFFLE || (SLJIT_SIMD_GET_ELEM_SIZE(type) == 0 && !(type & SLJIT_SIMD_FLOAT)));
CHECK_ARGUMENT(SLJIT_SIMD_GET_ELEM2_SIZE(type) <= (src2 & SLJIT_MEM) ? SLJIT_SIMD_GET_REG_SIZE(type) : 0);
CHECK_ARGUMENT(FUNCTION_CHECK_IS_VREG(dst_vreg));
CHECK_ARGUMENT(FUNCTION_CHECK_IS_VREG(src1_vreg));
FUNCTION_VCHECK(src2, src2w);
CHECK_ARGUMENT(FUNCTION_CHECK_IS_VREG(dst_vreg, type));
CHECK_ARGUMENT(FUNCTION_CHECK_IS_VREG(src1_vreg, type));
FUNCTION_VCHECK(src2, src2w, type);
#endif /* SLJIT_ARGUMENT_CHECKS */
#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
if (SLJIT_UNLIKELY(!!compiler->verbose)) {
Expand Down
15 changes: 13 additions & 2 deletions sljit_src/sljitLir.h
Original file line number Diff line number Diff line change
Expand Up @@ -529,12 +529,15 @@ struct sljit_compiler {
sljit_s32 fscratches;
/* Available float saved registers. */
sljit_s32 fsaveds;
#if (defined SLJIT_SEPARATE_VECTOR_REGISTERS && SLJIT_SEPARATE_VECTOR_REGISTERS)
#if (defined SLJIT_SEPARATE_VECTOR_REGISTERS && SLJIT_SEPARATE_VECTOR_REGISTERS) \
|| (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) \
|| (defined SLJIT_DEBUG && SLJIT_DEBUG) \
|| (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
/* Available vector scratch registers. */
sljit_s32 vscratches;
/* Available vector saved registers. */
sljit_s32 vsaveds;
#endif /* SLJIT_SEPARATE_VECTOR_REGISTERS */
#endif /* SLJIT_SEPARATE_VECTOR_REGISTERS || SLJIT_ARGUMENT_CHECKS || SLJIT_DEBUG || SLJIT_VERBOSE */
/* Local stack size. */
sljit_s32 local_size;
/* Maximum code size. */
Expand Down Expand Up @@ -615,6 +618,7 @@ struct sljit_compiler {
FILE* verbose;
#endif /* SLJIT_VERBOSE */

/* Note: SLJIT_DEBUG enables SLJIT_ARGUMENT_CHECKS. */
#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) \
|| (defined SLJIT_DEBUG && SLJIT_DEBUG)
/* Flags specified by the last arithmetic instruction.
Expand All @@ -629,6 +633,13 @@ struct sljit_compiler {
#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) \
|| (defined SLJIT_DEBUG && SLJIT_DEBUG) \
|| (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
#if !(defined SLJIT_SEPARATE_VECTOR_REGISTERS && SLJIT_SEPARATE_VECTOR_REGISTERS)
/* Available float scratch registers. */
sljit_s32 real_fscratches;
/* Available float saved registers. */
sljit_s32 real_fsaveds;
#endif /* !SLJIT_SEPARATE_VECTOR_REGISTERS */

/* Trust arguments when an API function is called.
Used internally for calling API functions. */
sljit_s32 skip_checks;
Expand Down
23 changes: 20 additions & 3 deletions sljit_src/sljitNativeARM_32.c
Original file line number Diff line number Diff line change
Expand Up @@ -200,11 +200,28 @@ static sljit_s32 function_check_is_freg(struct sljit_compiler *compiler, sljit_s
if (is_32 && fr >= SLJIT_F64_SECOND(SLJIT_FR0))
fr -= SLJIT_F64_SECOND(0);

return (fr >= SLJIT_FR0 && fr < (SLJIT_FR0 + compiler->fscratches))
|| (fr > (SLJIT_FS0 - compiler->fsaveds) && fr <= SLJIT_FS0)
return (fr >= SLJIT_FR0 && fr < (SLJIT_FR0 + compiler->real_fscratches))
|| (fr > (SLJIT_FS0 - compiler->real_fsaveds) && fr <= SLJIT_FS0)
|| (fr >= SLJIT_TMP_FREGISTER_BASE && fr < (SLJIT_TMP_FREGISTER_BASE + SLJIT_NUMBER_OF_TEMPORARY_FLOAT_REGISTERS));
}

static sljit_s32 function_check_is_vreg(struct sljit_compiler *compiler, sljit_s32 vr, sljit_s32 type)
{
sljit_s32 vr_low = vr;

if (compiler->scratches == -1)
return 0;

if (SLJIT_SIMD_GET_REG_SIZE(type) == 4) {
vr += (vr & 0x1);
vr_low = vr - 1;
}

return (vr >= SLJIT_VR0 && vr < (SLJIT_VR0 + compiler->vscratches))
|| (vr_low > (SLJIT_VS0 - compiler->vsaveds) && vr_low <= SLJIT_VS0)
|| (vr >= SLJIT_TMP_VREGISTER_BASE && vr < (SLJIT_TMP_VREGISTER_BASE + SLJIT_NUMBER_OF_TEMPORARY_VECTOR_REGISTERS));
}

#endif /* SLJIT_ARGUMENT_CHECKS */

#if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6)
Expand Down Expand Up @@ -1434,7 +1451,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_set_context(struct sljit_compiler *comp

CHECK_ERROR();
CHECK(check_sljit_set_context(compiler, options, arg_types, scratches, saveds, local_size));
set_set_context(compiler, options, arg_types, scratches, saveds, local_size);
set_emit_enter(compiler, options, arg_types, scratches, saveds, local_size);

scratches = ENTER_GET_REGS(scratches);
saveds = ENTER_GET_REGS(saveds);
Expand Down
2 changes: 1 addition & 1 deletion sljit_src/sljitNativeARM_64.c
Original file line number Diff line number Diff line change
Expand Up @@ -1421,7 +1421,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_set_context(struct sljit_compiler *comp

CHECK_ERROR();
CHECK(check_sljit_set_context(compiler, options, arg_types, scratches, saveds, local_size));
set_set_context(compiler, options, arg_types, scratches, saveds, local_size);
set_emit_enter(compiler, options, arg_types, scratches, saveds, local_size);

scratches = ENTER_GET_REGS(scratches);
saveds = ENTER_GET_REGS(saveds);
Expand Down
23 changes: 20 additions & 3 deletions sljit_src/sljitNativeARM_T2_32.c
Original file line number Diff line number Diff line change
Expand Up @@ -266,11 +266,28 @@ static sljit_s32 function_check_is_freg(struct sljit_compiler *compiler, sljit_s
if (is_32 && fr >= SLJIT_F64_SECOND(SLJIT_FR0))
fr -= SLJIT_F64_SECOND(0);

return (fr >= SLJIT_FR0 && fr < (SLJIT_FR0 + compiler->fscratches))
|| (fr > (SLJIT_FS0 - compiler->fsaveds) && fr <= SLJIT_FS0)
return (fr >= SLJIT_FR0 && fr < (SLJIT_FR0 + compiler->real_fscratches))
|| (fr > (SLJIT_FS0 - compiler->real_fsaveds) && fr <= SLJIT_FS0)
|| (fr >= SLJIT_TMP_FREGISTER_BASE && fr < (SLJIT_TMP_FREGISTER_BASE + SLJIT_NUMBER_OF_TEMPORARY_FLOAT_REGISTERS));
}

static sljit_s32 function_check_is_vreg(struct sljit_compiler *compiler, sljit_s32 vr, sljit_s32 type)
{
sljit_s32 vr_low = vr;

if (compiler->scratches == -1)
return 0;

if (SLJIT_SIMD_GET_REG_SIZE(type) == 4) {
vr += (vr & 0x1);
vr_low = vr - 1;
}

return (vr >= SLJIT_VR0 && vr < (SLJIT_VR0 + compiler->vscratches))
|| (vr_low > (SLJIT_VS0 - compiler->vsaveds) && vr_low <= SLJIT_VS0)
|| (vr >= SLJIT_TMP_VREGISTER_BASE && vr < (SLJIT_TMP_VREGISTER_BASE + SLJIT_NUMBER_OF_TEMPORARY_VECTOR_REGISTERS));
}

#endif /* SLJIT_ARGUMENT_CHECKS */

static sljit_s32 push_inst16(struct sljit_compiler *compiler, sljit_ins inst)
Expand Down Expand Up @@ -1618,7 +1635,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_set_context(struct sljit_compiler *comp

CHECK_ERROR();
CHECK(check_sljit_set_context(compiler, options, arg_types, scratches, saveds, local_size));
set_set_context(compiler, options, arg_types, scratches, saveds, local_size);
set_emit_enter(compiler, options, arg_types, scratches, saveds, local_size);

scratches = ENTER_GET_REGS(scratches);
saveds = ENTER_GET_REGS(saveds);
Expand Down
Loading