return false;
unsigned DestReg = Inst.getOperand(0).getReg();
- unsigned CheckReg;
// Operands[1] will be the first operand, DestReg.
SMLoc Loc = Operands[1]->getStartLoc();
if (TargetFlags & RISCVII::VS2Constraint) {
- CheckReg = Inst.getOperand(1).getReg();
+ unsigned CheckReg = Inst.getOperand(1).getReg();
if (DestReg == CheckReg)
return Error(Loc, "The destination vector register group cannot overlap"
" the source vector register group.");
}
if ((TargetFlags & RISCVII::VS1Constraint) && (Inst.getOperand(2).isReg())) {
- CheckReg = Inst.getOperand(2).getReg();
+ unsigned CheckReg = Inst.getOperand(2).getReg();
if (DestReg == CheckReg)
return Error(Loc, "The destination vector register group cannot overlap"
" the source vector register group.");
// same. For example, "viota.m v0, v2" is "viota.m v0, v2, NoRegister"
// actually. We need to check the last operand to ensure whether it is
// masked or not.
- if ((TargetFlags & RISCVII::OneInput) && (Inst.getNumOperands() == 3))
- CheckReg = Inst.getOperand(2).getReg();
- else if (Inst.getNumOperands() == 4)
- CheckReg = Inst.getOperand(3).getReg();
+ unsigned CheckReg = Inst.getOperand(Inst.getNumOperands() - 1).getReg();
+ assert((CheckReg == RISCV::V0 || CheckReg == RISCV::NoRegister) &&
+ "Unexpected register for mask operand");
+
if (DestReg == CheckReg)
return Error(Loc, "The destination vector register group cannot overlap"
" the mask register.");
def InstFormatCJ : InstFormat<16>;
def InstFormatOther : InstFormat<17>;
-class RISCVVConstraint<bits<4> val> {
- bits<4> Value = val;
+class RISCVVConstraint<bits<3> val> {
+ bits<3> Value = val;
}
-def NoConstraint : RISCVVConstraint<0b0000>;
-def VS2Constraint : RISCVVConstraint<0b0001>;
-def VS1Constraint : RISCVVConstraint<0b0010>;
-def VMConstraint : RISCVVConstraint<0b0100>;
-def OneInput : RISCVVConstraint<0b1000>;
+def NoConstraint : RISCVVConstraint<0b000>;
+def VS2Constraint : RISCVVConstraint<0b001>;
+def VS1Constraint : RISCVVConstraint<0b010>;
+def VMConstraint : RISCVVConstraint<0b100>;
+// Illegal instructions:
+//
+// * The destination vector register group for a masked vector instruction
+// cannot overlap the source mask register (v0), unless the destination vector
+// register is being written with a mask value (e.g., comparisons) or the
+// scalar result of a reduction.
+//
+// * Widening: The destination vector register group cannot overlap a source
+// vector register group of a different EEW
+//
+// * Narrowing: The destination vector register group cannot overlap the
+// first source vector register group
+//
+// * For vadc and vsbc, an illegal instruction exception is raised if the
+// destination vector register is v0.
+//
+// * For vmadc and vmsbc, an illegal instruction exception is raised if the
+// destination vector register overlaps a source vector register group.
+//
+// * viota: An illegal instruction exception is raised if the destination
+// vector register group overlaps the source vector mask register. If the
+// instruction is masked, an illegal instruction exception is issued if the
+// destination vector register group overlaps v0.
+//
+// * v[f]slide[1]up: The destination vector register group for vslideup cannot
+// overlap the source vector register group.
+//
+// * vrgather: The destination vector register group cannot overlap with the
+// source vector register groups.
+//
+// * vcompress: The destination vector register group cannot overlap the
+// source vector register group or the source mask register
def WidenV : RISCVVConstraint<!or(VS2Constraint.Value,
VS1Constraint.Value,
VMConstraint.Value)>;
def WidenW : RISCVVConstraint<!or(VS1Constraint.Value,
VMConstraint.Value)>;
def WidenCvt : RISCVVConstraint<!or(VS2Constraint.Value,
- VMConstraint.Value,
- OneInput.Value)>;
+ VMConstraint.Value)>;
def Narrow : RISCVVConstraint<!or(VS2Constraint.Value,
VMConstraint.Value)>;
def NarrowCvt : RISCVVConstraint<!or(VS2Constraint.Value,
- VMConstraint.Value,
- OneInput.Value)>;
+ VMConstraint.Value)>;
def Vmadc : RISCVVConstraint<!or(VS2Constraint.Value,
VS1Constraint.Value)>;
def Iota : RISCVVConstraint<!or(VS2Constraint.Value,
- VMConstraint.Value,
- OneInput.Value)>;
+ VMConstraint.Value)>;
def SlideUp : RISCVVConstraint<!or(VS2Constraint.Value,
VMConstraint.Value)>;
def Vrgather : RISCVVConstraint<!or(VS2Constraint.Value,
// Defaults
RISCVVConstraint RVVConstraint = NoConstraint;
- let TSFlags{8-5} = RVVConstraint.Value;
+ let TSFlags{7-5} = RVVConstraint.Value;
}
// Pseudo instructions
opcodestr, "$vd, (${rs1})"> {
let vm = 1;
let Uses = [];
+ let RVVConstraint = NoConstraint;
}
// segment load vd, (rs1), vm
defm VMERGE_V : VALUm_IV_V_X_I<"vmerge", 0b010111>;
// Vector Integer Move Instructions
-let hasSideEffects = 0, mayLoad = 0, mayStore = 0, vs2 = 0, vm = 1 in {
+let hasSideEffects = 0, mayLoad = 0, mayStore = 0, vs2 = 0, vm = 1,
+ RVVConstraint = NoConstraint in {
// op vd, vs1
def VMV_V_V : RVInstVV<0b010111, OPIVV, (outs VR:$vd),
(ins VR:$vs1), "vmv.v.v", "$vd, $vs1">;
}
// Vector Floating-Point Move Instruction
+let RVVConstraint = NoConstraint in
def VFMV_V_F : RVInstVX<0b010111, OPFVF, (outs VR:$vd),
(ins FPR32:$rs1), "vfmv.v.f", "$vd, $rs1"> {
let vs2 = 0;
let Predicates = [HasStdExtV] in {
// Vector Mask-Register Logical Instructions
+let RVVConstraint = NoConstraint in {
defm VMAND_M : VALU_MV_Mask<"vmand", 0b011001, "m">;
defm VMNAND_M : VALU_MV_Mask<"vmnand", 0b011101, "m">;
defm VMANDNOT_M : VALU_MV_Mask<"vmandnot", 0b011000, "m">;
defm VMNOR_M : VALU_MV_Mask<"vmnor", 0b011110, "m">;
defm VMORNOT_M : VALU_MV_Mask<"vmornot", 0b011100, "m">;
defm VMXNOR_M : VALU_MV_Mask<"vmxnor", 0b011111, "m">;
+}
def : InstAlias<"vmmv.m $vd, $vs",
(VMAND_MM VR:$vd, VR:$vs, VR:$vs)>;
def : InstAlias<"vmnot.m $vd, $vs",
(VMNAND_MM VR:$vd, VR:$vs, VR:$vs)>;
-let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in {
+let hasSideEffects = 0, mayLoad = 0, mayStore = 0,
+ RVVConstraint = NoConstraint in {
// Vector mask population count vpopc
def VPOPC_M : RVInstV<0b010000, 0b10000, OPMVV, (outs GPR:$vd),
(ins VR:$vs2, VMaskOp:$vm),
}
// Integer Scalar Move Instructions
-let vm = 1 in {
+let vm = 1, RVVConstraint = NoConstraint in {
def VMV_X_S : RVInstV<0b010000, 0b00000, OPMVV, (outs GPR:$vd),
(ins VR:$vs2), "vmv.x.s", "$vd, $vs2">;
let Constraints = "$vd = $vd_wb" in
} // Predicates = [HasStdExtV]
let Predicates = [HasStdExtV, HasStdExtF] in {
-let hasSideEffects = 0, mayLoad = 0, mayStore = 0, vm = 1 in {
+let hasSideEffects = 0, mayLoad = 0, mayStore = 0, vm = 1,
+ RVVConstraint = NoConstraint in {
// Floating-Point Scalar Move Instructions
def VFMV_F_S : RVInstV<0b010000, 0b00000, OPFVV, (outs FPR32:$vd),
(ins VR:$vs2), "vfmv.f.s", "$vd, $vs2">;
defm VCOMPRESS_V : VALU_MV_Mask<"vcompress", 0b010111>;
} // Constraints = "@earlyclobber $vd", RVVConstraint = Vcompress
-let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in {
+let hasSideEffects = 0, mayLoad = 0, mayStore = 0,
+ RVVConstraint = NoConstraint in {
foreach nf = [1, 2, 4, 8] in {
def VMV#nf#R_V : RVInstV<0b100111, !add(nf, -1), OPIVI, (outs VR:$vd),
(ins VR:$vs2), "vmv" # nf # "r.v",
InstFormatMask = 31,
ConstraintOffset = 5,
- ConstraintMask = 0b1111
+ ConstraintMask = 0b111
};
// Match with the definitions in RISCVInstrFormatsV.td
enum RVVConstraintType {
NoConstraint = 0,
- VS2Constraint = 0b0001,
- VS1Constraint = 0b0010,
- VMConstraint = 0b0100,
- OneInput = 0b1000,
-
- // Illegal instructions:
- //
- // * The destination vector register group for a masked vector instruction
- // cannot overlap the source mask register (v0), unless the destination vector
- // register is being written with a mask value (e.g., comparisons) or the
- // scalar result of a reduction.
- //
- // * Widening: The destination vector register group cannot overlap a source
- // vector register group of a different EEW
- //
- // * Narrowing: The destination vector register group cannot overlap the
- // first source vector register group
- //
- // * For vadc and vsbc, an illegal instruction exception is raised if the
- // destination vector register is v0.
- //
- // * For vmadc and vmsbc, an illegal instruction exception is raised if the
- // destination vector register overlaps a source vector register group.
- //
- // * viota: An illegal instruction exception is raised if the destination
- // vector register group overlaps the source vector mask register. If the
- // instruction is masked, an illegal instruction exception is issued if the
- // destination vector register group overlaps v0.
- //
- // * v[f]slide[1]up: The destination vector register group for vslideup cannot
- // overlap the source vector register group.
- //
- // * vrgather: The destination vector register group cannot overlap with the
- // source vector register groups.
- //
- // * vcompress: The destination vector register group cannot overlap the
- // source vector register group or the source mask register
- WidenV = VS2Constraint | VS1Constraint | VMConstraint,
- WidenW = VS1Constraint | VMConstraint,
- WidenCvt = VS2Constraint | VMConstraint | OneInput,
- Narrow = VS2Constraint | VMConstraint,
- NarrowCvt = VS2Constraint | VMConstraint | OneInput,
- Vmadc = VS2Constraint | VS1Constraint,
- Iota = VS2Constraint | VMConstraint | OneInput,
- SlideUp = VS2Constraint | VMConstraint,
- Vrgather = VS2Constraint | VS1Constraint | VMConstraint,
- Vcompress = VS2Constraint | VS1Constraint,
+ VS2Constraint = 0b001,
+ VS1Constraint = 0b010,
+ VMConstraint = 0b100,
};
// RISC-V Specific Machine Operand Flags
vfmerge.vfm v0, v1, f1, v0
# CHECK-ERROR: The destination vector register group cannot be V0.
# CHECK-ERROR-LABEL: vfmerge.vfm v0, v1, f1, v0
+
+vle8.v v0, (a0), v0.t
+# CHECK-ERROR: The destination vector register group cannot overlap the mask register.
+# CHECK-ERROR-LABEL: vle8.v v0, (a0), v0.t
+
+vfclass.v v0, v1, v0.t
+# CHECK-ERROR: The destination vector register group cannot overlap the mask register.
+# CHECK-ERROR-LABEL: vfclass.v v0, v1, v0.t
+
+vfsqrt.v v0, v1, v0.t
+# CHECK-ERROR: The destination vector register group cannot overlap the mask register.
+# CHECK-ERROR-LABEL: vfsqrt.v v0, v1, v0.t
+
+vzext.vf2 v0, v1, v0.t
+# CHECK-ERROR: The destination vector register group cannot overlap the mask register.
+# CHECK-ERROR-LABEL: vzext.vf2 v0, v1, v0.t
+
+vid.v v0, v0.t
+# CHECK-ERROR: The destination vector register group cannot overlap the mask register.
+# CHECK-ERROR-LABEL: vid.v v0, v0.t