Skip to content

Commit 559dffe

Browse files
committed
Fix unexpected "JALR" behavior in JIT
The register which stores the indirect address needs to be loaded first to avoid being overriden when the operands are same in "JALR", "C.JALR". Fix #472
1 parent 34c3db0 commit 559dffe

File tree

4 files changed

+31
-18
lines changed

4 files changed

+31
-18
lines changed

build/fibonacci.elf

0 Bytes
Binary file not shown.

src/rv32_template.c

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -270,14 +270,17 @@ RVOP(
270270
goto end_op;
271271
},
272272
GEN({
273-
cond, rd;
274-
map, VR0, rd;
275-
ldimm, VR0, pc, 4;
276-
end;
277-
rald, VR1, rs1;
278-
mov, VR1, TMP;
273+
/* The register which stores the indirect address needs to be loaded
274+
* first to avoid being overriden by other operation.
275+
*/
276+
rald, VR0, rs1;
277+
mov, VR0, TMP;
279278
alu32imm, 32, 0x81, 0, TMP, imm;
280279
alu32imm, 32, 0x81, 4, TMP, ~1U;
280+
cond, rd;
281+
map, VR1, rd;
282+
ldimm, VR1, pc, 4;
283+
end;
281284
break;
282285
predict;
283286
st, S32, TMP, PC;
@@ -2359,10 +2362,13 @@ RVOP(
23592362
goto end_op;
23602363
},
23612364
GEN({
2362-
map, VR0, rv_reg_ra;
2363-
ldimm, VR0, pc, 2;
2364-
rald, VR1, rs1;
2365-
mov, VR1, TMP;
2365+
/* The register which stores the indirect address needs to be loaded
2366+
* first to avoid being overriden by other operation.
2367+
*/
2368+
rald, VR0, rs1;
2369+
mov, VR0, TMP;
2370+
map, VR1, rv_reg_ra;
2371+
ldimm, VR1, pc, 2;
23662372
break;
23672373
predict;
23682374
st, S32, TMP, PC;

src/t2c_template.c

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -90,13 +90,17 @@ FORCE_INLINE void t2c_jit_cache_helper(LLVMBuilderRef *builder,
9090
}
9191

9292
T2C_OP(jalr, {
93+
/* The register which stores the indirect address needs to be loaded first
94+
* to avoid being overriden by other operation.
95+
*/
96+
T2C_LLVM_GEN_LOAD_VMREG(rs1, 32, t2c_gen_rs1_addr(start, builder, ir));
97+
val_rs1 = T2C_LLVM_GEN_ALU32_IMM(Add, val_rs1, ir->imm);
98+
val_rs1 = T2C_LLVM_GEN_ALU32_IMM(And, val_rs1, ~1U);
99+
93100
if (ir->rd)
94101
T2C_LLVM_GEN_STORE_IMM32(*builder, ir->pc + 4,
95102
t2c_gen_rd_addr(start, builder, ir));
96103

97-
T2C_LLVM_GEN_LOAD_VMREG(rs1, 32, t2c_gen_rs1_addr(start, builder, ir));
98-
val_rs1 = T2C_LLVM_GEN_ALU32_IMM(Add, val_rs1, ir->imm);
99-
val_rs1 = T2C_LLVM_GEN_ALU32_IMM(And, val_rs1, ~1U);
100104
t2c_jit_cache_helper(builder, start, val_rs1, rv, ir);
101105
})
102106

@@ -744,9 +748,12 @@ T2C_OP(cebreak, {
744748
})
745749

746750
T2C_OP(cjalr, {
751+
/* The register which stores the indirect address needs to be loaded first
752+
* to avoid being overriden by other operation.
753+
*/
754+
T2C_LLVM_GEN_LOAD_VMREG(rs1, 32, t2c_gen_rs1_addr(start, builder, ir));
747755
T2C_LLVM_GEN_STORE_IMM32(*builder, ir->pc + 2,
748756
t2c_gen_ra_addr(start, builder, ir));
749-
T2C_LLVM_GEN_LOAD_VMREG(rs1, 32, t2c_gen_rs1_addr(start, builder, ir));
750757
t2c_jit_cache_helper(builder, start, val_rs1, rv, ir);
751758
})
752759

tests/fibonacci.s

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,12 @@ fib:
77
sw s1, 4(sp)
88
mv s0, a0
99
addi a0, a0, -1
10-
la t0, fib
11-
jalr ra, 0(t0)
10+
la ra, fib
11+
jalr ra, 0(ra)
1212
mv s1, a0
1313
addi a0, s0, -2
14-
la t0, fib
15-
jalr ra, 0(t0)
14+
la ra, fib
15+
jalr ra, 0(ra)
1616
add a0, s1, a0
1717
lw ra, 12(sp)
1818
lw s0, 8(sp)

0 commit comments

Comments
 (0)