From 7cacfcc2fc5eaea6994b788a594a945bf67390d1 Mon Sep 17 00:00:00 2001 From: Luke Kenneth Casson Leighton Date: Sun, 7 Oct 2018 15:06:39 +0100 Subject: [PATCH] override setpc macro so that sv can redirect it in branch this is slightly complicated. setpc is a global macro, intended for use in the templates. however for SV it needs to be conditional, so needs to redirect to a function in sv_insn_t. that in turn needs quite a few extra parameters: the current loop element offset, the argument to set_pc just in case actually it is detected that this really is to be a branch not a predication scenario and so on. have not tried out vectorisation yet, at least straight non-vectorised branch operations (unit tests) pass. --- riscv/decode.h | 6 +++++- riscv/insn_template.cc | 3 ++- riscv/insn_template_sv.cc | 6 ++++++ riscv/sv.cc | 12 ++++++++++++ riscv/sv_decode.h | 6 +++++- 5 files changed, 30 insertions(+), 3 deletions(-) diff --git a/riscv/decode.h b/riscv/decode.h index f9e3b6f..f7a8f10 100644 --- a/riscv/decode.h +++ b/riscv/decode.h @@ -201,11 +201,15 @@ private: #define sext_xlen(x) (((sreg_t)(x) << (64-xlen)) >> (64-xlen)) #define zext_xlen(x) (((reg_t)(x) << (64-xlen)) >> (64-xlen)) -#define set_pc(x) \ +#define _set_pc(x) \ do { p->check_pc_alignment(x); \ npc = sext_xlen(x); \ } while(0) +#ifndef SPIKE_SIMPLEV + #define set_pc _set_pc +#endif + #define set_pc_and_serialize(x) \ do { reg_t __npc = (x) & p->pc_alignment_mask(); \ npc = PC_SERIALIZE_AFTER; \ diff --git a/riscv/insn_template.cc b/riscv/insn_template.cc index ebfc02a..3e23731 100644 --- a/riscv/insn_template.cc +++ b/riscv/insn_template.cc @@ -21,9 +21,10 @@ #define INSN NAME #define INCLUDEFILE "insns/NAME.h" +#define SVINCLUDEFILE "insns/sv_NAME.h" #define INSNCODE OPCODE -#include "sv_decode.h" #include "insns/regs_NAME.h" +#include "sv_decode.h" #define FN rv32_NAME #define ISASZ 32 #include "insn_template_sv.cc" diff --git a/riscv/insn_template_sv.cc b/riscv/insn_template_sv.cc index 9869707..9edce51 100644 --- a/riscv/insn_template_sv.cc +++ b/riscv/insn_template_sv.cc @@ -3,6 +3,12 @@ #define xstr(s) str(s) #define str(s) #s +#ifdef USING_NOREGS + #define set_pc _set_pc +#else + #define set_pc(x) insn.setpc(xlen, vlen, npc, x, *dest_offs); +#endif + reg_t FN(processor_t* p, insn_t s_insn, reg_t pc) { int xlen = ISASZ; diff --git a/riscv/sv.cc b/riscv/sv.cc index 6979e44..a5bae31 100644 --- a/riscv/sv.cc +++ b/riscv/sv.cc @@ -45,6 +45,7 @@ bool sv_insn_t::sv_check_reg(bool intreg, uint64_t reg) if (r->active && r->isvec) { fprintf(stderr, "checkreg: %ld active\n", reg); + at_least_one_reg_vectorised = true; return true; } return false; @@ -202,3 +203,14 @@ uint64_t sv_insn_t::rd_bitset(uint64_t bit, bool set) WRITE_REG(reg, val); return val; } + +void sv_insn_t::setpc(int xlen, int vlen, reg_t &npc, reg_t addr, uint64_t offs) +{ + if (vlen == 1 or not at_least_one_reg_vectorised) + { + _set_pc(addr); + return; + } + rd_bitset(offs, true); +} + diff --git a/riscv/sv_decode.h b/riscv/sv_decode.h index 54ede03..d72444f 100644 --- a/riscv/sv_decode.h +++ b/riscv/sv_decode.h @@ -24,7 +24,8 @@ public: uint64_t &p_rd, uint64_t &p_rs1, uint64_t &p_rs2, uint64_t &p_rs3, uint64_t *p_im, int *o_rd, int *o_rs1, int *o_rs2, int *o_rs3, int *o_imm) : - insn_t(bits), p(pr), vloop_continue(false), fimap(f), + insn_t(bits), p(pr), vloop_continue(false), + at_least_one_reg_vectorised(false), fimap(f), offs_rd(o_rd), offs_rs1(o_rs1), offs_rs2(o_rs2), offs_rs3(o_rs3), offs_imm(o_imm), prd(p_rd), prs1(p_rs1), prs2(p_rs2), prs3(p_rs3) {} @@ -57,6 +58,8 @@ public: uint64_t _rvc_rs2s() { return _remap(insn_t::rvc_rs2s(), fimap & REG_RVC_RS2S, offs_rs2); } + void setpc(int xlen, int vlen, reg_t &npc, reg_t addr, uint64_t offs); + // used for predicated branches. sets bit N if val=true; clears bit N if false uint64_t rd_bitset(uint64_t bit, bool val); @@ -84,6 +87,7 @@ public: private: bool vloop_continue; + bool at_least_one_reg_vectorised; unsigned int fimap; int *offs_rd; int *offs_rs1; -- 2.30.2