From 559dffeda2d1cec79e28dd1f6bc4cbe54e40f94e Mon Sep 17 00:00:00 2001 From: Vacantron Chen Date: Wed, 21 Aug 2024 19:37:17 +0800 Subject: [PATCH] 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 --- build/fibonacci.elf | Bin 76440 -> 76440 bytes src/rv32_template.c | 26 ++++++++++++++++---------- src/t2c_template.c | 15 +++++++++++---- tests/fibonacci.s | 8 ++++---- 4 files changed, 31 insertions(+), 18 deletions(-) diff --git a/build/fibonacci.elf b/build/fibonacci.elf index a1b1107615cad54fd99f8a08114d0450e0e214e4..8ec792de04dd57920798e7fef6729a2782eacb35 100644 GIT binary patch delta 766 zcmbPnm1V|NmI*1WJTi<7JR36|7?l_p7$!F`{CnO2q*+)Qgjt{bpAHr~@CPJj+`44) z|EZ#zA28-gFuD6p4v=zU>dMW5&2oHOdWZX6I8E(C=0b$Kx(s!x)38% zNB(9D4I?m}qd5&o=S^nO-UX6Apk2lUqAm2o*g?V*OwTd(1I;kYV`|Tve8H>;M7fw7 z0jbRu=5}l#dWY>gkP(|R?Ei@}brfvQ2#sfBEZ=-0+MgXrNhI%P0#a8}r8!v3n^zq# z-~1()i;s!bWmAnABaqr`QTqr?%hX?D0`WgIvN19pFP!|NDG9`lY3>6{ziFApB**IV zUZ8<#yBHILxhNCEN5eUKfAL*RK~vPT#RcsoecM4+%P>tm~om$Sz>ZxUP)1Yo_J}*fbr0ep>(x;0=WEc3ySH=ZuU!+rMfsE@lJ(ord^o delta 823 zcmb`EUr19?9LLY^?A~n%nR)#)reydh6`dEf+#dW#Wr?`V2P;UZ?K<4Z-Tm=ygcMF~ z2?ZhC>4pXc89|2C4tOggB>H0@5urUq4`G53fj$%jiFVF<>8W0NID9zY?>V0Xzmr(z z63g6ZH(!?zsP2KM2?{Yn>JZ*qi(sU3JQDcT?RYACw#l-Z=#;uWmQ6l^Y{G^P^_ckp zZVix_xr)axd&u*G2_Clu)H5aT8EkvMP>|x%Ou#KcVk@govA2AjGN5u5k6Arm5yp(R zs^bP0kM4hi+o_{g#zz9`+u9(*A!{`SIcIIqGd`@JVG81I+{(r+eZ<{)S`YnX;Z(bU z!X(XMiX~T`k?$YA^QxbG^QNWaXmj#>El?2Kg_RWZ2i{?}-x$;b9#PaELr%8s8orvU zzh0ccyQ9tP84;}IU}VjvL%DRgUeMDa@%|!#r)Q@|KBN?p%LPE+ym4j4SlHYq@Oo5K zJctBNkJeF>S9@ym|}D8EQ9-LJPqzAU!Q0N5NOb$WF7ZF8i?mo4#4sSOBp0TQvwL7wU+$+vS)@Pn@n1{Z PQ3`7SPqgo4a1(w3?j#lB 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)