diff --git a/build/fibonacci.elf b/build/fibonacci.elf index a1b11076..8ec792de 100644 Binary files a/build/fibonacci.elf and b/build/fibonacci.elf differ diff --git a/src/rv32_template.c b/src/rv32_template.c index 03a1273c..74981188 100644 --- a/src/rv32_template.c +++ b/src/rv32_template.c @@ -270,14 +270,17 @@ RVOP( goto end_op; }, GEN({ - cond, rd; - map, VR0, rd; - ldimm, VR0, pc, 4; - end; - rald, VR1, rs1; - mov, VR1, TMP; + /* The register which stores the indirect address needs to be loaded + * first to avoid being overriden by other operation. + */ + rald, VR0, rs1; + mov, VR0, TMP; alu32imm, 32, 0x81, 0, TMP, imm; alu32imm, 32, 0x81, 4, TMP, ~1U; + cond, rd; + map, VR1, rd; + ldimm, VR1, pc, 4; + end; break; predict; st, S32, TMP, PC; @@ -2359,10 +2362,13 @@ RVOP( goto end_op; }, GEN({ - map, VR0, rv_reg_ra; - ldimm, VR0, pc, 2; - rald, VR1, rs1; - mov, VR1, TMP; + /* The register which stores the indirect address needs to be loaded + * first to avoid being overriden by other operation. + */ + rald, VR0, rs1; + mov, VR0, TMP; + map, VR1, rv_reg_ra; + ldimm, VR1, pc, 2; break; predict; st, S32, TMP, PC; diff --git a/src/t2c_template.c b/src/t2c_template.c index 1b0737f2..fd2ded42 100644 --- a/src/t2c_template.c +++ b/src/t2c_template.c @@ -90,13 +90,17 @@ FORCE_INLINE void t2c_jit_cache_helper(LLVMBuilderRef *builder, } T2C_OP(jalr, { + /* The register which stores the indirect address needs to be loaded first + * to avoid being overriden by other operation. + */ + T2C_LLVM_GEN_LOAD_VMREG(rs1, 32, t2c_gen_rs1_addr(start, builder, ir)); + val_rs1 = T2C_LLVM_GEN_ALU32_IMM(Add, val_rs1, ir->imm); + val_rs1 = T2C_LLVM_GEN_ALU32_IMM(And, val_rs1, ~1U); + if (ir->rd) T2C_LLVM_GEN_STORE_IMM32(*builder, ir->pc + 4, t2c_gen_rd_addr(start, builder, ir)); - T2C_LLVM_GEN_LOAD_VMREG(rs1, 32, t2c_gen_rs1_addr(start, builder, ir)); - val_rs1 = T2C_LLVM_GEN_ALU32_IMM(Add, val_rs1, ir->imm); - val_rs1 = T2C_LLVM_GEN_ALU32_IMM(And, val_rs1, ~1U); t2c_jit_cache_helper(builder, start, val_rs1, rv, ir); }) @@ -744,9 +748,12 @@ T2C_OP(cebreak, { }) T2C_OP(cjalr, { + /* The register which stores the indirect address needs to be loaded first + * to avoid being overriden by other operation. + */ + T2C_LLVM_GEN_LOAD_VMREG(rs1, 32, t2c_gen_rs1_addr(start, builder, ir)); T2C_LLVM_GEN_STORE_IMM32(*builder, ir->pc + 2, t2c_gen_ra_addr(start, builder, ir)); - T2C_LLVM_GEN_LOAD_VMREG(rs1, 32, t2c_gen_rs1_addr(start, builder, ir)); t2c_jit_cache_helper(builder, start, val_rs1, rv, ir); }) diff --git a/tests/fibonacci.s b/tests/fibonacci.s index 65181b32..17f3de97 100644 --- a/tests/fibonacci.s +++ b/tests/fibonacci.s @@ -7,12 +7,12 @@ fib: sw s1, 4(sp) mv s0, a0 addi a0, a0, -1 - la t0, fib - jalr ra, 0(t0) + la ra, fib + jalr ra, 0(ra) mv s1, a0 addi a0, s0, -2 - la t0, fib - jalr ra, 0(t0) + la ra, fib + jalr ra, 0(ra) add a0, s1, a0 lw ra, 12(sp) lw s0, 8(sp)