diff --git a/src/emulate.c b/src/emulate.c index e5e4cddf..dafead5c 100644 --- a/src/emulate.c +++ b/src/emulate.c @@ -190,8 +190,22 @@ static uint32_t *csr_get_ptr(riscv_t *rv, uint32_t csr) * If rd == x0, then the instruction shall not read the CSR and shall not cause * any of the side effects that might occur on a CSR read. */ -static uint32_t csr_csrrw(riscv_t *rv, uint32_t csr, uint32_t val) +static uint32_t csr_csrrw(riscv_t *rv, + uint32_t csr, + uint32_t val, + uint64_t cycle) { + /* Sync cycle counter for cycle-related CSRs only */ + switch (csr & 0xFFF) { + case CSR_CYCLE: + case CSR_CYCLEH: + case CSR_INSTRET: + case CSR_INSTRETH: + if (rv->csr_cycle != cycle) + rv->csr_cycle = cycle; + break; + } + uint32_t *c = csr_get_ptr(rv, csr); if (!c) return 0; @@ -222,8 +236,21 @@ static uint32_t csr_csrrw(riscv_t *rv, uint32_t csr, uint32_t val) } /* perform csrrs (atomic read and set) */ -static uint32_t csr_csrrs(riscv_t *rv, uint32_t csr, uint32_t val) +static uint32_t csr_csrrs(riscv_t *rv, + uint32_t csr, + uint32_t val, + uint64_t cycle) { + /* Sync cycle counter for cycle-related CSRs only */ + switch (csr & 0xFFF) { + case CSR_CYCLE: + case CSR_CYCLEH: + case CSR_INSTRET: + case CSR_INSTRETH: + if (rv->csr_cycle != cycle) + rv->csr_cycle = cycle; + break; + } uint32_t *c = csr_get_ptr(rv, csr); if (!c) return 0; @@ -243,8 +270,22 @@ static uint32_t csr_csrrs(riscv_t *rv, uint32_t csr, uint32_t val) * Read old value of CSR, zero-extend to XLEN bits, write to rd. * Read value from rs1, use as bit mask to clear bits in CSR. */ -static uint32_t csr_csrrc(riscv_t *rv, uint32_t csr, uint32_t val) +static uint32_t csr_csrrc(riscv_t *rv, + uint32_t csr, + uint32_t val, + uint64_t cycle) { + /* Sync cycle counter for cycle-related CSRs only */ + switch (csr & 0xFFF) { + case CSR_CYCLE: + case CSR_CYCLEH: + case CSR_INSTRET: + case CSR_INSTRETH: + if (rv->csr_cycle != cycle) + rv->csr_cycle = cycle; + break; + } + uint32_t *c = csr_get_ptr(rv, csr); if (!c) return 0; diff --git a/src/rv32_template.c b/src/rv32_template.c index 14ad8b7a..9a4f913b 100644 --- a/src/rv32_template.c +++ b/src/rv32_template.c @@ -1216,7 +1216,7 @@ RVOP( RVOP( csrrw, { - uint32_t tmp = csr_csrrw(rv, ir->imm, rv->X[ir->rs1]); + uint32_t tmp = csr_csrrw(rv, ir->imm, rv->X[ir->rs1], cycle); rv->X[ir->rd] = ir->rd ? tmp : rv->X[ir->rd]; }, GEN({ @@ -1236,7 +1236,7 @@ RVOP( csrrs, { uint32_t tmp = csr_csrrs( - rv, ir->imm, (ir->rs1 == rv_reg_zero) ? 0U : rv->X[ir->rs1]); + rv, ir->imm, (ir->rs1 == rv_reg_zero) ? 0U : rv->X[ir->rs1], cycle); rv->X[ir->rd] = ir->rd ? tmp : rv->X[ir->rd]; }, GEN({ @@ -1248,7 +1248,7 @@ RVOP( csrrc, { uint32_t tmp = csr_csrrc( - rv, ir->imm, (ir->rs1 == rv_reg_zero) ? 0U : rv->X[ir->rs1]); + rv, ir->imm, (ir->rs1 == rv_reg_zero) ? 0U : rv->X[ir->rs1], cycle); rv->X[ir->rd] = ir->rd ? tmp : rv->X[ir->rd]; }, GEN({ @@ -1259,7 +1259,7 @@ RVOP( RVOP( csrrwi, { - uint32_t tmp = csr_csrrw(rv, ir->imm, ir->rs1); + uint32_t tmp = csr_csrrw(rv, ir->imm, ir->rs1, cycle); rv->X[ir->rd] = ir->rd ? tmp : rv->X[ir->rd]; }, GEN({ @@ -1270,7 +1270,7 @@ RVOP( RVOP( csrrsi, { - uint32_t tmp = csr_csrrs(rv, ir->imm, ir->rs1); + uint32_t tmp = csr_csrrs(rv, ir->imm, ir->rs1, cycle); rv->X[ir->rd] = ir->rd ? tmp : rv->X[ir->rd]; }, GEN({ @@ -1281,7 +1281,7 @@ RVOP( RVOP( csrrci, { - uint32_t tmp = csr_csrrc(rv, ir->imm, ir->rs1); + uint32_t tmp = csr_csrrc(rv, ir->imm, ir->rs1, cycle); rv->X[ir->rd] = ir->rd ? tmp : rv->X[ir->rd]; }, GEN({