From dfc725838ee17f64e6601b5a4e64a9366a1a5681 Mon Sep 17 00:00:00 2001 From: Roger Chang Date: Thu, 31 Aug 2023 13:27:41 +0800 Subject: [PATCH 01/12] arch-riscv: Refactor PCState class Change-Id: I1d25350ba2a3c7c366f42340c20b4488c33cde6f --- src/arch/riscv/pcstate.hh | 37 +++++++++++++++++++++++++++++-------- 1 file changed, 29 insertions(+), 8 deletions(-) diff --git a/src/arch/riscv/pcstate.hh b/src/arch/riscv/pcstate.hh index 1c04cb5109..c790305504 100644 --- a/src/arch/riscv/pcstate.hh +++ b/src/arch/riscv/pcstate.hh @@ -56,15 +56,22 @@ constexpr enums::RiscvType RV64 = enums::RV64; class PCState : public GenericISA::UPCState<4> { - private: + protected: + typedef GenericISA::UPCState<4> Base; + bool _compressed = false; RiscvType _rvType = RV64; public: + PCState(const PCState &other) : Base(other), _rvType(other._rvType) + {} + PCState &operator=(const PCState &other) = default; PCState() = default; - PCState(const PCState &other) = default; - PCState(Addr addr, RiscvType rvType) : UPCState(addr), _rvType(rvType) + explicit PCState(Addr addr) { set(addr); } + explicit PCState(Addr addr, RiscvType rvType) { + set(addr); + _rvType = rvType; } PCStateBase *clone() const override { return new PCState(*this); } @@ -84,14 +91,28 @@ class PCState : public GenericISA::UPCState<4> void rvType(RiscvType rvType) { _rvType = rvType; } RiscvType rvType() const { return _rvType; } + uint64_t size() const { return _compressed ? 2 : 4; } + bool branching() const override { - if (_compressed) { - return npc() != pc() + 2 || nupc() != upc() + 1; - } else { - return npc() != pc() + 4 || nupc() != upc() + 1; - } + return npc() != pc() + size() || nupc() != upc() + 1; + } + + void + serialize(CheckpointOut &cp) const override + { + Base::serialize(cp); + SERIALIZE_SCALAR(_rvType); + SERIALIZE_SCALAR(_compressed); + } + + void + unserialize(CheckpointIn &cp) override + { + Base::unserialize(cp); + UNSERIALIZE_SCALAR(_rvType); + UNSERIALIZE_SCALAR(_compressed); } }; From 3f0475321a071b016ba92dc4401183032d1c08f0 Mon Sep 17 00:00:00 2001 From: Roger Chang Date: Tue, 5 Sep 2023 10:39:02 +0800 Subject: [PATCH 02/12] arch-riscv: Change VTYPE to BitUnion64 Change-Id: I7620ad1ef3ee0cc045bcd02b3c9a2d83f93bf3fe --- src/arch/riscv/regs/vector.hh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/arch/riscv/regs/vector.hh b/src/arch/riscv/regs/vector.hh index d722c2d03a..388e1cb78d 100644 --- a/src/arch/riscv/regs/vector.hh +++ b/src/arch/riscv/regs/vector.hh @@ -75,8 +75,8 @@ inline constexpr RegClass vecRegClass = ops(vecRegClassOps). regType(); -BitUnion32(VTYPE) - Bitfield<31> vill; +BitUnion64(VTYPE) + Bitfield<63> vill; Bitfield<7, 0> vtype8; Bitfield<7> vma; Bitfield<6> vta; From f94658098d666a96ce342f78c59528c3746ce7d4 Mon Sep 17 00:00:00 2001 From: Roger Chang Date: Mon, 14 Aug 2023 11:03:31 +0800 Subject: [PATCH 03/12] arch-riscv: Remove checked_type in StaticInst Constructor We should not try to check vtype when decoding the instruction. It should be checked in vset{i}vl{i} since the register can be modified via vset{i}vl{i} Change-Id: I403e5c4579bc5b8e6af10f93eac20c14662e4d2d --- src/arch/riscv/insts/vector.hh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/arch/riscv/insts/vector.hh b/src/arch/riscv/insts/vector.hh index cae0dcac0a..8098c98b78 100644 --- a/src/arch/riscv/insts/vector.hh +++ b/src/arch/riscv/insts/vector.hh @@ -100,7 +100,7 @@ class VectorNonSplitInst : public RiscvStaticInst OpClass __opClass) : RiscvStaticInst(mnem, _machInst, __opClass), vl(_machInst.vl), - vtype(checked_vtype(_machInst.vill, _machInst.vtype8)) + vtype(_machInst.vtype8) { this->flags[IsVector] = true; } @@ -118,7 +118,7 @@ class VectorMacroInst : public RiscvMacroInst OpClass __opClass) : RiscvMacroInst(mnem, _machInst, __opClass), vl(_machInst.vl), - vtype(checked_vtype(_machInst.vill, _machInst.vtype8)) + vtype(_machInst.vtype8) { this->flags[IsVector] = true; } From 7b5d8b4e5bc913d35f3be5f5242650140a92df78 Mon Sep 17 00:00:00 2001 From: Roger Chang Date: Thu, 31 Aug 2023 14:22:46 +0800 Subject: [PATCH 04/12] arch-riscv: Add vlenb, vtype and vl in PCState Change-Id: I7c2aed7dda34a1a449253671d7b86aa615c28464 --- src/arch/riscv/faults.cc | 4 ++++ src/arch/riscv/isa.hh | 2 +- src/arch/riscv/pcstate.hh | 39 +++++++++++++++++++++++++++++++++++++-- 3 files changed, 42 insertions(+), 3 deletions(-) diff --git a/src/arch/riscv/faults.cc b/src/arch/riscv/faults.cc index 89bb838f88..502b748087 100644 --- a/src/arch/riscv/faults.cc +++ b/src/arch/riscv/faults.cc @@ -183,6 +183,10 @@ Reset::invoke(ThreadContext *tc, const StaticInstPtr &inst) std::unique_ptr new_pc(dynamic_cast( tc->getIsaPtr()->newPCState(workload->getEntry()))); panic_if(!new_pc, "Failed create new PCState from ISA pointer"); + VTYPE vtype = 0; + vtype.vill = 1; + new_pc->vtype(vtype); + new_pc->vl(0); tc->pcState(*new_pc); // Reset PMP Cfg diff --git a/src/arch/riscv/isa.hh b/src/arch/riscv/isa.hh index f7726160c9..13366ef4c3 100644 --- a/src/arch/riscv/isa.hh +++ b/src/arch/riscv/isa.hh @@ -92,7 +92,7 @@ class ISA : public BaseISA PCStateBase* newPCState(Addr new_inst_addr=0) const override { - return new PCState(new_inst_addr, _rvType); + return new PCState(new_inst_addr, _rvType, VLENB); } public: diff --git a/src/arch/riscv/pcstate.hh b/src/arch/riscv/pcstate.hh index c790305504..918e85708b 100644 --- a/src/arch/riscv/pcstate.hh +++ b/src/arch/riscv/pcstate.hh @@ -43,6 +43,7 @@ #define __ARCH_RISCV_PCSTATE_HH__ #include "arch/generic/pcstate.hh" +#include "arch/riscv/regs/vector.hh" #include "enums/RiscvType.hh" namespace gem5 @@ -61,17 +62,23 @@ class PCState : public GenericISA::UPCState<4> bool _compressed = false; RiscvType _rvType = RV64; + uint64_t _vlenb = VLENB; + VTYPE _vtype = (1ULL << 63); // vtype.vill = 1 at initial; + uint32_t _vl = 0; public: - PCState(const PCState &other) : Base(other), _rvType(other._rvType) + PCState(const PCState &other) : Base(other), + _rvType(other._rvType), _vlenb(other._vlenb), + _vtype(other._vtype), _vl(other._vl) {} PCState &operator=(const PCState &other) = default; PCState() = default; explicit PCState(Addr addr) { set(addr); } - explicit PCState(Addr addr, RiscvType rvType) + explicit PCState(Addr addr, RiscvType rvType, uint64_t vlenb = VLENB) { set(addr); _rvType = rvType; + _vlenb = vlenb; } PCStateBase *clone() const override { return new PCState(*this); } @@ -83,6 +90,9 @@ class PCState : public GenericISA::UPCState<4> auto &pcstate = other.as(); _compressed = pcstate._compressed; _rvType = pcstate._rvType; + _vlenb = pcstate._vlenb; + _vtype = pcstate._vtype; + _vl = pcstate._vl; } void compressed(bool c) { _compressed = c; } @@ -91,6 +101,15 @@ class PCState : public GenericISA::UPCState<4> void rvType(RiscvType rvType) { _rvType = rvType; } RiscvType rvType() const { return _rvType; } + void vlenb(uint64_t v) { _vlenb = v; } + uint64_t vlenb() const { return _vlenb; } + + void vtype(VTYPE v) { _vtype = v; } + VTYPE vtype() const { return _vtype; } + + void vl(uint32_t v) { _vl = v; } + uint32_t vl() const { return _vl; } + uint64_t size() const { return _compressed ? 2 : 4; } bool @@ -99,11 +118,24 @@ class PCState : public GenericISA::UPCState<4> return npc() != pc() + size() || nupc() != upc() + 1; } + bool + equals(const PCStateBase &other) const override + { + auto &opc = other.as(); + return Base::equals(other) && + _vlenb == opc._vlenb && + _vtype == opc._vtype && + _vl == opc._vl; + } + void serialize(CheckpointOut &cp) const override { Base::serialize(cp); SERIALIZE_SCALAR(_rvType); + SERIALIZE_SCALAR(_vlenb); + SERIALIZE_SCALAR(_vtype); + SERIALIZE_SCALAR(_vl); SERIALIZE_SCALAR(_compressed); } @@ -112,6 +144,9 @@ class PCState : public GenericISA::UPCState<4> { Base::unserialize(cp); UNSERIALIZE_SCALAR(_rvType); + UNSERIALIZE_SCALAR(_vlenb); + UNSERIALIZE_SCALAR(_vtype); + UNSERIALIZE_SCALAR(_vl); UNSERIALIZE_SCALAR(_compressed); } }; From 8918302239576de56807e1b2c4269610a7d269de Mon Sep 17 00:00:00 2001 From: Roger Chang Date: Fri, 1 Sep 2023 16:20:51 +0800 Subject: [PATCH 05/12] arch-riscv: Change the implementation of vset*vl* The changes includes: 1. Add VL, Vtype and VlenbBits operands 2. Change R/W methods of VL, Vtype and VlenbBits from PCState Change-Id: I0531ddc14344f2cca94d0e750a3b4291e0227d54 --- src/arch/riscv/decoder.cc | 7 ++--- src/arch/riscv/isa/decoder.isa | 27 ++++++++++++++----- src/arch/riscv/isa/formats/vector_conf.isa | 31 +++++++++++----------- src/arch/riscv/isa/operands.isa | 6 +++++ 4 files changed, 47 insertions(+), 24 deletions(-) diff --git a/src/arch/riscv/decoder.cc b/src/arch/riscv/decoder.cc index 702d84fd91..2070b149dd 100644 --- a/src/arch/riscv/decoder.cc +++ b/src/arch/riscv/decoder.cc @@ -101,9 +101,7 @@ Decoder::moreBytes(const PCStateBase &pc, Addr fetchPC) } } if (instDone) { - emi.vl = this->machVl; - emi.vtype8 = this->machVtype & 0xff; - emi.vill = this->machVtype.vill; + if (vconf(emi)) { this->vConfigDone = false; // set true when vconfig inst execute } @@ -142,6 +140,9 @@ Decoder::decode(PCStateBase &_next_pc) next_pc.compressed(false); } + emi.vl = next_pc.vl(); + emi.vtype8 = next_pc.vtype() & 0xff; + emi.vill = next_pc.vtype().vill; emi.rv_type = static_cast(next_pc.rvType()); return decode(emi, next_pc.instAddr()); } diff --git a/src/arch/riscv/isa/decoder.isa b/src/arch/riscv/isa/decoder.isa index 71efac5958..4f573598e9 100644 --- a/src/arch/riscv/isa/decoder.isa +++ b/src/arch/riscv/isa/decoder.isa @@ -4359,8 +4359,13 @@ decode QUADRANT default Unknown::unknown() { uint64_t rs1_bits = RS1; uint64_t requested_vl = Rs1_ud; uint64_t requested_vtype = zimm11; - - Rd_ud = 0; + uint32_t vlen = VlenbBits * 8; + uint32_t vlmax = getVlmax(Vtype, vlen); + uint32_t current_vl = VL; + }}, {{ + Rd_ud = new_vl; + VL = new_vl; + Vtype = new_vtype; }}, VectorConfigOp, IsSerializeAfter, IsNonSpeculative); 0x1: decode BIT30 { 0x0: vsetvl({{ @@ -4368,8 +4373,13 @@ decode QUADRANT default Unknown::unknown() { uint64_t rs1_bits = RS1; uint64_t requested_vl = Rs1_ud; uint64_t requested_vtype = Rs2_ud; - - Rd_ud = 0; + uint32_t vlen = VlenbBits * 8; + uint32_t vlmax = getVlmax(Vtype, vlen); + uint32_t current_vl = VL; + }}, {{ + Rd_ud = new_vl; + VL = new_vl; + Vtype = new_vtype; }}, VectorConfigOp, IsSerializeAfter, IsNonSpeculative); 0x1: vsetivli({{ @@ -4377,8 +4387,13 @@ decode QUADRANT default Unknown::unknown() { uint64_t rs1_bits = -1; uint64_t requested_vl = uimm; uint64_t requested_vtype = zimm10; - - Rd_ud = 0; + uint32_t vlen = VlenbBits * 8; + uint32_t vlmax = getVlmax(Vtype, vlen); + uint32_t current_vl = VL; + }}, {{ + Rd_ud = new_vl; + VL = new_vl; + Vtype = new_vtype; }}, VectorConfigOp, IsSerializeAfter, IsNonSpeculative); } diff --git a/src/arch/riscv/isa/formats/vector_conf.isa b/src/arch/riscv/isa/formats/vector_conf.isa index 84e2f26783..93361ecb94 100644 --- a/src/arch/riscv/isa/formats/vector_conf.isa +++ b/src/arch/riscv/isa/formats/vector_conf.isa @@ -27,8 +27,17 @@ // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -def format VConfOp(code, *flags) {{ - iop = InstObjParams(name, Name, 'VConfOp', code, flags) +def format VConfOp(code, write_code, *flags) {{ + iop = InstObjParams( + name, + Name, + 'VConfOp', + { + 'code': code, + 'write_code': write_code, + }, + flags + ) header_output = BasicDeclare.subst(iop) decoder_output = BasicConstructor.subst(iop) decode_block = BasicDecode.subst(iop) @@ -54,11 +63,8 @@ def template VConfExecute {{ tc->setMiscReg(MISCREG_VSTART, 0); - uint32_t vlen = xc->readMiscReg(MISCREG_VLENB) * 8; - uint32_t vlmax = getVlmax(xc->readMiscReg(MISCREG_VTYPE), vlen); - VTYPE new_vtype = requested_vtype; - if (xc->readMiscReg(MISCREG_VTYPE) != new_vtype) { + if (Vtype != new_vtype) { vlmax = getVlmax(new_vtype, vlen); float vflmul = getVflmul(new_vtype.vlmul); @@ -68,17 +74,16 @@ def template VConfExecute {{ uint32_t new_vill = !(vflmul >= 0.125 && vflmul <= 8) || sew > std::min(vflmul, 1.0f) * ELEN || - bits(requested_vtype, 30, 8) != 0; + bits(requested_vtype, 62, 8) != 0; if (new_vill) { vlmax = 0; new_vtype = 0; new_vtype.vill = 1; } - - xc->setMiscReg(MISCREG_VTYPE, new_vtype); + } else { + new_vtype = Vtype; } - uint32_t current_vl = xc->readMiscReg(MISCREG_VL); uint32_t new_vl = 0; if (vlmax == 0) { new_vl = 0; @@ -90,11 +95,7 @@ def template VConfExecute {{ new_vl = requested_vl > vlmax ? vlmax : requested_vl; } - xc->setMiscReg(MISCREG_VL, new_vl); - - tc->getDecoderPtr()->as().setVlAndVtype(new_vl, new_vtype); - - Rd = new_vl; + %(write_code)s; %(op_wb)s; return NoFault; diff --git a/src/arch/riscv/isa/operands.isa b/src/arch/riscv/isa/operands.isa index a81b28df57..3a16e0994c 100644 --- a/src/arch/riscv/isa/operands.isa +++ b/src/arch/riscv/isa/operands.isa @@ -98,4 +98,10 @@ def operands {{ #Program Counter Operands 'PC': PCStateOp('ud', 'pc', (None, None, 'IsControl'), 7), 'NPC': PCStateOp('ud', 'npc', (None, None, 'IsControl'), 8), + +# VL and VTYPE + 'Vtype': PCStateOp('ud', 'vtype', (None, None, 'IsControl'), 10), + 'VL': PCStateOp('uw', 'vl', (None, None, 'IsControl'), 11), +#VLENB, actually the CSR is read only. + 'VlenbBits': PCStateOp('ud', 'vlenb', (None, None, 'IsControl'), 12), }}; From 1bde42760f51e4fb6b54107ad3ac65be8427968c Mon Sep 17 00:00:00 2001 From: Roger Chang Date: Mon, 4 Sep 2023 15:15:23 +0800 Subject: [PATCH 06/12] arch-riscv: Get vl, vtype and vlenb from PCState Change-Id: I0ded57a3dc2db6fcc7121f147bcaf6d8a8873f6a --- src/arch/riscv/isa.cc | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/arch/riscv/isa.cc b/src/arch/riscv/isa.cc index 14d741e9e4..4cb5082cad 100644 --- a/src/arch/riscv/isa.cc +++ b/src/arch/riscv/isa.cc @@ -40,6 +40,7 @@ #include "arch/riscv/mmu.hh" #include "arch/riscv/pagetable.hh" #include "arch/riscv/pmp.hh" +#include "arch/riscv/pcstate.hh" #include "arch/riscv/regs/float.hh" #include "arch/riscv/regs/int.hh" #include "arch/riscv/regs/misc.hh" @@ -503,9 +504,19 @@ ISA::readMiscReg(RegIndex idx) } case MISCREG_VLENB: { - return VLENB; + auto rpc = tc->pcState().as(); + return rpc.vlenb(); + } + case MISCREG_VTYPE: + { + auto rpc = tc->pcState().as(); + return rpc.vtype(); + } + case MISCREG_VL: + { + auto rpc = tc->pcState().as(); + return (RegVal)rpc.vl(); } - break; case MISCREG_VCSR: { return readMiscRegNoEffect(MISCREG_VXSAT) & From a3aaad2ecd252c591053500c5f2347550b320267 Mon Sep 17 00:00:00 2001 From: Roger Chang Date: Tue, 5 Sep 2023 11:18:57 +0800 Subject: [PATCH 07/12] arch-riscv: Refactor the execution part of vset*vl* Change-Id: Ie0d9671242481a85bb0fe5728748b16c3ef62592 --- src/arch/riscv/isa/formats/vector_conf.isa | 97 +++++++++++++++------- 1 file changed, 67 insertions(+), 30 deletions(-) diff --git a/src/arch/riscv/isa/formats/vector_conf.isa b/src/arch/riscv/isa/formats/vector_conf.isa index 93361ecb94..104d0ab2cd 100644 --- a/src/arch/riscv/isa/formats/vector_conf.isa +++ b/src/arch/riscv/isa/formats/vector_conf.isa @@ -38,13 +38,75 @@ def format VConfOp(code, write_code, *flags) {{ }, flags ) - header_output = BasicDeclare.subst(iop) + header_output = VSetVlDeclare.subst(iop) decoder_output = BasicConstructor.subst(iop) decode_block = BasicDecode.subst(iop) exec_output = VConfExecute.subst(iop) }}; +def template VSetVlDeclare {{ + // + // Static instruction class for "%(mnemonic)s". + // + class %(class_name)s : public %(base_class)s + { + private: + %(reg_idx_arr_decl)s; + VTYPE getNewVtype(VTYPE, VTYPE, uint32_t) const; + uint32_t getNewVL( + uint32_t, uint32_t, uint32_t, uint64_t, uint64_t) const; + + public: + /// Constructor. + %(class_name)s(ExtMachInst machInst); + Fault execute(ExecContext *, trace::InstRecord *) const override; + using %(base_class)s::generateDisassembly; + + }; +}}; + def template VConfExecute {{ + VTYPE + %(class_name)s::getNewVtype( + VTYPE oldVtype, VTYPE reqVtype, uint32_t vlen) const + { + VTYPE newVtype = oldVtype; + if (oldVtype != reqVtype) { + newVtype = reqVtype; + + float vflmul = getVflmul(newVtype.vlmul); + + uint32_t sew = getSew(newVtype.vsew); + + uint32_t newVill = + !(vflmul >= 0.125 && vflmul <= 8) || + sew > std::min(vflmul, 1.0f) * ELEN || + bits(reqVtype, 62, 8) != 0; + if (newVill) { + newVtype = 0; + newVtype.vill = 1; + } + } + return newVtype; + } + + uint32_t + %(class_name)s::getNewVL(uint32_t currentVl, uint32_t reqVl, + uint32_t vlmax, uint64_t rdBits, uint64_t rs1Bits) const + { + uint32_t newVl = 0; + if (vlmax == 0) { + newVl = 0; + } else if (rdBits == 0 && rs1Bits == 0) { + newVl = currentVl > vlmax ? vlmax : currentVl; + } else if (rdBits != 0 && rs1Bits == 0) { + newVl = vlmax; + } else if (rs1Bits != 0) { + newVl = reqVl > vlmax ? vlmax : reqVl; + } + return newVl; + } + Fault %(class_name)s::execute(ExecContext *xc, trace::InstRecord *traceData) const @@ -63,37 +125,12 @@ def template VConfExecute {{ tc->setMiscReg(MISCREG_VSTART, 0); - VTYPE new_vtype = requested_vtype; - if (Vtype != new_vtype) { - vlmax = getVlmax(new_vtype, vlen); + VTYPE new_vtype = getNewVtype(Vtype, requested_vtype, vlen); + vlmax = new_vtype.vill ? 0 : getVlmax(new_vtype, vlen); + uint32_t new_vl = getNewVL( + current_vl, requested_vl, vlmax, rd_bits, rs1_bits); - float vflmul = getVflmul(new_vtype.vlmul); - uint32_t sew = getSew(new_vtype.vsew); - - uint32_t new_vill = - !(vflmul >= 0.125 && vflmul <= 8) || - sew > std::min(vflmul, 1.0f) * ELEN || - bits(requested_vtype, 62, 8) != 0; - if (new_vill) { - vlmax = 0; - new_vtype = 0; - new_vtype.vill = 1; - } - } else { - new_vtype = Vtype; - } - - uint32_t new_vl = 0; - if (vlmax == 0) { - new_vl = 0; - } else if (rd_bits == 0 && rs1_bits == 0) { - new_vl = current_vl > vlmax ? vlmax : current_vl; - } else if (rd_bits != 0 && rs1_bits == 0) { - new_vl = vlmax; - } else if (rs1_bits != 0) { - new_vl = requested_vl > vlmax ? vlmax : requested_vl; - } %(write_code)s; From 282765234b58538dd3b48060c90ed5ad388eeef8 Mon Sep 17 00:00:00 2001 From: Roger Chang Date: Mon, 4 Sep 2023 15:24:45 +0800 Subject: [PATCH 08/12] arch-riscv: Implement the branchTarget for vset*vl* Change-Id: I10bf6be736ce2b99323ace410bff1d8e1e2a4123 --- src/arch/riscv/isa/decoder.isa | 9 +- src/arch/riscv/isa/formats/vector_conf.isa | 113 ++++++++++++++++++++- 2 files changed, 116 insertions(+), 6 deletions(-) diff --git a/src/arch/riscv/isa/decoder.isa b/src/arch/riscv/isa/decoder.isa index 4f573598e9..5e792e7dde 100644 --- a/src/arch/riscv/isa/decoder.isa +++ b/src/arch/riscv/isa/decoder.isa @@ -4366,7 +4366,8 @@ decode QUADRANT default Unknown::unknown() { Rd_ud = new_vl; VL = new_vl; Vtype = new_vtype; - }}, VectorConfigOp, IsSerializeAfter, IsNonSpeculative); + }}, VSetVlDeclare, VSetVliBranchTarget + , VectorConfigOp, IsSerializeAfter, IsNonSpeculative); 0x1: decode BIT30 { 0x0: vsetvl({{ uint64_t rd_bits = RD; @@ -4380,7 +4381,8 @@ decode QUADRANT default Unknown::unknown() { Rd_ud = new_vl; VL = new_vl; Vtype = new_vtype; - }}, VectorConfigOp, IsSerializeAfter, + }}, VSetVlDeclare, VSetVlBranchTarget + , VectorConfigOp, IsSerializeAfter, IsNonSpeculative); 0x1: vsetivli({{ uint64_t rd_bits = RD; @@ -4394,7 +4396,8 @@ decode QUADRANT default Unknown::unknown() { Rd_ud = new_vl; VL = new_vl; Vtype = new_vtype; - }}, VectorConfigOp, IsSerializeAfter, + }}, VSetiVliDeclare, VSetiVliBranchTarget + , VectorConfigOp, IsSerializeAfter, IsNonSpeculative); } } diff --git a/src/arch/riscv/isa/formats/vector_conf.isa b/src/arch/riscv/isa/formats/vector_conf.isa index 104d0ab2cd..457c5ce40d 100644 --- a/src/arch/riscv/isa/formats/vector_conf.isa +++ b/src/arch/riscv/isa/formats/vector_conf.isa @@ -27,7 +27,7 @@ // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -def format VConfOp(code, write_code, *flags) {{ +def format VConfOp(code, write_code, declare_class, branch_class, *flags) {{ iop = InstObjParams( name, Name, @@ -38,10 +38,13 @@ def format VConfOp(code, write_code, *flags) {{ }, flags ) - header_output = VSetVlDeclare.subst(iop) + declareTemplate = eval(declare_class) + branchTargetTemplate = eval(branch_class) + + header_output = declareTemplate.subst(iop) decoder_output = BasicConstructor.subst(iop) decode_block = BasicDecode.subst(iop) - exec_output = VConfExecute.subst(iop) + exec_output = VConfExecute.subst(iop) + branchTargetTemplate.subst(iop) }}; def template VSetVlDeclare {{ @@ -60,6 +63,35 @@ def template VSetVlDeclare {{ /// Constructor. %(class_name)s(ExtMachInst machInst); Fault execute(ExecContext *, trace::InstRecord *) const override; + std::unique_ptr branchTarget( + ThreadContext *tc) const override; + + using StaticInst::branchTarget; + using %(base_class)s::generateDisassembly; + + }; +}}; + +def template VSetiVliDeclare {{ + // + // Static instruction class for "%(mnemonic)s". + // + class %(class_name)s : public %(base_class)s + { + private: + %(reg_idx_arr_decl)s; + VTYPE getNewVtype(VTYPE, VTYPE, uint32_t) const; + uint32_t getNewVL( + uint32_t, uint32_t, uint32_t, uint64_t, uint64_t) const; + + public: + /// Constructor. + %(class_name)s(ExtMachInst machInst); + Fault execute(ExecContext *, trace::InstRecord *) const override; + std::unique_ptr branchTarget( + const PCStateBase &branch_pc) const override; + + using StaticInst::branchTarget; using %(base_class)s::generateDisassembly; }; @@ -138,3 +170,78 @@ def template VConfExecute {{ return NoFault; } }}; + +def template VSetiVliBranchTarget {{ + std::unique_ptr + %(class_name)s::branchTarget(const PCStateBase &branch_pc) const + { + auto &rpc = branch_pc.as(); + + uint64_t rd_bits = machInst.rd; + uint64_t rs1_bits = -1; + uint64_t requested_vl = uimm; + uint64_t requested_vtype = zimm10; + + uint32_t vlen = rpc.vlenb() * 8; + + VTYPE new_vtype = getNewVtype(rpc.vtype(), requested_vtype, vlen); + uint32_t vlmax = new_vtype.vill ? 0 : getVlmax(new_vtype, vlen); + uint32_t new_vl = getNewVL( + rpc.vl(), requested_vl, vlmax, rd_bits, rs1_bits); + + std::unique_ptr npc(dynamic_cast(rpc.clone())); + npc->vtype(new_vtype); + npc->vl(new_vl); + return npc; + } +}}; + +def template VSetVliBranchTarget {{ + std::unique_ptr + %(class_name)s::branchTarget(ThreadContext *tc) const + { + PCStateBase *pc_ptr = tc->pcState().clone(); + + uint64_t rd_bits = machInst.rd; + uint64_t rs1_bits = machInst.rs1; + uint64_t requested_vl = tc->getReg(srcRegIdx(0)); + uint64_t requested_vtype = zimm11; + + uint32_t vlen = pc_ptr->as().vlenb() * 8; + + VTYPE new_vtype = getNewVtype( + pc_ptr->as().vtype(), requested_vtype, vlen); + uint32_t vlmax = new_vtype.vill ? 0 : getVlmax(new_vtype, vlen); + uint32_t new_vl = getNewVL( + pc_ptr->as().vl(), requested_vl, vlmax, rd_bits, rs1_bits); + + pc_ptr->as().vtype(new_vtype); + pc_ptr->as().vl(new_vl); + return std::unique_ptr{pc_ptr}; + } +}}; + +def template VSetVlBranchTarget {{ + std::unique_ptr + %(class_name)s::branchTarget(ThreadContext *tc) const + { + PCStateBase *pc_ptr = tc->pcState().clone(); + + uint64_t rd_bits = machInst.rd; + uint64_t rs1_bits = machInst.rs1; + uint64_t requested_vl = tc->getReg(srcRegIdx(0)); + uint64_t requested_vtype = tc->getReg(srcRegIdx(1)); + + uint32_t vlen = pc_ptr->as().vlenb() * 8; + + VTYPE new_vtype = getNewVtype( + pc_ptr->as().vtype(), requested_vtype, vlen); + uint32_t vlmax = new_vtype.vill ? 0 : getVlmax(new_vtype, vlen); + uint32_t new_vl = getNewVL( + pc_ptr->as().vl(), requested_vl, vlmax, rd_bits, rs1_bits); + + pc_ptr->as().vtype(new_vtype); + pc_ptr->as().vl(new_vl); + return std::unique_ptr{pc_ptr}; + } +}}; From 31b95987da9aa9dab225108c6fb9a5e4b4d20789 Mon Sep 17 00:00:00 2001 From: Roger Chang Date: Fri, 1 Sep 2023 15:53:15 +0800 Subject: [PATCH 09/12] arch-riscv: Change the instruction family to jump like The method that get the vl, vtype from PCState in the next changes Change-Id: I022b47b7a96572f6434eed30dd9f7caa79854c31 --- src/arch/riscv/isa/decoder.isa | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/arch/riscv/isa/decoder.isa b/src/arch/riscv/isa/decoder.isa index 5e792e7dde..aeebfd6bf5 100644 --- a/src/arch/riscv/isa/decoder.isa +++ b/src/arch/riscv/isa/decoder.isa @@ -4367,7 +4367,8 @@ decode QUADRANT default Unknown::unknown() { VL = new_vl; Vtype = new_vtype; }}, VSetVlDeclare, VSetVliBranchTarget - , VectorConfigOp, IsSerializeAfter, IsNonSpeculative); + , VectorConfigOp, IsUncondControl + , IsIndirectControl); 0x1: decode BIT30 { 0x0: vsetvl({{ uint64_t rd_bits = RD; @@ -4382,8 +4383,8 @@ decode QUADRANT default Unknown::unknown() { VL = new_vl; Vtype = new_vtype; }}, VSetVlDeclare, VSetVlBranchTarget - , VectorConfigOp, IsSerializeAfter, - IsNonSpeculative); + , VectorConfigOp, IsUncondControl + , IsIndirectControl); 0x1: vsetivli({{ uint64_t rd_bits = RD; uint64_t rs1_bits = -1; @@ -4397,8 +4398,8 @@ decode QUADRANT default Unknown::unknown() { VL = new_vl; Vtype = new_vtype; }}, VSetiVliDeclare, VSetiVliBranchTarget - , VectorConfigOp, IsSerializeAfter, - IsNonSpeculative); + , VectorConfigOp, IsUncondControl + , IsDirectControl); } } } From 0f54cb05936ac97d447343c58c52ac0b0b89bb39 Mon Sep 17 00:00:00 2001 From: Roger Chang Date: Mon, 4 Sep 2023 16:13:51 +0800 Subject: [PATCH 10/12] arch-riscv: Remove check vconf done implementation Change-Id: If633cef209390d0500c4c2c5741d56158ef26c00 --- src/arch/riscv/decoder.cc | 31 ------------------------------- src/arch/riscv/decoder.hh | 10 ---------- 2 files changed, 41 deletions(-) diff --git a/src/arch/riscv/decoder.cc b/src/arch/riscv/decoder.cc index 2070b149dd..d225871241 100644 --- a/src/arch/riscv/decoder.cc +++ b/src/arch/riscv/decoder.cc @@ -41,8 +41,6 @@ namespace RiscvISA Decoder::Decoder(const RiscvDecoderParams &p) : InstDecoder(p, &machInst) { - ISA *isa = dynamic_cast(p.isa); - enableRvv = isa->getEnableRvv(); reset(); } @@ -50,7 +48,6 @@ void Decoder::reset() { aligned = true; mid = false; - vConfigDone = true; machInst = 0; emi = 0; } @@ -58,19 +55,6 @@ void Decoder::reset() void Decoder::moreBytes(const PCStateBase &pc, Addr fetchPC) { - // TODO: Current vsetvl instructions stall decode. Future fixes should - // enable speculation, and this code will be removed. - if (GEM5_UNLIKELY(!this->vConfigDone)) { - fatal_if(!enableRvv, - "Vector extension is not enabled for this CPU type\n" - "You can manually enable vector extensions by setting rvv_enabled " - "to true for each ISA object after `createThreads()`\n"); - DPRINTF(Decode, "Waiting for vset*vl* to be executed\n"); - instDone = false; - outOfBytes = false; - return; - } - // The MSB of the upper and lower halves of a machine instruction. constexpr size_t max_bit = sizeof(machInst) * 8 - 1; constexpr size_t mid_bit = sizeof(machInst) * 4 - 1; @@ -100,12 +84,6 @@ Decoder::moreBytes(const PCStateBase &pc, Addr fetchPC) instDone = compressed(emi); } } - if (instDone) { - - if (vconf(emi)) { - this->vConfigDone = false; // set true when vconfig inst execute - } - } } StaticInstPtr @@ -147,14 +125,5 @@ Decoder::decode(PCStateBase &_next_pc) return decode(emi, next_pc.instAddr()); } -void -Decoder::setVlAndVtype(uint32_t vl, VTYPE vtype) -{ - this->machVtype = vtype; - this->machVl = vl; - - this->vConfigDone = true; -} - } // namespace RiscvISA } // namespace gem5 diff --git a/src/arch/riscv/decoder.hh b/src/arch/riscv/decoder.hh index 1f510e8280..6ce72ee35a 100644 --- a/src/arch/riscv/decoder.hh +++ b/src/arch/riscv/decoder.hh @@ -54,17 +54,12 @@ class Decoder : public InstDecoder decode_cache::InstMap instMap; bool aligned; bool mid; - bool vConfigDone; protected: //The extended machine instruction being generated ExtMachInst emi; uint32_t machInst; - bool enableRvv = false; - VTYPE machVtype; - uint32_t machVl; - StaticInstPtr decodeInst(ExtMachInst mach_inst); /// Decode a machine instruction. @@ -78,17 +73,12 @@ class Decoder : public InstDecoder void reset() override; inline bool compressed(ExtMachInst inst) { return inst.quadRant < 0x3; } - inline bool vconf(ExtMachInst inst) { - return inst.opcode == 0b1010111u && inst.funct3 == 0b111u; - } //Use this to give data to the decoder. This should be used //when there is control flow. void moreBytes(const PCStateBase &pc, Addr fetchPC) override; StaticInstPtr decode(PCStateBase &nextPC) override; - - void setVlAndVtype(uint32_t vl, VTYPE vtype); }; } // namespace RiscvISA From def89745bc054622dd17ae9d34d1fae06fbd1cfd Mon Sep 17 00:00:00 2001 From: Roger Chang Date: Mon, 14 Aug 2023 15:06:11 +0800 Subject: [PATCH 11/12] arch-riscv: Allow Minor and O3 CPU execute RVV Change-Id: I4780b42c25d349806254b5053fb0da3b6993ca2f --- src/arch/riscv/RiscvCPU.py | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/src/arch/riscv/RiscvCPU.py b/src/arch/riscv/RiscvCPU.py index 449bf5e7af..1c77045c67 100644 --- a/src/arch/riscv/RiscvCPU.py +++ b/src/arch/riscv/RiscvCPU.py @@ -41,17 +41,6 @@ class RiscvCPU: ArchISA = RiscvISA -class RiscvISANoRVV(RiscvISA): - enable_rvv = False - - -class RiscvCPUNoRVV: - ArchDecoder = RiscvDecoder - ArchMMU = RiscvMMU - ArchInterrupts = RiscvInterrupts - ArchISA = RiscvISANoRVV - - class RiscvAtomicSimpleCPU(BaseAtomicSimpleCPU, RiscvCPU): mmu = RiscvMMU() @@ -64,9 +53,9 @@ class RiscvTimingSimpleCPU(BaseTimingSimpleCPU, RiscvCPU): mmu = RiscvMMU() -class RiscvO3CPU(BaseO3CPU, RiscvCPUNoRVV): +class RiscvO3CPU(BaseO3CPU, RiscvCPU): mmu = RiscvMMU() -class RiscvMinorCPU(BaseMinorCPU, RiscvCPUNoRVV): +class RiscvMinorCPU(BaseMinorCPU, RiscvCPU): mmu = RiscvMMU() From e41184fafc693c5e8405c347c451b5bd98b96666 Mon Sep 17 00:00:00 2001 From: Roger Chang Date: Wed, 6 Sep 2023 10:09:19 +0800 Subject: [PATCH 12/12] util: Update the RISC-V PCState checkpoint Change-Id: I64b6a3e1706173a001f5f8fb06756bd50d65f5bd --- util/cpt_upgraders/riscv-pcstate.py | 51 +++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 util/cpt_upgraders/riscv-pcstate.py diff --git a/util/cpt_upgraders/riscv-pcstate.py b/util/cpt_upgraders/riscv-pcstate.py new file mode 100644 index 0000000000..b8c6baf729 --- /dev/null +++ b/util/cpt_upgraders/riscv-pcstate.py @@ -0,0 +1,51 @@ +# Copyright (c) 2023 Google LLC +# All rights reserved. + +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. + +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +def upgrader(cpt): + + # Update the RISC-V pcstate to match the new version of + # PCState + + for sec in cpt.sections(): + import re + + if re.search(".*processor.*\.core.*\.xc.*", sec): + + if cpt.get(sec, "_rvType", fallback="") == "": + cpt.set(sec, "_rvType", "1") + + if cpt.get(sec, "_vlenb", fallback="") == "": + cpt.set(sec, "_vlenb", "32") + + if cpt.get(sec, "_vtype", fallback="") == "": + cpt.set(sec, "_vtype", str(1 << 63)) + + if cpt.get(sec, "_vl", fallback="") == "": + cpt.set(sec, "_vl", "0") + + if cpt.get(sec, "_compressed", fallback="") == "": + cpt.set(sec, "_compressed", "false")