static MachineBasicBlock *addVSetVL(MachineInstr &MI, MachineBasicBlock *BB,
int VLIndex, unsigned SEWIndex,
- unsigned VLMul, bool WritesElement0) {
+ RISCVVLMUL VLMul, bool WritesElement0) {
MachineFunction &MF = *BB->getParent();
DebugLoc DL = MI.getDebugLoc();
const TargetInstrInfo &TII = *MF.getSubtarget().getInstrInfo();
assert(RISCVVType::isValidSEW(SEW) && "Unexpected SEW");
RISCVVSEW ElementWidth = static_cast<RISCVVSEW>(Log2_32(SEW / 8));
- // LMUL should already be encoded correctly.
- RISCVVLMUL Multiplier = static_cast<RISCVVLMUL>(VLMul);
-
MachineRegisterInfo &MRI = MF.getRegInfo();
// VL and VTYPE are alive here.
TailAgnostic = false;
// For simplicity we reuse the vtype representation here.
- MIB.addImm(RISCVVType::encodeVTYPE(Multiplier, ElementWidth,
+ MIB.addImm(RISCVVType::encodeVTYPE(VLMul, ElementWidth,
/*TailAgnostic*/ TailAgnostic,
/*MaskAgnostic*/ false));
MachineBasicBlock *
RISCVTargetLowering::EmitInstrWithCustomInserter(MachineInstr &MI,
MachineBasicBlock *BB) const {
+ uint64_t TSFlags = MI.getDesc().TSFlags;
- if (const RISCVVPseudosTable::PseudoInfo *RVV =
- RISCVVPseudosTable::getPseudoInfo(MI.getOpcode())) {
- int VLIndex = RVV->getVLIndex();
- int SEWIndex = RVV->getSEWIndex();
- bool WritesElement0 = RVV->writesElement0();
+ if (TSFlags & RISCVII::HasSEWOpMask) {
+ unsigned NumOperands = MI.getNumExplicitOperands();
+ int VLIndex = (TSFlags & RISCVII::HasVLOpMask) ? NumOperands - 2 : -1;
+ unsigned SEWIndex = NumOperands - 1;
+ bool WritesElement0 = TSFlags & RISCVII::WritesElement0Mask;
- assert(SEWIndex >= 0 && "SEWIndex must be >= 0");
- return addVSetVL(MI, BB, VLIndex, SEWIndex, RVV->VLMul, WritesElement0);
+ RISCVVLMUL VLMul = static_cast<RISCVVLMUL>((TSFlags & RISCVII::VLMulMask) >>
+ RISCVII::VLMulShift);
+ return addVSetVL(MI, BB, VLIndex, SEWIndex, VLMul, WritesElement0);
}
switch (MI.getOpcode()) {
class RISCVVPseudo {
Pseudo Pseudo = !cast<Pseudo>(NAME); // Used as a key.
Instruction BaseInstr;
- bits<8> VLIndex = InvalidIndex.V;
- bits<8> SEWIndex = InvalidIndex.V;
- bits<8> MergeOpIndex = InvalidIndex.V;
- bits<3> VLMul;
- bit HasDummyMask = 0;
- bit WritesElement0 = 0;
}
// The actual table.
def RISCVVPseudosTable : GenericTable {
let FilterClass = "RISCVVPseudo";
let CppTypeName = "PseudoInfo";
- let Fields = [ "Pseudo", "BaseInstr", "VLIndex", "SEWIndex", "MergeOpIndex",
- "VLMul", "HasDummyMask", "WritesElement0" ];
+ let Fields = [ "Pseudo", "BaseInstr" ];
let PrimaryKey = [ "Pseudo" ];
let PrimaryKeyName = "getPseudoInfo";
}
let hasSideEffects = 0;
let usesCustomInserter = 1;
let Uses = [VL, VTYPE];
- let VLIndex = 2;
- let SEWIndex = 3;
+ let HasVLOp = 1;
+ let HasSEWOp = 1;
let HasDummyMask = 1;
let BaseInstr = !cast<Instruction>(PseudoToVInst<NAME>.VInst);
}
let usesCustomInserter = 1;
let Constraints = "$rd = $merge";
let Uses = [VL, VTYPE];
- let VLIndex = 4;
- let SEWIndex = 5;
- let MergeOpIndex = 1;
+ let HasVLOp = 1;
+ let HasSEWOp = 1;
+ let HasMergeOp = 1;
let BaseInstr = !cast<Instruction>(PseudoToVInst<NAME>.VInst);
}
let hasSideEffects = 0;
let usesCustomInserter = 1;
let Uses = [VL, VTYPE];
- let VLIndex = 3;
- let SEWIndex = 4;
+ let HasVLOp = 1;
+ let HasSEWOp = 1;
let HasDummyMask = 1;
let BaseInstr = !cast<Instruction>(PseudoToVInst<NAME>.VInst);
}
let usesCustomInserter = 1;
let Constraints = "$rd = $merge";
let Uses = [VL, VTYPE];
- let VLIndex = 5;
- let SEWIndex = 6;
- let MergeOpIndex = 1;
+ let HasVLOp = 1;
+ let HasSEWOp = 1;
+ let HasMergeOp = 1;
let BaseInstr = !cast<Instruction>(PseudoToVInst<NAME>.VInst);
}
let hasSideEffects = 0;
let usesCustomInserter = 1;
let Uses = [VL, VTYPE];
- let VLIndex = 3;
- let SEWIndex = 4;
+ let HasVLOp = 1;
+ let HasSEWOp = 1;
let HasDummyMask = 1;
let BaseInstr = !cast<Instruction>(PseudoToVInst<NAME>.VInst);
}
let usesCustomInserter = 1;
let Constraints = "$rd = $merge";
let Uses = [VL, VTYPE];
- let VLIndex = 5;
- let SEWIndex = 6;
- let MergeOpIndex = 1;
+ let HasVLOp = 1;
+ let HasSEWOp = 1;
+ let HasMergeOp = 1;
let BaseInstr = !cast<Instruction>(PseudoToVInst<NAME>.VInst);
}
let hasSideEffects = 0;
let usesCustomInserter = 1;
let Uses = [VL, VTYPE];
- let VLIndex = 2;
- let SEWIndex = 3;
+ let HasVLOp = 1;
+ let HasSEWOp = 1;
let HasDummyMask = 1;
let BaseInstr = !cast<Instruction>(PseudoToVInst<NAME>.VInst);
}
let hasSideEffects = 0;
let usesCustomInserter = 1;
let Uses = [VL, VTYPE];
- let VLIndex = 3;
- let SEWIndex = 4;
+ let HasVLOp = 1;
+ let HasSEWOp = 1;
let BaseInstr = !cast<Instruction>(PseudoToVInst<NAME>.VInst);
}
let hasSideEffects = 0;
let usesCustomInserter = 1;
let Uses = [VL, VTYPE];
- let VLIndex = 3;
- let SEWIndex = 4;
+ let HasVLOp = 1;
+ let HasSEWOp = 1;
let HasDummyMask = 1;
let BaseInstr = !cast<Instruction>(PseudoToVInst<NAME>.VInst);
}
let hasSideEffects = 0;
let usesCustomInserter = 1;
let Uses = [VL, VTYPE];
- let VLIndex = 4;
- let SEWIndex = 5;
+ let HasVLOp = 1;
+ let HasSEWOp = 1;
let BaseInstr = !cast<Instruction>(PseudoToVInst<NAME>.VInst);
}
let hasSideEffects = 0;
let usesCustomInserter = 1;
let Uses = [VL, VTYPE];
- let VLIndex = 2;
- let SEWIndex = 3;
+ let HasVLOp = 1;
+ let HasSEWOp = 1;
let BaseInstr = !cast<Instruction>(PseudoToVInst<NAME>.VInst);
}
let hasSideEffects = 0;
let usesCustomInserter = 1;
let Uses = [VL, VTYPE];
- let VLIndex = 1;
- let SEWIndex = 2;
+ let HasVLOp = 1;
+ let HasSEWOp = 1;
let HasDummyMask = 1;
let BaseInstr = !cast<Instruction>(PseudoToVInst<NAME>.VInst);
}
let usesCustomInserter = 1;
let Constraints ="$rd = $merge";
let Uses = [VL, VTYPE];
- let VLIndex = 3;
- let SEWIndex = 4;
- let MergeOpIndex = 1;
+ let HasVLOp = 1;
+ let HasSEWOp = 1;
+ let HasMergeOp = 1;
let BaseInstr = !cast<Instruction>(PseudoToVInst<NAME>.VInst);
}
let hasSideEffects = 0;
let usesCustomInserter = 1;
let Uses = [VL, VTYPE];
- let VLIndex = 1;
- let SEWIndex = 2;
+ let HasVLOp = 1;
+ let HasSEWOp = 1;
// BaseInstr is not used in RISCVExpandPseudoInsts pass.
// Just fill a corresponding real v-inst to pass tablegen check.
let BaseInstr = !cast<Instruction>(BaseInst);
let usesCustomInserter = 1;
let Constraints = Constraint;
let Uses = [VL, VTYPE];
- let VLIndex = 2;
- let SEWIndex = 3;
+ let HasVLOp = 1;
+ let HasSEWOp = 1;
let HasDummyMask = 1;
let BaseInstr = !cast<Instruction>(PseudoToVInst<NAME>.VInst);
}
let usesCustomInserter = 1;
let Constraints = Join<[Constraint, "$rd = $merge"], ",">.ret;
let Uses = [VL, VTYPE];
- let VLIndex = 4;
- let SEWIndex = 5;
- let MergeOpIndex = 1;
+ let HasVLOp = 1;
+ let HasSEWOp = 1;
+ let HasMergeOp = 1;
let BaseInstr = !cast<Instruction>(PseudoToVInst<NAME>.VInst);
}
let hasSideEffects = 0;
let usesCustomInserter = 1;
let Uses = [VL, VTYPE];
- let VLIndex = 3;
- let SEWIndex = 4;
+ let HasVLOp = 1;
+ let HasSEWOp = 1;
let BaseInstr = !cast<Instruction>(PseudoToVInst<NAME>.VInst);
}
let usesCustomInserter = 1;
let Constraints = "$rd = $merge";
let Uses = [VL, VTYPE];
- let VLIndex = 4;
- let SEWIndex = 5;
- let MergeOpIndex = 1;
+ let HasVLOp = 1;
+ let HasSEWOp = 1;
+ let HasMergeOp = 1;
let BaseInstr = !cast<Instruction>(PseudoToVInst<NAME>.VInst);
}
let usesCustomInserter = 1;
let Constraints = "@earlyclobber $rd, $rd = $merge";
let Uses = [VL, VTYPE];
- let VLIndex = 4;
- let SEWIndex = 5;
- let MergeOpIndex = 1;
+ let HasVLOp = 1;
+ let HasSEWOp = 1;
+ let HasMergeOp = 1;
let BaseInstr = !cast<Instruction>(PseudoToVInst<NAME>.VInst);
}
let usesCustomInserter = 1;
let Constraints = Constraint;
let Uses = [VL, VTYPE];
- let VLIndex = 3;
- let SEWIndex = 4;
+ let HasVLOp = 1;
+ let HasSEWOp = 1;
let HasDummyMask = 1;
let BaseInstr = !cast<Instruction>(PseudoToVInst<NAME>.VInst);
}
let hasSideEffects = 0;
let usesCustomInserter = 1;
let Uses = [VL, VTYPE];
- let VLIndex = 3;
- let SEWIndex = 4;
+ let HasVLOp = 1;
+ let HasSEWOp = 1;
let HasDummyMask = 1;
let BaseInstr = !cast<Instruction>(PseudoToVInst<NAME>.VInst);
}
let hasSideEffects = 0;
let usesCustomInserter = 1;
let Uses = [VL, VTYPE];
- let VLIndex = 4;
- let SEWIndex = 5;
+ let HasVLOp = 1;
+ let HasSEWOp = 1;
let BaseInstr = !cast<Instruction>(PseudoToVInst<NAME>.VInst);
}
let usesCustomInserter = 1;
let Constraints = Join<[Constraint, "$rd = $merge"], ",">.ret;
let Uses = [VL, VTYPE];
- let VLIndex = 5;
- let SEWIndex = 6;
- let MergeOpIndex = 1;
+ let HasVLOp = 1;
+ let HasSEWOp = 1;
+ let HasMergeOp = 1;
let BaseInstr = !cast<Instruction>(PseudoToVInst<NAME>.VInst);
}
let usesCustomInserter = 1;
let Constraints = Constraint;
let Uses = [VL, VTYPE];
- let VLIndex = !if(CarryIn, 4, 3);
- let SEWIndex = !if(CarryIn, 5, 4);
- let MergeOpIndex = InvalidIndex.V;
+ let HasVLOp = 1;
+ let HasSEWOp = 1;
+ let HasMergeOp = 0;
let BaseInstr = !cast<Instruction>(PseudoToVInst<NAME>.VInst);
let VLMul = MInfo.value;
}
let usesCustomInserter = 1;
let Constraints = Join<[Constraint, "$rd = $rs3"], ",">.ret;
let Uses = [VL, VTYPE];
- let VLIndex = 4;
- let SEWIndex = 5;
- let MergeOpIndex = 1;
+ let HasVLOp = 1;
+ let HasSEWOp = 1;
+ let HasMergeOp = 1;
let HasDummyMask = 1;
let BaseInstr = !cast<Instruction>(PseudoToVInst<NAME>.VInst);
}
Uses = [VL, VTYPE] in {
foreach m = MxList.m in {
let VLMul = m.value in {
- let SEWIndex = 2, BaseInstr = VMV_X_S in
+ let HasSEWOp = 1, BaseInstr = VMV_X_S in
def PseudoVMV_X_S # "_" # m.MX: Pseudo<(outs GPR:$rd),
(ins m.vrclass:$rs2, ixlenimm:$sew),
[]>, RISCVVPseudo;
- let VLIndex = 3, SEWIndex = 4, BaseInstr = VMV_S_X, WritesElement0 = 1,
+ let HasVLOp = 1, HasSEWOp = 1, BaseInstr = VMV_S_X, WritesElement0 = 1,
Constraints = "$rd = $rs1" in
def PseudoVMV_S_X # "_" # m.MX: Pseudo<(outs m.vrclass:$rd),
(ins m.vrclass:$rs1, GPR:$rs2,
Uses = [VL, VTYPE] in {
foreach m = MxList.m in {
let VLMul = m.value in {
- let SEWIndex = 2, BaseInstr = VFMV_F_S in
+ let HasSEWOp = 1, BaseInstr = VFMV_F_S in
def PseudoVFMV_F_S # "_" # m.MX : Pseudo<(outs FPR32:$rd),
(ins m.vrclass:$rs2,
ixlenimm:$sew),
[]>, RISCVVPseudo;
- let VLIndex = 3, SEWIndex = 4, BaseInstr = VFMV_S_F, WritesElement0 = 1,
+ let HasVLOp = 1, HasSEWOp = 1, BaseInstr = VFMV_S_F, WritesElement0 = 1,
Constraints = "$rd = $rs1" in
def PseudoVFMV_S_F # "_" # m.MX : Pseudo<(outs m.vrclass:$rd),
(ins m.vrclass:$rs1, FPR32:$rs2,
ConstraintShift = 5,
ConstraintMask = 0b111 << ConstraintShift,
+
+ VLMulShift = ConstraintShift + 3,
+ VLMulMask = 0b111 << VLMulShift,
+
+ // Do we need to add a dummy mask op when converting RVV Pseudo to MCInst.
+ HasDummyMaskOpShift = VLMulShift + 3,
+ HasDummyMaskOpMask = 1 << HasDummyMaskOpShift,
+
+ // Does this instruction only update element 0 the destination register.
+ WritesElement0Shift = HasDummyMaskOpShift + 1,
+ WritesElement0Mask = 1 << WritesElement0Shift,
+
+ // Does this instruction have a merge operand that must be removed when
+ // converting to MCInst. It will be the first explicit use operand. Used by
+ // RVV Pseudos.
+ HasMergeOpShift = WritesElement0Shift + 1,
+ HasMergeOpMask = 1 << HasMergeOpShift,
+
+ // Does this instruction have a SEW operand. It will be the last explicit
+ // operand. Used by RVV Pseudos.
+ HasSEWOpShift = HasMergeOpShift + 1,
+ HasSEWOpMask = 1 << HasSEWOpShift,
+
+ // Does this instruction have a VL operand. It will be the second to last
+ // explicit operand. Used by RVV Pseudos.
+ HasVLOpShift = HasSEWOpShift + 1,
+ HasVLOpMask = 1 << HasVLOpShift,
};
// Match with the definitions in RISCVInstrFormatsV.td
struct PseudoInfo {
uint16_t Pseudo;
uint16_t BaseInstr;
- uint8_t VLIndex;
- uint8_t SEWIndex;
- uint8_t MergeOpIndex;
- uint8_t VLMul;
- bool HasDummyMask;
- bool WritesElement0;
-
- int getVLIndex() const { return static_cast<int8_t>(VLIndex); }
-
- int getSEWIndex() const { return static_cast<int8_t>(SEWIndex); }
-
- int getMergeOpIndex() const { return static_cast<int8_t>(MergeOpIndex); }
-
- bool hasDummyMask() const { return HasDummyMask; }
-
- bool writesElement0() const { return WritesElement0; }
};
using namespace RISCV;