JIT compiler update.
This commit is contained in:
parent
111cd470b5
commit
dea56d2df9
|
@ -613,6 +613,8 @@ the start pointers when the end of the capturing group has not yet reached. */
|
|||
sljit_emit_op1(compiler, (op), (dst), (dstw), (src), (srcw))
|
||||
#define OP2(op, dst, dstw, src1, src1w, src2, src2w) \
|
||||
sljit_emit_op2(compiler, (op), (dst), (dstw), (src1), (src1w), (src2), (src2w))
|
||||
#define OP2U(op, src1, src1w, src2, src2w) \
|
||||
sljit_emit_op2u(compiler, (op), (src1), (src1w), (src2), (src2w))
|
||||
#define OP_SRC(op, src, srcw) \
|
||||
sljit_emit_op_src(compiler, (op), (src), (srcw))
|
||||
#define LABEL() \
|
||||
|
@ -3743,9 +3745,9 @@ if (common->invalid_utf)
|
|||
else
|
||||
{
|
||||
OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, SLJIT_IMM, 0xd800);
|
||||
OP2(SLJIT_SUB | SLJIT_SET_GREATER_EQUAL, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x110000);
|
||||
OP2U(SLJIT_SUB | SLJIT_SET_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 0x110000);
|
||||
CMOV(SLJIT_GREATER_EQUAL, TMP1, SLJIT_IMM, INVALID_UTF_CHAR);
|
||||
OP2(SLJIT_SUB | SLJIT_SET_LESS, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, 0xe000 - 0xd800);
|
||||
OP2U(SLJIT_SUB | SLJIT_SET_LESS, TMP2, 0, SLJIT_IMM, 0xe000 - 0xd800);
|
||||
CMOV(SLJIT_LESS, TMP1, SLJIT_IMM, INVALID_UTF_CHAR);
|
||||
}
|
||||
}
|
||||
|
@ -3982,7 +3984,7 @@ if (common->utf)
|
|||
{
|
||||
if (options & READ_CHAR_UPDATE_STR_PTR)
|
||||
OP2(SLJIT_ADD, RETURN_ADDR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
|
||||
OP2(SLJIT_SUB | SLJIT_SET_LESS, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, 0x400);
|
||||
OP2U(SLJIT_SUB | SLJIT_SET_LESS, TMP2, 0, SLJIT_IMM, 0x400);
|
||||
if (options & READ_CHAR_UPDATE_STR_PTR)
|
||||
CMOV(SLJIT_LESS, STR_PTR, RETURN_ADDR, 0);
|
||||
if (max >= 0xd800)
|
||||
|
@ -4010,9 +4012,9 @@ if (common->invalid_utf)
|
|||
else
|
||||
{
|
||||
OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, SLJIT_IMM, 0xd800);
|
||||
OP2(SLJIT_SUB | SLJIT_SET_GREATER_EQUAL, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x110000);
|
||||
OP2U(SLJIT_SUB | SLJIT_SET_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 0x110000);
|
||||
CMOV(SLJIT_GREATER_EQUAL, TMP1, SLJIT_IMM, INVALID_UTF_CHAR);
|
||||
OP2(SLJIT_SUB | SLJIT_SET_LESS, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, 0xe000 - 0xd800);
|
||||
OP2U(SLJIT_SUB | SLJIT_SET_LESS, TMP2, 0, SLJIT_IMM, 0xe000 - 0xd800);
|
||||
CMOV(SLJIT_LESS, TMP1, SLJIT_IMM, INVALID_UTF_CHAR);
|
||||
}
|
||||
}
|
||||
|
@ -4167,7 +4169,7 @@ if (common->utf && negated)
|
|||
if (sljit_has_cpu_feature(SLJIT_HAS_CMOV) && !HAS_VIRTUAL_REGISTERS)
|
||||
{
|
||||
OP2(SLJIT_ADD, RETURN_ADDR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
|
||||
OP2(SLJIT_SUB | SLJIT_SET_LESS, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, 0x400);
|
||||
OP2U(SLJIT_SUB | SLJIT_SET_LESS, TMP2, 0, SLJIT_IMM, 0x400);
|
||||
CMOV(SLJIT_LESS, STR_PTR, RETURN_ADDR, 0);
|
||||
}
|
||||
else
|
||||
|
@ -4250,7 +4252,7 @@ if (common->utf)
|
|||
|
||||
/* Skip low surrogate if necessary. */
|
||||
OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
|
||||
OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xdc00);
|
||||
OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, 0xdc00);
|
||||
OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_EQUAL);
|
||||
OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, UCHAR_SHIFT);
|
||||
OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
|
||||
|
@ -4267,7 +4269,7 @@ if (common->invalid_utf && !must_be_valid)
|
|||
return;
|
||||
}
|
||||
|
||||
OP2(SLJIT_SUB | SLJIT_SET_LESS, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x110000);
|
||||
OP2U(SLJIT_SUB | SLJIT_SET_LESS, TMP1, 0, SLJIT_IMM, 0x110000);
|
||||
OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_LESS);
|
||||
OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, UCHAR_SHIFT);
|
||||
OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
|
||||
|
@ -4332,7 +4334,7 @@ OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
|
|||
OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
|
||||
|
||||
/* Searching for the first zero. */
|
||||
OP2(SLJIT_AND | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x800);
|
||||
OP2U(SLJIT_AND | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, 0x800);
|
||||
jump = JUMP(SLJIT_NOT_ZERO);
|
||||
/* Two byte sequence. */
|
||||
OP2(SLJIT_XOR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3000);
|
||||
|
@ -4345,7 +4347,7 @@ OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);
|
|||
OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
|
||||
OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
|
||||
|
||||
OP2(SLJIT_AND | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x10000);
|
||||
OP2U(SLJIT_AND | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, 0x10000);
|
||||
jump = JUMP(SLJIT_NOT_ZERO);
|
||||
/* Three byte sequence. */
|
||||
OP2(SLJIT_XOR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xe0000);
|
||||
|
@ -4373,7 +4375,7 @@ struct sljit_jump *compare;
|
|||
|
||||
sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
|
||||
|
||||
OP2(SLJIT_AND | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, 0x20);
|
||||
OP2U(SLJIT_AND | SLJIT_SET_Z, TMP2, 0, SLJIT_IMM, 0x20);
|
||||
jump = JUMP(SLJIT_NOT_ZERO);
|
||||
/* Two byte sequence. */
|
||||
OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
|
||||
|
@ -4432,7 +4434,7 @@ OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0);
|
|||
OP2(SLJIT_SUB, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x80);
|
||||
exit_invalid[1] = CMP(SLJIT_GREATER_EQUAL, TMP2, 0, SLJIT_IMM, 0x40);
|
||||
|
||||
OP2(SLJIT_AND | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x800);
|
||||
OP2U(SLJIT_AND | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, 0x800);
|
||||
jump = JUMP(SLJIT_NOT_ZERO);
|
||||
|
||||
OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
|
||||
|
@ -4447,14 +4449,14 @@ OP2(SLJIT_SUB, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x80);
|
|||
OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
|
||||
if (has_cmov)
|
||||
{
|
||||
OP2(SLJIT_SUB | SLJIT_SET_GREATER_EQUAL, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, 0x40);
|
||||
OP2U(SLJIT_SUB | SLJIT_SET_GREATER_EQUAL, TMP2, 0, SLJIT_IMM, 0x40);
|
||||
CMOV(SLJIT_GREATER_EQUAL, TMP1, SLJIT_IMM, 0x20000);
|
||||
exit_invalid[2] = NULL;
|
||||
}
|
||||
else
|
||||
exit_invalid[2] = CMP(SLJIT_GREATER_EQUAL, TMP2, 0, SLJIT_IMM, 0x40);
|
||||
|
||||
OP2(SLJIT_AND | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x10000);
|
||||
OP2U(SLJIT_AND | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, 0x10000);
|
||||
jump = JUMP(SLJIT_NOT_ZERO);
|
||||
|
||||
three_byte_entry = LABEL();
|
||||
|
@ -4462,7 +4464,7 @@ three_byte_entry = LABEL();
|
|||
OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x2d800);
|
||||
if (has_cmov)
|
||||
{
|
||||
OP2(SLJIT_SUB | SLJIT_SET_LESS, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x800);
|
||||
OP2U(SLJIT_SUB | SLJIT_SET_LESS, TMP1, 0, SLJIT_IMM, 0x800);
|
||||
CMOV(SLJIT_LESS, TMP1, SLJIT_IMM, INVALID_UTF_CHAR - 0xd800);
|
||||
exit_invalid[3] = NULL;
|
||||
}
|
||||
|
@ -4473,7 +4475,7 @@ OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
|
|||
|
||||
if (has_cmov)
|
||||
{
|
||||
OP2(SLJIT_SUB | SLJIT_SET_LESS, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x800);
|
||||
OP2U(SLJIT_SUB | SLJIT_SET_LESS, TMP1, 0, SLJIT_IMM, 0x800);
|
||||
CMOV(SLJIT_LESS, TMP1, SLJIT_IMM, INVALID_UTF_CHAR);
|
||||
exit_invalid[4] = NULL;
|
||||
}
|
||||
|
@ -4490,7 +4492,7 @@ OP2(SLJIT_SUB, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x80);
|
|||
OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
|
||||
if (has_cmov)
|
||||
{
|
||||
OP2(SLJIT_SUB | SLJIT_SET_GREATER_EQUAL, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, 0x40);
|
||||
OP2U(SLJIT_SUB | SLJIT_SET_GREATER_EQUAL, TMP2, 0, SLJIT_IMM, 0x40);
|
||||
CMOV(SLJIT_GREATER_EQUAL, TMP1, SLJIT_IMM, 0);
|
||||
exit_invalid[5] = NULL;
|
||||
}
|
||||
|
@ -4500,7 +4502,7 @@ else
|
|||
OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xc10000);
|
||||
if (has_cmov)
|
||||
{
|
||||
OP2(SLJIT_SUB | SLJIT_SET_GREATER_EQUAL, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x100000);
|
||||
OP2U(SLJIT_SUB | SLJIT_SET_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 0x100000);
|
||||
CMOV(SLJIT_GREATER_EQUAL, TMP1, SLJIT_IMM, INVALID_UTF_CHAR - 0x10000);
|
||||
exit_invalid[6] = NULL;
|
||||
}
|
||||
|
@ -4522,7 +4524,7 @@ OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0);
|
|||
OP2(SLJIT_SUB, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x80);
|
||||
exit_invalid[8] = CMP(SLJIT_GREATER_EQUAL, TMP2, 0, SLJIT_IMM, 0x40);
|
||||
|
||||
OP2(SLJIT_AND | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x800);
|
||||
OP2U(SLJIT_AND | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, 0x800);
|
||||
jump = JUMP(SLJIT_NOT_ZERO);
|
||||
|
||||
OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0);
|
||||
|
@ -4537,7 +4539,7 @@ OP2(SLJIT_SUB, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x80);
|
|||
OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
|
||||
if (has_cmov)
|
||||
{
|
||||
OP2(SLJIT_SUB | SLJIT_SET_GREATER_EQUAL, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, 0x40);
|
||||
OP2U(SLJIT_SUB | SLJIT_SET_GREATER_EQUAL, TMP2, 0, SLJIT_IMM, 0x40);
|
||||
CMOV(SLJIT_GREATER_EQUAL, TMP1, SLJIT_IMM, INVALID_UTF_CHAR);
|
||||
exit_invalid[10] = NULL;
|
||||
}
|
||||
|
@ -4830,7 +4832,7 @@ OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
|
|||
OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xd800);
|
||||
if (has_cmov)
|
||||
{
|
||||
OP2(SLJIT_SUB | SLJIT_SET_LESS, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x800);
|
||||
OP2U(SLJIT_SUB | SLJIT_SET_LESS, TMP1, 0, SLJIT_IMM, 0x800);
|
||||
CMOV(SLJIT_LESS, TMP1, SLJIT_IMM, -0xd800);
|
||||
exit_invalid[2] = NULL;
|
||||
}
|
||||
|
@ -4840,7 +4842,7 @@ else
|
|||
OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xd800);
|
||||
if (has_cmov)
|
||||
{
|
||||
OP2(SLJIT_SUB | SLJIT_SET_LESS, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x800);
|
||||
OP2U(SLJIT_SUB | SLJIT_SET_LESS, TMP1, 0, SLJIT_IMM, 0x800);
|
||||
CMOV(SLJIT_LESS, TMP1, SLJIT_IMM, INVALID_UTF_CHAR);
|
||||
exit_invalid[3] = NULL;
|
||||
}
|
||||
|
@ -4865,7 +4867,7 @@ OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0);
|
|||
|
||||
if (has_cmov)
|
||||
{
|
||||
OP2(SLJIT_SUB | SLJIT_SET_GREATER_EQUAL, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x100000);
|
||||
OP2U(SLJIT_SUB | SLJIT_SET_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 0x100000);
|
||||
CMOV(SLJIT_GREATER_EQUAL, TMP1, SLJIT_IMM, INVALID_UTF_CHAR - 0x10000);
|
||||
exit_invalid[5] = NULL;
|
||||
}
|
||||
|
@ -4968,7 +4970,7 @@ OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
|
|||
exit_invalid[1] = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 0xdc00);
|
||||
|
||||
OP2(SLJIT_SUB, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xdc00);
|
||||
OP2(SLJIT_SUB | SLJIT_SET_LESS, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, 0x400);
|
||||
OP2U(SLJIT_SUB | SLJIT_SET_LESS, TMP2, 0, SLJIT_IMM, 0x400);
|
||||
OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_LESS);
|
||||
OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0x10000);
|
||||
OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, UCHAR_SHIFT);
|
||||
|
@ -5239,7 +5241,7 @@ if (newlinecheck)
|
|||
OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
|
||||
end = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
|
||||
OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
|
||||
OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, common->newline & 0xff);
|
||||
OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, common->newline & 0xff);
|
||||
OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_EQUAL);
|
||||
#if PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32
|
||||
OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, UCHAR_SHIFT);
|
||||
|
@ -5304,12 +5306,12 @@ else if (common->utf)
|
|||
if (sljit_has_cpu_feature(SLJIT_HAS_CMOV))
|
||||
{
|
||||
OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
|
||||
OP2(SLJIT_SUB | SLJIT_SET_LESS, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x400);
|
||||
OP2U(SLJIT_SUB | SLJIT_SET_LESS, TMP1, 0, SLJIT_IMM, 0x400);
|
||||
CMOV(SLJIT_LESS, STR_PTR, TMP2, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
OP2(SLJIT_SUB | SLJIT_SET_LESS, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x400);
|
||||
OP2U(SLJIT_SUB | SLJIT_SET_LESS, TMP1, 0, SLJIT_IMM, 0x400);
|
||||
OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_LESS);
|
||||
OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, UCHAR_SHIFT);
|
||||
OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
|
||||
|
@ -5860,7 +5862,7 @@ if (has_match_end)
|
|||
OP1(SLJIT_MOV, TMP3, 0, STR_END, 0);
|
||||
|
||||
OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(offset + 1));
|
||||
OP2(SLJIT_SUB | SLJIT_SET_GREATER, SLJIT_UNUSED, 0, STR_END, 0, TMP1, 0);
|
||||
OP2U(SLJIT_SUB | SLJIT_SET_GREATER, STR_END, 0, TMP1, 0);
|
||||
CMOV(SLJIT_GREATER, STR_END, TMP1, 0);
|
||||
}
|
||||
|
||||
|
@ -6063,7 +6065,7 @@ if (common->match_end_ptr != 0)
|
|||
OP1(SLJIT_MOV, TMP3, 0, STR_END, 0);
|
||||
OP2(SLJIT_SUB | SLJIT_SET_LESS, STR_END, 0, STR_END, 0, SLJIT_IMM, IN_UCHARS(max));
|
||||
add_jump(compiler, &common->failed_match, JUMP(SLJIT_LESS));
|
||||
OP2(SLJIT_SUB | SLJIT_SET_GREATER, SLJIT_UNUSED, 0, STR_END, 0, TMP1, 0);
|
||||
OP2U(SLJIT_SUB | SLJIT_SET_GREATER, STR_END, 0, TMP1, 0);
|
||||
CMOV(SLJIT_GREATER, STR_END, TMP1, 0);
|
||||
}
|
||||
else
|
||||
|
@ -6200,7 +6202,7 @@ if (common->nltype == NLTYPE_FIXED && common->newline > 255)
|
|||
firstchar = CMP(SLJIT_LESS_EQUAL, STR_PTR, 0, TMP2, 0);
|
||||
|
||||
OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
|
||||
OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_UNUSED, 0, STR_PTR, 0, TMP1, 0);
|
||||
OP2U(SLJIT_SUB | SLJIT_SET_Z, STR_PTR, 0, TMP1, 0);
|
||||
OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_NOT_EQUAL);
|
||||
#if PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32
|
||||
OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, UCHAR_SHIFT);
|
||||
|
@ -6228,7 +6230,7 @@ if (common->nltype == NLTYPE_FIXED && common->newline > 255)
|
|||
firstchar = CMP(SLJIT_LESS_EQUAL, STR_PTR, 0, TMP2, 0);
|
||||
|
||||
OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(2));
|
||||
OP2(SLJIT_SUB | SLJIT_SET_GREATER_EQUAL, SLJIT_UNUSED, 0, STR_PTR, 0, TMP1, 0);
|
||||
OP2U(SLJIT_SUB | SLJIT_SET_GREATER_EQUAL, STR_PTR, 0, TMP1, 0);
|
||||
OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_GREATER_EQUAL);
|
||||
#if PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32
|
||||
OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, UCHAR_SHIFT);
|
||||
|
@ -6293,7 +6295,7 @@ if (JIT_HAS_FAST_FORWARD_CHAR_SIMD && (common->nltype == NLTYPE_FIXED || common-
|
|||
OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
|
||||
if (common->mode != PCRE2_JIT_COMPLETE)
|
||||
{
|
||||
OP2(SLJIT_SUB | SLJIT_SET_GREATER, SLJIT_UNUSED, 0, STR_PTR, 0, STR_END, 0);
|
||||
OP2U(SLJIT_SUB | SLJIT_SET_GREATER, STR_PTR, 0, STR_END, 0);
|
||||
CMOV(SLJIT_GREATER, STR_PTR, STR_END, 0);
|
||||
}
|
||||
}
|
||||
|
@ -6319,7 +6321,7 @@ if (common->nltype == NLTYPE_ANY || common->nltype == NLTYPE_ANYCRLF)
|
|||
|
||||
notfoundnl = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
|
||||
OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
|
||||
OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, CHAR_NL);
|
||||
OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, CHAR_NL);
|
||||
OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_EQUAL);
|
||||
#if PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32
|
||||
OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, UCHAR_SHIFT);
|
||||
|
@ -6355,7 +6357,7 @@ if (common->match_end_ptr != 0)
|
|||
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->match_end_ptr);
|
||||
OP1(SLJIT_MOV, RETURN_ADDR, 0, STR_END, 0);
|
||||
OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1));
|
||||
OP2(SLJIT_SUB | SLJIT_SET_GREATER, SLJIT_UNUSED, 0, STR_END, 0, TMP1, 0);
|
||||
OP2U(SLJIT_SUB | SLJIT_SET_GREATER, STR_END, 0, TMP1, 0);
|
||||
CMOV(SLJIT_GREATER, STR_END, TMP1, 0);
|
||||
}
|
||||
|
||||
|
@ -6385,12 +6387,12 @@ if (!optimize_class(common, start_bits, (start_bits[31] & 0x80) != 0, FALSE, &ma
|
|||
if (!HAS_VIRTUAL_REGISTERS)
|
||||
{
|
||||
OP2(SLJIT_SHL, TMP3, 0, SLJIT_IMM, 1, TMP2, 0);
|
||||
OP2(SLJIT_AND | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP1, 0, TMP3, 0);
|
||||
OP2U(SLJIT_AND | SLJIT_SET_Z, TMP1, 0, TMP3, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);
|
||||
OP2(SLJIT_AND | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0);
|
||||
OP2U(SLJIT_AND | SLJIT_SET_Z, TMP1, 0, TMP2, 0);
|
||||
}
|
||||
JUMPTO(SLJIT_ZERO, start);
|
||||
}
|
||||
|
@ -6600,10 +6602,10 @@ if (common->ucp)
|
|||
jump = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE);
|
||||
add_jump(compiler, &common->getucdtype, JUMP(SLJIT_FAST_CALL));
|
||||
OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Ll);
|
||||
OP2(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ucp_Lu - ucp_Ll);
|
||||
OP2U(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, TMP1, 0, SLJIT_IMM, ucp_Lu - ucp_Ll);
|
||||
OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_LESS_EQUAL);
|
||||
OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Nd - ucp_Ll);
|
||||
OP2(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ucp_No - ucp_Nd);
|
||||
OP2U(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, TMP1, 0, SLJIT_IMM, ucp_No - ucp_Nd);
|
||||
OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_LESS_EQUAL);
|
||||
JUMPHERE(jump);
|
||||
OP1(SLJIT_MOV, TMP3, 0, TMP2, 0);
|
||||
|
@ -6646,10 +6648,10 @@ if (common->ucp)
|
|||
jump = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE);
|
||||
add_jump(compiler, &common->getucdtype, JUMP(SLJIT_FAST_CALL));
|
||||
OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Ll);
|
||||
OP2(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ucp_Lu - ucp_Ll);
|
||||
OP2U(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, TMP1, 0, SLJIT_IMM, ucp_Lu - ucp_Ll);
|
||||
OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_LESS_EQUAL);
|
||||
OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Nd - ucp_Ll);
|
||||
OP2(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ucp_No - ucp_Nd);
|
||||
OP2U(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, TMP1, 0, SLJIT_IMM, ucp_No - ucp_Nd);
|
||||
OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_LESS_EQUAL);
|
||||
JUMPHERE(jump);
|
||||
}
|
||||
|
@ -6916,7 +6918,7 @@ j = 0;
|
|||
if (char_list[0] == 0)
|
||||
{
|
||||
i++;
|
||||
OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0);
|
||||
OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, 0);
|
||||
OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_ZERO);
|
||||
}
|
||||
else
|
||||
|
@ -6928,7 +6930,7 @@ while (i < len)
|
|||
j++;
|
||||
else
|
||||
{
|
||||
OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, char_list[i]);
|
||||
OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, char_list[i]);
|
||||
CMOV(SLJIT_ZERO, TMP2, TMP1, 0);
|
||||
}
|
||||
i++;
|
||||
|
@ -6942,7 +6944,7 @@ if (j != 0)
|
|||
if ((char_list[i] & 0x100) != 0)
|
||||
{
|
||||
j--;
|
||||
OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, char_list[i] & 0xff);
|
||||
OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, char_list[i] & 0xff);
|
||||
CMOV(SLJIT_ZERO, TMP2, TMP1, 0);
|
||||
}
|
||||
}
|
||||
|
@ -6971,9 +6973,9 @@ DEFINE_COMPILER;
|
|||
sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
|
||||
|
||||
OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0a);
|
||||
OP2(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x0d - 0x0a);
|
||||
OP2U(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, TMP1, 0, SLJIT_IMM, 0x0d - 0x0a);
|
||||
OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_LESS_EQUAL);
|
||||
OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x85 - 0x0a);
|
||||
OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, 0x85 - 0x0a);
|
||||
#if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32
|
||||
#if PCRE2_CODE_UNIT_WIDTH == 8
|
||||
if (common->utf)
|
||||
|
@ -6981,7 +6983,7 @@ if (common->utf)
|
|||
#endif
|
||||
OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_EQUAL);
|
||||
OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1);
|
||||
OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x2029 - 0x0a);
|
||||
OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, 0x2029 - 0x0a);
|
||||
#if PCRE2_CODE_UNIT_WIDTH == 8
|
||||
}
|
||||
#endif
|
||||
|
@ -6997,29 +6999,29 @@ DEFINE_COMPILER;
|
|||
|
||||
sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
|
||||
|
||||
OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x09);
|
||||
OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, 0x09);
|
||||
OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_EQUAL);
|
||||
OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x20);
|
||||
OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, 0x20);
|
||||
OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_EQUAL);
|
||||
OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xa0);
|
||||
OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, 0xa0);
|
||||
#if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32
|
||||
#if PCRE2_CODE_UNIT_WIDTH == 8
|
||||
if (common->utf)
|
||||
{
|
||||
#endif
|
||||
OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_EQUAL);
|
||||
OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x1680);
|
||||
OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, 0x1680);
|
||||
OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_EQUAL);
|
||||
OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x180e);
|
||||
OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, 0x180e);
|
||||
OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_EQUAL);
|
||||
OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x2000);
|
||||
OP2(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x200A - 0x2000);
|
||||
OP2U(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, TMP1, 0, SLJIT_IMM, 0x200A - 0x2000);
|
||||
OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_LESS_EQUAL);
|
||||
OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x202f - 0x2000);
|
||||
OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, 0x202f - 0x2000);
|
||||
OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_EQUAL);
|
||||
OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x205f - 0x2000);
|
||||
OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, 0x205f - 0x2000);
|
||||
OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_EQUAL);
|
||||
OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x3000 - 0x2000);
|
||||
OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, 0x3000 - 0x2000);
|
||||
#if PCRE2_CODE_UNIT_WIDTH == 8
|
||||
}
|
||||
#endif
|
||||
|
@ -7037,9 +7039,9 @@ DEFINE_COMPILER;
|
|||
sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
|
||||
|
||||
OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0a);
|
||||
OP2(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x0d - 0x0a);
|
||||
OP2U(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, TMP1, 0, SLJIT_IMM, 0x0d - 0x0a);
|
||||
OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_LESS_EQUAL);
|
||||
OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x85 - 0x0a);
|
||||
OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, 0x85 - 0x0a);
|
||||
#if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32
|
||||
#if PCRE2_CODE_UNIT_WIDTH == 8
|
||||
if (common->utf)
|
||||
|
@ -7047,7 +7049,7 @@ if (common->utf)
|
|||
#endif
|
||||
OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_EQUAL);
|
||||
OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1);
|
||||
OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x2029 - 0x0a);
|
||||
OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, 0x2029 - 0x0a);
|
||||
#if PCRE2_CODE_UNIT_WIDTH == 8
|
||||
}
|
||||
#endif
|
||||
|
@ -7593,7 +7595,7 @@ if ((cc[-1] & XCL_HASPROP) == 0)
|
|||
OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);
|
||||
OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)cc);
|
||||
OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);
|
||||
OP2(SLJIT_AND | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0);
|
||||
OP2U(SLJIT_AND | SLJIT_SET_Z, TMP1, 0, TMP2, 0);
|
||||
add_jump(compiler, &found, JUMP(SLJIT_NOT_ZERO));
|
||||
}
|
||||
|
||||
|
@ -7626,7 +7628,7 @@ else if ((cc[-1] & XCL_MAP) != 0)
|
|||
OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);
|
||||
OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)cc);
|
||||
OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);
|
||||
OP2(SLJIT_AND | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0);
|
||||
OP2U(SLJIT_AND | SLJIT_SET_Z, TMP1, 0, TMP2, 0);
|
||||
add_jump(compiler, list, JUMP(SLJIT_NOT_ZERO));
|
||||
|
||||
#if PCRE2_CODE_UNIT_WIDTH == 8
|
||||
|
@ -7736,7 +7738,7 @@ if (unicode_status & XCLASS_NEEDS_UCD)
|
|||
if (cc[-1] == XCL_NOTPROP)
|
||||
invertcmp ^= 0x1;
|
||||
|
||||
OP2(SLJIT_AND32 | SLJIT_SET_Z, SLJIT_UNUSED, 0, SLJIT_MEM1(TMP1), (sljit_sw)(PRIV(ucd_boolprop_sets) + (cc[1] >> 5)), SLJIT_IMM, (sljit_sw)1 << (cc[1] & 0x1f));
|
||||
OP2U(SLJIT_AND32 | SLJIT_SET_Z, SLJIT_MEM1(TMP1), (sljit_sw)(PRIV(ucd_boolprop_sets) + (cc[1] >> 5)), SLJIT_IMM, (sljit_sw)1 << (cc[1] & 0x1f));
|
||||
add_jump(compiler, compares > 0 ? list : backtracks, JUMP(SLJIT_NOT_ZERO ^ invertcmp));
|
||||
}
|
||||
cc += 2;
|
||||
|
@ -7847,7 +7849,7 @@ if (unicode_status & XCLASS_NEEDS_UCD)
|
|||
invertcmp ^= 0x1;
|
||||
}
|
||||
|
||||
OP2(SLJIT_AND32 | SLJIT_SET_Z, SLJIT_UNUSED, 0, SLJIT_MEM1(TMP1), (sljit_sw)(PRIV(ucd_script_sets) + (cc[1] >> 5)), SLJIT_IMM, (sljit_sw)1 << (cc[1] & 0x1f));
|
||||
OP2U(SLJIT_AND32 | SLJIT_SET_Z, SLJIT_MEM1(TMP1), (sljit_sw)(PRIV(ucd_script_sets) + (cc[1] >> 5)), SLJIT_IMM, (sljit_sw)1 << (cc[1] & 0x1f));
|
||||
add_jump(compiler, compares > 0 ? list : backtracks, JUMP(SLJIT_NOT_ZERO ^ invertcmp));
|
||||
|
||||
if (jump != NULL)
|
||||
|
@ -7897,13 +7899,13 @@ while (*cc != XCL_END)
|
|||
|
||||
if (numberofcmps < 3 && (*cc == XCL_SINGLE || *cc == XCL_RANGE))
|
||||
{
|
||||
OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(c - charoffset));
|
||||
OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, (sljit_sw)(c - charoffset));
|
||||
OP_FLAGS(numberofcmps == 0 ? SLJIT_MOV : SLJIT_OR, TMP2, 0, SLJIT_EQUAL);
|
||||
numberofcmps++;
|
||||
}
|
||||
else if (numberofcmps > 0)
|
||||
{
|
||||
OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(c - charoffset));
|
||||
OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, (sljit_sw)(c - charoffset));
|
||||
OP_FLAGS(SLJIT_OR | SLJIT_SET_Z, TMP2, 0, SLJIT_EQUAL);
|
||||
jump = JUMP(SLJIT_NOT_ZERO ^ invertcmp);
|
||||
numberofcmps = 0;
|
||||
|
@ -7923,13 +7925,13 @@ while (*cc != XCL_END)
|
|||
|
||||
if (numberofcmps < 3 && (*cc == XCL_SINGLE || *cc == XCL_RANGE))
|
||||
{
|
||||
OP2(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(c - charoffset));
|
||||
OP2U(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, TMP1, 0, SLJIT_IMM, (sljit_sw)(c - charoffset));
|
||||
OP_FLAGS(numberofcmps == 0 ? SLJIT_MOV : SLJIT_OR, TMP2, 0, SLJIT_LESS_EQUAL);
|
||||
numberofcmps++;
|
||||
}
|
||||
else if (numberofcmps > 0)
|
||||
{
|
||||
OP2(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(c - charoffset));
|
||||
OP2U(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, TMP1, 0, SLJIT_IMM, (sljit_sw)(c - charoffset));
|
||||
OP_FLAGS(SLJIT_OR | SLJIT_SET_Z, TMP2, 0, SLJIT_LESS_EQUAL);
|
||||
jump = JUMP(SLJIT_NOT_ZERO ^ invertcmp);
|
||||
numberofcmps = 0;
|
||||
|
@ -7955,11 +7957,11 @@ while (*cc != XCL_END)
|
|||
break;
|
||||
|
||||
case PT_LAMP:
|
||||
OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Lu - typeoffset);
|
||||
OP2U(SLJIT_SUB | SLJIT_SET_Z, typereg, 0, SLJIT_IMM, ucp_Lu - typeoffset);
|
||||
OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_EQUAL);
|
||||
OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Ll - typeoffset);
|
||||
OP2U(SLJIT_SUB | SLJIT_SET_Z, typereg, 0, SLJIT_IMM, ucp_Ll - typeoffset);
|
||||
OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_EQUAL);
|
||||
OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Lt - typeoffset);
|
||||
OP2U(SLJIT_SUB | SLJIT_SET_Z, typereg, 0, SLJIT_IMM, ucp_Lt - typeoffset);
|
||||
OP_FLAGS(SLJIT_OR | SLJIT_SET_Z, TMP2, 0, SLJIT_EQUAL);
|
||||
jump = JUMP(SLJIT_NOT_ZERO ^ invertcmp);
|
||||
break;
|
||||
|
@ -7985,32 +7987,32 @@ while (*cc != XCL_END)
|
|||
case PT_SPACE:
|
||||
case PT_PXSPACE:
|
||||
SET_CHAR_OFFSET(9);
|
||||
OP2(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd - 0x9);
|
||||
OP2U(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, TMP1, 0, SLJIT_IMM, 0xd - 0x9);
|
||||
OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_LESS_EQUAL);
|
||||
|
||||
OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x85 - 0x9);
|
||||
OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, 0x85 - 0x9);
|
||||
OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_EQUAL);
|
||||
|
||||
OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x180e - 0x9);
|
||||
OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, 0x180e - 0x9);
|
||||
OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_EQUAL);
|
||||
|
||||
SET_TYPE_OFFSET(ucp_Zl);
|
||||
OP2(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Zs - ucp_Zl);
|
||||
OP2U(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, typereg, 0, SLJIT_IMM, ucp_Zs - ucp_Zl);
|
||||
OP_FLAGS(SLJIT_OR | SLJIT_SET_Z, TMP2, 0, SLJIT_LESS_EQUAL);
|
||||
jump = JUMP(SLJIT_NOT_ZERO ^ invertcmp);
|
||||
break;
|
||||
|
||||
case PT_WORD:
|
||||
OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(CHAR_UNDERSCORE - charoffset));
|
||||
OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, (sljit_sw)(CHAR_UNDERSCORE - charoffset));
|
||||
OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_EQUAL);
|
||||
/* Fall through. */
|
||||
|
||||
case PT_ALNUM:
|
||||
SET_TYPE_OFFSET(ucp_Ll);
|
||||
OP2(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Lu - ucp_Ll);
|
||||
OP2U(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, typereg, 0, SLJIT_IMM, ucp_Lu - ucp_Ll);
|
||||
OP_FLAGS((*cc == PT_ALNUM) ? SLJIT_MOV : SLJIT_OR, TMP2, 0, SLJIT_LESS_EQUAL);
|
||||
SET_TYPE_OFFSET(ucp_Nd);
|
||||
OP2(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_No - ucp_Nd);
|
||||
OP2U(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, typereg, 0, SLJIT_IMM, ucp_No - ucp_Nd);
|
||||
OP_FLAGS(SLJIT_OR | SLJIT_SET_Z, TMP2, 0, SLJIT_LESS_EQUAL);
|
||||
jump = JUMP(SLJIT_NOT_ZERO ^ invertcmp);
|
||||
break;
|
||||
|
@ -8033,7 +8035,7 @@ while (*cc != XCL_END)
|
|||
OP2(SLJIT_ADD, TMP2, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)charoffset);
|
||||
OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, other_cases[1] ^ other_cases[0]);
|
||||
}
|
||||
OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, other_cases[1]);
|
||||
OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP2, 0, SLJIT_IMM, other_cases[1]);
|
||||
OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_EQUAL);
|
||||
other_cases += 2;
|
||||
}
|
||||
|
@ -8046,41 +8048,41 @@ while (*cc != XCL_END)
|
|||
OP2(SLJIT_ADD, TMP2, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)charoffset);
|
||||
OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, other_cases[1] ^ other_cases[0]);
|
||||
}
|
||||
OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, other_cases[2]);
|
||||
OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP2, 0, SLJIT_IMM, other_cases[2]);
|
||||
OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_EQUAL);
|
||||
|
||||
OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(other_cases[0] - charoffset));
|
||||
OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, (sljit_sw)(other_cases[0] - charoffset));
|
||||
OP_FLAGS(SLJIT_OR | ((other_cases[3] == NOTACHAR) ? SLJIT_SET_Z : 0), TMP2, 0, SLJIT_EQUAL);
|
||||
|
||||
other_cases += 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(*other_cases++ - charoffset));
|
||||
OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, (sljit_sw)(*other_cases++ - charoffset));
|
||||
OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_EQUAL);
|
||||
}
|
||||
|
||||
while (*other_cases != NOTACHAR)
|
||||
{
|
||||
OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(*other_cases++ - charoffset));
|
||||
OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, (sljit_sw)(*other_cases++ - charoffset));
|
||||
OP_FLAGS(SLJIT_OR | ((*other_cases == NOTACHAR) ? SLJIT_SET_Z : 0), TMP2, 0, SLJIT_EQUAL);
|
||||
}
|
||||
jump = JUMP(SLJIT_NOT_ZERO ^ invertcmp);
|
||||
break;
|
||||
|
||||
case PT_UCNC:
|
||||
OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(CHAR_DOLLAR_SIGN - charoffset));
|
||||
OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, (sljit_sw)(CHAR_DOLLAR_SIGN - charoffset));
|
||||
OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_EQUAL);
|
||||
OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(CHAR_COMMERCIAL_AT - charoffset));
|
||||
OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, (sljit_sw)(CHAR_COMMERCIAL_AT - charoffset));
|
||||
OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_EQUAL);
|
||||
OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(CHAR_GRAVE_ACCENT - charoffset));
|
||||
OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, (sljit_sw)(CHAR_GRAVE_ACCENT - charoffset));
|
||||
OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_EQUAL);
|
||||
|
||||
SET_CHAR_OFFSET(0xa0);
|
||||
OP2(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(0xd7ff - charoffset));
|
||||
OP2U(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, TMP1, 0, SLJIT_IMM, (sljit_sw)(0xd7ff - charoffset));
|
||||
OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_LESS_EQUAL);
|
||||
SET_CHAR_OFFSET(0);
|
||||
OP2(SLJIT_SUB | SLJIT_SET_GREATER_EQUAL, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xe000 - 0);
|
||||
OP2U(SLJIT_SUB | SLJIT_SET_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 0xe000 - 0);
|
||||
OP_FLAGS(SLJIT_OR | SLJIT_SET_Z, TMP2, 0, SLJIT_GREATER_EQUAL);
|
||||
jump = JUMP(SLJIT_NOT_ZERO ^ invertcmp);
|
||||
break;
|
||||
|
@ -8088,20 +8090,20 @@ while (*cc != XCL_END)
|
|||
case PT_PXGRAPH:
|
||||
/* C and Z groups are the farthest two groups. */
|
||||
SET_TYPE_OFFSET(ucp_Ll);
|
||||
OP2(SLJIT_SUB | SLJIT_SET_GREATER, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_So - ucp_Ll);
|
||||
OP2U(SLJIT_SUB | SLJIT_SET_GREATER, typereg, 0, SLJIT_IMM, ucp_So - ucp_Ll);
|
||||
OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_GREATER);
|
||||
|
||||
jump = CMP(SLJIT_NOT_EQUAL, typereg, 0, SLJIT_IMM, ucp_Cf - ucp_Ll);
|
||||
|
||||
/* In case of ucp_Cf, we overwrite the result. */
|
||||
SET_CHAR_OFFSET(0x2066);
|
||||
OP2(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x2069 - 0x2066);
|
||||
OP2U(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, TMP1, 0, SLJIT_IMM, 0x2069 - 0x2066);
|
||||
OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_LESS_EQUAL);
|
||||
|
||||
OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x061c - 0x2066);
|
||||
OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, 0x061c - 0x2066);
|
||||
OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_EQUAL);
|
||||
|
||||
OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x180e - 0x2066);
|
||||
OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, 0x180e - 0x2066);
|
||||
OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_EQUAL);
|
||||
|
||||
JUMPHERE(jump);
|
||||
|
@ -8111,20 +8113,20 @@ while (*cc != XCL_END)
|
|||
case PT_PXPRINT:
|
||||
/* C and Z groups are the farthest two groups. */
|
||||
SET_TYPE_OFFSET(ucp_Ll);
|
||||
OP2(SLJIT_SUB | SLJIT_SET_GREATER, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_So - ucp_Ll);
|
||||
OP2U(SLJIT_SUB | SLJIT_SET_GREATER, typereg, 0, SLJIT_IMM, ucp_So - ucp_Ll);
|
||||
OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_GREATER);
|
||||
|
||||
OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Zs - ucp_Ll);
|
||||
OP2U(SLJIT_SUB | SLJIT_SET_Z, typereg, 0, SLJIT_IMM, ucp_Zs - ucp_Ll);
|
||||
OP_FLAGS(SLJIT_AND, TMP2, 0, SLJIT_NOT_EQUAL);
|
||||
|
||||
jump = CMP(SLJIT_NOT_EQUAL, typereg, 0, SLJIT_IMM, ucp_Cf - ucp_Ll);
|
||||
|
||||
/* In case of ucp_Cf, we overwrite the result. */
|
||||
SET_CHAR_OFFSET(0x2066);
|
||||
OP2(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x2069 - 0x2066);
|
||||
OP2U(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, TMP1, 0, SLJIT_IMM, 0x2069 - 0x2066);
|
||||
OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_LESS_EQUAL);
|
||||
|
||||
OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x061c - 0x2066);
|
||||
OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, 0x061c - 0x2066);
|
||||
OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_EQUAL);
|
||||
|
||||
JUMPHERE(jump);
|
||||
|
@ -8133,15 +8135,15 @@ while (*cc != XCL_END)
|
|||
|
||||
case PT_PXPUNCT:
|
||||
SET_TYPE_OFFSET(ucp_Sc);
|
||||
OP2(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_So - ucp_Sc);
|
||||
OP2U(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, typereg, 0, SLJIT_IMM, ucp_So - ucp_Sc);
|
||||
OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_LESS_EQUAL);
|
||||
|
||||
SET_CHAR_OFFSET(0);
|
||||
OP2(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x7f);
|
||||
OP2U(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, TMP1, 0, SLJIT_IMM, 0x7f);
|
||||
OP_FLAGS(SLJIT_AND, TMP2, 0, SLJIT_LESS_EQUAL);
|
||||
|
||||
SET_TYPE_OFFSET(ucp_Pc);
|
||||
OP2(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Ps - ucp_Pc);
|
||||
OP2U(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, typereg, 0, SLJIT_IMM, ucp_Ps - ucp_Pc);
|
||||
OP_FLAGS(SLJIT_OR | SLJIT_SET_Z, TMP2, 0, SLJIT_LESS_EQUAL);
|
||||
jump = JUMP(SLJIT_NOT_ZERO ^ invertcmp);
|
||||
break;
|
||||
|
@ -8226,9 +8228,9 @@ switch(type)
|
|||
else
|
||||
{
|
||||
jump[1] = CMP(SLJIT_EQUAL, TMP2, 0, STR_END, 0);
|
||||
OP2(SLJIT_SUB | SLJIT_SET_LESS, SLJIT_UNUSED, 0, TMP2, 0, STR_END, 0);
|
||||
OP2U(SLJIT_SUB | SLJIT_SET_LESS, TMP2, 0, STR_END, 0);
|
||||
OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_LESS);
|
||||
OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff);
|
||||
OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff);
|
||||
OP_FLAGS(SLJIT_OR | SLJIT_SET_Z, TMP2, 0, SLJIT_NOT_EQUAL);
|
||||
add_jump(compiler, backtracks, JUMP(SLJIT_NOT_EQUAL));
|
||||
check_partial(common, TRUE);
|
||||
|
@ -8251,7 +8253,7 @@ switch(type)
|
|||
OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
|
||||
jump[1] = CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR);
|
||||
OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
|
||||
OP2(SLJIT_SUB | SLJIT_SET_Z | SLJIT_SET_GREATER, SLJIT_UNUSED, 0, TMP2, 0, STR_END, 0);
|
||||
OP2U(SLJIT_SUB | SLJIT_SET_Z | SLJIT_SET_GREATER, TMP2, 0, STR_END, 0);
|
||||
jump[2] = JUMP(SLJIT_GREATER);
|
||||
add_jump(compiler, backtracks, JUMP(SLJIT_NOT_EQUAL) /* LESS */);
|
||||
/* Equal. */
|
||||
|
@ -8294,10 +8296,10 @@ switch(type)
|
|||
if (HAS_VIRTUAL_REGISTERS)
|
||||
{
|
||||
OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);
|
||||
OP2(SLJIT_AND32 | SLJIT_SET_Z, SLJIT_UNUSED, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, options), SLJIT_IMM, PCRE2_NOTEOL);
|
||||
OP2U(SLJIT_AND32 | SLJIT_SET_Z, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, options), SLJIT_IMM, PCRE2_NOTEOL);
|
||||
}
|
||||
else
|
||||
OP2(SLJIT_AND32 | SLJIT_SET_Z, SLJIT_UNUSED, 0, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, options), SLJIT_IMM, PCRE2_NOTEOL);
|
||||
OP2U(SLJIT_AND32 | SLJIT_SET_Z, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, options), SLJIT_IMM, PCRE2_NOTEOL);
|
||||
add_jump(compiler, backtracks, JUMP(SLJIT_NOT_ZERO));
|
||||
|
||||
if (!common->endonly)
|
||||
|
@ -8314,10 +8316,10 @@ switch(type)
|
|||
if (HAS_VIRTUAL_REGISTERS)
|
||||
{
|
||||
OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);
|
||||
OP2(SLJIT_AND32 | SLJIT_SET_Z, SLJIT_UNUSED, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, options), SLJIT_IMM, PCRE2_NOTEOL);
|
||||
OP2U(SLJIT_AND32 | SLJIT_SET_Z, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, options), SLJIT_IMM, PCRE2_NOTEOL);
|
||||
}
|
||||
else
|
||||
OP2(SLJIT_AND32 | SLJIT_SET_Z, SLJIT_UNUSED, 0, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, options), SLJIT_IMM, PCRE2_NOTEOL);
|
||||
OP2U(SLJIT_AND32 | SLJIT_SET_Z, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, options), SLJIT_IMM, PCRE2_NOTEOL);
|
||||
add_jump(compiler, backtracks, JUMP(SLJIT_NOT_ZERO));
|
||||
check_partial(common, FALSE);
|
||||
jump[0] = JUMP(SLJIT_JUMP);
|
||||
|
@ -8357,14 +8359,14 @@ switch(type)
|
|||
OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);
|
||||
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, begin));
|
||||
add_jump(compiler, backtracks, CMP(SLJIT_GREATER, STR_PTR, 0, TMP1, 0));
|
||||
OP2(SLJIT_AND32 | SLJIT_SET_Z, SLJIT_UNUSED, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, options), SLJIT_IMM, PCRE2_NOTBOL);
|
||||
OP2U(SLJIT_AND32 | SLJIT_SET_Z, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, options), SLJIT_IMM, PCRE2_NOTBOL);
|
||||
add_jump(compiler, backtracks, JUMP(SLJIT_NOT_ZERO));
|
||||
}
|
||||
else
|
||||
{
|
||||
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, begin));
|
||||
add_jump(compiler, backtracks, CMP(SLJIT_GREATER, STR_PTR, 0, TMP1, 0));
|
||||
OP2(SLJIT_AND32 | SLJIT_SET_Z, SLJIT_UNUSED, 0, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, options), SLJIT_IMM, PCRE2_NOTBOL);
|
||||
OP2U(SLJIT_AND32 | SLJIT_SET_Z, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, options), SLJIT_IMM, PCRE2_NOTBOL);
|
||||
add_jump(compiler, backtracks, JUMP(SLJIT_NOT_ZERO));
|
||||
}
|
||||
return cc;
|
||||
|
@ -8376,13 +8378,13 @@ switch(type)
|
|||
OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
|
||||
OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));
|
||||
jump[1] = CMP(SLJIT_GREATER, STR_PTR, 0, TMP2, 0);
|
||||
OP2(SLJIT_AND32 | SLJIT_SET_Z, SLJIT_UNUSED, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, options), SLJIT_IMM, PCRE2_NOTBOL);
|
||||
OP2U(SLJIT_AND32 | SLJIT_SET_Z, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, options), SLJIT_IMM, PCRE2_NOTBOL);
|
||||
}
|
||||
else
|
||||
{
|
||||
OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, begin));
|
||||
jump[1] = CMP(SLJIT_GREATER, STR_PTR, 0, TMP2, 0);
|
||||
OP2(SLJIT_AND32 | SLJIT_SET_Z, SLJIT_UNUSED, 0, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, options), SLJIT_IMM, PCRE2_NOTBOL);
|
||||
OP2U(SLJIT_AND32 | SLJIT_SET_Z, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, options), SLJIT_IMM, PCRE2_NOTBOL);
|
||||
}
|
||||
add_jump(compiler, backtracks, JUMP(SLJIT_NOT_ZERO));
|
||||
jump[0] = JUMP(SLJIT_JUMP);
|
||||
|
@ -8677,7 +8679,7 @@ switch(type)
|
|||
#endif
|
||||
read_char8_type(common, backtracks, type == OP_NOT_DIGIT);
|
||||
/* Flip the starting bit in the negative case. */
|
||||
OP2(SLJIT_AND | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_digit);
|
||||
OP2U(SLJIT_AND | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, ctype_digit);
|
||||
add_jump(compiler, backtracks, JUMP(type == OP_DIGIT ? SLJIT_ZERO : SLJIT_NOT_ZERO));
|
||||
return cc;
|
||||
|
||||
|
@ -8691,7 +8693,7 @@ switch(type)
|
|||
else
|
||||
#endif
|
||||
read_char8_type(common, backtracks, type == OP_NOT_WHITESPACE);
|
||||
OP2(SLJIT_AND | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_space);
|
||||
OP2U(SLJIT_AND | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, ctype_space);
|
||||
add_jump(compiler, backtracks, JUMP(type == OP_WHITESPACE ? SLJIT_ZERO : SLJIT_NOT_ZERO));
|
||||
return cc;
|
||||
|
||||
|
@ -8705,7 +8707,7 @@ switch(type)
|
|||
else
|
||||
#endif
|
||||
read_char8_type(common, backtracks, type == OP_NOT_WORDCHAR);
|
||||
OP2(SLJIT_AND | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_word);
|
||||
OP2U(SLJIT_AND | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, ctype_word);
|
||||
add_jump(compiler, backtracks, JUMP(type == OP_WORDCHAR ? SLJIT_ZERO : SLJIT_NOT_ZERO));
|
||||
return cc;
|
||||
|
||||
|
@ -8753,7 +8755,7 @@ switch(type)
|
|||
#elif PCRE2_CODE_UNIT_WIDTH == 16
|
||||
jump[0] = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
|
||||
OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
|
||||
OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);
|
||||
OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, 0xd800);
|
||||
OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_EQUAL);
|
||||
OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
|
||||
OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
|
||||
|
@ -8847,13 +8849,13 @@ switch(type)
|
|||
OP1(SLJIT_MOV, SLJIT_R0, 0, ARGUMENTS, 0);
|
||||
|
||||
#if PCRE2_CODE_UNIT_WIDTH != 32
|
||||
sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_RET(SW) | SLJIT_ARG1(SW) | SLJIT_ARG2(SW), SLJIT_IMM,
|
||||
common->utf ? (common->invalid_utf ? SLJIT_FUNC_OFFSET(do_extuni_utf_invalid) : SLJIT_FUNC_OFFSET(do_extuni_utf)) : SLJIT_FUNC_OFFSET(do_extuni_no_utf));
|
||||
sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_ARGS2(W, W, W), SLJIT_IMM,
|
||||
common->utf ? (common->invalid_utf ? SLJIT_FUNC_ADDR(do_extuni_utf_invalid) : SLJIT_FUNC_ADDR(do_extuni_utf)) : SLJIT_FUNC_ADDR(do_extuni_no_utf));
|
||||
if (common->invalid_utf)
|
||||
add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0));
|
||||
#else
|
||||
sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_RET(SW) | SLJIT_ARG1(SW) | SLJIT_ARG2(SW), SLJIT_IMM,
|
||||
common->invalid_utf ? SLJIT_FUNC_OFFSET(do_extuni_utf_invalid) : SLJIT_FUNC_OFFSET(do_extuni_no_utf));
|
||||
sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_ARGS2(W, W, W), SLJIT_IMM,
|
||||
common->invalid_utf ? SLJIT_FUNC_ADDR(do_extuni_utf_invalid) : SLJIT_FUNC_ADDR(do_extuni_no_utf));
|
||||
if (!common->utf || common->invalid_utf)
|
||||
add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0));
|
||||
#endif
|
||||
|
@ -8915,7 +8917,7 @@ switch(type)
|
|||
|
||||
if (sljit_has_cpu_feature(SLJIT_HAS_CMOV))
|
||||
{
|
||||
OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, oc);
|
||||
OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, oc);
|
||||
CMOV(SLJIT_EQUAL, TMP1, SLJIT_IMM, c);
|
||||
add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, c));
|
||||
}
|
||||
|
@ -9035,7 +9037,7 @@ switch(type)
|
|||
OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);
|
||||
OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)cc);
|
||||
OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);
|
||||
OP2(SLJIT_AND | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0);
|
||||
OP2U(SLJIT_AND | SLJIT_SET_Z, TMP1, 0, TMP2, 0);
|
||||
add_jump(compiler, backtracks, JUMP(SLJIT_ZERO));
|
||||
|
||||
#if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH != 8
|
||||
|
@ -9273,7 +9275,7 @@ if (common->utf && *cc == OP_REFI)
|
|||
caseless_loop = LABEL();
|
||||
OP1(SLJIT_MOV_U32, TMP1, 0, SLJIT_MEM1(TMP2), 0);
|
||||
OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, SLJIT_IMM, sizeof(uint32_t));
|
||||
OP2(SLJIT_SUB | SLJIT_SET_Z | SLJIT_SET_LESS, SLJIT_UNUSED, 0, TMP1, 0, char1_reg, 0);
|
||||
OP2U(SLJIT_SUB | SLJIT_SET_Z | SLJIT_SET_LESS, TMP1, 0, char1_reg, 0);
|
||||
JUMPTO(SLJIT_EQUAL, loop);
|
||||
JUMPTO(SLJIT_LESS, caseless_loop);
|
||||
|
||||
|
@ -9732,12 +9734,12 @@ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS0, STR_PTR, 0);
|
|||
/* SLJIT_R0 = arguments */
|
||||
OP1(SLJIT_MOV, SLJIT_R1, 0, STACK_TOP, 0);
|
||||
GET_LOCAL_BASE(SLJIT_R2, 0, OVECTOR_START);
|
||||
sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_RET(S32) | SLJIT_ARG1(SW) | SLJIT_ARG2(SW) | SLJIT_ARG3(SW), SLJIT_IMM, SLJIT_FUNC_OFFSET(do_callout));
|
||||
sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_ARGS3(32, W, W, W), SLJIT_IMM, SLJIT_FUNC_ADDR(do_callout));
|
||||
OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), LOCALS0);
|
||||
free_stack(common, callout_arg_size);
|
||||
|
||||
/* Check return value. */
|
||||
OP2(SLJIT_SUB32 | SLJIT_SET_Z | SLJIT_SET_SIG_GREATER, SLJIT_UNUSED, 0, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0);
|
||||
OP2U(SLJIT_SUB32 | SLJIT_SET_Z | SLJIT_SET_SIG_GREATER, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0);
|
||||
add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_SIG_GREATER));
|
||||
if (common->abort_label == NULL)
|
||||
add_jump(compiler, &common->abort, JUMP(SLJIT_NOT_EQUAL) /* SIG_LESS */);
|
||||
|
@ -10305,10 +10307,10 @@ SLJIT_ASSERT(TMP1 == SLJIT_R0 && STR_PTR == SLJIT_R1);
|
|||
|
||||
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);
|
||||
#ifdef SUPPORT_UNICODE
|
||||
sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_RET(SW) | SLJIT_ARG1(SW) | SLJIT_ARG2(SW), SLJIT_IMM,
|
||||
common->utf ? SLJIT_FUNC_OFFSET(do_script_run_utf) : SLJIT_FUNC_OFFSET(do_script_run));
|
||||
sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_ARGS2(W, W, W), SLJIT_IMM,
|
||||
common->utf ? SLJIT_FUNC_ADDR(do_script_run_utf) : SLJIT_FUNC_ADDR(do_script_run));
|
||||
#else
|
||||
sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_RET(SW) | SLJIT_ARG1(SW) | SLJIT_ARG2(SW), SLJIT_IMM, SLJIT_FUNC_OFFSET(do_script_run));
|
||||
sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_ARGS2(W, W, W), SLJIT_IMM, SLJIT_FUNC_ADDR(do_script_run));
|
||||
#endif
|
||||
|
||||
OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_RETURN_REG, 0);
|
||||
|
@ -11531,7 +11533,7 @@ switch(opcode)
|
|||
|
||||
if (common->mode == PCRE2_JIT_COMPLETE)
|
||||
{
|
||||
OP2(SLJIT_SUB | SLJIT_SET_GREATER, SLJIT_UNUSED, 0, STR_PTR, 0, STR_END, 0);
|
||||
OP2U(SLJIT_SUB | SLJIT_SET_GREATER, STR_PTR, 0, STR_END, 0);
|
||||
CMOV(SLJIT_GREATER, STR_PTR, STR_END, 0);
|
||||
}
|
||||
else
|
||||
|
@ -11824,7 +11826,7 @@ switch(opcode)
|
|||
|
||||
if (common->mode == PCRE2_JIT_COMPLETE)
|
||||
{
|
||||
OP2(SLJIT_SUB | SLJIT_SET_GREATER, SLJIT_UNUSED, 0, STR_PTR, 0, STR_END, 0);
|
||||
OP2U(SLJIT_SUB | SLJIT_SET_GREATER, STR_PTR, 0, STR_END, 0);
|
||||
CMOV(SLJIT_GREATER, STR_PTR, STR_END, 0);
|
||||
}
|
||||
else
|
||||
|
@ -11908,9 +11910,9 @@ if (HAS_VIRTUAL_REGISTERS)
|
|||
else
|
||||
OP1(SLJIT_MOV_U32, TMP2, 0, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, options));
|
||||
|
||||
OP2(SLJIT_AND | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, PCRE2_NOTEMPTY);
|
||||
OP2U(SLJIT_AND | SLJIT_SET_Z, TMP2, 0, SLJIT_IMM, PCRE2_NOTEMPTY);
|
||||
add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_NOT_ZERO));
|
||||
OP2(SLJIT_AND | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, PCRE2_NOTEMPTY_ATSTART);
|
||||
OP2U(SLJIT_AND | SLJIT_SET_Z, TMP2, 0, SLJIT_IMM, PCRE2_NOTEMPTY_ATSTART);
|
||||
if (common->accept_label == NULL)
|
||||
add_jump(compiler, &common->accept, JUMP(SLJIT_ZERO));
|
||||
else
|
||||
|
@ -13161,7 +13163,7 @@ if (opcode == OP_SKIP_ARG)
|
|||
SLJIT_ASSERT(common->control_head_ptr != 0 && TMP1 == SLJIT_R0 && STR_PTR == SLJIT_R1);
|
||||
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr);
|
||||
OP1(SLJIT_MOV, SLJIT_R1, 0, SLJIT_IMM, (sljit_sw)(current->cc + 2));
|
||||
sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_RET(SW) | SLJIT_ARG1(SW) | SLJIT_ARG2(SW), SLJIT_IMM, SLJIT_FUNC_OFFSET(do_search_mark));
|
||||
sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_ARGS2(W, W, W), SLJIT_IMM, SLJIT_FUNC_ADDR(do_search_mark));
|
||||
|
||||
OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_R0, 0);
|
||||
add_jump(compiler, &common->reset_match, CMP(SLJIT_NOT_EQUAL, SLJIT_R0, 0, SLJIT_IMM, 0));
|
||||
|
@ -13850,7 +13852,7 @@ if (!compiler)
|
|||
common->compiler = compiler;
|
||||
|
||||
/* Main pcre2_jit_exec entry. */
|
||||
sljit_emit_enter(compiler, 0, SLJIT_ARG1(SW), 5, 5, 0, 0, private_data_size);
|
||||
sljit_emit_enter(compiler, 0, SLJIT_ARGS1(W, W), 5, 5, 0, 0, private_data_size);
|
||||
|
||||
/* Register init. */
|
||||
reset_ovector(common, (re->top_bracket + 1) * 2);
|
||||
|
@ -14057,9 +14059,9 @@ if (common->might_be_empty)
|
|||
JUMPHERE(empty_match);
|
||||
OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
|
||||
OP1(SLJIT_MOV_U32, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, options));
|
||||
OP2(SLJIT_AND | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, PCRE2_NOTEMPTY);
|
||||
OP2U(SLJIT_AND | SLJIT_SET_Z, TMP2, 0, SLJIT_IMM, PCRE2_NOTEMPTY);
|
||||
JUMPTO(SLJIT_NOT_ZERO, empty_match_backtrack_label);
|
||||
OP2(SLJIT_AND | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, PCRE2_NOTEMPTY_ATSTART);
|
||||
OP2U(SLJIT_AND | SLJIT_SET_Z, TMP2, 0, SLJIT_IMM, PCRE2_NOTEMPTY_ATSTART);
|
||||
JUMPTO(SLJIT_ZERO, empty_match_found_label);
|
||||
OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str));
|
||||
CMPTO(SLJIT_NOT_EQUAL, TMP2, 0, STR_PTR, 0, empty_match_found_label);
|
||||
|
@ -14104,7 +14106,7 @@ OP2(SLJIT_SUB, SLJIT_R1, 0, STACK_LIMIT, 0, SLJIT_IMM, STACK_GROWTH_RATE);
|
|||
OP1(SLJIT_MOV, SLJIT_R0, 0, SLJIT_MEM1(SLJIT_R0), SLJIT_OFFSETOF(jit_arguments, stack));
|
||||
OP1(SLJIT_MOV, STACK_LIMIT, 0, TMP2, 0);
|
||||
|
||||
sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_RET(SW) | SLJIT_ARG1(SW) | SLJIT_ARG2(SW), SLJIT_IMM, SLJIT_FUNC_OFFSET(sljit_stack_resize));
|
||||
sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_ARGS2(W, W, W), SLJIT_IMM, SLJIT_FUNC_ADDR(sljit_stack_resize));
|
||||
|
||||
jump = CMP(SLJIT_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0);
|
||||
OP1(SLJIT_MOV, TMP2, 0, STACK_LIMIT, 0);
|
||||
|
|
|
@ -339,7 +339,7 @@ if (common->mode != PCRE2_JIT_COMPLETE)
|
|||
{
|
||||
JUMPHERE(partial_quit[0]);
|
||||
JUMPHERE(partial_quit[1]);
|
||||
OP2(SLJIT_SUB | SLJIT_SET_GREATER, SLJIT_UNUSED, 0, STR_PTR, 0, STR_END, 0);
|
||||
OP2U(SLJIT_SUB | SLJIT_SET_GREATER, STR_PTR, 0, STR_END, 0);
|
||||
CMOV(SLJIT_GREATER, STR_PTR, STR_END, 0);
|
||||
}
|
||||
else
|
||||
|
@ -537,7 +537,7 @@ if (common->match_end_ptr != 0)
|
|||
OP1(SLJIT_MOV, TMP3, 0, STR_END, 0);
|
||||
OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(offs1 + 1));
|
||||
|
||||
OP2(SLJIT_SUB | SLJIT_SET_LESS, SLJIT_UNUSED, 0, TMP1, 0, STR_END, 0);
|
||||
OP2U(SLJIT_SUB | SLJIT_SET_LESS, TMP1, 0, STR_END, 0);
|
||||
CMOV(SLJIT_LESS, STR_END, TMP1, 0);
|
||||
}
|
||||
|
||||
|
@ -1067,7 +1067,7 @@ else
|
|||
OP1(SLJIT_MOV, SLJIT_R0, 0, SLJIT_MEM1(SLJIT_SP), common->match_end_ptr);
|
||||
OP2(SLJIT_ADD, SLJIT_R0, 0, SLJIT_R0, 0, SLJIT_IMM, IN_UCHARS(offs1 + 1));
|
||||
|
||||
OP2(SLJIT_SUB | SLJIT_SET_LESS, SLJIT_UNUSED, 0, STR_END, 0, SLJIT_R0, 0);
|
||||
OP2U(SLJIT_SUB | SLJIT_SET_LESS, STR_END, 0, SLJIT_R0, 0);
|
||||
CMOV(SLJIT_LESS, SLJIT_R0, STR_END, 0);
|
||||
}
|
||||
|
||||
|
@ -1418,7 +1418,7 @@ if (common->mode != PCRE2_JIT_COMPLETE)
|
|||
{
|
||||
JUMPHERE(partial_quit[0]);
|
||||
JUMPHERE(partial_quit[1]);
|
||||
OP2(SLJIT_SUB | SLJIT_SET_GREATER, SLJIT_UNUSED, 0, STR_PTR, 0, STR_END, 0);
|
||||
OP2U(SLJIT_SUB | SLJIT_SET_GREATER, STR_PTR, 0, STR_END, 0);
|
||||
CMOV(SLJIT_GREATER, STR_PTR, STR_END, 0);
|
||||
}
|
||||
else
|
||||
|
@ -1673,7 +1673,7 @@ if (common->match_end_ptr != 0)
|
|||
OP1(SLJIT_MOV, TMP3, 0, STR_END, 0);
|
||||
OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(offs1 + 1));
|
||||
|
||||
OP2(SLJIT_SUB | SLJIT_SET_LESS, SLJIT_UNUSED, 0, TMP1, 0, STR_END, 0);
|
||||
OP2U(SLJIT_SUB | SLJIT_SET_LESS, TMP1, 0, STR_END, 0);
|
||||
CMOV(SLJIT_LESS, STR_END, TMP1, 0);
|
||||
}
|
||||
|
||||
|
|
|
@ -60,7 +60,7 @@ extern "C" {
|
|||
SLJIT_LITTLE_ENDIAN : little endian architecture
|
||||
SLJIT_BIG_ENDIAN : big endian architecture
|
||||
SLJIT_UNALIGNED : allows unaligned memory accesses for non-fpu operations (only!)
|
||||
SLJIT_INDIRECT_CALL : see SLJIT_FUNC_OFFSET() for more information
|
||||
SLJIT_INDIRECT_CALL : see SLJIT_FUNC_ADDR() for more information
|
||||
|
||||
Constants:
|
||||
SLJIT_NUMBER_OF_REGISTERS : number of available registers
|
||||
|
@ -148,7 +148,7 @@ extern "C" {
|
|||
#endif
|
||||
#elif defined (__aarch64__)
|
||||
#define SLJIT_CONFIG_ARM_64 1
|
||||
#elif defined(__ppc64__) || defined(__powerpc64__) || defined(_ARCH_PPC64) || (defined(_POWER) && defined(__64BIT__))
|
||||
#elif defined(__ppc64__) || defined(__powerpc64__) || (defined(_ARCH_PPC64) && defined(__64BIT__)) || (defined(_POWER) && defined(__64BIT__))
|
||||
#define SLJIT_CONFIG_PPC_64 1
|
||||
#elif defined(__ppc__) || defined(__powerpc__) || defined(_ARCH_PPC) || defined(_ARCH_PWR) || defined(_ARCH_PWR2) || defined(_POWER)
|
||||
#define SLJIT_CONFIG_PPC_32 1
|
||||
|
@ -645,18 +645,23 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_sw sljit_exec_offset(void* ptr);
|
|||
|
||||
#define SLJIT_NUMBER_OF_REGISTERS 12
|
||||
#define SLJIT_NUMBER_OF_SAVED_REGISTERS 9
|
||||
#define SLJIT_NUMBER_OF_FLOAT_REGISTERS 7
|
||||
#define SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS 0
|
||||
#define SLJIT_LOCALS_OFFSET_BASE (compiler->locals_offset)
|
||||
#define SLJIT_PREF_SHIFT_REG SLJIT_R2
|
||||
|
||||
#elif (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
|
||||
|
||||
#define SLJIT_NUMBER_OF_REGISTERS 13
|
||||
#define SLJIT_NUMBER_OF_FLOAT_REGISTERS 15
|
||||
#ifndef _WIN64
|
||||
#define SLJIT_NUMBER_OF_SAVED_REGISTERS 6
|
||||
#define SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS 0
|
||||
#define SLJIT_LOCALS_OFFSET_BASE 0
|
||||
#else /* _WIN64 */
|
||||
#define SLJIT_NUMBER_OF_SAVED_REGISTERS 8
|
||||
#define SLJIT_LOCALS_OFFSET_BASE (compiler->locals_offset)
|
||||
#define SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS 10
|
||||
#define SLJIT_LOCALS_OFFSET_BASE (4 * (sljit_s32)sizeof(sljit_sw))
|
||||
#endif /* !_WIN64 */
|
||||
#define SLJIT_PREF_SHIFT_REG SLJIT_R3
|
||||
|
||||
|
@ -664,31 +669,39 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_sw sljit_exec_offset(void* ptr);
|
|||
|
||||
#define SLJIT_NUMBER_OF_REGISTERS 12
|
||||
#define SLJIT_NUMBER_OF_SAVED_REGISTERS 8
|
||||
#define SLJIT_NUMBER_OF_FLOAT_REGISTERS 14
|
||||
#define SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS 8
|
||||
#define SLJIT_LOCALS_OFFSET_BASE 0
|
||||
|
||||
#elif (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2)
|
||||
|
||||
#define SLJIT_NUMBER_OF_REGISTERS 12
|
||||
#define SLJIT_NUMBER_OF_SAVED_REGISTERS 8
|
||||
#define SLJIT_NUMBER_OF_FLOAT_REGISTERS 14
|
||||
#define SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS 8
|
||||
#define SLJIT_LOCALS_OFFSET_BASE 0
|
||||
|
||||
#elif (defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64)
|
||||
|
||||
#define SLJIT_NUMBER_OF_REGISTERS 26
|
||||
#define SLJIT_NUMBER_OF_SAVED_REGISTERS 10
|
||||
#define SLJIT_LOCALS_OFFSET_BASE 0
|
||||
#define SLJIT_NUMBER_OF_FLOAT_REGISTERS 30
|
||||
#define SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS 8
|
||||
#define SLJIT_LOCALS_OFFSET_BASE (2 * (sljit_s32)sizeof(sljit_sw))
|
||||
|
||||
#elif (defined SLJIT_CONFIG_PPC && SLJIT_CONFIG_PPC)
|
||||
|
||||
#define SLJIT_NUMBER_OF_REGISTERS 23
|
||||
#define SLJIT_NUMBER_OF_SAVED_REGISTERS 17
|
||||
#define SLJIT_NUMBER_OF_FLOAT_REGISTERS 30
|
||||
#define SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS 18
|
||||
#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) || (defined _AIX)
|
||||
#define SLJIT_LOCALS_OFFSET_BASE ((6 + 8) * sizeof(sljit_sw))
|
||||
#define SLJIT_LOCALS_OFFSET_BASE ((6 + 8) * (sljit_s32)sizeof(sljit_sw))
|
||||
#elif (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
|
||||
/* Add +1 for double alignment. */
|
||||
#define SLJIT_LOCALS_OFFSET_BASE ((3 + 1) * sizeof(sljit_sw))
|
||||
#define SLJIT_LOCALS_OFFSET_BASE ((3 + 1) * (sljit_s32)sizeof(sljit_sw))
|
||||
#else
|
||||
#define SLJIT_LOCALS_OFFSET_BASE (3 * sizeof(sljit_sw))
|
||||
#define SLJIT_LOCALS_OFFSET_BASE (3 * (sljit_s32)sizeof(sljit_sw))
|
||||
#endif /* SLJIT_CONFIG_PPC_64 || _AIX */
|
||||
|
||||
#elif (defined SLJIT_CONFIG_MIPS && SLJIT_CONFIG_MIPS)
|
||||
|
@ -696,19 +709,25 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_sw sljit_exec_offset(void* ptr);
|
|||
#define SLJIT_NUMBER_OF_REGISTERS 21
|
||||
#define SLJIT_NUMBER_OF_SAVED_REGISTERS 8
|
||||
#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
|
||||
#define SLJIT_LOCALS_OFFSET_BASE (4 * sizeof(sljit_sw))
|
||||
#define SLJIT_LOCALS_OFFSET_BASE (4 * (sljit_s32)sizeof(sljit_sw))
|
||||
#define SLJIT_NUMBER_OF_FLOAT_REGISTERS 13
|
||||
#define SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS 6
|
||||
#else
|
||||
#define SLJIT_LOCALS_OFFSET_BASE 0
|
||||
#define SLJIT_NUMBER_OF_FLOAT_REGISTERS 29
|
||||
#define SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS 8
|
||||
#endif
|
||||
|
||||
#elif (defined SLJIT_CONFIG_SPARC && SLJIT_CONFIG_SPARC)
|
||||
|
||||
#define SLJIT_NUMBER_OF_REGISTERS 18
|
||||
#define SLJIT_NUMBER_OF_SAVED_REGISTERS 14
|
||||
#define SLJIT_NUMBER_OF_FLOAT_REGISTERS 14
|
||||
#define SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS 0
|
||||
#if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32)
|
||||
/* saved registers (16), return struct pointer (1), space for 6 argument words (1),
|
||||
4th double arg (2), double alignment (1). */
|
||||
#define SLJIT_LOCALS_OFFSET_BASE ((16 + 1 + 6 + 2 + 1) * sizeof(sljit_sw))
|
||||
#define SLJIT_LOCALS_OFFSET_BASE ((16 + 1 + 6 + 2 + 1) * (sljit_s32)sizeof(sljit_sw))
|
||||
#endif
|
||||
|
||||
#elif (defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X)
|
||||
|
@ -736,12 +755,16 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_sw sljit_exec_offset(void* ptr);
|
|||
|
||||
#define SLJIT_NUMBER_OF_REGISTERS 12
|
||||
#define SLJIT_NUMBER_OF_SAVED_REGISTERS 8
|
||||
#define SLJIT_NUMBER_OF_FLOAT_REGISTERS 15
|
||||
#define SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS 8
|
||||
#define SLJIT_LOCALS_OFFSET_BASE SLJIT_S390X_DEFAULT_STACK_FRAME_SIZE
|
||||
|
||||
#elif (defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED)
|
||||
|
||||
#define SLJIT_NUMBER_OF_REGISTERS 0
|
||||
#define SLJIT_NUMBER_OF_SAVED_REGISTERS 0
|
||||
#define SLJIT_NUMBER_OF_FLOAT_REGISTERS 0
|
||||
#define SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS 0
|
||||
#define SLJIT_LOCALS_OFFSET_BASE 0
|
||||
|
||||
#endif
|
||||
|
@ -751,13 +774,6 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_sw sljit_exec_offset(void* ptr);
|
|||
#define SLJIT_NUMBER_OF_SCRATCH_REGISTERS \
|
||||
(SLJIT_NUMBER_OF_REGISTERS - SLJIT_NUMBER_OF_SAVED_REGISTERS)
|
||||
|
||||
#define SLJIT_NUMBER_OF_FLOAT_REGISTERS 6
|
||||
#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) && (defined _WIN64)
|
||||
#define SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS 1
|
||||
#else
|
||||
#define SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS 0
|
||||
#endif
|
||||
|
||||
#define SLJIT_NUMBER_OF_SCRATCH_FLOAT_REGISTERS \
|
||||
(SLJIT_NUMBER_OF_FLOAT_REGISTERS - SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS)
|
||||
|
||||
|
|
|
@ -66,7 +66,7 @@
|
|||
/* --------------------------------------------------------------------- */
|
||||
|
||||
/* 64 KByte. */
|
||||
#define CHUNK_SIZE 0x10000
|
||||
#define CHUNK_SIZE (sljit_uw)0x10000u
|
||||
|
||||
/*
|
||||
alloc_chunk / free_chunk :
|
||||
|
@ -112,7 +112,7 @@ static SLJIT_INLINE void free_chunk(void *chunk, sljit_uw size)
|
|||
|
||||
static SLJIT_INLINE int get_map_jit_flag()
|
||||
{
|
||||
sljit_sw page_size;
|
||||
size_t page_size;
|
||||
void *ptr;
|
||||
struct utsname name;
|
||||
static int map_jit_flag = -1;
|
||||
|
@ -139,8 +139,9 @@ static SLJIT_INLINE int get_map_jit_flag()
|
|||
#endif /* MAP_ANON */
|
||||
#else /* !SLJIT_CONFIG_X86 */
|
||||
#if !(defined SLJIT_CONFIG_ARM && SLJIT_CONFIG_ARM)
|
||||
#error Unsupported architecture
|
||||
#error "Unsupported architecture"
|
||||
#endif /* SLJIT_CONFIG_ARM */
|
||||
#include <AvailabilityMacros.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#define SLJIT_MAP_JIT (MAP_JIT)
|
||||
|
@ -149,7 +150,11 @@ static SLJIT_INLINE int get_map_jit_flag()
|
|||
|
||||
static SLJIT_INLINE void apple_update_wx_flags(sljit_s32 enable_exec)
|
||||
{
|
||||
#if MAC_OS_X_VERSION_MIN_REQUIRED >= 110000
|
||||
pthread_jit_write_protect_np(enable_exec);
|
||||
#else
|
||||
#error "Must target Big Sur or newer"
|
||||
#endif /* BigSur */
|
||||
}
|
||||
#endif /* SLJIT_CONFIG_X86 */
|
||||
#else /* !TARGET_OS_OSX */
|
||||
|
@ -187,10 +192,13 @@ static SLJIT_INLINE void* alloc_chunk(sljit_uw size)
|
|||
if (retval == MAP_FAILED)
|
||||
return NULL;
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
/* HardenedBSD's mmap lies, so check permissions again */
|
||||
if (mprotect(retval, size, PROT_READ | PROT_WRITE | PROT_EXEC) < 0) {
|
||||
munmap(retval, size);
|
||||
return NULL;
|
||||
}
|
||||
#endif /* FreeBSD */
|
||||
|
||||
SLJIT_UPDATE_WX_FLAGS(retval, (uint8_t *)retval + size, 0);
|
||||
|
||||
|
@ -227,7 +235,7 @@ struct free_block {
|
|||
#define AS_FREE_BLOCK(base, offset) \
|
||||
((struct free_block*)(((sljit_u8*)base) + offset))
|
||||
#define MEM_START(base) ((void*)(((sljit_u8*)base) + sizeof(struct block_header)))
|
||||
#define ALIGN_SIZE(size) (((size) + sizeof(struct block_header) + 7) & ~7)
|
||||
#define ALIGN_SIZE(size) (((size) + sizeof(struct block_header) + 7u) & ~(sljit_uw)7)
|
||||
|
||||
static struct free_block* free_blocks;
|
||||
static sljit_uw allocated_size;
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -163,13 +163,6 @@ extern "C" {
|
|||
is not available at all.
|
||||
*/
|
||||
|
||||
/* When SLJIT_UNUSED is specified as the destination of sljit_emit_op1
|
||||
or sljit_emit_op2 operations the result is discarded. Some status
|
||||
flags must be set when the destination is SLJIT_UNUSED, because the
|
||||
operation would have no effect otherwise. Other SLJIT operations do
|
||||
not support SLJIT_UNUSED as a destination operand. */
|
||||
#define SLJIT_UNUSED 0
|
||||
|
||||
/* Scratch registers. */
|
||||
#define SLJIT_R0 1
|
||||
#define SLJIT_R1 2
|
||||
|
@ -231,9 +224,6 @@ extern "C" {
|
|||
value. The FR and FS register sets are overlap in the same way as R
|
||||
and S register sets. See above. */
|
||||
|
||||
/* Note: SLJIT_UNUSED as destination is not valid for floating point
|
||||
operations, since they cannot be used for setting flags. */
|
||||
|
||||
/* Floating point scratch registers. */
|
||||
#define SLJIT_FR0 1
|
||||
#define SLJIT_FR1 2
|
||||
|
@ -263,74 +253,80 @@ extern "C" {
|
|||
/* Argument type definitions */
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
/* Argument type definitions.
|
||||
Used by SLJIT_[DEF_]ARGx and SLJIT_[DEF]_RET macros. */
|
||||
|
||||
#define SLJIT_ARG_TYPE_VOID 0
|
||||
#define SLJIT_ARG_TYPE_SW 1
|
||||
#define SLJIT_ARG_TYPE_UW 2
|
||||
#define SLJIT_ARG_TYPE_S32 3
|
||||
#define SLJIT_ARG_TYPE_U32 4
|
||||
#define SLJIT_ARG_TYPE_F32 5
|
||||
#define SLJIT_ARG_TYPE_F64 6
|
||||
|
||||
/* The following argument type definitions are used by sljit_emit_enter,
|
||||
sljit_set_context, sljit_emit_call, and sljit_emit_icall functions.
|
||||
The following return type definitions are used by sljit_emit_call
|
||||
and sljit_emit_icall functions.
|
||||
|
||||
When a function is called, the first integer argument must be placed
|
||||
in SLJIT_R0, the second in SLJIT_R1, and so on. Similarly the first
|
||||
floating point argument must be placed in SLJIT_FR0, the second in
|
||||
As for sljit_emit_enter, the first integer argument is available in
|
||||
SLJIT_R0, the second one in SLJIT_R1, and so on. Similarly the first
|
||||
floating point argument is available in SLJIT_FR0, the second one in
|
||||
SLJIT_FR1, and so on.
|
||||
|
||||
As for sljit_emit_call and sljit_emit_icall, the first integer argument
|
||||
must be placed into SLJIT_R0, the second one into SLJIT_R1, and so on.
|
||||
Similarly the first floating point argument must be placed into SLJIT_FR0,
|
||||
the second one into SLJIT_FR1, and so on.
|
||||
|
||||
Example function definition:
|
||||
sljit_f32 SLJIT_FUNC example_c_callback(sljit_sw arg_a,
|
||||
sljit_f32 SLJIT_FUNC example_c_callback(void *arg_a,
|
||||
sljit_f64 arg_b, sljit_u32 arg_c, sljit_f32 arg_d);
|
||||
|
||||
Argument type definition:
|
||||
SLJIT_DEF_RET(SLJIT_ARG_TYPE_F32)
|
||||
| SLJIT_DEF_ARG1(SLJIT_ARG_TYPE_SW) | SLJIT_DEF_ARG2(SLJIT_ARG_TYPE_F64)
|
||||
| SLJIT_DEF_ARG3(SLJIT_ARG_TYPE_U32) | SLJIT_DEF_ARG2(SLJIT_ARG_TYPE_F32)
|
||||
SLJIT_ARG_RETURN(SLJIT_ARG_TYPE_F32)
|
||||
| SLJIT_ARG_VALUE(SLJIT_ARG_TYPE_P, 1) | SLJIT_ARG_VALUE(SLJIT_ARG_TYPE_F64, 2)
|
||||
| SLJIT_ARG_VALUE(SLJIT_ARG_TYPE_32, 3) | SLJIT_ARG_VALUE(SLJIT_ARG_TYPE_F32, 4)
|
||||
|
||||
Short form of argument type definition:
|
||||
SLJIT_RET(F32) | SLJIT_ARG1(SW) | SLJIT_ARG2(F64)
|
||||
| SLJIT_ARG3(S32) | SLJIT_ARG4(F32)
|
||||
SLJIT_ARGS4(F32, P, F64, 32, F32)
|
||||
|
||||
Argument passing:
|
||||
arg_a must be placed in SLJIT_R0
|
||||
arg_c must be placed in SLJIT_R1
|
||||
arg_b must be placed in SLJIT_FR0
|
||||
arg_d must be placed in SLJIT_FR1
|
||||
*/
|
||||
|
||||
Note:
|
||||
The SLJIT_ARG_TYPE_VOID type is only supported by
|
||||
SLJIT_DEF_RET, and SLJIT_ARG_TYPE_VOID is also the
|
||||
default value when SLJIT_DEF_RET is not specified. */
|
||||
#define SLJIT_DEF_SHIFT 4
|
||||
#define SLJIT_DEF_RET(type) (type)
|
||||
#define SLJIT_DEF_ARG1(type) ((type) << SLJIT_DEF_SHIFT)
|
||||
#define SLJIT_DEF_ARG2(type) ((type) << (2 * SLJIT_DEF_SHIFT))
|
||||
#define SLJIT_DEF_ARG3(type) ((type) << (3 * SLJIT_DEF_SHIFT))
|
||||
#define SLJIT_DEF_ARG4(type) ((type) << (4 * SLJIT_DEF_SHIFT))
|
||||
/* Void result, can only be used by SLJIT_ARG_RETURN. */
|
||||
#define SLJIT_ARG_TYPE_VOID 0
|
||||
/* Machine word sized integer argument or result. */
|
||||
#define SLJIT_ARG_TYPE_W 1
|
||||
/* 32 bit integer argument or result. */
|
||||
#define SLJIT_ARG_TYPE_32 2
|
||||
/* Pointer sized integer argument or result. */
|
||||
#define SLJIT_ARG_TYPE_P 3
|
||||
/* 64 bit floating point argument or result. */
|
||||
#define SLJIT_ARG_TYPE_F64 4
|
||||
/* 32 bit floating point argument or result. */
|
||||
#define SLJIT_ARG_TYPE_F32 5
|
||||
|
||||
/* Short form of the macros above.
|
||||
#define SLJIT_ARG_SHIFT 4
|
||||
#define SLJIT_ARG_RETURN(type) (type)
|
||||
#define SLJIT_ARG_VALUE(type, idx) ((type) << ((idx) * SLJIT_ARG_SHIFT))
|
||||
|
||||
For example the following definition:
|
||||
SLJIT_DEF_RET(SLJIT_ARG_TYPE_SW) | SLJIT_DEF_ARG1(SLJIT_ARG_TYPE_F32)
|
||||
/* Simplified argument list definitions.
|
||||
|
||||
The following definition:
|
||||
SLJIT_ARG_RETURN(SLJIT_ARG_TYPE_W) | SLJIT_ARG_VALUE(SLJIT_ARG_TYPE_F32, 1)
|
||||
|
||||
can be shortened to:
|
||||
SLJIT_RET(SW) | SLJIT_ARG1(F32)
|
||||
SLJIT_ARGS1(W, F32)
|
||||
*/
|
||||
|
||||
Note:
|
||||
The VOID type is only supported by SLJIT_RET, and
|
||||
VOID is also the default value when SLJIT_RET is
|
||||
not specified. */
|
||||
#define SLJIT_RET(type) SLJIT_DEF_RET(SLJIT_ARG_TYPE_ ## type)
|
||||
#define SLJIT_ARG1(type) SLJIT_DEF_ARG1(SLJIT_ARG_TYPE_ ## type)
|
||||
#define SLJIT_ARG2(type) SLJIT_DEF_ARG2(SLJIT_ARG_TYPE_ ## type)
|
||||
#define SLJIT_ARG3(type) SLJIT_DEF_ARG3(SLJIT_ARG_TYPE_ ## type)
|
||||
#define SLJIT_ARG4(type) SLJIT_DEF_ARG4(SLJIT_ARG_TYPE_ ## type)
|
||||
#define SLJIT_ARG_TO_TYPE(type) SLJIT_ARG_TYPE_ ## type
|
||||
|
||||
#define SLJIT_ARGS0(ret) \
|
||||
SLJIT_ARG_RETURN(SLJIT_ARG_TO_TYPE(ret))
|
||||
|
||||
#define SLJIT_ARGS1(ret, arg1) \
|
||||
(SLJIT_ARGS0(ret) | SLJIT_ARG_VALUE(SLJIT_ARG_TO_TYPE(arg1), 1))
|
||||
|
||||
#define SLJIT_ARGS2(ret, arg1, arg2) \
|
||||
(SLJIT_ARGS1(ret, arg1) | SLJIT_ARG_VALUE(SLJIT_ARG_TO_TYPE(arg2), 2))
|
||||
|
||||
#define SLJIT_ARGS3(ret, arg1, arg2, arg3) \
|
||||
(SLJIT_ARGS2(ret, arg1, arg2) | SLJIT_ARG_VALUE(SLJIT_ARG_TO_TYPE(arg3), 3))
|
||||
|
||||
#define SLJIT_ARGS4(ret, arg1, arg2, arg3, arg4) \
|
||||
(SLJIT_ARGS3(ret, arg1, arg2, arg3) | SLJIT_ARG_VALUE(SLJIT_ARG_TO_TYPE(arg4), 4))
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
/* Main structures and functions */
|
||||
|
@ -408,7 +404,7 @@ struct sljit_compiler {
|
|||
/* Code size. */
|
||||
sljit_uw size;
|
||||
/* Relative offset of the executable mapping from the writable mapping. */
|
||||
sljit_uw executable_offset;
|
||||
sljit_sw executable_offset;
|
||||
/* Executable size for statistical purposes. */
|
||||
sljit_uw executable_size;
|
||||
|
||||
|
@ -417,7 +413,7 @@ struct sljit_compiler {
|
|||
#endif
|
||||
|
||||
#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
|
||||
sljit_s32 args;
|
||||
sljit_s32 args_size;
|
||||
sljit_s32 locals_offset;
|
||||
sljit_s32 saveds_offset;
|
||||
sljit_s32 stack_tmp_size;
|
||||
|
@ -425,9 +421,6 @@ struct sljit_compiler {
|
|||
|
||||
#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
|
||||
sljit_s32 mode32;
|
||||
#ifdef _WIN64
|
||||
sljit_s32 locals_offset;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
|
||||
|
@ -444,10 +437,14 @@ struct sljit_compiler {
|
|||
#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) || (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7)
|
||||
/* Temporary fields. */
|
||||
sljit_uw shift_imm;
|
||||
#endif /* SLJIT_CONFIG_ARM_V5 || SLJIT_CONFIG_ARM_V7 */
|
||||
|
||||
#if (defined SLJIT_CONFIG_ARM_32 && SLJIT_CONFIG_ARM_32) && (defined __SOFTFP__)
|
||||
sljit_uw args_size;
|
||||
#endif
|
||||
|
||||
#if (defined SLJIT_CONFIG_PPC && SLJIT_CONFIG_PPC)
|
||||
sljit_sw imm;
|
||||
sljit_u32 imm;
|
||||
#endif
|
||||
|
||||
#if (defined SLJIT_CONFIG_MIPS && SLJIT_CONFIG_MIPS)
|
||||
|
@ -456,6 +453,10 @@ struct sljit_compiler {
|
|||
sljit_sw cache_argw;
|
||||
#endif
|
||||
|
||||
#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
|
||||
sljit_uw args_size;
|
||||
#endif
|
||||
|
||||
#if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32)
|
||||
sljit_s32 delay_slot;
|
||||
sljit_s32 cache_arg;
|
||||
|
@ -476,7 +477,9 @@ struct sljit_compiler {
|
|||
/* Flags specified by the last arithmetic instruction.
|
||||
It contains the type of the variable flag. */
|
||||
sljit_s32 last_flags;
|
||||
/* Local size passed to the functions. */
|
||||
/* Return value type set by entry functions. */
|
||||
sljit_s32 last_return;
|
||||
/* Local size passed to entry functions. */
|
||||
sljit_s32 logical_local_size;
|
||||
#endif
|
||||
|
||||
|
@ -615,31 +618,36 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type)
|
|||
available options are listed before sljit_emit_enter.
|
||||
|
||||
The function argument list is the combination of SLJIT_ARGx
|
||||
(SLJIT_DEF_ARG1) macros. Currently maximum 3 SW / UW
|
||||
(SLJIT_ARG_TYPE_SW / LJIT_ARG_TYPE_UW) arguments are supported.
|
||||
The first argument goes to SLJIT_S0, the second goes to SLJIT_S1
|
||||
and so on. The register set used by the function must be declared
|
||||
as well. The number of scratch and saved registers used by the
|
||||
function must be passed to sljit_emit_enter. Only R registers
|
||||
between R0 and "scratches" argument can be used later. E.g. if
|
||||
"scratches" is set to 2, the scratch register set will be limited
|
||||
to SLJIT_R0 and SLJIT_R1. The S registers and the floating point
|
||||
registers ("fscratches" and "fsaveds") are specified in a similar
|
||||
manner. The sljit_emit_enter is also capable of allocating a stack
|
||||
space for local variables. The "local_size" argument contains the
|
||||
size in bytes of this local area and its staring address is stored
|
||||
(SLJIT_DEF_ARG1) macros. Currently maximum 4 arguments are
|
||||
supported. The first integer argument is loaded into SLJIT_S0,
|
||||
the second one is loaded into SLJIT_S1, and so on. Similarly,
|
||||
the first floating point argument is loaded into SLJIT_FR0,
|
||||
the second one is loaded into SLJIT_FR1, and so on. Furthermore
|
||||
the register set used by the function must be declared as well.
|
||||
The number of scratch and saved registers used by the function
|
||||
must be passed to sljit_emit_enter. Only R registers between R0
|
||||
and "scratches" argument can be used later. E.g. if "scratches"
|
||||
is set to 2, the scratch register set will be limited to SLJIT_R0
|
||||
and SLJIT_R1. The S registers and the floating point registers
|
||||
("fscratches" and "fsaveds") are specified in a similar manner.
|
||||
The sljit_emit_enter is also capable of allocating a stack space
|
||||
for local variables. The "local_size" argument contains the size
|
||||
in bytes of this local area and its staring address is stored
|
||||
in SLJIT_SP. The memory area between SLJIT_SP (inclusive) and
|
||||
SLJIT_SP + local_size (exclusive) can be modified freely until
|
||||
the function returns. The stack space is not initialized.
|
||||
|
||||
Note: the following conditions must met:
|
||||
0 <= scratches <= SLJIT_NUMBER_OF_REGISTERS
|
||||
0 <= saveds <= SLJIT_NUMBER_OF_REGISTERS
|
||||
0 <= saveds <= SLJIT_NUMBER_OF_SAVED_REGISTERS
|
||||
scratches + saveds <= SLJIT_NUMBER_OF_REGISTERS
|
||||
0 <= fscratches <= SLJIT_NUMBER_OF_FLOAT_REGISTERS
|
||||
0 <= fsaveds <= SLJIT_NUMBER_OF_FLOAT_REGISTERS
|
||||
0 <= fsaveds <= SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS
|
||||
fscratches + fsaveds <= SLJIT_NUMBER_OF_FLOAT_REGISTERS
|
||||
|
||||
Note: the compiler can use saved registers as scratch registers,
|
||||
but the opposite is not supported
|
||||
|
||||
Note: every call of sljit_emit_enter and sljit_set_context
|
||||
overwrites the previous context.
|
||||
*/
|
||||
|
@ -657,7 +665,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compi
|
|||
|
||||
/* The machine code has a context (which contains the local stack space size,
|
||||
number of used registers, etc.) which initialized by sljit_emit_enter. Several
|
||||
functions (like sljit_emit_return) requres this context to be able to generate
|
||||
functions (such as sljit_emit_return) requres this context to be able to generate
|
||||
the appropriate code. However, some code fragments (like inline cache) may have
|
||||
no normal entry point so their context is unknown for the compiler. Their context
|
||||
can be provided to the compiler by the sljit_set_context function.
|
||||
|
@ -669,11 +677,12 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_set_context(struct sljit_compiler *comp
|
|||
sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds,
|
||||
sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size);
|
||||
|
||||
/* Return from machine code. The op argument can be SLJIT_UNUSED which means the
|
||||
function does not return with anything or any opcode between SLJIT_MOV and
|
||||
SLJIT_MOV_P (see sljit_emit_op1). As for src and srcw they must be 0 if op
|
||||
is SLJIT_UNUSED, otherwise see below the description about source and
|
||||
destination arguments. */
|
||||
/* Return from machine code. The sljit_emit_return_void function does not return with
|
||||
any value. The sljit_emit_return function returns with a single value which stores
|
||||
the result of a data move instruction. The instruction is specified by the op
|
||||
argument, and must be between SLJIT_MOV and SLJIT_MOV_P (see sljit_emit_op1). */
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return_void(struct sljit_compiler *compiler);
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return(struct sljit_compiler *compiler, sljit_s32 op,
|
||||
sljit_s32 src, sljit_sw srcw);
|
||||
|
@ -766,7 +775,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_enter(struct sljit_compiler *
|
|||
#define SLJIT_MEM2(r1, r2) (SLJIT_MEM | (r1) | ((r2) << 8))
|
||||
#define SLJIT_IMM 0x40
|
||||
|
||||
/* Set 32 bit operation mode (I) on 64 bit CPUs. This option is ignored on
|
||||
/* Sets 32 bit operation mode on 64 bit CPUs. This option is ignored on
|
||||
32 bit CPUs. When this option is set for an arithmetic operation, only
|
||||
the lower 32 bit of the input registers are used, and the CPU status
|
||||
flags are set according to the 32 bit result. Although the higher 32 bit
|
||||
|
@ -774,12 +783,16 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_enter(struct sljit_compiler *
|
|||
be defined by the CPU architecture (e.g. MIPS). To satisfy these CPU
|
||||
requirements all source registers must be the result of those operations
|
||||
where this option was also set. Memory loads read 32 bit values rather
|
||||
than 64 bit ones. In other words 32 bit and 64 bit operations cannot
|
||||
be mixed. The only exception is SLJIT_MOV32 and SLJIT_MOVU32 whose source
|
||||
register can hold any 32 or 64 bit value, and it is converted to a 32 bit
|
||||
compatible format first. This conversion is free (no instructions are
|
||||
emitted) on most CPUs. A 32 bit value can also be converted to a 64 bit
|
||||
value by SLJIT_MOV_S32 (sign extension) or SLJIT_MOV_U32 (zero extension).
|
||||
than 64 bit ones. In other words 32 bit and 64 bit operations cannot be
|
||||
mixed. The only exception is SLJIT_MOV32 whose source register can hold
|
||||
any 32 or 64 bit value, and it is converted to a 32 bit compatible format
|
||||
first. This conversion is free (no instructions are emitted) on most CPUs.
|
||||
A 32 bit value can also be converted to a 64 bit value by SLJIT_MOV_S32
|
||||
(sign extension) or SLJIT_MOV_U32 (zero extension).
|
||||
|
||||
As for floating-point operations, this option sets 32 bit single
|
||||
precision mode. Similar to the integer operations, all register arguments
|
||||
must be the result of those operations where this option was also set.
|
||||
|
||||
Note: memory addressing always uses 64 bit values on 64 bit systems so
|
||||
the result of a 32 bit operation must not be used with SLJIT_MEMx
|
||||
|
@ -788,22 +801,8 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_enter(struct sljit_compiler *
|
|||
This option is part of the instruction name, so there is no need to
|
||||
manually set it. E.g:
|
||||
|
||||
SLJIT_ADD32 == (SLJIT_ADD | SLJIT_I32_OP) */
|
||||
#define SLJIT_I32_OP 0x100
|
||||
|
||||
/* Set F32 (single) precision mode for floating-point computation. This
|
||||
option is similar to SLJIT_I32_OP, it just applies to floating point
|
||||
registers. When this option is passed, the CPU performs 32 bit floating
|
||||
point operations, rather than 64 bit one. Similar to SLJIT_I32_OP, all
|
||||
register arguments must be the result of those operations where this
|
||||
option was also set.
|
||||
|
||||
This option is part of the instruction name, so there is no need to
|
||||
manually set it. E.g:
|
||||
|
||||
SLJIT_MOV_F32 = (SLJIT_MOV_F64 | SLJIT_F32_OP)
|
||||
*/
|
||||
#define SLJIT_F32_OP SLJIT_I32_OP
|
||||
SLJIT_ADD32 == (SLJIT_ADD | SLJIT_32) */
|
||||
#define SLJIT_32 0x100
|
||||
|
||||
/* Many CPUs (x86, ARM, PPC) have status flags which can be set according
|
||||
to the result of an operation. Other CPUs (MIPS) do not have status
|
||||
|
@ -887,7 +886,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_enter(struct sljit_compiler *
|
|||
The result is placed into SLJIT_R0 and the remainder into SLJIT_R1.
|
||||
Note: if SLJIT_R1 is 0, the behaviour is undefined. */
|
||||
#define SLJIT_DIVMOD_UW (SLJIT_OP0_BASE + 4)
|
||||
#define SLJIT_DIVMOD_U32 (SLJIT_DIVMOD_UW | SLJIT_I32_OP)
|
||||
#define SLJIT_DIVMOD_U32 (SLJIT_DIVMOD_UW | SLJIT_32)
|
||||
/* Flags: - (may destroy flags)
|
||||
Signed divide of the value in SLJIT_R0 by the value in SLJIT_R1.
|
||||
The result is placed into SLJIT_R0 and the remainder into SLJIT_R1.
|
||||
|
@ -895,13 +894,13 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_enter(struct sljit_compiler *
|
|||
Note: if SLJIT_R1 is -1 and SLJIT_R0 is integer min (0x800..00),
|
||||
the behaviour is undefined. */
|
||||
#define SLJIT_DIVMOD_SW (SLJIT_OP0_BASE + 5)
|
||||
#define SLJIT_DIVMOD_S32 (SLJIT_DIVMOD_SW | SLJIT_I32_OP)
|
||||
#define SLJIT_DIVMOD_S32 (SLJIT_DIVMOD_SW | SLJIT_32)
|
||||
/* Flags: - (may destroy flags)
|
||||
Unsigned divide of the value in SLJIT_R0 by the value in SLJIT_R1.
|
||||
The result is placed into SLJIT_R0. SLJIT_R1 preserves its value.
|
||||
Note: if SLJIT_R1 is 0, the behaviour is undefined. */
|
||||
#define SLJIT_DIV_UW (SLJIT_OP0_BASE + 6)
|
||||
#define SLJIT_DIV_U32 (SLJIT_DIV_UW | SLJIT_I32_OP)
|
||||
#define SLJIT_DIV_U32 (SLJIT_DIV_UW | SLJIT_32)
|
||||
/* Flags: - (may destroy flags)
|
||||
Signed divide of the value in SLJIT_R0 by the value in SLJIT_R1.
|
||||
The result is placed into SLJIT_R0. SLJIT_R1 preserves its value.
|
||||
|
@ -909,7 +908,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_enter(struct sljit_compiler *
|
|||
Note: if SLJIT_R1 is -1 and SLJIT_R0 is integer min (0x800..00),
|
||||
the behaviour is undefined. */
|
||||
#define SLJIT_DIV_SW (SLJIT_OP0_BASE + 7)
|
||||
#define SLJIT_DIV_S32 (SLJIT_DIV_SW | SLJIT_I32_OP)
|
||||
#define SLJIT_DIV_S32 (SLJIT_DIV_SW | SLJIT_32)
|
||||
/* Flags: - (does not modify flags)
|
||||
ENDBR32 instruction for x86-32 and ENDBR64 instruction for x86-64
|
||||
when Intel Control-flow Enforcement Technology (CET) is enabled.
|
||||
|
@ -941,16 +940,16 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compile
|
|||
#define SLJIT_MOV (SLJIT_OP1_BASE + 0)
|
||||
/* Flags: - (does not modify flags) */
|
||||
#define SLJIT_MOV_U8 (SLJIT_OP1_BASE + 1)
|
||||
#define SLJIT_MOV32_U8 (SLJIT_MOV_U8 | SLJIT_I32_OP)
|
||||
#define SLJIT_MOV32_U8 (SLJIT_MOV_U8 | SLJIT_32)
|
||||
/* Flags: - (does not modify flags) */
|
||||
#define SLJIT_MOV_S8 (SLJIT_OP1_BASE + 2)
|
||||
#define SLJIT_MOV32_S8 (SLJIT_MOV_S8 | SLJIT_I32_OP)
|
||||
#define SLJIT_MOV32_S8 (SLJIT_MOV_S8 | SLJIT_32)
|
||||
/* Flags: - (does not modify flags) */
|
||||
#define SLJIT_MOV_U16 (SLJIT_OP1_BASE + 3)
|
||||
#define SLJIT_MOV32_U16 (SLJIT_MOV_U16 | SLJIT_I32_OP)
|
||||
#define SLJIT_MOV32_U16 (SLJIT_MOV_U16 | SLJIT_32)
|
||||
/* Flags: - (does not modify flags) */
|
||||
#define SLJIT_MOV_S16 (SLJIT_OP1_BASE + 4)
|
||||
#define SLJIT_MOV32_S16 (SLJIT_MOV_S16 | SLJIT_I32_OP)
|
||||
#define SLJIT_MOV32_S16 (SLJIT_MOV_S16 | SLJIT_32)
|
||||
/* Flags: - (does not modify flags)
|
||||
Note: no SLJIT_MOV32_U32 form, since it is the same as SLJIT_MOV32 */
|
||||
#define SLJIT_MOV_U32 (SLJIT_OP1_BASE + 5)
|
||||
|
@ -958,25 +957,25 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compile
|
|||
Note: no SLJIT_MOV32_S32 form, since it is the same as SLJIT_MOV32 */
|
||||
#define SLJIT_MOV_S32 (SLJIT_OP1_BASE + 6)
|
||||
/* Flags: - (does not modify flags) */
|
||||
#define SLJIT_MOV32 (SLJIT_MOV_S32 | SLJIT_I32_OP)
|
||||
#define SLJIT_MOV32 (SLJIT_OP1_BASE + 7)
|
||||
/* Flags: - (does not modify flags)
|
||||
Note: load a pointer sized data, useful on x32 (a 32 bit mode on x86-64
|
||||
where all x64 features are available, e.g. 16 register) or similar
|
||||
compiling modes */
|
||||
#define SLJIT_MOV_P (SLJIT_OP1_BASE + 7)
|
||||
#define SLJIT_MOV_P (SLJIT_OP1_BASE + 8)
|
||||
/* Flags: Z
|
||||
Note: immediate source argument is not supported */
|
||||
#define SLJIT_NOT (SLJIT_OP1_BASE + 8)
|
||||
#define SLJIT_NOT32 (SLJIT_NOT | SLJIT_I32_OP)
|
||||
#define SLJIT_NOT (SLJIT_OP1_BASE + 9)
|
||||
#define SLJIT_NOT32 (SLJIT_NOT | SLJIT_32)
|
||||
/* Flags: Z | OVERFLOW
|
||||
Note: immediate source argument is not supported */
|
||||
#define SLJIT_NEG (SLJIT_OP1_BASE + 9)
|
||||
#define SLJIT_NEG32 (SLJIT_NEG | SLJIT_I32_OP)
|
||||
#define SLJIT_NEG (SLJIT_OP1_BASE + 10)
|
||||
#define SLJIT_NEG32 (SLJIT_NEG | SLJIT_32)
|
||||
/* Count leading zeroes
|
||||
Flags: - (may destroy flags)
|
||||
Note: immediate source argument is not supported */
|
||||
#define SLJIT_CLZ (SLJIT_OP1_BASE + 10)
|
||||
#define SLJIT_CLZ32 (SLJIT_CLZ | SLJIT_I32_OP)
|
||||
#define SLJIT_CLZ (SLJIT_OP1_BASE + 11)
|
||||
#define SLJIT_CLZ32 (SLJIT_CLZ | SLJIT_32)
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compiler, sljit_s32 op,
|
||||
sljit_s32 dst, sljit_sw dstw,
|
||||
|
@ -987,58 +986,64 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compile
|
|||
|
||||
/* Flags: Z | OVERFLOW | CARRY */
|
||||
#define SLJIT_ADD (SLJIT_OP2_BASE + 0)
|
||||
#define SLJIT_ADD32 (SLJIT_ADD | SLJIT_I32_OP)
|
||||
#define SLJIT_ADD32 (SLJIT_ADD | SLJIT_32)
|
||||
/* Flags: CARRY */
|
||||
#define SLJIT_ADDC (SLJIT_OP2_BASE + 1)
|
||||
#define SLJIT_ADDC32 (SLJIT_ADDC | SLJIT_I32_OP)
|
||||
#define SLJIT_ADDC32 (SLJIT_ADDC | SLJIT_32)
|
||||
/* Flags: Z | LESS | GREATER_EQUAL | GREATER | LESS_EQUAL
|
||||
SIG_LESS | SIG_GREATER_EQUAL | SIG_GREATER
|
||||
SIG_LESS_EQUAL | CARRY */
|
||||
#define SLJIT_SUB (SLJIT_OP2_BASE + 2)
|
||||
#define SLJIT_SUB32 (SLJIT_SUB | SLJIT_I32_OP)
|
||||
#define SLJIT_SUB32 (SLJIT_SUB | SLJIT_32)
|
||||
/* Flags: CARRY */
|
||||
#define SLJIT_SUBC (SLJIT_OP2_BASE + 3)
|
||||
#define SLJIT_SUBC32 (SLJIT_SUBC | SLJIT_I32_OP)
|
||||
#define SLJIT_SUBC32 (SLJIT_SUBC | SLJIT_32)
|
||||
/* Note: integer mul
|
||||
Flags: OVERFLOW */
|
||||
#define SLJIT_MUL (SLJIT_OP2_BASE + 4)
|
||||
#define SLJIT_MUL32 (SLJIT_MUL | SLJIT_I32_OP)
|
||||
#define SLJIT_MUL32 (SLJIT_MUL | SLJIT_32)
|
||||
/* Flags: Z */
|
||||
#define SLJIT_AND (SLJIT_OP2_BASE + 5)
|
||||
#define SLJIT_AND32 (SLJIT_AND | SLJIT_I32_OP)
|
||||
#define SLJIT_AND32 (SLJIT_AND | SLJIT_32)
|
||||
/* Flags: Z */
|
||||
#define SLJIT_OR (SLJIT_OP2_BASE + 6)
|
||||
#define SLJIT_OR32 (SLJIT_OR | SLJIT_I32_OP)
|
||||
#define SLJIT_OR32 (SLJIT_OR | SLJIT_32)
|
||||
/* Flags: Z */
|
||||
#define SLJIT_XOR (SLJIT_OP2_BASE + 7)
|
||||
#define SLJIT_XOR32 (SLJIT_XOR | SLJIT_I32_OP)
|
||||
#define SLJIT_XOR32 (SLJIT_XOR | SLJIT_32)
|
||||
/* Flags: Z
|
||||
Let bit_length be the length of the shift operation: 32 or 64.
|
||||
If src2 is immediate, src2w is masked by (bit_length - 1).
|
||||
Otherwise, if the content of src2 is outside the range from 0
|
||||
to bit_length - 1, the result is undefined. */
|
||||
#define SLJIT_SHL (SLJIT_OP2_BASE + 8)
|
||||
#define SLJIT_SHL32 (SLJIT_SHL | SLJIT_I32_OP)
|
||||
#define SLJIT_SHL32 (SLJIT_SHL | SLJIT_32)
|
||||
/* Flags: Z
|
||||
Let bit_length be the length of the shift operation: 32 or 64.
|
||||
If src2 is immediate, src2w is masked by (bit_length - 1).
|
||||
Otherwise, if the content of src2 is outside the range from 0
|
||||
to bit_length - 1, the result is undefined. */
|
||||
#define SLJIT_LSHR (SLJIT_OP2_BASE + 9)
|
||||
#define SLJIT_LSHR32 (SLJIT_LSHR | SLJIT_I32_OP)
|
||||
#define SLJIT_LSHR32 (SLJIT_LSHR | SLJIT_32)
|
||||
/* Flags: Z
|
||||
Let bit_length be the length of the shift operation: 32 or 64.
|
||||
If src2 is immediate, src2w is masked by (bit_length - 1).
|
||||
Otherwise, if the content of src2 is outside the range from 0
|
||||
to bit_length - 1, the result is undefined. */
|
||||
#define SLJIT_ASHR (SLJIT_OP2_BASE + 10)
|
||||
#define SLJIT_ASHR32 (SLJIT_ASHR | SLJIT_I32_OP)
|
||||
#define SLJIT_ASHR32 (SLJIT_ASHR | SLJIT_32)
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compiler, sljit_s32 op,
|
||||
sljit_s32 dst, sljit_sw dstw,
|
||||
sljit_s32 src1, sljit_sw src1w,
|
||||
sljit_s32 src2, sljit_sw src2w);
|
||||
|
||||
/* The sljit_emit_op2u function is the same as sljit_emit_op2 except the result is discarded. */
|
||||
|
||||
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);
|
||||
|
||||
/* Starting index of opcodes for sljit_emit_op2. */
|
||||
#define SLJIT_OP_SRC_BASE 128
|
||||
|
||||
|
@ -1082,35 +1087,35 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_src(struct sljit_compiler *comp
|
|||
|
||||
/* Flags: - (does not modify flags) */
|
||||
#define SLJIT_MOV_F64 (SLJIT_FOP1_BASE + 0)
|
||||
#define SLJIT_MOV_F32 (SLJIT_MOV_F64 | SLJIT_F32_OP)
|
||||
#define SLJIT_MOV_F32 (SLJIT_MOV_F64 | SLJIT_32)
|
||||
/* Convert opcodes: CONV[DST_TYPE].FROM[SRC_TYPE]
|
||||
SRC/DST TYPE can be: D - double, S - single, W - signed word, I - signed int
|
||||
Rounding mode when the destination is W or I: round towards zero. */
|
||||
/* Flags: - (does not modify flags) */
|
||||
/* Flags: - (may destroy flags) */
|
||||
#define SLJIT_CONV_F64_FROM_F32 (SLJIT_FOP1_BASE + 1)
|
||||
#define SLJIT_CONV_F32_FROM_F64 (SLJIT_CONV_F64_FROM_F32 | SLJIT_F32_OP)
|
||||
/* Flags: - (does not modify flags) */
|
||||
#define SLJIT_CONV_F32_FROM_F64 (SLJIT_CONV_F64_FROM_F32 | SLJIT_32)
|
||||
/* Flags: - (may destroy flags) */
|
||||
#define SLJIT_CONV_SW_FROM_F64 (SLJIT_FOP1_BASE + 2)
|
||||
#define SLJIT_CONV_SW_FROM_F32 (SLJIT_CONV_SW_FROM_F64 | SLJIT_F32_OP)
|
||||
/* Flags: - (does not modify flags) */
|
||||
#define SLJIT_CONV_SW_FROM_F32 (SLJIT_CONV_SW_FROM_F64 | SLJIT_32)
|
||||
/* Flags: - (may destroy flags) */
|
||||
#define SLJIT_CONV_S32_FROM_F64 (SLJIT_FOP1_BASE + 3)
|
||||
#define SLJIT_CONV_S32_FROM_F32 (SLJIT_CONV_S32_FROM_F64 | SLJIT_F32_OP)
|
||||
/* Flags: - (does not modify flags) */
|
||||
#define SLJIT_CONV_S32_FROM_F32 (SLJIT_CONV_S32_FROM_F64 | SLJIT_32)
|
||||
/* Flags: - (may destroy flags) */
|
||||
#define SLJIT_CONV_F64_FROM_SW (SLJIT_FOP1_BASE + 4)
|
||||
#define SLJIT_CONV_F32_FROM_SW (SLJIT_CONV_F64_FROM_SW | SLJIT_F32_OP)
|
||||
/* Flags: - (does not modify flags) */
|
||||
#define SLJIT_CONV_F32_FROM_SW (SLJIT_CONV_F64_FROM_SW | SLJIT_32)
|
||||
/* Flags: - (may destroy flags) */
|
||||
#define SLJIT_CONV_F64_FROM_S32 (SLJIT_FOP1_BASE + 5)
|
||||
#define SLJIT_CONV_F32_FROM_S32 (SLJIT_CONV_F64_FROM_S32 | SLJIT_F32_OP)
|
||||
#define SLJIT_CONV_F32_FROM_S32 (SLJIT_CONV_F64_FROM_S32 | SLJIT_32)
|
||||
/* Note: dst is the left and src is the right operand for SLJIT_CMPD.
|
||||
Flags: EQUAL_F | LESS_F | GREATER_EQUAL_F | GREATER_F | LESS_EQUAL_F */
|
||||
#define SLJIT_CMP_F64 (SLJIT_FOP1_BASE + 6)
|
||||
#define SLJIT_CMP_F32 (SLJIT_CMP_F64 | SLJIT_F32_OP)
|
||||
/* Flags: - (does not modify flags) */
|
||||
#define SLJIT_CMP_F32 (SLJIT_CMP_F64 | SLJIT_32)
|
||||
/* Flags: - (may destroy flags) */
|
||||
#define SLJIT_NEG_F64 (SLJIT_FOP1_BASE + 7)
|
||||
#define SLJIT_NEG_F32 (SLJIT_NEG_F64 | SLJIT_F32_OP)
|
||||
/* Flags: - (does not modify flags) */
|
||||
#define SLJIT_NEG_F32 (SLJIT_NEG_F64 | SLJIT_32)
|
||||
/* Flags: - (may destroy flags) */
|
||||
#define SLJIT_ABS_F64 (SLJIT_FOP1_BASE + 8)
|
||||
#define SLJIT_ABS_F32 (SLJIT_ABS_F64 | SLJIT_F32_OP)
|
||||
#define SLJIT_ABS_F32 (SLJIT_ABS_F64 | SLJIT_32)
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop1(struct sljit_compiler *compiler, sljit_s32 op,
|
||||
sljit_s32 dst, sljit_sw dstw,
|
||||
|
@ -1119,18 +1124,18 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop1(struct sljit_compiler *compil
|
|||
/* Starting index of opcodes for sljit_emit_fop2. */
|
||||
#define SLJIT_FOP2_BASE 192
|
||||
|
||||
/* Flags: - (does not modify flags) */
|
||||
/* Flags: - (may destroy flags) */
|
||||
#define SLJIT_ADD_F64 (SLJIT_FOP2_BASE + 0)
|
||||
#define SLJIT_ADD_F32 (SLJIT_ADD_F64 | SLJIT_F32_OP)
|
||||
/* Flags: - (does not modify flags) */
|
||||
#define SLJIT_ADD_F32 (SLJIT_ADD_F64 | SLJIT_32)
|
||||
/* Flags: - (may destroy flags) */
|
||||
#define SLJIT_SUB_F64 (SLJIT_FOP2_BASE + 1)
|
||||
#define SLJIT_SUB_F32 (SLJIT_SUB_F64 | SLJIT_F32_OP)
|
||||
/* Flags: - (does not modify flags) */
|
||||
#define SLJIT_SUB_F32 (SLJIT_SUB_F64 | SLJIT_32)
|
||||
/* Flags: - (may destroy flags) */
|
||||
#define SLJIT_MUL_F64 (SLJIT_FOP2_BASE + 2)
|
||||
#define SLJIT_MUL_F32 (SLJIT_MUL_F64 | SLJIT_F32_OP)
|
||||
/* Flags: - (does not modify flags) */
|
||||
#define SLJIT_MUL_F32 (SLJIT_MUL_F64 | SLJIT_32)
|
||||
/* Flags: - (may destroy flags) */
|
||||
#define SLJIT_DIV_F64 (SLJIT_FOP2_BASE + 3)
|
||||
#define SLJIT_DIV_F32 (SLJIT_DIV_F64 | SLJIT_F32_OP)
|
||||
#define SLJIT_DIV_F32 (SLJIT_DIV_F64 | SLJIT_32)
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop2(struct sljit_compiler *compiler, sljit_s32 op,
|
||||
sljit_s32 dst, sljit_sw dstw,
|
||||
|
@ -1175,28 +1180,28 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compi
|
|||
|
||||
/* Floating point comparison types. */
|
||||
#define SLJIT_EQUAL_F64 14
|
||||
#define SLJIT_EQUAL_F32 (SLJIT_EQUAL_F64 | SLJIT_F32_OP)
|
||||
#define SLJIT_EQUAL_F32 (SLJIT_EQUAL_F64 | SLJIT_32)
|
||||
#define SLJIT_SET_EQUAL_F SLJIT_SET(SLJIT_EQUAL_F64)
|
||||
#define SLJIT_NOT_EQUAL_F64 15
|
||||
#define SLJIT_NOT_EQUAL_F32 (SLJIT_NOT_EQUAL_F64 | SLJIT_F32_OP)
|
||||
#define SLJIT_NOT_EQUAL_F32 (SLJIT_NOT_EQUAL_F64 | SLJIT_32)
|
||||
#define SLJIT_SET_NOT_EQUAL_F SLJIT_SET(SLJIT_NOT_EQUAL_F64)
|
||||
#define SLJIT_LESS_F64 16
|
||||
#define SLJIT_LESS_F32 (SLJIT_LESS_F64 | SLJIT_F32_OP)
|
||||
#define SLJIT_LESS_F32 (SLJIT_LESS_F64 | SLJIT_32)
|
||||
#define SLJIT_SET_LESS_F SLJIT_SET(SLJIT_LESS_F64)
|
||||
#define SLJIT_GREATER_EQUAL_F64 17
|
||||
#define SLJIT_GREATER_EQUAL_F32 (SLJIT_GREATER_EQUAL_F64 | SLJIT_F32_OP)
|
||||
#define SLJIT_GREATER_EQUAL_F32 (SLJIT_GREATER_EQUAL_F64 | SLJIT_32)
|
||||
#define SLJIT_SET_GREATER_EQUAL_F SLJIT_SET(SLJIT_GREATER_EQUAL_F64)
|
||||
#define SLJIT_GREATER_F64 18
|
||||
#define SLJIT_GREATER_F32 (SLJIT_GREATER_F64 | SLJIT_F32_OP)
|
||||
#define SLJIT_GREATER_F32 (SLJIT_GREATER_F64 | SLJIT_32)
|
||||
#define SLJIT_SET_GREATER_F SLJIT_SET(SLJIT_GREATER_F64)
|
||||
#define SLJIT_LESS_EQUAL_F64 19
|
||||
#define SLJIT_LESS_EQUAL_F32 (SLJIT_LESS_EQUAL_F64 | SLJIT_F32_OP)
|
||||
#define SLJIT_LESS_EQUAL_F32 (SLJIT_LESS_EQUAL_F64 | SLJIT_32)
|
||||
#define SLJIT_SET_LESS_EQUAL_F SLJIT_SET(SLJIT_LESS_EQUAL_F64)
|
||||
#define SLJIT_UNORDERED_F64 20
|
||||
#define SLJIT_UNORDERED_F32 (SLJIT_UNORDERED_F64 | SLJIT_F32_OP)
|
||||
#define SLJIT_UNORDERED_F32 (SLJIT_UNORDERED_F64 | SLJIT_32)
|
||||
#define SLJIT_SET_UNORDERED_F SLJIT_SET(SLJIT_UNORDERED_F64)
|
||||
#define SLJIT_ORDERED_F64 21
|
||||
#define SLJIT_ORDERED_F32 (SLJIT_ORDERED_F64 | SLJIT_F32_OP)
|
||||
#define SLJIT_ORDERED_F32 (SLJIT_ORDERED_F64 | SLJIT_32)
|
||||
#define SLJIT_SET_ORDERED_F SLJIT_SET(SLJIT_ORDERED_F64)
|
||||
|
||||
/* Unconditional jump types. */
|
||||
|
@ -1211,6 +1216,15 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compi
|
|||
|
||||
/* The target can be changed during runtime (see: sljit_set_jump_addr). */
|
||||
#define SLJIT_REWRITABLE_JUMP 0x1000
|
||||
/* When this flag is passed, the execution of the current function ends and
|
||||
the called function returns to the caller of the current function. The
|
||||
stack usage is reduced before the call, but it is not necessarily reduced
|
||||
to zero. In the latter case the compiler needs to allocate space for some
|
||||
arguments and the return register must be kept as well.
|
||||
|
||||
This feature is highly experimental and not supported on SPARC platform
|
||||
at the moment. */
|
||||
#define SLJIT_CALL_RETURN 0x2000
|
||||
|
||||
/* Emit a jump instruction. The destination is not set, only the type of the jump.
|
||||
type must be between SLJIT_EQUAL and SLJIT_FAST_CALL
|
||||
|
@ -1221,15 +1235,14 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compile
|
|||
|
||||
/* Emit a C compiler (ABI) compatible function call.
|
||||
type must be SLJIT_CALL or SLJIT_CALL_CDECL
|
||||
type can be combined (or'ed) with SLJIT_REWRITABLE_JUMP
|
||||
type can be combined (or'ed) with SLJIT_REWRITABLE_JUMP and SLJIT_CALL_RETURN
|
||||
arg_types is the combination of SLJIT_RET / SLJIT_ARGx (SLJIT_DEF_RET / SLJIT_DEF_ARGx) macros
|
||||
|
||||
Flags: destroy all flags. */
|
||||
SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_call(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 arg_types);
|
||||
|
||||
/* Basic arithmetic comparison. In most architectures it is implemented as
|
||||
an SLJIT_SUB operation (with SLJIT_UNUSED destination and setting
|
||||
appropriate flags) followed by a sljit_emit_jump. However some
|
||||
an compare operation followed by a sljit_emit_jump. However some
|
||||
architectures (i.e: ARM64 or MIPS) may employ special optimizations here.
|
||||
It is suggested to use this comparison form when appropriate.
|
||||
type must be between SLJIT_EQUAL and SLJIT_I_SIG_LESS_EQUAL
|
||||
|
@ -1271,6 +1284,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_ijump(struct sljit_compiler *compi
|
|||
Direct form: set src to SLJIT_IMM() and srcw to the address
|
||||
Indirect form: any other valid addressing mode
|
||||
type must be SLJIT_CALL or SLJIT_CALL_CDECL
|
||||
type can be combined (or'ed) with SLJIT_CALL_RETURN
|
||||
arg_types is the combination of SLJIT_RET / SLJIT_ARGx (SLJIT_DEF_RET / SLJIT_DEF_ARGx) macros
|
||||
|
||||
Flags: destroy all flags. */
|
||||
|
@ -1298,7 +1312,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_flags(struct sljit_compiler *co
|
|||
|
||||
type must be between SLJIT_EQUAL and SLJIT_ORDERED_F64
|
||||
dst_reg must be a valid register and it can be combined
|
||||
with SLJIT_I32_OP to perform a 32 bit arithmetic operation
|
||||
with SLJIT_32 to perform a 32 bit arithmetic operation
|
||||
src must be register or immediate (SLJIT_IMM)
|
||||
|
||||
Flags: - (does not modify flags) */
|
||||
|
@ -1454,26 +1468,29 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_u8 *SLJIT_FUNC sljit_stack_resize(struct sljit_st
|
|||
|
||||
#if !(defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL)
|
||||
|
||||
/* Get the entry address of a given function. */
|
||||
#define SLJIT_FUNC_OFFSET(func_name) ((sljit_sw)func_name)
|
||||
/* Get the entry address of a given function (signed, unsigned result). */
|
||||
#define SLJIT_FUNC_ADDR(func_name) ((sljit_sw)func_name)
|
||||
#define SLJIT_FUNC_UADDR(func_name) ((sljit_uw)func_name)
|
||||
|
||||
#else /* !(defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL) */
|
||||
|
||||
/* All JIT related code should be placed in the same context (library, binary, etc.). */
|
||||
|
||||
#define SLJIT_FUNC_OFFSET(func_name) (*(sljit_sw*)(void*)func_name)
|
||||
/* Get the entry address of a given function (signed, unsigned result). */
|
||||
#define SLJIT_FUNC_ADDR(func_name) (*(sljit_sw*)(void*)func_name)
|
||||
#define SLJIT_FUNC_UADDR(func_name) (*(sljit_uw*)(void*)func_name)
|
||||
|
||||
/* For powerpc64, the function pointers point to a context descriptor. */
|
||||
struct sljit_function_context {
|
||||
sljit_sw addr;
|
||||
sljit_sw r2;
|
||||
sljit_sw r11;
|
||||
sljit_uw addr;
|
||||
sljit_uw r2;
|
||||
sljit_uw r11;
|
||||
};
|
||||
|
||||
/* Fill the context arguments using the addr and the function.
|
||||
If func_ptr is NULL, it will not be set to the address of context
|
||||
If addr is NULL, the function address also comes from the func pointer. */
|
||||
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_function_context(void** func_ptr, struct sljit_function_context* context, sljit_sw addr, void* func);
|
||||
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_function_context(void** func_ptr, struct sljit_function_context* context, sljit_uw addr, void* func);
|
||||
|
||||
#endif /* !(defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL) */
|
||||
|
||||
|
@ -1516,15 +1533,15 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_float_register_index(sljit_s32 reg)
|
|||
Otherwise: size must be 4 and instruction argument must be 4 byte aligned. */
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_custom(struct sljit_compiler *compiler,
|
||||
void *instruction, sljit_s32 size);
|
||||
void *instruction, sljit_u32 size);
|
||||
|
||||
/* Flags were set by a 32 bit operation. */
|
||||
#define SLJIT_CURRENT_FLAGS_I32_OP SLJIT_I32_OP
|
||||
#define SLJIT_CURRENT_FLAGS_32 SLJIT_32
|
||||
|
||||
/* Flags were set by an ADD, ADDC, SUB, SUBC, or NEG operation. */
|
||||
#define SLJIT_CURRENT_FLAGS_ADD_SUB 0x01
|
||||
|
||||
/* Flags were set by a SUB with unused destination.
|
||||
/* Flags were set by sljit_emit_op2u with SLJIT_SUB opcode.
|
||||
Must be combined with SLJIT_CURRENT_FLAGS_ADD_SUB. */
|
||||
#define SLJIT_CURRENT_FLAGS_COMPARE 0x02
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -73,50 +73,49 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl
|
|||
|
||||
switch (GET_OPCODE(op)) {
|
||||
case SLJIT_MOV:
|
||||
case SLJIT_MOV_U32:
|
||||
case SLJIT_MOV_S32:
|
||||
case SLJIT_MOV_P:
|
||||
SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
|
||||
if (dst != src2)
|
||||
return push_inst(compiler, ADDU | S(src2) | TA(0) | D(dst), DR(dst));
|
||||
return SLJIT_SUCCESS;
|
||||
|
||||
case SLJIT_MOV_U8:
|
||||
SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
|
||||
if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE))
|
||||
return push_inst(compiler, ANDI | S(src2) | T(dst) | IMM(0xff), DR(dst));
|
||||
SLJIT_ASSERT(dst == src2);
|
||||
return SLJIT_SUCCESS;
|
||||
|
||||
case SLJIT_MOV_S8:
|
||||
SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
|
||||
if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) {
|
||||
if (op == SLJIT_MOV_S8) {
|
||||
#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1)
|
||||
return push_inst(compiler, SEB | T(src2) | D(dst), DR(dst));
|
||||
return push_inst(compiler, SEB | T(src2) | D(dst), DR(dst));
|
||||
#else /* SLJIT_MIPS_REV < 1 */
|
||||
FAIL_IF(push_inst(compiler, SLL | T(src2) | D(dst) | SH_IMM(24), DR(dst)));
|
||||
return push_inst(compiler, SRA | T(dst) | D(dst) | SH_IMM(24), DR(dst));
|
||||
FAIL_IF(push_inst(compiler, SLL | T(src2) | D(dst) | SH_IMM(24), DR(dst)));
|
||||
return push_inst(compiler, SRA | T(dst) | D(dst) | SH_IMM(24), DR(dst));
|
||||
#endif /* SLJIT_MIPS_REV >= 1 */
|
||||
}
|
||||
return push_inst(compiler, ANDI | S(src2) | T(dst) | IMM(0xff), DR(dst));
|
||||
}
|
||||
else {
|
||||
SLJIT_ASSERT(dst == src2);
|
||||
}
|
||||
SLJIT_ASSERT(dst == src2);
|
||||
return SLJIT_SUCCESS;
|
||||
|
||||
case SLJIT_MOV_U16:
|
||||
SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
|
||||
if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE))
|
||||
return push_inst(compiler, ANDI | S(src2) | T(dst) | IMM(0xffff), DR(dst));
|
||||
SLJIT_ASSERT(dst == src2);
|
||||
return SLJIT_SUCCESS;
|
||||
|
||||
case SLJIT_MOV_S16:
|
||||
SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
|
||||
if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) {
|
||||
if (op == SLJIT_MOV_S16) {
|
||||
#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1)
|
||||
return push_inst(compiler, SEH | T(src2) | D(dst), DR(dst));
|
||||
return push_inst(compiler, SEH | T(src2) | D(dst), DR(dst));
|
||||
#else /* SLJIT_MIPS_REV < 1 */
|
||||
FAIL_IF(push_inst(compiler, SLL | T(src2) | D(dst) | SH_IMM(16), DR(dst)));
|
||||
return push_inst(compiler, SRA | T(dst) | D(dst) | SH_IMM(16), DR(dst));
|
||||
FAIL_IF(push_inst(compiler, SLL | T(src2) | D(dst) | SH_IMM(16), DR(dst)));
|
||||
return push_inst(compiler, SRA | T(dst) | D(dst) | SH_IMM(16), DR(dst));
|
||||
#endif /* SLJIT_MIPS_REV >= 1 */
|
||||
}
|
||||
return push_inst(compiler, ANDI | S(src2) | T(dst) | IMM(0xffff), DR(dst));
|
||||
}
|
||||
else {
|
||||
SLJIT_ASSERT(dst == src2);
|
||||
}
|
||||
SLJIT_ASSERT(dst == src2);
|
||||
return SLJIT_SUCCESS;
|
||||
|
||||
case SLJIT_NOT:
|
||||
|
@ -438,92 +437,119 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_ta
|
|||
|
||||
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant, sljit_sw executable_offset)
|
||||
{
|
||||
sljit_set_jump_addr(addr, new_constant, executable_offset);
|
||||
sljit_set_jump_addr(addr, (sljit_uw)new_constant, executable_offset);
|
||||
}
|
||||
|
||||
static sljit_s32 call_with_args(struct sljit_compiler *compiler, sljit_s32 arg_types, sljit_ins *ins_ptr)
|
||||
static sljit_s32 call_with_args(struct sljit_compiler *compiler, sljit_s32 arg_types, sljit_ins *ins_ptr, sljit_u32 *extra_space)
|
||||
{
|
||||
sljit_s32 stack_offset = 0;
|
||||
sljit_s32 arg_count = 0;
|
||||
sljit_u32 is_tail_call = *extra_space & SLJIT_CALL_RETURN;
|
||||
sljit_u32 offset = 0;
|
||||
sljit_s32 float_arg_count = 0;
|
||||
sljit_s32 word_arg_count = 0;
|
||||
sljit_s32 types = 0;
|
||||
sljit_s32 arg_count_save, types_save;
|
||||
sljit_ins prev_ins = NOP;
|
||||
sljit_ins ins = NOP;
|
||||
sljit_u8 offsets[4];
|
||||
sljit_u8 *offsets_ptr = offsets;
|
||||
|
||||
SLJIT_ASSERT(reg_map[TMP_REG1] == 4 && freg_map[TMP_FREG1] == 12);
|
||||
|
||||
arg_types >>= SLJIT_DEF_SHIFT;
|
||||
arg_types >>= SLJIT_ARG_SHIFT;
|
||||
|
||||
/* See ABI description in sljit_emit_enter. */
|
||||
|
||||
while (arg_types) {
|
||||
types = (types << SLJIT_DEF_SHIFT) | (arg_types & SLJIT_DEF_MASK);
|
||||
types = (types << SLJIT_ARG_SHIFT) | (arg_types & SLJIT_ARG_MASK);
|
||||
*offsets_ptr = (sljit_u8)offset;
|
||||
|
||||
switch (arg_types & SLJIT_DEF_MASK) {
|
||||
case SLJIT_ARG_TYPE_F32:
|
||||
offsets[arg_count] = (sljit_u8)stack_offset;
|
||||
switch (arg_types & SLJIT_ARG_MASK) {
|
||||
case SLJIT_ARG_TYPE_F64:
|
||||
if (offset & 0x7) {
|
||||
offset += sizeof(sljit_sw);
|
||||
*offsets_ptr = (sljit_u8)offset;
|
||||
}
|
||||
|
||||
if (word_arg_count == 0 && arg_count <= 1)
|
||||
offsets[arg_count] = 254 + arg_count;
|
||||
if (word_arg_count == 0 && float_arg_count <= 1)
|
||||
*offsets_ptr = (sljit_u8)(254 + float_arg_count);
|
||||
|
||||
stack_offset += sizeof(sljit_f32);
|
||||
arg_count++;
|
||||
offset += sizeof(sljit_f64);
|
||||
float_arg_count++;
|
||||
break;
|
||||
case SLJIT_ARG_TYPE_F64:
|
||||
if (stack_offset & 0x7)
|
||||
stack_offset += sizeof(sljit_sw);
|
||||
offsets[arg_count] = (sljit_u8)stack_offset;
|
||||
case SLJIT_ARG_TYPE_F32:
|
||||
if (word_arg_count == 0 && float_arg_count <= 1)
|
||||
*offsets_ptr = (sljit_u8)(254 + float_arg_count);
|
||||
|
||||
if (word_arg_count == 0 && arg_count <= 1)
|
||||
offsets[arg_count] = 254 + arg_count;
|
||||
|
||||
stack_offset += sizeof(sljit_f64);
|
||||
arg_count++;
|
||||
offset += sizeof(sljit_f32);
|
||||
float_arg_count++;
|
||||
break;
|
||||
default:
|
||||
offsets[arg_count] = (sljit_u8)stack_offset;
|
||||
stack_offset += sizeof(sljit_sw);
|
||||
arg_count++;
|
||||
offset += sizeof(sljit_sw);
|
||||
word_arg_count++;
|
||||
break;
|
||||
}
|
||||
|
||||
arg_types >>= SLJIT_DEF_SHIFT;
|
||||
arg_types >>= SLJIT_ARG_SHIFT;
|
||||
offsets_ptr++;
|
||||
}
|
||||
|
||||
/* Stack is aligned to 16 bytes, max two doubles can be placed on the stack. */
|
||||
if (stack_offset > 16)
|
||||
FAIL_IF(push_inst(compiler, ADDIU | S(SLJIT_SP) | T(SLJIT_SP) | IMM(-16), DR(SLJIT_SP)));
|
||||
/* Stack is aligned to 16 bytes. */
|
||||
SLJIT_ASSERT(offset <= 8 * sizeof(sljit_sw));
|
||||
|
||||
types_save = types;
|
||||
arg_count_save = arg_count;
|
||||
if (offset > 4 * sizeof(sljit_sw) && (!is_tail_call || offset > compiler->args_size)) {
|
||||
if (is_tail_call) {
|
||||
offset = (offset + sizeof(sljit_sw) + 15) & ~(sljit_uw)0xf;
|
||||
FAIL_IF(emit_stack_frame_release(compiler, (sljit_s32)offset, &prev_ins));
|
||||
*extra_space = offset;
|
||||
} else {
|
||||
FAIL_IF(push_inst(compiler, ADDIU | S(SLJIT_SP) | T(SLJIT_SP) | IMM(-16), DR(SLJIT_SP)));
|
||||
*extra_space = 16;
|
||||
}
|
||||
} else {
|
||||
if (is_tail_call)
|
||||
FAIL_IF(emit_stack_frame_release(compiler, 0, &prev_ins));
|
||||
*extra_space = 0;
|
||||
}
|
||||
|
||||
while (types) {
|
||||
switch (types & SLJIT_DEF_MASK) {
|
||||
case SLJIT_ARG_TYPE_F32:
|
||||
arg_count--;
|
||||
if (offsets[arg_count] < 254)
|
||||
ins = SWC1 | S(SLJIT_SP) | FT(float_arg_count) | IMM(offsets[arg_count]);
|
||||
--offsets_ptr;
|
||||
|
||||
switch (types & SLJIT_ARG_MASK) {
|
||||
case SLJIT_ARG_TYPE_F64:
|
||||
if (*offsets_ptr < 4 * sizeof (sljit_sw)) {
|
||||
if (prev_ins != NOP)
|
||||
FAIL_IF(push_inst(compiler, prev_ins, MOVABLE_INS));
|
||||
|
||||
/* Must be preceded by at least one other argument,
|
||||
* and its starting offset must be 8 because of alignment. */
|
||||
SLJIT_ASSERT((*offsets_ptr >> 2) == 2);
|
||||
|
||||
prev_ins = MFC1 | TA(6) | FS(float_arg_count) | (1 << 11);
|
||||
ins = MFC1 | TA(7) | FS(float_arg_count);
|
||||
} else if (*offsets_ptr < 254)
|
||||
ins = SDC1 | S(SLJIT_SP) | FT(float_arg_count) | IMM(*offsets_ptr);
|
||||
else if (*offsets_ptr == 254)
|
||||
ins = MOV_S | FMT_D | FS(SLJIT_FR0) | FD(TMP_FREG1);
|
||||
|
||||
float_arg_count--;
|
||||
break;
|
||||
case SLJIT_ARG_TYPE_F64:
|
||||
arg_count--;
|
||||
if (offsets[arg_count] < 254)
|
||||
ins = SDC1 | S(SLJIT_SP) | FT(float_arg_count) | IMM(offsets[arg_count]);
|
||||
case SLJIT_ARG_TYPE_F32:
|
||||
if (*offsets_ptr < 4 * sizeof (sljit_sw))
|
||||
ins = MFC1 | TA(4 + (*offsets_ptr >> 2)) | FS(float_arg_count);
|
||||
else if (*offsets_ptr < 254)
|
||||
ins = SWC1 | S(SLJIT_SP) | FT(float_arg_count) | IMM(*offsets_ptr);
|
||||
else if (*offsets_ptr == 254)
|
||||
ins = MOV_S | FMT_S | FS(SLJIT_FR0) | FD(TMP_FREG1);
|
||||
|
||||
float_arg_count--;
|
||||
break;
|
||||
default:
|
||||
if (offsets[arg_count - 1] >= 16)
|
||||
ins = SW | S(SLJIT_SP) | T(word_arg_count) | IMM(offsets[arg_count - 1]);
|
||||
else if (arg_count != word_arg_count)
|
||||
ins = ADDU | S(word_arg_count) | TA(0) | DA(4 + (offsets[arg_count - 1] >> 2));
|
||||
else if (arg_count == 1)
|
||||
if (*offsets_ptr >= 4 * sizeof (sljit_sw))
|
||||
ins = SW | S(SLJIT_SP) | T(word_arg_count) | IMM(*offsets_ptr);
|
||||
else if ((*offsets_ptr >> 2) != word_arg_count - 1)
|
||||
ins = ADDU | S(word_arg_count) | TA(0) | DA(4 + (*offsets_ptr >> 2));
|
||||
else if (*offsets_ptr == 0)
|
||||
ins = ADDU | S(SLJIT_R0) | TA(0) | DA(4);
|
||||
|
||||
arg_count--;
|
||||
word_arg_count--;
|
||||
break;
|
||||
}
|
||||
|
@ -535,45 +561,7 @@ static sljit_s32 call_with_args(struct sljit_compiler *compiler, sljit_s32 arg_t
|
|||
ins = NOP;
|
||||
}
|
||||
|
||||
types >>= SLJIT_DEF_SHIFT;
|
||||
}
|
||||
|
||||
types = types_save;
|
||||
arg_count = arg_count_save;
|
||||
|
||||
while (types) {
|
||||
switch (types & SLJIT_DEF_MASK) {
|
||||
case SLJIT_ARG_TYPE_F32:
|
||||
arg_count--;
|
||||
if (offsets[arg_count] == 254)
|
||||
ins = MOV_S | FMT_S | FS(SLJIT_FR0) | FD(TMP_FREG1);
|
||||
else if (offsets[arg_count] < 16)
|
||||
ins = LW | S(SLJIT_SP) | TA(4 + (offsets[arg_count] >> 2)) | IMM(offsets[arg_count]);
|
||||
break;
|
||||
case SLJIT_ARG_TYPE_F64:
|
||||
arg_count--;
|
||||
if (offsets[arg_count] == 254)
|
||||
ins = MOV_S | FMT_D | FS(SLJIT_FR0) | FD(TMP_FREG1);
|
||||
else if (offsets[arg_count] < 16) {
|
||||
if (prev_ins != NOP)
|
||||
FAIL_IF(push_inst(compiler, prev_ins, MOVABLE_INS));
|
||||
prev_ins = LW | S(SLJIT_SP) | TA(4 + (offsets[arg_count] >> 2)) | IMM(offsets[arg_count]);
|
||||
ins = LW | S(SLJIT_SP) | TA(5 + (offsets[arg_count] >> 2)) | IMM(offsets[arg_count] + sizeof(sljit_sw));
|
||||
}
|
||||
break;
|
||||
default:
|
||||
arg_count--;
|
||||
break;
|
||||
}
|
||||
|
||||
if (ins != NOP) {
|
||||
if (prev_ins != NOP)
|
||||
FAIL_IF(push_inst(compiler, prev_ins, MOVABLE_INS));
|
||||
prev_ins = ins;
|
||||
ins = NOP;
|
||||
}
|
||||
|
||||
types >>= SLJIT_DEF_SHIFT;
|
||||
types >>= SLJIT_ARG_SHIFT;
|
||||
}
|
||||
|
||||
*ins_ptr = prev_ins;
|
||||
|
@ -581,41 +569,11 @@ static sljit_s32 call_with_args(struct sljit_compiler *compiler, sljit_s32 arg_t
|
|||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
static sljit_s32 post_call_with_args(struct sljit_compiler *compiler, sljit_s32 arg_types)
|
||||
{
|
||||
sljit_s32 stack_offset = 0;
|
||||
|
||||
arg_types >>= SLJIT_DEF_SHIFT;
|
||||
|
||||
while (arg_types) {
|
||||
switch (arg_types & SLJIT_DEF_MASK) {
|
||||
case SLJIT_ARG_TYPE_F32:
|
||||
stack_offset += sizeof(sljit_f32);
|
||||
break;
|
||||
case SLJIT_ARG_TYPE_F64:
|
||||
if (stack_offset & 0x7)
|
||||
stack_offset += sizeof(sljit_sw);
|
||||
stack_offset += sizeof(sljit_f64);
|
||||
break;
|
||||
default:
|
||||
stack_offset += sizeof(sljit_sw);
|
||||
break;
|
||||
}
|
||||
|
||||
arg_types >>= SLJIT_DEF_SHIFT;
|
||||
}
|
||||
|
||||
/* Stack is aligned to 16 bytes, max two doubles can be placed on the stack. */
|
||||
if (stack_offset > 16)
|
||||
return push_inst(compiler, ADDIU | S(SLJIT_SP) | T(SLJIT_SP) | IMM(16), DR(SLJIT_SP));
|
||||
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_call(struct sljit_compiler *compiler, sljit_s32 type,
|
||||
sljit_s32 arg_types)
|
||||
{
|
||||
struct sljit_jump *jump;
|
||||
sljit_u32 extra_space = (sljit_u32)type;
|
||||
sljit_ins ins;
|
||||
|
||||
CHECK_ERROR_PTR();
|
||||
|
@ -624,21 +582,34 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_call(struct sljit_compile
|
|||
jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
|
||||
PTR_FAIL_IF(!jump);
|
||||
set_jump(jump, compiler, type & SLJIT_REWRITABLE_JUMP);
|
||||
type &= 0xff;
|
||||
|
||||
PTR_FAIL_IF(call_with_args(compiler, arg_types, &ins));
|
||||
PTR_FAIL_IF(call_with_args(compiler, arg_types, &ins, &extra_space));
|
||||
|
||||
SLJIT_ASSERT(DR(PIC_ADDR_REG) == 25 && PIC_ADDR_REG == TMP_REG2);
|
||||
|
||||
PTR_FAIL_IF(emit_const(compiler, PIC_ADDR_REG, 0));
|
||||
|
||||
jump->flags |= IS_JAL | IS_CALL;
|
||||
PTR_FAIL_IF(push_inst(compiler, JALR | S(PIC_ADDR_REG) | DA(RETURN_ADDR_REG), UNMOVABLE_INS));
|
||||
if (!(type & SLJIT_CALL_RETURN) || extra_space > 0) {
|
||||
jump->flags |= IS_JAL | IS_CALL;
|
||||
PTR_FAIL_IF(push_inst(compiler, JALR | S(PIC_ADDR_REG) | DA(RETURN_ADDR_REG), UNMOVABLE_INS));
|
||||
} else
|
||||
PTR_FAIL_IF(push_inst(compiler, JR | S(PIC_ADDR_REG), UNMOVABLE_INS));
|
||||
|
||||
jump->addr = compiler->size;
|
||||
PTR_FAIL_IF(push_inst(compiler, ins, UNMOVABLE_INS));
|
||||
|
||||
PTR_FAIL_IF(post_call_with_args(compiler, arg_types));
|
||||
if (extra_space == 0)
|
||||
return jump;
|
||||
|
||||
if (type & SLJIT_CALL_RETURN)
|
||||
PTR_FAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, RETURN_ADDR_REG,
|
||||
SLJIT_MEM1(SLJIT_SP), (sljit_sw)(extra_space - sizeof(sljit_sw))));
|
||||
|
||||
if (type & SLJIT_CALL_RETURN)
|
||||
PTR_FAIL_IF(push_inst(compiler, JR | SA(RETURN_ADDR_REG), UNMOVABLE_INS));
|
||||
|
||||
PTR_FAIL_IF(push_inst(compiler, ADDIU | S(SLJIT_SP) | T(SLJIT_SP) | IMM(extra_space),
|
||||
(type & SLJIT_CALL_RETURN) ? UNMOVABLE_INS : DR(SLJIT_SP)));
|
||||
return jump;
|
||||
}
|
||||
|
||||
|
@ -646,6 +617,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_icall(struct sljit_compiler *compi
|
|||
sljit_s32 arg_types,
|
||||
sljit_s32 src, sljit_sw srcw)
|
||||
{
|
||||
sljit_u32 extra_space = (sljit_u32)type;
|
||||
sljit_ins ins;
|
||||
|
||||
CHECK_ERROR();
|
||||
|
@ -662,10 +634,25 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_icall(struct sljit_compiler *compi
|
|||
FAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, DR(PIC_ADDR_REG), src, srcw));
|
||||
}
|
||||
|
||||
FAIL_IF(call_with_args(compiler, arg_types, &ins));
|
||||
FAIL_IF(call_with_args(compiler, arg_types, &ins, &extra_space));
|
||||
|
||||
/* Register input. */
|
||||
FAIL_IF(push_inst(compiler, JALR | S(PIC_ADDR_REG) | DA(RETURN_ADDR_REG), UNMOVABLE_INS));
|
||||
if (!(type & SLJIT_CALL_RETURN) || extra_space > 0)
|
||||
FAIL_IF(push_inst(compiler, JALR | S(PIC_ADDR_REG) | DA(RETURN_ADDR_REG), UNMOVABLE_INS));
|
||||
else
|
||||
FAIL_IF(push_inst(compiler, JR | S(PIC_ADDR_REG), UNMOVABLE_INS));
|
||||
FAIL_IF(push_inst(compiler, ins, UNMOVABLE_INS));
|
||||
return post_call_with_args(compiler, arg_types);
|
||||
|
||||
if (extra_space == 0)
|
||||
return SLJIT_SUCCESS;
|
||||
|
||||
if (type & SLJIT_CALL_RETURN)
|
||||
FAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, RETURN_ADDR_REG,
|
||||
SLJIT_MEM1(SLJIT_SP), (sljit_sw)(extra_space - sizeof(sljit_sw))));
|
||||
|
||||
if (type & SLJIT_CALL_RETURN)
|
||||
FAIL_IF(push_inst(compiler, JR | SA(RETURN_ADDR_REG), UNMOVABLE_INS));
|
||||
|
||||
return push_inst(compiler, ADDIU | S(SLJIT_SP) | T(SLJIT_SP) | IMM(extra_space),
|
||||
(type & SLJIT_CALL_RETURN) ? UNMOVABLE_INS : DR(SLJIT_SP));
|
||||
}
|
||||
|
|
|
@ -46,9 +46,9 @@ static sljit_s32 load_immediate(struct sljit_compiler *compiler, sljit_s32 dst_a
|
|||
}
|
||||
|
||||
/* Zero extended number. */
|
||||
uimm = imm;
|
||||
uimm = (sljit_uw)imm;
|
||||
if (imm < 0) {
|
||||
uimm = ~imm;
|
||||
uimm = ~(sljit_uw)imm;
|
||||
inv = 1;
|
||||
}
|
||||
|
||||
|
@ -119,7 +119,7 @@ static sljit_s32 load_immediate(struct sljit_compiler *compiler, sljit_s32 dst_a
|
|||
}
|
||||
|
||||
#define SELECT_OP(a, b) \
|
||||
(!(op & SLJIT_I32_OP) ? a : b)
|
||||
(!(op & SLJIT_32) ? a : b)
|
||||
|
||||
#define EMIT_LOGICAL(op_imm, op_norm) \
|
||||
if (flags & SRC2_IMM) { \
|
||||
|
@ -138,19 +138,19 @@ static sljit_s32 load_immediate(struct sljit_compiler *compiler, sljit_s32 dst_a
|
|||
#define EMIT_SHIFT(op_dimm, op_dimm32, op_imm, op_dv, op_v) \
|
||||
if (flags & SRC2_IMM) { \
|
||||
if (src2 >= 32) { \
|
||||
SLJIT_ASSERT(!(op & SLJIT_I32_OP)); \
|
||||
SLJIT_ASSERT(!(op & SLJIT_32)); \
|
||||
ins = op_dimm32; \
|
||||
src2 -= 32; \
|
||||
} \
|
||||
else \
|
||||
ins = (op & SLJIT_I32_OP) ? op_imm : op_dimm; \
|
||||
ins = (op & SLJIT_32) ? op_imm : op_dimm; \
|
||||
if (op & SLJIT_SET_Z) \
|
||||
FAIL_IF(push_inst(compiler, ins | T(src1) | DA(EQUAL_FLAG) | SH_IMM(src2), EQUAL_FLAG)); \
|
||||
if (!(flags & UNUSED_DEST)) \
|
||||
FAIL_IF(push_inst(compiler, ins | T(src1) | D(dst) | SH_IMM(src2), DR(dst))); \
|
||||
} \
|
||||
else { \
|
||||
ins = (op & SLJIT_I32_OP) ? op_v : op_dv; \
|
||||
ins = (op & SLJIT_32) ? op_v : op_dv; \
|
||||
if (op & SLJIT_SET_Z) \
|
||||
FAIL_IF(push_inst(compiler, ins | S(src2) | T(src1) | DA(EQUAL_FLAG), EQUAL_FLAG)); \
|
||||
if (!(flags & UNUSED_DEST)) \
|
||||
|
@ -165,50 +165,71 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl
|
|||
|
||||
switch (GET_OPCODE(op)) {
|
||||
case SLJIT_MOV:
|
||||
case SLJIT_MOV_P:
|
||||
SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
|
||||
if (dst != src2)
|
||||
return push_inst(compiler, SELECT_OP(DADDU, ADDU) | S(src2) | TA(0) | D(dst), DR(dst));
|
||||
return SLJIT_SUCCESS;
|
||||
|
||||
case SLJIT_MOV_U8:
|
||||
SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
|
||||
if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE))
|
||||
return push_inst(compiler, ANDI | S(src2) | T(dst) | IMM(0xff), DR(dst));
|
||||
SLJIT_ASSERT(dst == src2);
|
||||
return SLJIT_SUCCESS;
|
||||
|
||||
case SLJIT_MOV_S8:
|
||||
SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
|
||||
if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) {
|
||||
if (op == SLJIT_MOV_S8) {
|
||||
FAIL_IF(push_inst(compiler, DSLL32 | T(src2) | D(dst) | SH_IMM(24), DR(dst)));
|
||||
return push_inst(compiler, DSRA32 | T(dst) | D(dst) | SH_IMM(24), DR(dst));
|
||||
}
|
||||
return push_inst(compiler, ANDI | S(src2) | T(dst) | IMM(0xff), DR(dst));
|
||||
}
|
||||
else {
|
||||
SLJIT_ASSERT(dst == src2);
|
||||
#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1)
|
||||
if (op & SLJIT_32)
|
||||
return push_inst(compiler, SEB | T(src2) | D(dst), DR(dst));
|
||||
#endif /* SLJIT_MIPS_REV >= 1 */
|
||||
FAIL_IF(push_inst(compiler, DSLL32 | T(src2) | D(dst) | SH_IMM(24), DR(dst)));
|
||||
return push_inst(compiler, DSRA32 | T(dst) | D(dst) | SH_IMM(24), DR(dst));
|
||||
}
|
||||
SLJIT_ASSERT(dst == src2);
|
||||
return SLJIT_SUCCESS;
|
||||
|
||||
case SLJIT_MOV_U16:
|
||||
SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
|
||||
if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE))
|
||||
return push_inst(compiler, ANDI | S(src2) | T(dst) | IMM(0xffff), DR(dst));
|
||||
SLJIT_ASSERT(dst == src2);
|
||||
return SLJIT_SUCCESS;
|
||||
|
||||
case SLJIT_MOV_S16:
|
||||
SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
|
||||
if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) {
|
||||
if (op == SLJIT_MOV_S16) {
|
||||
FAIL_IF(push_inst(compiler, DSLL32 | T(src2) | D(dst) | SH_IMM(16), DR(dst)));
|
||||
return push_inst(compiler, DSRA32 | T(dst) | D(dst) | SH_IMM(16), DR(dst));
|
||||
}
|
||||
return push_inst(compiler, ANDI | S(src2) | T(dst) | IMM(0xffff), DR(dst));
|
||||
}
|
||||
else {
|
||||
SLJIT_ASSERT(dst == src2);
|
||||
#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1)
|
||||
if (op & SLJIT_32)
|
||||
return push_inst(compiler, SEH | T(src2) | D(dst), DR(dst));
|
||||
#endif /* SLJIT_MIPS_REV >= 1 */
|
||||
FAIL_IF(push_inst(compiler, DSLL32 | T(src2) | D(dst) | SH_IMM(16), DR(dst)));
|
||||
return push_inst(compiler, DSRA32 | T(dst) | D(dst) | SH_IMM(16), DR(dst));
|
||||
}
|
||||
SLJIT_ASSERT(dst == src2);
|
||||
return SLJIT_SUCCESS;
|
||||
|
||||
case SLJIT_MOV_U32:
|
||||
SLJIT_ASSERT(!(op & SLJIT_I32_OP));
|
||||
FAIL_IF(push_inst(compiler, DSLL32 | T(src2) | D(dst) | SH_IMM(0), DR(dst)));
|
||||
return push_inst(compiler, DSRL32 | T(dst) | D(dst) | SH_IMM(0), DR(dst));
|
||||
SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM) && !(op & SLJIT_32));
|
||||
if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) {
|
||||
#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 2)
|
||||
if (dst == src2)
|
||||
return push_inst(compiler, DINSU | T(src2) | SA(0) | (31 << 11) | (0 << 11), DR(dst));
|
||||
#endif /* SLJIT_MIPS_REV >= 2 */
|
||||
FAIL_IF(push_inst(compiler, DSLL32 | T(src2) | D(dst) | SH_IMM(0), DR(dst)));
|
||||
return push_inst(compiler, DSRL32 | T(dst) | D(dst) | SH_IMM(0), DR(dst));
|
||||
}
|
||||
SLJIT_ASSERT(dst == src2);
|
||||
return SLJIT_SUCCESS;
|
||||
|
||||
case SLJIT_MOV_S32:
|
||||
SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
|
||||
return push_inst(compiler, SLL | T(src2) | D(dst) | SH_IMM(0), DR(dst));
|
||||
SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM) && !(op & SLJIT_32));
|
||||
if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) {
|
||||
return push_inst(compiler, SLL | T(src2) | D(dst) | SH_IMM(0), DR(dst));
|
||||
}
|
||||
SLJIT_ASSERT(dst == src2);
|
||||
return SLJIT_SUCCESS;
|
||||
|
||||
case SLJIT_NOT:
|
||||
SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
|
||||
|
@ -234,7 +255,7 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl
|
|||
FAIL_IF(push_inst(compiler, SELECT_OP(DADDU, ADDU) | S(src2) | TA(0) | D(TMP_REG1), DR(TMP_REG1)));
|
||||
/* Check zero. */
|
||||
FAIL_IF(push_inst(compiler, BEQ | S(TMP_REG1) | TA(0) | IMM(5), UNMOVABLE_INS));
|
||||
FAIL_IF(push_inst(compiler, ORI | SA(0) | T(dst) | IMM((op & SLJIT_I32_OP) ? 32 : 64), UNMOVABLE_INS));
|
||||
FAIL_IF(push_inst(compiler, ORI | SA(0) | T(dst) | IMM((op & SLJIT_32) ? 32 : 64), UNMOVABLE_INS));
|
||||
FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | SA(0) | T(dst) | IMM(-1), DR(dst)));
|
||||
/* Loop for searching the highest bit. */
|
||||
FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | S(dst) | T(dst) | IMM(1), DR(dst)));
|
||||
|
@ -462,7 +483,7 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl
|
|||
#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
|
||||
return push_inst(compiler, SELECT_OP(DMUL, MUL) | S(src1) | T(src2) | D(dst), DR(dst));
|
||||
#elif (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1)
|
||||
if (op & SLJIT_I32_OP)
|
||||
if (op & SLJIT_32)
|
||||
return push_inst(compiler, MUL | S(src1) | T(src2) | D(dst), DR(dst));
|
||||
FAIL_IF(push_inst(compiler, DMULT | S(src1) | T(src2), MOVABLE_INS));
|
||||
return push_inst(compiler, MFLO | D(dst), DR(dst));
|
||||
|
@ -528,10 +549,10 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_ta
|
|||
SLJIT_UNUSED_ARG(executable_offset);
|
||||
|
||||
SLJIT_UPDATE_WX_FLAGS(inst, inst + 6, 0);
|
||||
inst[0] = (inst[0] & 0xffff0000) | ((new_target >> 48) & 0xffff);
|
||||
inst[1] = (inst[1] & 0xffff0000) | ((new_target >> 32) & 0xffff);
|
||||
inst[3] = (inst[3] & 0xffff0000) | ((new_target >> 16) & 0xffff);
|
||||
inst[5] = (inst[5] & 0xffff0000) | (new_target & 0xffff);
|
||||
inst[0] = (inst[0] & 0xffff0000) | ((sljit_ins)(new_target >> 48) & 0xffff);
|
||||
inst[1] = (inst[1] & 0xffff0000) | ((sljit_ins)(new_target >> 32) & 0xffff);
|
||||
inst[3] = (inst[3] & 0xffff0000) | ((sljit_ins)(new_target >> 16) & 0xffff);
|
||||
inst[5] = (inst[5] & 0xffff0000) | ((sljit_ins)new_target & 0xffff);
|
||||
SLJIT_UPDATE_WX_FLAGS(inst, inst + 6, 1);
|
||||
inst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
|
||||
SLJIT_CACHE_FLUSH(inst, inst + 6);
|
||||
|
@ -539,7 +560,7 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_ta
|
|||
|
||||
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant, sljit_sw executable_offset)
|
||||
{
|
||||
sljit_set_jump_addr(addr, new_constant, executable_offset);
|
||||
sljit_set_jump_addr(addr, (sljit_uw)new_constant, executable_offset);
|
||||
}
|
||||
|
||||
static sljit_s32 call_with_args(struct sljit_compiler *compiler, sljit_s32 arg_types, sljit_ins *ins_ptr)
|
||||
|
@ -548,19 +569,19 @@ static sljit_s32 call_with_args(struct sljit_compiler *compiler, sljit_s32 arg_t
|
|||
sljit_s32 word_arg_count = 0;
|
||||
sljit_s32 float_arg_count = 0;
|
||||
sljit_s32 types = 0;
|
||||
sljit_ins prev_ins = NOP;
|
||||
sljit_ins prev_ins = *ins_ptr;
|
||||
sljit_ins ins = NOP;
|
||||
|
||||
SLJIT_ASSERT(reg_map[TMP_REG1] == 4 && freg_map[TMP_FREG1] == 12);
|
||||
|
||||
arg_types >>= SLJIT_DEF_SHIFT;
|
||||
arg_types >>= SLJIT_ARG_SHIFT;
|
||||
|
||||
while (arg_types) {
|
||||
types = (types << SLJIT_DEF_SHIFT) | (arg_types & SLJIT_DEF_MASK);
|
||||
types = (types << SLJIT_ARG_SHIFT) | (arg_types & SLJIT_ARG_MASK);
|
||||
|
||||
switch (arg_types & SLJIT_DEF_MASK) {
|
||||
case SLJIT_ARG_TYPE_F32:
|
||||
switch (arg_types & SLJIT_ARG_MASK) {
|
||||
case SLJIT_ARG_TYPE_F64:
|
||||
case SLJIT_ARG_TYPE_F32:
|
||||
arg_count++;
|
||||
float_arg_count++;
|
||||
break;
|
||||
|
@ -570,19 +591,11 @@ static sljit_s32 call_with_args(struct sljit_compiler *compiler, sljit_s32 arg_t
|
|||
break;
|
||||
}
|
||||
|
||||
arg_types >>= SLJIT_DEF_SHIFT;
|
||||
arg_types >>= SLJIT_ARG_SHIFT;
|
||||
}
|
||||
|
||||
while (types) {
|
||||
switch (types & SLJIT_DEF_MASK) {
|
||||
case SLJIT_ARG_TYPE_F32:
|
||||
if (arg_count != float_arg_count)
|
||||
ins = MOV_S | FMT_S | FS(float_arg_count) | FD(arg_count);
|
||||
else if (arg_count == 1)
|
||||
ins = MOV_S | FMT_S | FS(SLJIT_FR0) | FD(TMP_FREG1);
|
||||
arg_count--;
|
||||
float_arg_count--;
|
||||
break;
|
||||
switch (types & SLJIT_ARG_MASK) {
|
||||
case SLJIT_ARG_TYPE_F64:
|
||||
if (arg_count != float_arg_count)
|
||||
ins = MOV_S | FMT_D | FS(float_arg_count) | FD(arg_count);
|
||||
|
@ -591,6 +604,14 @@ static sljit_s32 call_with_args(struct sljit_compiler *compiler, sljit_s32 arg_t
|
|||
arg_count--;
|
||||
float_arg_count--;
|
||||
break;
|
||||
case SLJIT_ARG_TYPE_F32:
|
||||
if (arg_count != float_arg_count)
|
||||
ins = MOV_S | FMT_S | FS(float_arg_count) | FD(arg_count);
|
||||
else if (arg_count == 1)
|
||||
ins = MOV_S | FMT_S | FS(SLJIT_FR0) | FD(TMP_FREG1);
|
||||
arg_count--;
|
||||
float_arg_count--;
|
||||
break;
|
||||
default:
|
||||
if (arg_count != word_arg_count)
|
||||
ins = DADDU | S(word_arg_count) | TA(0) | D(arg_count);
|
||||
|
@ -608,7 +629,7 @@ static sljit_s32 call_with_args(struct sljit_compiler *compiler, sljit_s32 arg_t
|
|||
ins = NOP;
|
||||
}
|
||||
|
||||
types >>= SLJIT_DEF_SHIFT;
|
||||
types >>= SLJIT_ARG_SHIFT;
|
||||
}
|
||||
|
||||
*ins_ptr = prev_ins;
|
||||
|
@ -620,7 +641,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_call(struct sljit_compile
|
|||
sljit_s32 arg_types)
|
||||
{
|
||||
struct sljit_jump *jump;
|
||||
sljit_ins ins;
|
||||
sljit_ins ins = NOP;
|
||||
|
||||
CHECK_ERROR_PTR();
|
||||
CHECK_PTR(check_sljit_emit_call(compiler, type, arg_types));
|
||||
|
@ -628,7 +649,9 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_call(struct sljit_compile
|
|||
jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
|
||||
PTR_FAIL_IF(!jump);
|
||||
set_jump(jump, compiler, type & SLJIT_REWRITABLE_JUMP);
|
||||
type &= 0xff;
|
||||
|
||||
if (type & SLJIT_CALL_RETURN)
|
||||
PTR_FAIL_IF(emit_stack_frame_release(compiler, 0, &ins));
|
||||
|
||||
PTR_FAIL_IF(call_with_args(compiler, arg_types, &ins));
|
||||
|
||||
|
@ -636,8 +659,12 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_call(struct sljit_compile
|
|||
|
||||
PTR_FAIL_IF(emit_const(compiler, PIC_ADDR_REG, 0));
|
||||
|
||||
jump->flags |= IS_JAL | IS_CALL;
|
||||
PTR_FAIL_IF(push_inst(compiler, JALR | S(PIC_ADDR_REG) | DA(RETURN_ADDR_REG), UNMOVABLE_INS));
|
||||
if (!(type & SLJIT_CALL_RETURN)) {
|
||||
jump->flags |= IS_JAL | IS_CALL;
|
||||
PTR_FAIL_IF(push_inst(compiler, JALR | S(PIC_ADDR_REG) | DA(RETURN_ADDR_REG), UNMOVABLE_INS));
|
||||
} else
|
||||
PTR_FAIL_IF(push_inst(compiler, JR | S(PIC_ADDR_REG), UNMOVABLE_INS));
|
||||
|
||||
jump->addr = compiler->size;
|
||||
PTR_FAIL_IF(push_inst(compiler, ins, UNMOVABLE_INS));
|
||||
|
||||
|
@ -648,7 +675,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_icall(struct sljit_compiler *compi
|
|||
sljit_s32 arg_types,
|
||||
sljit_s32 src, sljit_sw srcw)
|
||||
{
|
||||
sljit_ins ins;
|
||||
sljit_ins ins = NOP;
|
||||
|
||||
CHECK_ERROR();
|
||||
CHECK(check_sljit_emit_icall(compiler, type, arg_types, src, srcw));
|
||||
|
@ -664,9 +691,15 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_icall(struct sljit_compiler *compi
|
|||
FAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, DR(PIC_ADDR_REG), src, srcw));
|
||||
}
|
||||
|
||||
if (type & SLJIT_CALL_RETURN)
|
||||
FAIL_IF(emit_stack_frame_release(compiler, 0, &ins));
|
||||
|
||||
FAIL_IF(call_with_args(compiler, arg_types, &ins));
|
||||
|
||||
/* Register input. */
|
||||
FAIL_IF(push_inst(compiler, JALR | S(PIC_ADDR_REG) | DA(RETURN_ADDR_REG), UNMOVABLE_INS));
|
||||
if (!(type & SLJIT_CALL_RETURN))
|
||||
FAIL_IF(push_inst(compiler, JALR | S(PIC_ADDR_REG) | DA(RETURN_ADDR_REG), UNMOVABLE_INS));
|
||||
else
|
||||
FAIL_IF(push_inst(compiler, JR | S(PIC_ADDR_REG), UNMOVABLE_INS));
|
||||
return push_inst(compiler, ins, UNMOVABLE_INS);
|
||||
}
|
||||
|
|
|
@ -86,13 +86,13 @@ static const sljit_u8 reg_map[SLJIT_NUMBER_OF_REGISTERS + 5] = {
|
|||
#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
|
||||
|
||||
static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 4] = {
|
||||
0, 0, 14, 2, 4, 6, 8, 12, 10, 16
|
||||
0, 0, 14, 2, 4, 6, 8, 18, 30, 28, 26, 24, 22, 20, 12, 10, 16
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 4] = {
|
||||
0, 0, 13, 14, 15, 16, 17, 12, 18, 10
|
||||
0, 0, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 1, 2, 3, 4, 5, 6, 7, 8, 9, 31, 30, 29, 28, 27, 26, 25, 24, 12, 11, 10
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -101,23 +101,23 @@ static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 4] = {
|
|||
/* Instrucion forms */
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
#define S(s) (reg_map[s] << 21)
|
||||
#define T(t) (reg_map[t] << 16)
|
||||
#define D(d) (reg_map[d] << 11)
|
||||
#define FT(t) (freg_map[t] << 16)
|
||||
#define FS(s) (freg_map[s] << 11)
|
||||
#define FD(d) (freg_map[d] << 6)
|
||||
#define S(s) ((sljit_ins)reg_map[s] << 21)
|
||||
#define T(t) ((sljit_ins)reg_map[t] << 16)
|
||||
#define D(d) ((sljit_ins)reg_map[d] << 11)
|
||||
#define FT(t) ((sljit_ins)freg_map[t] << 16)
|
||||
#define FS(s) ((sljit_ins)freg_map[s] << 11)
|
||||
#define FD(d) ((sljit_ins)freg_map[d] << 6)
|
||||
/* Absolute registers. */
|
||||
#define SA(s) ((s) << 21)
|
||||
#define TA(t) ((t) << 16)
|
||||
#define DA(d) ((d) << 11)
|
||||
#define IMM(imm) ((imm) & 0xffff)
|
||||
#define SH_IMM(imm) ((imm) << 6)
|
||||
#define SA(s) ((sljit_ins)(s) << 21)
|
||||
#define TA(t) ((sljit_ins)(t) << 16)
|
||||
#define DA(d) ((sljit_ins)(d) << 11)
|
||||
#define IMM(imm) ((sljit_ins)(imm) & 0xffff)
|
||||
#define SH_IMM(imm) ((sljit_ins)(imm) << 6)
|
||||
|
||||
#define DR(dr) (reg_map[dr])
|
||||
#define FR(dr) (freg_map[dr])
|
||||
#define HI(opcode) ((opcode) << 26)
|
||||
#define LO(opcode) (opcode)
|
||||
#define HI(opcode) ((sljit_ins)(opcode) << 26)
|
||||
#define LO(opcode) ((sljit_ins)(opcode))
|
||||
#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
|
||||
/* CMP.cond.fmt */
|
||||
/* S = (20 << 21) D = (21 << 21) */
|
||||
|
@ -186,6 +186,7 @@ static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 4] = {
|
|||
#define DMULTU (HI(0) | LO(29))
|
||||
#endif /* SLJIT_MIPS_REV >= 6 */
|
||||
#define DIV_S (HI(17) | FMT_S | LO(3))
|
||||
#define DINSU (HI(31) | LO(6))
|
||||
#define DSLL (HI(0) | LO(56))
|
||||
#define DSLL32 (HI(0) | LO(60))
|
||||
#define DSLLV (HI(0) | LO(20))
|
||||
|
@ -205,8 +206,10 @@ static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 4] = {
|
|||
#define JR (HI(0) | LO(8))
|
||||
#endif /* SLJIT_MIPS_REV >= 6 */
|
||||
#define LD (HI(55))
|
||||
#define LDC1 (HI(53))
|
||||
#define LUI (HI(15))
|
||||
#define LW (HI(35))
|
||||
#define LWC1 (HI(49))
|
||||
#define MFC1 (HI(17))
|
||||
#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
|
||||
#define MOD (HI(0) | (3 << 6) | LO(26))
|
||||
|
@ -292,7 +295,8 @@ static sljit_s32 push_inst(struct sljit_compiler *compiler, sljit_ins ins, sljit
|
|||
{
|
||||
sljit_ins *ptr = (sljit_ins*)ensure_buf(compiler, sizeof(sljit_ins));
|
||||
SLJIT_ASSERT(delay_slot == MOVABLE_INS || delay_slot >= UNMOVABLE_INS
|
||||
|| delay_slot == ((ins >> 11) & 0x1f) || delay_slot == ((ins >> 16) & 0x1f));
|
||||
|| (sljit_ins)delay_slot == ((ins >> 11) & 0x1f)
|
||||
|| (sljit_ins)delay_slot == ((ins >> 16) & 0x1f));
|
||||
FAIL_IF(!ptr);
|
||||
*ptr = ins;
|
||||
compiler->size++;
|
||||
|
@ -300,7 +304,7 @@ static sljit_s32 push_inst(struct sljit_compiler *compiler, sljit_ins ins, sljit
|
|||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
static SLJIT_INLINE sljit_ins invert_branch(sljit_s32 flags)
|
||||
static SLJIT_INLINE sljit_ins invert_branch(sljit_uw flags)
|
||||
{
|
||||
if (flags & IS_BIT26_COND)
|
||||
return (1 << 26);
|
||||
|
@ -371,7 +375,7 @@ static SLJIT_INLINE sljit_ins* detect_jump_type(struct sljit_jump *jump, sljit_i
|
|||
inst[1] = NOP;
|
||||
return inst + 1;
|
||||
}
|
||||
inst[0] = inst[0] ^ invert_branch(jump->flags);
|
||||
inst[0] ^= invert_branch(jump->flags);
|
||||
inst[1] = NOP;
|
||||
jump->addr -= sizeof(sljit_ins);
|
||||
return inst + 1;
|
||||
|
@ -379,7 +383,7 @@ static SLJIT_INLINE sljit_ins* detect_jump_type(struct sljit_jump *jump, sljit_i
|
|||
}
|
||||
|
||||
if (jump->flags & IS_COND) {
|
||||
if ((jump->flags & IS_MOVABLE) && (target_addr & ~0xfffffff) == ((jump->addr + 2 * sizeof(sljit_ins)) & ~0xfffffff)) {
|
||||
if ((jump->flags & IS_MOVABLE) && (target_addr & ~(sljit_uw)0xfffffff) == ((jump->addr + 2 * sizeof(sljit_ins)) & ~(sljit_uw)0xfffffff)) {
|
||||
jump->flags |= PATCH_J;
|
||||
saved_inst = inst[0];
|
||||
inst[0] = inst[-1];
|
||||
|
@ -388,7 +392,7 @@ static SLJIT_INLINE sljit_ins* detect_jump_type(struct sljit_jump *jump, sljit_i
|
|||
inst[2] = NOP;
|
||||
return inst + 2;
|
||||
}
|
||||
else if ((target_addr & ~0xfffffff) == ((jump->addr + 3 * sizeof(sljit_ins)) & ~0xfffffff)) {
|
||||
else if ((target_addr & ~(sljit_uw)0xfffffff) == ((jump->addr + 3 * sizeof(sljit_ins)) & ~(sljit_uw)0xfffffff)) {
|
||||
jump->flags |= PATCH_J;
|
||||
inst[0] = (inst[0] & 0xffff0000) | 3;
|
||||
inst[1] = NOP;
|
||||
|
@ -400,7 +404,7 @@ static SLJIT_INLINE sljit_ins* detect_jump_type(struct sljit_jump *jump, sljit_i
|
|||
}
|
||||
else {
|
||||
/* J instuctions. */
|
||||
if ((jump->flags & IS_MOVABLE) && (target_addr & ~0xfffffff) == (jump->addr & ~0xfffffff)) {
|
||||
if ((jump->flags & IS_MOVABLE) && (target_addr & ~(sljit_uw)0xfffffff) == (jump->addr & ~(sljit_uw)0xfffffff)) {
|
||||
jump->flags |= PATCH_J;
|
||||
inst[0] = inst[-1];
|
||||
inst[-1] = (jump->flags & IS_JAL) ? JAL : J;
|
||||
|
@ -408,7 +412,7 @@ static SLJIT_INLINE sljit_ins* detect_jump_type(struct sljit_jump *jump, sljit_i
|
|||
return inst;
|
||||
}
|
||||
|
||||
if ((target_addr & ~0xfffffff) == ((jump->addr + sizeof(sljit_ins)) & ~0xfffffff)) {
|
||||
if ((target_addr & ~(sljit_uw)0xfffffff) == ((jump->addr + sizeof(sljit_ins)) & ~(sljit_uw)0xfffffff)) {
|
||||
jump->flags |= PATCH_J;
|
||||
inst[0] = (jump->flags & IS_JAL) ? JAL : J;
|
||||
inst[1] = NOP;
|
||||
|
@ -472,7 +476,7 @@ static SLJIT_INLINE void put_label_set(struct sljit_put_label *put_label)
|
|||
{
|
||||
sljit_uw addr = put_label->label->addr;
|
||||
sljit_ins *inst = (sljit_ins *)put_label->addr;
|
||||
sljit_s32 reg = *inst;
|
||||
sljit_u32 reg = *inst;
|
||||
|
||||
if (put_label->flags == 0) {
|
||||
SLJIT_ASSERT(addr < 0x80000000l);
|
||||
|
@ -548,7 +552,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
|
|||
/* These structures are ordered by their address. */
|
||||
if (label && label->size == word_count) {
|
||||
label->addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
|
||||
label->size = code_ptr - code;
|
||||
label->size = (sljit_uw)(code_ptr - code);
|
||||
label = label->next;
|
||||
}
|
||||
if (jump && jump->addr == word_count) {
|
||||
|
@ -584,7 +588,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
|
|||
|
||||
if (label && label->size == word_count) {
|
||||
label->addr = (sljit_uw)code_ptr;
|
||||
label->size = code_ptr - code;
|
||||
label->size = (sljit_uw)(code_ptr - code);
|
||||
label = label->next;
|
||||
}
|
||||
|
||||
|
@ -601,39 +605,46 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
|
|||
buf_ptr = (sljit_ins *)jump->addr;
|
||||
|
||||
if (jump->flags & PATCH_B) {
|
||||
addr = (sljit_sw)(addr - ((sljit_uw)SLJIT_ADD_EXEC_OFFSET(buf_ptr, executable_offset) + sizeof(sljit_ins))) >> 2;
|
||||
addr = (sljit_uw)((sljit_sw)(addr - (sljit_uw)SLJIT_ADD_EXEC_OFFSET(buf_ptr, executable_offset) - sizeof(sljit_ins)) >> 2);
|
||||
SLJIT_ASSERT((sljit_sw)addr <= SIMM_MAX && (sljit_sw)addr >= SIMM_MIN);
|
||||
buf_ptr[0] = (buf_ptr[0] & 0xffff0000) | (addr & 0xffff);
|
||||
buf_ptr[0] = (buf_ptr[0] & 0xffff0000) | ((sljit_ins)addr & 0xffff);
|
||||
break;
|
||||
}
|
||||
if (jump->flags & PATCH_J) {
|
||||
SLJIT_ASSERT((addr & ~0xfffffff) == (((sljit_uw)SLJIT_ADD_EXEC_OFFSET(buf_ptr, executable_offset) + sizeof(sljit_ins)) & ~0xfffffff));
|
||||
buf_ptr[0] |= (addr >> 2) & 0x03ffffff;
|
||||
SLJIT_ASSERT((addr & ~(sljit_uw)0xfffffff)
|
||||
== (((sljit_uw)SLJIT_ADD_EXEC_OFFSET(buf_ptr, executable_offset) + sizeof(sljit_ins)) & ~(sljit_uw)0xfffffff));
|
||||
buf_ptr[0] |= (sljit_ins)(addr >> 2) & 0x03ffffff;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Set the fields of immediate loads. */
|
||||
#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
|
||||
buf_ptr[0] = (buf_ptr[0] & 0xffff0000) | ((addr >> 16) & 0xffff);
|
||||
buf_ptr[1] = (buf_ptr[1] & 0xffff0000) | (addr & 0xffff);
|
||||
SLJIT_ASSERT(((buf_ptr[0] | buf_ptr[1]) & 0xffff) == 0);
|
||||
buf_ptr[0] |= (sljit_ins)(addr >> 16) & 0xffff;
|
||||
buf_ptr[1] |= (sljit_ins)addr & 0xffff;
|
||||
#else
|
||||
if (jump->flags & PATCH_ABS32) {
|
||||
SLJIT_ASSERT(addr <= 0x7fffffff);
|
||||
buf_ptr[0] = (buf_ptr[0] & 0xffff0000) | ((addr >> 16) & 0xffff);
|
||||
buf_ptr[1] = (buf_ptr[1] & 0xffff0000) | (addr & 0xffff);
|
||||
SLJIT_ASSERT(((buf_ptr[0] | buf_ptr[1]) & 0xffff) == 0);
|
||||
buf_ptr[0] |= (sljit_ins)(addr >> 16) & 0xffff;
|
||||
buf_ptr[1] |= (sljit_ins)addr & 0xffff;
|
||||
break;
|
||||
}
|
||||
else if (jump->flags & PATCH_ABS48) {
|
||||
|
||||
if (jump->flags & PATCH_ABS48) {
|
||||
SLJIT_ASSERT(addr <= 0x7fffffffffffl);
|
||||
buf_ptr[0] = (buf_ptr[0] & 0xffff0000) | ((addr >> 32) & 0xffff);
|
||||
buf_ptr[1] = (buf_ptr[1] & 0xffff0000) | ((addr >> 16) & 0xffff);
|
||||
buf_ptr[3] = (buf_ptr[3] & 0xffff0000) | (addr & 0xffff);
|
||||
}
|
||||
else {
|
||||
buf_ptr[0] = (buf_ptr[0] & 0xffff0000) | ((addr >> 48) & 0xffff);
|
||||
buf_ptr[1] = (buf_ptr[1] & 0xffff0000) | ((addr >> 32) & 0xffff);
|
||||
buf_ptr[3] = (buf_ptr[3] & 0xffff0000) | ((addr >> 16) & 0xffff);
|
||||
buf_ptr[5] = (buf_ptr[5] & 0xffff0000) | (addr & 0xffff);
|
||||
SLJIT_ASSERT(((buf_ptr[0] | buf_ptr[1] | buf_ptr[3]) & 0xffff) == 0);
|
||||
buf_ptr[0] |= (sljit_ins)(addr >> 32) & 0xffff;
|
||||
buf_ptr[1] |= (sljit_ins)(addr >> 16) & 0xffff;
|
||||
buf_ptr[3] |= (sljit_ins)addr & 0xffff;
|
||||
break;
|
||||
}
|
||||
|
||||
SLJIT_ASSERT(((buf_ptr[0] | buf_ptr[1] | buf_ptr[3] | buf_ptr[5]) & 0xffff) == 0);
|
||||
buf_ptr[0] |= (sljit_ins)(addr >> 48) & 0xffff;
|
||||
buf_ptr[1] |= (sljit_ins)(addr >> 32) & 0xffff;
|
||||
buf_ptr[3] |= (sljit_ins)(addr >> 16) & 0xffff;
|
||||
buf_ptr[5] |= (sljit_ins)addr & 0xffff;
|
||||
#endif
|
||||
} while (0);
|
||||
jump = jump->next;
|
||||
|
@ -656,7 +667,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
|
|||
|
||||
compiler->error = SLJIT_ERR_COMPILED;
|
||||
compiler->executable_offset = executable_offset;
|
||||
compiler->executable_size = (code_ptr - code) * sizeof(sljit_ins);
|
||||
compiler->executable_size = (sljit_uw)(code_ptr - code) * sizeof(sljit_ins);
|
||||
|
||||
code = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(code, executable_offset);
|
||||
code_ptr = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
|
||||
|
@ -673,7 +684,9 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
|
|||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type)
|
||||
{
|
||||
#if defined(__GNUC__) && !defined(SLJIT_IS_FPU_AVAILABLE)
|
||||
sljit_sw fir = 0;
|
||||
#endif /* __GNUC__ && !SLJIT_IS_FPU_AVAILABLE */
|
||||
|
||||
switch (feature_type) {
|
||||
case SLJIT_HAS_FPU:
|
||||
|
@ -696,7 +709,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type)
|
|||
#endif /* SLJIT_MIPS_REV >= 1 */
|
||||
|
||||
default:
|
||||
return fir;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -723,15 +736,16 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type)
|
|||
#define CUMULATIVE_OP 0x00080
|
||||
#define LOGICAL_OP 0x00100
|
||||
#define IMM_OP 0x00200
|
||||
#define SRC2_IMM 0x00400
|
||||
#define MOVE_OP 0x00400
|
||||
#define SRC2_IMM 0x00800
|
||||
|
||||
#define UNUSED_DEST 0x00800
|
||||
#define REG_DEST 0x01000
|
||||
#define REG1_SOURCE 0x02000
|
||||
#define REG2_SOURCE 0x04000
|
||||
#define SLOW_SRC1 0x08000
|
||||
#define SLOW_SRC2 0x10000
|
||||
#define SLOW_DEST 0x20000
|
||||
#define UNUSED_DEST 0x01000
|
||||
#define REG_DEST 0x02000
|
||||
#define REG1_SOURCE 0x04000
|
||||
#define REG2_SOURCE 0x08000
|
||||
#define SLOW_SRC1 0x10000
|
||||
#define SLOW_SRC2 0x20000
|
||||
#define SLOW_DEST 0x40000
|
||||
|
||||
#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
|
||||
#define STACK_STORE SW
|
||||
|
@ -741,7 +755,8 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type)
|
|||
#define STACK_LOAD LD
|
||||
#endif
|
||||
|
||||
static SLJIT_INLINE sljit_s32 emit_op_mem(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg_ar, sljit_s32 arg, sljit_sw argw);
|
||||
static sljit_s32 emit_op_mem(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg_ar, sljit_s32 arg, sljit_sw argw);
|
||||
static sljit_s32 emit_stack_frame_release(struct sljit_compiler *compiler, sljit_s32 frame_size, sljit_ins *ins_ptr);
|
||||
|
||||
#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
|
||||
#include "sljitNativeMIPS_32.c"
|
||||
|
@ -754,56 +769,178 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compi
|
|||
sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size)
|
||||
{
|
||||
sljit_ins base;
|
||||
sljit_s32 args, i, tmp, offs;
|
||||
sljit_s32 i, tmp, offset;
|
||||
sljit_s32 arg_count, word_arg_count, float_arg_count;
|
||||
|
||||
CHECK_ERROR();
|
||||
CHECK(check_sljit_emit_enter(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size));
|
||||
set_emit_enter(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size);
|
||||
|
||||
local_size += GET_SAVED_REGISTERS_SIZE(scratches, saveds, 1) + SLJIT_LOCALS_OFFSET;
|
||||
local_size += GET_SAVED_REGISTERS_SIZE(scratches, saveds, 1);
|
||||
#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
|
||||
local_size = (local_size + 15) & ~0xf;
|
||||
if (fsaveds > 0 || fscratches >= SLJIT_FIRST_SAVED_FLOAT_REG) {
|
||||
if ((local_size & SSIZE_OF(sw)) != 0)
|
||||
local_size += SSIZE_OF(sw);
|
||||
local_size += GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, sizeof(sljit_f64));
|
||||
}
|
||||
|
||||
local_size = (local_size + SLJIT_LOCALS_OFFSET + 15) & ~0xf;
|
||||
#else
|
||||
local_size = (local_size + 31) & ~0x1f;
|
||||
local_size += GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, sizeof(sljit_f64));
|
||||
local_size = (local_size + SLJIT_LOCALS_OFFSET + 31) & ~0x1f;
|
||||
#endif
|
||||
compiler->local_size = local_size;
|
||||
|
||||
if (local_size <= SIMM_MAX) {
|
||||
#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
|
||||
tmp = arg_types >> SLJIT_ARG_SHIFT;
|
||||
arg_count = 0;
|
||||
offset = 0;
|
||||
|
||||
while (tmp) {
|
||||
offset = arg_count;
|
||||
if ((tmp & SLJIT_ARG_MASK) == SLJIT_ARG_TYPE_F64) {
|
||||
if ((arg_count & 0x1) != 0)
|
||||
arg_count++;
|
||||
arg_count++;
|
||||
}
|
||||
|
||||
arg_count++;
|
||||
tmp >>= SLJIT_ARG_SHIFT;
|
||||
}
|
||||
|
||||
compiler->args_size = (sljit_uw)arg_count << 2;
|
||||
offset = (offset >= 4) ? (offset << 2) : 0;
|
||||
#else /* !SLJIT_CONFIG_MIPS_32 */
|
||||
offset = 0;
|
||||
#endif /* SLJIT_CONFIG_MIPS_32 */
|
||||
|
||||
if (local_size + offset <= -SIMM_MIN) {
|
||||
/* Frequent case. */
|
||||
FAIL_IF(push_inst(compiler, ADDIU_W | S(SLJIT_SP) | T(SLJIT_SP) | IMM(-local_size), DR(SLJIT_SP)));
|
||||
base = S(SLJIT_SP);
|
||||
offs = local_size - (sljit_sw)sizeof(sljit_sw);
|
||||
}
|
||||
else {
|
||||
offset = local_size - SSIZE_OF(sw);
|
||||
} else {
|
||||
FAIL_IF(load_immediate(compiler, DR(OTHER_FLAG), local_size));
|
||||
FAIL_IF(push_inst(compiler, ADDU_W | S(SLJIT_SP) | TA(0) | D(TMP_REG2), DR(TMP_REG2)));
|
||||
FAIL_IF(push_inst(compiler, SUBU_W | S(SLJIT_SP) | T(OTHER_FLAG) | D(SLJIT_SP), DR(SLJIT_SP)));
|
||||
base = S(TMP_REG2);
|
||||
offset = -SSIZE_OF(sw);
|
||||
#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
|
||||
local_size = 0;
|
||||
offs = -(sljit_sw)sizeof(sljit_sw);
|
||||
#endif
|
||||
}
|
||||
|
||||
FAIL_IF(push_inst(compiler, STACK_STORE | base | TA(RETURN_ADDR_REG) | IMM(offs), MOVABLE_INS));
|
||||
FAIL_IF(push_inst(compiler, STACK_STORE | base | TA(RETURN_ADDR_REG) | IMM(offset), MOVABLE_INS));
|
||||
|
||||
tmp = saveds < SLJIT_NUMBER_OF_SAVED_REGISTERS ? (SLJIT_S0 + 1 - saveds) : SLJIT_FIRST_SAVED_REG;
|
||||
for (i = SLJIT_S0; i >= tmp; i--) {
|
||||
offs -= (sljit_s32)(sizeof(sljit_sw));
|
||||
FAIL_IF(push_inst(compiler, STACK_STORE | base | T(i) | IMM(offs), MOVABLE_INS));
|
||||
tmp = SLJIT_S0 - saveds;
|
||||
for (i = SLJIT_S0; i > tmp; i--) {
|
||||
offset -= SSIZE_OF(sw);
|
||||
FAIL_IF(push_inst(compiler, STACK_STORE | base | T(i) | IMM(offset), MOVABLE_INS));
|
||||
}
|
||||
|
||||
for (i = scratches; i >= SLJIT_FIRST_SAVED_REG; i--) {
|
||||
offs -= (sljit_s32)(sizeof(sljit_sw));
|
||||
FAIL_IF(push_inst(compiler, STACK_STORE | base | T(i) | IMM(offs), MOVABLE_INS));
|
||||
offset -= SSIZE_OF(sw);
|
||||
FAIL_IF(push_inst(compiler, STACK_STORE | base | T(i) | IMM(offset), MOVABLE_INS));
|
||||
}
|
||||
|
||||
args = get_arg_count(arg_types);
|
||||
#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
|
||||
/* This alignment is valid because offset is not used after storing FPU regs. */
|
||||
if ((offset & SSIZE_OF(sw)) != 0)
|
||||
offset -= SSIZE_OF(sw);
|
||||
#endif
|
||||
|
||||
if (args >= 1)
|
||||
FAIL_IF(push_inst(compiler, ADDU_W | SA(4) | TA(0) | D(SLJIT_S0), DR(SLJIT_S0)));
|
||||
if (args >= 2)
|
||||
FAIL_IF(push_inst(compiler, ADDU_W | SA(5) | TA(0) | D(SLJIT_S1), DR(SLJIT_S1)));
|
||||
if (args >= 3)
|
||||
FAIL_IF(push_inst(compiler, ADDU_W | SA(6) | TA(0) | D(SLJIT_S2), DR(SLJIT_S2)));
|
||||
tmp = SLJIT_FS0 - fsaveds;
|
||||
for (i = SLJIT_FS0; i > tmp; i--) {
|
||||
offset -= SSIZE_OF(f64);
|
||||
FAIL_IF(push_inst(compiler, SDC1 | base | FT(i) | IMM(offset), MOVABLE_INS));
|
||||
}
|
||||
|
||||
for (i = fscratches; i >= SLJIT_FIRST_SAVED_FLOAT_REG; i--) {
|
||||
offset -= SSIZE_OF(f64);
|
||||
FAIL_IF(push_inst(compiler, SDC1 | base | FT(i) | IMM(offset), MOVABLE_INS));
|
||||
}
|
||||
|
||||
arg_types >>= SLJIT_ARG_SHIFT;
|
||||
arg_count = 0;
|
||||
word_arg_count = 0;
|
||||
float_arg_count = 0;
|
||||
|
||||
#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
|
||||
/* The first maximum two floating point arguments are passed in floating point
|
||||
registers if no integer argument precedes them. The first 16 byte data is
|
||||
passed in four integer registers, the rest is placed onto the stack.
|
||||
The floating point registers are also part of the first 16 byte data, so
|
||||
their corresponding integer registers are not used when they are present. */
|
||||
|
||||
while (arg_types) {
|
||||
switch (arg_types & SLJIT_ARG_MASK) {
|
||||
case SLJIT_ARG_TYPE_F64:
|
||||
float_arg_count++;
|
||||
if ((arg_count & 0x1) != 0)
|
||||
arg_count++;
|
||||
|
||||
if (word_arg_count == 0 && float_arg_count <= 2) {
|
||||
if (float_arg_count == 1)
|
||||
FAIL_IF(push_inst(compiler, MOV_S | FMT_D | FS(TMP_FREG1) | FD(SLJIT_FR0), MOVABLE_INS));
|
||||
} else if (arg_count < 4) {
|
||||
FAIL_IF(push_inst(compiler, MTC1 | TA(4 + arg_count) | FS(float_arg_count), MOVABLE_INS));
|
||||
FAIL_IF(push_inst(compiler, MTC1 | TA(5 + arg_count) | FS(float_arg_count) | (1 << 11), MOVABLE_INS));
|
||||
} else
|
||||
FAIL_IF(push_inst(compiler, LDC1 | base | FT(float_arg_count) | IMM(local_size + (arg_count << 2)), MOVABLE_INS));
|
||||
arg_count++;
|
||||
break;
|
||||
case SLJIT_ARG_TYPE_F32:
|
||||
float_arg_count++;
|
||||
|
||||
if (word_arg_count == 0 && float_arg_count <= 2) {
|
||||
if (float_arg_count == 1)
|
||||
FAIL_IF(push_inst(compiler, MOV_S | FMT_S | FS(TMP_FREG1) | FD(SLJIT_FR0), MOVABLE_INS));
|
||||
} else if (arg_count < 4)
|
||||
FAIL_IF(push_inst(compiler, MTC1 | TA(4 + arg_count) | FS(float_arg_count), MOVABLE_INS));
|
||||
else
|
||||
FAIL_IF(push_inst(compiler, LWC1 | base | FT(float_arg_count) | IMM(local_size + (arg_count << 2)), MOVABLE_INS));
|
||||
break;
|
||||
default:
|
||||
if (arg_count < 4)
|
||||
FAIL_IF(push_inst(compiler, ADDU_W | SA(4 + arg_count) | TA(0) | D(SLJIT_S0 - word_arg_count),
|
||||
DR(SLJIT_S0 - word_arg_count)));
|
||||
else
|
||||
FAIL_IF(push_inst(compiler, LW | base | T(SLJIT_S0 - word_arg_count) | IMM(local_size + (arg_count << 2)),
|
||||
DR(SLJIT_S0 - word_arg_count)));
|
||||
word_arg_count++;
|
||||
break;
|
||||
}
|
||||
arg_count++;
|
||||
arg_types >>= SLJIT_ARG_SHIFT;
|
||||
}
|
||||
|
||||
SLJIT_ASSERT(compiler->args_size == (sljit_uw)arg_count << 2);
|
||||
#else /* !SLJIT_CONFIG_MIPS_32 */
|
||||
while (arg_types) {
|
||||
arg_count++;
|
||||
switch (arg_types & SLJIT_ARG_MASK) {
|
||||
case SLJIT_ARG_TYPE_F64:
|
||||
float_arg_count++;
|
||||
if (arg_count != float_arg_count)
|
||||
FAIL_IF(push_inst(compiler, MOV_S | FMT_D | FS(arg_count) | FD(float_arg_count), MOVABLE_INS));
|
||||
else if (arg_count == 1)
|
||||
FAIL_IF(push_inst(compiler, MOV_S | FMT_D | FS(TMP_FREG1) | FD(SLJIT_FR0), MOVABLE_INS));
|
||||
break;
|
||||
case SLJIT_ARG_TYPE_F32:
|
||||
float_arg_count++;
|
||||
if (arg_count != float_arg_count)
|
||||
FAIL_IF(push_inst(compiler, MOV_S | FMT_S | FS(arg_count) | FD(float_arg_count), MOVABLE_INS));
|
||||
else if (arg_count == 1)
|
||||
FAIL_IF(push_inst(compiler, MOV_S | FMT_S | FS(TMP_FREG1) | FD(SLJIT_FR0), MOVABLE_INS));
|
||||
break;
|
||||
default:
|
||||
FAIL_IF(push_inst(compiler, ADDU_W | SA(3 + arg_count) | TA(0) | D(SLJIT_S0 - word_arg_count), DR(SLJIT_S0 - word_arg_count)));
|
||||
word_arg_count++;
|
||||
break;
|
||||
}
|
||||
arg_types >>= SLJIT_ARG_SHIFT;
|
||||
}
|
||||
#endif /* SLJIT_CONFIG_MIPS_32 */
|
||||
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
@ -816,57 +953,110 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_set_context(struct sljit_compiler *comp
|
|||
CHECK(check_sljit_set_context(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size));
|
||||
set_set_context(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size);
|
||||
|
||||
local_size += GET_SAVED_REGISTERS_SIZE(scratches, saveds, 1) + SLJIT_LOCALS_OFFSET;
|
||||
local_size += GET_SAVED_REGISTERS_SIZE(scratches, saveds, 1);
|
||||
#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
|
||||
compiler->local_size = (local_size + 15) & ~0xf;
|
||||
if (fsaveds > 0 || fscratches >= SLJIT_FIRST_SAVED_FLOAT_REG) {
|
||||
if ((local_size & SSIZE_OF(sw)) != 0)
|
||||
local_size += SSIZE_OF(sw);
|
||||
local_size += GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, sizeof(sljit_f64));
|
||||
}
|
||||
|
||||
compiler->local_size = (local_size + SLJIT_LOCALS_OFFSET + 15) & ~0xf;
|
||||
#else
|
||||
compiler->local_size = (local_size + 31) & ~0x1f;
|
||||
local_size += GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, sizeof(sljit_f64));
|
||||
compiler->local_size = (local_size + SLJIT_LOCALS_OFFSET + 31) & ~0x1f;
|
||||
#endif
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 src, sljit_sw srcw)
|
||||
static sljit_s32 emit_stack_frame_release(struct sljit_compiler *compiler, sljit_s32 frame_size, sljit_ins *ins_ptr)
|
||||
{
|
||||
sljit_s32 local_size, i, tmp, offs;
|
||||
sljit_ins base;
|
||||
|
||||
CHECK_ERROR();
|
||||
CHECK(check_sljit_emit_return(compiler, op, src, srcw));
|
||||
|
||||
FAIL_IF(emit_mov_before_return(compiler, op, src, srcw));
|
||||
sljit_s32 local_size, i, tmp, offset;
|
||||
sljit_s32 scratches = compiler->scratches;
|
||||
sljit_s32 saveds = compiler->saveds;
|
||||
sljit_s32 fsaveds = compiler->fsaveds;
|
||||
sljit_s32 fscratches = compiler->fscratches;
|
||||
|
||||
local_size = compiler->local_size;
|
||||
if (local_size <= SIMM_MAX)
|
||||
base = S(SLJIT_SP);
|
||||
else {
|
||||
FAIL_IF(load_immediate(compiler, DR(TMP_REG1), local_size));
|
||||
FAIL_IF(push_inst(compiler, ADDU_W | S(SLJIT_SP) | T(TMP_REG1) | D(TMP_REG1), DR(TMP_REG1)));
|
||||
base = S(TMP_REG1);
|
||||
local_size = 0;
|
||||
|
||||
tmp = GET_SAVED_REGISTERS_SIZE(scratches, saveds, 1);
|
||||
#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
|
||||
if (fsaveds > 0 || fscratches >= SLJIT_FIRST_SAVED_FLOAT_REG) {
|
||||
if ((tmp & SSIZE_OF(sw)) != 0)
|
||||
tmp += SSIZE_OF(sw);
|
||||
tmp += GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, sizeof(sljit_f64));
|
||||
}
|
||||
#else
|
||||
tmp += GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, sizeof(sljit_f64));
|
||||
#endif
|
||||
|
||||
if (local_size <= SIMM_MAX) {
|
||||
if (local_size < frame_size) {
|
||||
FAIL_IF(push_inst(compiler, ADDIU_W | S(SLJIT_SP) | T(SLJIT_SP) | IMM(local_size - frame_size), DR(SLJIT_SP)));
|
||||
local_size = frame_size;
|
||||
}
|
||||
} else {
|
||||
if (tmp < frame_size)
|
||||
tmp = frame_size;
|
||||
|
||||
FAIL_IF(load_immediate(compiler, DR(TMP_REG1), local_size - tmp));
|
||||
FAIL_IF(push_inst(compiler, ADDU_W | S(SLJIT_SP) | T(TMP_REG1) | D(SLJIT_SP), DR(SLJIT_SP)));
|
||||
local_size = tmp;
|
||||
}
|
||||
|
||||
FAIL_IF(push_inst(compiler, STACK_LOAD | base | TA(RETURN_ADDR_REG) | IMM(local_size - (sljit_s32)sizeof(sljit_sw)), RETURN_ADDR_REG));
|
||||
offs = local_size - (sljit_s32)GET_SAVED_REGISTERS_SIZE(compiler->scratches, compiler->saveds, 1);
|
||||
SLJIT_ASSERT(local_size >= frame_size);
|
||||
|
||||
tmp = compiler->scratches;
|
||||
for (i = SLJIT_FIRST_SAVED_REG; i <= tmp; i++) {
|
||||
FAIL_IF(push_inst(compiler, STACK_LOAD | base | T(i) | IMM(offs), DR(i)));
|
||||
offs += (sljit_s32)(sizeof(sljit_sw));
|
||||
offset = local_size - SSIZE_OF(sw);
|
||||
if (frame_size == 0)
|
||||
FAIL_IF(push_inst(compiler, STACK_LOAD | S(SLJIT_SP) | TA(RETURN_ADDR_REG) | IMM(offset), RETURN_ADDR_REG));
|
||||
|
||||
tmp = SLJIT_S0 - saveds;
|
||||
for (i = SLJIT_S0; i > tmp; i--) {
|
||||
offset -= SSIZE_OF(sw);
|
||||
FAIL_IF(push_inst(compiler, STACK_LOAD | S(SLJIT_SP) | T(i) | IMM(offset), MOVABLE_INS));
|
||||
}
|
||||
|
||||
tmp = compiler->saveds < SLJIT_NUMBER_OF_SAVED_REGISTERS ? (SLJIT_S0 + 1 - compiler->saveds) : SLJIT_FIRST_SAVED_REG;
|
||||
for (i = tmp; i <= SLJIT_S0; i++) {
|
||||
FAIL_IF(push_inst(compiler, STACK_LOAD | base | T(i) | IMM(offs), DR(i)));
|
||||
offs += (sljit_s32)(sizeof(sljit_sw));
|
||||
for (i = scratches; i >= SLJIT_FIRST_SAVED_REG; i--) {
|
||||
offset -= SSIZE_OF(sw);
|
||||
FAIL_IF(push_inst(compiler, STACK_LOAD | S(SLJIT_SP) | T(i) | IMM(offset), MOVABLE_INS));
|
||||
}
|
||||
|
||||
SLJIT_ASSERT(offs == local_size - (sljit_sw)(sizeof(sljit_sw)));
|
||||
#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
|
||||
/* This alignment is valid because offset is not used after storing FPU regs. */
|
||||
if ((offset & SSIZE_OF(sw)) != 0)
|
||||
offset -= SSIZE_OF(sw);
|
||||
#endif
|
||||
|
||||
tmp = SLJIT_FS0 - fsaveds;
|
||||
for (i = SLJIT_FS0; i > tmp; i--) {
|
||||
offset -= SSIZE_OF(f64);
|
||||
FAIL_IF(push_inst(compiler, LDC1 | S(SLJIT_SP) | FT(i) | IMM(offset), MOVABLE_INS));
|
||||
}
|
||||
|
||||
for (i = fscratches; i >= SLJIT_FIRST_SAVED_FLOAT_REG; i--) {
|
||||
offset -= SSIZE_OF(f64);
|
||||
FAIL_IF(push_inst(compiler, LDC1 | S(SLJIT_SP) | FT(i) | IMM(offset), MOVABLE_INS));
|
||||
}
|
||||
|
||||
if (local_size > frame_size)
|
||||
*ins_ptr = ADDIU_W | S(SLJIT_SP) | T(SLJIT_SP) | IMM(local_size - frame_size);
|
||||
else
|
||||
*ins_ptr = NOP;
|
||||
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return_void(struct sljit_compiler *compiler)
|
||||
{
|
||||
sljit_ins ins;
|
||||
|
||||
CHECK_ERROR();
|
||||
CHECK(check_sljit_emit_return_void(compiler));
|
||||
|
||||
emit_stack_frame_release(compiler, 0, &ins);
|
||||
|
||||
FAIL_IF(push_inst(compiler, JR | SA(RETURN_ADDR_REG), UNMOVABLE_INS));
|
||||
if (compiler->local_size <= SIMM_MAX)
|
||||
return push_inst(compiler, ADDIU_W | S(SLJIT_SP) | T(SLJIT_SP) | IMM(compiler->local_size), UNMOVABLE_INS);
|
||||
else
|
||||
return push_inst(compiler, ADDU_W | S(TMP_REG1) | TA(0) | D(SLJIT_SP), UNMOVABLE_INS);
|
||||
return push_inst(compiler, ins, UNMOVABLE_INS);
|
||||
}
|
||||
|
||||
#undef STACK_STORE
|
||||
|
@ -1041,7 +1231,7 @@ static sljit_s32 getput_arg(struct sljit_compiler *compiler, sljit_s32 flags, sl
|
|||
return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | SA(tmp_ar) | TA(reg_ar), delay_slot);
|
||||
}
|
||||
|
||||
static SLJIT_INLINE sljit_s32 emit_op_mem(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg_ar, sljit_s32 arg, sljit_sw argw)
|
||||
static sljit_s32 emit_op_mem(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg_ar, sljit_s32 arg, sljit_sw argw)
|
||||
{
|
||||
sljit_s32 tmp_ar, base, delay_slot;
|
||||
|
||||
|
@ -1104,14 +1294,14 @@ static sljit_s32 emit_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s3
|
|||
compiler->cache_argw = 0;
|
||||
}
|
||||
|
||||
if (SLJIT_UNLIKELY(dst == SLJIT_UNUSED)) {
|
||||
if (dst == TMP_REG2) {
|
||||
SLJIT_ASSERT(HAS_FLAGS(op));
|
||||
flags |= UNUSED_DEST;
|
||||
}
|
||||
else if (FAST_IS_REG(dst)) {
|
||||
dst_r = dst;
|
||||
flags |= REG_DEST;
|
||||
if (op >= SLJIT_MOV && op <= SLJIT_MOV_P)
|
||||
if (flags & MOVE_OP)
|
||||
sugg_src2_r = dst_r;
|
||||
}
|
||||
else if ((dst & SLJIT_MEM) && !getput_arg_fast(compiler, flags | ARG_TEST, DR(TMP_REG1), dst, dstw))
|
||||
|
@ -1165,8 +1355,8 @@ static sljit_s32 emit_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s3
|
|||
if (FAST_IS_REG(src2)) {
|
||||
src2_r = src2;
|
||||
flags |= REG2_SOURCE;
|
||||
if (!(flags & REG_DEST) && op >= SLJIT_MOV && op <= SLJIT_MOV_P)
|
||||
dst_r = src2_r;
|
||||
if ((flags & (REG_DEST | MOVE_OP)) == MOVE_OP)
|
||||
dst_r = (sljit_s32)src2_r;
|
||||
}
|
||||
else if (src2 & SLJIT_IMM) {
|
||||
if (!(flags & SRC2_IMM)) {
|
||||
|
@ -1176,8 +1366,12 @@ static sljit_s32 emit_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s3
|
|||
}
|
||||
else {
|
||||
src2_r = 0;
|
||||
if ((op >= SLJIT_MOV && op <= SLJIT_MOV_P) && (dst & SLJIT_MEM))
|
||||
dst_r = 0;
|
||||
if (flags & MOVE_OP) {
|
||||
if (dst & SLJIT_MEM)
|
||||
dst_r = 0;
|
||||
else
|
||||
op = SLJIT_MOV;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1221,7 +1415,7 @@ static sljit_s32 emit_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s3
|
|||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compiler, sljit_s32 op)
|
||||
{
|
||||
#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
|
||||
sljit_s32 int_op = op & SLJIT_I32_OP;
|
||||
sljit_s32 int_op = op & SLJIT_32;
|
||||
#endif
|
||||
|
||||
CHECK_ERROR();
|
||||
|
@ -1326,11 +1520,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compile
|
|||
sljit_s32 dst, sljit_sw dstw,
|
||||
sljit_s32 src, sljit_sw srcw)
|
||||
{
|
||||
#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
|
||||
# define flags 0
|
||||
#else
|
||||
sljit_s32 flags = 0;
|
||||
#endif
|
||||
|
||||
CHECK_ERROR();
|
||||
CHECK(check_sljit_emit_op1(compiler, op, dst, dstw, src, srcw));
|
||||
|
@ -1338,40 +1528,40 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compile
|
|||
ADJUST_LOCAL_OFFSET(src, srcw);
|
||||
|
||||
#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
|
||||
if ((op & SLJIT_I32_OP) && GET_OPCODE(op) >= SLJIT_NOT)
|
||||
flags |= INT_DATA | SIGNED_DATA;
|
||||
if (op & SLJIT_32)
|
||||
flags = INT_DATA | SIGNED_DATA;
|
||||
#endif
|
||||
|
||||
switch (GET_OPCODE(op)) {
|
||||
case SLJIT_MOV:
|
||||
case SLJIT_MOV_P:
|
||||
return emit_op(compiler, SLJIT_MOV, WORD_DATA, dst, dstw, TMP_REG1, 0, src, srcw);
|
||||
|
||||
case SLJIT_MOV_U32:
|
||||
#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
|
||||
return emit_op(compiler, SLJIT_MOV_U32, INT_DATA, dst, dstw, TMP_REG1, 0, src, srcw);
|
||||
#else
|
||||
return emit_op(compiler, SLJIT_MOV_U32, INT_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_u32)srcw : srcw);
|
||||
case SLJIT_MOV_U32:
|
||||
case SLJIT_MOV_S32:
|
||||
case SLJIT_MOV32:
|
||||
#endif
|
||||
case SLJIT_MOV_P:
|
||||
return emit_op(compiler, SLJIT_MOV, WORD_DATA | MOVE_OP, dst, dstw, TMP_REG1, 0, src, srcw);
|
||||
|
||||
#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
|
||||
case SLJIT_MOV_U32:
|
||||
return emit_op(compiler, SLJIT_MOV_U32, INT_DATA | MOVE_OP, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_u32)srcw : srcw);
|
||||
|
||||
case SLJIT_MOV_S32:
|
||||
#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
|
||||
return emit_op(compiler, SLJIT_MOV_S32, INT_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, srcw);
|
||||
#else
|
||||
return emit_op(compiler, SLJIT_MOV_S32, INT_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_s32)srcw : srcw);
|
||||
case SLJIT_MOV32:
|
||||
return emit_op(compiler, SLJIT_MOV_S32, INT_DATA | SIGNED_DATA | MOVE_OP, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_s32)srcw : srcw);
|
||||
#endif
|
||||
|
||||
case SLJIT_MOV_U8:
|
||||
return emit_op(compiler, SLJIT_MOV_U8, BYTE_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_u8)srcw : srcw);
|
||||
return emit_op(compiler, op, BYTE_DATA | MOVE_OP, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_u8)srcw : srcw);
|
||||
|
||||
case SLJIT_MOV_S8:
|
||||
return emit_op(compiler, SLJIT_MOV_S8, BYTE_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_s8)srcw : srcw);
|
||||
return emit_op(compiler, op, BYTE_DATA | SIGNED_DATA | MOVE_OP, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_s8)srcw : srcw);
|
||||
|
||||
case SLJIT_MOV_U16:
|
||||
return emit_op(compiler, SLJIT_MOV_U16, HALF_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_u16)srcw : srcw);
|
||||
return emit_op(compiler, op, HALF_DATA | MOVE_OP, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_u16)srcw : srcw);
|
||||
|
||||
case SLJIT_MOV_S16:
|
||||
return emit_op(compiler, SLJIT_MOV_S16, HALF_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_s16)srcw : srcw);
|
||||
return emit_op(compiler, op, HALF_DATA | SIGNED_DATA | MOVE_OP, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_s16)srcw : srcw);
|
||||
|
||||
case SLJIT_NOT:
|
||||
return emit_op(compiler, op, flags, dst, dstw, TMP_REG1, 0, src, srcw);
|
||||
|
@ -1386,10 +1576,6 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compile
|
|||
|
||||
SLJIT_UNREACHABLE();
|
||||
return SLJIT_SUCCESS;
|
||||
|
||||
#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
|
||||
# undef flags
|
||||
#endif
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compiler, sljit_s32 op,
|
||||
|
@ -1397,23 +1583,16 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compile
|
|||
sljit_s32 src1, sljit_sw src1w,
|
||||
sljit_s32 src2, sljit_sw src2w)
|
||||
{
|
||||
#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
|
||||
# define flags 0
|
||||
#else
|
||||
sljit_s32 flags = 0;
|
||||
#endif
|
||||
|
||||
CHECK_ERROR();
|
||||
CHECK(check_sljit_emit_op2(compiler, op, dst, dstw, src1, src1w, src2, src2w));
|
||||
CHECK(check_sljit_emit_op2(compiler, op, 0, dst, dstw, src1, src1w, src2, src2w));
|
||||
ADJUST_LOCAL_OFFSET(dst, dstw);
|
||||
ADJUST_LOCAL_OFFSET(src1, src1w);
|
||||
ADJUST_LOCAL_OFFSET(src2, src2w);
|
||||
|
||||
if (dst == SLJIT_UNUSED && !HAS_FLAGS(op))
|
||||
return SLJIT_SUCCESS;
|
||||
|
||||
#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
|
||||
if (op & SLJIT_I32_OP) {
|
||||
if (op & SLJIT_32) {
|
||||
flags |= INT_DATA | SIGNED_DATA;
|
||||
if (src1 & SLJIT_IMM)
|
||||
src1w = (sljit_s32)src1w;
|
||||
|
@ -1450,7 +1629,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compile
|
|||
src2w &= 0x1f;
|
||||
#else
|
||||
if (src2 & SLJIT_IMM) {
|
||||
if (op & SLJIT_I32_OP)
|
||||
if (op & SLJIT_32)
|
||||
src2w &= 0x1f;
|
||||
else
|
||||
src2w &= 0x3f;
|
||||
|
@ -1461,10 +1640,20 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compile
|
|||
|
||||
SLJIT_UNREACHABLE();
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
|
||||
# undef flags
|
||||
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)
|
||||
{
|
||||
CHECK_ERROR();
|
||||
CHECK(check_sljit_emit_op2(compiler, op, 1, 0, 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_op2(compiler, op, TMP_REG2, 0, src1, src1w, src2, src2w);
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_src(struct sljit_compiler *compiler, sljit_s32 op,
|
||||
|
@ -1512,7 +1701,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_float_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)
|
||||
{
|
||||
CHECK_ERROR();
|
||||
CHECK(check_sljit_emit_op_custom(compiler, instruction, size));
|
||||
|
@ -1524,17 +1713,17 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_custom(struct sljit_compiler *c
|
|||
/* Floating point operators */
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
#define FLOAT_DATA(op) (DOUBLE_DATA | ((op & SLJIT_F32_OP) >> 7))
|
||||
#define FMT(op) (((op & SLJIT_F32_OP) ^ SLJIT_F32_OP) << (21 - 8))
|
||||
#define FLOAT_DATA(op) (DOUBLE_DATA | ((op & SLJIT_32) >> 7))
|
||||
#define FMT(op) ((((sljit_ins)op & SLJIT_32) ^ SLJIT_32) << (21 - 8))
|
||||
|
||||
static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_sw_from_f64(struct sljit_compiler *compiler, sljit_s32 op,
|
||||
sljit_s32 dst, sljit_sw dstw,
|
||||
sljit_s32 src, sljit_sw srcw)
|
||||
{
|
||||
#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
|
||||
# define flags 0
|
||||
# define flags (sljit_u32)0
|
||||
#else
|
||||
sljit_s32 flags = (GET_OPCODE(op) == SLJIT_CONV_SW_FROM_F64) << 21;
|
||||
sljit_u32 flags = (GET_OPCODE(op) == SLJIT_CONV_SW_FROM_F64) << 21;
|
||||
#endif
|
||||
|
||||
if (src & SLJIT_MEM) {
|
||||
|
@ -1560,9 +1749,9 @@ static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_f64_from_sw(struct sljit_comp
|
|||
sljit_s32 src, sljit_sw srcw)
|
||||
{
|
||||
#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
|
||||
# define flags 0
|
||||
# define flags (sljit_u32)0
|
||||
#else
|
||||
sljit_s32 flags = (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_SW) << 21;
|
||||
sljit_u32 flags = (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_SW) << 21;
|
||||
#endif
|
||||
|
||||
sljit_s32 dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1;
|
||||
|
@ -1582,7 +1771,7 @@ static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_f64_from_sw(struct sljit_comp
|
|||
FAIL_IF(push_inst(compiler, MTC1 | flags | T(TMP_REG1) | FS(TMP_FREG1), MOVABLE_INS));
|
||||
}
|
||||
|
||||
FAIL_IF(push_inst(compiler, CVT_S_S | flags | (4 << 21) | (((op & SLJIT_F32_OP) ^ SLJIT_F32_OP) >> 8) | FS(TMP_FREG1) | FD(dst_r), MOVABLE_INS));
|
||||
FAIL_IF(push_inst(compiler, CVT_S_S | flags | (4 << 21) | ((((sljit_ins)op & SLJIT_32) ^ SLJIT_32) >> 8) | FS(TMP_FREG1) | FD(dst_r), MOVABLE_INS));
|
||||
|
||||
if (dst & SLJIT_MEM)
|
||||
return emit_op_mem2(compiler, FLOAT_DATA(op), FR(TMP_FREG1), dst, dstw, 0, 0);
|
||||
|
@ -1640,11 +1829,11 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop1(struct sljit_compiler *compil
|
|||
compiler->cache_arg = 0;
|
||||
compiler->cache_argw = 0;
|
||||
|
||||
SLJIT_COMPILE_ASSERT((SLJIT_F32_OP == 0x100) && !(DOUBLE_DATA & 0x2), float_transfer_bit_error);
|
||||
SLJIT_COMPILE_ASSERT((SLJIT_32 == 0x100) && !(DOUBLE_DATA & 0x2), float_transfer_bit_error);
|
||||
SELECT_FOP1_OPERATION_WITH_CHECKS(compiler, op, dst, dstw, src, srcw);
|
||||
|
||||
if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_F32)
|
||||
op ^= SLJIT_F32_OP;
|
||||
op ^= SLJIT_32;
|
||||
|
||||
dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1;
|
||||
|
||||
|
@ -1669,8 +1858,8 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop1(struct sljit_compiler *compil
|
|||
FAIL_IF(push_inst(compiler, ABS_S | FMT(op) | FS(src) | FD(dst_r), MOVABLE_INS));
|
||||
break;
|
||||
case SLJIT_CONV_F64_FROM_F32:
|
||||
FAIL_IF(push_inst(compiler, CVT_S_S | ((op & SLJIT_F32_OP) ? 1 : (1 << 21)) | FS(src) | FD(dst_r), MOVABLE_INS));
|
||||
op ^= SLJIT_F32_OP;
|
||||
FAIL_IF(push_inst(compiler, CVT_S_S | (sljit_ins)((op & SLJIT_32) ? 1 : (1 << 21)) | FS(src) | FD(dst_r), MOVABLE_INS));
|
||||
op ^= SLJIT_32;
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -1841,7 +2030,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compile
|
|||
{
|
||||
struct sljit_jump *jump;
|
||||
sljit_ins inst;
|
||||
sljit_s32 flags = 0;
|
||||
sljit_u32 flags = 0;
|
||||
sljit_s32 delay_check = UNMOVABLE_INS;
|
||||
|
||||
CHECK_ERROR_PTR();
|
||||
|
@ -1947,7 +2136,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_cmp(struct sljit_compiler
|
|||
|
||||
compiler->cache_arg = 0;
|
||||
compiler->cache_argw = 0;
|
||||
flags = ((type & SLJIT_I32_OP) ? INT_DATA : WORD_DATA) | LOAD_DATA;
|
||||
flags = ((type & SLJIT_32) ? INT_DATA : WORD_DATA) | LOAD_DATA;
|
||||
if (src1 & SLJIT_MEM) {
|
||||
PTR_FAIL_IF(emit_op_mem2(compiler, flags, DR(TMP_REG1), src1, src1w, src2, src2w));
|
||||
src1 = TMP_REG1;
|
||||
|
@ -2074,7 +2263,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_ijump(struct sljit_compiler *compi
|
|||
jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
|
||||
FAIL_IF(!jump);
|
||||
set_jump(jump, compiler, JUMP_ADDR | ((type >= SLJIT_FAST_CALL) ? IS_JAL : 0));
|
||||
jump->u.target = srcw;
|
||||
jump->u.target = (sljit_uw)srcw;
|
||||
|
||||
if (compiler->delay_slot != UNMOVABLE_INS)
|
||||
jump->flags |= IS_MOVABLE;
|
||||
|
@ -2103,7 +2292,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_flags(struct sljit_compiler *co
|
|||
#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
|
||||
sljit_s32 mem_type = WORD_DATA;
|
||||
#else
|
||||
sljit_s32 mem_type = (op & SLJIT_I32_OP) ? (INT_DATA | SIGNED_DATA) : WORD_DATA;
|
||||
sljit_s32 mem_type = ((op & SLJIT_32) || op == SLJIT_MOV32) ? (INT_DATA | SIGNED_DATA) : WORD_DATA;
|
||||
#endif
|
||||
|
||||
CHECK_ERROR();
|
||||
|
@ -2111,10 +2300,6 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_flags(struct sljit_compiler *co
|
|||
ADJUST_LOCAL_OFFSET(dst, dstw);
|
||||
|
||||
op = GET_OPCODE(op);
|
||||
#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
|
||||
if (op == SLJIT_MOV_S32)
|
||||
mem_type = INT_DATA | SIGNED_DATA;
|
||||
#endif
|
||||
dst_ar = DR((op < SLJIT_ADD && FAST_IS_REG(dst)) ? dst : TMP_REG2);
|
||||
|
||||
compiler->cache_arg = 0;
|
||||
|
@ -2142,6 +2327,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_flags(struct sljit_compiler *co
|
|||
case SLJIT_GREATER_F64:
|
||||
case SLJIT_LESS_EQUAL_F64:
|
||||
type ^= 0x1; /* Flip type bit for the XORI below. */
|
||||
/* fallthrough */
|
||||
case SLJIT_EQUAL_F64:
|
||||
case SLJIT_NOT_EQUAL_F64:
|
||||
case SLJIT_LESS_F64:
|
||||
|
@ -2203,7 +2389,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_cmov(struct sljit_compiler *compil
|
|||
|
||||
if (SLJIT_UNLIKELY(src & SLJIT_IMM)) {
|
||||
#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
|
||||
if (dst_reg & SLJIT_I32_OP)
|
||||
if (dst_reg & SLJIT_32)
|
||||
srcw = (sljit_s32)srcw;
|
||||
#endif
|
||||
FAIL_IF(load_immediate(compiler, DR(TMP_REG1), srcw));
|
||||
|
@ -2211,7 +2397,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_cmov(struct sljit_compiler *compil
|
|||
srcw = 0;
|
||||
}
|
||||
|
||||
dst_reg &= ~SLJIT_I32_OP;
|
||||
dst_reg &= ~SLJIT_32;
|
||||
|
||||
switch (type & 0xff) {
|
||||
case SLJIT_EQUAL:
|
||||
|
@ -2298,7 +2484,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_put_label* sljit_emit_put_label(struct slj
|
|||
#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
|
||||
PTR_FAIL_IF(emit_const(compiler, dst_r, 0));
|
||||
#else
|
||||
PTR_FAIL_IF(push_inst(compiler, dst_r, UNMOVABLE_INS));
|
||||
PTR_FAIL_IF(push_inst(compiler, (sljit_ins)dst_r, UNMOVABLE_INS));
|
||||
compiler->size += 5;
|
||||
#endif
|
||||
|
||||
|
|
|
@ -277,5 +277,5 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_ta
|
|||
|
||||
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant, sljit_sw executable_offset)
|
||||
{
|
||||
sljit_set_jump_addr(addr, new_constant, executable_offset);
|
||||
sljit_set_jump_addr(addr, (sljit_uw)new_constant, executable_offset);
|
||||
}
|
||||
|
|
|
@ -57,20 +57,20 @@ static sljit_s32 load_immediate(struct sljit_compiler *compiler, sljit_s32 reg,
|
|||
}
|
||||
|
||||
/* Count leading zeroes. */
|
||||
tmp = (imm >= 0) ? imm : ~imm;
|
||||
tmp = (sljit_uw)((imm >= 0) ? imm : ~imm);
|
||||
ASM_SLJIT_CLZ(tmp, shift);
|
||||
SLJIT_ASSERT(shift > 0);
|
||||
shift--;
|
||||
tmp = (imm << shift);
|
||||
tmp = ((sljit_uw)imm << shift);
|
||||
|
||||
if ((tmp & ~0xffff000000000000ul) == 0) {
|
||||
FAIL_IF(push_inst(compiler, ADDI | D(reg) | A(0) | IMM(tmp >> 48)));
|
||||
FAIL_IF(push_inst(compiler, ADDI | D(reg) | A(0) | (sljit_ins)(tmp >> 48)));
|
||||
shift += 15;
|
||||
return PUSH_RLDICR(reg, shift);
|
||||
}
|
||||
|
||||
if ((tmp & ~0xffffffff00000000ul) == 0) {
|
||||
FAIL_IF(push_inst(compiler, ADDIS | D(reg) | A(0) | IMM(tmp >> 48)));
|
||||
FAIL_IF(push_inst(compiler, ADDIS | D(reg) | A(0) | (sljit_ins)(tmp >> 48)));
|
||||
FAIL_IF(push_inst(compiler, ORI | S(reg) | A(reg) | IMM(tmp >> 32)));
|
||||
shift += 31;
|
||||
return PUSH_RLDICR(reg, shift);
|
||||
|
@ -78,18 +78,18 @@ static sljit_s32 load_immediate(struct sljit_compiler *compiler, sljit_s32 reg,
|
|||
|
||||
/* Cut out the 16 bit from immediate. */
|
||||
shift += 15;
|
||||
tmp2 = imm & ((1ul << (63 - shift)) - 1);
|
||||
tmp2 = (sljit_uw)imm & (((sljit_uw)1 << (63 - shift)) - 1);
|
||||
|
||||
if (tmp2 <= 0xffff) {
|
||||
FAIL_IF(push_inst(compiler, ADDI | D(reg) | A(0) | IMM(tmp >> 48)));
|
||||
FAIL_IF(push_inst(compiler, ADDI | D(reg) | A(0) | (sljit_ins)(tmp >> 48)));
|
||||
FAIL_IF(PUSH_RLDICR(reg, shift));
|
||||
return push_inst(compiler, ORI | S(reg) | A(reg) | tmp2);
|
||||
return push_inst(compiler, ORI | S(reg) | A(reg) | (sljit_ins)tmp2);
|
||||
}
|
||||
|
||||
if (tmp2 <= 0xffffffff) {
|
||||
FAIL_IF(push_inst(compiler, ADDI | D(reg) | A(0) | IMM(tmp >> 48)));
|
||||
FAIL_IF(PUSH_RLDICR(reg, shift));
|
||||
FAIL_IF(push_inst(compiler, ORIS | S(reg) | A(reg) | (tmp2 >> 16)));
|
||||
FAIL_IF(push_inst(compiler, ORIS | S(reg) | A(reg) | (sljit_ins)(tmp2 >> 16)));
|
||||
return (imm & 0xffff) ? push_inst(compiler, ORI | S(reg) | A(reg) | IMM(tmp2)) : SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -97,16 +97,16 @@ static sljit_s32 load_immediate(struct sljit_compiler *compiler, sljit_s32 reg,
|
|||
tmp2 <<= shift2;
|
||||
|
||||
if ((tmp2 & ~0xffff000000000000ul) == 0) {
|
||||
FAIL_IF(push_inst(compiler, ADDI | D(reg) | A(0) | IMM(tmp >> 48)));
|
||||
FAIL_IF(push_inst(compiler, ADDI | D(reg) | A(0) | (sljit_ins)(tmp >> 48)));
|
||||
shift2 += 15;
|
||||
shift += (63 - shift2);
|
||||
FAIL_IF(PUSH_RLDICR(reg, shift));
|
||||
FAIL_IF(push_inst(compiler, ORI | S(reg) | A(reg) | (tmp2 >> 48)));
|
||||
FAIL_IF(push_inst(compiler, ORI | S(reg) | A(reg) | (sljit_ins)(tmp2 >> 48)));
|
||||
return PUSH_RLDICR(reg, shift2);
|
||||
}
|
||||
|
||||
/* The general version. */
|
||||
FAIL_IF(push_inst(compiler, ADDIS | D(reg) | A(0) | IMM(imm >> 48)));
|
||||
FAIL_IF(push_inst(compiler, ADDIS | D(reg) | A(0) | (sljit_ins)((sljit_uw)imm >> 48)));
|
||||
FAIL_IF(push_inst(compiler, ORI | S(reg) | A(reg) | IMM(imm >> 32)));
|
||||
FAIL_IF(PUSH_RLDICR(reg, 31));
|
||||
FAIL_IF(push_inst(compiler, ORIS | S(reg) | A(reg) | IMM(imm >> 16)));
|
||||
|
@ -432,14 +432,14 @@ static sljit_s32 call_with_args(struct sljit_compiler *compiler, sljit_s32 arg_t
|
|||
if (src)
|
||||
reg = *src & REG_MASK;
|
||||
|
||||
arg_types >>= SLJIT_DEF_SHIFT;
|
||||
arg_types >>= SLJIT_ARG_SHIFT;
|
||||
|
||||
while (arg_types) {
|
||||
types = (types << SLJIT_DEF_SHIFT) | (arg_types & SLJIT_DEF_MASK);
|
||||
types = (types << SLJIT_ARG_SHIFT) | (arg_types & SLJIT_ARG_MASK);
|
||||
|
||||
switch (arg_types & SLJIT_DEF_MASK) {
|
||||
case SLJIT_ARG_TYPE_F32:
|
||||
switch (arg_types & SLJIT_ARG_MASK) {
|
||||
case SLJIT_ARG_TYPE_F64:
|
||||
case SLJIT_ARG_TYPE_F32:
|
||||
arg_count++;
|
||||
break;
|
||||
default:
|
||||
|
@ -453,13 +453,13 @@ static sljit_s32 call_with_args(struct sljit_compiler *compiler, sljit_s32 arg_t
|
|||
break;
|
||||
}
|
||||
|
||||
arg_types >>= SLJIT_DEF_SHIFT;
|
||||
arg_types >>= SLJIT_ARG_SHIFT;
|
||||
}
|
||||
|
||||
while (types) {
|
||||
switch (types & SLJIT_DEF_MASK) {
|
||||
case SLJIT_ARG_TYPE_F32:
|
||||
switch (types & SLJIT_ARG_MASK) {
|
||||
case SLJIT_ARG_TYPE_F64:
|
||||
case SLJIT_ARG_TYPE_F32:
|
||||
arg_count--;
|
||||
break;
|
||||
default:
|
||||
|
@ -471,7 +471,7 @@ static sljit_s32 call_with_args(struct sljit_compiler *compiler, sljit_s32 arg_t
|
|||
break;
|
||||
}
|
||||
|
||||
types >>= SLJIT_DEF_SHIFT;
|
||||
types >>= SLJIT_ARG_SHIFT;
|
||||
}
|
||||
|
||||
return SLJIT_SUCCESS;
|
||||
|
@ -492,10 +492,10 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_ta
|
|||
SLJIT_UNUSED_ARG(executable_offset);
|
||||
|
||||
SLJIT_UPDATE_WX_FLAGS(inst, inst + 5, 0);
|
||||
inst[0] = (inst[0] & 0xffff0000) | ((new_target >> 48) & 0xffff);
|
||||
inst[1] = (inst[1] & 0xffff0000) | ((new_target >> 32) & 0xffff);
|
||||
inst[3] = (inst[3] & 0xffff0000) | ((new_target >> 16) & 0xffff);
|
||||
inst[4] = (inst[4] & 0xffff0000) | (new_target & 0xffff);
|
||||
inst[0] = (inst[0] & 0xffff0000u) | ((sljit_ins)(new_target >> 48) & 0xffff);
|
||||
inst[1] = (inst[1] & 0xffff0000u) | ((sljit_ins)(new_target >> 32) & 0xffff);
|
||||
inst[3] = (inst[3] & 0xffff0000u) | ((sljit_ins)(new_target >> 16) & 0xffff);
|
||||
inst[4] = (inst[4] & 0xffff0000u) | ((sljit_ins)new_target & 0xffff);
|
||||
SLJIT_UPDATE_WX_FLAGS(inst, inst + 5, 1);
|
||||
inst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
|
||||
SLJIT_CACHE_FLUSH(inst, inst + 5);
|
||||
|
@ -503,5 +503,5 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_ta
|
|||
|
||||
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant, sljit_sw executable_offset)
|
||||
{
|
||||
sljit_set_jump_addr(addr, new_constant, executable_offset);
|
||||
sljit_set_jump_addr(addr, (sljit_uw)new_constant, executable_offset);
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -35,16 +35,13 @@ static sljit_s32 load_immediate(struct sljit_compiler *compiler, sljit_s32 dst,
|
|||
|
||||
#define ARG2(flags, src2) ((flags & SRC2_IMM) ? IMM(src2) : S2(src2))
|
||||
|
||||
static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 flags,
|
||||
static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_u32 flags,
|
||||
sljit_s32 dst, sljit_s32 src1, sljit_sw src2)
|
||||
{
|
||||
SLJIT_COMPILE_ASSERT(ICC_IS_SET == SET_FLAGS, icc_is_set_and_set_flags_must_be_the_same);
|
||||
|
||||
switch (op) {
|
||||
case SLJIT_MOV:
|
||||
case SLJIT_MOV_U32:
|
||||
case SLJIT_MOV_S32:
|
||||
case SLJIT_MOV_P:
|
||||
SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
|
||||
if (dst != src2)
|
||||
return push_inst(compiler, OR | D(dst) | S1(0) | S2(src2), DR(dst));
|
||||
|
@ -59,8 +56,7 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl
|
|||
FAIL_IF(push_inst(compiler, SLL | D(dst) | S1(src2) | IMM(24), DR(dst)));
|
||||
return push_inst(compiler, SRA | D(dst) | S1(dst) | IMM(24), DR(dst));
|
||||
}
|
||||
else if (dst != src2)
|
||||
SLJIT_UNREACHABLE();
|
||||
SLJIT_ASSERT(dst == src2);
|
||||
return SLJIT_SUCCESS;
|
||||
|
||||
case SLJIT_MOV_U16:
|
||||
|
@ -70,13 +66,12 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl
|
|||
FAIL_IF(push_inst(compiler, SLL | D(dst) | S1(src2) | IMM(16), DR(dst)));
|
||||
return push_inst(compiler, (op == SLJIT_MOV_S16 ? SRA : SRL) | D(dst) | S1(dst) | IMM(16), DR(dst));
|
||||
}
|
||||
else if (dst != src2)
|
||||
SLJIT_UNREACHABLE();
|
||||
SLJIT_ASSERT(dst == src2);
|
||||
return SLJIT_SUCCESS;
|
||||
|
||||
case SLJIT_NOT:
|
||||
SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
|
||||
return push_inst(compiler, XNOR | (flags & SET_FLAGS) | D(dst) | S1(0) | S2(src2), DR(dst) | (flags & SET_FLAGS));
|
||||
return push_inst(compiler, XNOR | (flags & SET_FLAGS) | D(dst) | S1(0) | S2(src2), DRF(dst, flags));
|
||||
|
||||
case SLJIT_CLZ:
|
||||
SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
|
||||
|
@ -89,22 +84,22 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl
|
|||
/* Loop. */
|
||||
FAIL_IF(push_inst(compiler, SUB | SET_FLAGS | D(0) | S1(TMP_REG1) | S2(0), SET_FLAGS));
|
||||
FAIL_IF(push_inst(compiler, SLL | D(TMP_REG1) | S1(TMP_REG1) | IMM(1), DR(TMP_REG1)));
|
||||
FAIL_IF(push_inst(compiler, BICC | DA(0xe) | (-2 & DISP_MASK), UNMOVABLE_INS));
|
||||
FAIL_IF(push_inst(compiler, BICC | DA(0xe) | ((sljit_ins)-2 & DISP_MASK), UNMOVABLE_INS));
|
||||
return push_inst(compiler, ADD | D(dst) | S1(dst) | IMM(1), UNMOVABLE_INS);
|
||||
|
||||
case SLJIT_ADD:
|
||||
compiler->status_flags_state = SLJIT_CURRENT_FLAGS_ADD_SUB;
|
||||
return push_inst(compiler, ADD | (flags & SET_FLAGS) | D(dst) | S1(src1) | ARG2(flags, src2), DR(dst) | (flags & SET_FLAGS));
|
||||
return push_inst(compiler, ADD | (flags & SET_FLAGS) | D(dst) | S1(src1) | ARG2(flags, src2), DRF(dst, flags));
|
||||
|
||||
case SLJIT_ADDC:
|
||||
return push_inst(compiler, ADDC | (flags & SET_FLAGS) | D(dst) | S1(src1) | ARG2(flags, src2), DR(dst) | (flags & SET_FLAGS));
|
||||
return push_inst(compiler, ADDC | (flags & SET_FLAGS) | D(dst) | S1(src1) | ARG2(flags, src2), DRF(dst, flags));
|
||||
|
||||
case SLJIT_SUB:
|
||||
compiler->status_flags_state = SLJIT_CURRENT_FLAGS_ADD_SUB;
|
||||
return push_inst(compiler, SUB | (flags & SET_FLAGS) | D(dst) | S1(src1) | ARG2(flags, src2), DR(dst) | (flags & SET_FLAGS));
|
||||
return push_inst(compiler, SUB | (flags & SET_FLAGS) | D(dst) | S1(src1) | ARG2(flags, src2), DRF(dst, flags));
|
||||
|
||||
case SLJIT_SUBC:
|
||||
return push_inst(compiler, SUBC | (flags & SET_FLAGS) | D(dst) | S1(src1) | ARG2(flags, src2), DR(dst) | (flags & SET_FLAGS));
|
||||
return push_inst(compiler, SUBC | (flags & SET_FLAGS) | D(dst) | S1(src1) | ARG2(flags, src2), DRF(dst, flags));
|
||||
|
||||
case SLJIT_MUL:
|
||||
compiler->status_flags_state = 0;
|
||||
|
@ -116,13 +111,13 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl
|
|||
return push_inst(compiler, SUB | SET_FLAGS | D(0) | S1(TMP_REG1) | S2(TMP_LINK), MOVABLE_INS | SET_FLAGS);
|
||||
|
||||
case SLJIT_AND:
|
||||
return push_inst(compiler, AND | (flags & SET_FLAGS) | D(dst) | S1(src1) | ARG2(flags, src2), DR(dst) | (flags & SET_FLAGS));
|
||||
return push_inst(compiler, AND | (flags & SET_FLAGS) | D(dst) | S1(src1) | ARG2(flags, src2), DRF(dst, flags));
|
||||
|
||||
case SLJIT_OR:
|
||||
return push_inst(compiler, OR | (flags & SET_FLAGS) | D(dst) | S1(src1) | ARG2(flags, src2), DR(dst) | (flags & SET_FLAGS));
|
||||
return push_inst(compiler, OR | (flags & SET_FLAGS) | D(dst) | S1(src1) | ARG2(flags, src2), DRF(dst, flags));
|
||||
|
||||
case SLJIT_XOR:
|
||||
return push_inst(compiler, XOR | (flags & SET_FLAGS) | D(dst) | S1(src1) | ARG2(flags, src2), DR(dst) | (flags & SET_FLAGS));
|
||||
return push_inst(compiler, XOR | (flags & SET_FLAGS) | D(dst) | S1(src1) | ARG2(flags, src2), DRF(dst, flags));
|
||||
|
||||
case SLJIT_SHL:
|
||||
FAIL_IF(push_inst(compiler, SLL | D(dst) | S1(src1) | ARG2(flags, src2), DR(dst)));
|
||||
|
@ -147,7 +142,7 @@ static sljit_s32 call_with_args(struct sljit_compiler *compiler, sljit_s32 arg_t
|
|||
sljit_s32 word_reg_index = 8;
|
||||
sljit_s32 float_arg_index = 1;
|
||||
sljit_s32 double_arg_count = 0;
|
||||
sljit_s32 float_offset = (16 + 6) * sizeof(sljit_sw);
|
||||
sljit_u32 float_offset = (16 + 6) * sizeof(sljit_sw);
|
||||
sljit_s32 types = 0;
|
||||
sljit_s32 reg = 0;
|
||||
sljit_s32 move_to_tmp2 = 0;
|
||||
|
@ -155,18 +150,12 @@ static sljit_s32 call_with_args(struct sljit_compiler *compiler, sljit_s32 arg_t
|
|||
if (src)
|
||||
reg = reg_map[*src & REG_MASK];
|
||||
|
||||
arg_types >>= SLJIT_DEF_SHIFT;
|
||||
arg_types >>= SLJIT_ARG_SHIFT;
|
||||
|
||||
while (arg_types) {
|
||||
types = (types << SLJIT_DEF_SHIFT) | (arg_types & SLJIT_DEF_MASK);
|
||||
types = (types << SLJIT_ARG_SHIFT) | (arg_types & SLJIT_ARG_MASK);
|
||||
|
||||
switch (arg_types & SLJIT_DEF_MASK) {
|
||||
case SLJIT_ARG_TYPE_F32:
|
||||
float_arg_index++;
|
||||
if (reg_index == reg)
|
||||
move_to_tmp2 = 1;
|
||||
reg_index++;
|
||||
break;
|
||||
switch (arg_types & SLJIT_ARG_MASK) {
|
||||
case SLJIT_ARG_TYPE_F64:
|
||||
float_arg_index++;
|
||||
double_arg_count++;
|
||||
|
@ -174,36 +163,37 @@ static sljit_s32 call_with_args(struct sljit_compiler *compiler, sljit_s32 arg_t
|
|||
move_to_tmp2 = 1;
|
||||
reg_index += 2;
|
||||
break;
|
||||
case SLJIT_ARG_TYPE_F32:
|
||||
float_arg_index++;
|
||||
if (reg_index == reg)
|
||||
move_to_tmp2 = 1;
|
||||
reg_index++;
|
||||
break;
|
||||
default:
|
||||
if (reg_index != word_reg_index && reg_index < 14 && reg_index == reg)
|
||||
if (reg_index != word_reg_index && reg_index == reg)
|
||||
move_to_tmp2 = 1;
|
||||
reg_index++;
|
||||
word_reg_index++;
|
||||
break;
|
||||
}
|
||||
|
||||
if (move_to_tmp2) {
|
||||
move_to_tmp2 = 0;
|
||||
if (reg < 14)
|
||||
FAIL_IF(push_inst(compiler, OR | D(TMP_REG1) | S1(0) | S2A(reg), DR(TMP_REG1)));
|
||||
*src = TMP_REG1;
|
||||
}
|
||||
arg_types >>= SLJIT_ARG_SHIFT;
|
||||
}
|
||||
|
||||
arg_types >>= SLJIT_DEF_SHIFT;
|
||||
if (move_to_tmp2) {
|
||||
if (reg < 14)
|
||||
FAIL_IF(push_inst(compiler, OR | D(TMP_REG1) | S1(0) | S2A(reg), DR(TMP_REG1)));
|
||||
*src = TMP_REG1;
|
||||
}
|
||||
|
||||
arg_types = types;
|
||||
|
||||
while (arg_types) {
|
||||
switch (arg_types & SLJIT_DEF_MASK) {
|
||||
case SLJIT_ARG_TYPE_F32:
|
||||
float_arg_index--;
|
||||
FAIL_IF(push_inst(compiler, STF | FD(float_arg_index) | S1(SLJIT_SP) | IMM(float_offset), MOVABLE_INS));
|
||||
float_offset -= sizeof(sljit_f64);
|
||||
break;
|
||||
switch (arg_types & SLJIT_ARG_MASK) {
|
||||
case SLJIT_ARG_TYPE_F64:
|
||||
float_arg_index--;
|
||||
if (float_arg_index == 4 && double_arg_count == 4) {
|
||||
/* The address is not doubleword aligned, so two instructions are required to store the double. */
|
||||
FAIL_IF(push_inst(compiler, STF | FD(float_arg_index) | S1(SLJIT_SP) | IMM((16 + 7) * sizeof(sljit_sw)), MOVABLE_INS));
|
||||
FAIL_IF(push_inst(compiler, STF | FD(float_arg_index) | (1 << 25) | S1(SLJIT_SP) | IMM((16 + 8) * sizeof(sljit_sw)), MOVABLE_INS));
|
||||
}
|
||||
|
@ -211,36 +201,41 @@ static sljit_s32 call_with_args(struct sljit_compiler *compiler, sljit_s32 arg_t
|
|||
FAIL_IF(push_inst(compiler, STDF | FD(float_arg_index) | S1(SLJIT_SP) | IMM(float_offset), MOVABLE_INS));
|
||||
float_offset -= sizeof(sljit_f64);
|
||||
break;
|
||||
case SLJIT_ARG_TYPE_F32:
|
||||
float_arg_index--;
|
||||
FAIL_IF(push_inst(compiler, STF | FD(float_arg_index) | S1(SLJIT_SP) | IMM(float_offset), MOVABLE_INS));
|
||||
float_offset -= sizeof(sljit_f64);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
arg_types >>= SLJIT_DEF_SHIFT;
|
||||
arg_types >>= SLJIT_ARG_SHIFT;
|
||||
}
|
||||
|
||||
float_offset = (16 + 6) * sizeof(sljit_sw);
|
||||
|
||||
while (types) {
|
||||
switch (types & SLJIT_DEF_MASK) {
|
||||
case SLJIT_ARG_TYPE_F32:
|
||||
reg_index--;
|
||||
if (reg_index < 14)
|
||||
FAIL_IF(push_inst(compiler, LDUW | DA(reg_index) | S1(SLJIT_SP) | IMM(float_offset), reg_index));
|
||||
float_offset -= sizeof(sljit_f64);
|
||||
break;
|
||||
switch (types & SLJIT_ARG_MASK) {
|
||||
case SLJIT_ARG_TYPE_F64:
|
||||
reg_index -= 2;
|
||||
if (reg_index < 14) {
|
||||
if ((reg_index & 0x1) != 0) {
|
||||
FAIL_IF(push_inst(compiler, LDUW | DA(reg_index) | S1(SLJIT_SP) | IMM(float_offset), reg_index));
|
||||
if (reg_index < 13)
|
||||
if (reg_index < 8 + 6 - 1)
|
||||
FAIL_IF(push_inst(compiler, LDUW | DA(reg_index + 1) | S1(SLJIT_SP) | IMM(float_offset + sizeof(sljit_sw)), reg_index + 1));
|
||||
}
|
||||
else
|
||||
else
|
||||
FAIL_IF(push_inst(compiler, LDD | DA(reg_index) | S1(SLJIT_SP) | IMM(float_offset), reg_index));
|
||||
}
|
||||
float_offset -= sizeof(sljit_f64);
|
||||
break;
|
||||
case SLJIT_ARG_TYPE_F32:
|
||||
reg_index--;
|
||||
if (reg_index < 8 + 6)
|
||||
FAIL_IF(push_inst(compiler, LDUW | DA(reg_index) | S1(SLJIT_SP) | IMM(float_offset), reg_index));
|
||||
float_offset -= sizeof(sljit_f64);
|
||||
break;
|
||||
default:
|
||||
reg_index--;
|
||||
word_reg_index--;
|
||||
|
@ -254,7 +249,7 @@ static sljit_s32 call_with_args(struct sljit_compiler *compiler, sljit_s32 arg_t
|
|||
break;
|
||||
}
|
||||
|
||||
types >>= SLJIT_DEF_SHIFT;
|
||||
types >>= SLJIT_ARG_SHIFT;
|
||||
}
|
||||
|
||||
return SLJIT_SUCCESS;
|
||||
|
@ -282,5 +277,5 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_ta
|
|||
|
||||
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant, sljit_sw executable_offset)
|
||||
{
|
||||
sljit_set_jump_addr(addr, new_constant, executable_offset);
|
||||
sljit_set_jump_addr(addr, (sljit_uw)new_constant, executable_offset);
|
||||
}
|
||||
|
|
|
@ -98,36 +98,37 @@ static void sparc_cache_flush(sljit_ins *from, sljit_ins *to)
|
|||
#define TMP_FREG2 (SLJIT_NUMBER_OF_FLOAT_REGISTERS + 2)
|
||||
|
||||
static const sljit_u8 reg_map[SLJIT_NUMBER_OF_REGISTERS + 6] = {
|
||||
0, 8, 9, 10, 11, 29, 28, 27, 23, 22, 21, 20, 19, 18, 17, 16, 26, 25, 24, 14, 1, 12, 13, 15
|
||||
0, 8, 9, 10, 11, 23, 22, 21, 20, 19, 18, 17, 16, 29, 28, 27, 26, 25, 24, 14, 1, 12, 13, 15
|
||||
};
|
||||
|
||||
static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 3] = {
|
||||
0, 0, 2, 4, 6, 8, 10, 12, 14
|
||||
0, 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30
|
||||
};
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
/* Instrucion forms */
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
#define D(d) (reg_map[d] << 25)
|
||||
#define FD(d) (freg_map[d] << 25)
|
||||
#define FDN(d) ((freg_map[d] | 0x1) << 25)
|
||||
#define DA(d) ((d) << 25)
|
||||
#define S1(s1) (reg_map[s1] << 14)
|
||||
#define FS1(s1) (freg_map[s1] << 14)
|
||||
#define S1A(s1) ((s1) << 14)
|
||||
#define S2(s2) (reg_map[s2])
|
||||
#define FS2(s2) (freg_map[s2])
|
||||
#define FS2N(s2) (freg_map[s2] | 0x1)
|
||||
#define S2A(s2) (s2)
|
||||
#define D(d) ((sljit_ins)reg_map[d] << 25)
|
||||
#define FD(d) ((sljit_ins)freg_map[d] << 25)
|
||||
#define FDN(d) (((sljit_ins)freg_map[d] | 0x1) << 25)
|
||||
#define DA(d) ((sljit_ins)(d) << 25)
|
||||
#define S1(s1) ((sljit_ins)reg_map[s1] << 14)
|
||||
#define FS1(s1) ((sljit_ins)freg_map[s1] << 14)
|
||||
#define S1A(s1) ((sljit_ins)(s1) << 14)
|
||||
#define S2(s2) ((sljit_ins)reg_map[s2])
|
||||
#define FS2(s2) ((sljit_ins)freg_map[s2])
|
||||
#define FS2N(s2) ((sljit_ins)freg_map[s2] | 0x1)
|
||||
#define S2A(s2) ((sljit_ins)(s2))
|
||||
#define IMM_ARG 0x2000
|
||||
#define DOP(op) ((op) << 5)
|
||||
#define IMM(imm) (((imm) & 0x1fff) | IMM_ARG)
|
||||
#define DOP(op) ((sljit_ins)(op) << 5)
|
||||
#define IMM(imm) (((sljit_ins)(imm) & 0x1fff) | IMM_ARG)
|
||||
|
||||
#define DR(dr) (reg_map[dr])
|
||||
#define OPC1(opcode) ((opcode) << 30)
|
||||
#define OPC2(opcode) ((opcode) << 22)
|
||||
#define OPC3(opcode) ((opcode) << 19)
|
||||
#define DRF(dr, flags) ((sljit_s32)(reg_map[dr] | ((flags) & SET_FLAGS)))
|
||||
#define OPC1(opcode) ((sljit_ins)(opcode) << 30)
|
||||
#define OPC2(opcode) ((sljit_ins)(opcode) << 22)
|
||||
#define OPC3(opcode) ((sljit_ins)(opcode) << 19)
|
||||
#define SET_FLAGS OPC3(0x10)
|
||||
|
||||
#define ADD (OPC1(0x2) | OPC3(0x00))
|
||||
|
@ -156,6 +157,8 @@ static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 3] = {
|
|||
#define FSUBS (OPC1(0x2) | OPC3(0x34) | DOP(0x45))
|
||||
#define JMPL (OPC1(0x2) | OPC3(0x38))
|
||||
#define LDD (OPC1(0x3) | OPC3(0x03))
|
||||
#define LDDF (OPC1(0x3) | OPC3(0x23))
|
||||
#define LDF (OPC1(0x3) | OPC3(0x20))
|
||||
#define LDUW (OPC1(0x3) | OPC3(0x00))
|
||||
#define NOP (OPC1(0x0) | OPC2(0x04))
|
||||
#define OR (OPC1(0x2) | OPC3(0x02))
|
||||
|
@ -170,6 +173,7 @@ static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 3] = {
|
|||
#define SRAX (OPC1(0x2) | OPC3(0x27) | (1 << 12))
|
||||
#define SRL (OPC1(0x2) | OPC3(0x26))
|
||||
#define SRLX (OPC1(0x2) | OPC3(0x26) | (1 << 12))
|
||||
#define STD (OPC1(0x3) | OPC3(0x07))
|
||||
#define STDF (OPC1(0x3) | OPC3(0x27))
|
||||
#define STF (OPC1(0x3) | OPC3(0x24))
|
||||
#define STW (OPC1(0x3) | OPC3(0x04))
|
||||
|
@ -183,7 +187,7 @@ static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 3] = {
|
|||
#if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32)
|
||||
#define MAX_DISP (0x1fffff)
|
||||
#define MIN_DISP (-0x200000)
|
||||
#define DISP_MASK (0x3fffff)
|
||||
#define DISP_MASK ((sljit_ins)0x3fffff)
|
||||
|
||||
#define BICC (OPC1(0x0) | OPC2(0x2))
|
||||
#define FBFCC (OPC1(0x0) | OPC2(0x6))
|
||||
|
@ -274,7 +278,7 @@ static SLJIT_INLINE sljit_ins* detect_jump_type(struct sljit_jump *jump, sljit_i
|
|||
}
|
||||
}
|
||||
|
||||
diff += sizeof(sljit_ins);
|
||||
diff += SSIZE_OF(ins);
|
||||
|
||||
if (diff <= MAX_DISP && diff >= MIN_DISP) {
|
||||
jump->flags |= PATCH_B;
|
||||
|
@ -300,7 +304,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
|
|||
sljit_uw word_count;
|
||||
sljit_uw next_addr;
|
||||
sljit_sw executable_offset;
|
||||
sljit_uw addr;
|
||||
sljit_sw addr;
|
||||
|
||||
struct sljit_label *label;
|
||||
struct sljit_jump *jump;
|
||||
|
@ -340,7 +344,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
|
|||
if (label && label->size == word_count) {
|
||||
/* Just recording the address. */
|
||||
label->addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
|
||||
label->size = code_ptr - code;
|
||||
label->size = (sljit_uw)(code_ptr - code);
|
||||
label = label->next;
|
||||
}
|
||||
if (jump && jump->addr == word_count) {
|
||||
|
@ -373,7 +377,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
|
|||
|
||||
if (label && label->size == word_count) {
|
||||
label->addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
|
||||
label->size = code_ptr - code;
|
||||
label->size = (sljit_uw)(code_ptr - code);
|
||||
label = label->next;
|
||||
}
|
||||
|
||||
|
@ -386,27 +390,27 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
|
|||
jump = compiler->jumps;
|
||||
while (jump) {
|
||||
do {
|
||||
addr = (jump->flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target;
|
||||
addr = (sljit_sw)((jump->flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target);
|
||||
buf_ptr = (sljit_ins *)jump->addr;
|
||||
|
||||
if (jump->flags & PATCH_CALL) {
|
||||
addr = (sljit_sw)(addr - (sljit_uw)SLJIT_ADD_EXEC_OFFSET(buf_ptr, executable_offset)) >> 2;
|
||||
SLJIT_ASSERT((sljit_sw)addr <= 0x1fffffff && (sljit_sw)addr >= -0x20000000);
|
||||
buf_ptr[0] = CALL | (addr & 0x3fffffff);
|
||||
addr = (addr - (sljit_sw)SLJIT_ADD_EXEC_OFFSET(buf_ptr, executable_offset)) >> 2;
|
||||
SLJIT_ASSERT(addr <= 0x1fffffff && addr >= -0x20000000);
|
||||
buf_ptr[0] = CALL | ((sljit_ins)addr & 0x3fffffff);
|
||||
break;
|
||||
}
|
||||
if (jump->flags & PATCH_B) {
|
||||
addr = (sljit_sw)(addr - (sljit_uw)SLJIT_ADD_EXEC_OFFSET(buf_ptr, executable_offset)) >> 2;
|
||||
SLJIT_ASSERT((sljit_sw)addr <= MAX_DISP && (sljit_sw)addr >= MIN_DISP);
|
||||
buf_ptr[0] = (buf_ptr[0] & ~DISP_MASK) | (addr & DISP_MASK);
|
||||
addr = (addr - (sljit_sw)SLJIT_ADD_EXEC_OFFSET(buf_ptr, executable_offset)) >> 2;
|
||||
SLJIT_ASSERT(addr <= MAX_DISP && addr >= MIN_DISP);
|
||||
buf_ptr[0] = (buf_ptr[0] & ~DISP_MASK) | ((sljit_ins)addr & DISP_MASK);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Set the fields of immediate loads. */
|
||||
#if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32)
|
||||
SLJIT_ASSERT(((buf_ptr[0] & 0xc1cfffff) == 0x01000000) && ((buf_ptr[1] & 0xc1f83fff) == 0x80102000));
|
||||
buf_ptr[0] |= (addr >> 10) & 0x3fffff;
|
||||
buf_ptr[1] |= addr & 0x3ff;
|
||||
buf_ptr[0] |= (sljit_ins)(addr >> 10) & 0x3fffff;
|
||||
buf_ptr[1] |= (sljit_ins)addr & 0x3ff;
|
||||
#else
|
||||
#error "Implementation required"
|
||||
#endif
|
||||
|
@ -416,7 +420,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
|
|||
|
||||
put_label = compiler->put_labels;
|
||||
while (put_label) {
|
||||
addr = put_label->label->addr;
|
||||
addr = (sljit_sw)put_label->label->addr;
|
||||
buf_ptr = (sljit_ins *)put_label->addr;
|
||||
|
||||
#if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32)
|
||||
|
@ -431,7 +435,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
|
|||
|
||||
compiler->error = SLJIT_ERR_COMPILED;
|
||||
compiler->executable_offset = executable_offset;
|
||||
compiler->executable_size = (code_ptr - code) * sizeof(sljit_ins);
|
||||
compiler->executable_size = (sljit_uw)(code_ptr - code) * sizeof(sljit_ins);
|
||||
|
||||
code = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(code, executable_offset);
|
||||
code_ptr = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
|
||||
|
@ -487,13 +491,14 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type)
|
|||
#define ALT_KEEP_CACHE 0x00040
|
||||
#define CUMULATIVE_OP 0x00080
|
||||
#define IMM_OP 0x00100
|
||||
#define SRC2_IMM 0x00200
|
||||
#define MOVE_OP 0x00200
|
||||
#define SRC2_IMM 0x00400
|
||||
|
||||
#define REG_DEST 0x00400
|
||||
#define REG2_SOURCE 0x00800
|
||||
#define SLOW_SRC1 0x01000
|
||||
#define SLOW_SRC2 0x02000
|
||||
#define SLOW_DEST 0x04000
|
||||
#define REG_DEST 0x00800
|
||||
#define REG2_SOURCE 0x01000
|
||||
#define SLOW_SRC1 0x02000
|
||||
#define SLOW_SRC2 0x04000
|
||||
#define SLOW_DEST 0x08000
|
||||
|
||||
/* SET_FLAGS (0x10 << 19) also belong here! */
|
||||
|
||||
|
@ -507,6 +512,10 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compi
|
|||
sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds,
|
||||
sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size)
|
||||
{
|
||||
sljit_s32 reg_index, types;
|
||||
sljit_u32 float_offset, args_offset;
|
||||
sljit_s32 word_arg_index, float_arg_index;
|
||||
|
||||
CHECK_ERROR();
|
||||
CHECK(check_sljit_emit_enter(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size));
|
||||
set_emit_enter(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size);
|
||||
|
@ -514,7 +523,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compi
|
|||
local_size = (local_size + SLJIT_LOCALS_OFFSET + 7) & ~0x7;
|
||||
compiler->local_size = local_size;
|
||||
|
||||
if (local_size <= SIMM_MAX) {
|
||||
if (local_size <= -SIMM_MIN) {
|
||||
FAIL_IF(push_inst(compiler, SAVE | D(SLJIT_SP) | S1(SLJIT_SP) | IMM(-local_size), UNMOVABLE_INS));
|
||||
}
|
||||
else {
|
||||
|
@ -522,7 +531,82 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compi
|
|||
FAIL_IF(push_inst(compiler, SAVE | D(SLJIT_SP) | S1(SLJIT_SP) | S2(TMP_REG1), UNMOVABLE_INS));
|
||||
}
|
||||
|
||||
/* Arguments are in their appropriate registers. */
|
||||
arg_types >>= SLJIT_ARG_SHIFT;
|
||||
|
||||
types = arg_types;
|
||||
float_offset = 16 * sizeof(sljit_sw);
|
||||
reg_index = 24;
|
||||
|
||||
while (types && reg_index < 24 + 6) {
|
||||
switch (types & SLJIT_ARG_MASK) {
|
||||
case SLJIT_ARG_TYPE_F64:
|
||||
if (reg_index & 0x1) {
|
||||
FAIL_IF(push_inst(compiler, STW | DA(reg_index) | S1(SLJIT_SP) | IMM(float_offset), MOVABLE_INS));
|
||||
if (reg_index >= 24 + 6 - 1)
|
||||
break;
|
||||
FAIL_IF(push_inst(compiler, STW | DA(reg_index + 1) | S1(SLJIT_SP) | IMM(float_offset + sizeof(sljit_sw)), MOVABLE_INS));
|
||||
} else
|
||||
FAIL_IF(push_inst(compiler, STD | DA(reg_index) | S1(SLJIT_SP) | IMM(float_offset), MOVABLE_INS));
|
||||
|
||||
float_offset += sizeof(sljit_f64);
|
||||
reg_index++;
|
||||
break;
|
||||
case SLJIT_ARG_TYPE_F32:
|
||||
FAIL_IF(push_inst(compiler, STW | DA(reg_index) | S1(SLJIT_SP) | IMM(float_offset), MOVABLE_INS));
|
||||
float_offset += sizeof(sljit_f64);
|
||||
break;
|
||||
}
|
||||
|
||||
reg_index++;
|
||||
types >>= SLJIT_ARG_SHIFT;
|
||||
}
|
||||
|
||||
args_offset = (16 + 1 + 6) * sizeof(sljit_sw);
|
||||
float_offset = 16 * sizeof(sljit_sw);
|
||||
reg_index = 24;
|
||||
word_arg_index = 24;
|
||||
float_arg_index = 1;
|
||||
|
||||
while (arg_types) {
|
||||
switch (arg_types & SLJIT_ARG_MASK) {
|
||||
case SLJIT_ARG_TYPE_F64:
|
||||
if (reg_index < 24 + 6 - 1) {
|
||||
FAIL_IF(push_inst(compiler, LDDF | FD(float_arg_index) | S1(SLJIT_SP) | IMM(float_offset), MOVABLE_INS));
|
||||
} else if (reg_index < 24 + 6) {
|
||||
FAIL_IF(push_inst(compiler, LDF | FD(float_arg_index) | S1(SLJIT_SP) | IMM(float_offset), MOVABLE_INS));
|
||||
FAIL_IF(push_inst(compiler, LDF | FD(float_arg_index) | (1 << 25) | S1A(30) | IMM(args_offset), MOVABLE_INS));
|
||||
} else {
|
||||
FAIL_IF(push_inst(compiler, LDF | FD(float_arg_index) | S1A(30) | IMM(args_offset), MOVABLE_INS));
|
||||
FAIL_IF(push_inst(compiler, LDF | FD(float_arg_index) | (1 << 25) | S1A(30) | IMM(args_offset + sizeof(sljit_sw)), MOVABLE_INS));
|
||||
}
|
||||
|
||||
float_arg_index++;
|
||||
float_offset += sizeof(sljit_f64);
|
||||
reg_index++;
|
||||
break;
|
||||
case SLJIT_ARG_TYPE_F32:
|
||||
if (reg_index < 24 + 6)
|
||||
FAIL_IF(push_inst(compiler, LDF | FD(float_arg_index) | S1(SLJIT_SP) | IMM(float_offset), MOVABLE_INS));
|
||||
else
|
||||
FAIL_IF(push_inst(compiler, LDF | FD(float_arg_index) | S1A(30) | IMM(args_offset), MOVABLE_INS));
|
||||
float_arg_index++;
|
||||
float_offset += sizeof(sljit_f64);
|
||||
break;
|
||||
default:
|
||||
if (reg_index != word_arg_index) {
|
||||
if (reg_index < 24 + 6)
|
||||
FAIL_IF(push_inst(compiler, OR | DA(word_arg_index) | S1(0) | S2A(reg_index), word_arg_index));
|
||||
else
|
||||
FAIL_IF(push_inst(compiler, LDUW | DA(word_arg_index) | S1A(30) | IMM(args_offset), word_arg_index));
|
||||
}
|
||||
|
||||
word_arg_index++;
|
||||
break;
|
||||
}
|
||||
|
||||
reg_index++;
|
||||
arg_types >>= SLJIT_ARG_SHIFT;
|
||||
}
|
||||
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
@ -539,12 +623,21 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_set_context(struct sljit_compiler *comp
|
|||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return_void(struct sljit_compiler *compiler)
|
||||
{
|
||||
CHECK_ERROR();
|
||||
CHECK(check_sljit_emit_return_void(compiler));
|
||||
|
||||
FAIL_IF(push_inst(compiler, JMPL | D(0) | S1A(31) | IMM(8), UNMOVABLE_INS));
|
||||
return push_inst(compiler, RESTORE | D(SLJIT_R0) | S1(SLJIT_R0) | S2(0), UNMOVABLE_INS);
|
||||
}
|
||||
|
||||
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 (op != SLJIT_MOV || !FAST_IS_REG(src)) {
|
||||
if (TYPE_CAST_NEEDED(op) || !FAST_IS_REG(src)) {
|
||||
FAIL_IF(emit_mov_before_return(compiler, op, src, srcw));
|
||||
src = SLJIT_R0;
|
||||
}
|
||||
|
@ -591,7 +684,7 @@ static const sljit_ins data_transfer_insts[16 + 4] = {
|
|||
#undef ARCH_32_64
|
||||
|
||||
/* Can perform an operation using at most 1 instruction. */
|
||||
static sljit_s32 getput_arg_fast(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg, sljit_s32 arg, sljit_sw argw)
|
||||
static sljit_s32 getput_arg_fast(struct sljit_compiler *compiler, sljit_u32 flags, sljit_s32 reg, sljit_s32 arg, sljit_sw argw)
|
||||
{
|
||||
SLJIT_ASSERT(arg & SLJIT_MEM);
|
||||
|
||||
|
@ -632,7 +725,7 @@ static sljit_s32 can_cache(sljit_s32 arg, sljit_sw argw, sljit_s32 next_arg, slj
|
|||
}
|
||||
|
||||
/* Emit the necessary instructions. See can_cache above. */
|
||||
static sljit_s32 getput_arg(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg, sljit_s32 arg, sljit_sw argw, sljit_s32 next_arg, sljit_sw next_argw)
|
||||
static sljit_s32 getput_arg(struct sljit_compiler *compiler, sljit_u32 flags, sljit_s32 reg, sljit_s32 arg, sljit_sw argw, sljit_s32 next_arg, sljit_sw next_argw)
|
||||
{
|
||||
sljit_s32 base, arg2, delay_slot;
|
||||
sljit_ins dest;
|
||||
|
@ -660,7 +753,7 @@ static sljit_s32 getput_arg(struct sljit_compiler *compiler, sljit_s32 flags, sl
|
|||
arg2 = reg;
|
||||
else /* It must be a mov operation, so tmp1 must be free to use. */
|
||||
arg2 = TMP_REG1;
|
||||
FAIL_IF(push_inst(compiler, SLL_W | D(arg2) | S1(OFFS_REG(arg)) | IMM_ARG | argw, DR(arg2)));
|
||||
FAIL_IF(push_inst(compiler, SLL_W | D(arg2) | S1(OFFS_REG(arg)) | IMM_ARG | (sljit_ins)argw, DR(arg2)));
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
@ -692,7 +785,7 @@ static sljit_s32 getput_arg(struct sljit_compiler *compiler, sljit_s32 flags, sl
|
|||
return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | dest | S1(base) | S2(arg2), delay_slot);
|
||||
}
|
||||
|
||||
static SLJIT_INLINE sljit_s32 emit_op_mem(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg, sljit_s32 arg, sljit_sw argw)
|
||||
static SLJIT_INLINE sljit_s32 emit_op_mem(struct sljit_compiler *compiler, sljit_u32 flags, sljit_s32 reg, sljit_s32 arg, sljit_sw argw)
|
||||
{
|
||||
if (getput_arg_fast(compiler, flags, reg, arg, argw))
|
||||
return compiler->error;
|
||||
|
@ -701,14 +794,14 @@ static SLJIT_INLINE sljit_s32 emit_op_mem(struct sljit_compiler *compiler, sljit
|
|||
return getput_arg(compiler, flags, reg, arg, argw, 0, 0);
|
||||
}
|
||||
|
||||
static SLJIT_INLINE sljit_s32 emit_op_mem2(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg, sljit_s32 arg1, sljit_sw arg1w, sljit_s32 arg2, sljit_sw arg2w)
|
||||
static SLJIT_INLINE sljit_s32 emit_op_mem2(struct sljit_compiler *compiler, sljit_u32 flags, sljit_s32 reg, sljit_s32 arg1, sljit_sw arg1w, sljit_s32 arg2, sljit_sw arg2w)
|
||||
{
|
||||
if (getput_arg_fast(compiler, flags, reg, arg1, arg1w))
|
||||
return compiler->error;
|
||||
return getput_arg(compiler, flags, reg, arg1, arg1w, arg2, arg2w);
|
||||
}
|
||||
|
||||
static sljit_s32 emit_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 flags,
|
||||
static sljit_s32 emit_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_u32 flags,
|
||||
sljit_s32 dst, sljit_sw dstw,
|
||||
sljit_s32 src1, sljit_sw src1w,
|
||||
sljit_s32 src2, sljit_sw src2w)
|
||||
|
@ -727,11 +820,11 @@ static sljit_s32 emit_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s3
|
|||
compiler->cache_argw = 0;
|
||||
}
|
||||
|
||||
if (dst != SLJIT_UNUSED) {
|
||||
if (dst != TMP_REG2) {
|
||||
if (FAST_IS_REG(dst)) {
|
||||
dst_r = dst;
|
||||
flags |= REG_DEST;
|
||||
if (op >= SLJIT_MOV && op <= SLJIT_MOV_P)
|
||||
if (flags & MOVE_OP)
|
||||
sugg_src2_r = dst_r;
|
||||
}
|
||||
else if ((dst & SLJIT_MEM) && !getput_arg_fast(compiler, flags | ARG_TEST, TMP_REG1, dst, dstw))
|
||||
|
@ -782,7 +875,7 @@ static sljit_s32 emit_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s3
|
|||
if (FAST_IS_REG(src2)) {
|
||||
src2_r = src2;
|
||||
flags |= REG2_SOURCE;
|
||||
if (!(flags & REG_DEST) && op >= SLJIT_MOV && op <= SLJIT_MOV_P)
|
||||
if ((flags & (REG_DEST | MOVE_OP)) == MOVE_OP)
|
||||
dst_r = src2_r;
|
||||
}
|
||||
else if (src2 & SLJIT_IMM) {
|
||||
|
@ -793,8 +886,12 @@ static sljit_s32 emit_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s3
|
|||
}
|
||||
else {
|
||||
src2_r = 0;
|
||||
if ((op >= SLJIT_MOV && op <= SLJIT_MOV_P) && (dst & SLJIT_MEM))
|
||||
dst_r = 0;
|
||||
if (flags & MOVE_OP) {
|
||||
if (dst & SLJIT_MEM)
|
||||
dst_r = 0;
|
||||
else
|
||||
op = SLJIT_MOV;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -888,7 +985,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compile
|
|||
sljit_s32 dst, sljit_sw dstw,
|
||||
sljit_s32 src, sljit_sw srcw)
|
||||
{
|
||||
sljit_s32 flags = HAS_FLAGS(op) ? SET_FLAGS : 0;
|
||||
sljit_u32 flags = HAS_FLAGS(op) ? SET_FLAGS : 0;
|
||||
|
||||
CHECK_ERROR();
|
||||
CHECK(check_sljit_emit_op1(compiler, op, dst, dstw, src, srcw));
|
||||
|
@ -898,26 +995,25 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compile
|
|||
op = GET_OPCODE(op);
|
||||
switch (op) {
|
||||
case SLJIT_MOV:
|
||||
case SLJIT_MOV_P:
|
||||
return emit_op(compiler, SLJIT_MOV, flags | WORD_DATA, dst, dstw, TMP_REG1, 0, src, srcw);
|
||||
|
||||
#if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32)
|
||||
case SLJIT_MOV_U32:
|
||||
return emit_op(compiler, SLJIT_MOV_U32, flags | INT_DATA, dst, dstw, TMP_REG1, 0, src, srcw);
|
||||
|
||||
case SLJIT_MOV_S32:
|
||||
return emit_op(compiler, SLJIT_MOV_S32, flags | INT_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, srcw);
|
||||
case SLJIT_MOV32:
|
||||
#endif
|
||||
case SLJIT_MOV_P:
|
||||
return emit_op(compiler, SLJIT_MOV, flags | WORD_DATA | MOVE_OP, dst, dstw, TMP_REG1, 0, src, srcw);
|
||||
|
||||
case SLJIT_MOV_U8:
|
||||
return emit_op(compiler, SLJIT_MOV_U8, flags | BYTE_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_u8)srcw : srcw);
|
||||
return emit_op(compiler, SLJIT_MOV_U8, flags | BYTE_DATA | MOVE_OP, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_u8)srcw : srcw);
|
||||
|
||||
case SLJIT_MOV_S8:
|
||||
return emit_op(compiler, SLJIT_MOV_S8, flags | BYTE_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_s8)srcw : srcw);
|
||||
return emit_op(compiler, SLJIT_MOV_S8, flags | BYTE_DATA | SIGNED_DATA | MOVE_OP, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_s8)srcw : srcw);
|
||||
|
||||
case SLJIT_MOV_U16:
|
||||
return emit_op(compiler, SLJIT_MOV_U16, flags | HALF_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_u16)srcw : srcw);
|
||||
return emit_op(compiler, SLJIT_MOV_U16, flags | HALF_DATA | MOVE_OP, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_u16)srcw : srcw);
|
||||
|
||||
case SLJIT_MOV_S16:
|
||||
return emit_op(compiler, SLJIT_MOV_S16, flags | HALF_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_s16)srcw : srcw);
|
||||
return emit_op(compiler, SLJIT_MOV_S16, flags | HALF_DATA | SIGNED_DATA | MOVE_OP, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_s16)srcw : srcw);
|
||||
|
||||
case SLJIT_NOT:
|
||||
case SLJIT_CLZ:
|
||||
|
@ -935,17 +1031,14 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compile
|
|||
sljit_s32 src1, sljit_sw src1w,
|
||||
sljit_s32 src2, sljit_sw src2w)
|
||||
{
|
||||
sljit_s32 flags = HAS_FLAGS(op) ? SET_FLAGS : 0;
|
||||
sljit_u32 flags = HAS_FLAGS(op) ? SET_FLAGS : 0;
|
||||
|
||||
CHECK_ERROR();
|
||||
CHECK(check_sljit_emit_op2(compiler, op, dst, dstw, src1, src1w, src2, src2w));
|
||||
CHECK(check_sljit_emit_op2(compiler, op, 0, dst, dstw, src1, src1w, src2, src2w));
|
||||
ADJUST_LOCAL_OFFSET(dst, dstw);
|
||||
ADJUST_LOCAL_OFFSET(src1, src1w);
|
||||
ADJUST_LOCAL_OFFSET(src2, src2w);
|
||||
|
||||
if (dst == SLJIT_UNUSED && !HAS_FLAGS(op))
|
||||
return SLJIT_SUCCESS;
|
||||
|
||||
op = GET_OPCODE(op);
|
||||
switch (op) {
|
||||
case SLJIT_ADD:
|
||||
|
@ -975,6 +1068,20 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compile
|
|||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
CHECK_ERROR();
|
||||
CHECK(check_sljit_emit_op2(compiler, op, 1, 0, 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_op2(compiler, op, TMP_REG2, 0, src1, src1w, src2, src2w);
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_src(struct sljit_compiler *compiler, sljit_s32 op,
|
||||
sljit_s32 src, sljit_sw srcw)
|
||||
{
|
||||
|
@ -1015,7 +1122,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_float_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)
|
||||
{
|
||||
CHECK_ERROR();
|
||||
CHECK(check_sljit_emit_op_custom(compiler, instruction, size));
|
||||
|
@ -1027,8 +1134,8 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_custom(struct sljit_compiler *c
|
|||
/* Floating point operators */
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
#define FLOAT_DATA(op) (DOUBLE_DATA | ((op & SLJIT_F32_OP) >> 7))
|
||||
#define SELECT_FOP(op, single, double) ((op & SLJIT_F32_OP) ? single : double)
|
||||
#define FLOAT_DATA(op) ((sljit_ins)DOUBLE_DATA | (((sljit_ins)(op) & SLJIT_32) >> 7))
|
||||
#define SELECT_FOP(op, single, double) ((op & SLJIT_32) ? single : double)
|
||||
#define FLOAT_TMP_MEM_OFFSET (22 * sizeof(sljit_sw))
|
||||
|
||||
static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_sw_from_f64(struct sljit_compiler *compiler, sljit_s32 op,
|
||||
|
@ -1108,11 +1215,11 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop1(struct sljit_compiler *compil
|
|||
compiler->cache_arg = 0;
|
||||
compiler->cache_argw = 0;
|
||||
|
||||
SLJIT_COMPILE_ASSERT((SLJIT_F32_OP == 0x100) && !(DOUBLE_DATA & 0x2), float_transfer_bit_error);
|
||||
SLJIT_COMPILE_ASSERT((SLJIT_32 == 0x100) && !(DOUBLE_DATA & 0x2), float_transfer_bit_error);
|
||||
SELECT_FOP1_OPERATION_WITH_CHECKS(compiler, op, dst, dstw, src, srcw);
|
||||
|
||||
if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_F32)
|
||||
op ^= SLJIT_F32_OP;
|
||||
op ^= SLJIT_32;
|
||||
|
||||
dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1;
|
||||
|
||||
|
@ -1126,7 +1233,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop1(struct sljit_compiler *compil
|
|||
if (src != dst_r) {
|
||||
if (dst_r != TMP_FREG1) {
|
||||
FAIL_IF(push_inst(compiler, FMOVS | FD(dst_r) | FS2(src), MOVABLE_INS));
|
||||
if (!(op & SLJIT_F32_OP))
|
||||
if (!(op & SLJIT_32))
|
||||
FAIL_IF(push_inst(compiler, FMOVS | FDN(dst_r) | FS2N(src), MOVABLE_INS));
|
||||
}
|
||||
else
|
||||
|
@ -1135,17 +1242,17 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop1(struct sljit_compiler *compil
|
|||
break;
|
||||
case SLJIT_NEG_F64:
|
||||
FAIL_IF(push_inst(compiler, FNEGS | FD(dst_r) | FS2(src), MOVABLE_INS));
|
||||
if (dst_r != src && !(op & SLJIT_F32_OP))
|
||||
if (dst_r != src && !(op & SLJIT_32))
|
||||
FAIL_IF(push_inst(compiler, FMOVS | FDN(dst_r) | FS2N(src), MOVABLE_INS));
|
||||
break;
|
||||
case SLJIT_ABS_F64:
|
||||
FAIL_IF(push_inst(compiler, FABSS | FD(dst_r) | FS2(src), MOVABLE_INS));
|
||||
if (dst_r != src && !(op & SLJIT_F32_OP))
|
||||
if (dst_r != src && !(op & SLJIT_32))
|
||||
FAIL_IF(push_inst(compiler, FMOVS | FDN(dst_r) | FS2N(src), MOVABLE_INS));
|
||||
break;
|
||||
case SLJIT_CONV_F64_FROM_F32:
|
||||
FAIL_IF(push_inst(compiler, SELECT_FOP(op, FSTOD, FDTOS) | FD(dst_r) | FS2(src), MOVABLE_INS));
|
||||
op ^= SLJIT_F32_OP;
|
||||
op ^= SLJIT_32;
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -1317,6 +1424,7 @@ static sljit_ins get_cc(struct sljit_compiler *compiler, sljit_s32 type)
|
|||
case SLJIT_OVERFLOW:
|
||||
if (!(compiler->status_flags_state & SLJIT_CURRENT_FLAGS_ADD_SUB))
|
||||
return DA(0x9);
|
||||
/* fallthrough */
|
||||
|
||||
case SLJIT_UNORDERED_F64:
|
||||
return DA(0x7);
|
||||
|
@ -1324,6 +1432,7 @@ static sljit_ins get_cc(struct sljit_compiler *compiler, sljit_s32 type)
|
|||
case SLJIT_NOT_OVERFLOW:
|
||||
if (!(compiler->status_flags_state & SLJIT_CURRENT_FLAGS_ADD_SUB))
|
||||
return DA(0x1);
|
||||
/* fallthrough */
|
||||
|
||||
case SLJIT_ORDERED_F64:
|
||||
return DA(0xf);
|
||||
|
@ -1412,7 +1521,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_ijump(struct sljit_compiler *compi
|
|||
jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
|
||||
FAIL_IF(!jump);
|
||||
set_jump(jump, compiler, JUMP_ADDR);
|
||||
jump->u.target = srcw;
|
||||
jump->u.target = (sljit_uw)srcw;
|
||||
|
||||
if ((compiler->delay_slot & DST_INS_MASK) != UNMOVABLE_INS)
|
||||
jump->flags |= IS_MOVABLE;
|
||||
|
@ -1460,7 +1569,8 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_flags(struct sljit_compiler *co
|
|||
sljit_s32 dst, sljit_sw dstw,
|
||||
sljit_s32 type)
|
||||
{
|
||||
sljit_s32 reg, flags = HAS_FLAGS(op) ? SET_FLAGS : 0;
|
||||
sljit_s32 reg;
|
||||
sljit_u32 flags = HAS_FLAGS(op) ? SET_FLAGS : 0;
|
||||
|
||||
CHECK_ERROR();
|
||||
CHECK(check_sljit_emit_op_flags(compiler, op, dst, dstw, type));
|
||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -65,6 +65,8 @@ SLJIT_API_FUNC_ATTRIBUTE const char* sljit_get_platform_name(void)
|
|||
15 - R15
|
||||
*/
|
||||
|
||||
#define TMP_FREG (0)
|
||||
|
||||
#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
|
||||
|
||||
/* Last register + 1. */
|
||||
|
@ -77,9 +79,9 @@ static const sljit_u8 reg_map[SLJIT_NUMBER_OF_REGISTERS + 3] = {
|
|||
#define CHECK_EXTRA_REGS(p, w, do) \
|
||||
if (p >= SLJIT_R3 && p <= SLJIT_S3) { \
|
||||
if (p <= compiler->scratches) \
|
||||
w = compiler->saveds_offset - ((p) - SLJIT_R2) * (sljit_sw)sizeof(sljit_sw); \
|
||||
w = compiler->saveds_offset - ((p) - SLJIT_R2) * SSIZE_OF(sw); \
|
||||
else \
|
||||
w = compiler->locals_offset + ((p) - SLJIT_S2) * (sljit_sw)sizeof(sljit_sw); \
|
||||
w = compiler->locals_offset + ((p) - SLJIT_S2) * SSIZE_OF(sw); \
|
||||
p = SLJIT_MEM1(SLJIT_SP); \
|
||||
do; \
|
||||
}
|
||||
|
@ -115,11 +117,11 @@ static const sljit_u8 reg_lmap[SLJIT_NUMBER_OF_REGISTERS + 4] = {
|
|||
|
||||
/* Args: xmm0-xmm3 */
|
||||
static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 1] = {
|
||||
4, 0, 1, 2, 3, 5, 6
|
||||
4, 0, 1, 2, 3, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
|
||||
};
|
||||
/* low-map. freg_map & 0x7. */
|
||||
static const sljit_u8 freg_lmap[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 1] = {
|
||||
4, 0, 1, 2, 3, 5, 6
|
||||
4, 0, 1, 2, 3, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7
|
||||
};
|
||||
|
||||
#define REX_W 0x48
|
||||
|
@ -143,7 +145,8 @@ static const sljit_u8 freg_lmap[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 1] = {
|
|||
|
||||
#endif /* SLJIT_CONFIG_X86_32 */
|
||||
|
||||
#define TMP_FREG (0)
|
||||
#define U8(v) ((sljit_u8)(v))
|
||||
|
||||
|
||||
/* Size flags for emit_x86_instruction: */
|
||||
#define EX86_BIN_INS 0x0010
|
||||
|
@ -211,6 +214,8 @@ static const sljit_u8 freg_lmap[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 1] = {
|
|||
#define MOV_rm_i32 0xc7
|
||||
#define MOV_rm8_i8 0xc6
|
||||
#define MOV_rm8_r8 0x88
|
||||
#define MOVAPS_x_xm 0x28
|
||||
#define MOVAPS_xm_x 0x29
|
||||
#define MOVSD_x_xm 0x10
|
||||
#define MOVSD_xm_x 0x11
|
||||
#define MOVSXD_r_rm 0x63
|
||||
|
@ -274,14 +279,12 @@ static const sljit_u8 freg_lmap[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 1] = {
|
|||
#define MOD_REG 0xc0
|
||||
#define MOD_DISP8 0x40
|
||||
|
||||
#define INC_SIZE(s) (*inst++ = (s), compiler->size += (s))
|
||||
#define INC_SIZE(s) (*inst++ = U8(s), compiler->size += (s))
|
||||
|
||||
#define PUSH_REG(r) (*inst++ = (PUSH_r + (r)))
|
||||
#define POP_REG(r) (*inst++ = (POP_r + (r)))
|
||||
#define RET() (*inst++ = (RET_near))
|
||||
#define RET_I16(n) (*inst++ = (RET_i16), *inst++ = n, *inst++ = 0)
|
||||
/* r32, r/m32 */
|
||||
#define MOV_RM(mod, reg, rm) (*inst++ = (MOV_r_rm), *inst++ = (mod) << 6 | (reg) << 3 | (rm))
|
||||
#define PUSH_REG(r) (*inst++ = U8(PUSH_r + (r)))
|
||||
#define POP_REG(r) (*inst++ = U8(POP_r + (r)))
|
||||
#define RET() (*inst++ = RET_near)
|
||||
#define RET_I16(n) (*inst++ = RET_i16, *inst++ = U8(n), *inst++ = 0)
|
||||
|
||||
/* Multithreading does not affect these static variables, since they store
|
||||
built-in CPU features. Therefore they can be overwritten by different threads
|
||||
|
@ -371,7 +374,7 @@ static void get_cpu_features(void)
|
|||
cpu_has_cmov = (features >> 15) & 0x1;
|
||||
}
|
||||
|
||||
static sljit_u8 get_jump_code(sljit_s32 type)
|
||||
static sljit_u8 get_jump_code(sljit_uw type)
|
||||
{
|
||||
switch (type) {
|
||||
case SLJIT_EQUAL:
|
||||
|
@ -434,14 +437,14 @@ static sljit_u8* generate_put_label_code(struct sljit_put_label *put_label, slji
|
|||
|
||||
static sljit_u8* generate_near_jump_code(struct sljit_jump *jump, sljit_u8 *code_ptr, sljit_u8 *code, sljit_sw executable_offset)
|
||||
{
|
||||
sljit_s32 type = jump->flags >> TYPE_SHIFT;
|
||||
sljit_uw type = jump->flags >> TYPE_SHIFT;
|
||||
sljit_s32 short_jump;
|
||||
sljit_uw label_addr;
|
||||
|
||||
if (jump->flags & JUMP_LABEL)
|
||||
label_addr = (sljit_uw)(code + jump->u.label->size);
|
||||
else
|
||||
label_addr = jump->u.target - executable_offset;
|
||||
label_addr = jump->u.target - (sljit_uw)executable_offset;
|
||||
|
||||
short_jump = (sljit_sw)(label_addr - (jump->addr + 2)) >= -128 && (sljit_sw)(label_addr - (jump->addr + 2)) <= 127;
|
||||
|
||||
|
@ -463,7 +466,7 @@ static sljit_u8* generate_near_jump_code(struct sljit_jump *jump, sljit_u8 *code
|
|||
jump->addr++;
|
||||
}
|
||||
else if (short_jump) {
|
||||
*code_ptr++ = get_jump_code(type) - 0x10;
|
||||
*code_ptr++ = U8(get_jump_code(type) - 0x10);
|
||||
jump->addr++;
|
||||
}
|
||||
else {
|
||||
|
@ -492,7 +495,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
|
|||
sljit_u8 *buf_end;
|
||||
sljit_u8 len;
|
||||
sljit_sw executable_offset;
|
||||
sljit_sw jump_addr;
|
||||
sljit_uw jump_addr;
|
||||
|
||||
struct sljit_label *label;
|
||||
struct sljit_jump *jump;
|
||||
|
@ -530,7 +533,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
|
|||
switch (*buf_ptr) {
|
||||
case 0:
|
||||
label->addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
|
||||
label->size = code_ptr - code;
|
||||
label->size = (sljit_uw)(code_ptr - code);
|
||||
label = label->next;
|
||||
break;
|
||||
case 1:
|
||||
|
@ -575,11 +578,11 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
|
|||
|
||||
jump = compiler->jumps;
|
||||
while (jump) {
|
||||
jump_addr = jump->addr + executable_offset;
|
||||
jump_addr = jump->addr + (sljit_uw)executable_offset;
|
||||
|
||||
if (jump->flags & PATCH_MB) {
|
||||
SLJIT_ASSERT((sljit_sw)(jump->u.label->addr - (jump_addr + sizeof(sljit_s8))) >= -128 && (sljit_sw)(jump->u.label->addr - (jump_addr + sizeof(sljit_s8))) <= 127);
|
||||
*(sljit_u8*)jump->addr = (sljit_u8)(jump->u.label->addr - (jump_addr + sizeof(sljit_s8)));
|
||||
*(sljit_u8*)jump->addr = U8(jump->u.label->addr - (jump_addr + sizeof(sljit_s8)));
|
||||
} else if (jump->flags & PATCH_MW) {
|
||||
if (jump->flags & JUMP_LABEL) {
|
||||
#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
|
||||
|
@ -600,7 +603,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
|
|||
}
|
||||
#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
|
||||
else if (jump->flags & PATCH_MD)
|
||||
sljit_unaligned_store_sw((void*)jump->addr, jump->u.label->addr);
|
||||
sljit_unaligned_store_sw((void*)jump->addr, (sljit_sw)jump->u.label->addr);
|
||||
#endif
|
||||
|
||||
jump = jump->next;
|
||||
|
@ -626,7 +629,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
|
|||
|
||||
compiler->error = SLJIT_ERR_COMPILED;
|
||||
compiler->executable_offset = executable_offset;
|
||||
compiler->executable_size = code_ptr - code;
|
||||
compiler->executable_size = (sljit_uw)(code_ptr - code);
|
||||
|
||||
code = (sljit_u8*)SLJIT_ADD_EXEC_OFFSET(code, executable_offset);
|
||||
|
||||
|
@ -795,7 +798,7 @@ static SLJIT_INLINE sljit_s32 cpu_has_shadow_stack(void)
|
|||
}
|
||||
|
||||
static SLJIT_INLINE sljit_s32 adjust_shadow_stack(struct sljit_compiler *compiler,
|
||||
sljit_s32 src, sljit_sw srcw, sljit_s32 base, sljit_sw disp)
|
||||
sljit_s32 src, sljit_sw srcw)
|
||||
{
|
||||
#if (defined SLJIT_CONFIG_X86_CET && SLJIT_CONFIG_X86_CET) && defined (__SHSTK__)
|
||||
sljit_u8 *inst, *jz_after_cmp_inst;
|
||||
|
@ -821,12 +824,6 @@ static SLJIT_INLINE sljit_s32 adjust_shadow_stack(struct sljit_compiler *compile
|
|||
EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_MEM1(TMP_REG1), 0);
|
||||
#endif /* SLJIT_CONFIG_X86_32 */
|
||||
|
||||
if (src == SLJIT_UNUSED) {
|
||||
/* Return address is on stack. */
|
||||
src = SLJIT_MEM1(base);
|
||||
srcw = disp;
|
||||
}
|
||||
|
||||
/* Compare return address against TMP_REG1. */
|
||||
FAIL_IF(emit_cmp_binary (compiler, TMP_REG1, 0, src, srcw));
|
||||
|
||||
|
@ -861,8 +858,6 @@ static SLJIT_INLINE sljit_s32 adjust_shadow_stack(struct sljit_compiler *compile
|
|||
SLJIT_UNUSED_ARG(compiler);
|
||||
SLJIT_UNUSED_ARG(src);
|
||||
SLJIT_UNUSED_ARG(srcw);
|
||||
SLJIT_UNUSED_ARG(base);
|
||||
SLJIT_UNUSED_ARG(disp);
|
||||
#endif /* SLJIT_CONFIG_X86_CET && __SHSTK__ */
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
@ -879,8 +874,6 @@ static sljit_s32 emit_mov(struct sljit_compiler *compiler,
|
|||
{
|
||||
sljit_u8* inst;
|
||||
|
||||
SLJIT_ASSERT(dst != SLJIT_UNUSED);
|
||||
|
||||
if (FAST_IS_REG(src)) {
|
||||
inst = emit_x86_instruction(compiler, 1, src, 0, dst, dstw);
|
||||
FAIL_IF(!inst);
|
||||
|
@ -890,14 +883,14 @@ static sljit_s32 emit_mov(struct sljit_compiler *compiler,
|
|||
if (src & SLJIT_IMM) {
|
||||
if (FAST_IS_REG(dst)) {
|
||||
#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
|
||||
return emit_do_imm(compiler, MOV_r_i32 + reg_map[dst], srcw);
|
||||
return emit_do_imm(compiler, MOV_r_i32 | reg_map[dst], srcw);
|
||||
#else
|
||||
if (!compiler->mode32) {
|
||||
if (NOT_HALFWORD(srcw))
|
||||
return emit_load_imm64(compiler, dst, srcw);
|
||||
}
|
||||
else
|
||||
return emit_do_imm32(compiler, (reg_map[dst] >= 8) ? REX_B : 0, MOV_r_i32 + reg_lmap[dst], srcw);
|
||||
return emit_do_imm32(compiler, (reg_map[dst] >= 8) ? REX_B : 0, U8(MOV_r_i32 | reg_lmap[dst]), srcw);
|
||||
#endif
|
||||
}
|
||||
#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
|
||||
|
@ -938,7 +931,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compile
|
|||
{
|
||||
sljit_u8 *inst;
|
||||
#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
|
||||
sljit_s32 size;
|
||||
sljit_uw size;
|
||||
#endif
|
||||
|
||||
CHECK_ERROR();
|
||||
|
@ -975,7 +968,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compile
|
|||
&& reg_map[SLJIT_R1] < 7
|
||||
&& reg_map[TMP_REG1] == 2);
|
||||
#endif
|
||||
compiler->mode32 = op & SLJIT_I32_OP;
|
||||
compiler->mode32 = op & SLJIT_32;
|
||||
#endif
|
||||
SLJIT_COMPILE_ASSERT((SLJIT_DIVMOD_UW & 0x2) == 0 && SLJIT_DIV_UW - 0x2 == SLJIT_DIVMOD_UW, bad_div_opcode_assignments);
|
||||
|
||||
|
@ -1084,7 +1077,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compile
|
|||
inst = (sljit_u8*)ensure_buf(compiler, 1 + 1); \
|
||||
FAIL_IF(!inst); \
|
||||
INC_SIZE(1); \
|
||||
*inst = (prefix); \
|
||||
*inst = U8(prefix); \
|
||||
} while (0)
|
||||
|
||||
static sljit_s32 emit_mov_byte(struct sljit_compiler *compiler, sljit_s32 sign,
|
||||
|
@ -1104,7 +1097,7 @@ static sljit_s32 emit_mov_byte(struct sljit_compiler *compiler, sljit_s32 sign,
|
|||
if (src & SLJIT_IMM) {
|
||||
if (FAST_IS_REG(dst)) {
|
||||
#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
|
||||
return emit_do_imm(compiler, MOV_r_i32 + reg_map[dst], srcw);
|
||||
return emit_do_imm(compiler, MOV_r_i32 | reg_map[dst], srcw);
|
||||
#else
|
||||
inst = emit_x86_instruction(compiler, 1, SLJIT_IMM, srcw, dst, 0);
|
||||
FAIL_IF(!inst);
|
||||
|
@ -1134,7 +1127,7 @@ static sljit_s32 emit_mov_byte(struct sljit_compiler *compiler, sljit_s32 sign,
|
|||
#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
|
||||
else if (FAST_IS_REG(src) && reg_map[src] >= 4) {
|
||||
/* src, dst are registers. */
|
||||
SLJIT_ASSERT(SLOW_IS_REG(dst));
|
||||
SLJIT_ASSERT(FAST_IS_REG(dst));
|
||||
if (reg_map[dst] < 4) {
|
||||
if (dst != src)
|
||||
EMIT_MOV(compiler, dst, 0, src, 0);
|
||||
|
@ -1193,7 +1186,7 @@ static sljit_s32 emit_mov_byte(struct sljit_compiler *compiler, sljit_s32 sign,
|
|||
}
|
||||
|
||||
if (work_r == SLJIT_R0) {
|
||||
ENCODE_PREFIX(XCHG_EAX_r + reg_map[TMP_REG1]);
|
||||
ENCODE_PREFIX(XCHG_EAX_r | reg_map[TMP_REG1]);
|
||||
}
|
||||
else {
|
||||
inst = emit_x86_instruction(compiler, 1, work_r, 0, dst_r, 0);
|
||||
|
@ -1206,7 +1199,7 @@ static sljit_s32 emit_mov_byte(struct sljit_compiler *compiler, sljit_s32 sign,
|
|||
*inst = MOV_rm8_r8;
|
||||
|
||||
if (work_r == SLJIT_R0) {
|
||||
ENCODE_PREFIX(XCHG_EAX_r + reg_map[TMP_REG1]);
|
||||
ENCODE_PREFIX(XCHG_EAX_r | reg_map[TMP_REG1]);
|
||||
}
|
||||
else {
|
||||
inst = emit_x86_instruction(compiler, 1, work_r, 0, dst_r, 0);
|
||||
|
@ -1267,7 +1260,7 @@ static sljit_s32 emit_mov_half(struct sljit_compiler *compiler, sljit_s32 sign,
|
|||
if (src & SLJIT_IMM) {
|
||||
if (FAST_IS_REG(dst)) {
|
||||
#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
|
||||
return emit_do_imm(compiler, MOV_r_i32 + reg_map[dst], srcw);
|
||||
return emit_do_imm(compiler, MOV_r_i32 | reg_map[dst], srcw);
|
||||
#else
|
||||
inst = emit_x86_instruction(compiler, 1, SLJIT_IMM, srcw, dst, 0);
|
||||
FAIL_IF(!inst);
|
||||
|
@ -1316,9 +1309,6 @@ static sljit_s32 emit_unary(struct sljit_compiler *compiler, sljit_u8 opcode,
|
|||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
if (SLJIT_UNLIKELY(dst == SLJIT_UNUSED))
|
||||
dst = TMP_REG1;
|
||||
|
||||
if (FAST_IS_REG(dst)) {
|
||||
EMIT_MOV(compiler, dst, 0, src, srcw);
|
||||
inst = emit_x86_instruction(compiler, 1, 0, 0, dst, 0);
|
||||
|
@ -1343,9 +1333,6 @@ static sljit_s32 emit_not_with_flags(struct sljit_compiler *compiler,
|
|||
{
|
||||
sljit_u8* inst;
|
||||
|
||||
if (dst == SLJIT_UNUSED)
|
||||
dst = TMP_REG1;
|
||||
|
||||
if (FAST_IS_REG(dst)) {
|
||||
EMIT_MOV(compiler, dst, 0, src, srcw);
|
||||
inst = emit_x86_instruction(compiler, 1, 0, 0, dst, 0);
|
||||
|
@ -1412,7 +1399,7 @@ static sljit_s32 emit_clz(struct sljit_compiler *compiler, sljit_s32 op_flags,
|
|||
inst = emit_x86_instruction(compiler, 1 | EX86_BIN_INS, SLJIT_IMM, 31, dst_r, 0);
|
||||
#else
|
||||
if (cpu_has_cmov) {
|
||||
EMIT_MOV(compiler, TMP_REG2, 0, SLJIT_IMM, !(op_flags & SLJIT_I32_OP) ? (64 + 63) : (32 + 31));
|
||||
EMIT_MOV(compiler, TMP_REG2, 0, SLJIT_IMM, !(op_flags & SLJIT_32) ? (64 + 63) : (32 + 31));
|
||||
|
||||
inst = emit_x86_instruction(compiler, 2, dst_r, 0, TMP_REG2, 0);
|
||||
FAIL_IF(!inst);
|
||||
|
@ -1420,9 +1407,9 @@ static sljit_s32 emit_clz(struct sljit_compiler *compiler, sljit_s32 op_flags,
|
|||
*inst = CMOVE_r_rm;
|
||||
}
|
||||
else
|
||||
FAIL_IF(sljit_emit_cmov_generic(compiler, SLJIT_EQUAL, dst_r, SLJIT_IMM, !(op_flags & SLJIT_I32_OP) ? (64 + 63) : (32 + 31)));
|
||||
FAIL_IF(sljit_emit_cmov_generic(compiler, SLJIT_EQUAL, dst_r, SLJIT_IMM, !(op_flags & SLJIT_32) ? (64 + 63) : (32 + 31)));
|
||||
|
||||
inst = emit_x86_instruction(compiler, 1 | EX86_BIN_INS, SLJIT_IMM, !(op_flags & SLJIT_I32_OP) ? 63 : 31, dst_r, 0);
|
||||
inst = emit_x86_instruction(compiler, 1 | EX86_BIN_INS, SLJIT_IMM, !(op_flags & SLJIT_32) ? 63 : 31, dst_r, 0);
|
||||
#endif
|
||||
|
||||
FAIL_IF(!inst);
|
||||
|
@ -1450,7 +1437,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compile
|
|||
CHECK_EXTRA_REGS(dst, dstw, dst_is_ereg = 1);
|
||||
CHECK_EXTRA_REGS(src, srcw, (void)0);
|
||||
#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
|
||||
compiler->mode32 = op_flags & SLJIT_I32_OP;
|
||||
compiler->mode32 = op_flags & SLJIT_32;
|
||||
#endif
|
||||
|
||||
op = GET_OPCODE(op);
|
||||
|
@ -1465,8 +1452,8 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compile
|
|||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
if (op_flags & SLJIT_I32_OP) {
|
||||
#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
|
||||
if (op_flags & SLJIT_32) {
|
||||
if (src & SLJIT_MEM) {
|
||||
if (op == SLJIT_MOV_S32)
|
||||
op = SLJIT_MOV_U32;
|
||||
|
@ -1475,8 +1462,8 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compile
|
|||
if (op == SLJIT_MOV_U32)
|
||||
op = SLJIT_MOV_S32;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
if (src & SLJIT_IMM) {
|
||||
switch (op) {
|
||||
|
@ -1520,8 +1507,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compile
|
|||
#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
|
||||
case SLJIT_MOV_U32:
|
||||
case SLJIT_MOV_S32:
|
||||
case SLJIT_MOV32:
|
||||
#endif
|
||||
FAIL_IF(emit_mov(compiler, dst, dstw, src, srcw));
|
||||
EMIT_MOV(compiler, dst, dstw, src, srcw);
|
||||
break;
|
||||
case SLJIT_MOV_U8:
|
||||
FAIL_IF(emit_mov_byte(compiler, 0, dst, dstw, src, srcw));
|
||||
|
@ -1542,6 +1530,11 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compile
|
|||
case SLJIT_MOV_S32:
|
||||
FAIL_IF(emit_mov_int(compiler, 1, dst, dstw, src, srcw));
|
||||
break;
|
||||
case SLJIT_MOV32:
|
||||
compiler->mode32 = 1;
|
||||
EMIT_MOV(compiler, dst, dstw, src, srcw);
|
||||
compiler->mode32 = 0;
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -1605,23 +1598,10 @@ static sljit_s32 emit_cum_binary(struct sljit_compiler *compiler,
|
|||
sljit_s32 src2, sljit_sw src2w)
|
||||
{
|
||||
sljit_u8* inst;
|
||||
sljit_u8 op_eax_imm = (op_types >> 24);
|
||||
sljit_u8 op_rm = (op_types >> 16) & 0xff;
|
||||
sljit_u8 op_mr = (op_types >> 8) & 0xff;
|
||||
sljit_u8 op_imm = op_types & 0xff;
|
||||
|
||||
if (dst == SLJIT_UNUSED) {
|
||||
EMIT_MOV(compiler, TMP_REG1, 0, src1, src1w);
|
||||
if (src2 & SLJIT_IMM) {
|
||||
BINARY_IMM(op_imm, op_mr, src2w, TMP_REG1, 0);
|
||||
}
|
||||
else {
|
||||
inst = emit_x86_instruction(compiler, 1, TMP_REG1, 0, src2, src2w);
|
||||
FAIL_IF(!inst);
|
||||
*inst = op_rm;
|
||||
}
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
sljit_u8 op_eax_imm = U8(op_types >> 24);
|
||||
sljit_u8 op_rm = U8((op_types >> 16) & 0xff);
|
||||
sljit_u8 op_mr = U8((op_types >> 8) & 0xff);
|
||||
sljit_u8 op_imm = U8(op_types & 0xff);
|
||||
|
||||
if (dst == src1 && dstw == src1w) {
|
||||
if (src2 & SLJIT_IMM) {
|
||||
|
@ -1725,23 +1705,10 @@ static sljit_s32 emit_non_cum_binary(struct sljit_compiler *compiler,
|
|||
sljit_s32 src2, sljit_sw src2w)
|
||||
{
|
||||
sljit_u8* inst;
|
||||
sljit_u8 op_eax_imm = (op_types >> 24);
|
||||
sljit_u8 op_rm = (op_types >> 16) & 0xff;
|
||||
sljit_u8 op_mr = (op_types >> 8) & 0xff;
|
||||
sljit_u8 op_imm = op_types & 0xff;
|
||||
|
||||
if (dst == SLJIT_UNUSED) {
|
||||
EMIT_MOV(compiler, TMP_REG1, 0, src1, src1w);
|
||||
if (src2 & SLJIT_IMM) {
|
||||
BINARY_IMM(op_imm, op_mr, src2w, TMP_REG1, 0);
|
||||
}
|
||||
else {
|
||||
inst = emit_x86_instruction(compiler, 1, TMP_REG1, 0, src2, src2w);
|
||||
FAIL_IF(!inst);
|
||||
*inst = op_rm;
|
||||
}
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
sljit_u8 op_eax_imm = U8(op_types >> 24);
|
||||
sljit_u8 op_rm = U8((op_types >> 16) & 0xff);
|
||||
sljit_u8 op_mr = U8((op_types >> 8) & 0xff);
|
||||
sljit_u8 op_imm = U8(op_types & 0xff);
|
||||
|
||||
if (dst == src1 && dstw == src1w) {
|
||||
if (src2 & SLJIT_IMM) {
|
||||
|
@ -1810,9 +1777,7 @@ static sljit_s32 emit_mul(struct sljit_compiler *compiler,
|
|||
sljit_s32 src2, sljit_sw src2w)
|
||||
{
|
||||
sljit_u8* inst;
|
||||
sljit_s32 dst_r;
|
||||
|
||||
dst_r = SLOW_IS_REG(dst) ? dst : TMP_REG1;
|
||||
sljit_s32 dst_r = FAST_IS_REG(dst) ? dst : TMP_REG1;
|
||||
|
||||
/* Register destination. */
|
||||
if (dst_r == src1 && !(src2 & SLJIT_IMM)) {
|
||||
|
@ -1841,7 +1806,7 @@ static sljit_s32 emit_mul(struct sljit_compiler *compiler,
|
|||
inst = (sljit_u8*)ensure_buf(compiler, 1 + 1);
|
||||
FAIL_IF(!inst);
|
||||
INC_SIZE(1);
|
||||
*inst = (sljit_s8)src1w;
|
||||
*inst = U8(src1w);
|
||||
}
|
||||
#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
|
||||
else {
|
||||
|
@ -1884,7 +1849,7 @@ static sljit_s32 emit_mul(struct sljit_compiler *compiler,
|
|||
inst = (sljit_u8*)ensure_buf(compiler, 1 + 1);
|
||||
FAIL_IF(!inst);
|
||||
INC_SIZE(1);
|
||||
*inst = (sljit_s8)src2w;
|
||||
*inst = U8(src2w);
|
||||
}
|
||||
#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
|
||||
else {
|
||||
|
@ -2167,13 +2132,6 @@ static sljit_s32 emit_shift(struct sljit_compiler *compiler,
|
|||
*inst |= mode;
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
if (dst == SLJIT_UNUSED) {
|
||||
EMIT_MOV(compiler, TMP_REG1, 0, src1, src1w);
|
||||
inst = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, src2, src2w, TMP_REG1, 0);
|
||||
FAIL_IF(!inst);
|
||||
*inst |= mode;
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
if (dst == SLJIT_PREF_SHIFT_REG && src2 == SLJIT_PREF_SHIFT_REG) {
|
||||
EMIT_MOV(compiler, TMP_REG1, 0, src1, src1w);
|
||||
inst = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_PREF_SHIFT_REG, 0, TMP_REG1, 0);
|
||||
|
@ -2206,7 +2164,7 @@ static sljit_s32 emit_shift(struct sljit_compiler *compiler,
|
|||
*inst |= mode;
|
||||
EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, TMP_REG1, 0);
|
||||
}
|
||||
else if (SLOW_IS_REG(dst) && dst != src2 && !ADDRESSING_DEPENDS_ON(src2, dst)) {
|
||||
else if (FAST_IS_REG(dst) && dst != src2 && dst != TMP_REG1 && !ADDRESSING_DEPENDS_ON(src2, dst)) {
|
||||
if (src1 != dst)
|
||||
EMIT_MOV(compiler, dst, 0, src1, src1w);
|
||||
EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_PREF_SHIFT_REG, 0);
|
||||
|
@ -2235,7 +2193,7 @@ static sljit_s32 emit_shift(struct sljit_compiler *compiler,
|
|||
*inst |= mode;
|
||||
EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, TMP_REG2, 0);
|
||||
#endif
|
||||
if (dst != SLJIT_UNUSED)
|
||||
if (dst != TMP_REG1)
|
||||
return emit_mov(compiler, dst, dstw, TMP_REG1, 0);
|
||||
}
|
||||
|
||||
|
@ -2273,7 +2231,7 @@ static sljit_s32 emit_shift_with_flags(struct sljit_compiler *compiler,
|
|||
FAIL_IF(emit_shift(compiler, mode, dst, dstw, src1, src1w, src2, src2w));
|
||||
|
||||
if (FAST_IS_REG(dst))
|
||||
return emit_cmp_binary(compiler, (dst == SLJIT_UNUSED) ? TMP_REG1 : dst, dstw, SLJIT_IMM, 0);
|
||||
return emit_cmp_binary(compiler, dst, dstw, SLJIT_IMM, 0);
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -2283,7 +2241,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compile
|
|||
sljit_s32 src2, sljit_sw src2w)
|
||||
{
|
||||
CHECK_ERROR();
|
||||
CHECK(check_sljit_emit_op2(compiler, op, dst, dstw, src1, src1w, src2, src2w));
|
||||
CHECK(check_sljit_emit_op2(compiler, op, 0, dst, dstw, src1, src1w, src2, src2w));
|
||||
ADJUST_LOCAL_OFFSET(dst, dstw);
|
||||
ADJUST_LOCAL_OFFSET(src1, src1w);
|
||||
ADJUST_LOCAL_OFFSET(src2, src2w);
|
||||
|
@ -2292,11 +2250,10 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compile
|
|||
CHECK_EXTRA_REGS(src1, src1w, (void)0);
|
||||
CHECK_EXTRA_REGS(src2, src2w, (void)0);
|
||||
#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
|
||||
compiler->mode32 = op & SLJIT_I32_OP;
|
||||
compiler->mode32 = op & SLJIT_32;
|
||||
#endif
|
||||
|
||||
if (dst == SLJIT_UNUSED && !HAS_FLAGS(op))
|
||||
return SLJIT_SUCCESS;
|
||||
SLJIT_ASSERT(dst != TMP_REG1 || HAS_FLAGS(op));
|
||||
|
||||
switch (GET_OPCODE(op)) {
|
||||
case SLJIT_ADD:
|
||||
|
@ -2313,14 +2270,12 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compile
|
|||
if (!HAS_FLAGS(op)) {
|
||||
if ((src2 & SLJIT_IMM) && emit_lea_binary(compiler, dst, dstw, src1, src1w, SLJIT_IMM, -src2w) != SLJIT_ERR_UNSUPPORTED)
|
||||
return compiler->error;
|
||||
if (SLOW_IS_REG(dst) && src2 == dst) {
|
||||
if (FAST_IS_REG(dst) && src2 == dst) {
|
||||
FAIL_IF(emit_non_cum_binary(compiler, BINARY_OPCODE(SUB), dst, 0, dst, 0, src1, src1w));
|
||||
return emit_unary(compiler, NEG_rm, dst, 0, dst, 0);
|
||||
}
|
||||
}
|
||||
|
||||
if (dst == SLJIT_UNUSED)
|
||||
return emit_cmp_binary(compiler, src1, src1w, src2, src2w);
|
||||
return emit_non_cum_binary(compiler, BINARY_OPCODE(SUB),
|
||||
dst, dstw, src1, src1w, src2, src2w);
|
||||
case SLJIT_SUBC:
|
||||
|
@ -2329,8 +2284,6 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compile
|
|||
case SLJIT_MUL:
|
||||
return emit_mul(compiler, dst, dstw, src1, src1w, src2, src2w);
|
||||
case SLJIT_AND:
|
||||
if (dst == SLJIT_UNUSED)
|
||||
return emit_test_binary(compiler, src1, src1w, src2, src2w);
|
||||
return emit_cum_binary(compiler, BINARY_OPCODE(AND),
|
||||
dst, dstw, src1, src1w, src2, src2w);
|
||||
case SLJIT_OR:
|
||||
|
@ -2353,6 +2306,38 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compile
|
|||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
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_s32 opcode = GET_OPCODE(op);
|
||||
|
||||
CHECK_ERROR();
|
||||
CHECK(check_sljit_emit_op2(compiler, op, 1, 0, 0, src1, src1w, src2, src2w));
|
||||
|
||||
if (opcode != SLJIT_SUB && opcode != SLJIT_AND) {
|
||||
#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \
|
||||
|| (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
|
||||
compiler->skip_checks = 1;
|
||||
#endif
|
||||
return sljit_emit_op2(compiler, op, TMP_REG1, 0, src1, src1w, src2, src2w);
|
||||
}
|
||||
|
||||
ADJUST_LOCAL_OFFSET(src1, src1w);
|
||||
ADJUST_LOCAL_OFFSET(src2, src2w);
|
||||
|
||||
CHECK_EXTRA_REGS(src1, src1w, (void)0);
|
||||
CHECK_EXTRA_REGS(src2, src2w, (void)0);
|
||||
#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
|
||||
compiler->mode32 = op & SLJIT_32;
|
||||
#endif
|
||||
|
||||
if (opcode == SLJIT_SUB) {
|
||||
return emit_cmp_binary(compiler, src1, src1w, src2, src2w);
|
||||
}
|
||||
return emit_test_binary(compiler, src1, src1w, src2, src2w);
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_src(struct sljit_compiler *compiler, sljit_s32 op,
|
||||
sljit_s32 src, sljit_sw srcw)
|
||||
{
|
||||
|
@ -2369,7 +2354,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_src(struct sljit_compiler *comp
|
|||
/* Don't adjust shadow stack if it isn't enabled. */
|
||||
if (!cpu_has_shadow_stack ())
|
||||
return SLJIT_SUCCESS;
|
||||
return adjust_shadow_stack(compiler, src, srcw, SLJIT_UNUSED, 0);
|
||||
return adjust_shadow_stack(compiler, src, srcw);
|
||||
case SLJIT_PREFETCH_L1:
|
||||
case SLJIT_PREFETCH_L2:
|
||||
case SLJIT_PREFETCH_L3:
|
||||
|
@ -2401,7 +2386,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_float_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_u8 *inst;
|
||||
|
||||
|
@ -2420,13 +2405,13 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_custom(struct sljit_compiler *c
|
|||
/* --------------------------------------------------------------------- */
|
||||
|
||||
/* Alignment(3) + 4 * 16 bytes. */
|
||||
static sljit_s32 sse2_data[3 + (4 * 4)];
|
||||
static sljit_s32 *sse2_buffer;
|
||||
static sljit_u32 sse2_data[3 + (4 * 4)];
|
||||
static sljit_u32 *sse2_buffer;
|
||||
|
||||
static void init_compiler(void)
|
||||
{
|
||||
/* Align to 16 bytes. */
|
||||
sse2_buffer = (sljit_s32*)(((sljit_uw)sse2_data + 15) & ~0xf);
|
||||
sse2_buffer = (sljit_u32*)(((sljit_uw)sse2_data + 15) & ~(sljit_uw)0xf);
|
||||
|
||||
/* Single precision constants (each constant is 16 byte long). */
|
||||
sse2_buffer[0] = 0x80000000;
|
||||
|
@ -2486,7 +2471,7 @@ static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_sw_from_f64(struct sljit_comp
|
|||
compiler->mode32 = 0;
|
||||
#endif
|
||||
|
||||
inst = emit_x86_instruction(compiler, 2 | ((op & SLJIT_F32_OP) ? EX86_PREF_F3 : EX86_PREF_F2) | EX86_SSE2_OP2, dst_r, 0, src, srcw);
|
||||
inst = emit_x86_instruction(compiler, 2 | ((op & SLJIT_32) ? EX86_PREF_F3 : EX86_PREF_F2) | EX86_SSE2_OP2, dst_r, 0, src, srcw);
|
||||
FAIL_IF(!inst);
|
||||
*inst++ = GROUP_0F;
|
||||
*inst = CVTTSD2SI_r_xm;
|
||||
|
@ -2518,7 +2503,7 @@ static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_f64_from_sw(struct sljit_comp
|
|||
srcw = 0;
|
||||
}
|
||||
|
||||
inst = emit_x86_instruction(compiler, 2 | ((op & SLJIT_F32_OP) ? EX86_PREF_F3 : EX86_PREF_F2) | EX86_SSE2_OP1, dst_r, 0, src, srcw);
|
||||
inst = emit_x86_instruction(compiler, 2 | ((op & SLJIT_32) ? EX86_PREF_F3 : EX86_PREF_F2) | EX86_SSE2_OP1, dst_r, 0, src, srcw);
|
||||
FAIL_IF(!inst);
|
||||
*inst++ = GROUP_0F;
|
||||
*inst = CVTSI2SD_x_rm;
|
||||
|
@ -2527,7 +2512,7 @@ static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_f64_from_sw(struct sljit_comp
|
|||
compiler->mode32 = 1;
|
||||
#endif
|
||||
if (dst_r == TMP_FREG)
|
||||
return emit_sse2_store(compiler, op & SLJIT_F32_OP, dst, dstw, TMP_FREG);
|
||||
return emit_sse2_store(compiler, op & SLJIT_32, dst, dstw, TMP_FREG);
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -2536,11 +2521,11 @@ static SLJIT_INLINE sljit_s32 sljit_emit_fop1_cmp(struct sljit_compiler *compile
|
|||
sljit_s32 src2, sljit_sw src2w)
|
||||
{
|
||||
if (!FAST_IS_REG(src1)) {
|
||||
FAIL_IF(emit_sse2_load(compiler, op & SLJIT_F32_OP, TMP_FREG, src1, src1w));
|
||||
FAIL_IF(emit_sse2_load(compiler, op & SLJIT_32, TMP_FREG, src1, src1w));
|
||||
src1 = TMP_FREG;
|
||||
}
|
||||
|
||||
return emit_sse2_logic(compiler, UCOMISD_x_xm, !(op & SLJIT_F32_OP), src1, src2, src2w);
|
||||
return emit_sse2_logic(compiler, UCOMISD_x_xm, !(op & SLJIT_32), src1, src2, src2w);
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop1(struct sljit_compiler *compiler, sljit_s32 op,
|
||||
|
@ -2558,11 +2543,11 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop1(struct sljit_compiler *compil
|
|||
|
||||
if (GET_OPCODE(op) == SLJIT_MOV_F64) {
|
||||
if (FAST_IS_REG(dst))
|
||||
return emit_sse2_load(compiler, op & SLJIT_F32_OP, dst, src, srcw);
|
||||
return emit_sse2_load(compiler, op & SLJIT_32, dst, src, srcw);
|
||||
if (FAST_IS_REG(src))
|
||||
return emit_sse2_store(compiler, op & SLJIT_F32_OP, dst, dstw, src);
|
||||
FAIL_IF(emit_sse2_load(compiler, op & SLJIT_F32_OP, TMP_FREG, src, srcw));
|
||||
return emit_sse2_store(compiler, op & SLJIT_F32_OP, dst, dstw, TMP_FREG);
|
||||
return emit_sse2_store(compiler, op & SLJIT_32, dst, dstw, src);
|
||||
FAIL_IF(emit_sse2_load(compiler, op & SLJIT_32, TMP_FREG, src, srcw));
|
||||
return emit_sse2_store(compiler, op & SLJIT_32, dst, dstw, TMP_FREG);
|
||||
}
|
||||
|
||||
if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_F32) {
|
||||
|
@ -2571,41 +2556,41 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop1(struct sljit_compiler *compil
|
|||
/* We overwrite the high bits of source. From SLJIT point of view,
|
||||
this is not an issue.
|
||||
Note: In SSE3, we could also use MOVDDUP and MOVSLDUP. */
|
||||
FAIL_IF(emit_sse2_logic(compiler, UNPCKLPD_x_xm, op & SLJIT_F32_OP, src, src, 0));
|
||||
FAIL_IF(emit_sse2_logic(compiler, UNPCKLPD_x_xm, op & SLJIT_32, src, src, 0));
|
||||
}
|
||||
else {
|
||||
FAIL_IF(emit_sse2_load(compiler, !(op & SLJIT_F32_OP), TMP_FREG, src, srcw));
|
||||
FAIL_IF(emit_sse2_load(compiler, !(op & SLJIT_32), TMP_FREG, src, srcw));
|
||||
src = TMP_FREG;
|
||||
}
|
||||
|
||||
FAIL_IF(emit_sse2_logic(compiler, CVTPD2PS_x_xm, op & SLJIT_F32_OP, dst_r, src, 0));
|
||||
FAIL_IF(emit_sse2_logic(compiler, CVTPD2PS_x_xm, op & SLJIT_32, dst_r, src, 0));
|
||||
if (dst_r == TMP_FREG)
|
||||
return emit_sse2_store(compiler, op & SLJIT_F32_OP, dst, dstw, TMP_FREG);
|
||||
return emit_sse2_store(compiler, op & SLJIT_32, dst, dstw, TMP_FREG);
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
if (FAST_IS_REG(dst)) {
|
||||
dst_r = dst;
|
||||
if (dst != src)
|
||||
FAIL_IF(emit_sse2_load(compiler, op & SLJIT_F32_OP, dst_r, src, srcw));
|
||||
FAIL_IF(emit_sse2_load(compiler, op & SLJIT_32, dst_r, src, srcw));
|
||||
}
|
||||
else {
|
||||
dst_r = TMP_FREG;
|
||||
FAIL_IF(emit_sse2_load(compiler, op & SLJIT_F32_OP, dst_r, src, srcw));
|
||||
FAIL_IF(emit_sse2_load(compiler, op & SLJIT_32, dst_r, src, srcw));
|
||||
}
|
||||
|
||||
switch (GET_OPCODE(op)) {
|
||||
case SLJIT_NEG_F64:
|
||||
FAIL_IF(emit_sse2_logic(compiler, XORPD_x_xm, 1, dst_r, SLJIT_MEM0(), (sljit_sw)(op & SLJIT_F32_OP ? sse2_buffer : sse2_buffer + 8)));
|
||||
FAIL_IF(emit_sse2_logic(compiler, XORPD_x_xm, 1, dst_r, SLJIT_MEM0(), (sljit_sw)(op & SLJIT_32 ? sse2_buffer : sse2_buffer + 8)));
|
||||
break;
|
||||
|
||||
case SLJIT_ABS_F64:
|
||||
FAIL_IF(emit_sse2_logic(compiler, ANDPD_x_xm, 1, dst_r, SLJIT_MEM0(), (sljit_sw)(op & SLJIT_F32_OP ? sse2_buffer + 4 : sse2_buffer + 12)));
|
||||
FAIL_IF(emit_sse2_logic(compiler, ANDPD_x_xm, 1, dst_r, SLJIT_MEM0(), (sljit_sw)(op & SLJIT_32 ? sse2_buffer + 4 : sse2_buffer + 12)));
|
||||
break;
|
||||
}
|
||||
|
||||
if (dst_r == TMP_FREG)
|
||||
return emit_sse2_store(compiler, op & SLJIT_F32_OP, dst, dstw, TMP_FREG);
|
||||
return emit_sse2_store(compiler, op & SLJIT_32, dst, dstw, TMP_FREG);
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -2636,37 +2621,37 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop2(struct sljit_compiler *compil
|
|||
src2w = src1w;
|
||||
}
|
||||
else if (dst != src2)
|
||||
FAIL_IF(emit_sse2_load(compiler, op & SLJIT_F32_OP, dst_r, src1, src1w));
|
||||
FAIL_IF(emit_sse2_load(compiler, op & SLJIT_32, dst_r, src1, src1w));
|
||||
else {
|
||||
dst_r = TMP_FREG;
|
||||
FAIL_IF(emit_sse2_load(compiler, op & SLJIT_F32_OP, TMP_FREG, src1, src1w));
|
||||
FAIL_IF(emit_sse2_load(compiler, op & SLJIT_32, TMP_FREG, src1, src1w));
|
||||
}
|
||||
}
|
||||
else {
|
||||
dst_r = TMP_FREG;
|
||||
FAIL_IF(emit_sse2_load(compiler, op & SLJIT_F32_OP, TMP_FREG, src1, src1w));
|
||||
FAIL_IF(emit_sse2_load(compiler, op & SLJIT_32, TMP_FREG, src1, src1w));
|
||||
}
|
||||
|
||||
switch (GET_OPCODE(op)) {
|
||||
case SLJIT_ADD_F64:
|
||||
FAIL_IF(emit_sse2(compiler, ADDSD_x_xm, op & SLJIT_F32_OP, dst_r, src2, src2w));
|
||||
FAIL_IF(emit_sse2(compiler, ADDSD_x_xm, op & SLJIT_32, dst_r, src2, src2w));
|
||||
break;
|
||||
|
||||
case SLJIT_SUB_F64:
|
||||
FAIL_IF(emit_sse2(compiler, SUBSD_x_xm, op & SLJIT_F32_OP, dst_r, src2, src2w));
|
||||
FAIL_IF(emit_sse2(compiler, SUBSD_x_xm, op & SLJIT_32, dst_r, src2, src2w));
|
||||
break;
|
||||
|
||||
case SLJIT_MUL_F64:
|
||||
FAIL_IF(emit_sse2(compiler, MULSD_x_xm, op & SLJIT_F32_OP, dst_r, src2, src2w));
|
||||
FAIL_IF(emit_sse2(compiler, MULSD_x_xm, op & SLJIT_32, dst_r, src2, src2w));
|
||||
break;
|
||||
|
||||
case SLJIT_DIV_F64:
|
||||
FAIL_IF(emit_sse2(compiler, DIVSD_x_xm, op & SLJIT_F32_OP, dst_r, src2, src2w));
|
||||
FAIL_IF(emit_sse2(compiler, DIVSD_x_xm, op & SLJIT_32, dst_r, src2, src2w));
|
||||
break;
|
||||
}
|
||||
|
||||
if (dst_r == TMP_FREG)
|
||||
return emit_sse2_store(compiler, op & SLJIT_F32_OP, dst, dstw, TMP_FREG);
|
||||
return emit_sse2_store(compiler, op & SLJIT_32, dst, dstw, TMP_FREG);
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -2708,7 +2693,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compile
|
|||
|
||||
jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
|
||||
PTR_FAIL_IF_NULL(jump);
|
||||
set_jump(jump, compiler, (type & SLJIT_REWRITABLE_JUMP) | ((type & 0xff) << TYPE_SHIFT));
|
||||
set_jump(jump, compiler, (sljit_u32)((type & SLJIT_REWRITABLE_JUMP) | ((type & 0xff) << TYPE_SHIFT)));
|
||||
type &= 0xff;
|
||||
|
||||
/* Worst case size. */
|
||||
|
@ -2740,8 +2725,8 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_ijump(struct sljit_compiler *compi
|
|||
if (src == SLJIT_IMM) {
|
||||
jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
|
||||
FAIL_IF_NULL(jump);
|
||||
set_jump(jump, compiler, JUMP_ADDR | (type << TYPE_SHIFT));
|
||||
jump->u.target = srcw;
|
||||
set_jump(jump, compiler, (sljit_u32)(JUMP_ADDR | (type << TYPE_SHIFT)));
|
||||
jump->u.target = (sljit_uw)srcw;
|
||||
|
||||
/* Worst case size. */
|
||||
#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
|
||||
|
@ -2764,7 +2749,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_ijump(struct sljit_compiler *compi
|
|||
inst = emit_x86_instruction(compiler, 1, 0, 0, src, srcw);
|
||||
FAIL_IF(!inst);
|
||||
*inst++ = GROUP_FF;
|
||||
*inst |= (type >= SLJIT_FAST_CALL) ? CALL_rm : JMP_rm;
|
||||
*inst = U8(*inst | ((type >= SLJIT_FAST_CALL) ? CALL_rm : JMP_rm));
|
||||
}
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
@ -2790,7 +2775,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_flags(struct sljit_compiler *co
|
|||
|
||||
type &= 0xff;
|
||||
/* setcc = jcc + 0x10. */
|
||||
cond_set = get_jump_code(type) + 0x10;
|
||||
cond_set = U8(get_jump_code((sljit_uw)type) + 0x10);
|
||||
|
||||
#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
|
||||
if (GET_OPCODE(op) == SLJIT_OR && !GET_ALL_FLAGS(op) && FAST_IS_REG(dst)) {
|
||||
|
@ -2802,9 +2787,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_flags(struct sljit_compiler *co
|
|||
*inst++ = GROUP_0F;
|
||||
*inst++ = cond_set;
|
||||
*inst++ = MOD_REG | reg_lmap[TMP_REG1];
|
||||
*inst++ = REX | (reg_map[TMP_REG1] <= 7 ? 0 : REX_R) | (reg_map[dst] <= 7 ? 0 : REX_B);
|
||||
*inst++ = U8(REX | (reg_map[TMP_REG1] <= 7 ? 0 : REX_R) | (reg_map[dst] <= 7 ? 0 : REX_B));
|
||||
*inst++ = OR_rm8_r8;
|
||||
*inst++ = MOD_REG | (reg_lmap[TMP_REG1] << 3) | reg_lmap[dst];
|
||||
*inst++ = U8(MOD_REG | (reg_lmap[TMP_REG1] << 3) | reg_lmap[dst]);
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -2822,7 +2807,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_flags(struct sljit_compiler *co
|
|||
/* The movzx instruction does not affect flags. */
|
||||
*inst++ = GROUP_0F;
|
||||
*inst++ = MOVZX_r_rm8;
|
||||
*inst = MOD_REG | (reg_lmap[reg] << 3) | reg_lmap[reg];
|
||||
*inst = U8(MOD_REG | (reg_lmap[reg] << 3) | reg_lmap[reg]);
|
||||
|
||||
if (reg != TMP_REG1)
|
||||
return SLJIT_SUCCESS;
|
||||
|
@ -2849,11 +2834,11 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_flags(struct sljit_compiler *co
|
|||
/* Set low byte to conditional flag. */
|
||||
*inst++ = GROUP_0F;
|
||||
*inst++ = cond_set;
|
||||
*inst++ = MOD_REG | reg_map[dst];
|
||||
*inst++ = U8(MOD_REG | reg_map[dst]);
|
||||
|
||||
*inst++ = GROUP_0F;
|
||||
*inst++ = MOVZX_r_rm8;
|
||||
*inst = MOD_REG | (reg_map[dst] << 3) | reg_map[dst];
|
||||
*inst = U8(MOD_REG | (reg_map[dst] << 3) | reg_map[dst]);
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -2872,15 +2857,15 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_flags(struct sljit_compiler *co
|
|||
|
||||
*inst++ = GROUP_0F;
|
||||
/* cmovcc = setcc - 0x50. */
|
||||
*inst++ = cond_set - 0x50;
|
||||
*inst++ = MOD_REG | (reg_map[dst] << 3) | reg_map[TMP_REG1];
|
||||
*inst++ = U8(cond_set - 0x50);
|
||||
*inst++ = U8(MOD_REG | (reg_map[dst] << 3) | reg_map[TMP_REG1]);
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
inst = (sljit_u8*)ensure_buf(compiler, 1 + 1 + 3 + 3 + 1);
|
||||
FAIL_IF(!inst);
|
||||
INC_SIZE(1 + 3 + 3 + 1);
|
||||
*inst++ = XCHG_EAX_r + reg_map[TMP_REG1];
|
||||
*inst++ = U8(XCHG_EAX_r | reg_map[TMP_REG1]);
|
||||
/* Set al to conditional flag. */
|
||||
*inst++ = GROUP_0F;
|
||||
*inst++ = cond_set;
|
||||
|
@ -2888,8 +2873,8 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_flags(struct sljit_compiler *co
|
|||
|
||||
*inst++ = GROUP_0F;
|
||||
*inst++ = MOVZX_r_rm8;
|
||||
*inst++ = MOD_REG | (reg_map[dst] << 3) | 0 /* eax */;
|
||||
*inst++ = XCHG_EAX_r + reg_map[TMP_REG1];
|
||||
*inst++ = U8(MOD_REG | (reg_map[dst] << 3) | 0 /* eax */);
|
||||
*inst++ = U8(XCHG_EAX_r | reg_map[TMP_REG1]);
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -2901,13 +2886,13 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_flags(struct sljit_compiler *co
|
|||
FAIL_IF(!inst);
|
||||
INC_SIZE(1 + 3 + 2 + 1);
|
||||
/* Set low register to conditional flag. */
|
||||
*inst++ = XCHG_EAX_r + reg_map[TMP_REG1];
|
||||
*inst++ = U8(XCHG_EAX_r | reg_map[TMP_REG1]);
|
||||
*inst++ = GROUP_0F;
|
||||
*inst++ = cond_set;
|
||||
*inst++ = MOD_REG | 0 /* eax */;
|
||||
*inst++ = OR_rm8_r8;
|
||||
*inst++ = MOD_REG | (0 /* eax */ << 3) | reg_map[dst];
|
||||
*inst++ = XCHG_EAX_r + reg_map[TMP_REG1];
|
||||
*inst++ = U8(XCHG_EAX_r | reg_map[TMP_REG1]);
|
||||
}
|
||||
else {
|
||||
inst = (sljit_u8*)ensure_buf(compiler, 1 + 2 + 3 + 2 + 2);
|
||||
|
@ -2915,14 +2900,14 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_flags(struct sljit_compiler *co
|
|||
INC_SIZE(2 + 3 + 2 + 2);
|
||||
/* Set low register to conditional flag. */
|
||||
*inst++ = XCHG_r_rm;
|
||||
*inst++ = MOD_REG | (1 /* ecx */ << 3) | reg_map[TMP_REG1];
|
||||
*inst++ = U8(MOD_REG | (1 /* ecx */ << 3) | reg_map[TMP_REG1]);
|
||||
*inst++ = GROUP_0F;
|
||||
*inst++ = cond_set;
|
||||
*inst++ = MOD_REG | 1 /* ecx */;
|
||||
*inst++ = OR_rm8_r8;
|
||||
*inst++ = MOD_REG | (1 /* ecx */ << 3) | 0 /* eax */;
|
||||
*inst++ = XCHG_r_rm;
|
||||
*inst++ = MOD_REG | (1 /* ecx */ << 3) | reg_map[TMP_REG1];
|
||||
*inst++ = U8(MOD_REG | (1 /* ecx */ << 3) | reg_map[TMP_REG1]);
|
||||
}
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
@ -2931,7 +2916,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_flags(struct sljit_compiler *co
|
|||
inst = (sljit_u8*)ensure_buf(compiler, 1 + 1 + 3 + 3 + 1);
|
||||
FAIL_IF(!inst);
|
||||
INC_SIZE(1 + 3 + 3 + 1);
|
||||
*inst++ = XCHG_EAX_r + reg_map[TMP_REG1];
|
||||
*inst++ = U8(XCHG_EAX_r | reg_map[TMP_REG1]);
|
||||
/* Set al to conditional flag. */
|
||||
*inst++ = GROUP_0F;
|
||||
*inst++ = cond_set;
|
||||
|
@ -2941,7 +2926,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_flags(struct sljit_compiler *co
|
|||
*inst++ = MOVZX_r_rm8;
|
||||
*inst++ = MOD_REG | (0 << 3) /* eax */ | 0 /* eax */;
|
||||
|
||||
*inst++ = XCHG_EAX_r + reg_map[TMP_REG1];
|
||||
*inst++ = U8(XCHG_EAX_r | reg_map[TMP_REG1]);
|
||||
|
||||
if (GET_OPCODE(op) < SLJIT_ADD)
|
||||
return emit_mov(compiler, dst, dstw, TMP_REG1, 0);
|
||||
|
@ -2964,7 +2949,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_cmov(struct sljit_compiler *compil
|
|||
CHECK(check_sljit_emit_cmov(compiler, type, dst_reg, src, srcw));
|
||||
|
||||
#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
|
||||
dst_reg &= ~SLJIT_I32_OP;
|
||||
dst_reg &= ~SLJIT_32;
|
||||
|
||||
if (!sljit_has_cpu_feature(SLJIT_HAS_CMOV) || (dst_reg >= SLJIT_R3 && dst_reg <= SLJIT_S3))
|
||||
return sljit_emit_cmov_generic(compiler, type, dst_reg, src, srcw);
|
||||
|
@ -2977,8 +2962,8 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_cmov(struct sljit_compiler *compil
|
|||
CHECK_EXTRA_REGS(src, srcw, (void)0);
|
||||
|
||||
#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
|
||||
compiler->mode32 = dst_reg & SLJIT_I32_OP;
|
||||
dst_reg &= ~SLJIT_I32_OP;
|
||||
compiler->mode32 = dst_reg & SLJIT_32;
|
||||
dst_reg &= ~SLJIT_32;
|
||||
#endif
|
||||
|
||||
if (SLJIT_UNLIKELY(src & SLJIT_IMM)) {
|
||||
|
@ -2990,7 +2975,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_cmov(struct sljit_compiler *compil
|
|||
inst = emit_x86_instruction(compiler, 2, dst_reg, 0, src, srcw);
|
||||
FAIL_IF(!inst);
|
||||
*inst++ = GROUP_0F;
|
||||
*inst = get_jump_code(type & 0xff) - 0x40;
|
||||
*inst = U8(get_jump_code(type & 0xff) - 0x40);
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -3123,9 +3108,9 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_ta
|
|||
|
||||
SLJIT_UPDATE_WX_FLAGS((void*)addr, (void*)(addr + sizeof(sljit_uw)), 0);
|
||||
#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
|
||||
sljit_unaligned_store_sw((void*)addr, new_target - (addr + 4) - (sljit_uw)executable_offset);
|
||||
sljit_unaligned_store_sw((void*)addr, (sljit_sw)(new_target - (addr + 4) - (sljit_uw)executable_offset));
|
||||
#else
|
||||
sljit_unaligned_store_sw((void*)addr, (sljit_sw) new_target);
|
||||
sljit_unaligned_store_sw((void*)addr, (sljit_sw)new_target);
|
||||
#endif
|
||||
SLJIT_UPDATE_WX_FLAGS((void*)addr, (void*)(addr + sizeof(sljit_uw)), 1);
|
||||
}
|
||||
|
|
|
@ -66,7 +66,7 @@
|
|||
/* --------------------------------------------------------------------- */
|
||||
|
||||
/* 64 KByte. */
|
||||
#define CHUNK_SIZE 0x10000
|
||||
#define CHUNK_SIZE (sljit_uw)0x10000
|
||||
|
||||
struct chunk_header {
|
||||
void *executable;
|
||||
|
@ -194,7 +194,7 @@ static SLJIT_INLINE struct chunk_header* alloc_chunk(sljit_uw size)
|
|||
if (fd == -1)
|
||||
return NULL;
|
||||
|
||||
if (ftruncate(fd, size)) {
|
||||
if (ftruncate(fd, (off_t)size)) {
|
||||
close(fd);
|
||||
return NULL;
|
||||
}
|
||||
|
@ -281,7 +281,7 @@ struct free_block {
|
|||
#define AS_FREE_BLOCK(base, offset) \
|
||||
((struct free_block*)(((sljit_u8*)base) + offset))
|
||||
#define MEM_START(base) ((void*)((base) + 1))
|
||||
#define ALIGN_SIZE(size) (((size) + sizeof(struct block_header) + 7) & ~7)
|
||||
#define ALIGN_SIZE(size) (((size) + sizeof(struct block_header) + 7u) & ~(sljit_uw)7)
|
||||
|
||||
static struct free_block* free_blocks;
|
||||
static sljit_uw allocated_size;
|
||||
|
|
|
@ -131,12 +131,12 @@ static SLJIT_INLINE int open_dev_zero(void)
|
|||
|
||||
#ifdef _WIN32
|
||||
|
||||
static SLJIT_INLINE sljit_sw get_page_alignment(void) {
|
||||
static SLJIT_INLINE sljit_uw get_page_alignment(void) {
|
||||
SYSTEM_INFO si;
|
||||
static sljit_sw sljit_page_align;
|
||||
static sljit_uw sljit_page_align = 0;
|
||||
if (!sljit_page_align) {
|
||||
GetSystemInfo(&si);
|
||||
sljit_page_align = si.dwPageSize - 1;
|
||||
sljit_page_align = (sljit_uw)si.dwPageSize - 1;
|
||||
}
|
||||
return sljit_page_align;
|
||||
}
|
||||
|
@ -145,18 +145,21 @@ static SLJIT_INLINE sljit_sw get_page_alignment(void) {
|
|||
|
||||
#include <unistd.h>
|
||||
|
||||
static SLJIT_INLINE sljit_sw get_page_alignment(void) {
|
||||
static sljit_sw sljit_page_align = -1;
|
||||
if (sljit_page_align < 0) {
|
||||
static SLJIT_INLINE sljit_uw get_page_alignment(void) {
|
||||
static sljit_uw sljit_page_align = 0;
|
||||
|
||||
sljit_sw align;
|
||||
|
||||
if (!sljit_page_align) {
|
||||
#ifdef _SC_PAGESIZE
|
||||
sljit_page_align = sysconf(_SC_PAGESIZE);
|
||||
align = sysconf(_SC_PAGESIZE);
|
||||
#else
|
||||
sljit_page_align = getpagesize();
|
||||
align = getpagesize();
|
||||
#endif
|
||||
/* Should never happen. */
|
||||
if (sljit_page_align < 0)
|
||||
sljit_page_align = 4096;
|
||||
sljit_page_align--;
|
||||
if (align < 0)
|
||||
align = 4096;
|
||||
sljit_page_align = (sljit_uw)align - 1;
|
||||
}
|
||||
return sljit_page_align;
|
||||
}
|
||||
|
@ -227,7 +230,7 @@ SLJIT_API_FUNC_ATTRIBUTE void SLJIT_FUNC sljit_free_stack(struct sljit_stack *st
|
|||
SLJIT_API_FUNC_ATTRIBUTE void SLJIT_FUNC sljit_free_stack(struct sljit_stack *stack, void *allocator_data)
|
||||
{
|
||||
SLJIT_UNUSED_ARG(allocator_data);
|
||||
munmap((void*)stack->min_start, stack->end - stack->min_start);
|
||||
munmap((void*)stack->min_start, (size_t)(stack->end - stack->min_start));
|
||||
SLJIT_FREE(stack, allocator_data);
|
||||
}
|
||||
|
||||
|
@ -237,7 +240,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_stack* SLJIT_FUNC sljit_allocate_stack(slj
|
|||
{
|
||||
struct sljit_stack *stack;
|
||||
void *ptr;
|
||||
sljit_sw page_align;
|
||||
sljit_uw page_align;
|
||||
|
||||
SLJIT_UNUSED_ARG(allocator_data);
|
||||
|
||||
|
@ -295,7 +298,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_u8 *SLJIT_FUNC sljit_stack_resize(struct sljit_st
|
|||
#if defined _WIN32 || defined(POSIX_MADV_DONTNEED)
|
||||
sljit_uw aligned_old_start;
|
||||
sljit_uw aligned_new_start;
|
||||
sljit_sw page_align;
|
||||
sljit_uw page_align;
|
||||
#endif
|
||||
|
||||
if ((new_start < stack->min_start) || (new_start >= stack->end))
|
||||
|
|
Loading…
Reference in New Issue