arch-riscv: Implement the branchTarget for vset*vl*

Change-Id: I10bf6be736ce2b99323ace410bff1d8e1e2a4123
This commit is contained in:
Roger Chang
2023-09-04 15:24:45 +08:00
parent a3aaad2ecd
commit 282765234b
2 changed files with 116 additions and 6 deletions

View File

@@ -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);
}
}

View File

@@ -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<PCStateBase> 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<PCStateBase> 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<PCStateBase>
%(class_name)s::branchTarget(const PCStateBase &branch_pc) const
{
auto &rpc = branch_pc.as<RiscvISA::PCState>();
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<PCState> npc(dynamic_cast<PCState*>(rpc.clone()));
npc->vtype(new_vtype);
npc->vl(new_vl);
return npc;
}
}};
def template VSetVliBranchTarget {{
std::unique_ptr<PCStateBase>
%(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<PCState>().vlenb() * 8;
VTYPE new_vtype = getNewVtype(
pc_ptr->as<PCState>().vtype(), requested_vtype, vlen);
uint32_t vlmax = new_vtype.vill ? 0 : getVlmax(new_vtype, vlen);
uint32_t new_vl = getNewVL(
pc_ptr->as<PCState>().vl(), requested_vl, vlmax, rd_bits, rs1_bits);
pc_ptr->as<PCState>().vtype(new_vtype);
pc_ptr->as<PCState>().vl(new_vl);
return std::unique_ptr<PCStateBase>{pc_ptr};
}
}};
def template VSetVlBranchTarget {{
std::unique_ptr<PCStateBase>
%(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<PCState>().vlenb() * 8;
VTYPE new_vtype = getNewVtype(
pc_ptr->as<PCState>().vtype(), requested_vtype, vlen);
uint32_t vlmax = new_vtype.vill ? 0 : getVlmax(new_vtype, vlen);
uint32_t new_vl = getNewVL(
pc_ptr->as<PCState>().vl(), requested_vl, vlmax, rd_bits, rs1_bits);
pc_ptr->as<PCState>().vtype(new_vtype);
pc_ptr->as<PCState>().vl(new_vl);
return std::unique_ptr<PCStateBase>{pc_ptr};
}
}};