diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2022-01-27 22:17:16 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2022-05-14 11:44:34 +0000 |
commit | 04eeddc0aa8e0a417a16eaf9d7d095207f4a8623 (patch) | |
tree | 2a5d3b2fe5c852e91531d128d9177754572d5338 /contrib/llvm-project/llvm/lib/Target/RISCV/RISCVInstrInfoVPseudos.td | |
parent | 0eae32dcef82f6f06de6419a0d623d7def0cc8f6 (diff) | |
parent | 6f8fc217eaa12bf657be1c6468ed9938d10168b3 (diff) | |
download | src-04eeddc0aa8e0a417a16eaf9d7d095207f4a8623.tar.gz src-04eeddc0aa8e0a417a16eaf9d7d095207f4a8623.zip |
Diffstat (limited to 'contrib/llvm-project/llvm/lib/Target/RISCV/RISCVInstrInfoVPseudos.td')
-rw-r--r-- | contrib/llvm-project/llvm/lib/Target/RISCV/RISCVInstrInfoVPseudos.td | 611 |
1 files changed, 336 insertions, 275 deletions
diff --git a/contrib/llvm-project/llvm/lib/Target/RISCV/RISCVInstrInfoVPseudos.td b/contrib/llvm-project/llvm/lib/Target/RISCV/RISCVInstrInfoVPseudos.td index 073fa605e0fb..4e7e251bc412 100644 --- a/contrib/llvm-project/llvm/lib/Target/RISCV/RISCVInstrInfoVPseudos.td +++ b/contrib/llvm-project/llvm/lib/Target/RISCV/RISCVInstrInfoVPseudos.td @@ -71,49 +71,45 @@ def V_MF4 : LMULInfo<0b110, 2, VR, VR, VR,/*NoVReg*/VR,/*NoVReg*/VR, "M def V_MF2 : LMULInfo<0b111, 4, VR, VR, VR, VR,/*NoVReg*/VR, "MF2">; // Used to iterate over all possible LMULs. -def MxList { - list<LMULInfo> m = [V_MF8, V_MF4, V_MF2, V_M1, V_M2, V_M4, V_M8]; -} +defvar MxList = [V_MF8, V_MF4, V_MF2, V_M1, V_M2, V_M4, V_M8]; +// For floating point which don't need MF8. +defvar MxListF = [V_MF4, V_MF2, V_M1, V_M2, V_M4, V_M8]; + // Used for widening and narrowing instructions as it doesn't contain M8. -def MxListW { - list<LMULInfo> m = [V_MF8, V_MF4, V_MF2, V_M1, V_M2, V_M4]; -} +defvar MxListW = [V_MF8, V_MF4, V_MF2, V_M1, V_M2, V_M4]; +// For floating point which don't need MF8. +defvar MxListFW = [V_MF4, V_MF2, V_M1, V_M2, V_M4]; + // Use for zext/sext.vf2 -def MxListVF2 { - list<LMULInfo> m = [V_MF4, V_MF2, V_M1, V_M2, V_M4, V_M8]; -} +defvar MxListVF2 = [V_MF4, V_MF2, V_M1, V_M2, V_M4, V_M8]; + // Use for zext/sext.vf4 -def MxListVF4 { - list<LMULInfo> m = [V_MF2, V_M1, V_M2, V_M4, V_M8]; -} +defvar MxListVF4 = [V_MF2, V_M1, V_M2, V_M4, V_M8]; + // Use for zext/sext.vf8 -def MxListVF8 { - list<LMULInfo> m = [V_M1, V_M2, V_M4, V_M8]; +defvar MxListVF8 = [V_M1, V_M2, V_M4, V_M8]; + +class MxSet<int eew> { + list<LMULInfo> m = !cond(!eq(eew, 8) : [V_MF8, V_MF4, V_MF2, V_M1, V_M2, V_M4, V_M8], + !eq(eew, 16) : [V_MF4, V_MF2, V_M1, V_M2, V_M4, V_M8], + !eq(eew, 32) : [V_MF2, V_M1, V_M2, V_M4, V_M8], + !eq(eew, 64) : [V_M1, V_M2, V_M4, V_M8]); } -class FPR_Info<RegisterClass regclass, string fx> { +class FPR_Info<RegisterClass regclass, string fx, list<LMULInfo> mxlist> { RegisterClass fprclass = regclass; string FX = fx; + list<LMULInfo> MxList = mxlist; } -def SCALAR_F16 : FPR_Info<FPR16, "F16">; -def SCALAR_F32 : FPR_Info<FPR32, "F32">; -def SCALAR_F64 : FPR_Info<FPR64, "F64">; +def SCALAR_F16 : FPR_Info<FPR16, "F16", MxSet<16>.m>; +def SCALAR_F32 : FPR_Info<FPR32, "F32", MxSet<32>.m>; +def SCALAR_F64 : FPR_Info<FPR64, "F64", MxSet<64>.m>; -def FPList { - list<FPR_Info> fpinfo = [SCALAR_F16, SCALAR_F32, SCALAR_F64]; -} -// Used for widening instructions. It excludes F64. -def FPListW { - list<FPR_Info> fpinfo = [SCALAR_F16, SCALAR_F32]; -} +defvar FPList = [SCALAR_F16, SCALAR_F32, SCALAR_F64]; -class MxSet<int eew> { - list<LMULInfo> m = !cond(!eq(eew, 8) : [V_MF8, V_MF4, V_MF2, V_M1, V_M2, V_M4, V_M8], - !eq(eew, 16) : [V_MF4, V_MF2, V_M1, V_M2, V_M4, V_M8], - !eq(eew, 32) : [V_MF2, V_M1, V_M2, V_M4, V_M8], - !eq(eew, 64) : [V_M1, V_M2, V_M4, V_M8]); -} +// Used for widening instructions. It excludes F64. +defvar FPListW = [SCALAR_F16, SCALAR_F32]; class NFSet<LMULInfo m> { list<int> L = !cond(!eq(m.value, V_M8.value): [], @@ -236,25 +232,25 @@ defset list<VTypeInfo> AllVectors = { defset list<GroupVTypeInfo> GroupFloatVectors = { def VF16M2: GroupVTypeInfo<vfloat16m2_t, vfloat16m1_t, vbool8_t, 16, - VRM2, V_M2, f16, FPR16>; + VRM2, V_M2, f16, FPR16>; def VF16M4: GroupVTypeInfo<vfloat16m4_t, vfloat16m1_t, vbool4_t, 16, - VRM4, V_M4, f16, FPR16>; + VRM4, V_M4, f16, FPR16>; def VF16M8: GroupVTypeInfo<vfloat16m8_t, vfloat16m1_t, vbool2_t, 16, - VRM8, V_M8, f16, FPR16>; + VRM8, V_M8, f16, FPR16>; def VF32M2: GroupVTypeInfo<vfloat32m2_t, vfloat32m1_t, vbool16_t, 32, - VRM2, V_M2, f32, FPR32>; + VRM2, V_M2, f32, FPR32>; def VF32M4: GroupVTypeInfo<vfloat32m4_t, vfloat32m1_t, vbool8_t, 32, - VRM4, V_M4, f32, FPR32>; + VRM4, V_M4, f32, FPR32>; def VF32M8: GroupVTypeInfo<vfloat32m8_t, vfloat32m1_t, vbool4_t, 32, - VRM8, V_M8, f32, FPR32>; + VRM8, V_M8, f32, FPR32>; def VF64M2: GroupVTypeInfo<vfloat64m2_t, vfloat64m1_t, vbool32_t, 64, - VRM2, V_M2, f64, FPR64>; + VRM2, V_M2, f64, FPR64>; def VF64M4: GroupVTypeInfo<vfloat64m4_t, vfloat64m1_t, vbool16_t, 64, - VRM4, V_M4, f64, FPR64>; + VRM4, V_M4, f64, FPR64>; def VF64M8: GroupVTypeInfo<vfloat64m8_t, vfloat64m1_t, vbool8_t, 64, - VRM8, V_M8, f64, FPR64>; + VRM8, V_M8, f64, FPR64>; } } } @@ -423,13 +419,14 @@ def RISCVVPseudosTable : GenericTable { def RISCVVIntrinsicsTable : GenericTable { let FilterClass = "RISCVVIntrinsic"; let CppTypeName = "RISCVVIntrinsicInfo"; - let Fields = ["IntrinsicID", "SplatOperand"]; + let Fields = ["IntrinsicID", "SplatOperand", "VLOperand"]; let PrimaryKey = ["IntrinsicID"]; let PrimaryKeyName = "getRISCVVIntrinsicInfo"; } -class RISCVVLE<bit M, bit Str, bit F, bits<3> S, bits<3> L> { +class RISCVVLE<bit M, bit TU, bit Str, bit F, bits<3> S, bits<3> L> { bits<1> Masked = M; + bits<1> IsTU = TU; bits<1> Strided = Str; bits<1> FF = F; bits<3> Log2SEW = S; @@ -440,8 +437,8 @@ class RISCVVLE<bit M, bit Str, bit F, bits<3> S, bits<3> L> { def RISCVVLETable : GenericTable { let FilterClass = "RISCVVLE"; let CppTypeName = "VLEPseudo"; - let Fields = ["Masked", "Strided", "FF", "Log2SEW", "LMUL", "Pseudo"]; - let PrimaryKey = ["Masked", "Strided", "FF", "Log2SEW", "LMUL"]; + let Fields = ["Masked", "IsTU", "Strided", "FF", "Log2SEW", "LMUL", "Pseudo"]; + let PrimaryKey = ["Masked", "IsTU", "Strided", "FF", "Log2SEW", "LMUL"]; let PrimaryKeyName = "getVLEPseudo"; } @@ -461,8 +458,9 @@ def RISCVVSETable : GenericTable { let PrimaryKeyName = "getVSEPseudo"; } -class RISCVVLX_VSX<bit M, bit O, bits<3> S, bits<3> L, bits<3> IL> { +class RISCVVLX_VSX<bit M, bit TU, bit O, bits<3> S, bits<3> L, bits<3> IL> { bits<1> Masked = M; + bits<1> IsTU = TU; bits<1> Ordered = O; bits<3> Log2SEW = S; bits<3> LMUL = L; @@ -470,15 +468,15 @@ class RISCVVLX_VSX<bit M, bit O, bits<3> S, bits<3> L, bits<3> IL> { Pseudo Pseudo = !cast<Pseudo>(NAME); } -class RISCVVLX<bit M, bit O, bits<3> S, bits<3> L, bits<3> IL> : - RISCVVLX_VSX<M, O, S, L, IL>; +class RISCVVLX<bit M, bit TU, bit O, bits<3> S, bits<3> L, bits<3> IL> : + RISCVVLX_VSX<M, TU, O, S, L, IL>; class RISCVVSX<bit M, bit O, bits<3> S, bits<3> L, bits<3> IL> : - RISCVVLX_VSX<M, O, S, L, IL>; + RISCVVLX_VSX<M, /*TU*/0, O, S, L, IL>; class RISCVVLX_VSXTable : GenericTable { let CppTypeName = "VLX_VSXPseudo"; - let Fields = ["Masked", "Ordered", "Log2SEW", "LMUL", "IndexLMUL", "Pseudo"]; - let PrimaryKey = ["Masked", "Ordered", "Log2SEW", "LMUL", "IndexLMUL"]; + let Fields = ["Masked", "IsTU", "Ordered", "Log2SEW", "LMUL", "IndexLMUL", "Pseudo"]; + let PrimaryKey = ["Masked", "IsTU", "Ordered", "Log2SEW", "LMUL", "IndexLMUL"]; } def RISCVVLXTable : RISCVVLX_VSXTable { @@ -583,10 +581,11 @@ class PseudoToVInst<string PseudoInst> { !subst("_B64", "", !subst("_MASK", "", !subst("_TIED", "", + !subst("_TU", "", !subst("F16", "F", !subst("F32", "F", !subst("F64", "F", - !subst("Pseudo", "", PseudoInst)))))))))))))))))))); + !subst("Pseudo", "", PseudoInst))))))))))))))))))))); } // The destination vector register group for a masked vector instruction cannot @@ -632,7 +631,7 @@ class VPseudoUSLoadNoMask<VReg RetClass, int EEW, bit isFF> : Pseudo<(outs RetClass:$rd), (ins GPR:$rs1, AVL:$vl, ixlenimm:$sew),[]>, RISCVVPseudo, - RISCVVLE</*Masked*/0, /*Strided*/0, /*FF*/isFF, log2<EEW>.val, VLMul> { + RISCVVLE</*Masked*/0, /*TU*/0, /*Strided*/0, /*FF*/isFF, log2<EEW>.val, VLMul> { let mayLoad = 1; let mayStore = 0; let hasSideEffects = 0; @@ -642,13 +641,29 @@ class VPseudoUSLoadNoMask<VReg RetClass, int EEW, bit isFF> : let BaseInstr = !cast<Instruction>(PseudoToVInst<NAME>.VInst); } +class VPseudoUSLoadNoMaskTU<VReg RetClass, int EEW, bit isFF> : + Pseudo<(outs RetClass:$rd), + (ins RetClass:$dest, GPR:$rs1, AVL:$vl, ixlenimm:$sew),[]>, + RISCVVPseudo, + RISCVVLE</*Masked*/0, /*TU*/1, /*Strided*/0, /*FF*/isFF, log2<EEW>.val, VLMul> { + let mayLoad = 1; + let mayStore = 0; + let hasSideEffects = 0; + let HasVLOp = 1; + let HasSEWOp = 1; + let HasDummyMask = 1; + let HasMergeOp = 1; + let Constraints = "$rd = $dest"; + let BaseInstr = !cast<Instruction>(PseudoToVInst<NAME>.VInst); +} + class VPseudoUSLoadMask<VReg RetClass, int EEW, bit isFF> : Pseudo<(outs GetVRegNoV0<RetClass>.R:$rd), (ins GetVRegNoV0<RetClass>.R:$merge, GPR:$rs1, VMaskOp:$vm, AVL:$vl, ixlenimm:$sew, ixlenimm:$policy),[]>, RISCVVPseudo, - RISCVVLE</*Masked*/1, /*Strided*/0, /*FF*/isFF, log2<EEW>.val, VLMul> { + RISCVVLE</*Masked*/1, /*TU*/1, /*Strided*/0, /*FF*/isFF, log2<EEW>.val, VLMul> { let mayLoad = 1; let mayStore = 0; let hasSideEffects = 0; @@ -664,7 +679,7 @@ class VPseudoSLoadNoMask<VReg RetClass, int EEW>: Pseudo<(outs RetClass:$rd), (ins GPR:$rs1, GPR:$rs2, AVL:$vl, ixlenimm:$sew),[]>, RISCVVPseudo, - RISCVVLE</*Masked*/0, /*Strided*/1, /*FF*/0, log2<EEW>.val, VLMul> { + RISCVVLE</*Masked*/0, /*TU*/0, /*Strided*/1, /*FF*/0, log2<EEW>.val, VLMul> { let mayLoad = 1; let mayStore = 0; let hasSideEffects = 0; @@ -674,13 +689,29 @@ class VPseudoSLoadNoMask<VReg RetClass, int EEW>: let BaseInstr = !cast<Instruction>(PseudoToVInst<NAME>.VInst); } +class VPseudoSLoadNoMaskTU<VReg RetClass, int EEW>: + Pseudo<(outs RetClass:$rd), + (ins RetClass:$dest, GPR:$rs1, GPR:$rs2, AVL:$vl, ixlenimm:$sew),[]>, + RISCVVPseudo, + RISCVVLE</*Masked*/0, /*TU*/1, /*Strided*/1, /*FF*/0, log2<EEW>.val, VLMul> { + let mayLoad = 1; + let mayStore = 0; + let hasSideEffects = 0; + let HasVLOp = 1; + let HasSEWOp = 1; + let HasDummyMask = 1; + let HasMergeOp = 1; + let Constraints = "$rd = $dest"; + let BaseInstr = !cast<Instruction>(PseudoToVInst<NAME>.VInst); +} + class VPseudoSLoadMask<VReg RetClass, int EEW>: Pseudo<(outs GetVRegNoV0<RetClass>.R:$rd), (ins GetVRegNoV0<RetClass>.R:$merge, GPR:$rs1, GPR:$rs2, VMaskOp:$vm, AVL:$vl, ixlenimm:$sew, ixlenimm:$policy),[]>, RISCVVPseudo, - RISCVVLE</*Masked*/1, /*Strided*/1, /*FF*/0, log2<EEW>.val, VLMul> { + RISCVVLE</*Masked*/1, /*TU*/1, /*Strided*/1, /*FF*/0, log2<EEW>.val, VLMul> { let mayLoad = 1; let mayStore = 0; let hasSideEffects = 0; @@ -695,9 +726,10 @@ class VPseudoSLoadMask<VReg RetClass, int EEW>: class VPseudoILoadNoMask<VReg RetClass, VReg IdxClass, int EEW, bits<3> LMUL, bit Ordered, bit EarlyClobber>: Pseudo<(outs RetClass:$rd), - (ins GPR:$rs1, IdxClass:$rs2, AVL:$vl, ixlenimm:$sew),[]>, + (ins GPR:$rs1, IdxClass:$rs2, AVL:$vl, + ixlenimm:$sew),[]>, RISCVVPseudo, - RISCVVLX</*Masked*/0, Ordered, log2<EEW>.val, VLMul, LMUL> { + RISCVVLX</*Masked*/0, /*TU*/0, Ordered, log2<EEW>.val, VLMul, LMUL> { let mayLoad = 1; let mayStore = 0; let hasSideEffects = 0; @@ -708,6 +740,24 @@ class VPseudoILoadNoMask<VReg RetClass, VReg IdxClass, int EEW, bits<3> LMUL, let BaseInstr = !cast<Instruction>(PseudoToVInst<NAME>.VInst); } +class VPseudoILoadNoMaskTU<VReg RetClass, VReg IdxClass, int EEW, bits<3> LMUL, + bit Ordered, bit EarlyClobber>: + Pseudo<(outs RetClass:$rd), + (ins RetClass:$dest, GPR:$rs1, IdxClass:$rs2, AVL:$vl, + ixlenimm:$sew),[]>, + RISCVVPseudo, + RISCVVLX</*Masked*/0, /*TU*/1, Ordered, log2<EEW>.val, VLMul, LMUL> { + let mayLoad = 1; + let mayStore = 0; + let hasSideEffects = 0; + let HasVLOp = 1; + let HasSEWOp = 1; + let HasDummyMask = 1; + let HasMergeOp = 1; + let Constraints = !if(!eq(EarlyClobber, 1), "@earlyclobber $rd, $rd = $dest", "$rd = $dest"); + let BaseInstr = !cast<Instruction>(PseudoToVInst<NAME>.VInst); +} + class VPseudoILoadMask<VReg RetClass, VReg IdxClass, int EEW, bits<3> LMUL, bit Ordered, bit EarlyClobber>: Pseudo<(outs GetVRegNoV0<RetClass>.R:$rd), @@ -715,7 +765,7 @@ class VPseudoILoadMask<VReg RetClass, VReg IdxClass, int EEW, bits<3> LMUL, GPR:$rs1, IdxClass:$rs2, VMaskOp:$vm, AVL:$vl, ixlenimm:$sew, ixlenimm:$policy),[]>, RISCVVPseudo, - RISCVVLX</*Masked*/1, Ordered, log2<EEW>.val, VLMul, LMUL> { + RISCVVLX</*Masked*/1, /*TU*/1, Ordered, log2<EEW>.val, VLMul, LMUL> { let mayLoad = 1; let mayStore = 0; let hasSideEffects = 0; @@ -932,6 +982,9 @@ class VPseudoBinaryNoMask<VReg RetClass, let BaseInstr = !cast<Instruction>(PseudoToVInst<NAME>.VInst); } +// Special version of VPseudoBinaryNoMask where we pretend the first source is +// tied to the destination. +// This allows maskedoff and rs2 to be the same register. class VPseudoTiedBinaryNoMask<VReg RetClass, DAGOperand Op2Class, string Constraint> : @@ -1083,6 +1136,30 @@ class VPseudoBinaryCarryIn<VReg RetClass, let VLMul = MInfo.value; } +class VPseudoTiedBinaryCarryIn<VReg RetClass, + VReg Op1Class, + DAGOperand Op2Class, + LMULInfo MInfo, + bit CarryIn, + string Constraint> : + Pseudo<(outs RetClass:$rd), + !if(CarryIn, + (ins RetClass:$merge, Op1Class:$rs2, Op2Class:$rs1, VMV0:$carry, AVL:$vl, + ixlenimm:$sew), + (ins RetClass:$merge, Op1Class:$rs2, Op2Class:$rs1, AVL:$vl, ixlenimm:$sew)), []>, + RISCVVPseudo { + let mayLoad = 0; + let mayStore = 0; + let hasSideEffects = 0; + let Constraints = Join<[Constraint, "$rd = $merge"], ",">.ret; + let HasVLOp = 1; + let HasSEWOp = 1; + let HasMergeOp = 1; + let HasVecPolicyOp = 0; + let BaseInstr = !cast<Instruction>(PseudoToVInst<NAME>.VInst); + let VLMul = MInfo.value; +} + class VPseudoTernaryNoMask<VReg RetClass, RegisterClass Op1Class, DAGOperand Op2Class, @@ -1323,6 +1400,9 @@ multiclass VPseudoUSLoad { def "E" # eew # "_V_" # LInfo : VPseudoUSLoadNoMask<vreg, eew, false>, VLESched<eew>; + def "E" # eew # "_V_" # LInfo # "_TU": + VPseudoUSLoadNoMaskTU<vreg, eew, false>, + VLESched<eew>; def "E" # eew # "_V_" # LInfo # "_MASK" : VPseudoUSLoadMask<vreg, eew, false>, VLESched<eew>; @@ -1340,6 +1420,9 @@ multiclass VPseudoFFLoad { def "E" # eew # "FF_V_" # LInfo : VPseudoUSLoadNoMask<vreg, eew, true>, VLFSched<eew>; + def "E" # eew # "FF_V_" # LInfo # "_TU": + VPseudoUSLoadNoMaskTU<vreg, eew, true>, + VLFSched<eew>; def "E" # eew # "FF_V_" # LInfo # "_MASK" : VPseudoUSLoadMask<vreg, eew, true>, VLFSched<eew>; @@ -1364,6 +1447,8 @@ multiclass VPseudoSLoad { let VLMul = lmul.value in { def "E" # eew # "_V_" # LInfo : VPseudoSLoadNoMask<vreg, eew>, VLSSched<eew>; + def "E" # eew # "_V_" # LInfo # "_TU": VPseudoSLoadNoMaskTU<vreg, eew>, + VLSSched<eew>; def "E" # eew # "_V_" # LInfo # "_MASK" : VPseudoSLoadMask<vreg, eew>, VLSSched<eew>; } @@ -1390,6 +1475,9 @@ multiclass VPseudoILoad<bit Ordered> { def "EI" # eew # "_V_" # IdxLInfo # "_" # LInfo : VPseudoILoadNoMask<Vreg, IdxVreg, eew, idx_lmul.value, Ordered, HasConstraint>, VLXSched<eew, Order>; + def "EI" # eew # "_V_" # IdxLInfo # "_" # LInfo # "_TU": + VPseudoILoadNoMaskTU<Vreg, IdxVreg, eew, idx_lmul.value, Ordered, HasConstraint>, + VLXSched<eew, Order>; def "EI" # eew # "_V_" # IdxLInfo # "_" # LInfo # "_MASK" : VPseudoILoadMask<Vreg, IdxVreg, eew, idx_lmul.value, Ordered, HasConstraint>, VLXSched<eew, Order>; @@ -1504,7 +1592,7 @@ multiclass VPseudoVSFS_M { } multiclass VPseudoVID_V { - foreach m = MxList.m in { + foreach m = MxList in { let VLMul = m.value in { def "_V_" # m.MX : VPseudoNullaryNoMask<m.vrclass>, Sched<[WriteVMIdxV, ReadVMask]>; @@ -1524,7 +1612,7 @@ multiclass VPseudoNullaryPseudoM <string BaseInst> { multiclass VPseudoVIOT_M { defvar constraint = "@earlyclobber $rd"; - foreach m = MxList.m in { + foreach m = MxList in { let VLMul = m.value in { def "_" # m.MX : VPseudoUnaryNoMask<m.vrclass, VR, constraint>, Sched<[WriteVMIotV, ReadVMIotV, ReadVMask]>; @@ -1535,7 +1623,7 @@ multiclass VPseudoVIOT_M { } multiclass VPseudoVCPR_V { - foreach m = MxList.m in { + foreach m = MxList in { let VLMul = m.value in def _VM # "_" # m.MX : VPseudoUnaryAnyMask<m.vrclass, m.vrclass>, Sched<[WriteVCompressV, ReadVCompressV, ReadVCompressV]>; @@ -1596,12 +1684,18 @@ multiclass VPseudoTiedBinary<VReg RetClass, } multiclass VPseudoBinaryV_VV<string Constraint = ""> { - foreach m = MxList.m in + foreach m = MxList in + defm _VV : VPseudoBinary<m.vrclass, m.vrclass, m.vrclass, m, Constraint>; +} + +// Similar to VPseudoBinaryV_VV, but uses MxListF. +multiclass VPseudoBinaryFV_VV<string Constraint = ""> { + foreach m = MxListF in defm _VV : VPseudoBinary<m.vrclass, m.vrclass, m.vrclass, m, Constraint>; } multiclass VPseudoVGTR_VV_EEW<int eew, string Constraint = ""> { - foreach m = MxList.m in { + foreach m = MxList in { foreach sew = EEWList in { defvar octuple_lmul = m.octuple; // emul = lmul * eew / sew @@ -1617,38 +1711,38 @@ multiclass VPseudoVGTR_VV_EEW<int eew, string Constraint = ""> { } multiclass VPseudoBinaryV_VX<string Constraint = ""> { - foreach m = MxList.m in + foreach m = MxList in defm "_VX" : VPseudoBinary<m.vrclass, m.vrclass, GPR, m, Constraint>; } multiclass VPseudoVSLD1_VX<string Constraint = ""> { - foreach m = MxList.m in + foreach m = MxList in defm "_VX" : VPseudoBinary<m.vrclass, m.vrclass, GPR, m, Constraint>, Sched<[WriteVISlide1X, ReadVISlideV, ReadVISlideX, ReadVMask]>; } multiclass VPseudoBinaryV_VF<string Constraint = ""> { - foreach m = MxList.m in - foreach f = FPList.fpinfo in + foreach f = FPList in + foreach m = f.MxList in defm "_V" # f.FX : VPseudoBinary<m.vrclass, m.vrclass, f.fprclass, m, Constraint>; } multiclass VPseudoVSLD1_VF<string Constraint = ""> { - foreach m = MxList.m in - foreach f = FPList.fpinfo in + foreach f = FPList in + foreach m = f.MxList in defm "_V" # f.FX : VPseudoBinary<m.vrclass, m.vrclass, f.fprclass, m, Constraint>, Sched<[WriteVFSlide1F, ReadVFSlideV, ReadVFSlideF, ReadVMask]>; } multiclass VPseudoBinaryV_VI<Operand ImmType = simm5, string Constraint = ""> { - foreach m = MxList.m in + foreach m = MxList in defm _VI : VPseudoBinary<m.vrclass, m.vrclass, ImmType, m, Constraint>; } multiclass VPseudoVALU_MM { - foreach m = MxList.m in + foreach m = MxList in let VLMul = m.value in { def "_MM_" # m.MX : VPseudoBinaryNoMask<VR, VR, VR, "">, Sched<[WriteVMALUV, ReadVMALUV, ReadVMALUV]>; @@ -1662,28 +1756,28 @@ multiclass VPseudoVALU_MM { // * The destination EEW is greater than the source EEW, the source EMUL is // at least 1, and the overlap is in the highest-numbered part of the // destination register group is legal. Otherwise, it is illegal. -multiclass VPseudoBinaryW_VV { - foreach m = MxListW.m in +multiclass VPseudoBinaryW_VV<list<LMULInfo> mxlist = MxListW> { + foreach m = mxlist in defm _VV : VPseudoBinary<m.wvrclass, m.vrclass, m.vrclass, m, "@earlyclobber $rd">; } multiclass VPseudoBinaryW_VX { - foreach m = MxListW.m in + foreach m = MxListW in defm "_VX" : VPseudoBinary<m.wvrclass, m.vrclass, GPR, m, "@earlyclobber $rd">; } multiclass VPseudoBinaryW_VF { - foreach m = MxListW.m in - foreach f = FPListW.fpinfo in + foreach f = FPListW in + foreach m = f.MxList in defm "_V" # f.FX : VPseudoBinary<m.wvrclass, m.vrclass, f.fprclass, m, "@earlyclobber $rd">; } -multiclass VPseudoBinaryW_WV { - foreach m = MxListW.m in { +multiclass VPseudoBinaryW_WV<list<LMULInfo> mxlist = MxListW> { + foreach m = mxlist in { defm _WV : VPseudoBinary<m.wvrclass, m.wvrclass, m.vrclass, m, "@earlyclobber $rd">; defm _WV : VPseudoTiedBinary<m.wvrclass, m.vrclass, m, @@ -1692,13 +1786,13 @@ multiclass VPseudoBinaryW_WV { } multiclass VPseudoBinaryW_WX { - foreach m = MxListW.m in + foreach m = MxListW in defm "_WX" : VPseudoBinary<m.wvrclass, m.wvrclass, GPR, m>; } multiclass VPseudoBinaryW_WF { - foreach m = MxListW.m in - foreach f = FPListW.fpinfo in + foreach f = FPListW in + foreach m = f.MxList in defm "_W" # f.FX : VPseudoBinary<m.wvrclass, m.wvrclass, f.fprclass, m>; } @@ -1709,19 +1803,19 @@ multiclass VPseudoBinaryW_WF { // "The destination EEW is smaller than the source EEW and the overlap is in the // lowest-numbered part of the source register group." multiclass VPseudoBinaryV_WV { - foreach m = MxListW.m in + foreach m = MxListW in defm _WV : VPseudoBinary<m.vrclass, m.wvrclass, m.vrclass, m, !if(!ge(m.octuple, 8), "@earlyclobber $rd", "")>; } multiclass VPseudoBinaryV_WX { - foreach m = MxListW.m in + foreach m = MxListW in defm _WX : VPseudoBinary<m.vrclass, m.wvrclass, GPR, m, !if(!ge(m.octuple, 8), "@earlyclobber $rd", "")>; } multiclass VPseudoBinaryV_WI { - foreach m = MxListW.m in + foreach m = MxListW in defm _WI : VPseudoBinary<m.vrclass, m.wvrclass, uimm5, m, !if(!ge(m.octuple, 8), "@earlyclobber $rd", "")>; } @@ -1731,7 +1825,7 @@ multiclass VPseudoBinaryV_WI { // For vadc and vsbc, CarryIn == 1 and CarryOut == 0 multiclass VPseudoBinaryV_VM<bit CarryOut = 0, bit CarryIn = 1, string Constraint = ""> { - foreach m = MxList.m in + foreach m = MxList in def "_VV" # !if(CarryIn, "M", "") # "_" # m.MX : VPseudoBinaryCarryIn<!if(CarryOut, VR, !if(!and(CarryIn, !not(CarryOut)), @@ -1739,9 +1833,19 @@ multiclass VPseudoBinaryV_VM<bit CarryOut = 0, bit CarryIn = 1, m.vrclass, m.vrclass, m, CarryIn, Constraint>; } +multiclass VPseudoTiedBinaryV_VM<bit CarryOut = 0, bit CarryIn = 1, + string Constraint = ""> { + foreach m = MxList in + def "_VV" # !if(CarryIn, "M", "") # "_" # m.MX # "_TU" : + VPseudoTiedBinaryCarryIn<!if(CarryOut, VR, + !if(!and(CarryIn, !not(CarryOut)), + GetVRegNoV0<m.vrclass>.R, m.vrclass)), + m.vrclass, m.vrclass, m, CarryIn, Constraint>; +} + multiclass VPseudoBinaryV_XM<bit CarryOut = 0, bit CarryIn = 1, string Constraint = ""> { - foreach m = MxList.m in + foreach m = MxList in def "_VX" # !if(CarryIn, "M", "") # "_" # m.MX : VPseudoBinaryCarryIn<!if(CarryOut, VR, !if(!and(CarryIn, !not(CarryOut)), @@ -1749,18 +1853,34 @@ multiclass VPseudoBinaryV_XM<bit CarryOut = 0, bit CarryIn = 1, m.vrclass, GPR, m, CarryIn, Constraint>; } +multiclass VPseudoTiedBinaryV_XM<bit CarryOut = 0, bit CarryIn = 1, + string Constraint = ""> { + foreach m = MxList in + def "_VX" # !if(CarryIn, "M", "") # "_" # m.MX # "_TU": + VPseudoTiedBinaryCarryIn<!if(CarryOut, VR, + !if(!and(CarryIn, !not(CarryOut)), + GetVRegNoV0<m.vrclass>.R, m.vrclass)), + m.vrclass, GPR, m, CarryIn, Constraint>; +} + multiclass VPseudoVMRG_FM { - foreach m = MxList.m in - foreach f = FPList.fpinfo in + foreach f = FPList in + foreach m = f.MxList in { def "_V" # f.FX # "M_" # m.MX : VPseudoBinaryCarryIn<GetVRegNoV0<m.vrclass>.R, m.vrclass, f.fprclass, m, /*CarryIn=*/1, "">, Sched<[WriteVFMergeV, ReadVFMergeV, ReadVFMergeF, ReadVMask]>; + // Tied version to allow codegen control over the tail elements + def "_V" # f.FX # "M_" # m.MX # "_TU": + VPseudoTiedBinaryCarryIn<GetVRegNoV0<m.vrclass>.R, + m.vrclass, f.fprclass, m, /*CarryIn=*/1, "">, + Sched<[WriteVFMergeV, ReadVFMergeV, ReadVFMergeF, ReadVMask]>; + } } multiclass VPseudoBinaryV_IM<bit CarryOut = 0, bit CarryIn = 1, string Constraint = ""> { - foreach m = MxList.m in + foreach m = MxList in def "_VI" # !if(CarryIn, "M", "") # "_" # m.MX : VPseudoBinaryCarryIn<!if(CarryOut, VR, !if(!and(CarryIn, !not(CarryOut)), @@ -1768,8 +1888,18 @@ multiclass VPseudoBinaryV_IM<bit CarryOut = 0, bit CarryIn = 1, m.vrclass, simm5, m, CarryIn, Constraint>; } +multiclass VPseudoTiedBinaryV_IM<bit CarryOut = 0, bit CarryIn = 1, + string Constraint = ""> { + foreach m = MxList in + def "_VI" # !if(CarryIn, "M", "") # "_" # m.MX # "_TU": + VPseudoTiedBinaryCarryIn<!if(CarryOut, VR, + !if(!and(CarryIn, !not(CarryOut)), + GetVRegNoV0<m.vrclass>.R, m.vrclass)), + m.vrclass, simm5, m, CarryIn, Constraint>; +} + multiclass VPseudoUnaryVMV_V_X_I { - foreach m = MxList.m in { + foreach m = MxList in { let VLMul = m.value in { def "_V_" # m.MX : VPseudoUnaryNoDummyMask<m.vrclass, m.vrclass>, Sched<[WriteVIMovV, ReadVIMovV]>; @@ -1782,8 +1912,8 @@ multiclass VPseudoUnaryVMV_V_X_I { } multiclass VPseudoVMV_F { - foreach m = MxList.m in { - foreach f = FPList.fpinfo in { + foreach f = FPList in { + foreach m = f.MxList in { let VLMul = m.value in { def "_" # f.FX # "_" # m.MX : VPseudoUnaryNoDummyMask<m.vrclass, f.fprclass>, @@ -1794,7 +1924,7 @@ multiclass VPseudoVMV_F { } multiclass VPseudoVCLS_V { - foreach m = MxList.m in { + foreach m = MxListF in { let VLMul = m.value in { def "_V_" # m.MX : VPseudoUnaryNoMask<m.vrclass, m.vrclass>, Sched<[WriteVFClassV, ReadVFClassV, ReadVMask]>; @@ -1805,7 +1935,7 @@ multiclass VPseudoVCLS_V { } multiclass VPseudoVSQR_V { - foreach m = MxList.m in { + foreach m = MxListF in { let VLMul = m.value in { def "_V_" # m.MX : VPseudoUnaryNoMask<m.vrclass, m.vrclass>, Sched<[WriteVFSqrtV, ReadVFSqrtV, ReadVMask]>; @@ -1816,7 +1946,7 @@ multiclass VPseudoVSQR_V { } multiclass VPseudoVRCP_V { - foreach m = MxList.m in { + foreach m = MxListF in { let VLMul = m.value in { def "_V_" # m.MX : VPseudoUnaryNoMask<m.vrclass, m.vrclass>, Sched<[WriteVFRecpV, ReadVFRecpV, ReadVMask]>; @@ -1828,7 +1958,7 @@ multiclass VPseudoVRCP_V { multiclass PseudoVEXT_VF2 { defvar constraints = "@earlyclobber $rd"; - foreach m = MxListVF2.m in + foreach m = MxListVF2 in { let VLMul = m.value in { def "_" # m.MX : VPseudoUnaryNoMask<m.vrclass, m.f2vrclass, constraints>, @@ -1842,7 +1972,7 @@ multiclass PseudoVEXT_VF2 { multiclass PseudoVEXT_VF4 { defvar constraints = "@earlyclobber $rd"; - foreach m = MxListVF4.m in + foreach m = MxListVF4 in { let VLMul = m.value in { def "_" # m.MX : VPseudoUnaryNoMask<m.vrclass, m.f4vrclass, constraints>, @@ -1856,7 +1986,7 @@ multiclass PseudoVEXT_VF4 { multiclass PseudoVEXT_VF8 { defvar constraints = "@earlyclobber $rd"; - foreach m = MxListVF8.m in + foreach m = MxListVF8 in { let VLMul = m.value in { def "_" # m.MX : VPseudoUnaryNoMask<m.vrclass, m.f8vrclass, constraints>, @@ -1879,29 +2009,29 @@ multiclass PseudoVEXT_VF8 { // lowest-numbered part of the source register group". // With LMUL<=1 the source and dest occupy a single register so any overlap // is in the lowest-numbered part. -multiclass VPseudoBinaryM_VV { - foreach m = MxList.m in +multiclass VPseudoBinaryM_VV<list<LMULInfo> mxlist = MxList> { + foreach m = mxlist in defm _VV : VPseudoBinaryM<VR, m.vrclass, m.vrclass, m, !if(!ge(m.octuple, 16), "@earlyclobber $rd", "")>; } multiclass VPseudoBinaryM_VX { - foreach m = MxList.m in + foreach m = MxList in defm "_VX" : VPseudoBinaryM<VR, m.vrclass, GPR, m, !if(!ge(m.octuple, 16), "@earlyclobber $rd", "")>; } multiclass VPseudoBinaryM_VF { - foreach m = MxList.m in - foreach f = FPList.fpinfo in + foreach f = FPList in + foreach m = f.MxList in defm "_V" # f.FX : VPseudoBinaryM<VR, m.vrclass, f.fprclass, m, !if(!ge(m.octuple, 16), "@earlyclobber $rd", "")>; } multiclass VPseudoBinaryM_VI { - foreach m = MxList.m in + foreach m = MxList in defm _VI : VPseudoBinaryM<VR, m.vrclass, simm5, m, !if(!ge(m.octuple, 16), "@earlyclobber $rd", "")>; } @@ -1995,14 +2125,14 @@ multiclass VPseudoVDIV_VV_VX { } multiclass VPseudoVFMUL_VV_VF { - defm "" : VPseudoBinaryV_VV, + defm "" : VPseudoBinaryFV_VV, Sched<[WriteVFMulV, ReadVFMulV, ReadVFMulV, ReadVMask]>; defm "" : VPseudoBinaryV_VF, Sched<[WriteVFMulF, ReadVFMulV, ReadVFMulF, ReadVMask]>; } multiclass VPseudoVFDIV_VV_VF { - defm "" : VPseudoBinaryV_VV, + defm "" : VPseudoBinaryFV_VV, Sched<[WriteVFDivV, ReadVFDivV, ReadVFDivV, ReadVMask]>; defm "" : VPseudoBinaryV_VF, Sched<[WriteVFDivF, ReadVFDivV, ReadVFDivF, ReadVMask]>; @@ -2021,21 +2151,21 @@ multiclass VPseudoVALU_VV_VX { } multiclass VPseudoVSGNJ_VV_VF { - defm "" : VPseudoBinaryV_VV, + defm "" : VPseudoBinaryFV_VV, Sched<[WriteVFSgnjV, ReadVFSgnjV, ReadVFSgnjV, ReadVMask]>; defm "" : VPseudoBinaryV_VF, Sched<[WriteVFSgnjF, ReadVFSgnjV, ReadVFSgnjF, ReadVMask]>; } multiclass VPseudoVMAX_VV_VF { - defm "" : VPseudoBinaryV_VV, + defm "" : VPseudoBinaryFV_VV, Sched<[WriteVFCmpV, ReadVFCmpV, ReadVFCmpV, ReadVMask]>; defm "" : VPseudoBinaryV_VF, Sched<[WriteVFCmpF, ReadVFCmpV, ReadVFCmpF, ReadVMask]>; } multiclass VPseudoVALU_VV_VF { - defm "" : VPseudoBinaryV_VV, + defm "" : VPseudoBinaryFV_VV, Sched<[WriteVFALUV, ReadVFALUV, ReadVFALUV, ReadVMask]>; defm "" : VPseudoBinaryV_VF, Sched<[WriteVFALUF, ReadVFALUV, ReadVFALUF, ReadVMask]>; @@ -2068,17 +2198,12 @@ multiclass VPseudoVWMUL_VV_VX { } multiclass VPseudoVWMUL_VV_VF { - defm "" : VPseudoBinaryW_VV, + defm "" : VPseudoBinaryW_VV<MxListFW>, Sched<[WriteVFWMulV, ReadVFWMulV, ReadVFWMulV, ReadVMask]>; defm "" : VPseudoBinaryW_VF, Sched<[WriteVFWMulF, ReadVFWMulV, ReadVFWMulF, ReadVMask]>; } -multiclass VPseudoBinaryW_VV_VF { - defm "" : VPseudoBinaryW_VV; - defm "" : VPseudoBinaryW_VF; -} - multiclass VPseudoVWALU_WV_WX { defm "" : VPseudoBinaryW_WV, Sched<[WriteVIWALUV, ReadVIWALUV, ReadVIWALUV, ReadVMask]>; @@ -2087,14 +2212,14 @@ multiclass VPseudoVWALU_WV_WX { } multiclass VPseudoVFWALU_VV_VF { - defm "" : VPseudoBinaryW_VV, + defm "" : VPseudoBinaryW_VV<MxListFW>, Sched<[WriteVFWALUV, ReadVFWALUV, ReadVFWALUV, ReadVMask]>; defm "" : VPseudoBinaryW_VF, Sched<[WriteVFWALUF, ReadVFWALUV, ReadVFWALUF, ReadVMask]>; } multiclass VPseudoVFWALU_WV_WF { - defm "" : VPseudoBinaryW_WV, + defm "" : VPseudoBinaryW_WV<MxListFW>, Sched<[WriteVFWALUV, ReadVFWALUV, ReadVFWALUV, ReadVMask]>; defm "" : VPseudoBinaryW_WF, Sched<[WriteVFWALUF, ReadVFWALUV, ReadVFWALUF, ReadVMask]>; @@ -2107,6 +2232,13 @@ multiclass VPseudoVMRG_VM_XM_IM { Sched<[WriteVIMergeX, ReadVIMergeV, ReadVIMergeX, ReadVMask]>; defm "" : VPseudoBinaryV_IM, Sched<[WriteVIMergeI, ReadVIMergeV, ReadVMask]>; + // Tied versions to allow codegen control over the tail elements + defm "" : VPseudoTiedBinaryV_VM, + Sched<[WriteVIMergeV, ReadVIMergeV, ReadVIMergeV, ReadVMask]>; + defm "" : VPseudoTiedBinaryV_XM, + Sched<[WriteVIMergeX, ReadVIMergeV, ReadVIMergeX, ReadVMask]>; + defm "" : VPseudoTiedBinaryV_IM, + Sched<[WriteVIMergeI, ReadVIMergeV, ReadVMask]>; } multiclass VPseudoVCALU_VM_XM_IM { @@ -2199,56 +2331,57 @@ multiclass VPseudoTernaryWithPolicy<VReg RetClass, } } -multiclass VPseudoTernaryV_VV_AAXA<string Constraint = ""> { - foreach m = MxList.m in { +multiclass VPseudoTernaryV_VV_AAXA<string Constraint = "", + list<LMULInfo> mxlist = MxList> { + foreach m = mxlist in { defm _VV : VPseudoTernaryWithPolicy<m.vrclass, m.vrclass, m.vrclass, m, Constraint, /*Commutable*/1>; } } multiclass VPseudoTernaryV_VX<string Constraint = ""> { - foreach m = MxList.m in + foreach m = MxList in defm _VX : VPseudoTernary<m.vrclass, m.vrclass, GPR, m, Constraint>; } multiclass VPseudoTernaryV_VX_AAXA<string Constraint = ""> { - foreach m = MxList.m in + foreach m = MxList in defm "_VX" : VPseudoTernaryWithPolicy<m.vrclass, GPR, m.vrclass, m, Constraint, /*Commutable*/1>; } multiclass VPseudoTernaryV_VF_AAXA<string Constraint = ""> { - foreach m = MxList.m in - foreach f = FPList.fpinfo in + foreach f = FPList in + foreach m = f.MxList in defm "_V" # f.FX : VPseudoTernaryWithPolicy<m.vrclass, f.fprclass, m.vrclass, m, Constraint, /*Commutable*/1>; } -multiclass VPseudoTernaryW_VV { +multiclass VPseudoTernaryW_VV<list<LMULInfo> mxlist = MxListW> { defvar constraint = "@earlyclobber $rd"; - foreach m = MxListW.m in + foreach m = mxlist in defm _VV : VPseudoTernaryWithPolicy<m.wvrclass, m.vrclass, m.vrclass, m, constraint>; } multiclass VPseudoTernaryW_VX { defvar constraint = "@earlyclobber $rd"; - foreach m = MxListW.m in + foreach m = MxListW in defm "_VX" : VPseudoTernaryWithPolicy<m.wvrclass, GPR, m.vrclass, m, constraint>; } multiclass VPseudoTernaryW_VF { defvar constraint = "@earlyclobber $rd"; - foreach m = MxListW.m in - foreach f = FPListW.fpinfo in + foreach f = FPListW in + foreach m = f.MxList in defm "_V" # f.FX : VPseudoTernaryWithPolicy<m.wvrclass, f.fprclass, m.vrclass, m, constraint>; } multiclass VPseudoTernaryV_VI<Operand ImmType = simm5, string Constraint = ""> { - foreach m = MxList.m in + foreach m = MxList in defm _VI : VPseudoTernary<m.vrclass, m.vrclass, ImmType, m, Constraint>; } @@ -2260,7 +2393,7 @@ multiclass VPseudoVMAC_VV_VX_AAXA<string Constraint = ""> { } multiclass VPseudoVMAC_VV_VF_AAXA<string Constraint = ""> { - defm "" : VPseudoTernaryV_VV_AAXA<Constraint>, + defm "" : VPseudoTernaryV_VV_AAXA<Constraint, MxListF>, Sched<[WriteVFMulAddV, ReadVFMulAddV, ReadVFMulAddV, ReadVFMulAddV, ReadVMask]>; defm "" : VPseudoTernaryV_VF_AAXA<Constraint>, Sched<[WriteVFMulAddF, ReadVFMulAddV, ReadVFMulAddV, ReadVFMulAddF, ReadVMask]>; @@ -2286,7 +2419,7 @@ multiclass VPseudoVWMAC_VX { } multiclass VPseudoVWMAC_VV_VF { - defm "" : VPseudoTernaryW_VV, + defm "" : VPseudoTernaryW_VV<MxListFW>, Sched<[WriteVFWMulAddV, ReadVFWMulAddV, ReadVFWMulAddV, ReadVFWMulAddV, ReadVMask]>; defm "" : VPseudoTernaryW_VF, Sched<[WriteVFWMulAddF, ReadVFWMulAddV, ReadVFWMulAddV, ReadVFWMulAddF, ReadVMask]>; @@ -2309,7 +2442,7 @@ multiclass VPseudoVCMPM_VV_VX { } multiclass VPseudoVCMPM_VV_VF { - defm "" : VPseudoBinaryM_VV, + defm "" : VPseudoBinaryM_VV<MxListF>, Sched<[WriteVFCmpV, ReadVFCmpV, ReadVFCmpV, ReadVMask]>; defm "" : VPseudoBinaryM_VF, Sched<[WriteVFCmpF, ReadVFCmpV, ReadVFCmpF, ReadVMask]>; @@ -2328,35 +2461,35 @@ multiclass VPseudoVCMPM_VX_VI { } multiclass VPseudoVRED_VS { - foreach m = MxList.m in { + foreach m = MxList in { defm _VS : VPseudoTernary<V_M1.vrclass, m.vrclass, V_M1.vrclass, m>, Sched<[WriteVIRedV, ReadVIRedV, ReadVIRedV, ReadVIRedV, ReadVMask]>; } } multiclass VPseudoVWRED_VS { - foreach m = MxList.m in { + foreach m = MxList in { defm _VS : VPseudoTernary<V_M1.vrclass, m.vrclass, V_M1.vrclass, m>, Sched<[WriteVIWRedV, ReadVIWRedV, ReadVIWRedV, ReadVIWRedV, ReadVMask]>; } } multiclass VPseudoVFRED_VS { - foreach m = MxList.m in { + foreach m = MxListF in { defm _VS : VPseudoTernary<V_M1.vrclass, m.vrclass, V_M1.vrclass, m>, Sched<[WriteVFRedV, ReadVFRedV, ReadVFRedV, ReadVFRedV, ReadVMask]>; } } multiclass VPseudoVFREDO_VS { - foreach m = MxList.m in { + foreach m = MxListF in { defm _VS : VPseudoTernary<V_M1.vrclass, m.vrclass, V_M1.vrclass, m>, Sched<[WriteVFRedOV, ReadVFRedOV, ReadVFRedOV, ReadVFRedOV, ReadVMask]>; } } multiclass VPseudoVFWRED_VS { - foreach m = MxList.m in { + foreach m = MxListF in { defm _VS : VPseudoTernary<V_M1.vrclass, m.vrclass, V_M1.vrclass, m>, Sched<[WriteVFWRedV, ReadVFWRedV, ReadVFWRedV, ReadVFWRedV, ReadVMask]>; } @@ -2374,61 +2507,61 @@ multiclass VPseudoConversion<VReg RetClass, } multiclass VPseudoVCVTI_V { - foreach m = MxList.m in + foreach m = MxListF in defm _V : VPseudoConversion<m.vrclass, m.vrclass, m>, Sched<[WriteVFCvtFToIV, ReadVFCvtFToIV, ReadVMask]>; } multiclass VPseudoVCVTF_V { - foreach m = MxList.m in + foreach m = MxListF in defm _V : VPseudoConversion<m.vrclass, m.vrclass, m>, Sched<[WriteVFCvtIToFV, ReadVFCvtIToFV, ReadVMask]>; } multiclass VPseudoConversionW_V { defvar constraint = "@earlyclobber $rd"; - foreach m = MxListW.m in + foreach m = MxListW in defm _V : VPseudoConversion<m.wvrclass, m.vrclass, m, constraint>; } multiclass VPseudoVWCVTI_V { defvar constraint = "@earlyclobber $rd"; - foreach m = MxList.m[0-5] in + foreach m = MxListFW in defm _V : VPseudoConversion<m.wvrclass, m.vrclass, m, constraint>, Sched<[WriteVFWCvtFToIV, ReadVFWCvtFToIV, ReadVMask]>; } multiclass VPseudoVWCVTF_V { defvar constraint = "@earlyclobber $rd"; - foreach m = MxList.m[0-5] in + foreach m = MxListW in defm _V : VPseudoConversion<m.wvrclass, m.vrclass, m, constraint>, Sched<[WriteVFWCvtIToFV, ReadVFWCvtIToFV, ReadVMask]>; } multiclass VPseudoVWCVTD_V { defvar constraint = "@earlyclobber $rd"; - foreach m = MxList.m[0-5] in + foreach m = MxListFW in defm _V : VPseudoConversion<m.wvrclass, m.vrclass, m, constraint>, Sched<[WriteVFWCvtFToFV, ReadVFWCvtFToFV, ReadVMask]>; } multiclass VPseudoVNCVTI_W { defvar constraint = "@earlyclobber $rd"; - foreach m = MxList.m[0-5] in + foreach m = MxListW in defm _W : VPseudoConversion<m.vrclass, m.wvrclass, m, constraint>, Sched<[WriteVFNCvtFToIV, ReadVFNCvtFToIV, ReadVMask]>; } multiclass VPseudoVNCVTF_W { defvar constraint = "@earlyclobber $rd"; - foreach m = MxList.m[0-5] in + foreach m = MxListFW in defm _W : VPseudoConversion<m.vrclass, m.wvrclass, m, constraint>, Sched<[WriteVFNCvtIToFV, ReadVFNCvtIToFV, ReadVMask]>; } multiclass VPseudoVNCVTD_W { defvar constraint = "@earlyclobber $rd"; - foreach m = MxListW.m in + foreach m = MxListFW in defm _W : VPseudoConversion<m.vrclass, m.wvrclass, m, constraint>, Sched<[WriteVFNCvtFToFV, ReadVFNCvtFToFV, ReadVMask]>; } @@ -3702,6 +3835,28 @@ multiclass VPatConversionVF_WF <string intrinsic, string instruction> { } } +multiclass VPatCompare_VI<string intrinsic, string inst, + ImmLeaf ImmType = simm5_plus1> { + foreach vti = AllIntegerVectors in { + defvar Intr = !cast<Intrinsic>(intrinsic); + defvar Pseudo = !cast<Instruction>(inst#"_VI_"#vti.LMul.MX); + def : Pat<(vti.Mask (Intr (vti.Vector vti.RegClass:$rs1), + (vti.Scalar ImmType:$rs2), + VLOpFrag)), + (Pseudo vti.RegClass:$rs1, (DecImm ImmType:$rs2), + GPR:$vl, vti.Log2SEW)>; + defvar IntrMask = !cast<Intrinsic>(intrinsic # "_mask"); + defvar PseudoMask = !cast<Instruction>(inst#"_VI_"#vti.LMul.MX#"_MASK"); + def : Pat<(vti.Mask (IntrMask (vti.Mask VR:$merge), + (vti.Vector vti.RegClass:$rs1), + (vti.Scalar ImmType:$rs2), + (vti.Mask V0), + VLOpFrag)), + (PseudoMask VR:$merge, vti.RegClass:$rs1, (DecImm ImmType:$rs2), + (vti.Mask V0), GPR:$vl, vti.Log2SEW)>; + } +} + //===----------------------------------------------------------------------===// // Pseudo instructions //===----------------------------------------------------------------------===// @@ -3741,7 +3896,7 @@ let hasSideEffects = 0, mayLoad = 1, mayStore = 0, isCodeGenOnly = 1 in { def PseudoVRELOAD_M8 : VPseudo<VL8RE8_V, V_M8, (outs VRM8:$rs1), (ins GPR:$rs2)>; } -foreach lmul = MxList.m in { +foreach lmul = MxList in { foreach nf = NFSet<lmul>.L in { defvar vreg = SegRegClass<lmul, nf>.RC; let hasSideEffects = 0, mayLoad = 0, mayStore = 1, isCodeGenOnly = 1 in { @@ -3765,9 +3920,9 @@ let hasSideEffects = 1, mayLoad = 0, mayStore = 0, Defs = [VL, VTYPE] in { // the when we aren't using one of the special X0 encodings. Otherwise it could // be accidentally be made X0 by MachineIR optimizations. To satisfy the // verifier, we also need a GPRX0 instruction for the special encodings. -def PseudoVSETVLI : Pseudo<(outs GPR:$rd), (ins GPRNoX0:$rs1, VTypeIOp:$vtypei), []>; -def PseudoVSETVLIX0 : Pseudo<(outs GPR:$rd), (ins GPRX0:$rs1, VTypeIOp:$vtypei), []>; -def PseudoVSETIVLI : Pseudo<(outs GPR:$rd), (ins uimm5:$rs1, VTypeIOp:$vtypei), []>; +def PseudoVSETVLI : Pseudo<(outs GPR:$rd), (ins GPRNoX0:$rs1, VTypeIOp11:$vtypei), []>; +def PseudoVSETVLIX0 : Pseudo<(outs GPR:$rd), (ins GPRX0:$rs1, VTypeIOp11:$vtypei), []>; +def PseudoVSETIVLI : Pseudo<(outs GPR:$rd), (ins uimm5:$rs1, VTypeIOp10:$vtypei), []>; } //===----------------------------------------------------------------------===// @@ -4304,7 +4459,7 @@ defm PseudoVID : VPseudoVID_V; let Predicates = [HasVInstructions] in { let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in { - foreach m = MxList.m in { + foreach m = MxList in { let VLMul = m.value in { let HasSEWOp = 1, BaseInstr = VMV_X_S in def PseudoVMV_X_S # "_" # m.MX: @@ -4330,8 +4485,8 @@ let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in { let Predicates = [HasVInstructionsAnyF] in { let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in { - foreach m = MxList.m in { - foreach f = FPList.fpinfo in { + foreach f = FPList in { + foreach m = f.MxList in { let VLMul = m.value in { let HasSEWOp = 1, BaseInstr = VFMV_F_S in def "PseudoVFMV_" # f.FX # "_S_" # m.MX : @@ -4452,6 +4607,30 @@ defm : VPatBinaryV_VV_VX_VI<"int_riscv_vsrl", "PseudoVSRL", AllIntegerVectors, defm : VPatBinaryV_VV_VX_VI<"int_riscv_vsra", "PseudoVSRA", AllIntegerVectors, uimm5>; +foreach vti = AllIntegerVectors in { + // Emit shift by 1 as an add since it might be faster. + def : Pat<(vti.Vector (int_riscv_vsll (vti.Vector vti.RegClass:$rs1), + (XLenVT 1), VLOpFrag)), + (!cast<Instruction>("PseudoVADD_VV_"#vti.LMul.MX) vti.RegClass:$rs1, + vti.RegClass:$rs1, + GPR:$vl, + vti.Log2SEW)>; + def : Pat<(vti.Vector (int_riscv_vsll_mask (vti.Vector vti.RegClass:$merge), + (vti.Vector vti.RegClass:$rs1), + (XLenVT 1), + (vti.Mask V0), + VLOpFrag, + (XLenVT timm:$policy))), + (!cast<Instruction>("PseudoVADD_VV_"#vti.LMul.MX#"_MASK") + vti.RegClass:$merge, + vti.RegClass:$rs1, + vti.RegClass:$rs1, + (vti.Mask V0), + GPR:$vl, + vti.Log2SEW, + (XLenVT timm:$policy))>; +} + //===----------------------------------------------------------------------===// // 12.7. Vector Narrowing Integer Right Shift Instructions //===----------------------------------------------------------------------===// @@ -4481,129 +4660,11 @@ defm : VPatBinarySwappedM_VV<"int_riscv_vmsge", "PseudoVMSLE", AllIntegerVectors // Match vmslt(u).vx intrinsics to vmsle(u).vi if the scalar is -15 to 16. This // avoids the user needing to know that there is no vmslt(u).vi instruction. // Similar for vmsge(u).vx intrinsics using vmslt(u).vi. -foreach vti = AllIntegerVectors in { - def : Pat<(vti.Mask (int_riscv_vmslt (vti.Vector vti.RegClass:$rs1), - (vti.Scalar simm5_plus1:$rs2), - VLOpFrag)), - (!cast<Instruction>("PseudoVMSLE_VI_"#vti.LMul.MX) vti.RegClass:$rs1, - (DecImm simm5_plus1:$rs2), - GPR:$vl, - vti.Log2SEW)>; - def : Pat<(vti.Mask (int_riscv_vmslt_mask (vti.Mask VR:$merge), - (vti.Vector vti.RegClass:$rs1), - (vti.Scalar simm5_plus1:$rs2), - (vti.Mask V0), - VLOpFrag)), - (!cast<Instruction>("PseudoVMSLE_VI_"#vti.LMul.MX#"_MASK") - VR:$merge, - vti.RegClass:$rs1, - (DecImm simm5_plus1:$rs2), - (vti.Mask V0), - GPR:$vl, - vti.Log2SEW)>; +defm : VPatCompare_VI<"int_riscv_vmslt", "PseudoVMSLE">; +defm : VPatCompare_VI<"int_riscv_vmsltu", "PseudoVMSLEU", simm5_plus1_nonzero>; - def : Pat<(vti.Mask (int_riscv_vmsltu (vti.Vector vti.RegClass:$rs1), - (vti.Scalar simm5_plus1:$rs2), - VLOpFrag)), - (!cast<Instruction>("PseudoVMSLEU_VI_"#vti.LMul.MX) vti.RegClass:$rs1, - (DecImm simm5_plus1:$rs2), - GPR:$vl, - vti.Log2SEW)>; - def : Pat<(vti.Mask (int_riscv_vmsltu_mask (vti.Mask VR:$merge), - (vti.Vector vti.RegClass:$rs1), - (vti.Scalar simm5_plus1:$rs2), - (vti.Mask V0), - VLOpFrag)), - (!cast<Instruction>("PseudoVMSLEU_VI_"#vti.LMul.MX#"_MASK") - VR:$merge, - vti.RegClass:$rs1, - (DecImm simm5_plus1:$rs2), - (vti.Mask V0), - GPR:$vl, - vti.Log2SEW)>; - - // Special cases to avoid matching vmsltu.vi 0 (always false) to - // vmsleu.vi -1 (always true). Instead match to vmsne.vv. - def : Pat<(vti.Mask (int_riscv_vmsltu (vti.Vector vti.RegClass:$rs1), - (vti.Scalar 0), VLOpFrag)), - (!cast<Instruction>("PseudoVMSNE_VV_"#vti.LMul.MX) vti.RegClass:$rs1, - vti.RegClass:$rs1, - GPR:$vl, - vti.Log2SEW)>; - def : Pat<(vti.Mask (int_riscv_vmsltu_mask (vti.Mask VR:$merge), - (vti.Vector vti.RegClass:$rs1), - (vti.Scalar 0), - (vti.Mask V0), - VLOpFrag)), - (!cast<Instruction>("PseudoVMSNE_VV_"#vti.LMul.MX#"_MASK") - VR:$merge, - vti.RegClass:$rs1, - vti.RegClass:$rs1, - (vti.Mask V0), - GPR:$vl, - vti.Log2SEW)>; - - def : Pat<(vti.Mask (int_riscv_vmsge (vti.Vector vti.RegClass:$rs1), - (vti.Scalar simm5_plus1:$rs2), - VLOpFrag)), - (!cast<Instruction>("PseudoVMSGT_VI_"#vti.LMul.MX) vti.RegClass:$rs1, - (DecImm simm5_plus1:$rs2), - GPR:$vl, - vti.Log2SEW)>; - def : Pat<(vti.Mask (int_riscv_vmsge_mask (vti.Mask VR:$merge), - (vti.Vector vti.RegClass:$rs1), - (vti.Scalar simm5_plus1:$rs2), - (vti.Mask V0), - VLOpFrag)), - (!cast<Instruction>("PseudoVMSGT_VI_"#vti.LMul.MX#"_MASK") - VR:$merge, - vti.RegClass:$rs1, - (DecImm simm5_plus1:$rs2), - (vti.Mask V0), - GPR:$vl, - vti.Log2SEW)>; - - def : Pat<(vti.Mask (int_riscv_vmsgeu (vti.Vector vti.RegClass:$rs1), - (vti.Scalar simm5_plus1:$rs2), - VLOpFrag)), - (!cast<Instruction>("PseudoVMSGTU_VI_"#vti.LMul.MX) vti.RegClass:$rs1, - (DecImm simm5_plus1:$rs2), - GPR:$vl, - vti.Log2SEW)>; - def : Pat<(vti.Mask (int_riscv_vmsgeu_mask (vti.Mask VR:$merge), - (vti.Vector vti.RegClass:$rs1), - (vti.Scalar simm5_plus1:$rs2), - (vti.Mask V0), - VLOpFrag)), - (!cast<Instruction>("PseudoVMSGTU_VI_"#vti.LMul.MX#"_MASK") - VR:$merge, - vti.RegClass:$rs1, - (DecImm simm5_plus1:$rs2), - (vti.Mask V0), - GPR:$vl, - vti.Log2SEW)>; - - // Special cases to avoid matching vmsgeu.vi 0 (always true) to - // vmsgtu.vi -1 (always false). Instead match to vmsne.vv. - def : Pat<(vti.Mask (int_riscv_vmsgeu (vti.Vector vti.RegClass:$rs1), - (vti.Scalar 0), VLOpFrag)), - (!cast<Instruction>("PseudoVMSEQ_VV_"#vti.LMul.MX) vti.RegClass:$rs1, - vti.RegClass:$rs1, - GPR:$vl, - vti.Log2SEW)>; - def : Pat<(vti.Mask (int_riscv_vmsgeu_mask (vti.Mask VR:$merge), - (vti.Vector vti.RegClass:$rs1), - (vti.Scalar 0), - (vti.Mask V0), - VLOpFrag)), - (!cast<Instruction>("PseudoVMSEQ_VV_"#vti.LMul.MX#"_MASK") - VR:$merge, - vti.RegClass:$rs1, - vti.RegClass:$rs1, - (vti.Mask V0), - GPR:$vl, - vti.Log2SEW)>; -} +defm : VPatCompare_VI<"int_riscv_vmsge", "PseudoVMSGT">; +defm : VPatCompare_VI<"int_riscv_vmsgeu", "PseudoVMSGTU", simm5_plus1_nonzero>; //===----------------------------------------------------------------------===// // 12.9. Vector Integer Min/Max Instructions |