Skip to content

Commit fecbe28

Browse files
author
Zoltan Herczeg
committed
Implement several compressed instructions for RISCV
1 parent a969602 commit fecbe28

File tree

4 files changed

+248
-98
lines changed

4 files changed

+248
-98
lines changed

sljit_src/sljitNativeRISCV_32.c

+13-2
Original file line numberDiff line numberDiff line change
@@ -28,17 +28,28 @@ static sljit_s32 load_immediate(struct sljit_compiler *compiler, sljit_s32 dst_r
2828
{
2929
SLJIT_UNUSED_ARG(tmp_r);
3030

31+
if (RISCV_HAS_COMPRESSED(200) && imm <= SIMM16_MAX && imm >= SIMM16_MIN)
32+
return push_inst16(compiler, C_LI | C_RD(dst_r) | CIMM_I(imm));
33+
3134
if (imm <= SIMM_MAX && imm >= SIMM_MIN)
3235
return push_inst(compiler, ADDI | RD(dst_r) | RS1(TMP_ZERO) | IMM_I(imm));
3336

3437
if (imm & 0x800)
3538
imm += 0x1000;
3639

37-
FAIL_IF(push_inst(compiler, LUI | RD(dst_r) | (sljit_ins)(imm & ~0xfff)));
40+
if (RISCV_HAS_COMPRESSED(200) && imm <= 0x1ffff && imm >= -0x20000)
41+
FAIL_IF(push_inst16(compiler, C_LUI | C_RD(dst_r) | ((sljit_u16)(((imm) & 0x1f000) >> 10) | ((imm) & 0x20000) >> 5)));
42+
else
43+
FAIL_IF(push_inst(compiler, LUI | RD(dst_r) | (sljit_ins)(imm & ~0xfff)));
44+
45+
imm &= 0xfff;
3846

39-
if ((imm & 0xfff) == 0)
47+
if (imm == 0)
4048
return SLJIT_SUCCESS;
4149

50+
if (RISCV_HAS_COMPRESSED(200) && (imm <= 0x1f || imm >= 0xfe0))
51+
return push_inst16(compiler, C_ADDI | C_RD(dst_r) | CIMM_I(imm));
52+
4253
return push_inst(compiler, ADDI | RD(dst_r) | RS1(dst_r) | IMM_I(imm));
4354
}
4455

sljit_src/sljitNativeRISCV_64.c

+70-33
Original file line numberDiff line numberDiff line change
@@ -24,31 +24,58 @@
2424
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2525
*/
2626

27-
static sljit_s32 load_immediate(struct sljit_compiler *compiler, sljit_s32 dst_r, sljit_sw imm, sljit_s32 tmp_r)
27+
static sljit_s32 load_immediate32(struct sljit_compiler *compiler, sljit_s32 dst_r, sljit_sw imm)
2828
{
29-
sljit_sw high;
29+
SLJIT_ASSERT((imm <= 0x7fffffffl && imm > SIMM_MAX) || (imm >= S32_MIN && imm < SIMM_MIN));
3030

31-
if (imm <= SIMM_MAX && imm >= SIMM_MIN)
32-
return push_inst(compiler, ADDI | RD(dst_r) | RS1(TMP_ZERO) | IMM_I(imm));
31+
if (imm > S32_MAX) {
32+
SLJIT_ASSERT((imm & 0x800) != 0);
33+
FAIL_IF(push_inst(compiler, LUI | RD(dst_r) | (sljit_ins)0x80000000u));
34+
return push_inst(compiler, XORI | RD(dst_r) | RS1(dst_r) | IMM_I(imm));
35+
}
3336

34-
if (imm <= 0x7fffffffl && imm >= S32_MIN) {
35-
if (imm > S32_MAX) {
37+
if (RISCV_HAS_COMPRESSED(200) && imm <= 0x1ffff && imm >= -0x20000) {
38+
if (imm > 0x1f7ff) {
3639
SLJIT_ASSERT((imm & 0x800) != 0);
37-
FAIL_IF(push_inst(compiler, LUI | RD(dst_r) | (sljit_ins)0x80000000u));
40+
FAIL_IF(push_inst16(compiler, C_LUI | C_RD(dst_r) | (sljit_u16)0x1000));
3841
return push_inst(compiler, XORI | RD(dst_r) | RS1(dst_r) | IMM_I(imm));
3942
}
4043

4144
if ((imm & 0x800) != 0)
4245
imm += 0x1000;
4346

44-
FAIL_IF(push_inst(compiler, LUI | RD(dst_r) | (sljit_ins)(imm & ~0xfff)));
45-
46-
if ((imm & 0xfff) == 0)
47-
return SLJIT_SUCCESS;
47+
FAIL_IF(push_inst16(compiler, C_LUI | C_RD(dst_r) | ((sljit_u16)(((imm) & 0x1f000) >> 10) | ((imm) & 0x20000) >> 5)));
48+
} else {
49+
if ((imm & 0x800) != 0)
50+
imm += 0x1000;
4851

49-
return push_inst(compiler, ADDI | RD(dst_r) | RS1(dst_r) | IMM_I(imm));
52+
FAIL_IF(push_inst(compiler, LUI | RD(dst_r) | (sljit_ins)(imm & ~(sljit_sw)0xfff)));
5053
}
5154

55+
imm &= 0xfff;
56+
57+
if (imm == 0)
58+
return SLJIT_SUCCESS;
59+
60+
if (RISCV_HAS_COMPRESSED(200) && (imm <= 0x1f || imm >= 0xfe0))
61+
return push_inst16(compiler, C_ADDI | C_RD(dst_r) | CIMM_I(imm));
62+
63+
return push_inst(compiler, ADDI | RD(dst_r) | RS1(dst_r) | IMM_I(imm));
64+
}
65+
66+
static sljit_s32 load_immediate(struct sljit_compiler *compiler, sljit_s32 dst_r, sljit_sw imm, sljit_s32 tmp_r)
67+
{
68+
sljit_sw high;
69+
70+
if (RISCV_HAS_COMPRESSED(200) && imm <= SIMM16_MAX && imm >= SIMM16_MIN)
71+
return push_inst16(compiler, C_LI | C_RD(dst_r) | CIMM_I(imm));
72+
73+
if (imm <= SIMM_MAX && imm >= SIMM_MIN)
74+
return push_inst(compiler, ADDI | RD(dst_r) | RS1(TMP_ZERO) | IMM_I(imm));
75+
76+
if (imm <= 0x7fffffffl && imm >= S32_MIN)
77+
return load_immediate32(compiler, dst_r, imm);
78+
5279
/* Trailing zeroes could be used to produce shifted immediates. */
5380

5481
if (imm <= 0x7ffffffffffl && imm >= -0x80000000000l) {
@@ -57,21 +84,12 @@ static sljit_s32 load_immediate(struct sljit_compiler *compiler, sljit_s32 dst_r
5784
if (imm & 0x800)
5885
high = ~high;
5986

60-
if (high > S32_MAX) {
61-
SLJIT_ASSERT((high & 0x800) != 0);
62-
FAIL_IF(push_inst(compiler, LUI | RD(dst_r) | (sljit_ins)0x80000000u));
63-
FAIL_IF(push_inst(compiler, XORI | RD(dst_r) | RS1(dst_r) | IMM_I(high)));
64-
} else {
65-
if ((high & 0x800) != 0)
66-
high += 0x1000;
67-
68-
FAIL_IF(push_inst(compiler, LUI | RD(dst_r) | (sljit_ins)(high & ~0xfff)));
69-
70-
if ((high & 0xfff) != 0)
71-
FAIL_IF(push_inst(compiler, ADDI | RD(dst_r) | RS1(dst_r) | IMM_I(high)));
72-
}
87+
FAIL_IF(load_immediate32(compiler, dst_r, high));
7388

74-
FAIL_IF(push_inst(compiler, SLLI | RD(dst_r) | RS1(dst_r) | IMM_I(12)));
89+
if (RISCV_HAS_COMPRESSED(200))
90+
FAIL_IF(push_inst16(compiler, C_SLLI | C_RD(dst_r) | (sljit_u16)(12 << 2)));
91+
else
92+
FAIL_IF(push_inst(compiler, SLLI | RD(dst_r) | RS1(dst_r) | IMM_I(12)));
7593

7694
if ((imm & 0xfff) != 0)
7795
return push_inst(compiler, XORI | RD(dst_r) | RS1(dst_r) | IMM_I(imm));
@@ -99,7 +117,10 @@ static sljit_s32 load_immediate(struct sljit_compiler *compiler, sljit_s32 dst_r
99117
}
100118

101119
if (imm <= SIMM_MAX && imm >= SIMM_MIN) {
102-
FAIL_IF(push_inst(compiler, ADDI | RD(dst_r) | RS1(TMP_ZERO) | IMM_I(imm)));
120+
if (RISCV_HAS_COMPRESSED(200) && imm <= 0x1f && imm >= -0x20)
121+
FAIL_IF(push_inst16(compiler, C_LI | C_RD(dst_r) | CIMM_I(imm)));
122+
else
123+
FAIL_IF(push_inst(compiler, ADDI | RD(dst_r) | RS1(TMP_ZERO) | IMM_I(imm)));
103124
imm = 0;
104125
} else if (imm > S32_MAX) {
105126
SLJIT_ASSERT((imm & 0x800) != 0);
@@ -110,19 +131,35 @@ static sljit_s32 load_immediate(struct sljit_compiler *compiler, sljit_s32 dst_r
110131
if ((imm & 0x800) != 0)
111132
imm += 0x1000;
112133

113-
FAIL_IF(push_inst(compiler, LUI | RD(dst_r) | (sljit_ins)(imm & ~0xfff)));
134+
if (RISCV_HAS_COMPRESSED(200) && imm <= 0x1ffff && imm >= -0x20000)
135+
FAIL_IF(push_inst16(compiler, C_LUI | C_RD(dst_r) | ((sljit_u16)(((imm) & 0x1f000) >> 10) | ((imm) & 0x20000) >> 5)));
136+
else
137+
FAIL_IF(push_inst(compiler, LUI | RD(dst_r) | (sljit_ins)(imm & ~0xfff)));
114138
imm &= 0xfff;
115139
}
116140

117-
if ((high & 0xfff) != 0)
118-
FAIL_IF(push_inst(compiler, ADDI | RD(tmp_r) | RS1(tmp_r) | IMM_I(high)));
141+
if ((high & 0xfff) != 0) {
142+
SLJIT_ASSERT(high <= 0xfff);
143+
if (RISCV_HAS_COMPRESSED(200) && (high <= 0x1f || high >= 0xfe0))
144+
FAIL_IF(push_inst16(compiler, C_ADDI | C_RD(tmp_r) | CIMM_I(high)));
145+
else
146+
FAIL_IF(push_inst(compiler, ADDI | RD(tmp_r) | RS1(tmp_r) | IMM_I(high)));
147+
}
119148

120149
if (imm & 0x1000)
121150
FAIL_IF(push_inst(compiler, XORI | RD(dst_r) | RS1(dst_r) | IMM_I(imm)));
122-
else if (imm != 0)
123-
FAIL_IF(push_inst(compiler, ADDI | RD(dst_r) | RS1(dst_r) | IMM_I(imm)));
151+
else if (imm != 0) {
152+
SLJIT_ASSERT(imm <= 0xfff);
153+
if (RISCV_HAS_COMPRESSED(200) && (imm <= 0x1f || imm >= 0xfe0))
154+
FAIL_IF(push_inst16(compiler, C_ADDI | C_RD(dst_r) | CIMM_I(imm)));
155+
else
156+
FAIL_IF(push_inst(compiler, ADDI | RD(dst_r) | RS1(dst_r) | IMM_I(imm)));
157+
}
124158

125-
FAIL_IF(push_inst(compiler, SLLI | RD(tmp_r) | RS1(tmp_r) | IMM_I((high & 0x1000) ? 20 : 32)));
159+
if (RISCV_HAS_COMPRESSED(200))
160+
FAIL_IF(push_inst16(compiler, C_SLLI | C_RD(tmp_r) | (sljit_u16)((high & 0x1000) ? (20 << 2) : (1 << 12))));
161+
else
162+
FAIL_IF(push_inst(compiler, SLLI | RD(tmp_r) | RS1(tmp_r) | IMM_I((high & 0x1000) ? 20 : 32)));
126163
return push_inst(compiler, XOR | RD(dst_r) | RS1(dst_r) | RS2(tmp_r));
127164
}
128165

0 commit comments

Comments
 (0)