Skip to content

Commit

Permalink
Avoid the tier-1 JIT compiler from translating RV32F and RV32A
Browse files Browse the repository at this point in the history
  • Loading branch information
qwe661234 committed Dec 15, 2023
1 parent 3aa197b commit 042ac1c
Show file tree
Hide file tree
Showing 5 changed files with 175 additions and 157 deletions.
290 changes: 145 additions & 145 deletions src/decode.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,150 +32,150 @@ enum op_field {
* 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 */

Expand All @@ -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,
Expand Down
32 changes: 24 additions & 8 deletions src/emulate.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -356,15 +357,15 @@ 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 _
};

/* 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 _
Expand Down Expand Up @@ -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 */
Expand All @@ -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 _
Expand All @@ -557,6 +558,18 @@ FORCE_INLINE bool insn_is_branch(uint8_t opcode)
return false;
}

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;
}

FORCE_INLINE bool insn_is_unconditional_branch(uint8_t opcode)
{
switch (opcode) {
Expand Down Expand Up @@ -607,6 +620,8 @@ 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 (!insn_is_translatable(ir->opcode))
block->translatable = false;
/* stop on branch */
if (insn_is_branch(ir->opcode)) {
if (ir->imm < 0)
Expand Down Expand Up @@ -898,7 +913,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 _
Expand Down Expand Up @@ -1045,9 +1060,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)(
Expand Down
Loading

0 comments on commit 042ac1c

Please sign in to comment.