@@ -73,7 +73,8 @@ sim_open (SIM_OPEN_KIND kind, host_callback *callback,
callback->syscall_map = cb_riscv_syscall_map;
/* The cpu data is kept in a separately allocated chunk of memory. */
- if (sim_cpu_alloc_all (sd, 1) != SIM_RC_OK)
+ if (sim_cpu_alloc_all_extra (sd, 1, sizeof (struct riscv_sim_cpu))
+ != SIM_RC_OK)
{
free_state (sd);
return 0;
@@ -37,7 +37,7 @@
#define TRACE_REG(cpu, reg) \
TRACE_REGISTER (cpu, "wrote %s = %#" PRIxTW, riscv_gpr_names_abi[reg], \
- cpu->regs[reg])
+ RISCV_SIM_CPU (cpu)->regs[reg])
static const struct riscv_opcode *riscv_hash[OP_MASK_OP + 1];
#define OP_HASH_IDX(i) ((i) & (riscv_insn_length (i) == 2 ? 0x3 : 0x7f))
@@ -48,7 +48,8 @@ static const struct riscv_opcode *riscv_hash[OP_MASK_OP + 1];
{ \
SIM_DESC sd = CPU_STATE (cpu); \
TRACE_INSN (cpu, "RV32I-only " fmt, ## args); \
- sim_engine_halt (sd, cpu, NULL, cpu->pc, sim_signalled, SIM_SIGILL); \
+ sim_engine_halt (sd, cpu, NULL, sim_pc_get (cpu), sim_signalled, \
+ SIM_SIGILL); \
} \
} while (0)
@@ -58,16 +59,19 @@ static const struct riscv_opcode *riscv_hash[OP_MASK_OP + 1];
{ \
SIM_DESC sd = CPU_STATE (cpu); \
TRACE_INSN (cpu, "RV64I-only " fmt, ## args); \
- sim_engine_halt (sd, cpu, NULL, cpu->pc, sim_signalled, SIM_SIGILL); \
+ sim_engine_halt (sd, cpu, NULL, sim_pc_get (cpu), sim_signalled, \
+ SIM_SIGILL); \
} \
} while (0)
static INLINE void
store_rd (SIM_CPU *cpu, int rd, unsigned_word val)
{
+ struct riscv_sim_cpu *riscv_cpu = RISCV_SIM_CPU (cpu);
+
if (rd)
{
- cpu->regs[rd] = val;
+ riscv_cpu->regs[rd] = val;
TRACE_REG (cpu, rd);
}
}
@@ -93,24 +97,26 @@ static INLINE void
store_csr (SIM_CPU *cpu, const char *name, int csr, unsigned_word *reg,
unsigned_word val)
{
+ struct riscv_sim_cpu *riscv_cpu = RISCV_SIM_CPU (cpu);
+
switch (csr)
{
/* These are pseudo registers that modify sub-fields of fcsr. */
case CSR_FRM:
val &= 0x7;
*reg = val;
- cpu->csr.fcsr = (cpu->csr.fcsr & ~0xe0) | (val << 5);
+ riscv_cpu->csr.fcsr = (riscv_cpu->csr.fcsr & ~0xe0) | (val << 5);
break;
case CSR_FFLAGS:
val &= 0x1f;
*reg = val;
- cpu->csr.fcsr = (cpu->csr.fcsr & ~0x1f) | val;
+ riscv_cpu->csr.fcsr = (riscv_cpu->csr.fcsr & ~0x1f) | val;
break;
/* Keep the sub-fields in sync. */
case CSR_FCSR:
*reg = val;
- cpu->csr.frm = (val >> 5) & 0x7;
- cpu->csr.fflags = val & 0x1f;
+ riscv_cpu->csr.frm = (val >> 5) & 0x7;
+ riscv_cpu->csr.fflags = val & 0x1f;
break;
/* Allow certain registers only in respective modes. */
@@ -147,6 +153,7 @@ static sim_cia
execute_i (SIM_CPU *cpu, unsigned_word iw, const struct riscv_opcode *op)
{
SIM_DESC sd = CPU_STATE (cpu);
+ struct riscv_sim_cpu *riscv_cpu = RISCV_SIM_CPU (cpu);
int rd = (iw >> OP_SH_RD) & OP_MASK_RD;
int rs1 = (iw >> OP_SH_RS1) & OP_MASK_RS1;
int rs2 = (iw >> OP_SH_RS2) & OP_MASK_RS2;
@@ -160,7 +167,7 @@ execute_i (SIM_CPU *cpu, unsigned_word iw, const struct riscv_opcode *op)
unsigned_word sb_imm = EXTRACT_BTYPE_IMM (iw);
unsigned_word shamt_imm = ((iw >> OP_SH_SHAMT) & OP_MASK_SHAMT);
unsigned_word tmp;
- sim_cia pc = cpu->pc + 4;
+ sim_cia pc = riscv_cpu->pc + 4;
TRACE_EXTRACT (cpu,
"rd:%-2i:%-4s "
@@ -168,8 +175,10 @@ execute_i (SIM_CPU *cpu, unsigned_word iw, const struct riscv_opcode *op)
"rs2:%-2i:%-4s %0*" PRIxTW " "
"match:%#x mask:%#x",
rd, rd_name,
- rs1, rs1_name, (int) sizeof (unsigned_word) * 2, cpu->regs[rs1],
- rs2, rs2_name, (int) sizeof (unsigned_word) * 2, cpu->regs[rs2],
+ rs1, rs1_name, (int) sizeof (unsigned_word) * 2,
+ riscv_cpu->regs[rs1],
+ rs2, rs2_name, (int) sizeof (unsigned_word) * 2,
+ riscv_cpu->regs[rs2],
(unsigned) op->match, (unsigned) op->mask);
switch (op->match)
@@ -177,65 +186,67 @@ execute_i (SIM_CPU *cpu, unsigned_word iw, const struct riscv_opcode *op)
case MATCH_ADD:
TRACE_INSN (cpu, "add %s, %s, %s; // %s = %s + %s",
rd_name, rs1_name, rs2_name, rd_name, rs1_name, rs2_name);
- store_rd (cpu, rd, cpu->regs[rs1] + cpu->regs[rs2]);
+ store_rd (cpu, rd, riscv_cpu->regs[rs1] + riscv_cpu->regs[rs2]);
break;
case MATCH_ADDW:
TRACE_INSN (cpu, "addw %s, %s, %s; // %s = %s + %s",
rd_name, rs1_name, rs2_name, rd_name, rs1_name, rs2_name);
RISCV_ASSERT_RV64 (cpu, "insn: %s", op->name);
- store_rd (cpu, rd, EXTEND32 (cpu->regs[rs1] + cpu->regs[rs2]));
+ store_rd (cpu, rd,
+ EXTEND32 (riscv_cpu->regs[rs1] + riscv_cpu->regs[rs2]));
break;
case MATCH_ADDI:
TRACE_INSN (cpu, "addi %s, %s, %#" PRIxTW "; // %s = %s + %#" PRIxTW,
rd_name, rs1_name, i_imm, rd_name, rs1_name, i_imm);
- store_rd (cpu, rd, cpu->regs[rs1] + i_imm);
+ store_rd (cpu, rd, riscv_cpu->regs[rs1] + i_imm);
break;
case MATCH_ADDIW:
TRACE_INSN (cpu, "addiw %s, %s, %#" PRIxTW "; // %s = %s + %#" PRIxTW,
rd_name, rs1_name, i_imm, rd_name, rs1_name, i_imm);
RISCV_ASSERT_RV64 (cpu, "insn: %s", op->name);
- store_rd (cpu, rd, EXTEND32 (cpu->regs[rs1] + i_imm));
+ store_rd (cpu, rd, EXTEND32 (riscv_cpu->regs[rs1] + i_imm));
break;
case MATCH_AND:
TRACE_INSN (cpu, "and %s, %s, %s; // %s = %s & %s",
rd_name, rs1_name, rs2_name, rd_name, rs1_name, rs2_name);
- store_rd (cpu, rd, cpu->regs[rs1] & cpu->regs[rs2]);
+ store_rd (cpu, rd, riscv_cpu->regs[rs1] & riscv_cpu->regs[rs2]);
break;
case MATCH_ANDI:
TRACE_INSN (cpu, "andi %s, %s, %" PRIiTW "; // %s = %s & %#" PRIxTW,
rd_name, rs1_name, i_imm, rd_name, rs1_name, i_imm);
- store_rd (cpu, rd, cpu->regs[rs1] & i_imm);
+ store_rd (cpu, rd, riscv_cpu->regs[rs1] & i_imm);
break;
case MATCH_OR:
TRACE_INSN (cpu, "or %s, %s, %s; // %s = %s | %s",
rd_name, rs1_name, rs2_name, rd_name, rs1_name, rs2_name);
- store_rd (cpu, rd, cpu->regs[rs1] | cpu->regs[rs2]);
+ store_rd (cpu, rd, riscv_cpu->regs[rs1] | riscv_cpu->regs[rs2]);
break;
case MATCH_ORI:
TRACE_INSN (cpu, "ori %s, %s, %" PRIiTW "; // %s = %s | %#" PRIxTW,
rd_name, rs1_name, i_imm, rd_name, rs1_name, i_imm);
- store_rd (cpu, rd, cpu->regs[rs1] | i_imm);
+ store_rd (cpu, rd, riscv_cpu->regs[rs1] | i_imm);
break;
case MATCH_XOR:
TRACE_INSN (cpu, "xor %s, %s, %s; // %s = %s ^ %s",
rd_name, rs1_name, rs2_name, rd_name, rs1_name, rs2_name);
- store_rd (cpu, rd, cpu->regs[rs1] ^ cpu->regs[rs2]);
+ store_rd (cpu, rd, riscv_cpu->regs[rs1] ^ riscv_cpu->regs[rs2]);
break;
case MATCH_XORI:
TRACE_INSN (cpu, "xori %s, %s, %" PRIiTW "; // %s = %s ^ %#" PRIxTW,
rd_name, rs1_name, i_imm, rd_name, rs1_name, i_imm);
- store_rd (cpu, rd, cpu->regs[rs1] ^ i_imm);
+ store_rd (cpu, rd, riscv_cpu->regs[rs1] ^ i_imm);
break;
case MATCH_SUB:
TRACE_INSN (cpu, "sub %s, %s, %s; // %s = %s - %s",
rd_name, rs1_name, rs2_name, rd_name, rs1_name, rs2_name);
- store_rd (cpu, rd, cpu->regs[rs1] - cpu->regs[rs2]);
+ store_rd (cpu, rd, riscv_cpu->regs[rs1] - riscv_cpu->regs[rs2]);
break;
case MATCH_SUBW:
TRACE_INSN (cpu, "subw %s, %s, %s; // %s = %s - %s",
rd_name, rs1_name, rs2_name, rd_name, rs1_name, rs2_name);
RISCV_ASSERT_RV64 (cpu, "insn: %s", op->name);
- store_rd (cpu, rd, EXTEND32 (cpu->regs[rs1] - cpu->regs[rs2]));
+ store_rd (cpu, rd,
+ EXTEND32 (riscv_cpu->regs[rs1] - riscv_cpu->regs[rs2]));
break;
case MATCH_LUI:
TRACE_INSN (cpu, "lui %s, %#" PRIxTW ";", rd_name, u_imm);
@@ -245,61 +256,67 @@ execute_i (SIM_CPU *cpu, unsigned_word iw, const struct riscv_opcode *op)
TRACE_INSN (cpu, "sll %s, %s, %s; // %s = %s << %s",
rd_name, rs1_name, rs2_name, rd_name, rs1_name, rs2_name);
u_imm = RISCV_XLEN (cpu) == 32 ? 0x1f : 0x3f;
- store_rd (cpu, rd, cpu->regs[rs1] << (cpu->regs[rs2] & u_imm));
+ store_rd (cpu, rd,
+ riscv_cpu->regs[rs1] << (riscv_cpu->regs[rs2] & u_imm));
break;
case MATCH_SLLW:
TRACE_INSN (cpu, "sllw %s, %s, %s; // %s = %s << %s",
rd_name, rs1_name, rs2_name, rd_name, rs1_name, rs2_name);
RISCV_ASSERT_RV64 (cpu, "insn: %s", op->name);
store_rd (cpu, rd, EXTEND32 (
- (uint32_t) cpu->regs[rs1] << (cpu->regs[rs2] & 0x1f)));
+ (uint32_t) riscv_cpu->regs[rs1] << (riscv_cpu->regs[rs2] & 0x1f)));
break;
case MATCH_SLLI:
TRACE_INSN (cpu, "slli %s, %s, %" PRIiTW "; // %s = %s << %#" PRIxTW,
rd_name, rs1_name, shamt_imm, rd_name, rs1_name, shamt_imm);
if (RISCV_XLEN (cpu) == 32 && shamt_imm > 0x1f)
- sim_engine_halt (sd, cpu, NULL, cpu->pc, sim_signalled, SIM_SIGILL);
- store_rd (cpu, rd, cpu->regs[rs1] << shamt_imm);
+ sim_engine_halt (sd, cpu, NULL, riscv_cpu->pc, sim_signalled,
+ SIM_SIGILL);
+ store_rd (cpu, rd, riscv_cpu->regs[rs1] << shamt_imm);
break;
case MATCH_SLLIW:
TRACE_INSN (cpu, "slliw %s, %s, %" PRIiTW "; // %s = %s << %#" PRIxTW,
rd_name, rs1_name, shamt_imm, rd_name, rs1_name, shamt_imm);
RISCV_ASSERT_RV64 (cpu, "insn: %s", op->name);
- store_rd (cpu, rd, EXTEND32 ((uint32_t) cpu->regs[rs1] << shamt_imm));
+ store_rd (cpu, rd,
+ EXTEND32 ((uint32_t) riscv_cpu->regs[rs1] << shamt_imm));
break;
case MATCH_SRL:
TRACE_INSN (cpu, "srl %s, %s, %s; // %s = %s >> %s",
rd_name, rs1_name, rs2_name, rd_name, rs1_name, rs2_name);
u_imm = RISCV_XLEN (cpu) == 32 ? 0x1f : 0x3f;
- store_rd (cpu, rd, cpu->regs[rs1] >> (cpu->regs[rs2] & u_imm));
+ store_rd (cpu, rd,
+ riscv_cpu->regs[rs1] >> (riscv_cpu->regs[rs2] & u_imm));
break;
case MATCH_SRLW:
TRACE_INSN (cpu, "srlw %s, %s, %s; // %s = %s >> %s",
rd_name, rs1_name, rs2_name, rd_name, rs1_name, rs2_name);
RISCV_ASSERT_RV64 (cpu, "insn: %s", op->name);
store_rd (cpu, rd, EXTEND32 (
- (uint32_t) cpu->regs[rs1] >> (cpu->regs[rs2] & 0x1f)));
+ (uint32_t) riscv_cpu->regs[rs1] >> (riscv_cpu->regs[rs2] & 0x1f)));
break;
case MATCH_SRLI:
TRACE_INSN (cpu, "srli %s, %s, %" PRIiTW "; // %s = %s >> %#" PRIxTW,
rd_name, rs1_name, shamt_imm, rd_name, rs1_name, shamt_imm);
if (RISCV_XLEN (cpu) == 32 && shamt_imm > 0x1f)
- sim_engine_halt (sd, cpu, NULL, cpu->pc, sim_signalled, SIM_SIGILL);
- store_rd (cpu, rd, cpu->regs[rs1] >> shamt_imm);
+ sim_engine_halt (sd, cpu, NULL, riscv_cpu->pc, sim_signalled,
+ SIM_SIGILL);
+ store_rd (cpu, rd, riscv_cpu->regs[rs1] >> shamt_imm);
break;
case MATCH_SRLIW:
TRACE_INSN (cpu, "srliw %s, %s, %" PRIiTW "; // %s = %s >> %#" PRIxTW,
rd_name, rs1_name, shamt_imm, rd_name, rs1_name, shamt_imm);
RISCV_ASSERT_RV64 (cpu, "insn: %s", op->name);
- store_rd (cpu, rd, EXTEND32 ((uint32_t) cpu->regs[rs1] >> shamt_imm));
+ store_rd (cpu, rd,
+ EXTEND32 ((uint32_t) riscv_cpu->regs[rs1] >> shamt_imm));
break;
case MATCH_SRA:
TRACE_INSN (cpu, "sra %s, %s, %s; // %s = %s >>> %s",
rd_name, rs1_name, rs2_name, rd_name, rs1_name, rs2_name);
if (RISCV_XLEN (cpu) == 32)
- tmp = ashiftrt (cpu->regs[rs1], cpu->regs[rs2] & 0x1f);
+ tmp = ashiftrt (riscv_cpu->regs[rs1], riscv_cpu->regs[rs2] & 0x1f);
else
- tmp = ashiftrt64 (cpu->regs[rs1], cpu->regs[rs2] & 0x3f);
+ tmp = ashiftrt64 (riscv_cpu->regs[rs1], riscv_cpu->regs[rs2] & 0x3f);
store_rd (cpu, rd, tmp);
break;
case MATCH_SRAW:
@@ -307,7 +324,8 @@ execute_i (SIM_CPU *cpu, unsigned_word iw, const struct riscv_opcode *op)
rd_name, rs1_name, rs2_name, rd_name, rs1_name, rs2_name);
RISCV_ASSERT_RV64 (cpu, "insn: %s", op->name);
store_rd (cpu, rd, EXTEND32 (
- ashiftrt ((int32_t) cpu->regs[rs1], cpu->regs[rs2] & 0x1f)));
+ ashiftrt ((int32_t) riscv_cpu->regs[rs1],
+ riscv_cpu->regs[rs2] & 0x1f)));
break;
case MATCH_SRAI:
TRACE_INSN (cpu, "srai %s, %s, %" PRIiTW "; // %s = %s >>> %#" PRIxTW,
@@ -315,11 +333,12 @@ execute_i (SIM_CPU *cpu, unsigned_word iw, const struct riscv_opcode *op)
if (RISCV_XLEN (cpu) == 32)
{
if (shamt_imm > 0x1f)
- sim_engine_halt (sd, cpu, NULL, cpu->pc, sim_signalled, SIM_SIGILL);
- tmp = ashiftrt (cpu->regs[rs1], shamt_imm);
+ sim_engine_halt (sd, cpu, NULL, riscv_cpu->pc, sim_signalled,
+ SIM_SIGILL);
+ tmp = ashiftrt (riscv_cpu->regs[rs1], shamt_imm);
}
else
- tmp = ashiftrt64 (cpu->regs[rs1], shamt_imm);
+ tmp = ashiftrt64 (riscv_cpu->regs[rs1], shamt_imm);
store_rd (cpu, rd, tmp);
break;
case MATCH_SRAIW:
@@ -327,40 +346,41 @@ execute_i (SIM_CPU *cpu, unsigned_word iw, const struct riscv_opcode *op)
rd_name, rs1_name, shamt_imm, rd_name, rs1_name, shamt_imm);
RISCV_ASSERT_RV64 (cpu, "insn: %s", op->name);
store_rd (cpu, rd, EXTEND32 (
- ashiftrt ((int32_t) cpu->regs[rs1], shamt_imm)));
+ ashiftrt ((int32_t) riscv_cpu->regs[rs1], shamt_imm)));
break;
case MATCH_SLT:
TRACE_INSN (cpu, "slt");
store_rd (cpu, rd,
- !!((signed_word) cpu->regs[rs1] < (signed_word) cpu->regs[rs2]));
+ !!((signed_word) riscv_cpu->regs[rs1] <
+ (signed_word) riscv_cpu->regs[rs2]));
break;
case MATCH_SLTU:
TRACE_INSN (cpu, "sltu");
- store_rd (cpu, rd, !!((unsigned_word) cpu->regs[rs1] <
- (unsigned_word) cpu->regs[rs2]));
+ store_rd (cpu, rd, !!((unsigned_word) riscv_cpu->regs[rs1] <
+ (unsigned_word) riscv_cpu->regs[rs2]));
break;
case MATCH_SLTI:
TRACE_INSN (cpu, "slti");
- store_rd (cpu, rd, !!((signed_word) cpu->regs[rs1] <
+ store_rd (cpu, rd, !!((signed_word) riscv_cpu->regs[rs1] <
(signed_word) i_imm));
break;
case MATCH_SLTIU:
TRACE_INSN (cpu, "sltiu");
- store_rd (cpu, rd, !!((unsigned_word) cpu->regs[rs1] <
+ store_rd (cpu, rd, !!((unsigned_word) riscv_cpu->regs[rs1] <
(unsigned_word) i_imm));
break;
case MATCH_AUIPC:
TRACE_INSN (cpu, "auipc %s, %" PRIiTW "; // %s = pc + %" PRIiTW,
rd_name, u_imm, rd_name, u_imm);
- store_rd (cpu, rd, cpu->pc + u_imm);
+ store_rd (cpu, rd, riscv_cpu->pc + u_imm);
break;
case MATCH_BEQ:
TRACE_INSN (cpu, "beq %s, %s, %#" PRIxTW "; "
"// if (%s == %s) goto %#" PRIxTW,
rs1_name, rs2_name, sb_imm, rs1_name, rs2_name, sb_imm);
- if (cpu->regs[rs1] == cpu->regs[rs2])
+ if (riscv_cpu->regs[rs1] == riscv_cpu->regs[rs2])
{
- pc = cpu->pc + sb_imm;
+ pc = riscv_cpu->pc + sb_imm;
TRACE_BRANCH (cpu, "to %#" PRIxTW, pc);
}
break;
@@ -368,9 +388,10 @@ execute_i (SIM_CPU *cpu, unsigned_word iw, const struct riscv_opcode *op)
TRACE_INSN (cpu, "blt %s, %s, %#" PRIxTW "; "
"// if (%s < %s) goto %#" PRIxTW,
rs1_name, rs2_name, sb_imm, rs1_name, rs2_name, sb_imm);
- if ((signed_word) cpu->regs[rs1] < (signed_word) cpu->regs[rs2])
+ if ((signed_word) riscv_cpu->regs[rs1] <
+ (signed_word) riscv_cpu->regs[rs2])
{
- pc = cpu->pc + sb_imm;
+ pc = riscv_cpu->pc + sb_imm;
TRACE_BRANCH (cpu, "to %#" PRIxTW, pc);
}
break;
@@ -378,9 +399,10 @@ execute_i (SIM_CPU *cpu, unsigned_word iw, const struct riscv_opcode *op)
TRACE_INSN (cpu, "bltu %s, %s, %#" PRIxTW "; "
"// if (%s < %s) goto %#" PRIxTW,
rs1_name, rs2_name, sb_imm, rs1_name, rs2_name, sb_imm);
- if ((unsigned_word) cpu->regs[rs1] < (unsigned_word) cpu->regs[rs2])
+ if ((unsigned_word) riscv_cpu->regs[rs1] <
+ (unsigned_word) riscv_cpu->regs[rs2])
{
- pc = cpu->pc + sb_imm;
+ pc = riscv_cpu->pc + sb_imm;
TRACE_BRANCH (cpu, "to %#" PRIxTW, pc);
}
break;
@@ -388,9 +410,10 @@ execute_i (SIM_CPU *cpu, unsigned_word iw, const struct riscv_opcode *op)
TRACE_INSN (cpu, "bge %s, %s, %#" PRIxTW "; "
"// if (%s >= %s) goto %#" PRIxTW,
rs1_name, rs2_name, sb_imm, rs1_name, rs2_name, sb_imm);
- if ((signed_word) cpu->regs[rs1] >= (signed_word) cpu->regs[rs2])
+ if ((signed_word) riscv_cpu->regs[rs1] >=
+ (signed_word) riscv_cpu->regs[rs2])
{
- pc = cpu->pc + sb_imm;
+ pc = riscv_cpu->pc + sb_imm;
TRACE_BRANCH (cpu, "to %#" PRIxTW, pc);
}
break;
@@ -398,9 +421,10 @@ execute_i (SIM_CPU *cpu, unsigned_word iw, const struct riscv_opcode *op)
TRACE_INSN (cpu, "bgeu %s, %s, %#" PRIxTW "; "
"// if (%s >= %s) goto %#" PRIxTW,
rs1_name, rs2_name, sb_imm, rs1_name, rs2_name, sb_imm);
- if ((unsigned_word) cpu->regs[rs1] >= (unsigned_word) cpu->regs[rs2])
+ if ((unsigned_word) riscv_cpu->regs[rs1] >=
+ (unsigned_word) riscv_cpu->regs[rs2])
{
- pc = cpu->pc + sb_imm;
+ pc = riscv_cpu->pc + sb_imm;
TRACE_BRANCH (cpu, "to %#" PRIxTW, pc);
}
break;
@@ -408,23 +432,23 @@ execute_i (SIM_CPU *cpu, unsigned_word iw, const struct riscv_opcode *op)
TRACE_INSN (cpu, "bne %s, %s, %#" PRIxTW "; "
"// if (%s != %s) goto %#" PRIxTW,
rs1_name, rs2_name, sb_imm, rs1_name, rs2_name, sb_imm);
- if (cpu->regs[rs1] != cpu->regs[rs2])
+ if (riscv_cpu->regs[rs1] != riscv_cpu->regs[rs2])
{
- pc = cpu->pc + sb_imm;
+ pc = riscv_cpu->pc + sb_imm;
TRACE_BRANCH (cpu, "to %#" PRIxTW, pc);
}
break;
case MATCH_JAL:
TRACE_INSN (cpu, "jal %s, %" PRIiTW ";", rd_name,
EXTRACT_JTYPE_IMM (iw));
- store_rd (cpu, rd, cpu->pc + 4);
- pc = cpu->pc + EXTRACT_JTYPE_IMM (iw);
+ store_rd (cpu, rd, riscv_cpu->pc + 4);
+ pc = riscv_cpu->pc + EXTRACT_JTYPE_IMM (iw);
TRACE_BRANCH (cpu, "to %#" PRIxTW, pc);
break;
case MATCH_JALR:
TRACE_INSN (cpu, "jalr %s, %s, %" PRIiTW ";", rd_name, rs1_name, i_imm);
- store_rd (cpu, rd, cpu->pc + 4);
- pc = cpu->regs[rs1] + i_imm;
+ store_rd (cpu, rd, riscv_cpu->pc + 4);
+ pc = riscv_cpu->regs[rs1] + i_imm;
TRACE_BRANCH (cpu, "to %#" PRIxTW, pc);
break;
@@ -433,75 +457,79 @@ execute_i (SIM_CPU *cpu, unsigned_word iw, const struct riscv_opcode *op)
rd_name, i_imm, rs1_name);
RISCV_ASSERT_RV64 (cpu, "insn: %s", op->name);
store_rd (cpu, rd,
- sim_core_read_unaligned_8 (cpu, cpu->pc, read_map,
- cpu->regs[rs1] + i_imm));
+ sim_core_read_unaligned_8 (cpu, riscv_cpu->pc, read_map,
+ riscv_cpu->regs[rs1] + i_imm));
break;
case MATCH_LW:
TRACE_INSN (cpu, "lw %s, %" PRIiTW "(%s);",
rd_name, i_imm, rs1_name);
store_rd (cpu, rd, EXTEND32 (
- sim_core_read_unaligned_4 (cpu, cpu->pc, read_map,
- cpu->regs[rs1] + i_imm)));
+ sim_core_read_unaligned_4 (cpu, riscv_cpu->pc, read_map,
+ riscv_cpu->regs[rs1] + i_imm)));
break;
case MATCH_LWU:
TRACE_INSN (cpu, "lwu %s, %" PRIiTW "(%s);",
rd_name, i_imm, rs1_name);
store_rd (cpu, rd,
- sim_core_read_unaligned_4 (cpu, cpu->pc, read_map,
- cpu->regs[rs1] + i_imm));
+ sim_core_read_unaligned_4 (cpu, riscv_cpu->pc, read_map,
+ riscv_cpu->regs[rs1] + i_imm));
break;
case MATCH_LH:
TRACE_INSN (cpu, "lh %s, %" PRIiTW "(%s);",
rd_name, i_imm, rs1_name);
store_rd (cpu, rd, EXTEND16 (
- sim_core_read_unaligned_2 (cpu, cpu->pc, read_map,
- cpu->regs[rs1] + i_imm)));
+ sim_core_read_unaligned_2 (cpu, riscv_cpu->pc, read_map,
+ riscv_cpu->regs[rs1] + i_imm)));
break;
case MATCH_LHU:
TRACE_INSN (cpu, "lbu %s, %" PRIiTW "(%s);",
rd_name, i_imm, rs1_name);
store_rd (cpu, rd,
- sim_core_read_unaligned_2 (cpu, cpu->pc, read_map,
- cpu->regs[rs1] + i_imm));
+ sim_core_read_unaligned_2 (cpu, riscv_cpu->pc, read_map,
+ riscv_cpu->regs[rs1] + i_imm));
break;
case MATCH_LB:
TRACE_INSN (cpu, "lb %s, %" PRIiTW "(%s);",
rd_name, i_imm, rs1_name);
store_rd (cpu, rd, EXTEND8 (
- sim_core_read_unaligned_1 (cpu, cpu->pc, read_map,
- cpu->regs[rs1] + i_imm)));
+ sim_core_read_unaligned_1 (cpu, riscv_cpu->pc, read_map,
+ riscv_cpu->regs[rs1] + i_imm)));
break;
case MATCH_LBU:
TRACE_INSN (cpu, "lbu %s, %" PRIiTW "(%s);",
rd_name, i_imm, rs1_name);
store_rd (cpu, rd,
- sim_core_read_unaligned_1 (cpu, cpu->pc, read_map,
- cpu->regs[rs1] + i_imm));
+ sim_core_read_unaligned_1 (cpu, riscv_cpu->pc, read_map,
+ riscv_cpu->regs[rs1] + i_imm));
break;
case MATCH_SD:
TRACE_INSN (cpu, "sd %s, %" PRIiTW "(%s);",
rs2_name, s_imm, rs1_name);
RISCV_ASSERT_RV64 (cpu, "insn: %s", op->name);
- sim_core_write_unaligned_8 (cpu, cpu->pc, write_map,
- cpu->regs[rs1] + s_imm, cpu->regs[rs2]);
+ sim_core_write_unaligned_8 (cpu, riscv_cpu->pc, write_map,
+ riscv_cpu->regs[rs1] + s_imm,
+ riscv_cpu->regs[rs2]);
break;
case MATCH_SW:
TRACE_INSN (cpu, "sw %s, %" PRIiTW "(%s);",
rs2_name, s_imm, rs1_name);
- sim_core_write_unaligned_4 (cpu, cpu->pc, write_map,
- cpu->regs[rs1] + s_imm, cpu->regs[rs2]);
+ sim_core_write_unaligned_4 (cpu, riscv_cpu->pc, write_map,
+ riscv_cpu->regs[rs1] + s_imm,
+ riscv_cpu->regs[rs2]);
break;
case MATCH_SH:
TRACE_INSN (cpu, "sh %s, %" PRIiTW "(%s);",
rs2_name, s_imm, rs1_name);
- sim_core_write_unaligned_2 (cpu, cpu->pc, write_map,
- cpu->regs[rs1] + s_imm, cpu->regs[rs2]);
+ sim_core_write_unaligned_2 (cpu, riscv_cpu->pc, write_map,
+ riscv_cpu->regs[rs1] + s_imm,
+ riscv_cpu->regs[rs2]);
break;
case MATCH_SB:
TRACE_INSN (cpu, "sb %s, %" PRIiTW "(%s);",
rs2_name, s_imm, rs1_name);
- sim_core_write_unaligned_1 (cpu, cpu->pc, write_map,
- cpu->regs[rs1] + s_imm, cpu->regs[rs2]);
+ sim_core_write_unaligned_1 (cpu, riscv_cpu->pc, write_map,
+ riscv_cpu->regs[rs1] + s_imm,
+ riscv_cpu->regs[rs2]);
break;
case MATCH_CSRRC:
@@ -510,9 +538,10 @@ execute_i (SIM_CPU *cpu, unsigned_word iw, const struct riscv_opcode *op)
{
#define DECLARE_CSR(name, num, ...) \
case num: \
- store_rd (cpu, rd, fetch_csr (cpu, #name, num, &cpu->csr.name)); \
- store_csr (cpu, #name, num, &cpu->csr.name, \
- cpu->csr.name & !cpu->regs[rs1]); \
+ store_rd (cpu, rd, \
+ fetch_csr (cpu, #name, num, &riscv_cpu->csr.name)); \
+ store_csr (cpu, #name, num, &riscv_cpu->csr.name, \
+ riscv_cpu->csr.name & !riscv_cpu->regs[rs1]); \
break;
#include "opcode/riscv-opc.h"
#undef DECLARE_CSR
@@ -524,9 +553,10 @@ execute_i (SIM_CPU *cpu, unsigned_word iw, const struct riscv_opcode *op)
{
#define DECLARE_CSR(name, num, ...) \
case num: \
- store_rd (cpu, rd, fetch_csr (cpu, #name, num, &cpu->csr.name)); \
- store_csr (cpu, #name, num, &cpu->csr.name, \
- cpu->csr.name | cpu->regs[rs1]); \
+ store_rd (cpu, rd, \
+ fetch_csr (cpu, #name, num, &riscv_cpu->csr.name)); \
+ store_csr (cpu, #name, num, &riscv_cpu->csr.name, \
+ riscv_cpu->csr.name | riscv_cpu->regs[rs1]); \
break;
#include "opcode/riscv-opc.h"
#undef DECLARE_CSR
@@ -538,8 +568,10 @@ execute_i (SIM_CPU *cpu, unsigned_word iw, const struct riscv_opcode *op)
{
#define DECLARE_CSR(name, num, ...) \
case num: \
- store_rd (cpu, rd, fetch_csr (cpu, #name, num, &cpu->csr.name)); \
- store_csr (cpu, #name, num, &cpu->csr.name, cpu->regs[rs1]); \
+ store_rd (cpu, rd, \
+ fetch_csr (cpu, #name, num, &riscv_cpu->csr.name)); \
+ store_csr (cpu, #name, num, &riscv_cpu->csr.name, \
+ riscv_cpu->regs[rs1]); \
break;
#include "opcode/riscv-opc.h"
#undef DECLARE_CSR
@@ -548,33 +580,38 @@ execute_i (SIM_CPU *cpu, unsigned_word iw, const struct riscv_opcode *op)
case MATCH_RDCYCLE:
TRACE_INSN (cpu, "rdcycle %s;", rd_name);
- store_rd (cpu, rd, fetch_csr (cpu, "cycle", CSR_CYCLE, &cpu->csr.cycle));
+ store_rd (cpu, rd,
+ fetch_csr (cpu, "cycle", CSR_CYCLE, &riscv_cpu->csr.cycle));
break;
case MATCH_RDCYCLEH:
TRACE_INSN (cpu, "rdcycleh %s;", rd_name);
RISCV_ASSERT_RV32 (cpu, "insn: %s", op->name);
store_rd (cpu, rd,
- fetch_csr (cpu, "cycleh", CSR_CYCLEH, &cpu->csr.cycleh));
+ fetch_csr (cpu, "cycleh", CSR_CYCLEH, &riscv_cpu->csr.cycleh));
break;
case MATCH_RDINSTRET:
TRACE_INSN (cpu, "rdinstret %s;", rd_name);
store_rd (cpu, rd,
- fetch_csr (cpu, "instret", CSR_INSTRET, &cpu->csr.instret));
+ fetch_csr (cpu, "instret", CSR_INSTRET,
+ &riscv_cpu->csr.instret));
break;
case MATCH_RDINSTRETH:
TRACE_INSN (cpu, "rdinstreth %s;", rd_name);
RISCV_ASSERT_RV32 (cpu, "insn: %s", op->name);
store_rd (cpu, rd,
- fetch_csr (cpu, "instreth", CSR_INSTRETH, &cpu->csr.instreth));
+ fetch_csr (cpu, "instreth", CSR_INSTRETH,
+ &riscv_cpu->csr.instreth));
break;
case MATCH_RDTIME:
TRACE_INSN (cpu, "rdtime %s;", rd_name);
- store_rd (cpu, rd, fetch_csr (cpu, "time", CSR_TIME, &cpu->csr.time));
+ store_rd (cpu, rd,
+ fetch_csr (cpu, "time", CSR_TIME, &riscv_cpu->csr.time));
break;
case MATCH_RDTIMEH:
TRACE_INSN (cpu, "rdtimeh %s;", rd_name);
RISCV_ASSERT_RV32 (cpu, "insn: %s", op->name);
- store_rd (cpu, rd, fetch_csr (cpu, "timeh", CSR_TIMEH, &cpu->csr.timeh));
+ store_rd (cpu, rd,
+ fetch_csr (cpu, "timeh", CSR_TIMEH, &riscv_cpu->csr.timeh));
break;
case MATCH_FENCE:
@@ -586,15 +623,17 @@ execute_i (SIM_CPU *cpu, unsigned_word iw, const struct riscv_opcode *op)
case MATCH_EBREAK:
TRACE_INSN (cpu, "ebreak;");
/* GDB expects us to step over EBREAK. */
- sim_engine_halt (sd, cpu, NULL, cpu->pc + 4, sim_stopped, SIM_SIGTRAP);
+ sim_engine_halt (sd, cpu, NULL, riscv_cpu->pc + 4, sim_stopped,
+ SIM_SIGTRAP);
break;
case MATCH_ECALL:
TRACE_INSN (cpu, "ecall;");
- cpu->a0 = sim_syscall (cpu, cpu->a7, cpu->a0, cpu->a1, cpu->a2, cpu->a3);
+ riscv_cpu->a0 = sim_syscall (cpu, riscv_cpu->a7, riscv_cpu->a0,
+ riscv_cpu->a1, riscv_cpu->a2, riscv_cpu->a3);
break;
default:
TRACE_INSN (cpu, "UNHANDLED INSN: %s", op->name);
- sim_engine_halt (sd, cpu, NULL, cpu->pc, sim_signalled, SIM_SIGILL);
+ sim_engine_halt (sd, cpu, NULL, riscv_cpu->pc, sim_signalled, SIM_SIGILL);
}
return pc;
@@ -645,6 +684,7 @@ mulhsu (int64_t a, uint64_t b)
static sim_cia
execute_m (SIM_CPU *cpu, unsigned_word iw, const struct riscv_opcode *op)
{
+ struct riscv_sim_cpu *riscv_cpu = RISCV_SIM_CPU (cpu);
SIM_DESC sd = CPU_STATE (cpu);
int rd = (iw >> OP_SH_RD) & OP_MASK_RD;
int rs1 = (iw >> OP_SH_RS1) & OP_MASK_RS1;
@@ -653,7 +693,7 @@ execute_m (SIM_CPU *cpu, unsigned_word iw, const struct riscv_opcode *op)
const char *rs1_name = riscv_gpr_names_abi[rs1];
const char *rs2_name = riscv_gpr_names_abi[rs2];
unsigned_word tmp, dividend_max;
- sim_cia pc = cpu->pc + 4;
+ sim_cia pc = riscv_cpu->pc + 4;
dividend_max = -((unsigned_word) 1 << (WITH_TARGET_WORD_BITSIZE - 1));
@@ -662,10 +702,11 @@ execute_m (SIM_CPU *cpu, unsigned_word iw, const struct riscv_opcode *op)
case MATCH_DIV:
TRACE_INSN (cpu, "div %s, %s, %s; // %s = %s / %s",
rd_name, rs1_name, rs2_name, rd_name, rs1_name, rs2_name);
- if (cpu->regs[rs1] == dividend_max && cpu->regs[rs2] == -1)
+ if (riscv_cpu->regs[rs1] == dividend_max && riscv_cpu->regs[rs2] == -1)
tmp = dividend_max;
- else if (cpu->regs[rs2])
- tmp = (signed_word) cpu->regs[rs1] / (signed_word) cpu->regs[rs2];
+ else if (riscv_cpu->regs[rs2])
+ tmp = (signed_word) riscv_cpu->regs[rs1] /
+ (signed_word) riscv_cpu->regs[rs2];
else
tmp = -1;
store_rd (cpu, rd, tmp);
@@ -674,10 +715,10 @@ execute_m (SIM_CPU *cpu, unsigned_word iw, const struct riscv_opcode *op)
TRACE_INSN (cpu, "divw %s, %s, %s; // %s = %s / %s",
rd_name, rs1_name, rs2_name, rd_name, rs1_name, rs2_name);
RISCV_ASSERT_RV64 (cpu, "insn: %s", op->name);
- if (EXTEND32 (cpu->regs[rs2]) == -1)
+ if (EXTEND32 (riscv_cpu->regs[rs2]) == -1)
tmp = 1 << 31;
- else if (EXTEND32 (cpu->regs[rs2]))
- tmp = EXTEND32 (cpu->regs[rs1]) / EXTEND32 (cpu->regs[rs2]);
+ else if (EXTEND32 (riscv_cpu->regs[rs2]))
+ tmp = EXTEND32 (riscv_cpu->regs[rs1]) / EXTEND32 (riscv_cpu->regs[rs2]);
else
tmp = -1;
store_rd (cpu, rd, EXTEND32 (tmp));
@@ -685,9 +726,9 @@ execute_m (SIM_CPU *cpu, unsigned_word iw, const struct riscv_opcode *op)
case MATCH_DIVU:
TRACE_INSN (cpu, "divu %s, %s, %s; // %s = %s / %s",
rd_name, rs1_name, rs2_name, rd_name, rs1_name, rs2_name);
- if (cpu->regs[rs2])
- store_rd (cpu, rd, (unsigned_word) cpu->regs[rs1]
- / (unsigned_word) cpu->regs[rs2]);
+ if (riscv_cpu->regs[rs2])
+ store_rd (cpu, rd, (unsigned_word) riscv_cpu->regs[rs1]
+ / (unsigned_word) riscv_cpu->regs[rs2]);
else
store_rd (cpu, rd, -1);
break;
@@ -695,8 +736,8 @@ execute_m (SIM_CPU *cpu, unsigned_word iw, const struct riscv_opcode *op)
TRACE_INSN (cpu, "divuw %s, %s, %s; // %s = %s / %s",
rd_name, rs1_name, rs2_name, rd_name, rs1_name, rs2_name);
RISCV_ASSERT_RV64 (cpu, "insn: %s", op->name);
- if ((uint32_t) cpu->regs[rs2])
- tmp = (uint32_t) cpu->regs[rs1] / (uint32_t) cpu->regs[rs2];
+ if ((uint32_t) riscv_cpu->regs[rs2])
+ tmp = (uint32_t) riscv_cpu->regs[rs1] / (uint32_t) riscv_cpu->regs[rs2];
else
tmp = -1;
store_rd (cpu, rd, EXTEND32 (tmp));
@@ -704,86 +745,88 @@ execute_m (SIM_CPU *cpu, unsigned_word iw, const struct riscv_opcode *op)
case MATCH_MUL:
TRACE_INSN (cpu, "mul %s, %s, %s; // %s = %s * %s",
rd_name, rs1_name, rs2_name, rd_name, rs1_name, rs2_name);
- store_rd (cpu, rd, cpu->regs[rs1] * cpu->regs[rs2]);
+ store_rd (cpu, rd, riscv_cpu->regs[rs1] * riscv_cpu->regs[rs2]);
break;
case MATCH_MULW:
TRACE_INSN (cpu, "mulw %s, %s, %s; // %s = %s * %s",
rd_name, rs1_name, rs2_name, rd_name, rs1_name, rs2_name);
RISCV_ASSERT_RV64 (cpu, "insn: %s", op->name);
- store_rd (cpu, rd, EXTEND32 ((int32_t) cpu->regs[rs1]
- * (int32_t) cpu->regs[rs2]));
+ store_rd (cpu, rd, EXTEND32 ((int32_t) riscv_cpu->regs[rs1]
+ * (int32_t) riscv_cpu->regs[rs2]));
break;
case MATCH_MULH:
TRACE_INSN (cpu, "mulh %s, %s, %s; // %s = %s * %s",
rd_name, rs1_name, rs2_name, rd_name, rs1_name, rs2_name);
if (RISCV_XLEN (cpu) == 32)
- store_rd (cpu, rd, ((int64_t)(signed_word) cpu->regs[rs1]
- * (int64_t)(signed_word) cpu->regs[rs2]) >> 32);
+ store_rd (cpu, rd,
+ ((int64_t)(signed_word) riscv_cpu->regs[rs1]
+ * (int64_t)(signed_word) riscv_cpu->regs[rs2]) >> 32);
else
- store_rd (cpu, rd, mulh (cpu->regs[rs1], cpu->regs[rs2]));
+ store_rd (cpu, rd, mulh (riscv_cpu->regs[rs1], riscv_cpu->regs[rs2]));
break;
case MATCH_MULHU:
TRACE_INSN (cpu, "mulhu %s, %s, %s; // %s = %s * %s",
rd_name, rs1_name, rs2_name, rd_name, rs1_name, rs2_name);
if (RISCV_XLEN (cpu) == 32)
- store_rd (cpu, rd, ((uint64_t)cpu->regs[rs1]
- * (uint64_t)cpu->regs[rs2]) >> 32);
+ store_rd (cpu, rd, ((uint64_t)riscv_cpu->regs[rs1]
+ * (uint64_t)riscv_cpu->regs[rs2]) >> 32);
else
- store_rd (cpu, rd, mulhu (cpu->regs[rs1], cpu->regs[rs2]));
+ store_rd (cpu, rd, mulhu (riscv_cpu->regs[rs1], riscv_cpu->regs[rs2]));
break;
case MATCH_MULHSU:
TRACE_INSN (cpu, "mulhsu %s, %s, %s; // %s = %s * %s",
rd_name, rs1_name, rs2_name, rd_name, rs1_name, rs2_name);
if (RISCV_XLEN (cpu) == 32)
- store_rd (cpu, rd, ((int64_t)(signed_word) cpu->regs[rs1]
- * (uint64_t)cpu->regs[rs2]) >> 32);
+ store_rd (cpu, rd, ((int64_t)(signed_word) riscv_cpu->regs[rs1]
+ * (uint64_t)riscv_cpu->regs[rs2]) >> 32);
else
- store_rd (cpu, rd, mulhsu (cpu->regs[rs1], cpu->regs[rs2]));
+ store_rd (cpu, rd, mulhsu (riscv_cpu->regs[rs1], riscv_cpu->regs[rs2]));
break;
case MATCH_REM:
TRACE_INSN (cpu, "rem %s, %s, %s; // %s = %s %% %s",
rd_name, rs1_name, rs2_name, rd_name, rs1_name, rs2_name);
- if (cpu->regs[rs1] == dividend_max && cpu->regs[rs2] == -1)
+ if (riscv_cpu->regs[rs1] == dividend_max && riscv_cpu->regs[rs2] == -1)
tmp = 0;
- else if (cpu->regs[rs2])
- tmp = (signed_word) cpu->regs[rs1] % (signed_word) cpu->regs[rs2];
+ else if (riscv_cpu->regs[rs2])
+ tmp = (signed_word) riscv_cpu->regs[rs1]
+ % (signed_word) riscv_cpu->regs[rs2];
else
- tmp = cpu->regs[rs1];
+ tmp = riscv_cpu->regs[rs1];
store_rd (cpu, rd, tmp);
break;
case MATCH_REMW:
TRACE_INSN (cpu, "remw %s, %s, %s; // %s = %s %% %s",
rd_name, rs1_name, rs2_name, rd_name, rs1_name, rs2_name);
RISCV_ASSERT_RV64 (cpu, "insn: %s", op->name);
- if (EXTEND32 (cpu->regs[rs2]) == -1)
+ if (EXTEND32 (riscv_cpu->regs[rs2]) == -1)
tmp = 0;
- else if (EXTEND32 (cpu->regs[rs2]))
- tmp = EXTEND32 (cpu->regs[rs1]) % EXTEND32 (cpu->regs[rs2]);
+ else if (EXTEND32 (riscv_cpu->regs[rs2]))
+ tmp = EXTEND32 (riscv_cpu->regs[rs1]) % EXTEND32 (riscv_cpu->regs[rs2]);
else
- tmp = cpu->regs[rs1];
+ tmp = riscv_cpu->regs[rs1];
store_rd (cpu, rd, EXTEND32 (tmp));
break;
case MATCH_REMU:
TRACE_INSN (cpu, "remu %s, %s, %s; // %s = %s %% %s",
rd_name, rs1_name, rs2_name, rd_name, rs1_name, rs2_name);
- if (cpu->regs[rs2])
- store_rd (cpu, rd, cpu->regs[rs1] % cpu->regs[rs2]);
+ if (riscv_cpu->regs[rs2])
+ store_rd (cpu, rd, riscv_cpu->regs[rs1] % riscv_cpu->regs[rs2]);
else
- store_rd (cpu, rd, cpu->regs[rs1]);
+ store_rd (cpu, rd, riscv_cpu->regs[rs1]);
break;
case MATCH_REMUW:
TRACE_INSN (cpu, "remuw %s, %s, %s; // %s = %s %% %s",
rd_name, rs1_name, rs2_name, rd_name, rs1_name, rs2_name);
RISCV_ASSERT_RV64 (cpu, "insn: %s", op->name);
- if ((uint32_t) cpu->regs[rs2])
- tmp = (uint32_t) cpu->regs[rs1] % (uint32_t) cpu->regs[rs2];
+ if ((uint32_t) riscv_cpu->regs[rs2])
+ tmp = (uint32_t) riscv_cpu->regs[rs1] % (uint32_t) riscv_cpu->regs[rs2];
else
- tmp = cpu->regs[rs1];
+ tmp = riscv_cpu->regs[rs1];
store_rd (cpu, rd, EXTEND32 (tmp));
break;
default:
TRACE_INSN (cpu, "UNHANDLED INSN: %s", op->name);
- sim_engine_halt (sd, cpu, NULL, cpu->pc, sim_signalled, SIM_SIGILL);
+ sim_engine_halt (sd, cpu, NULL, riscv_cpu->pc, sim_signalled, SIM_SIGILL);
}
return pc;
@@ -792,6 +835,7 @@ execute_m (SIM_CPU *cpu, unsigned_word iw, const struct riscv_opcode *op)
static sim_cia
execute_a (SIM_CPU *cpu, unsigned_word iw, const struct riscv_opcode *op)
{
+ struct riscv_sim_cpu *riscv_cpu = RISCV_SIM_CPU (cpu);
SIM_DESC sd = CPU_STATE (cpu);
struct riscv_sim_state *state = RISCV_SIM_STATE (sd);
int rd = (iw >> OP_SH_RD) & OP_MASK_RD;
@@ -802,7 +846,7 @@ execute_a (SIM_CPU *cpu, unsigned_word iw, const struct riscv_opcode *op)
const char *rs2_name = riscv_gpr_names_abi[rs2];
struct atomic_mem_reserved_list *amo_prev, *amo_curr;
unsigned_word tmp;
- sim_cia pc = cpu->pc + 4;
+ sim_cia pc = riscv_cpu->pc + 4;
/* Handle these two load/store operations specifically. */
switch (op->match)
@@ -810,20 +854,21 @@ execute_a (SIM_CPU *cpu, unsigned_word iw, const struct riscv_opcode *op)
case MATCH_LR_W:
TRACE_INSN (cpu, "%s %s, (%s);", op->name, rd_name, rs1_name);
store_rd (cpu, rd,
- sim_core_read_unaligned_4 (cpu, cpu->pc, read_map, cpu->regs[rs1]));
+ sim_core_read_unaligned_4 (cpu, riscv_cpu->pc, read_map,
+ riscv_cpu->regs[rs1]));
/* Walk the reservation list to find an existing match. */
amo_curr = state->amo_reserved_list;
while (amo_curr)
{
- if (amo_curr->addr == cpu->regs[rs1])
+ if (amo_curr->addr == riscv_cpu->regs[rs1])
goto done;
amo_curr = amo_curr->next;
}
/* No reservation exists, so add one. */
amo_curr = xmalloc (sizeof (*amo_curr));
- amo_curr->addr = cpu->regs[rs1];
+ amo_curr->addr = riscv_cpu->regs[rs1];
amo_curr->next = state->amo_reserved_list;
state->amo_reserved_list = amo_curr;
goto done;
@@ -835,11 +880,12 @@ execute_a (SIM_CPU *cpu, unsigned_word iw, const struct riscv_opcode *op)
amo_curr = amo_prev = state->amo_reserved_list;
while (amo_curr)
{
- if (amo_curr->addr == cpu->regs[rs1])
+ if (amo_curr->addr == riscv_cpu->regs[rs1])
{
/* We found a reservation, so operate it. */
- sim_core_write_unaligned_4 (cpu, cpu->pc, write_map,
- cpu->regs[rs1], cpu->regs[rs2]);
+ sim_core_write_unaligned_4 (cpu, riscv_cpu->pc, write_map,
+ riscv_cpu->regs[rs1],
+ riscv_cpu->regs[rs2]);
store_rd (cpu, rd, 0);
if (amo_curr == state->amo_reserved_list)
state->amo_reserved_list = amo_curr->next;
@@ -861,59 +907,66 @@ execute_a (SIM_CPU *cpu, unsigned_word iw, const struct riscv_opcode *op)
TRACE_INSN (cpu, "%s %s, %s, (%s);",
op->name, rd_name, rs2_name, rs1_name);
if (op->xlen_requirement == 64)
- tmp = sim_core_read_unaligned_8 (cpu, cpu->pc, read_map, cpu->regs[rs1]);
+ tmp = sim_core_read_unaligned_8 (cpu, riscv_cpu->pc, read_map,
+ riscv_cpu->regs[rs1]);
else
- tmp = EXTEND32 (sim_core_read_unaligned_4 (cpu, cpu->pc, read_map,
- cpu->regs[rs1]));
+ tmp = EXTEND32 (sim_core_read_unaligned_4 (cpu, riscv_cpu->pc, read_map,
+ riscv_cpu->regs[rs1]));
store_rd (cpu, rd, tmp);
switch (op->match)
{
case MATCH_AMOADD_D:
case MATCH_AMOADD_W:
- tmp = cpu->regs[rd] + cpu->regs[rs2];
+ tmp = riscv_cpu->regs[rd] + riscv_cpu->regs[rs2];
break;
case MATCH_AMOAND_D:
case MATCH_AMOAND_W:
- tmp = cpu->regs[rd] & cpu->regs[rs2];
+ tmp = riscv_cpu->regs[rd] & riscv_cpu->regs[rs2];
break;
case MATCH_AMOMAX_D:
case MATCH_AMOMAX_W:
- tmp = max ((signed_word) cpu->regs[rd], (signed_word) cpu->regs[rs2]);
+ tmp = max ((signed_word) riscv_cpu->regs[rd],
+ (signed_word) riscv_cpu->regs[rs2]);
break;
case MATCH_AMOMAXU_D:
case MATCH_AMOMAXU_W:
- tmp = max ((unsigned_word) cpu->regs[rd], (unsigned_word) cpu->regs[rs2]);
+ tmp = max ((unsigned_word) riscv_cpu->regs[rd],
+ (unsigned_word) riscv_cpu->regs[rs2]);
break;
case MATCH_AMOMIN_D:
case MATCH_AMOMIN_W:
- tmp = min ((signed_word) cpu->regs[rd], (signed_word) cpu->regs[rs2]);
+ tmp = min ((signed_word) riscv_cpu->regs[rd],
+ (signed_word) riscv_cpu->regs[rs2]);
break;
case MATCH_AMOMINU_D:
case MATCH_AMOMINU_W:
- tmp = min ((unsigned_word) cpu->regs[rd], (unsigned_word) cpu->regs[rs2]);
+ tmp = min ((unsigned_word) riscv_cpu->regs[rd],
+ (unsigned_word) riscv_cpu->regs[rs2]);
break;
case MATCH_AMOOR_D:
case MATCH_AMOOR_W:
- tmp = cpu->regs[rd] | cpu->regs[rs2];
+ tmp = riscv_cpu->regs[rd] | riscv_cpu->regs[rs2];
break;
case MATCH_AMOSWAP_D:
case MATCH_AMOSWAP_W:
- tmp = cpu->regs[rs2];
+ tmp = riscv_cpu->regs[rs2];
break;
case MATCH_AMOXOR_D:
case MATCH_AMOXOR_W:
- tmp = cpu->regs[rd] ^ cpu->regs[rs2];
+ tmp = riscv_cpu->regs[rd] ^ riscv_cpu->regs[rs2];
break;
default:
TRACE_INSN (cpu, "UNHANDLED INSN: %s", op->name);
- sim_engine_halt (sd, cpu, NULL, cpu->pc, sim_signalled, SIM_SIGILL);
+ sim_engine_halt (sd, cpu, NULL, riscv_cpu->pc, sim_signalled, SIM_SIGILL);
}
if (op->xlen_requirement == 64)
- sim_core_write_unaligned_8 (cpu, cpu->pc, write_map, cpu->regs[rs1], tmp);
+ sim_core_write_unaligned_8 (cpu, riscv_cpu->pc, write_map,
+ riscv_cpu->regs[rs1], tmp);
else
- sim_core_write_unaligned_4 (cpu, cpu->pc, write_map, cpu->regs[rs1], tmp);
+ sim_core_write_unaligned_4 (cpu, riscv_cpu->pc, write_map,
+ riscv_cpu->regs[rs1], tmp);
done:
return pc;
@@ -922,6 +975,7 @@ execute_a (SIM_CPU *cpu, unsigned_word iw, const struct riscv_opcode *op)
static sim_cia
execute_one (SIM_CPU *cpu, unsigned_word iw, const struct riscv_opcode *op)
{
+ struct riscv_sim_cpu *riscv_cpu = RISCV_SIM_CPU (cpu);
SIM_DESC sd = CPU_STATE (cpu);
if (op->xlen_requirement == 32)
@@ -940,19 +994,20 @@ execute_one (SIM_CPU *cpu, unsigned_word iw, const struct riscv_opcode *op)
return execute_m (cpu, iw, op);
default:
TRACE_INSN (cpu, "UNHANDLED EXTENSION: %d", op->insn_class);
- sim_engine_halt (sd, cpu, NULL, cpu->pc, sim_signalled, SIM_SIGILL);
+ sim_engine_halt (sd, cpu, NULL, riscv_cpu->pc, sim_signalled, SIM_SIGILL);
}
- return cpu->pc + riscv_insn_length (iw);
+ return riscv_cpu->pc + riscv_insn_length (iw);
}
/* Decode & execute a single instruction. */
void step_once (SIM_CPU *cpu)
{
+ struct riscv_sim_cpu *riscv_cpu = RISCV_SIM_CPU (cpu);
SIM_DESC sd = CPU_STATE (cpu);
unsigned_word iw;
unsigned int len;
- sim_cia pc = cpu->pc;
+ sim_cia pc = riscv_cpu->pc;
const struct riscv_opcode *op;
int xlen = RISCV_XLEN (cpu);
@@ -1000,29 +1055,35 @@ void step_once (SIM_CPU *cpu)
/* TODO: Handle overflow into high 32 bits. */
/* TODO: Try to use a common counter and only update on demand (reads). */
- ++cpu->csr.cycle;
- ++cpu->csr.instret;
+ ++riscv_cpu->csr.cycle;
+ ++riscv_cpu->csr.instret;
- cpu->pc = pc;
+ riscv_cpu->pc = pc;
}
/* Return the program counter for this cpu. */
static sim_cia
pc_get (sim_cpu *cpu)
{
- return cpu->pc;
+ struct riscv_sim_cpu *riscv_cpu = RISCV_SIM_CPU (cpu);
+
+ return riscv_cpu->pc;
}
/* Set the program counter for this cpu to the new pc value. */
static void
pc_set (sim_cpu *cpu, sim_cia pc)
{
- cpu->pc = pc;
+ struct riscv_sim_cpu *riscv_cpu = RISCV_SIM_CPU (cpu);
+
+ riscv_cpu->pc = pc;
}
static int
reg_fetch (sim_cpu *cpu, int rn, void *buf, int len)
{
+ struct riscv_sim_cpu *riscv_cpu = RISCV_SIM_CPU (cpu);
+
if (len <= 0 || len > sizeof (unsigned_word))
return -1;
@@ -1032,18 +1093,18 @@ reg_fetch (sim_cpu *cpu, int rn, void *buf, int len)
memset (buf, 0, len);
return len;
case SIM_RISCV_RA_REGNUM ... SIM_RISCV_T6_REGNUM:
- memcpy (buf, &cpu->regs[rn], len);
+ memcpy (buf, &riscv_cpu->regs[rn], len);
return len;
case SIM_RISCV_FIRST_FP_REGNUM ... SIM_RISCV_LAST_FP_REGNUM:
- memcpy (buf, &cpu->fpregs[rn - SIM_RISCV_FIRST_FP_REGNUM], len);
+ memcpy (buf, &riscv_cpu->fpregs[rn - SIM_RISCV_FIRST_FP_REGNUM], len);
return len;
case SIM_RISCV_PC_REGNUM:
- memcpy (buf, &cpu->pc, len);
+ memcpy (buf, &riscv_cpu->pc, len);
return len;
#define DECLARE_CSR(name, num, ...) \
case SIM_RISCV_ ## num ## _REGNUM: \
- memcpy (buf, &cpu->csr.name, len); \
+ memcpy (buf, &riscv_cpu->csr.name, len); \
return len;
#include "opcode/riscv-opc.h"
#undef DECLARE_CSR
@@ -1056,6 +1117,8 @@ reg_fetch (sim_cpu *cpu, int rn, void *buf, int len)
static int
reg_store (sim_cpu *cpu, int rn, const void *buf, int len)
{
+ struct riscv_sim_cpu *riscv_cpu = RISCV_SIM_CPU (cpu);
+
if (len <= 0 || len > sizeof (unsigned_word))
return -1;
@@ -1065,18 +1128,18 @@ reg_store (sim_cpu *cpu, int rn, const void *buf, int len)
/* Ignore writes. */
return len;
case SIM_RISCV_RA_REGNUM ... SIM_RISCV_T6_REGNUM:
- memcpy (&cpu->regs[rn], buf, len);
+ memcpy (&riscv_cpu->regs[rn], buf, len);
return len;
case SIM_RISCV_FIRST_FP_REGNUM ... SIM_RISCV_LAST_FP_REGNUM:
- memcpy (&cpu->fpregs[rn - SIM_RISCV_FIRST_FP_REGNUM], buf, len);
+ memcpy (&riscv_cpu->fpregs[rn - SIM_RISCV_FIRST_FP_REGNUM], buf, len);
return len;
case SIM_RISCV_PC_REGNUM:
- memcpy (&cpu->pc, buf, len);
+ memcpy (&riscv_cpu->pc, buf, len);
return len;
#define DECLARE_CSR(name, num, ...) \
case SIM_RISCV_ ## num ## _REGNUM: \
- memcpy (&cpu->csr.name, buf, len); \
+ memcpy (&riscv_cpu->csr.name, buf, len); \
return len;
#include "opcode/riscv-opc.h"
#undef DECLARE_CSR
@@ -1092,10 +1155,11 @@ reg_store (sim_cpu *cpu, int rn, const void *buf, int len)
void
initialize_cpu (SIM_DESC sd, SIM_CPU *cpu, int mhartid)
{
+ struct riscv_sim_cpu *riscv_cpu = RISCV_SIM_CPU (cpu);
const char *extensions;
int i;
- memset (cpu->regs, 0, sizeof (cpu->regs));
+ memset (riscv_cpu->regs, 0, sizeof (riscv_cpu->regs));
CPU_PC_FETCH (cpu) = pc_get;
CPU_PC_STORE (cpu) = pc_set;
@@ -1111,10 +1175,10 @@ initialize_cpu (SIM_DESC sd, SIM_CPU *cpu, int mhartid)
riscv_hash[OP_HASH_IDX (op->match)] = op;
}
- cpu->csr.misa = 0;
+ riscv_cpu->csr.misa = 0;
/* RV32 sets this field to 0, and we don't really support RV128 yet. */
if (RISCV_XLEN (cpu) == 64)
- cpu->csr.misa |= (uint64_t)2 << 62;
+ riscv_cpu->csr.misa |= (uint64_t)2 << 62;
/* Skip the leading "rv" prefix and the two numbers. */
extensions = MODEL_NAME (CPU_MODEL (cpu)) + 4;
@@ -1127,14 +1191,14 @@ initialize_cpu (SIM_DESC sd, SIM_CPU *cpu, int mhartid)
else if (strchr (extensions, ext) != NULL)
{
if (ext == 'G')
- cpu->csr.misa |= 0x1129; /* G = IMAFD. */
+ riscv_cpu->csr.misa |= 0x1129; /* G = IMAFD. */
else
- cpu->csr.misa |= (1 << i);
+ riscv_cpu->csr.misa |= (1 << i);
}
}
- cpu->csr.mimpid = 0x8000;
- cpu->csr.mhartid = mhartid;
+ riscv_cpu->csr.mimpid = 0x8000;
+ riscv_cpu->csr.mhartid = mhartid;
}
/* Some utils don't like having a NULL environ. */
@@ -1158,6 +1222,7 @@ void
initialize_env (SIM_DESC sd, const char * const *argv, const char * const *env)
{
SIM_CPU *cpu = STATE_CPU (sd, 0);
+ struct riscv_sim_cpu *riscv_cpu = RISCV_SIM_CPU (cpu);
int i;
int argc, argv_flat;
int envc, env_flat;
@@ -1188,8 +1253,8 @@ initialize_env (SIM_DESC sd, const char * const *argv, const char * const *env)
sp -= sizeof (unsigned_word);
/* Set up the regs the libgloss crt0 expects. */
- cpu->a0 = argc;
- cpu->sp = sp;
+ riscv_cpu->a0 = argc;
+ riscv_cpu->sp = sp;
/* First push the argc value. */
sim_write (sd, sp, &argc, sizeof (unsigned_word));
@@ -21,11 +21,13 @@
#ifndef SIM_MAIN_H
#define SIM_MAIN_H
+#define SIM_HAVE_COMMON_SIM_CPU
+
#include "sim-basics.h"
#include "machs.h"
#include "sim-base.h"
-struct _sim_cpu {
+struct riscv_sim_cpu {
union {
unsigned_word regs[32];
struct {
@@ -56,9 +58,8 @@ struct _sim_cpu {
#include "opcode/riscv-opc.h"
#undef DECLARE_CSR
} csr;
-
- sim_cpu_base base;
};
+#define RISCV_SIM_CPU(cpu) ((struct riscv_sim_cpu *) CPU_ARCH_DATA (cpu))
struct atomic_mem_reserved_list;
struct atomic_mem_reserved_list {