Please use GitHub pull requests for new patches. Avoid migrating existing patches. Phabricator shutdown timeline
Changeset View
Standalone View
llvm/lib/Target/RISCV/RISCVInstrInfoVPseudos.td
- This file is larger than 256 KB, so syntax highlighting is disabled by default.
Show First 20 Lines • Show All 203 Lines • ▼ Show 20 Lines | |||||
class GroupVTypeInfo<ValueType Vec, ValueType VecM1, ValueType Mas, int Sew, | class GroupVTypeInfo<ValueType Vec, ValueType VecM1, ValueType Mas, int Sew, | ||||
VReg Reg, LMULInfo M, ValueType Scal = XLenVT, | VReg Reg, LMULInfo M, ValueType Scal = XLenVT, | ||||
RegisterClass ScalarReg = GPR> | RegisterClass ScalarReg = GPR> | ||||
: VTypeInfo<Vec, Mas, Sew, Reg, M, Scal, ScalarReg> | : VTypeInfo<Vec, Mas, Sew, Reg, M, Scal, ScalarReg> | ||||
{ | { | ||||
ValueType VectorM1 = VecM1; | ValueType VectorM1 = VecM1; | ||||
} | } | ||||
defset list<VTypeInfo> I32I64IntegerVectors = { | |||||
defset list<VTypeInfo> I32IntegerVectors = { | |||||
def : VTypeInfo<vint32mf2_t, vbool64_t, 32, VR, V_MF2>; | |||||
def : VTypeInfo<vint32m1_t, vbool32_t, 32, VR, V_M1>; | |||||
def : GroupVTypeInfo<vint32m2_t,vint32m1_t,vbool16_t,32,VRM2, V_M2>; | |||||
def : GroupVTypeInfo<vint32m4_t,vint32m1_t,vbool8_t, 32,VRM4, V_M4>; | |||||
def : GroupVTypeInfo<vint32m8_t,vint32m1_t,vbool4_t, 32,VRM8, V_M8>; | |||||
} | |||||
defset list<VTypeInfo> I64IntegerVectors = { | |||||
def : VTypeInfo<vint64m1_t, vbool64_t, 64, VR, V_M1>; | |||||
def : GroupVTypeInfo<vint64m2_t,vint64m1_t,vbool32_t,64,VRM2, V_M2>; | |||||
def : GroupVTypeInfo<vint64m4_t,vint64m1_t,vbool16_t,64,VRM4, V_M4>; | |||||
def : GroupVTypeInfo<vint64m8_t,vint64m1_t,vbool8_t, 64,VRM8, V_M8>; | |||||
} | |||||
} | |||||
defset list<VTypeInfo> AllVectors = { | defset list<VTypeInfo> AllVectors = { | ||||
defset list<VTypeInfo> AllIntegerVectors = { | defset list<VTypeInfo> AllIntegerVectors = { | ||||
defset list<VTypeInfo> NoGroupIntegerVectors = { | defset list<VTypeInfo> NoGroupIntegerVectors = { | ||||
defset list<VTypeInfo> FractionalGroupIntegerVectors = { | defset list<VTypeInfo> FractionalGroupIntegerVectors = { | ||||
def VI8MF8: VTypeInfo<vint8mf8_t, vbool64_t, 8, VR, V_MF8>; | def VI8MF8: VTypeInfo<vint8mf8_t, vbool64_t, 8, VR, V_MF8>; | ||||
def VI8MF4: VTypeInfo<vint8mf4_t, vbool32_t, 8, VR, V_MF4>; | def VI8MF4: VTypeInfo<vint8mf4_t, vbool32_t, 8, VR, V_MF4>; | ||||
def VI8MF2: VTypeInfo<vint8mf2_t, vbool16_t, 8, VR, V_MF2>; | def VI8MF2: VTypeInfo<vint8mf2_t, vbool16_t, 8, VR, V_MF2>; | ||||
def VI16MF4: VTypeInfo<vint16mf4_t, vbool64_t, 16, VR, V_MF4>; | def VI16MF4: VTypeInfo<vint16mf4_t, vbool64_t, 16, VR, V_MF4>; | ||||
▲ Show 20 Lines • Show All 787 Lines • ▼ Show 20 Lines | class VPseudoUnaryNoMaskTU<DAGOperand RetClass, VReg OpClass, string Constraint = ""> : | ||||
let hasSideEffects = 0; | let hasSideEffects = 0; | ||||
let Constraints = Join<[Constraint, "$rd = $merge"], ",">.ret; | let Constraints = Join<[Constraint, "$rd = $merge"], ",">.ret; | ||||
let HasVLOp = 1; | let HasVLOp = 1; | ||||
let HasSEWOp = 1; | let HasSEWOp = 1; | ||||
let HasDummyMask = 1; | let HasDummyMask = 1; | ||||
let HasMergeOp = 1; | let HasMergeOp = 1; | ||||
} | } | ||||
class PPseudoUnaryNoMask<DAGOperand RetClass, VReg OpClass, string Constraint = ""> : | |||||
michaelmaitland: Is there a reason behind using `PPseudo` instead of `VPseudo`? If its the same `P` as the other… | |||||
Pseudo<(outs RetClass:$rd), | |||||
(ins RetClass:$merge, OpClass:$rs2, AVL:$vl, ixlenimm:$sew, ixlenimm:$policy), []>, | |||||
RISCVVPseudo { | |||||
let mayLoad = 0; | |||||
let mayStore = 0; | |||||
let hasSideEffects = 0; | |||||
let Constraints = Join<[Constraint, "$rd = $merge"], ",">.ret; | |||||
let HasVLOp = 1; | |||||
let HasSEWOp = 1; | |||||
let HasDummyMask = 1; | |||||
let HasVecPolicyOp = 1; | |||||
let HasMergeOp = 1; | |||||
let BaseInstr = !cast<Instruction>(PseudoToVInst<NAME>.VInst); | |||||
} | |||||
class VPseudoUnaryMask<VReg RetClass, VReg OpClass, string Constraint = ""> : | class VPseudoUnaryMask<VReg RetClass, VReg OpClass, string Constraint = ""> : | ||||
Pseudo<(outs GetVRegNoV0<RetClass>.R:$rd), | Pseudo<(outs GetVRegNoV0<RetClass>.R:$rd), | ||||
(ins GetVRegNoV0<RetClass>.R:$merge, OpClass:$rs2, | (ins GetVRegNoV0<RetClass>.R:$merge, OpClass:$rs2, | ||||
VMaskOp:$vm, AVL:$vl, ixlenimm:$sew), []>, | VMaskOp:$vm, AVL:$vl, ixlenimm:$sew), []>, | ||||
RISCVVPseudo { | RISCVVPseudo { | ||||
let mayLoad = 0; | let mayLoad = 0; | ||||
let mayStore = 0; | let mayStore = 0; | ||||
let hasSideEffects = 0; | let hasSideEffects = 0; | ||||
▲ Show 20 Lines • Show All 111 Lines • ▼ Show 20 Lines | class VPseudoBinaryNoMaskTU<VReg RetClass, | ||||
let hasSideEffects = 0; | let hasSideEffects = 0; | ||||
let Constraints = Join<[Constraint, "$rd = $merge"], ",">.ret; | let Constraints = Join<[Constraint, "$rd = $merge"], ",">.ret; | ||||
let HasVLOp = 1; | let HasVLOp = 1; | ||||
let HasSEWOp = 1; | let HasSEWOp = 1; | ||||
let HasDummyMask = 1; | let HasDummyMask = 1; | ||||
let HasMergeOp = 1; | let HasMergeOp = 1; | ||||
} | } | ||||
class PPseudoBinaryNoMask<VReg RetClass, | |||||
VReg Op1Class, | |||||
DAGOperand Op2Class, | |||||
string Constraint> : | |||||
Pseudo<(outs RetClass:$rd), | |||||
(ins RetClass:$merge, Op1Class:$rs2, Op2Class:$rs1, | |||||
AVL:$vl, ixlenimm:$sew, ixlenimm:$policy), []>, | |||||
RISCVVPseudo { | |||||
let mayLoad = 0; | |||||
let mayStore = 0; | |||||
let hasSideEffects = 0; | |||||
let Constraints = Join<[Constraint, "$rd = $merge"], ",">.ret; | |||||
let HasVLOp = 1; | |||||
let HasSEWOp = 1; | |||||
let HasDummyMask = 1; | |||||
let HasVecPolicyOp = 1; | |||||
let HasMergeOp = 1; | |||||
let BaseInstr = !cast<Instruction>(PseudoToVInst<NAME>.VInst); | |||||
} | |||||
// Special version of VPseudoBinaryNoMask where we pretend the first source is | // Special version of VPseudoBinaryNoMask where we pretend the first source is | ||||
// tied to the destination. | // tied to the destination. | ||||
// This allows maskedoff and rs2 to be the same register. | // This allows maskedoff and rs2 to be the same register. | ||||
class VPseudoTiedBinaryNoMask<VReg RetClass, | class VPseudoTiedBinaryNoMask<VReg RetClass, | ||||
DAGOperand Op2Class, | DAGOperand Op2Class, | ||||
string Constraint> : | string Constraint> : | ||||
Pseudo<(outs RetClass:$rd), | Pseudo<(outs RetClass:$rd), | ||||
(ins RetClass:$rs2, Op2Class:$rs1, AVL:$vl, ixlenimm:$sew, | (ins RetClass:$rs2, Op2Class:$rs1, AVL:$vl, ixlenimm:$sew, | ||||
▲ Show 20 Lines • Show All 788 Lines • ▼ Show 20 Lines | multiclass VPseudoBinaryV_VV<string Constraint = ""> { | ||||
foreach m = MxList in | foreach m = MxList in | ||||
defm _VV : VPseudoBinary<m.vrclass, m.vrclass, m.vrclass, m, Constraint>; | defm _VV : VPseudoBinary<m.vrclass, m.vrclass, m.vrclass, m, Constraint>; | ||||
} | } | ||||
multiclass VPseudoBinaryV_VV_LMUL<LMULInfo m, string Constraint = ""> { | multiclass VPseudoBinaryV_VV_LMUL<LMULInfo m, string Constraint = ""> { | ||||
defm _VV : VPseudoBinary<m.vrclass, m.vrclass, m.vrclass, m, Constraint>; | defm _VV : VPseudoBinary<m.vrclass, m.vrclass, m.vrclass, m, Constraint>; | ||||
} | } | ||||
multiclass PPseudoBinaryNoMask<VReg RetClass, | |||||
VReg Op1Class, | |||||
DAGOperand Op2Class, | |||||
LMULInfo MInfo, | |||||
string Constraint = ""> { | |||||
let VLMul = MInfo.value in | |||||
def "_" # MInfo.MX : PPseudoBinaryNoMask<RetClass, Op1Class, Op2Class, | |||||
Constraint>; | |||||
} | |||||
multiclass PPseudoBinaryV_VV_NoMask<LMULInfo m, string Constraint = ""> { | |||||
defm _VV : PPseudoBinaryNoMask<m.vrclass, m.vrclass, m.vrclass, m, Constraint>; | |||||
} | |||||
multiclass VPseudoUnaryV_V<LMULInfo m, string Constraint = ""> { | |||||
let VLMul = m.value in { | |||||
def "_V_" # m.MX : VPseudoUnaryNoMask<m.vrclass, m.vrclass, Constraint>; | |||||
def "_V_" # m.MX # "_TU": VPseudoUnaryNoMaskTU<m.vrclass, m.vrclass, Constraint>; | |||||
def "_V_" # m.MX # "_MASK" : VPseudoUnaryMaskTA<m.vrclass, m.vrclass, Constraint>, | |||||
RISCVMaskedPseudo</*MaskOpIdx*/ 2>; | |||||
} | |||||
} | |||||
multiclass PPseudoUnaryV_V_NoMask<LMULInfo m, string Constraint = ""> { | |||||
let VLMul = m.value in { | |||||
def "_VV_" # m.MX : PPseudoUnaryNoMask<m.vrclass, m.vrclass, Constraint>; | |||||
} | |||||
} | |||||
multiclass PPseudoUnaryV_S_NoMask<LMULInfo m, string Constraint = ""> { | |||||
let VLMul = m.value in { | |||||
def "_VS_" # m.MX : PPseudoUnaryNoMask<m.vrclass, m.vrclass, Constraint>; | |||||
} | |||||
} | |||||
// Similar to VPseudoBinaryV_VV, but uses MxListF. | // Similar to VPseudoBinaryV_VV, but uses MxListF. | ||||
multiclass VPseudoBinaryFV_VV<string Constraint = ""> { | multiclass VPseudoBinaryFV_VV<string Constraint = ""> { | ||||
foreach m = MxListF in | foreach m = MxListF in | ||||
defm _VV : VPseudoBinary<m.vrclass, m.vrclass, m.vrclass, m, Constraint>; | defm _VV : VPseudoBinary<m.vrclass, m.vrclass, m.vrclass, m, Constraint>; | ||||
} | } | ||||
multiclass VPseudoVGTR_VV_EEW<int eew, string Constraint = ""> { | multiclass VPseudoVGTR_VV_EEW<int eew, string Constraint = ""> { | ||||
foreach m = MxList in { | foreach m = MxList in { | ||||
▲ Show 20 Lines • Show All 45 Lines • ▼ Show 20 Lines | multiclass VPseudoBinaryV_VI<Operand ImmType = simm5, string Constraint = ""> { | ||||
foreach m = MxList in | foreach m = MxList in | ||||
defm _VI : VPseudoBinary<m.vrclass, m.vrclass, ImmType, m, Constraint>; | defm _VI : VPseudoBinary<m.vrclass, m.vrclass, ImmType, m, Constraint>; | ||||
} | } | ||||
multiclass VPseudoBinaryV_VI_LMUL<Operand ImmType = simm5, LMULInfo m, string Constraint = ""> { | multiclass VPseudoBinaryV_VI_LMUL<Operand ImmType = simm5, LMULInfo m, string Constraint = ""> { | ||||
defm _VI : VPseudoBinary<m.vrclass, m.vrclass, ImmType, m, Constraint>; | defm _VI : VPseudoBinary<m.vrclass, m.vrclass, ImmType, m, Constraint>; | ||||
} | } | ||||
multiclass PPseudoBinaryV_VI<LMULInfo m, Operand ImmType = simm5, string Constraint = ""> { | |||||
defm _VI : VPseudoBinary<m.vrclass, m.vrclass, ImmType, m, Constraint>; | |||||
} | |||||
multiclass PPseudoBinaryV_VI_NoMask<LMULInfo m, Operand ImmType = simm5, string Constraint = ""> { | |||||
defm _VI : PPseudoBinaryNoMask<m.vrclass, m.vrclass, ImmType, m, Constraint>; | |||||
} | |||||
multiclass VPseudoVALU_MM { | multiclass VPseudoVALU_MM { | ||||
foreach m = MxList in | foreach m = MxList in | ||||
let VLMul = m.value in { | let VLMul = m.value in { | ||||
def "_MM_" # m.MX : VPseudoBinaryNoMask<VR, VR, VR, "", /*DummyMask*/0>, | def "_MM_" # m.MX : VPseudoBinaryNoMask<VR, VR, VR, "", /*DummyMask*/0>, | ||||
Sched<[WriteVMALUV, ReadVMALUV, ReadVMALUV]>; | Sched<[WriteVMALUV, ReadVMALUV, ReadVMALUV]>; | ||||
} | } | ||||
} | } | ||||
▲ Show 20 Lines • Show All 413 Lines • ▼ Show 20 Lines | defm "" : VPseudoBinaryV_VV_LMUL<m, Constraint>, | ||||
Sched<[WriteVIALUV_MX, ReadVIALUV_MX, ReadVIALUV_MX, ReadVMask]>; | Sched<[WriteVIALUV_MX, ReadVIALUV_MX, ReadVIALUV_MX, ReadVMask]>; | ||||
defm "" : VPseudoBinaryV_VX_LMUL<m, Constraint>, | defm "" : VPseudoBinaryV_VX_LMUL<m, Constraint>, | ||||
Sched<[WriteVIALUX_MX, ReadVIALUV_MX, ReadVIALUX_MX, ReadVMask]>; | Sched<[WriteVIALUX_MX, ReadVIALUV_MX, ReadVIALUX_MX, ReadVMask]>; | ||||
defm "" : VPseudoBinaryV_VI_LMUL<ImmType, m, Constraint>, | defm "" : VPseudoBinaryV_VI_LMUL<ImmType, m, Constraint>, | ||||
Sched<[WriteVIALUI_MX, ReadVIALUV_MX, ReadVMask]>; | Sched<[WriteVIALUI_MX, ReadVIALUV_MX, ReadVMask]>; | ||||
} | } | ||||
} | } | ||||
multiclass VPseudoVALU_V<string Constraint = ""> { | |||||
foreach m = MxList in { | |||||
defvar mx = m.MX; | |||||
defvar WriteVIALUV_MX = !cast<SchedWrite>("WriteVIALUV_" # mx); | |||||
defvar ReadVIALUV_MX = !cast<SchedRead>("ReadVIALUV_" # mx); | |||||
defm "" : VPseudoUnaryV_V<m, Constraint>, | |||||
Sched<[WriteVIALUV_MX, ReadVIALUV_MX, ReadVIALUV_MX, ReadVMask]>; | |||||
} | |||||
} | |||||
multiclass PPseudoVALU_V_NoMask<string Constraint = ""> { | |||||
foreach m = MxListVF4 in { | |||||
Docstring for MxListVF4 says for zext/sext.vf4. Are you able to update this docstring now that it has more uses? michaelmaitland: Docstring for MxListVF4 says for `zext/sext.vf4`. Are you able to update this docstring now… | |||||
You are right, thanks! 4vtomat: You are right, thanks! | |||||
defvar mx = m.MX; | |||||
defvar WriteVIALUV_MX = !cast<SchedWrite>("WriteVIALUV_" # mx); | |||||
defvar ReadVIALUV_MX = !cast<SchedRead>("ReadVIALUV_" # mx); | |||||
defm "" : PPseudoUnaryV_V_NoMask<m, Constraint>, | |||||
Sched<[WriteVIALUV_MX, ReadVIALUV_MX, ReadVIALUV_MX, ReadVMask]>; | |||||
} | |||||
} | |||||
multiclass PPseudoVALU_S_NoMask<string Constraint = ""> { | |||||
foreach m = MxListVF4 in { | |||||
defvar mx = m.MX; | |||||
defvar WriteVIALUV_MX = !cast<SchedWrite>("WriteVIALUV_" # mx); | |||||
defvar ReadVIALUV_MX = !cast<SchedRead>("ReadVIALUV_" # mx); | |||||
defm "" : PPseudoUnaryV_S_NoMask<m, Constraint>, | |||||
Sched<[WriteVIALUV_MX, ReadVIALUV_MX, ReadVIALUV_MX, ReadVMask]>; | |||||
} | |||||
} | |||||
multiclass PPseudoVALU_V_S_NoMask<string Constraint = ""> { | |||||
defm "" : PPseudoVALU_V_NoMask<Constraint>; | |||||
defm "" : PPseudoVALU_S_NoMask<Constraint>; | |||||
} | |||||
multiclass PPseudoVALU_VV_NoMask<string Constraint = ""> { | |||||
foreach m = MxListVF4 in { | |||||
defvar mx = m.MX; | |||||
defvar WriteVIALUV_MX = !cast<SchedWrite>("WriteVIALUV_" # mx); | |||||
defvar ReadVIALUV_MX = !cast<SchedRead>("ReadVIALUV_" # mx); | |||||
defm "" : PPseudoBinaryV_VV_NoMask<m, Constraint>, | |||||
Sched<[WriteVIALUV_MX, ReadVIALUV_MX, ReadVIALUV_MX, ReadVMask]>; | |||||
} | |||||
} | |||||
multiclass PPseudoVALU_VI<Operand ImmType = simm5, string Constraint = ""> { | |||||
foreach m = MxListVF4 in { | |||||
defvar mx = m.MX; | |||||
defvar WriteVIALUV_MX = !cast<SchedWrite>("WriteVIALUV_" # mx); | |||||
defvar ReadVIALUV_MX = !cast<SchedRead>("ReadVIALUV_" # mx); | |||||
defm "" : PPseudoBinaryV_VI<m, ImmType, Constraint>, | |||||
Sched<[WriteVIALUV_MX, ReadVIALUV_MX, ReadVIALUV_MX, ReadVMask]>; | |||||
} | |||||
} | |||||
multiclass PPseudoVALU_VI_NoMask<Operand ImmType = simm5, string Constraint = ""> { | |||||
foreach m = MxListVF4 in { | |||||
defvar mx = m.MX; | |||||
defvar WriteVIALUV_MX = !cast<SchedWrite>("WriteVIALUV_" # mx); | |||||
defvar ReadVIALUV_MX = !cast<SchedRead>("ReadVIALUV_" # mx); | |||||
defm "" : PPseudoBinaryV_VI_NoMask<m, ImmType, Constraint>, | |||||
Sched<[WriteVIALUV_MX, ReadVIALUV_MX, ReadVIALUV_MX, ReadVMask]>; | |||||
} | |||||
} | |||||
multiclass VPseudoVSALU_VV_VX { | multiclass VPseudoVSALU_VV_VX { | ||||
defm "" : VPseudoBinaryV_VV, | defm "" : VPseudoBinaryV_VV, | ||||
Sched<[WriteVSALUV, ReadVSALUV, ReadVSALUV, ReadVMask]>; | Sched<[WriteVSALUV, ReadVSALUV, ReadVSALUV, ReadVMask]>; | ||||
defm "" : VPseudoBinaryV_VX, | defm "" : VPseudoBinaryV_VX, | ||||
Sched<[WriteVSALUX, ReadVSALUV, ReadVSALUX, ReadVMask]>; | Sched<[WriteVSALUX, ReadVSALUV, ReadVSALUX, ReadVMask]>; | ||||
} | } | ||||
multiclass VPseudoVSMUL_VV_VX { | multiclass VPseudoVSMUL_VV_VX { | ||||
▲ Show 20 Lines • Show All 84 Lines • ▼ Show 20 Lines | foreach m = MxList in { | ||||
defm "" : VPseudoBinaryV_VV_LMUL<m>, | defm "" : VPseudoBinaryV_VV_LMUL<m>, | ||||
Sched<[WriteVIALUV_MX, ReadVIALUV_MX, ReadVIALUV_MX, ReadVMask]>; | Sched<[WriteVIALUV_MX, ReadVIALUV_MX, ReadVIALUV_MX, ReadVMask]>; | ||||
defm "" : VPseudoBinaryV_VX_LMUL<m>, | defm "" : VPseudoBinaryV_VX_LMUL<m>, | ||||
Sched<[WriteVIALUX_MX, ReadVIALUV_MX, ReadVIALUX_MX, ReadVMask]>; | Sched<[WriteVIALUX_MX, ReadVIALUV_MX, ReadVIALUX_MX, ReadVMask]>; | ||||
} | } | ||||
} | } | ||||
multiclass VPseudoVALU_VCLMUL<string Constraint = ""> { | |||||
This parameter is never used. craig.topper: This parameter is never used. | |||||
foreach m = MxList in { | |||||
defvar mx = m.MX; | |||||
defvar WriteVIALUV_MX = !cast<SchedWrite>("WriteVIALUV_" # mx); | |||||
defvar WriteVIALUX_MX = !cast<SchedWrite>("WriteVIALUV_" # mx); | |||||
defvar ReadVIALUV_MX = !cast<SchedRead>("ReadVIALUV_" # mx); | |||||
defvar ReadVIALUX_MX = !cast<SchedRead>("ReadVIALUX_" # mx); | |||||
defm _VV : VPseudoBinary<m.vrclass, m.vrclass, m.vrclass, m, Constraint>, | |||||
I think this can use VPseudoBinaryV_VV craig.topper: I think this can use VPseudoBinaryV_VV | |||||
Sched<[WriteVIALUV_MX, ReadVIALUV_MX, ReadVIALUV_MX, ReadVMask]>; | |||||
defm _VX : VPseudoBinary<m.vrclass, m.vrclass, GPR, m, Constraint>, | |||||
I think this can use VPseudoBinaryV_VX craig.topper: I think this can use VPseudoBinaryV_VX | |||||
Sched<[WriteVIALUX_MX, ReadVIALUV_MX, ReadVIALUX_MX, ReadVMask]>; | |||||
} | |||||
} | |||||
multiclass VPseudoVSGNJ_VV_VF { | multiclass VPseudoVSGNJ_VV_VF { | ||||
defm "" : VPseudoBinaryFV_VV, | defm "" : VPseudoBinaryFV_VV, | ||||
Sched<[WriteVFSgnjV, ReadVFSgnjV, ReadVFSgnjV, ReadVMask]>; | Sched<[WriteVFSgnjV, ReadVFSgnjV, ReadVFSgnjV, ReadVMask]>; | ||||
defm "" : VPseudoBinaryV_VF, | defm "" : VPseudoBinaryV_VF, | ||||
Sched<[WriteVFSgnjF, ReadVFSgnjV, ReadVFSgnjF, ReadVMask]>; | Sched<[WriteVFSgnjF, ReadVFSgnjV, ReadVFSgnjF, ReadVMask]>; | ||||
} | } | ||||
multiclass VPseudoVMAX_VV_VF { | multiclass VPseudoVMAX_VV_VF { | ||||
▲ Show 20 Lines • Show All 820 Lines • ▼ Show 20 Lines | Pat<(result_type (!cast<Intrinsic>(intrinsic_name) | ||||
(result_type result_reg_class:$merge), | (result_type result_reg_class:$merge), | ||||
(op2_type op2_reg_class:$rs2), | (op2_type op2_reg_class:$rs2), | ||||
VLOpFrag)), | VLOpFrag)), | ||||
(!cast<Instruction>(inst#"_"#kind#"_"#vlmul.MX#"_TU") | (!cast<Instruction>(inst#"_"#kind#"_"#vlmul.MX#"_TU") | ||||
(result_type result_reg_class:$merge), | (result_type result_reg_class:$merge), | ||||
(op2_type op2_reg_class:$rs2), | (op2_type op2_reg_class:$rs2), | ||||
GPR:$vl, sew)>; | GPR:$vl, sew)>; | ||||
class PPatUnaryNoMask<string intrinsic_name, | |||||
I don't think using "PPat" instead of "VPat" meaningful highlights the difference between these patterns. The instructions being OP_P is an encoding detail only. craig.topper: I don't think using "PPat" instead of "VPat" meaningful highlights the difference between these… | |||||
string inst, | |||||
string kind, | |||||
ValueType result_type, | |||||
ValueType op2_type, | |||||
int sew, | |||||
LMULInfo vlmul, | |||||
VReg result_reg_class, | |||||
VReg op2_reg_class> : | |||||
Pat<(result_type (!cast<Intrinsic>(intrinsic_name) | |||||
(result_type result_reg_class:$merge), | |||||
(op2_type op2_reg_class:$rs2), | |||||
VLOpFrag, (XLenVT timm:$policy))), | |||||
(!cast<Instruction>(inst#"_"#kind#"_"#vlmul.MX) | |||||
(result_type result_reg_class:$merge), | |||||
(op2_type op2_reg_class:$rs2), | |||||
GPR:$vl, sew, (XLenVT timm:$policy))>; | |||||
class VPatUnaryMask<string intrinsic_name, | class VPatUnaryMask<string intrinsic_name, | ||||
string inst, | string inst, | ||||
string kind, | string kind, | ||||
ValueType result_type, | ValueType result_type, | ||||
ValueType op2_type, | ValueType op2_type, | ||||
ValueType mask_type, | ValueType mask_type, | ||||
int sew, | int sew, | ||||
LMULInfo vlmul, | LMULInfo vlmul, | ||||
▲ Show 20 Lines • Show All 123 Lines • ▼ Show 20 Lines | Pat<(result_type (!cast<Intrinsic>(intrinsic_name) | ||||
(op2_type op2_kind:$rs2), | (op2_type op2_kind:$rs2), | ||||
VLOpFrag)), | VLOpFrag)), | ||||
(!cast<Instruction>(inst#"_TU") | (!cast<Instruction>(inst#"_TU") | ||||
(result_type result_reg_class:$merge), | (result_type result_reg_class:$merge), | ||||
(op1_type op1_reg_class:$rs1), | (op1_type op1_reg_class:$rs1), | ||||
(op2_type op2_kind:$rs2), | (op2_type op2_kind:$rs2), | ||||
GPR:$vl, sew)>; | GPR:$vl, sew)>; | ||||
class PPatBinaryNoMask<string intrinsic_name, | |||||
I think this might be the same as VPatTernaryNoMaskWithPolicy craig.topper: I think this might be the same as VPatTernaryNoMaskWithPolicy | |||||
string inst, | |||||
ValueType result_type, | |||||
ValueType op1_type, | |||||
ValueType op2_type, | |||||
int sew, | |||||
VReg result_reg_class, | |||||
VReg op1_reg_class, | |||||
DAGOperand op2_kind> : | |||||
Pat<(result_type (!cast<Intrinsic>(intrinsic_name) | |||||
(result_type result_reg_class:$merge), | |||||
(op1_type op1_reg_class:$rs1), | |||||
(op2_type op2_kind:$rs2), | |||||
VLOpFrag, (XLenVT timm:$policy))), | |||||
(!cast<Instruction>(inst) | |||||
(result_type result_reg_class:$merge), | |||||
(op1_type op1_reg_class:$rs1), | |||||
(op2_type op2_kind:$rs2), | |||||
GPR:$vl, sew, (XLenVT timm:$policy))>; | |||||
// Same as above but source operands are swapped. | // Same as above but source operands are swapped. | ||||
class VPatBinaryNoMaskSwapped<string intrinsic_name, | class VPatBinaryNoMaskSwapped<string intrinsic_name, | ||||
string inst, | string inst, | ||||
ValueType result_type, | ValueType result_type, | ||||
ValueType op1_type, | ValueType op1_type, | ||||
ValueType op2_type, | ValueType op2_type, | ||||
int sew, | int sew, | ||||
VReg op1_reg_class, | VReg op1_reg_class, | ||||
▲ Show 20 Lines • Show All 296 Lines • ▼ Show 20 Lines | def : VPatUnaryNoMaskTU<intrinsic, instruction, "V", | ||||
vti.Vector, vti.Vector, | vti.Vector, vti.Vector, | ||||
vti.Log2SEW, vti.LMul, vti.RegClass, vti.RegClass>; | vti.Log2SEW, vti.LMul, vti.RegClass, vti.RegClass>; | ||||
def : VPatUnaryMaskTA<intrinsic, instruction, "V", | def : VPatUnaryMaskTA<intrinsic, instruction, "V", | ||||
vti.Vector, vti.Vector, vti.Mask, | vti.Vector, vti.Vector, vti.Mask, | ||||
vti.Log2SEW, vti.LMul, vti.RegClass, vti.RegClass>; | vti.Log2SEW, vti.LMul, vti.RegClass, vti.RegClass>; | ||||
} | } | ||||
} | } | ||||
multiclass PPatUnaryV_V_NoMask<string intrinsic, string instruction, | |||||
I raise the same question about whether this should be VPatUnary as above and if P is needed, should it be suffixed? michaelmaitland: I raise the same question about whether this should be `VPatUnary` as above and if `P` is… | |||||
list<VTypeInfo> vtilist> { | |||||
foreach vti = vtilist in | |||||
def : PPatUnaryNoMask<intrinsic # "_vv", instruction, "VV", | |||||
vti.Vector, vti.Vector, vti.Log2SEW, | |||||
vti.LMul, vti.RegClass, vti.RegClass>; | |||||
} | |||||
multiclass PPatUnaryV_S_NoMask<string intrinsic, string instruction, | |||||
list<VTypeInfo> vtilist> { | |||||
foreach vti = vtilist in | |||||
def : PPatUnaryNoMask<intrinsic # "_vs", instruction, "VS", | |||||
vti.Vector, vti.Vector, vti.Log2SEW, | |||||
vti.LMul, vti.RegClass, vti.RegClass>; | |||||
} | |||||
multiclass PPatUnaryV_V_S_NoMask<string intrinsic, string instruction, | |||||
list<VTypeInfo> vtilist> { | |||||
defm : PPatUnaryV_V_NoMask<intrinsic, instruction, vtilist>; | |||||
defm : PPatUnaryV_S_NoMask<intrinsic, instruction, vtilist>; | |||||
} | |||||
multiclass VPatNullaryV<string intrinsic, string instruction> | multiclass VPatNullaryV<string intrinsic, string instruction> | ||||
{ | { | ||||
foreach vti = AllIntegerVectors in { | foreach vti = AllIntegerVectors in { | ||||
def : Pat<(vti.Vector (!cast<Intrinsic>(intrinsic) | def : Pat<(vti.Vector (!cast<Intrinsic>(intrinsic) | ||||
(vti.Vector undef), | (vti.Vector undef), | ||||
VLOpFrag)), | VLOpFrag)), | ||||
(!cast<Instruction>(instruction#"_V_" # vti.LMul.MX) | (!cast<Instruction>(instruction#"_V_" # vti.LMul.MX) | ||||
GPR:$vl, vti.Log2SEW)>; | GPR:$vl, vti.Log2SEW)>; | ||||
▲ Show 20 Lines • Show All 178 Lines • ▼ Show 20 Lines | multiclass VPatBinaryV_VV<string intrinsic, string instruction, | ||||
list<VTypeInfo> vtilist> { | list<VTypeInfo> vtilist> { | ||||
foreach vti = vtilist in | foreach vti = vtilist in | ||||
defm : VPatBinaryTA<intrinsic, instruction # "_VV_" # vti.LMul.MX, | defm : VPatBinaryTA<intrinsic, instruction # "_VV_" # vti.LMul.MX, | ||||
vti.Vector, vti.Vector, vti.Vector,vti.Mask, | vti.Vector, vti.Vector, vti.Vector,vti.Mask, | ||||
vti.Log2SEW, vti.RegClass, | vti.Log2SEW, vti.RegClass, | ||||
vti.RegClass, vti.RegClass>; | vti.RegClass, vti.RegClass>; | ||||
} | } | ||||
multiclass VPatBinaryV_VV_NoMask<string intrinsic, string instruction, | |||||
list<VTypeInfo> vtilist> { | |||||
foreach vti = vtilist in | |||||
def : PPatBinaryNoMask<intrinsic, instruction # "_VV_" # vti.LMul.MX, | |||||
vti.Vector, vti.Vector, vti.Vector, | |||||
vti.Log2SEW, vti.RegClass, vti.RegClass, | |||||
vti.RegClass>; | |||||
} | |||||
multiclass VPatBinaryV_VV_INT<string intrinsic, string instruction, | multiclass VPatBinaryV_VV_INT<string intrinsic, string instruction, | ||||
list<VTypeInfo> vtilist> { | list<VTypeInfo> vtilist> { | ||||
foreach vti = vtilist in { | foreach vti = vtilist in { | ||||
defvar ivti = GetIntVTypeInfo<vti>.Vti; | defvar ivti = GetIntVTypeInfo<vti>.Vti; | ||||
defm : VPatBinaryTA<intrinsic, instruction # "_VV_" # vti.LMul.MX, | defm : VPatBinaryTA<intrinsic, instruction # "_VV_" # vti.LMul.MX, | ||||
vti.Vector, vti.Vector, ivti.Vector, vti.Mask, | vti.Vector, vti.Vector, ivti.Vector, vti.Mask, | ||||
vti.Log2SEW, vti.RegClass, | vti.Log2SEW, vti.RegClass, | ||||
vti.RegClass, vti.RegClass>; | vti.RegClass, vti.RegClass>; | ||||
▲ Show 20 Lines • Show All 43 Lines • ▼ Show 20 Lines | multiclass VPatBinaryV_VI<string intrinsic, string instruction, | ||||
list<VTypeInfo> vtilist, Operand imm_type> { | list<VTypeInfo> vtilist, Operand imm_type> { | ||||
foreach vti = vtilist in | foreach vti = vtilist in | ||||
defm : VPatBinaryTA<intrinsic, instruction # "_VI_" # vti.LMul.MX, | defm : VPatBinaryTA<intrinsic, instruction # "_VI_" # vti.LMul.MX, | ||||
vti.Vector, vti.Vector, XLenVT, vti.Mask, | vti.Vector, vti.Vector, XLenVT, vti.Mask, | ||||
vti.Log2SEW, vti.RegClass, | vti.Log2SEW, vti.RegClass, | ||||
vti.RegClass, imm_type>; | vti.RegClass, imm_type>; | ||||
} | } | ||||
multiclass VPatBinaryV_VI_NoMask<string intrinsic, string instruction, | |||||
list<VTypeInfo> vtilist, Operand imm_type = simm5> { | |||||
foreach vti = vtilist in | |||||
def : PPatBinaryNoMask<intrinsic, instruction # "_VI_" # vti.LMul.MX, | |||||
vti.Vector, vti.Vector, XLenVT, vti.Log2SEW, | |||||
vti.RegClass, vti.RegClass, imm_type>; | |||||
} | |||||
multiclass VPatBinaryM_MM<string intrinsic, string instruction> { | multiclass VPatBinaryM_MM<string intrinsic, string instruction> { | ||||
foreach mti = AllMasks in | foreach mti = AllMasks in | ||||
def : VPatBinaryM<intrinsic, instruction # "_MM_" # mti.LMul.MX, | def : VPatBinaryM<intrinsic, instruction # "_MM_" # mti.LMul.MX, | ||||
mti.Mask, mti.Mask, mti.Mask, | mti.Mask, mti.Mask, mti.Mask, | ||||
mti.Log2SEW, VR, VR>; | mti.Log2SEW, VR, VR>; | ||||
} | } | ||||
multiclass VPatBinaryW_VV<string intrinsic, string instruction, | multiclass VPatBinaryW_VV<string intrinsic, string instruction, | ||||
▲ Show 20 Lines • Show All 1,339 Lines • ▼ Show 20 Lines | |||||
defm PseudoVRGATHER : VPseudoVGTR_VV_VX_VI<uimm5, "@earlyclobber $rd">; | defm PseudoVRGATHER : VPseudoVGTR_VV_VX_VI<uimm5, "@earlyclobber $rd">; | ||||
defm PseudoVRGATHEREI16 : VPseudoVGTR_VV_EEW</* eew */ 16, "@earlyclobber $rd">; | defm PseudoVRGATHEREI16 : VPseudoVGTR_VV_EEW</* eew */ 16, "@earlyclobber $rd">; | ||||
//===----------------------------------------------------------------------===// | //===----------------------------------------------------------------------===// | ||||
// 17.5. Vector Compress Instruction | // 17.5. Vector Compress Instruction | ||||
//===----------------------------------------------------------------------===// | //===----------------------------------------------------------------------===// | ||||
defm PseudoVCOMPRESS : VPseudoVCPR_V; | defm PseudoVCOMPRESS : VPseudoVCPR_V; | ||||
let Predicates = [HasStdExtZvkns] in { | |||||
It looks like this is part of the Vector Compress Instruction section. Should we add a vector crypto comment to separate? michaelmaitland: It looks like this is part of the Vector Compress Instruction section. Should we add a vector… | |||||
Sure, thanks! 4vtomat: Sure, thanks! | |||||
defm PseudoVAESDF : PPseudoVALU_V_S_NoMask; | |||||
defm PseudoVAESDM : PPseudoVALU_V_S_NoMask; | |||||
defm PseudoVAESEF : PPseudoVALU_V_S_NoMask; | |||||
defm PseudoVAESEM : PPseudoVALU_V_S_NoMask; | |||||
defm PseudoVAESKF1 : PPseudoVALU_VI_NoMask<uimm5>; | |||||
defm PseudoVAESKF2 : PPseudoVALU_VI_NoMask<uimm5>; | |||||
defm PseudoVAESZ : PPseudoVALU_S_NoMask; | |||||
} // Predicates = [HasStdExtZvkns] | |||||
let Predicates = [HasStdExtZvkb] in { | |||||
defm PseudoVANDN : VPseudoVALU_VV_VX_VI; | |||||
defm PseudoVBREV8 : VPseudoVALU_V; | |||||
defm PseudoVCLMUL : VPseudoVALU_VCLMUL; | |||||
defm PseudoVCLMULH : VPseudoVALU_VCLMUL; | |||||
defm PseudoVREV8 : VPseudoVALU_V; | |||||
defm PseudoVROL : VPseudoVALU_VV_VX_VI; | |||||
defm PseudoVROR : VPseudoVALU_VV_VX_VI; | |||||
} // Predicates = [HasStdExtZvkb] | |||||
let Predicates = [HasStdExtZvkg] in { | |||||
defm PseudoVGHMAC : PPseudoVALU_VV_NoMask; | |||||
} // Predicates = [HasStdExtZvkg] | |||||
let Predicates = [HasStdExtZvksed] in { | |||||
defm PseudoVSM4K : PPseudoVALU_VI_NoMask<uimm5>; | |||||
defm PseudoVSM4R : PPseudoVALU_V_NoMask; | |||||
} // Predicates = [HasStdExtZvksed] | |||||
let Predicates = [HasStdExtZvksh] in { | |||||
defm PseudoVSM3C : PPseudoVALU_VI_NoMask<uimm5>; | |||||
defm PseudoVSM3ME : PPseudoVALU_VV_NoMask; | |||||
} // Predicates = [HasStdExtZvksh] | |||||
let Predicates = [HasStdExtZvknhaOrZvknhb] in { | |||||
defm PseudoVSHA2CH : PPseudoVALU_VV_NoMask; | |||||
defm PseudoVSHA2CL : PPseudoVALU_VV_NoMask; | |||||
defm PseudoVSHA2MS : PPseudoVALU_VV_NoMask; | |||||
} // Predicates = [HasStdExtZvknhaOrZvknhb] | |||||
//===----------------------------------------------------------------------===// | //===----------------------------------------------------------------------===// | ||||
// Patterns. | // Patterns. | ||||
//===----------------------------------------------------------------------===// | //===----------------------------------------------------------------------===// | ||||
//===----------------------------------------------------------------------===// | //===----------------------------------------------------------------------===// | ||||
// 12. Vector Integer Arithmetic Instructions | // 12. Vector Integer Arithmetic Instructions | ||||
//===----------------------------------------------------------------------===// | //===----------------------------------------------------------------------===// | ||||
▲ Show 20 Lines • Show All 563 Lines • ▼ Show 20 Lines | |||||
let Predicates = [HasVInstructions] in { | let Predicates = [HasVInstructions] in { | ||||
defm : VPatUnaryV_V_AnyMask<"int_riscv_vcompress", "PseudoVCOMPRESS", AllIntegerVectors>; | defm : VPatUnaryV_V_AnyMask<"int_riscv_vcompress", "PseudoVCOMPRESS", AllIntegerVectors>; | ||||
} // Predicates = [HasVInstructions] | } // Predicates = [HasVInstructions] | ||||
let Predicates = [HasVInstructionsAnyF] in { | let Predicates = [HasVInstructionsAnyF] in { | ||||
defm : VPatUnaryV_V_AnyMask<"int_riscv_vcompress", "PseudoVCOMPRESS", AllFloatVectors>; | defm : VPatUnaryV_V_AnyMask<"int_riscv_vcompress", "PseudoVCOMPRESS", AllFloatVectors>; | ||||
} // Predicates = [HasVInstructionsAnyF] | } // Predicates = [HasVInstructionsAnyF] | ||||
let Predicates = [HasStdExtZvkns] in { | |||||
It looks like this is part of the Vector Compress Instruction section. Should we add a vector crypto comment to separate? michaelmaitland: It looks like this is part of the Vector Compress Instruction section. Should we add a vector… | |||||
defm : PPatUnaryV_V_S_NoMask<"int_riscv_vaesdf", "PseudoVAESDF", I32IntegerVectors>; | |||||
defm : PPatUnaryV_V_S_NoMask<"int_riscv_vaesdm", "PseudoVAESDM", I32IntegerVectors>; | |||||
defm : PPatUnaryV_V_S_NoMask<"int_riscv_vaesef", "PseudoVAESEF", I32IntegerVectors>; | |||||
defm : PPatUnaryV_V_S_NoMask<"int_riscv_vaesem", "PseudoVAESEM", I32IntegerVectors>; | |||||
defm : VPatBinaryV_VI_NoMask<"int_riscv_vaeskf1", "PseudoVAESKF1", I32IntegerVectors, uimm5>; | |||||
defm : VPatBinaryV_VI_NoMask<"int_riscv_vaeskf2", "PseudoVAESKF2", I32IntegerVectors, uimm5>; | |||||
defm : PPatUnaryV_S_NoMask<"int_riscv_vaesz", "PseudoVAESZ", I32IntegerVectors>; | |||||
} // Predicates = [HasStdExtZvkns] | |||||
let Predicates = [HasStdExtZvkb] in { | |||||
defm : VPatBinaryV_VV_VX_VI<"int_riscv_vandn", "PseudoVANDN", AllIntegerVectors>; | |||||
Not Done ReplyInline ActionsWe will need to implement a VI version of the vrol intrinsic using the vror.vi instruction by changing the amount to sew-rotamount. craig.topper: We will need to implement a VI version of the vrol intrinsic using the vror.vi instruction by… | |||||
defm : VPatUnaryV_V<"int_riscv_vbrev8", "PseudoVBREV8", AllIntegerVectors>; | |||||
VPatBinaryV_VV_VX_VI defaults simm5, but vror.vi uses uimm6. craig.topper: VPatBinaryV_VV_VX_VI defaults simm5, but vror.vi uses uimm6. | |||||
Oh, I forgot this instruction has different encoding of immediate, thanks! 4vtomat: Oh, I forgot this instruction has different encoding of immediate, thanks! | |||||
defm : VPatBinaryV_VV_VX<"int_riscv_vclmul", "PseudoVCLMUL", I64IntegerVectors>; | |||||
defm : VPatBinaryV_VV_VX<"int_riscv_vclmulh", "PseudoVCLMULH", I64IntegerVectors>; | |||||
defm : VPatUnaryV_V<"int_riscv_vrev8", "PseudoVREV8", AllIntegerVectors>; | |||||
defm : VPatBinaryV_VV_VX_VI<"int_riscv_vrol", "PseudoVROL", AllIntegerVectors>; | |||||
defm : VPatBinaryV_VV_VX_VI<"int_riscv_vror", "PseudoVROR", AllIntegerVectors>; | |||||
} // Predicates = [HasStdExtZvkb] | |||||
let Predicates = [HasStdExtZvkg] in { | |||||
defm : VPatBinaryV_VV_NoMask<"int_riscv_vghmac", "PseudoVGHMAC", I32IntegerVectors>; | |||||
} // Predicates = [HasStdExtZvkg] | |||||
let Predicates = [HasStdExtZvksed] in { | |||||
defm : VPatBinaryV_VI_NoMask<"int_riscv_vsm4k", "PseudoVSM4K", I32IntegerVectors, uimm5>; | |||||
defm : PPatUnaryV_V_NoMask<"int_riscv_vsm4r", "PseudoVSM4R", I32IntegerVectors>; | |||||
} // Predicates = [HasStdExtZvksed] | |||||
let Predicates = [HasStdExtZvksh] in { | |||||
defm : VPatBinaryV_VI_NoMask<"int_riscv_vsm3c", "PseudoVSM3C", I32IntegerVectors, uimm5>; | |||||
defm : VPatBinaryV_VV_NoMask<"int_riscv_vsm3me", "PseudoVSM3ME", I32IntegerVectors>; | |||||
} // Predicates = [HasStdExtZvksh] | |||||
let Predicates = [HasStdExtZvknhaOrZvknhb] in { | |||||
defm : VPatBinaryV_VV_NoMask<"int_riscv_vsha2ch", "PseudoVSHA2CH", I32I64IntegerVectors>; | |||||
defm : VPatBinaryV_VV_NoMask<"int_riscv_vsha2cl", "PseudoVSHA2CH", I32I64IntegerVectors>; | |||||
defm : VPatBinaryV_VV_NoMask<"int_riscv_vsha2ms", "PseudoVSHA2MS", I32I64IntegerVectors>; | |||||
} // Predicates = [HasStdExtZvknhaOrZvknhb] | |||||
// Include the non-intrinsic ISel patterns | // Include the non-intrinsic ISel patterns | ||||
include "RISCVInstrInfoVVLPatterns.td" | include "RISCVInstrInfoVVLPatterns.td" | ||||
include "RISCVInstrInfoVSDPatterns.td" | include "RISCVInstrInfoVSDPatterns.td" |
Is there a reason behind using PPseudo instead of VPseudo? If its the same P as the other parts of this patch, should we keep it a suffix instead of prefix?