From 282765234b58538dd3b48060c90ed5ad388eeef8 Mon Sep 17 00:00:00 2001 From: Roger Chang Date: Mon, 4 Sep 2023 15:24:45 +0800 Subject: [PATCH] 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}; + } +}};