Skip to content

Commit f69568a

Browse files
committed
Fix synchronize cycle CSR update
Previous commit 78836cf prevents frequently update of rv->csr_cycle by manipulate it with register. However, currently rv->csr_cycle only update after a block end or JIT clearing block map. This results csr cycle instructions cannot fetch up-to-date cycle. If started cycle and ended cycle are located in a same block, it cause the cycle count becomes zero. This commit updates rv->csr_cycle before csr cycle instruction is executed.
1 parent bd0f10a commit f69568a

File tree

2 files changed

+50
-9
lines changed

2 files changed

+50
-9
lines changed

src/emulate.c

Lines changed: 44 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -190,8 +190,22 @@ static uint32_t *csr_get_ptr(riscv_t *rv, uint32_t csr)
190190
* If rd == x0, then the instruction shall not read the CSR and shall not cause
191191
* any of the side effects that might occur on a CSR read.
192192
*/
193-
static uint32_t csr_csrrw(riscv_t *rv, uint32_t csr, uint32_t val)
193+
static uint32_t csr_csrrw(riscv_t *rv,
194+
uint32_t csr,
195+
uint32_t val,
196+
uint64_t cycle)
194197
{
198+
/* Sync cycle counter for cycle-related CSRs only */
199+
switch (csr & 0xFFF) {
200+
case CSR_CYCLE:
201+
case CSR_CYCLEH:
202+
case CSR_INSTRET:
203+
case CSR_INSTRETH:
204+
if (rv->csr_cycle != cycle)
205+
rv->csr_cycle = cycle;
206+
break;
207+
}
208+
195209
uint32_t *c = csr_get_ptr(rv, csr);
196210
if (!c)
197211
return 0;
@@ -222,8 +236,21 @@ static uint32_t csr_csrrw(riscv_t *rv, uint32_t csr, uint32_t val)
222236
}
223237

224238
/* perform csrrs (atomic read and set) */
225-
static uint32_t csr_csrrs(riscv_t *rv, uint32_t csr, uint32_t val)
239+
static uint32_t csr_csrrs(riscv_t *rv,
240+
uint32_t csr,
241+
uint32_t val,
242+
uint64_t cycle)
226243
{
244+
/* Sync cycle counter for cycle-related CSRs only */
245+
switch (csr & 0xFFF) {
246+
case CSR_CYCLE:
247+
case CSR_CYCLEH:
248+
case CSR_INSTRET:
249+
case CSR_INSTRETH:
250+
if (rv->csr_cycle != cycle)
251+
rv->csr_cycle = cycle;
252+
break;
253+
}
227254
uint32_t *c = csr_get_ptr(rv, csr);
228255
if (!c)
229256
return 0;
@@ -243,8 +270,22 @@ static uint32_t csr_csrrs(riscv_t *rv, uint32_t csr, uint32_t val)
243270
* Read old value of CSR, zero-extend to XLEN bits, write to rd.
244271
* Read value from rs1, use as bit mask to clear bits in CSR.
245272
*/
246-
static uint32_t csr_csrrc(riscv_t *rv, uint32_t csr, uint32_t val)
273+
static uint32_t csr_csrrc(riscv_t *rv,
274+
uint32_t csr,
275+
uint32_t val,
276+
uint64_t cycle)
247277
{
278+
/* Sync cycle counter for cycle-related CSRs only */
279+
switch (csr & 0xFFF) {
280+
case CSR_CYCLE:
281+
case CSR_CYCLEH:
282+
case CSR_INSTRET:
283+
case CSR_INSTRETH:
284+
if (rv->csr_cycle != cycle)
285+
rv->csr_cycle = cycle;
286+
break;
287+
}
288+
248289
uint32_t *c = csr_get_ptr(rv, csr);
249290
if (!c)
250291
return 0;

src/rv32_template.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1216,7 +1216,7 @@ RVOP(
12161216
RVOP(
12171217
csrrw,
12181218
{
1219-
uint32_t tmp = csr_csrrw(rv, ir->imm, rv->X[ir->rs1]);
1219+
uint32_t tmp = csr_csrrw(rv, ir->imm, rv->X[ir->rs1], cycle);
12201220
rv->X[ir->rd] = ir->rd ? tmp : rv->X[ir->rd];
12211221
},
12221222
GEN({
@@ -1236,7 +1236,7 @@ RVOP(
12361236
csrrs,
12371237
{
12381238
uint32_t tmp = csr_csrrs(
1239-
rv, ir->imm, (ir->rs1 == rv_reg_zero) ? 0U : rv->X[ir->rs1]);
1239+
rv, ir->imm, (ir->rs1 == rv_reg_zero) ? 0U : rv->X[ir->rs1], cycle);
12401240
rv->X[ir->rd] = ir->rd ? tmp : rv->X[ir->rd];
12411241
},
12421242
GEN({
@@ -1248,7 +1248,7 @@ RVOP(
12481248
csrrc,
12491249
{
12501250
uint32_t tmp = csr_csrrc(
1251-
rv, ir->imm, (ir->rs1 == rv_reg_zero) ? 0U : rv->X[ir->rs1]);
1251+
rv, ir->imm, (ir->rs1 == rv_reg_zero) ? 0U : rv->X[ir->rs1], cycle);
12521252
rv->X[ir->rd] = ir->rd ? tmp : rv->X[ir->rd];
12531253
},
12541254
GEN({
@@ -1259,7 +1259,7 @@ RVOP(
12591259
RVOP(
12601260
csrrwi,
12611261
{
1262-
uint32_t tmp = csr_csrrw(rv, ir->imm, ir->rs1);
1262+
uint32_t tmp = csr_csrrw(rv, ir->imm, ir->rs1, cycle);
12631263
rv->X[ir->rd] = ir->rd ? tmp : rv->X[ir->rd];
12641264
},
12651265
GEN({
@@ -1270,7 +1270,7 @@ RVOP(
12701270
RVOP(
12711271
csrrsi,
12721272
{
1273-
uint32_t tmp = csr_csrrs(rv, ir->imm, ir->rs1);
1273+
uint32_t tmp = csr_csrrs(rv, ir->imm, ir->rs1, cycle);
12741274
rv->X[ir->rd] = ir->rd ? tmp : rv->X[ir->rd];
12751275
},
12761276
GEN({
@@ -1281,7 +1281,7 @@ RVOP(
12811281
RVOP(
12821282
csrrci,
12831283
{
1284-
uint32_t tmp = csr_csrrc(rv, ir->imm, ir->rs1);
1284+
uint32_t tmp = csr_csrrc(rv, ir->imm, ir->rs1, cycle);
12851285
rv->X[ir->rd] = ir->rd ? tmp : rv->X[ir->rd];
12861286
},
12871287
GEN({

0 commit comments

Comments
 (0)