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() diff --git a/src/arch/riscv/decoder.cc b/src/arch/riscv/decoder.cc index 702d84fd91..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,14 +84,6 @@ Decoder::moreBytes(const PCStateBase &pc, Addr fetchPC) instDone = compressed(emi); } } - 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 - } - } } StaticInstPtr @@ -142,18 +118,12 @@ 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()); } -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 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/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; } 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) & 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/isa/decoder.isa b/src/arch/riscv/isa/decoder.isa index 71efac5958..aeebfd6bf5 100644 --- a/src/arch/riscv/isa/decoder.isa +++ b/src/arch/riscv/isa/decoder.isa @@ -4359,28 +4359,47 @@ decode QUADRANT default Unknown::unknown() { uint64_t rs1_bits = RS1; uint64_t requested_vl = Rs1_ud; uint64_t requested_vtype = zimm11; - - Rd_ud = 0; - }}, VectorConfigOp, IsSerializeAfter, IsNonSpeculative); + 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; + }}, VSetVlDeclare, VSetVliBranchTarget + , VectorConfigOp, IsUncondControl + , IsIndirectControl); 0x1: decode BIT30 { 0x0: vsetvl({{ uint64_t rd_bits = RD; uint64_t rs1_bits = RS1; uint64_t requested_vl = Rs1_ud; uint64_t requested_vtype = Rs2_ud; - - Rd_ud = 0; - }}, VectorConfigOp, IsSerializeAfter, - IsNonSpeculative); + 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; + }}, VSetVlDeclare, VSetVlBranchTarget + , VectorConfigOp, IsUncondControl + , IsIndirectControl); 0x1: vsetivli({{ uint64_t rd_bits = RD; uint64_t rs1_bits = -1; uint64_t requested_vl = uimm; uint64_t requested_vtype = zimm10; - - Rd_ud = 0; - }}, VectorConfigOp, IsSerializeAfter, - IsNonSpeculative); + 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; + }}, VSetiVliDeclare, VSetiVliBranchTarget + , VectorConfigOp, IsUncondControl + , IsDirectControl); } } } diff --git a/src/arch/riscv/isa/formats/vector_conf.isa b/src/arch/riscv/isa/formats/vector_conf.isa index 84e2f26783..457c5ce40d 100644 --- a/src/arch/riscv/isa/formats/vector_conf.isa +++ b/src/arch/riscv/isa/formats/vector_conf.isa @@ -27,15 +27,118 @@ // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -def format VConfOp(code, *flags) {{ - iop = InstObjParams(name, Name, 'VConfOp', code, flags) - header_output = BasicDeclare.subst(iop) +def format VConfOp(code, write_code, declare_class, branch_class, *flags) {{ + iop = InstObjParams( + name, + Name, + 'VConfOp', + { + 'code': code, + 'write_code': write_code, + }, + flags + ) + 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 {{ + // + // 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( + 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; + + }; }}; 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 @@ -54,49 +157,91 @@ 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 = 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); - VTYPE new_vtype = requested_vtype; - if (xc->readMiscReg(MISCREG_VTYPE) != new_vtype) { - vlmax = getVlmax(new_vtype, vlen); - 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, 30, 8) != 0; - if (new_vill) { - vlmax = 0; - new_vtype = 0; - new_vtype.vill = 1; - } - - xc->setMiscReg(MISCREG_VTYPE, new_vtype); - } - - uint32_t current_vl = xc->readMiscReg(MISCREG_VL); - 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; - } - - 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; } }}; + +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}; + } +}}; 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), }}; diff --git a/src/arch/riscv/pcstate.hh b/src/arch/riscv/pcstate.hh index 1c04cb5109..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 @@ -56,15 +57,28 @@ 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; + 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), _vlenb(other._vlenb), + _vtype(other._vtype), _vl(other._vl) + {} + 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, uint64_t vlenb = VLENB) { + set(addr); + _rvType = rvType; + _vlenb = vlenb; } PCStateBase *clone() const override { return new PCState(*this); } @@ -76,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; } @@ -84,14 +101,53 @@ 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 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; + } + + 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); + } + + void + unserialize(CheckpointIn &cp) override + { + Base::unserialize(cp); + UNSERIALIZE_SCALAR(_rvType); + UNSERIALIZE_SCALAR(_vlenb); + UNSERIALIZE_SCALAR(_vtype); + UNSERIALIZE_SCALAR(_vl); + UNSERIALIZE_SCALAR(_compressed); } }; 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; 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")