arch-riscv: Implement the branchTarget for vset*vl*
Change-Id: I10bf6be736ce2b99323ace410bff1d8e1e2a4123
This commit is contained in:
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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};
|
||||
}
|
||||
}};
|
||||
|
||||
Reference in New Issue
Block a user