From f158bb3af1e7218609b1fdc987f1d5f9cab9d7ae Mon Sep 17 00:00:00 2001 From: Yen-Fu Chen Date: Tue, 10 Oct 2023 20:56:20 +0800 Subject: [PATCH] Manipulate csr_cycle by register --- src/decode.h | 2 +- src/emulate.c | 69 +++++++++++++++++++++++---------------------- src/rv32_template.c | 24 ++++++++-------- 3 files changed, 48 insertions(+), 47 deletions(-) diff --git a/src/decode.h b/src/decode.h index 3c2a817e9..9577f0553 100644 --- a/src/decode.h +++ b/src/decode.h @@ -291,7 +291,7 @@ typedef struct rv_insn { * self-recursive version, enabling the compiler to leverage TCO. */ bool tailcall; - bool (*impl)(riscv_t *, const struct rv_insn *); + bool (*impl)(riscv_t *, const struct rv_insn *, uint64_t); /* Two pointers, 'branch_taken' and 'branch_untaken', are employed to * avoid the overhead associated with aggressive memory copying. Instead diff --git a/src/emulate.c b/src/emulate.c index efc31db9b..6fd16e901 100644 --- a/src/emulate.c +++ b/src/emulate.c @@ -368,17 +368,17 @@ static bool branch_taken = false; static uint32_t last_pc = 0; /* Interpreter-based execution path */ -#define RVOP(inst, code) \ - static bool do_##inst(riscv_t *rv, const rv_insn_t *ir) \ - { \ - rv->csr_cycle++; \ - code; \ - nextop: \ - rv->PC += ir->insn_len; \ - if (unlikely(RVOP_NO_NEXT(ir))) \ - return true; \ - const rv_insn_t *next = ir->next; \ - MUST_TAIL return next->impl(rv, next); \ +#define RVOP(inst, code) \ + static bool do_##inst(riscv_t *rv, const rv_insn_t *ir, uint64_t cycle) \ + { \ + cycle++; \ + code; \ + nextop: \ + rv->PC += ir->insn_len; \ + if (unlikely(RVOP_NO_NEXT(ir))) \ + return true; \ + const rv_insn_t *next = ir->next; \ + MUST_TAIL return next->impl(rv, next, cycle); \ } #include "rv32_template.c" @@ -408,9 +408,9 @@ enum { }; /* multiple lui */ -static bool do_fuse1(riscv_t *rv, rv_insn_t *ir) +static bool do_fuse1(riscv_t *rv, rv_insn_t *ir, uint64_t cycle) { - rv->csr_cycle += ir->imm2; + cycle += ir->imm2; opcode_fuse_t *fuse = ir->fuse; for (int i = 0; i < ir->imm2; i++) rv->X[fuse[i].rd] = fuse[i].imm; @@ -418,26 +418,26 @@ static bool do_fuse1(riscv_t *rv, rv_insn_t *ir) if (unlikely(RVOP_NO_NEXT(ir))) return true; const rv_insn_t *next = ir->next; - MUST_TAIL return next->impl(rv, next); + MUST_TAIL return next->impl(rv, next, cycle); } /* LUI + ADD */ -static bool do_fuse2(riscv_t *rv, rv_insn_t *ir) +static bool do_fuse2(riscv_t *rv, rv_insn_t *ir, uint64_t cycle) { - rv->csr_cycle += 2; + cycle += 2; rv->X[ir->rd] = ir->imm; rv->X[ir->rs2] = rv->X[ir->rd] + rv->X[ir->rs1]; rv->PC += 2 * ir->insn_len; if (unlikely(RVOP_NO_NEXT(ir))) return true; const rv_insn_t *next = ir->next; - MUST_TAIL return next->impl(rv, next); + MUST_TAIL return next->impl(rv, next, cycle); } /* multiple SW */ -static bool do_fuse3(riscv_t *rv, rv_insn_t *ir) +static bool do_fuse3(riscv_t *rv, rv_insn_t *ir, uint64_t cycle) { - rv->csr_cycle += ir->imm2; + cycle += ir->imm2; opcode_fuse_t *fuse = ir->fuse; /* The memory addresses of the sw instructions are contiguous, thus only * the first SW instruction needs to be checked to determine if its memory @@ -452,13 +452,13 @@ static bool do_fuse3(riscv_t *rv, rv_insn_t *ir) if (unlikely(RVOP_NO_NEXT(ir))) return true; const rv_insn_t *next = ir->next; - MUST_TAIL return next->impl(rv, next); + MUST_TAIL return next->impl(rv, next, cycle); } /* multiple LW */ -static bool do_fuse4(riscv_t *rv, rv_insn_t *ir) +static bool do_fuse4(riscv_t *rv, rv_insn_t *ir, uint64_t cycle) { - rv->csr_cycle += ir->imm2; + cycle += ir->imm2; opcode_fuse_t *fuse = ir->fuse; /* The memory addresses of the lw instructions are contiguous, therefore * only the first LW instruction needs to be checked to determine if its @@ -473,13 +473,13 @@ static bool do_fuse4(riscv_t *rv, rv_insn_t *ir) if (unlikely(RVOP_NO_NEXT(ir))) return true; const rv_insn_t *next = ir->next; - MUST_TAIL return next->impl(rv, next); + MUST_TAIL return next->impl(rv, next, cycle); } /* memset */ -static bool do_fuse5(riscv_t *rv, const rv_insn_t *ir) +static bool do_fuse5(riscv_t *rv, const rv_insn_t *ir, uint64_t cycle) { - rv->csr_cycle += 2; + cycle += 2; memory_t *m = ((state_t *) rv->userdata)->mem; memset((char *) m->mem_base + rv->X[rv_reg_a0], rv->X[rv_reg_a1], rv->X[rv_reg_a2]); @@ -487,13 +487,13 @@ static bool do_fuse5(riscv_t *rv, const rv_insn_t *ir) if (unlikely(RVOP_NO_NEXT(ir))) return true; const rv_insn_t *next = ir->next; - MUST_TAIL return next->impl(rv, next); + MUST_TAIL return next->impl(rv, next, cycle); } /* memcpy */ -static bool do_fuse6(riscv_t *rv, const rv_insn_t *ir) +static bool do_fuse6(riscv_t *rv, const rv_insn_t *ir, uint64_t cycle) { - rv->csr_cycle += 2; + cycle += 2; memory_t *m = ((state_t *) rv->userdata)->mem; memcpy((char *) m->mem_base + rv->X[rv_reg_a0], (char *) m->mem_base + rv->X[rv_reg_a1], rv->X[rv_reg_a2]); @@ -501,13 +501,13 @@ static bool do_fuse6(riscv_t *rv, const rv_insn_t *ir) if (unlikely(RVOP_NO_NEXT(ir))) return true; const rv_insn_t *next = ir->next; - MUST_TAIL return next->impl(rv, next); + MUST_TAIL return next->impl(rv, next, cycle); } /* multiple shift immediate */ -static bool do_fuse7(riscv_t *rv, const rv_insn_t *ir) +static bool do_fuse7(riscv_t *rv, const rv_insn_t *ir, uint64_t cycle) { - rv->csr_cycle += ir->imm2; + cycle += ir->imm2; opcode_fuse_t *fuse = ir->fuse; for (int i = 0; i < ir->imm2; i++) shift_func(rv, (const rv_insn_t *) (&fuse[i])); @@ -515,7 +515,7 @@ static bool do_fuse7(riscv_t *rv, const rv_insn_t *ir) if (unlikely(RVOP_NO_NEXT(ir))) return true; const rv_insn_t *next = ir->next; - MUST_TAIL return next->impl(rv, next); + MUST_TAIL return next->impl(rv, next, cycle); } /* clang-format off */ @@ -988,9 +988,10 @@ void rv_step(riscv_t *rv, int32_t cycles) /* execute the block */ const rv_insn_t *ir = block->ir_head; - if (unlikely(!ir->impl(rv, ir))) + uint64_t cycle = rv->csr_cycle; + if (unlikely(!ir->impl(rv, ir, cycle))) break; - + rv->csr_cycle = cycle; prev = block; } } diff --git a/src/rv32_template.c b/src/rv32_template.c index fddcbb74d..d7661c2ae 100644 --- a/src/rv32_template.c +++ b/src/rv32_template.c @@ -31,7 +31,7 @@ RVOP(jal, { /* check instruction misaligned */ RV_EXC_MISALIGN_HANDLER(pc, insn, false, 0); if (ir->branch_taken) - return ir->branch_taken->impl(rv, ir->branch_taken); + return ir->branch_taken->impl(rv, ir->branch_taken, cycle); return true; }) @@ -53,7 +53,7 @@ RVOP(jalr, { RV_EXC_MISALIGN_HANDLER(pc, insn, false, 0); block_t *block = block_find(&rv->block_map, rv->PC); if (block) - return block->ir_head->impl(rv, block->ir_head); + return block->ir_head->impl(rv, block->ir_head, cycle); return true; }) @@ -66,7 +66,7 @@ RVOP(jalr, { goto nextop; \ rv->PC += ir->insn_len; \ last_pc = rv->PC; \ - return ir->branch_untaken->impl(rv, ir->branch_untaken); \ + return ir->branch_untaken->impl(rv, ir->branch_untaken, cycle); \ } \ branch_taken = true; \ rv->PC += ir->imm; \ @@ -74,7 +74,7 @@ RVOP(jalr, { RV_EXC_MISALIGN_HANDLER(pc, insn, false, 0); \ if (ir->branch_taken) { \ last_pc = rv->PC; \ - return ir->branch_taken->impl(rv, ir->branch_taken); \ + return ir->branch_taken->impl(rv, ir->branch_taken, cycle); \ } \ return true; /* clang-format on */ @@ -811,7 +811,7 @@ RVOP(cjal, { rv->PC += ir->imm; RV_EXC_MISALIGN_HANDLER(rv->PC, insn, true, 0); if (ir->branch_taken) - return ir->branch_taken->impl(rv, ir->branch_taken); + return ir->branch_taken->impl(rv, ir->branch_taken, cycle); return true; }) @@ -879,7 +879,7 @@ RVOP(cj, { rv->PC += ir->imm; RV_EXC_MISALIGN_HANDLER(rv->PC, insn, true, 0); if (ir->branch_taken) - return ir->branch_taken->impl(rv, ir->branch_taken); + return ir->branch_taken->impl(rv, ir->branch_taken, cycle); return true; }) @@ -895,13 +895,13 @@ RVOP(cbeqz, { goto nextop; rv->PC += ir->insn_len; last_pc = rv->PC; - return ir->branch_untaken->impl(rv, ir->branch_untaken); + return ir->branch_untaken->impl(rv, ir->branch_untaken, cycle); } branch_taken = true; rv->PC += (uint32_t) ir->imm; if (ir->branch_taken) { last_pc = rv->PC; - return ir->branch_taken->impl(rv, ir->branch_taken); + return ir->branch_taken->impl(rv, ir->branch_taken, cycle); } return true; }) @@ -914,13 +914,13 @@ RVOP(cbnez, { goto nextop; rv->PC += ir->insn_len; last_pc = rv->PC; - return ir->branch_untaken->impl(rv, ir->branch_untaken); + return ir->branch_untaken->impl(rv, ir->branch_untaken, cycle); } branch_taken = true; rv->PC += (uint32_t) ir->imm; if (ir->branch_taken) { last_pc = rv->PC; - return ir->branch_taken->impl(rv, ir->branch_taken); + return ir->branch_taken->impl(rv, ir->branch_taken, cycle); } return true; }) @@ -943,7 +943,7 @@ RVOP(cjr, { rv->PC = rv->X[ir->rs1]; block_t *block = block_find(&rv->block_map, rv->PC); if (block) - return block->ir_head->impl(rv, block->ir_head); + return block->ir_head->impl(rv, block->ir_head, cycle); return true; }) @@ -966,7 +966,7 @@ RVOP(cjalr, { RV_EXC_MISALIGN_HANDLER(rv->PC, insn, true, 0); block_t *block = block_find(&rv->block_map, rv->PC); if (block) - return block->ir_head->impl(rv, block->ir_head); + return block->ir_head->impl(rv, block->ir_head, cycle); return true; })