Skip to content

Commit

Permalink
Manipulate csr_cycle by register
Browse files Browse the repository at this point in the history
  • Loading branch information
qwe661234 committed Oct 10, 2023
1 parent c8d4acb commit 3fa3dc7
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 47 deletions.
2 changes: 1 addition & 1 deletion src/decode.h
Original file line number Diff line number Diff line change
Expand Up @@ -289,7 +289,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
Expand Down
69 changes: 35 additions & 34 deletions src/emulate.c
Original file line number Diff line number Diff line change
Expand Up @@ -363,17 +363,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"
Expand Down Expand Up @@ -403,9 +403,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;
Expand All @@ -414,26 +414,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
Expand All @@ -448,13 +448,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
Expand All @@ -469,49 +469,49 @@ 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]);
rv->PC = rv->X[rv_reg_ra] & ~1U;
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]);
rv->PC = rv->X[rv_reg_ra] & ~1U;
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]));
rv->PC += ir->imm2 * 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);
}

/* clang-format off */
Expand Down Expand Up @@ -1169,11 +1169,12 @@ void rv_step(riscv_t *rv, int32_t cycles)
}
last_pc = rv->PC;

register uint64_t cycle = rv->csr_cycle;
/* execute the block */
const rv_insn_t *ir = block->ir_head;
if (unlikely(!ir->impl(rv, ir)))
if (unlikely(!ir->impl(rv, ir, cycle)))
break;

rv->csr_cycle = cycle;
prev = block;
}
}
Expand Down
24 changes: 12 additions & 12 deletions src/rv32_template.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
})

Expand All @@ -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;
})

Expand All @@ -66,15 +66,15 @@ 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; \
/* check instruction misaligned */ \
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 */
Expand Down Expand Up @@ -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;
})

Expand Down Expand Up @@ -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;
})

Expand All @@ -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;
})
Expand All @@ -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;
})
Expand All @@ -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;
})

Expand All @@ -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;
})

Expand Down

0 comments on commit 3fa3dc7

Please sign in to comment.