diff --git a/sljit_src/sljitNativeRISCV_32.c b/sljit_src/sljitNativeRISCV_32.c index 23780b98..44b95568 100644 --- a/sljit_src/sljitNativeRISCV_32.c +++ b/sljit_src/sljitNativeRISCV_32.c @@ -29,7 +29,7 @@ static sljit_s32 load_immediate(struct sljit_compiler *compiler, sljit_s32 dst_r SLJIT_UNUSED_ARG(tmp_r); if (RISCV_HAS_COMPRESSED(200) && imm <= SIMM16_MAX && imm >= SIMM16_MIN) - return push_inst16(compiler, C_LI | C_RD(dst_r) | CIMM_I(imm)); + return push_inst16(compiler, C_LI | C_RD(dst_r) | C_IMM_I(imm)); if (imm <= SIMM_MAX && imm >= SIMM_MIN) return push_inst(compiler, ADDI | RD(dst_r) | RS1(TMP_ZERO) | IMM_I(imm)); @@ -48,7 +48,7 @@ static sljit_s32 load_immediate(struct sljit_compiler *compiler, sljit_s32 dst_r return SLJIT_SUCCESS; if (RISCV_HAS_COMPRESSED(200) && (imm <= 0x1f || imm >= 0xfe0)) - return push_inst16(compiler, C_ADDI | C_RD(dst_r) | CIMM_I(imm)); + return push_inst16(compiler, C_ADDI | C_RD(dst_r) | C_IMM_I(imm)); return push_inst(compiler, ADDI | RD(dst_r) | RS1(dst_r) | IMM_I(imm)); } diff --git a/sljit_src/sljitNativeRISCV_64.c b/sljit_src/sljitNativeRISCV_64.c index 9111c2a5..9ecfae3f 100644 --- a/sljit_src/sljitNativeRISCV_64.c +++ b/sljit_src/sljitNativeRISCV_64.c @@ -58,7 +58,7 @@ static sljit_s32 load_immediate32(struct sljit_compiler *compiler, sljit_s32 dst return SLJIT_SUCCESS; if (RISCV_HAS_COMPRESSED(200) && (imm <= 0x1f || imm >= 0xfe0)) - return push_inst16(compiler, C_ADDI | C_RD(dst_r) | CIMM_I(imm)); + return push_inst16(compiler, C_ADDI | C_RD(dst_r) | C_IMM_I(imm)); return push_inst(compiler, ADDI | RD(dst_r) | RS1(dst_r) | IMM_I(imm)); } @@ -68,7 +68,7 @@ static sljit_s32 load_immediate(struct sljit_compiler *compiler, sljit_s32 dst_r sljit_sw high; if (RISCV_HAS_COMPRESSED(200) && imm <= SIMM16_MAX && imm >= SIMM16_MIN) - return push_inst16(compiler, C_LI | C_RD(dst_r) | CIMM_I(imm)); + return push_inst16(compiler, C_LI | C_RD(dst_r) | C_IMM_I(imm)); if (imm <= SIMM_MAX && imm >= SIMM_MIN) return push_inst(compiler, ADDI | RD(dst_r) | RS1(TMP_ZERO) | IMM_I(imm)); @@ -118,7 +118,7 @@ static sljit_s32 load_immediate(struct sljit_compiler *compiler, sljit_s32 dst_r if (imm <= SIMM_MAX && imm >= SIMM_MIN) { if (RISCV_HAS_COMPRESSED(200) && imm <= 0x1f && imm >= -0x20) - FAIL_IF(push_inst16(compiler, C_LI | C_RD(dst_r) | CIMM_I(imm))); + FAIL_IF(push_inst16(compiler, C_LI | C_RD(dst_r) | C_IMM_I(imm))); else FAIL_IF(push_inst(compiler, ADDI | RD(dst_r) | RS1(TMP_ZERO) | IMM_I(imm))); imm = 0; @@ -141,7 +141,7 @@ static sljit_s32 load_immediate(struct sljit_compiler *compiler, sljit_s32 dst_r if ((high & 0xfff) != 0) { SLJIT_ASSERT(high <= 0xfff); if (RISCV_HAS_COMPRESSED(200) && (high <= 0x1f || high >= 0xfe0)) - FAIL_IF(push_inst16(compiler, C_ADDI | C_RD(tmp_r) | CIMM_I(high))); + FAIL_IF(push_inst16(compiler, C_ADDI | C_RD(tmp_r) | C_IMM_I(high))); else FAIL_IF(push_inst(compiler, ADDI | RD(tmp_r) | RS1(tmp_r) | IMM_I(high))); } @@ -151,7 +151,7 @@ static sljit_s32 load_immediate(struct sljit_compiler *compiler, sljit_s32 dst_r else if (imm != 0) { SLJIT_ASSERT(imm <= 0xfff); if (RISCV_HAS_COMPRESSED(200) && (imm <= 0x1f || imm >= 0xfe0)) - FAIL_IF(push_inst16(compiler, C_ADDI | C_RD(dst_r) | CIMM_I(imm))); + FAIL_IF(push_inst16(compiler, C_ADDI | C_RD(dst_r) | C_IMM_I(imm))); else FAIL_IF(push_inst(compiler, ADDI | RD(dst_r) | RS1(dst_r) | IMM_I(imm))); } diff --git a/sljit_src/sljitNativeRISCV_common.c b/sljit_src/sljitNativeRISCV_common.c index 2df558b4..5925d566 100644 --- a/sljit_src/sljitNativeRISCV_common.c +++ b/sljit_src/sljitNativeRISCV_common.c @@ -198,7 +198,7 @@ static const sljit_u8 vreg_map[SLJIT_NUMBER_OF_VECTOR_REGISTERS + 3] = { #define C_FRS2_R3(rs2) ((sljit_u16)((sljit_u16)(freg_map[rs2] & 0x7) << 2)) #define C_IS_R3(r) ((reg_map[r] & 0x18) == 0x08) #define C_IS_FR3(r) ((freg_map[r] & 0x18) == 0x08) -#define CIMM_I(imm) ((sljit_u16)((((imm) & 0x1f) << 2) | (((imm) & 0x20) << 7))) +#define C_IMM_I(imm) ((sljit_u16)((((imm) & 0x1f) << 2) | (((imm) & 0x20) << 7))) #define C_LD32_SP(imm) ((sljit_u16)((((imm) & 0x1c) << 2) | (((imm) & 0x20) << 7) | (((imm) & 0xc0) >> 4))) #define C_ST32_SP(imm) ((sljit_u16)((((imm) & 0x3c) << 7) | (((imm) & 0xc0) << 1))) #define C_LD64_SP(imm) ((sljit_u16)((((imm) & 0x18) << 2) | (((imm) & 0x20) << 7) | (((imm) & 0x1c0) >> 4))) @@ -237,7 +237,10 @@ static const sljit_u8 vreg_map[SLJIT_NUMBER_OF_VECTOR_REGISTERS + 3] = { #define C_ADD (C_OPC(0x2, 0x4) | (sljit_u16)(1 << 12)) #define C_ADDI (C_OPC(0x1, 0x0)) #define C_ADDIW (C_OPC(0x1, 0x1)) +#define C_ADDW (C_OPC(0x1, 0x4) | (sljit_u16)(7 << 10) | (sljit_u16)(1 << 5)) #define C_ADDI16SP (C_OPC(0x1, 0x3) | (sljit_u16)(2 << 7)) +#define C_AND (C_OPC(0x1, 0x4) | (sljit_u16)(3 << 10) | (sljit_u16)(3 << 5)) +#define C_ANDI (C_OPC(0x1, 0x4) | (sljit_u16)(2 << 10)) #define C_EBREAK (C_OPC(0x2, 0x4) | (sljit_u16)(1 << 12)) #define C_FLDSP (C_OPC(0x2, 0x1)) #define C_FLWSP (C_OPC(0x2, 0x3)) @@ -257,11 +260,16 @@ static const sljit_u8 vreg_map[SLJIT_NUMBER_OF_VECTOR_REGISTERS + 3] = { #define C_LWSP (C_OPC(0x2, 0x2)) #define C_MV (C_OPC(0x2, 0x4)) #define C_NOP (C_OPC(0x1, 0x0)) -#define C_SLLI (C_OPC(0x2, 0x0)) #define C_SD (C_OPC(0x0, 0x7)) #define C_SDSP (C_OPC(0x2, 0x7)) +#define C_SLLI (C_OPC(0x2, 0x0)) +#define C_OR (C_OPC(0x1, 0x4) | (sljit_u16)(3 << 10) | (sljit_u16)(2 << 5)) +#define C_SRAI (C_OPC(0x1, 0x4) | (sljit_u16)(1 << 10)) +#define C_SRLI (C_OPC(0x1, 0x4) | (sljit_u16)(0 << 10)) +#define C_SUB (C_OPC(0x1, 0x4) | (sljit_u16)(3 << 10) | (sljit_u16)(0 << 5)) #define C_SW (C_OPC(0x0, 0x6)) #define C_SWSP (C_OPC(0x2, 0x6)) +#define C_XOR (C_OPC(0x1, 0x4) | (sljit_u16)(3 << 10) | (sljit_u16)(1 << 5)) /* CLZ / CTZ: zbb */ #define CLZ (F7(0x30) | F3(0x1) | OPC(0x13)) #define CTZ (F7(0x30) | F12(0x1) | F3(0x1) | OPC(0x13)) @@ -389,6 +397,7 @@ static const sljit_u8 vreg_map[SLJIT_NUMBER_OF_VECTOR_REGISTERS + 3] = { #endif /* SLJIT_CONFIG_RISCV_64 */ #define C_ADDI_W(word) (C_ADDI | (sljit_u16)((word) << 10)) +#define C_SUB_W(word) (C_SUB | (sljit_u16)((word) << 9)) static sljit_s32 push_inst(struct sljit_compiler *compiler, sljit_ins ins) { @@ -1752,24 +1761,32 @@ static sljit_s32 emit_rev16(struct sljit_compiler *compiler, sljit_s32 op, sljit return push_inst(compiler, OR | RD(dst) | RS1(dst) | RS2(TMP_REG1)); } -#define EMIT_LOGICAL(op_imm, op_reg) \ +#define EMIT_LOGICAL(op_imm, op_c_imm, op_reg, op_c_reg) \ if (flags & SRC2_IMM) { \ if (op & SLJIT_SET_Z) \ FAIL_IF(push_inst(compiler, op_imm | RD(EQUAL_FLAG) | RS1(src1) | IMM_I(src2))); \ - if (!(flags & UNUSED_DEST)) \ - FAIL_IF(push_inst(compiler, op_imm | RD(dst) | RS1(src1) | IMM_I(src2))); \ - } \ - else { \ + if (!(flags & UNUSED_DEST)) { \ + if (op_c_imm != 0 && RISCV_HAS_COMPRESSED(200) && dst == src1 && src2 <= SIMM16_MAX && src2 >= SIMM16_MIN && C_IS_R3(dst)) \ + FAIL_IF(push_inst16(compiler, op_c_imm | C_RS1_R3(dst) | C_IMM_I(src2))); \ + else \ + FAIL_IF(push_inst(compiler, op_imm | RD(dst) | RS1(src1) | IMM_I(src2))); \ + } \ + } else { \ + if (dst == src2) { \ + src2 = src1; \ + src1 = dst; \ + } \ + \ if (op & SLJIT_SET_Z) \ FAIL_IF(push_inst(compiler, op_reg | RD(EQUAL_FLAG) | RS1(src1) | RS2(src2))); \ - if (!(flags & UNUSED_DEST)) \ - FAIL_IF(push_inst(compiler, op_reg | RD(dst) | RS1(src1) | RS2(src2))); \ + if (!(flags & UNUSED_DEST)) { \ + if (RISCV_HAS_COMPRESSED(200) && dst == src1 && C_IS_R3(dst) && C_IS_R3(src2)) \ + FAIL_IF(push_inst16(compiler, op_c_reg | C_RS1_R3(dst) | C_RS2_R3(src2))); \ + else \ + FAIL_IF(push_inst(compiler, op_reg | RD(dst) | RS1(src1) | RS2(src2))); \ + } \ } -#define EMIT_SHIFT(imm, reg) \ - op_imm = (imm); \ - op_reg = (reg); - static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 flags, sljit_s32 dst, sljit_s32 src1, sljit_sw src2) { @@ -1920,7 +1937,7 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl if (!(flags & UNUSED_DEST) || (op & VARIABLE_FLAG_MASK)) { SLJIT_ASSERT(src2 != 0); if (RISCV_HAS_COMPRESSED(200) && dst == src1 && src2 <= SIMM16_MAX && src2 >= SIMM16_MIN) - FAIL_IF(push_inst16(compiler, C_ADDI_W(WORD) | C_RD(dst) | CIMM_I(src2))); + FAIL_IF(push_inst16(compiler, C_ADDI_W(WORD) | C_RD(dst) | C_IMM_I(src2))); else FAIL_IF(push_inst(compiler, ADDI | WORD | RD(dst) | RS1(src1) | IMM_I(src2))); } @@ -1943,8 +1960,15 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl /* Only the zero flag is needed. */ if (!(flags & UNUSED_DEST) || (op & VARIABLE_FLAG_MASK)) { + if (dst == src2) { + src2 = src1; + src1 = dst; + } + if (RISCV_HAS_COMPRESSED(200) && WORD == 0 && dst == src1 && src2 != 0) - FAIL_IF(push_inst16(compiler, C_ADD | C_RD(dst) | C_RS2(src2))); + FAIL_IF(push_inst16(compiler, C_ADD | C_RD(dst) | C_RS2(src2))); + else if (RISCV_HAS_COMPRESSED(200) && WORD == 0x8 && dst == src1 && C_IS_R3(dst) && C_IS_R3(src2)) + FAIL_IF(push_inst16(compiler, C_ADDW | C_RS1_R3(dst) | C_RS2_R3(src2))); else FAIL_IF(push_inst(compiler, ADD | WORD | RD(dst) | RS1(src1) | RS2(src2))); } @@ -1977,7 +2001,7 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl if (flags & SRC2_IMM) { SLJIT_ASSERT(src2 != 0); if (RISCV_HAS_COMPRESSED(200) && dst == src1 && src2 <= SIMM16_MAX && src2 >= SIMM16_MIN) - FAIL_IF(push_inst16(compiler, C_ADDI_W(WORD) | C_RD(dst) | CIMM_I(src2))); + FAIL_IF(push_inst16(compiler, C_ADDI_W(WORD) | C_RD(dst) | C_IMM_I(src2))); else FAIL_IF(push_inst(compiler, ADDI | WORD | RD(dst) | RS1(src1) | IMM_I(src2))); } else { @@ -1995,8 +2019,15 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl } } + if (dst == src2) { + src2 = src1; + src1 = dst; + } + if (RISCV_HAS_COMPRESSED(200) && WORD == 0 && dst == src1 && src2 != 0) FAIL_IF(push_inst16(compiler, C_ADD | C_RD(dst) | C_RS2(src2))); + else if (RISCV_HAS_COMPRESSED(200) && WORD == 0x8 && dst == src1 && C_IS_R3(dst) && C_IS_R3(src2)) + FAIL_IF(push_inst16(compiler, C_ADDW | C_RS1_R3(dst) | C_RS2_R3(src2))); else FAIL_IF(push_inst(compiler, ADD | WORD | RD(dst) | RS1(src1) | RS2(src2))); } @@ -2047,7 +2078,7 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl if (flags & SRC2_IMM) { reg = (src1 == TMP_REG1) ? TMP_REG2 : TMP_REG1; if (RISCV_HAS_COMPRESSED(200) && src2 <= SIMM16_MAX && src2 >= SIMM16_MIN) - FAIL_IF(push_inst16(compiler, C_LI | C_RD(reg) | CIMM_I(src2))); + FAIL_IF(push_inst16(compiler, C_LI | C_RD(reg) | C_IMM_I(src2))); else FAIL_IF(push_inst(compiler, ADDI | RD(reg) | RS1(TMP_ZERO) | IMM_I(src2))); @@ -2078,15 +2109,19 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl if (!(flags & UNUSED_DEST)) { src2 = -src2; if (RISCV_HAS_COMPRESSED(200) && dst == src1 && src2 <= SIMM16_MAX && src2 >= SIMM16_MIN) - return push_inst16(compiler, C_ADDI_W(WORD) | C_RD(dst) | CIMM_I(src2)); + return push_inst16(compiler, C_ADDI_W(WORD) | C_RD(dst) | C_IMM_I(src2)); return push_inst(compiler, ADDI | WORD | RD(dst) | RS1(src1) | IMM_I(src2)); } } else { if (op & SLJIT_SET_Z) FAIL_IF(push_inst(compiler, SUB | WORD | RD(EQUAL_FLAG) | RS1(src1) | RS2(src2))); - if (!(flags & UNUSED_DEST)) + if (!(flags & UNUSED_DEST)) { + if (RISCV_HAS_COMPRESSED(200) && dst == src1 && C_IS_R3(dst) && C_IS_R3(src2)) + return push_inst16(compiler, C_SUB_W(WORD) | C_RS1_R3(dst) | C_RS2_R3(src2)); + return push_inst(compiler, SUB | WORD | RD(dst) | RS1(src1) | RS2(src2)); + } } return SLJIT_SUCCESS; } @@ -2113,7 +2148,7 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl if (!(flags & UNUSED_DEST) || (op & VARIABLE_FLAG_MASK)) { src2 = -src2; if (RISCV_HAS_COMPRESSED(200) && dst == src1 && src2 <= SIMM16_MAX && src2 >= SIMM16_MIN) - FAIL_IF(push_inst16(compiler, C_ADDI_W(WORD) | C_RD(dst) | CIMM_I(src2))); + FAIL_IF(push_inst16(compiler, C_ADDI_W(WORD) | C_RD(dst) | C_IMM_I(src2))); else FAIL_IF(push_inst(compiler, ADDI | WORD | RD(dst) | RS1(src1) | IMM_I(src2))); } @@ -2127,8 +2162,12 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl FAIL_IF(push_inst(compiler, SLTU | RD(OTHER_FLAG) | RS1(src1) | RS2(src2))); /* Only the zero flag is needed. */ - if (!(flags & UNUSED_DEST) || (op & VARIABLE_FLAG_MASK)) - FAIL_IF(push_inst(compiler, SUB | WORD | RD(dst) | RS1(src1) | RS2(src2))); + if (!(flags & UNUSED_DEST) || (op & VARIABLE_FLAG_MASK)) { + if (RISCV_HAS_COMPRESSED(200) && dst == src1 && C_IS_R3(dst) && C_IS_R3(src2)) + FAIL_IF(push_inst16(compiler, C_SUB_W(WORD) | C_RS1_R3(dst) | C_RS2_R3(src2))); + else + FAIL_IF(push_inst(compiler, SUB | WORD | RD(dst) | RS1(src1) | RS2(src2))); + } } if (!is_overflow) @@ -2159,14 +2198,17 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl src2 = -src2; if (RISCV_HAS_COMPRESSED(200) && dst == src1 && src2 <= SIMM16_MAX && src2 >= SIMM16_MIN) - FAIL_IF(push_inst16(compiler, C_ADDI_W(WORD) | C_RD(dst) | CIMM_I(src2))); + FAIL_IF(push_inst16(compiler, C_ADDI_W(WORD) | C_RD(dst) | C_IMM_I(src2))); else FAIL_IF(push_inst(compiler, ADDI | WORD | RD(dst) | RS1(src1) | IMM_I(src2))); } else { if (is_carry) FAIL_IF(push_inst(compiler, SLTU | RD(EQUAL_FLAG) | RS1(src1) | RS2(src2))); - FAIL_IF(push_inst(compiler, SUB | WORD | RD(dst) | RS1(src1) | RS2(src2))); + if (RISCV_HAS_COMPRESSED(200) && dst == src1 && C_IS_R3(dst) && C_IS_R3(src2)) + FAIL_IF(push_inst16(compiler, C_SUB_W(WORD) | C_RS1_R3(dst) | C_RS2_R3(src2))); + else + FAIL_IF(push_inst(compiler, SUB | WORD | RD(dst) | RS1(src1) | RS2(src2))); } if (is_carry) @@ -2203,32 +2245,33 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl return push_inst(compiler, SUB | RD(OTHER_FLAG) | RS1(EQUAL_FLAG) | RS2(OTHER_FLAG)); case SLJIT_AND: - EMIT_LOGICAL(ANDI, AND); + EMIT_LOGICAL(ANDI, C_ANDI, AND, C_AND); return SLJIT_SUCCESS; case SLJIT_OR: - EMIT_LOGICAL(ORI, OR); + EMIT_LOGICAL(ORI, 0, OR, C_OR); return SLJIT_SUCCESS; case SLJIT_XOR: - EMIT_LOGICAL(XORI, XOR); + EMIT_LOGICAL(XORI, 0, XOR, C_XOR); return SLJIT_SUCCESS; case SLJIT_SHL: case SLJIT_MSHL: - if (RISCV_HAS_COMPRESSED(200) && dst == src1 && (flags & SRC2_IMM)) - return push_inst16(compiler, C_SLLI | C_RD(dst) | CIMM_I(src2)); - EMIT_SHIFT(SLLI, SLL); + op_imm = SLLI; + op_reg = SLL; break; case SLJIT_LSHR: case SLJIT_MLSHR: - EMIT_SHIFT(SRLI, SRL); + op_imm = SRLI; + op_reg = SRL; break; case SLJIT_ASHR: case SLJIT_MASHR: - EMIT_SHIFT(SRAI, SRA); + op_imm = SRAI; + op_reg = SRA; break; case SLJIT_ROTL: @@ -2286,6 +2329,15 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl if (flags & UNUSED_DEST) return SLJIT_SUCCESS; + + if (RISCV_HAS_COMPRESSED(200) && WORD == 0 && dst == src1 && (flags & SRC2_IMM)) { + if (op_imm == SLLI) + return push_inst16(compiler, C_SLLI | C_RD(dst) | C_IMM_I(src2)); + + if (C_IS_R3(dst)) + return push_inst16(compiler, (op_imm == SRLI ? C_SRLI : C_SRAI) | C_RS1_R3(dst) | C_IMM_I(src2)); + } + return push_inst(compiler, op_imm | WORD | RD(dst) | RS1(src1) | IMM_I(src2)); } diff --git a/test_src/sljitTest.c b/test_src/sljitTest.c index da4fb945..c6020e9f 100644 --- a/test_src/sljitTest.c +++ b/test_src/sljitTest.c @@ -533,7 +533,7 @@ static void test6(void) /* Test addc, sub, subc. */ executable_code code; struct sljit_compiler* compiler = sljit_create_compiler(NULL); - sljit_sw buf[21]; + sljit_sw buf[23]; sljit_s32 i; if (verbose) @@ -541,7 +541,7 @@ static void test6(void) FAILED(!compiler, "cannot create compiler\n"); - for (i = 0; i < 21; i++) + for (i = 0; i < 23; i++) buf[i] = 0; buf[10] = 4000; @@ -629,6 +629,19 @@ static void test6(void) /* buf[20] */ sljit_emit_op2(compiler, SLJIT_SUBC, SLJIT_MEM1(SLJIT_S0), sizeof(sljit_sw) * 20, SLJIT_R2, 0, SLJIT_IMM, -4); + sljit_emit_op1(compiler, SLJIT_MOV, SLJIT_R1, 0, SLJIT_IMM, -100); + sljit_emit_op1(compiler, SLJIT_MOV, SLJIT_R0, 0, SLJIT_IMM, -200); + sljit_emit_op2(compiler, SLJIT_SUB, SLJIT_R1, 0, SLJIT_R1, 0, SLJIT_R0, 0); + /* buf[21] */ + sljit_emit_op1(compiler, SLJIT_MOV, SLJIT_MEM1(SLJIT_S0), sizeof(sljit_sw) * 21, SLJIT_R1, 0); + + sljit_emit_op1(compiler, SLJIT_MOV, SLJIT_R0, 0, SLJIT_IMM, 0); + sljit_emit_op1(compiler, SLJIT_MOV, SLJIT_R1, 0, SLJIT_IMM, 1); + sljit_emit_op2(compiler, SLJIT_SUB | SLJIT_SET_CARRY, SLJIT_R0, 0, SLJIT_R0, 0, SLJIT_IMM, 1); + sljit_emit_op2(compiler, SLJIT_SUBC, SLJIT_R0, 0, SLJIT_R0, 0, SLJIT_R1, 0); + /* buf[22] */ + sljit_emit_op1(compiler, SLJIT_MOV, SLJIT_MEM1(SLJIT_S0), sizeof(sljit_sw) * 22, SLJIT_R0, 0); + sljit_emit_op1(compiler, SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, 10); sljit_emit_op2(compiler, SLJIT_SUB | SLJIT_SET_CARRY, SLJIT_RETURN_REG, 0, SLJIT_RETURN_REG, 0, SLJIT_IMM, 5); sljit_emit_op2(compiler, SLJIT_SUBC, SLJIT_RETURN_REG, 0, SLJIT_RETURN_REG, 0, SLJIT_IMM, 2); @@ -661,6 +674,8 @@ static void test6(void) FAILED(buf[18] != 0, "test6 case 20 failed\n"); FAILED(buf[19] != 1, "test6 case 21 failed\n"); FAILED(buf[20] != 0, "test6 case 22 failed\n"); + FAILED(buf[21] != 100, "test6 case 23 failed\n"); + FAILED(buf[22] != -3, "test6 case 24 failed\n"); sljit_free_code(code.code, NULL); successful_tests++; @@ -671,19 +686,20 @@ static void test7(void) /* Test logical operators. */ executable_code code; struct sljit_compiler* compiler = sljit_create_compiler(NULL); - sljit_sw buf[8]; + sljit_s32 i; + sljit_sw buf[9]; if (verbose) printf("Run test7\n"); FAILED(!compiler, "cannot create compiler\n"); + for (i = 0; i < 9; i++) + buf[i] = 0; + buf[0] = 0xff80; buf[1] = 0x0f808080; - buf[2] = 0; buf[3] = 0xaaaaaa; - buf[4] = 0; buf[5] = 0x4040; - buf[6] = 0; buf[7] = (sljit_sw)0xc43a7f95; sljit_emit_enter(compiler, 0, SLJIT_ARGS1(W, P), 3, 1, 0); @@ -710,7 +726,11 @@ static void test7(void) /* buf[7] */ sljit_emit_op1(compiler, SLJIT_MOV, SLJIT_R0, 0, SLJIT_MEM1(SLJIT_S0), sizeof(sljit_sw) * 7); sljit_emit_op2(compiler, SLJIT_XOR, SLJIT_MEM1(SLJIT_S0), sizeof(sljit_sw) * 7, SLJIT_IMM, (sljit_sw)0xff00ff00, SLJIT_R0, 0); - /* Return vaue */ + sljit_emit_op1(compiler, SLJIT_MOV, SLJIT_R1, 0, SLJIT_IMM, 0x76); + sljit_emit_op2(compiler, SLJIT_AND, SLJIT_R1, 0, SLJIT_IMM, 0x1c, SLJIT_R1, 0); + /* buf[8] */ + sljit_emit_op1(compiler, SLJIT_MOV, SLJIT_MEM1(SLJIT_S0), sizeof(sljit_sw) * 8, SLJIT_R1, 0); + /* Return value */ sljit_emit_op1(compiler, SLJIT_MOV, SLJIT_R0, 0, SLJIT_IMM, (sljit_sw)0xff00ff00); sljit_emit_op2(compiler, SLJIT_OR, SLJIT_R1, 0, SLJIT_R0, 0, SLJIT_IMM, 0x0f); sljit_emit_op2(compiler, SLJIT_AND, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0x888888, SLJIT_R1, 0); @@ -730,6 +750,7 @@ static void test7(void) FAILED(buf[5] != 0x00FF4040, "test7 case 7 failed\n"); FAILED(buf[6] != (sljit_sw)0xa56c82c0, "test7 case 8 failed\n"); FAILED(buf[7] != 0x3b3a8095, "test7 case 9 failed\n"); + FAILED(buf[8] != 0x14, "test7 case 10 failed\n"); sljit_free_code(code.code, NULL); successful_tests++; @@ -896,7 +917,7 @@ static void test9(void) /* Test shift. */ executable_code code; struct sljit_compiler* compiler = sljit_create_compiler(NULL); - sljit_sw buf[15]; + sljit_sw buf[18]; sljit_s32 i; #ifdef SLJIT_PREF_SHIFT_REG sljit_s32 shift_reg = SLJIT_PREF_SHIFT_REG; @@ -911,7 +932,7 @@ static void test9(void) FAILED(!compiler, "cannot create compiler\n"); - for (i = 0; i < 15; i++) + for (i = 0; i < 18; i++) buf[i] = -1; buf[4] = 1 << 10; @@ -1018,6 +1039,23 @@ static void test9(void) /* buf[14] */ sljit_emit_op1(compiler, SLJIT_MOV, SLJIT_MEM1(SLJIT_S0), sizeof(sljit_sw) * 14, shift_reg, 0); + sljit_emit_op1(compiler, SLJIT_MOV, SLJIT_R0, 0, SLJIT_IMM, -0x3b7a81); + sljit_emit_op2(compiler, SLJIT_ASHR, SLJIT_R0, 0, SLJIT_R0, 0, SLJIT_IMM, 2); + /* buf[15] */ + sljit_emit_op1(compiler, SLJIT_MOV, SLJIT_MEM1(SLJIT_S0), sizeof(sljit_sw) * 15, SLJIT_R0, 0); + +#if IS_64BIT && (defined SLJIT_UPPER_BITS_IGNORED && SLJIT_UPPER_BITS_IGNORED) + sljit_emit_op1(compiler, SLJIT_MOV, SLJIT_R1, 0, SLJIT_IMM, SLJIT_W(0xf7c8e5aef)); + sljit_emit_op2(compiler, SLJIT_LSHR32, SLJIT_R1, 0, SLJIT_R1, 0, SLJIT_IMM, 4); + /* buf[16] */ + sljit_emit_op1(compiler, SLJIT_MOV32, SLJIT_MEM1(SLJIT_S0), sizeof(sljit_sw) * 16, SLJIT_R1, 0); + + sljit_emit_op1(compiler, SLJIT_MOV, SLJIT_S1, 0, SLJIT_IMM, SLJIT_W(0xff7e824baf)); + sljit_emit_op2(compiler, SLJIT_ASHR32, SLJIT_S1, 0, SLJIT_S1, 0, SLJIT_IMM, 8); + /* buf[17] */ + sljit_emit_op1(compiler, SLJIT_MOV32, SLJIT_MEM1(SLJIT_S0), sizeof(sljit_sw) * 17, SLJIT_S1, 0); +#endif /* IS_64BIT && SLJIT_UPPER_BITS_IGNORED */ + sljit_emit_return_void(compiler); code.code = sljit_generate_code(compiler, 0, NULL); @@ -1040,6 +1078,12 @@ static void test9(void) FAILED(buf[12] != 0x63f65c, "test9 case 13 failed\n"); FAILED(buf[13] != -3062, "test9 case 14 failed\n"); FAILED(buf[14] != -4691, "test9 case 15 failed\n"); + FAILED(buf[15] != -0xedea1, "test9 case 16 failed\n"); +#if IS_64BIT && (defined SLJIT_UPPER_BITS_IGNORED && SLJIT_UPPER_BITS_IGNORED) +printf("0x%x, 0x%x, ", *(sljit_s32*)(buf + 16), *(sljit_s32*)(buf + 17)); + FAILED(*(sljit_s32*)(buf + 16) != 0x7c8e5ae, "test9 case 17 failed\n"); + FAILED(*(sljit_s32*)(buf + 17) != 0x7e824b, "test9 case 18 failed\n"); +#endif /* IS_64BIT && SLJIT_UPPER_BITS_IGNORED */ sljit_free_code(code.code, NULL); successful_tests++; @@ -1416,22 +1460,20 @@ static void test15(void) /* Test 64 bit. */ executable_code code; struct sljit_compiler* compiler = sljit_create_compiler(NULL); - sljit_sw buf[11]; + sljit_s32 i; + sljit_sw buf[13]; if (verbose) printf("Run test15\n"); FAILED(!compiler, "cannot create compiler\n"); - buf[0] = 0; - buf[1] = 0; - buf[2] = 0; - buf[3] = 0; - buf[4] = 0; + for (i = 0; i < 13; i++) + buf[i] = 0; + buf[5] = 100; buf[6] = 100; buf[7] = 100; buf[8] = 100; - buf[9] = 0; #if IS_64BIT && (defined SLJIT_BIG_ENDIAN && SLJIT_BIG_ENDIAN) buf[10] = SLJIT_W(1) << 32; #else /* !IS_64BIT || !SLJIT_BIG_ENDIAN */ @@ -1480,6 +1522,15 @@ static void test15(void) sljit_emit_op2(compiler, SLJIT_SHL32, SLJIT_MEM1(SLJIT_S0), sizeof(sljit_sw) * 9, SLJIT_IMM, SLJIT_W(0xffff0000), SLJIT_R0, 0); /* buf[10] */ sljit_emit_op2(compiler, SLJIT_MUL32, SLJIT_MEM1(SLJIT_S0), sizeof(sljit_sw) * 10, SLJIT_MEM1(SLJIT_S0), sizeof(sljit_sw) * 10, SLJIT_IMM, -1); + + sljit_emit_op1(compiler, SLJIT_MOV32, SLJIT_R1, 0, SLJIT_IMM, -11); + sljit_emit_op1(compiler, SLJIT_MOV32, SLJIT_R0, 0, SLJIT_IMM, 20); + sljit_emit_op2(compiler, SLJIT_ADD32 | SLJIT_SET_CARRY, SLJIT_R1, 0, SLJIT_R1, 0, SLJIT_R0, 0); + /* buf[11] */ + sljit_emit_op1(compiler, SLJIT_MOV32, SLJIT_MEM1(SLJIT_S0), sizeof(sljit_sw) * 11, SLJIT_R1, 0); + sljit_emit_op2(compiler, SLJIT_ADDC32, SLJIT_R0, 0, SLJIT_R1, 0, SLJIT_R0, 0); + /* buf[12] */ + sljit_emit_op1(compiler, SLJIT_MOV32, SLJIT_MEM1(SLJIT_S0), sizeof(sljit_sw) * 12, SLJIT_R0, 0); #else /* !IS_64BIT */ /* buf[0] */ sljit_emit_op1(compiler, SLJIT_MOV32, SLJIT_MEM1(SLJIT_S0), 0, SLJIT_IMM, 0x11223344); @@ -1519,6 +1570,8 @@ static void test15(void) FAILED(buf[9] != (sljit_sw)SLJIT_W(0xfff0000000000000), "test15 case 10 failed\n"); FAILED(buf[10] != (sljit_sw)SLJIT_W(0xffffffff00000000), "test15 case 11 failed\n"); #endif /* SLJIT_LITTLE_ENDIAN */ + FAILED(*(sljit_s32*)(buf + 11) != 9, "test15 case 12 failed\n"); + FAILED(*(sljit_s32*)(buf + 12) != 30, "test15 case 13 failed\n"); #else /* !IS_64BIT */ FAILED(buf[0] != 0x11223344, "test15 case 1 failed\n"); FAILED(buf[1] != 0x44332211, "test15 case 2 failed\n");