@@ -579,10 +579,11 @@ class PseudoToVInst<string PseudoInst> {
579
579
!subst("_B64", "",
580
580
!subst("_MASK", "",
581
581
!subst("_TIED", "",
582
+ !subst("_TU", "",
582
583
!subst("F16", "F",
583
584
!subst("F32", "F",
584
585
!subst("F64", "F",
585
- !subst("Pseudo", "", PseudoInst))))))))))))))))))));
586
+ !subst("Pseudo", "", PseudoInst))))))))))))))))))))) ;
586
587
}
587
588
588
589
// The destination vector register group for a masked vector instruction cannot
@@ -928,6 +929,9 @@ class VPseudoBinaryNoMask<VReg RetClass,
928
929
let BaseInstr = !cast<Instruction>(PseudoToVInst<NAME>.VInst);
929
930
}
930
931
932
+ // Special version of VPseudoBinaryNoMask where we pretend the first source is
933
+ // tied to the destination.
934
+ // This allows maskedoff and rs2 to be the same register.
931
935
class VPseudoTiedBinaryNoMask<VReg RetClass,
932
936
DAGOperand Op2Class,
933
937
string Constraint> :
@@ -1079,6 +1083,30 @@ class VPseudoBinaryCarryIn<VReg RetClass,
1079
1083
let VLMul = MInfo.value;
1080
1084
}
1081
1085
1086
+ class VPseudoTiedBinaryCarryIn<VReg RetClass,
1087
+ VReg Op1Class,
1088
+ DAGOperand Op2Class,
1089
+ LMULInfo MInfo,
1090
+ bit CarryIn,
1091
+ string Constraint> :
1092
+ Pseudo<(outs RetClass:$rd),
1093
+ !if(CarryIn,
1094
+ (ins RetClass:$merge, Op1Class:$rs2, Op2Class:$rs1, VMV0:$carry, AVL:$vl,
1095
+ ixlenimm:$sew),
1096
+ (ins RetClass:$merge, Op1Class:$rs2, Op2Class:$rs1, AVL:$vl, ixlenimm:$sew)), []>,
1097
+ RISCVVPseudo {
1098
+ let mayLoad = 0;
1099
+ let mayStore = 0;
1100
+ let hasSideEffects = 0;
1101
+ let Constraints = Join<[Constraint, "$rd = $merge"], ",">.ret;
1102
+ let HasVLOp = 1;
1103
+ let HasSEWOp = 1;
1104
+ let HasMergeOp = 1;
1105
+ let HasVecPolicyOp = 0;
1106
+ let BaseInstr = !cast<Instruction>(PseudoToVInst<NAME>.VInst);
1107
+ let VLMul = MInfo.value;
1108
+ }
1109
+
1082
1110
class VPseudoTernaryNoMask<VReg RetClass,
1083
1111
RegisterClass Op1Class,
1084
1112
DAGOperand Op2Class,
@@ -1741,6 +1769,16 @@ multiclass VPseudoBinaryV_VM<bit CarryOut = 0, bit CarryIn = 1,
1741
1769
m.vrclass, m.vrclass, m, CarryIn, Constraint>;
1742
1770
}
1743
1771
1772
+ multiclass VPseudoTiedBinaryV_VM<bit CarryOut = 0, bit CarryIn = 1,
1773
+ string Constraint = ""> {
1774
+ foreach m = MxList in
1775
+ def "_VV" # !if(CarryIn, "M", "") # "_" # m.MX # "_TU" :
1776
+ VPseudoTiedBinaryCarryIn<!if(CarryOut, VR,
1777
+ !if(!and(CarryIn, !not(CarryOut)),
1778
+ GetVRegNoV0<m.vrclass>.R, m.vrclass)),
1779
+ m.vrclass, m.vrclass, m, CarryIn, Constraint>;
1780
+ }
1781
+
1744
1782
multiclass VPseudoBinaryV_XM<bit CarryOut = 0, bit CarryIn = 1,
1745
1783
string Constraint = ""> {
1746
1784
foreach m = MxList in
@@ -1751,13 +1789,29 @@ multiclass VPseudoBinaryV_XM<bit CarryOut = 0, bit CarryIn = 1,
1751
1789
m.vrclass, GPR, m, CarryIn, Constraint>;
1752
1790
}
1753
1791
1792
+ multiclass VPseudoTiedBinaryV_XM<bit CarryOut = 0, bit CarryIn = 1,
1793
+ string Constraint = ""> {
1794
+ foreach m = MxList in
1795
+ def "_VX" # !if(CarryIn, "M", "") # "_" # m.MX # "_TU":
1796
+ VPseudoTiedBinaryCarryIn<!if(CarryOut, VR,
1797
+ !if(!and(CarryIn, !not(CarryOut)),
1798
+ GetVRegNoV0<m.vrclass>.R, m.vrclass)),
1799
+ m.vrclass, GPR, m, CarryIn, Constraint>;
1800
+ }
1801
+
1754
1802
multiclass VPseudoVMRG_FM {
1755
1803
foreach f = FPList in
1756
- foreach m = f.MxList in
1804
+ foreach m = f.MxList in {
1757
1805
def "_V" # f.FX # "M_" # m.MX :
1758
1806
VPseudoBinaryCarryIn<GetVRegNoV0<m.vrclass>.R,
1759
1807
m.vrclass, f.fprclass, m, /*CarryIn=*/1, "">,
1760
1808
Sched<[WriteVFMergeV, ReadVFMergeV, ReadVFMergeF, ReadVMask]>;
1809
+ // Tied version to allow codegen control over the tail elements
1810
+ def "_V" # f.FX # "M_" # m.MX # "_TU":
1811
+ VPseudoTiedBinaryCarryIn<GetVRegNoV0<m.vrclass>.R,
1812
+ m.vrclass, f.fprclass, m, /*CarryIn=*/1, "">,
1813
+ Sched<[WriteVFMergeV, ReadVFMergeV, ReadVFMergeF, ReadVMask]>;
1814
+ }
1761
1815
}
1762
1816
1763
1817
multiclass VPseudoBinaryV_IM<bit CarryOut = 0, bit CarryIn = 1,
@@ -1770,6 +1824,16 @@ multiclass VPseudoBinaryV_IM<bit CarryOut = 0, bit CarryIn = 1,
1770
1824
m.vrclass, simm5, m, CarryIn, Constraint>;
1771
1825
}
1772
1826
1827
+ multiclass VPseudoTiedBinaryV_IM<bit CarryOut = 0, bit CarryIn = 1,
1828
+ string Constraint = ""> {
1829
+ foreach m = MxList in
1830
+ def "_VI" # !if(CarryIn, "M", "") # "_" # m.MX # "_TU":
1831
+ VPseudoTiedBinaryCarryIn<!if(CarryOut, VR,
1832
+ !if(!and(CarryIn, !not(CarryOut)),
1833
+ GetVRegNoV0<m.vrclass>.R, m.vrclass)),
1834
+ m.vrclass, simm5, m, CarryIn, Constraint>;
1835
+ }
1836
+
1773
1837
multiclass VPseudoUnaryVMV_V_X_I {
1774
1838
foreach m = MxList in {
1775
1839
let VLMul = m.value in {
@@ -2104,6 +2168,13 @@ multiclass VPseudoVMRG_VM_XM_IM {
2104
2168
Sched<[WriteVIMergeX, ReadVIMergeV, ReadVIMergeX, ReadVMask]>;
2105
2169
defm "" : VPseudoBinaryV_IM,
2106
2170
Sched<[WriteVIMergeI, ReadVIMergeV, ReadVMask]>;
2171
+ // Tied versions to allow codegen control over the tail elements
2172
+ defm "" : VPseudoTiedBinaryV_VM,
2173
+ Sched<[WriteVIMergeV, ReadVIMergeV, ReadVIMergeV, ReadVMask]>;
2174
+ defm "" : VPseudoTiedBinaryV_XM,
2175
+ Sched<[WriteVIMergeX, ReadVIMergeV, ReadVIMergeX, ReadVMask]>;
2176
+ defm "" : VPseudoTiedBinaryV_IM,
2177
+ Sched<[WriteVIMergeI, ReadVIMergeV, ReadVMask]>;
2107
2178
}
2108
2179
2109
2180
multiclass VPseudoVCALU_VM_XM_IM {
0 commit comments