summaryrefslogtreecommitdiff
path: root/riscv.c
diff options
context:
space:
mode:
authorJiri Gaisler <jiri@gaisler.se>2019-05-22 21:56:59 +0200
committerJiri Gaisler <jiri@gaisler.se>2019-05-27 10:35:06 +0200
commit6a742ad589f8a5967cb878e4065f70d93b90fb58 (patch)
tree7a71ab6385f0f177594ebe0be30f2c65f7e11497 /riscv.c
parent92d08c9905121d4022c3be45d9f4579429d5620a (diff)
Add emulated L1 cache to SMP configurations
* Also improve timing accuracy for certain instructions
Diffstat (limited to 'riscv.c')
-rw-r--r--riscv.c38
1 files changed, 28 insertions, 10 deletions
diff --git a/riscv.c b/riscv.c
index c21d625..68e9f85 100644
--- a/riscv.c
+++ b/riscv.c
@@ -819,36 +819,44 @@ riscv_dispatch_instruction (sregs)
sop2 = op2;
sop2 = op1 * op2;
sregs->g[rd] = sop2;
+ sregs->icnt = T_MUL;
break;
case 1: /* MULH */
sop64a = (int64) op1 *(int64) op2;
sregs->g[rd] = (sop64a >> 32) & 0xffffffff;
+ sregs->icnt = T_MUL;
break;
case 2: /* MULHSU */
sop64a = (int64) op1 *(uint64) op2;
sregs->g[rd] = (sop64a >> 32) & 0xffffffff;
+ sregs->icnt = T_MUL;
break;
case 3: /* MULHU */
op64a = (uint64) op1 *(uint64) op2;
sregs->g[rd] = (op64a >> 32) & 0xffffffff;
+ sregs->icnt = T_MUL;
break;
case 4: /* DIV */
sop1 = op1;
sop2 = op2;
result = sop1 / sop2;
sregs->g[rd] = result;
+ sregs->icnt = T_DIV;
break;
case 5: /* DIVU */
sregs->g[rd] = op1 / op2;
+ sregs->icnt = T_DIV;
break;
case 6: /* REM */
sop1 = op1;
sop2 = op2;
sop1 = sop1 % sop2;
sregs->g[rd] = sop1;
+ sregs->icnt = T_DIV;
break;
case 7: /* REMU */
sregs->g[rd] = op1 % op2;
+ sregs->icnt = T_DIV;
break;
}
break;
@@ -858,9 +866,7 @@ riscv_dispatch_instruction (sregs)
break;
case OP_STORE: /* store instructions */
-#ifdef STAT
sregs->nstore++;
-#endif
offset = EXTRACT_STYPE_IMM (sregs->inst);
address = op1 + offset;
wdata = &(sregs->g[rs2]);
@@ -918,12 +924,15 @@ riscv_dispatch_instruction (sregs)
default:
sregs->trap = TRAP_ILLEG;
}
+ if (ncpu > 1)
+ {
+ l1data_update(address, sregs->cpu);
+ l1data_snoop(address, sregs->cpu);
+ }
break;
case OP_FSW: /* F store instructions */
-#ifdef STAT
sregs->nstore++;
-#endif
offset = EXTRACT_STYPE_IMM (sregs->inst);
address = op1 + offset;
wdata = &sregs->fsi[rs2 << 1];
@@ -972,11 +981,14 @@ riscv_dispatch_instruction (sregs)
default:
sregs->trap = TRAP_ILLEG;
}
+ if (ncpu > 1)
+ {
+ l1data_update(address, sregs->cpu);
+ l1data_snoop(address, sregs->cpu);
+ }
break;
case OP_LOAD: /* load instructions */
-#ifdef STAT
sregs->nload++;
-#endif
offset = EXTRACT_ITYPE_IMM (sregs->inst);
address = op1 + offset;
if (ebase.wprnum)
@@ -1080,14 +1092,17 @@ riscv_dispatch_instruction (sregs)
default:
sregs->trap = TRAP_ILLEG;
}
+ if (ncpu > 1)
+ {
+ l1data_update(address, sregs->cpu);
+ }
break;
case OP_AMO: /* atomic instructions */
address = op1;
funct5 = (sregs->inst >> 27) & 0x1f;
-#ifdef STAT
sregs->nstore++;
sregs->nload++;
-#endif
+ sregs->icnt = T_AMO;
switch (funct5)
{
case LRQ:
@@ -1302,9 +1317,7 @@ riscv_dispatch_instruction (sregs)
}
break;
case OP_FLOAD: /* float load instructions */
-#ifdef STAT
sregs->nload++;
-#endif
offset = EXTRACT_ITYPE_IMM (sregs->inst);
address = op1 + offset;
if (ebase.wprnum)
@@ -1367,6 +1380,10 @@ riscv_dispatch_instruction (sregs)
default:
sregs->trap = TRAP_ILLEG;
}
+ if (ncpu > 1)
+ {
+ l1data_update(address, sregs->cpu);
+ }
break;
#ifdef FPU_ENABLED
case OP_FPU:
@@ -1841,6 +1858,7 @@ riscv_dispatch_instruction (sregs)
break;
#endif
case OP_FENCE:
+ sregs->icnt = TRAP_C;
break;
default:
sregs->trap = TRAP_ILLEG;