From: Mike Frysinger Date: Tue, 1 Nov 2022 06:15:34 +0000 (+0545) Subject: sim: riscv: invert sim_cpu storage X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=5409cab77ed607c4bb87160cf98861fad1e97381;p=binutils-gdb.git sim: riscv: invert sim_cpu storage --- diff --git a/sim/riscv/interp.c b/sim/riscv/interp.c index 937dc56bd0e..46f19165971 100644 --- a/sim/riscv/interp.c +++ b/sim/riscv/interp.c @@ -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; diff --git a/sim/riscv/sim-main.c b/sim/riscv/sim-main.c index b8771e66e67..4e7358b113a 100644 --- a/sim/riscv/sim-main.c +++ b/sim/riscv/sim-main.c @@ -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)); diff --git a/sim/riscv/sim-main.h b/sim/riscv/sim-main.h index d06ba97d969..aeeb0ad788f 100644 --- a/sim/riscv/sim-main.h +++ b/sim/riscv/sim-main.h @@ -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 {