From ae3eda6cd35dc5e9525d6852949751c7d127953a Mon Sep 17 00:00:00 2001 From: Luke Kenneth Casson Leighton Date: Sun, 11 Nov 2018 20:20:11 +0000 Subject: [PATCH] c_lwsp and c_swsp were not working correctly needed to be in ADDRmode (dropping down to mmu_t::load_xxx not sv_mmu_t) and also needed to stop using reg_spec.offset. added an extra argument to rvc_sp() which is "use_offset=true/false". switching to use_offset=false for c_lwsp and c_swsp, and getting them to both NOT be in the normal ADDRmode for LD/ST, we get an increment on the registers from SP. really should redirect the CSRs to not use SP, x28-x30 instead or something, in the unit tests... --- riscv/insns/c_lwsp.h | 2 +- riscv/insns/c_swsp.h | 2 +- riscv/sv_decode.h | 8 +++++--- riscv/sv_insn_redirect.cc | 8 ++++---- 4 files changed, 11 insertions(+), 9 deletions(-) diff --git a/riscv/insns/c_lwsp.h b/riscv/insns/c_lwsp.h index 6fd192c..e0bf8cb 100644 --- a/riscv/insns/c_lwsp.h +++ b/riscv/insns/c_lwsp.h @@ -1,3 +1,3 @@ require_extension('C'); require(insn.insn_t::rvc_rd() != 0); -WRITE_RD(MMU.load_int32(rv_add(RVC_SP, insn.rvc_lwsp_imm()))); +WRITE_RD(MMU.load_int32(insn.rvc_sp(false), insn.rvc_lwsp_imm())); diff --git a/riscv/insns/c_swsp.h b/riscv/insns/c_swsp.h index 57b1735..4aa3e0e 100644 --- a/riscv/insns/c_swsp.h +++ b/riscv/insns/c_swsp.h @@ -1,2 +1,2 @@ require_extension('C'); -MMU.store_uint32(rv_add(RVC_SP, insn.rvc_swsp_imm()), RVC_RS2); +MMU.store_uint32(insn.rvc_sp(false), insn.rvc_swsp_imm(), RVC_RS2); diff --git a/riscv/sv_decode.h b/riscv/sv_decode.h index f9551e8..18f67ae 100644 --- a/riscv/sv_decode.h +++ b/riscv/sv_decode.h @@ -68,7 +68,8 @@ public: reg_spec_t rvc_rs1s() { return predicated(_rvc_rs1s(), prs1); } reg_spec_t rvc_rs2 () { return predicated(_rvc_rs2 (), prs2); } reg_spec_t rvc_rs2s() { return predicated(_rvc_rs2s(), prs2); } - reg_spec_t rvc_sp () { return predicated(_rvc_sp (), psp ); } + reg_spec_t rvc_sp (bool use_offs=true) + { return predicated(_rvc_sp (use_offs), psp ); } reg_spec_t _rd () { return _remap(insn_t::rd (), fimap & REG_RD , offs_rd); } reg_spec_t _rs1() { return _remap(insn_t::rs1(), fimap & REG_RS1, offs_rs1); } @@ -82,8 +83,9 @@ public: offs_rs2); } reg_spec_t _rvc_rs2s() { return _remap(insn_t::rvc_rs2s(), fimap & REG_RVC_RS2S, offs_rs2); } - reg_spec_t _rvc_sp () { return _remap(2, true, // sp always 2, always int - offs_sp); } + reg_spec_t _rvc_sp (bool use_offs=true) + { return _remap(2, true, // sp always 2, always int + use_offs ? offs_sp : NULL); } void setpc(int xlen, int vlen, reg_t &npc, reg_t addr, uint64_t offs, reg_t *target_reg); diff --git a/riscv/sv_insn_redirect.cc b/riscv/sv_insn_redirect.cc index 67c39e3..7905245 100644 --- a/riscv/sv_insn_redirect.cc +++ b/riscv/sv_insn_redirect.cc @@ -308,7 +308,7 @@ reg_t sv_proc_t::READ_REG(reg_spec_t const& spec, int bitwidth = get_bitwidth(_insn->reg_elwidth(reg, true), xlen); int shift = 0; int offs = 0; - if (spec.offset != NULL && spec.reg != 2) { // XXX HACK on spec.reg != 2 + if (spec.offset != NULL) { int nbytes = width / bitwidth; if (nbytes == 0) { nbytes = 1; @@ -338,10 +338,10 @@ reg_t sv_proc_t::READ_REG(reg_spec_t const& spec, // gets element within the reg-block ndata = data >> (shift*bitwidth); ndata &= ((1UL<%lx\n", - spec.reg, bitwidth, offs, shift, data, ndata); } + fprintf(stderr, "readreg %ld bitwidth %d offs %d " \ + "shift %d %lx->%lx\n", + spec.reg, bitwidth, offs, shift, data, ndata); } return ndata; } -- 2.30.2