From 03cdb982f76e3fd0fd51751c90da56bc6651fed5 Mon Sep 17 00:00:00 2001 From: Yen-Fu Chen Date: Fri, 15 Dec 2023 21:50:07 +0800 Subject: [PATCH] Avoid the tier-1 JIT compiler from translating RV32F and RV32A --- src/decode.h | 292 +++++++++++++++++++++---------------------- src/emulate.c | 36 ++++-- src/jit_x64.c | 6 +- src/riscv_private.h | 2 + tools/rv_histogram.c | 4 +- 5 files changed, 181 insertions(+), 159 deletions(-) diff --git a/src/decode.h b/src/decode.h index 9861863c..3019beff 100644 --- a/src/decode.h +++ b/src/decode.h @@ -29,153 +29,153 @@ enum op_field { #define ENC(...) ENC_GEN(ENC, COUNT_VARARGS(__VA_ARGS__))(__VA_ARGS__) /* RISC-V instruction list in format _(instruction-name, can-branch, insn_len, - * reg-mask) + * translatable, reg-mask) */ /* clang-format off */ -#define RV_INSN_LIST \ - _(nop, 0, 4, ENC(rs1, rd)) \ - /* RV32I Base Instruction Set */ \ - _(lui, 0, 4, ENC(rd)) \ - _(auipc, 0, 4, ENC(rd)) \ - _(jal, 1, 4, ENC(rd)) \ - _(jalr, 1, 4, ENC(rs1, rd)) \ - _(beq, 1, 4, ENC(rs1, rs2)) \ - _(bne, 1, 4, ENC(rs1, rs2)) \ - _(blt, 1, 4, ENC(rs1, rs2)) \ - _(bge, 1, 4, ENC(rs1, rs2)) \ - _(bltu, 1, 4, ENC(rs1, rs2)) \ - _(bgeu, 1, 4, ENC(rs1, rs2)) \ - _(lb, 0, 4, ENC(rs1, rd)) \ - _(lh, 0, 4, ENC(rs1, rd)) \ - _(lw, 0, 4, ENC(rs1, rd)) \ - _(lbu, 0, 4, ENC(rs1, rd)) \ - _(lhu, 0, 4, ENC(rs1, rd)) \ - _(sb, 0, 4, ENC(rs1, rs2)) \ - _(sh, 0, 4, ENC(rs1, rs2)) \ - _(sw, 0, 4, ENC(rs1, rs2)) \ - _(addi, 0, 4, ENC(rs1, rd)) \ - _(slti, 0, 4, ENC(rs1, rd)) \ - _(sltiu, 0, 4, ENC(rs1, rd)) \ - _(xori, 0, 4, ENC(rs1, rd)) \ - _(ori, 0, 4, ENC(rs1, rd)) \ - _(andi, 0, 4, ENC(rs1, rd)) \ - _(slli, 0, 4, ENC(rs1, rd)) \ - _(srli, 0, 4, ENC(rs1, rd)) \ - _(srai, 0, 4, ENC(rs1, rd)) \ - _(add, 0, 4, ENC(rs1, rs2, rd)) \ - _(sub, 0, 4, ENC(rs1, rs2, rd)) \ - _(sll, 0, 4, ENC(rs1, rs2, rd)) \ - _(slt, 0, 4, ENC(rs1, rs2, rd)) \ - _(sltu, 0, 4, ENC(rs1, rs2, rd)) \ - _(xor, 0, 4, ENC(rs1, rs2, rd)) \ - _(srl, 0, 4, ENC(rs1, rs2, rd)) \ - _(sra, 0, 4, ENC(rs1, rs2, rd)) \ - _(or, 0, 4, ENC(rs1, rs2, rd)) \ - _(and, 0, 4, ENC(rs1, rs2, rd)) \ - _(ecall, 1, 4, ENC(rs1, rd)) \ - _(ebreak, 1, 4, ENC(rs1, rd)) \ - /* RISC-V Privileged Instruction */ \ - _(wfi, 0, 4, ENC(rs1, rd)) \ - _(uret, 0, 4, ENC(rs1, rd)) \ - _(sret, 0, 4, ENC(rs1, rd)) \ - _(hret, 0, 4, ENC(rs1, rd)) \ - _(mret, 1, 4, ENC(rs1, rd)) \ - /* RV32 Zifencei Standard Extension */ \ - IIF(RV32_HAS(Zifencei))( \ - _(fencei, 1, 4, ENC(rs1, rd)) \ - ) \ - /* RV32 Zicsr Standard Extension */ \ - IIF(RV32_HAS(Zicsr))( \ - _(csrrw, 0, 4, ENC(rs1, rd)) \ - _(csrrs, 0, 4, ENC(rs1, rd)) \ - _(csrrc, 0, 4, ENC(rs1, rd)) \ - _(csrrwi, 0, 4, ENC(rs1, rd)) \ - _(csrrsi, 0, 4, ENC(rs1, rd)) \ - _(csrrci, 0, 4, ENC(rs1, rd)) \ - ) \ - /* RV32M Standard Extension */ \ - IIF(RV32_HAS(EXT_M))( \ - _(mul, 0, 4, ENC(rs1, rs2, rd)) \ - _(mulh, 0, 4, ENC(rs1, rs2, rd)) \ - _(mulhsu, 0, 4, ENC(rs1, rs2, rd)) \ - _(mulhu, 0, 4, ENC(rs1, rs2, rd)) \ - _(div, 0, 4, ENC(rs1, rs2, rd)) \ - _(divu, 0, 4, ENC(rs1, rs2, rd)) \ - _(rem, 0, 4, ENC(rs1, rs2, rd)) \ - _(remu, 0, 4, ENC(rs1, rs2, rd)) \ - ) \ - /* RV32A Standard Extension */ \ - IIF(RV32_HAS(EXT_A))( \ - _(lrw, 0, 4, ENC(rs1, rs2, rd)) \ - _(scw, 0, 4, ENC(rs1, rs2, rd)) \ - _(amoswapw, 0, 4, ENC(rs1, rs2, rd)) \ - _(amoaddw, 0, 4, ENC(rs1, rs2, rd)) \ - _(amoxorw, 0, 4, ENC(rs1, rs2, rd)) \ - _(amoandw, 0, 4, ENC(rs1, rs2, rd)) \ - _(amoorw, 0, 4, ENC(rs1, rs2, rd)) \ - _(amominw, 0, 4, ENC(rs1, rs2, rd)) \ - _(amomaxw, 0, 4, ENC(rs1, rs2, rd)) \ - _(amominuw, 0, 4, ENC(rs1, rs2, rd)) \ - _(amomaxuw, 0, 4, ENC(rs1, rs2, rd)) \ - ) \ - /* RV32F Standard Extension */ \ - IIF(RV32_HAS(EXT_F))( \ - _(flw, 0, 4, ENC(rs1, rd)) \ - _(fsw, 0, 4, ENC(rs1, rs2)) \ - _(fmadds, 0, 4, ENC(rs1, rs2, rs3, rd)) \ - _(fmsubs, 0, 4, ENC(rs1, rs2, rs3, rd)) \ - _(fnmsubs, 0, 4, ENC(rs1, rs2, rs3, rd)) \ - _(fnmadds, 0, 4, ENC(rs1, rs2, rs3, rd)) \ - _(fadds, 0, 4, ENC(rs1, rs2, rd)) \ - _(fsubs, 0, 4, ENC(rs1, rs2, rd)) \ - _(fmuls, 0, 4, ENC(rs1, rs2, rd)) \ - _(fdivs, 0, 4, ENC(rs1, rs2, rd)) \ - _(fsqrts, 0, 4, ENC(rs1, rs2, rd)) \ - _(fsgnjs, 0, 4, ENC(rs1, rs2, rd)) \ - _(fsgnjns, 0, 4, ENC(rs1, rs2, rd)) \ - _(fsgnjxs, 0, 4, ENC(rs1, rs2, rd)) \ - _(fmins, 0, 4, ENC(rs1, rs2, rd)) \ - _(fmaxs, 0, 4, ENC(rs1, rs2, rd)) \ - _(fcvtws, 0, 4, ENC(rs1, rs2, rd)) \ - _(fcvtwus, 0, 4, ENC(rs1, rs2, rd)) \ - _(fmvxw, 0, 4, ENC(rs1, rs2, rd)) \ - _(feqs, 0, 4, ENC(rs1, rs2, rd)) \ - _(flts, 0, 4, ENC(rs1, rs2, rd)) \ - _(fles, 0, 4, ENC(rs1, rs2, rd)) \ - _(fclasss, 0, 4, ENC(rs1, rs2, rd)) \ - _(fcvtsw, 0, 4, ENC(rs1, rs2, rd)) \ - _(fcvtswu, 0, 4, ENC(rs1, rs2, rd)) \ - _(fmvwx, 0, 4, ENC(rs1, rs2, rd)) \ - ) \ - /* RV32C Standard Extension */ \ - IIF(RV32_HAS(EXT_C))( \ - _(caddi4spn, 0, 2, ENC(rd)) \ - _(clw, 0, 2, ENC(rs1, rd)) \ - _(csw, 0, 2, ENC(rs1, rs2)) \ - _(cnop, 0, 2, ENC()) \ - _(caddi, 0, 2, ENC(rd)) \ - _(cjal, 1, 2, ENC()) \ - _(cli, 0, 2, ENC(rd)) \ - _(caddi16sp, 0, 2, ENC()) \ - _(clui, 0, 2, ENC(rd)) \ - _(csrli, 0, 2, ENC(rs1)) \ - _(csrai, 0, 2, ENC(rs1)) \ - _(candi, 0, 2, ENC(rs1)) \ - _(csub, 0, 2, ENC(rs1, rs2, rd)) \ - _(cxor, 0, 2, ENC(rs1, rs2, rd)) \ - _(cor, 0, 2, ENC(rs1, rs2, rd)) \ - _(cand, 0, 2, ENC(rs1, rs2, rd)) \ - _(cj, 1, 2, ENC()) \ - _(cbeqz, 1, 2, ENC(rs1)) \ - _(cbnez, 1, 2, ENC(rs1)) \ - _(cslli, 0, 2, ENC(rd)) \ - _(clwsp, 0, 2, ENC(rd)) \ - _(cjr, 1, 2, ENC(rs1, rs2, rd)) \ - _(cmv, 0, 2, ENC(rs1, rs2, rd)) \ - _(cebreak, 1, 2, ENC(rs1, rs2, rd)) \ - _(cjalr, 1, 2, ENC(rs1, rs2, rd)) \ - _(cadd, 0, 2, ENC(rs1, rs2, rd)) \ - _(cswsp, 0, 2, ENC(rs2)) \ +#define RV_INSN_LIST \ + _(nop, 0, 4, 1, ENC(rs1, rd)) \ + /* RV32I Base Instruction Set */ \ + _(lui, 0, 4, 1, ENC(rd)) \ + _(auipc, 0, 4, 1, ENC(rd)) \ + _(jal, 1, 4, 1, ENC(rd)) \ + _(jalr, 1, 4, 1, ENC(rs1, rd)) \ + _(beq, 1, 4, 1, ENC(rs1, rs2)) \ + _(bne, 1, 4, 1, ENC(rs1, rs2)) \ + _(blt, 1, 4, 1, ENC(rs1, rs2)) \ + _(bge, 1, 4, 1, ENC(rs1, rs2)) \ + _(bltu, 1, 4, 1, ENC(rs1, rs2)) \ + _(bgeu, 1, 4, 1, ENC(rs1, rs2)) \ + _(lb, 0, 4, 1, ENC(rs1, rd)) \ + _(lh, 0, 4, 1, ENC(rs1, rd)) \ + _(lw, 0, 4, 1, ENC(rs1, rd)) \ + _(lbu, 0, 4, 1, ENC(rs1, rd)) \ + _(lhu, 0, 4, 1, ENC(rs1, rd)) \ + _(sb, 0, 4, 1, ENC(rs1, rs2)) \ + _(sh, 0, 4, 1, ENC(rs1, rs2)) \ + _(sw, 0, 4, 1, ENC(rs1, rs2)) \ + _(addi, 0, 4, 1, ENC(rs1, rd)) \ + _(slti, 0, 4, 1, ENC(rs1, rd)) \ + _(sltiu, 0, 4, 1, ENC(rs1, rd)) \ + _(xori, 0, 4, 1, ENC(rs1, rd)) \ + _(ori, 0, 4, 1, ENC(rs1, rd)) \ + _(andi, 0, 4, 1, ENC(rs1, rd)) \ + _(slli, 0, 4, 1, ENC(rs1, rd)) \ + _(srli, 0, 4, 1, ENC(rs1, rd)) \ + _(srai, 0, 4, 1, ENC(rs1, rd)) \ + _(add, 0, 4, 1, ENC(rs1, rs2, rd)) \ + _(sub, 0, 4, 1, ENC(rs1, rs2, rd)) \ + _(sll, 0, 4, 1, ENC(rs1, rs2, rd)) \ + _(slt, 0, 4, 1, ENC(rs1, rs2, rd)) \ + _(sltu, 0, 4, 1, ENC(rs1, rs2, rd)) \ + _(xor, 0, 4, 1, ENC(rs1, rs2, rd)) \ + _(srl, 0, 4, 1, ENC(rs1, rs2, rd)) \ + _(sra, 0, 4, 1, ENC(rs1, rs2, rd)) \ + _(or, 0, 4, 1, ENC(rs1, rs2, rd)) \ + _(and, 0, 4, 1, ENC(rs1, rs2, rd)) \ + _(ecall, 1, 4, 1, ENC(rs1, rd)) \ + _(ebreak, 1, 4, 1, ENC(rs1, rd)) \ + /* RISC-V Privileged Instruction */ \ + _(wfi, 0, 4, 0, ENC(rs1, rd)) \ + _(uret, 0, 4, 0, ENC(rs1, rd)) \ + _(sret, 0, 4, 0, ENC(rs1, rd)) \ + _(hret, 0, 4, 0, ENC(rs1, rd)) \ + _(mret, 1, 4, 0, ENC(rs1, rd)) \ + /* RV32 Zifencei Standard Extension */ \ + IIF(RV32_HAS(Zifencei))( \ + _(fencei, 1, 4, 0, ENC(rs1, rd)) \ + ) \ + /* RV32 Zicsr Standard Extension */ \ + IIF(RV32_HAS(Zicsr))( \ + _(csrrw, 0, 4, 0, ENC(rs1, rd)) \ + _(csrrs, 0, 4, 0, ENC(rs1, rd)) \ + _(csrrc, 0, 4, 0, ENC(rs1, rd)) \ + _(csrrwi, 0, 4, 0, ENC(rs1, rd)) \ + _(csrrsi, 0, 4, 0, ENC(rs1, rd)) \ + _(csrrci, 0, 4, 0, ENC(rs1, rd)) \ + ) \ + /* RV32M Standard Extension */ \ + IIF(RV32_HAS(EXT_M))( \ + _(mul, 0, 4, 1, ENC(rs1, rs2, rd)) \ + _(mulh, 0, 4, 1, ENC(rs1, rs2, rd)) \ + _(mulhsu, 0, 4, 1, ENC(rs1, rs2, rd)) \ + _(mulhu, 0, 4, 1, ENC(rs1, rs2, rd)) \ + _(div, 0, 4, 1, ENC(rs1, rs2, rd)) \ + _(divu, 0, 4, 1, ENC(rs1, rs2, rd)) \ + _(rem, 0, 4, 1, ENC(rs1, rs2, rd)) \ + _(remu, 0, 4, 1, ENC(rs1, rs2, rd)) \ + ) \ + /* RV32A Standard Extension */ \ + IIF(RV32_HAS(EXT_A))( \ + _(lrw, 0, 4, 0, ENC(rs1, rs2, rd)) \ + _(scw, 0, 4, 0, ENC(rs1, rs2, rd)) \ + _(amoswapw, 0, 4, 0, ENC(rs1, rs2, rd)) \ + _(amoaddw, 0, 4, 0, ENC(rs1, rs2, rd)) \ + _(amoxorw, 0, 4, 0, ENC(rs1, rs2, rd)) \ + _(amoandw, 0, 4, 0, ENC(rs1, rs2, rd)) \ + _(amoorw, 0, 4, 0, ENC(rs1, rs2, rd)) \ + _(amominw, 0, 4, 0, ENC(rs1, rs2, rd)) \ + _(amomaxw, 0, 4, 0, ENC(rs1, rs2, rd)) \ + _(amominuw, 0, 4, 0, ENC(rs1, rs2, rd)) \ + _(amomaxuw, 0, 4, 0, ENC(rs1, rs2, rd)) \ + ) \ + /* RV32F Standard Extension */ \ + IIF(RV32_HAS(EXT_F))( \ + _(flw, 0, 4, 0, ENC(rs1, rd)) \ + _(fsw, 0, 4, 0, ENC(rs1, rs2)) \ + _(fmadds, 0, 4, 0, ENC(rs1, rs2, rs3, rd)) \ + _(fmsubs, 0, 4, 0, ENC(rs1, rs2, rs3, rd)) \ + _(fnmsubs, 0, 4, 0, ENC(rs1, rs2, rs3, rd)) \ + _(fnmadds, 0, 4, 0, ENC(rs1, rs2, rs3, rd)) \ + _(fadds, 0, 4, 0, ENC(rs1, rs2, rd)) \ + _(fsubs, 0, 4, 0, ENC(rs1, rs2, rd)) \ + _(fmuls, 0, 4, 0, ENC(rs1, rs2, rd)) \ + _(fdivs, 0, 4, 0, ENC(rs1, rs2, rd)) \ + _(fsqrts, 0, 4, 0, ENC(rs1, rs2, rd)) \ + _(fsgnjs, 0, 4, 0, ENC(rs1, rs2, rd)) \ + _(fsgnjns, 0, 4, 0, ENC(rs1, rs2, rd)) \ + _(fsgnjxs, 0, 4, 0, ENC(rs1, rs2, rd)) \ + _(fmins, 0, 4, 0, ENC(rs1, rs2, rd)) \ + _(fmaxs, 0, 4, 0, ENC(rs1, rs2, rd)) \ + _(fcvtws, 0, 4, 0, ENC(rs1, rs2, rd)) \ + _(fcvtwus, 0, 4, 0, ENC(rs1, rs2, rd)) \ + _(fmvxw, 0, 4, 0, ENC(rs1, rs2, rd)) \ + _(feqs, 0, 4, 0, ENC(rs1, rs2, rd)) \ + _(flts, 0, 4, 0, ENC(rs1, rs2, rd)) \ + _(fles, 0, 4, 0, ENC(rs1, rs2, rd)) \ + _(fclasss, 0, 4, 0, ENC(rs1, rs2, rd)) \ + _(fcvtsw, 0, 4, 0, ENC(rs1, rs2, rd)) \ + _(fcvtswu, 0, 4, 0, ENC(rs1, rs2, rd)) \ + _(fmvwx, 0, 4, 0, ENC(rs1, rs2, rd)) \ + ) \ + /* RV32C Standard Extension */ \ + IIF(RV32_HAS(EXT_C))( \ + _(caddi4spn, 0, 2, 1, ENC(rd)) \ + _(clw, 0, 2, 1, ENC(rs1, rd)) \ + _(csw, 0, 2, 1, ENC(rs1, rs2)) \ + _(cnop, 0, 2, 1, ENC()) \ + _(caddi, 0, 2, 1, ENC(rd)) \ + _(cjal, 1, 2, 1, ENC()) \ + _(cli, 0, 2, 1, ENC(rd)) \ + _(caddi16sp, 0, 2, 1, ENC()) \ + _(clui, 0, 2, 1, ENC(rd)) \ + _(csrli, 0, 2, 1, ENC(rs1)) \ + _(csrai, 0, 2, 1, ENC(rs1)) \ + _(candi, 0, 2, 1, ENC(rs1)) \ + _(csub, 0, 2, 1, ENC(rs1, rs2, rd)) \ + _(cxor, 0, 2, 1, ENC(rs1, rs2, rd)) \ + _(cor, 0, 2, 1, ENC(rs1, rs2, rd)) \ + _(cand, 0, 2, 1, ENC(rs1, rs2, rd)) \ + _(cj, 1, 2, 1, ENC()) \ + _(cbeqz, 1, 2, 1, ENC(rs1)) \ + _(cbnez, 1, 2, 1, ENC(rs1)) \ + _(cslli, 0, 2, 1, ENC(rd)) \ + _(clwsp, 0, 2, 1, ENC(rd)) \ + _(cjr, 1, 2, 1, ENC(rs1, rs2, rd)) \ + _(cmv, 0, 2, 1, ENC(rs1, rs2, rd)) \ + _(cebreak, 1, 2, 1,ENC(rs1, rs2, rd)) \ + _(cjalr, 1, 2, 1, ENC(rs1, rs2, rd)) \ + _(cadd, 0, 2, 1, ENC(rs1, rs2, rd)) \ + _(cswsp, 0, 2, 1, ENC(rs2)) \ ) /* clang-format on */ @@ -196,7 +196,7 @@ enum op_field { /* clang-format off */ /* IR list */ enum { -#define _(inst, can_branch, insn_len, reg_mask) rv_insn_##inst, +#define _(inst, can_branch, insn_len, translatable, reg_mask) rv_insn_##inst, RV_INSN_LIST #undef _ N_RV_INSNS, diff --git a/src/emulate.c b/src/emulate.c index 4acca3dd..31515832 100644 --- a/src/emulate.c +++ b/src/emulate.c @@ -299,6 +299,7 @@ static block_t *block_alloc(riscv_t *rv) block->n_insn = 0; block->predict = NULL; #if RV32_HAS(JIT) + block->translatable = true; block->hot = false; block->backward = false; #endif @@ -356,7 +357,7 @@ FORCE_INLINE bool insn_is_misaligned(uint32_t pc) /* instruction length information for each RISC-V instruction */ enum { -#define _(inst, can_branch, insn_len, reg_mask) \ +#define _(inst, can_branch, insn_len, translatable, reg_mask) \ __rv_insn_##inst##_len = insn_len, RV_INSN_LIST #undef _ @@ -364,7 +365,7 @@ enum { /* can-branch information for each RISC-V instruction */ enum { -#define _(inst, can_branch, insn_len, reg_mask) \ +#define _(inst, can_branch, insn_len, translatable, reg_mask) \ __rv_insn_##inst##_canbranch = can_branch, RV_INSN_LIST #undef _ @@ -535,7 +536,7 @@ static bool do_fuse7(riscv_t *rv, /* clang-format off */ static const void *dispatch_table[] = { /* RV32 instructions */ -#define _(inst, can_branch, insn_len, reg_mask) [rv_insn_##inst] = do_##inst, +#define _(inst, can_branch, insn_len, translatable, reg_mask) [rv_insn_##inst] = do_##inst, RV_INSN_LIST #undef _ /* Macro operation fusion instructions */ @@ -548,7 +549,7 @@ static const void *dispatch_table[] = { FORCE_INLINE bool insn_is_branch(uint8_t opcode) { switch (opcode) { -#define _(inst, can_branch, insn_len, reg_mask) \ +#define _(inst, can_branch, insn_len, translatable, reg_mask) \ IIF(can_branch)(case rv_insn_##inst:, ) RV_INSN_LIST #undef _ @@ -557,6 +558,20 @@ FORCE_INLINE bool insn_is_branch(uint8_t opcode) return false; } +#if RV32_HAS(JIT) +FORCE_INLINE bool insn_is_translatable(uint8_t opcode) +{ + switch (opcode) { +#define _(inst, can_branch, insn_len, translatable, reg_mask) \ + IIF(translatable)(case rv_insn_##inst:, ) + RV_INSN_LIST +#undef _ + return true; + } + return false; +} +#endif + FORCE_INLINE bool insn_is_unconditional_branch(uint8_t opcode) { switch (opcode) { @@ -607,6 +622,10 @@ static void block_translate(riscv_t *rv, block_t *block) block->pc_end += is_compressed(insn) ? 2 : 4; block->n_insn++; prev_ir = ir; +#if RV32_HAS(JIT) + if (!insn_is_translatable(ir->opcode)) + block->translatable = false; +#endif /* stop on branch */ if (insn_is_branch(ir->opcode)) { if (ir->imm < 0) @@ -898,7 +917,7 @@ typedef struct { #include "rv32_constopt.c" static const void *constopt_table[] = { -#define _(inst, can_branch, insn_len, reg_mask) \ +#define _(inst, can_branch, insn_len, translatable, reg_mask) \ [rv_insn_##inst] = constopt_##inst, RV_INSN_LIST #undef _ @@ -1045,9 +1064,10 @@ void rv_step(riscv_t *rv, int32_t cycles) prev = NULL; continue; } /* check if using frequency of block exceed threshold */ - else if ((block->backward && - cache_freq(rv->block_cache, block->pc_start) >= 1024) || - cache_hot(rv->block_cache, block->pc_start)) { + else if (block->translatable && + ((block->backward && + cache_freq(rv->block_cache, block->pc_start) >= 1024) || + cache_hot(rv->block_cache, block->pc_start))) { block->hot = true; block->offset = translate_x64(rv, block); ((exec_block_func_t) state->buf)( diff --git a/src/jit_x64.c b/src/jit_x64.c index a850c633..b9e481a1 100644 --- a/src/jit_x64.c +++ b/src/jit_x64.c @@ -466,7 +466,7 @@ static void do_fuse7(struct jit_state *state, riscv_t *rv UNUSED, rv_insn_t *ir) /* clang-format off */ static const void *dispatch_table[] = { /* RV32 instructions */ -#define _(inst, can_branch, insn_len, reg_mask) [rv_insn_##inst] = do_##inst, +#define _(inst, can_branch, insn_len, translatable, reg_mask) [rv_insn_##inst] = do_##inst, RV_INSN_LIST #undef _ /* Macro operation fusion instructions */ @@ -532,12 +532,12 @@ static void translate_chained_block(struct jit_state *state, rv_insn_t *ir = block->ir_tail; if (ir->branch_untaken && !set_has(set, ir->pc + 4)) { block_t *block1 = cache_get(rv->block_cache, ir->pc + 4); - if (block1) + if (block1 && block1->translatable) translate_chained_block(state, rv, block1, set); } if (ir->branch_taken && !set_has(set, ir->pc + ir->imm)) { block_t *block1 = cache_get(rv->block_cache, ir->pc + ir->imm); - if (block1) + if (block1 && block1->translatable) translate_chained_block(state, rv, block1, set); } } diff --git a/src/riscv_private.h b/src/riscv_private.h index fb15b277..558c9253 100644 --- a/src/riscv_private.h +++ b/src/riscv_private.h @@ -66,6 +66,8 @@ typedef struct block { #if RV32_HAS(JIT) bool hot; /**< Determine the block is hotspot or not */ uint32_t offset; + bool + translatable; /**< Determine the block has RV32AF insturctions or not */ #endif } block_t; diff --git a/tools/rv_histogram.c b/tools/rv_histogram.c index aeb067e3..4c946f83 100644 --- a/tools/rv_histogram.c +++ b/tools/rv_histogram.c @@ -36,9 +36,9 @@ typedef struct { /* clang-format off */ static rv_hist_t rv_insn_stats[] = { -#define _(inst, can_branch, insn_len, reg_mask) {#inst, 0, reg_mask}, +#define _(inst, can_branch, insn_len, translatable, reg_mask) {#inst, 0, reg_mask}, RV_INSN_LIST - _(unknown, 0, 0, 0) + _(unknown, 0, 0, 0, 0) #undef _ }; /* clang-format on */