Centralize the range test for this encoding. Directly OR into the insn value. Assert success in encode_j. Use encode_jimm in tcg_out_call_int.
Signed-off-by: Richard Henderson <[email protected]> --- tcg/riscv64/tcg-target.c.inc | 46 ++++++++++++++++-------------------- 1 file changed, 21 insertions(+), 25 deletions(-) diff --git a/tcg/riscv64/tcg-target.c.inc b/tcg/riscv64/tcg-target.c.inc index a5ed1e95722..09bfce79bb7 100644 --- a/tcg/riscv64/tcg-target.c.inc +++ b/tcg/riscv64/tcg-target.c.inc @@ -511,24 +511,26 @@ static tcg_insn_unit encode_u(RISCVInsn opc, TCGReg rd, tcg_target_long imm) /* Type-J */ -static tcg_insn_unit encode_jimm20(tcg_target_long imm) +static bool encode_jimm20(tcg_insn_unit *insn, tcg_target_long imm) { - tcg_insn_unit ret = 0; - - ret |= (imm & 0x0007fe) << (21 - 1); - ret |= (imm & 0x000800) << (20 - 11); - ret |= (imm & 0x0ff000) << (12 - 12); - ret |= (imm & 0x100000) << (31 - 20); - - return ret; + if ((imm & 1) == 0 && imm == sextract32(imm, 0, 20)) { + *insn |= ((imm & 0x0007fe) << (21 - 1) + | (imm & 0x000800) << (20 - 11) + | (imm & 0x0ff000) << (12 - 12) + | (imm & 0x100000) << (31 - 20)); + return true; + } + return false; } static tcg_insn_unit encode_j(RISCVInsn opc, TCGReg rd, tcg_target_long imm) { - return opc | (rd & 0x1f) << 7 | encode_jimm20(imm); + tcg_insn_unit insn = opc | (rd & 0x1f) << 7; + bool ok = encode_jimm20(&insn, imm); + tcg_debug_assert(ok); + return insn; } - /* Type-OPIVI */ static tcg_insn_unit encode_vi(RISCVInsn opc, TCGReg rd, int32_t imm, @@ -638,12 +640,7 @@ static bool reloc_jimm20(tcg_insn_unit *src_rw, const tcg_insn_unit *target) intptr_t offset = (intptr_t)target - (intptr_t)src_rx; tcg_debug_assert((offset & 1) == 0); - if (offset == sextreg(offset, 0, 20)) { - *src_rw |= encode_jimm20(offset); - return true; - } - - return false; + return encode_jimm20(src_rw, offset); } static bool reloc_call(tcg_insn_unit *src_rw, const tcg_insn_unit *target) @@ -1577,14 +1574,15 @@ static void tcg_out_call_int(TCGContext *s, const tcg_insn_unit *arg, bool tail) { TCGReg link = tail ? TCG_REG_ZERO : TCG_REG_RA; ptrdiff_t offset = tcg_pcrel_diff(s, arg); + tcg_insn_unit insn = encode_j(OPC_JAL, link, 0); int ret; init_setting_vtype(s); tcg_debug_assert((offset & 1) == 0); - if (offset == sextreg(offset, 0, 20)) { - /* short jump: -2097150 to 2097152 */ - tcg_out_opc_jump(s, OPC_JAL, link, offset); + if (encode_jimm20(&insn, offset)) { + /* short jump */ + tcg_out32(s, insn); } else if (offset == (int32_t)offset) { /* long jump: -2147483646 to 2147483648 */ tcg_out_opc_upper(s, OPC_AUIPC, TCG_REG_TMP0, 0); @@ -1961,15 +1959,13 @@ void tb_target_set_jmp_target(const TranslationBlock *tb, int n, { uintptr_t addr = tb->jmp_target_addr[n]; ptrdiff_t offset = addr - jmp_rx; - tcg_insn_unit insn; + tcg_insn_unit insn = OPC_JAL; /* rd = TCG_REG_ZERO */ /* Either directly branch, or fall through to indirect branch. */ - if (offset == sextreg(offset, 0, 20)) { - insn = encode_j(OPC_JAL, TCG_REG_ZERO, offset); - } else { + if (!encode_jimm20(&insn, offset)) { insn = OPC_NOP; } - qatomic_set((uint32_t *)jmp_rw, insn); + qatomic_set((tcg_insn_unit *)jmp_rw, insn); flush_idcache_range(jmp_rx, jmp_rw, 4); } -- 2.53.0
