summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/ARM/ARMInstrMVE.td
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Target/ARM/ARMInstrMVE.td')
-rw-r--r--llvm/lib/Target/ARM/ARMInstrMVE.td363
1 files changed, 363 insertions, 0 deletions
diff --git a/llvm/lib/Target/ARM/ARMInstrMVE.td b/llvm/lib/Target/ARM/ARMInstrMVE.td
index 06fb3ece389..5393435fdc8 100644
--- a/llvm/lib/Target/ARM/ARMInstrMVE.td
+++ b/llvm/lib/Target/ARM/ARMInstrMVE.td
@@ -10,6 +10,100 @@
//
//===----------------------------------------------------------------------===//
+// VPT condition mask
+def vpt_mask : Operand<i32> {
+ let PrintMethod = "printVPTMask";
+ let ParserMatchClass = it_mask_asmoperand;
+ let EncoderMethod = "getVPTMaskOpValue";
+ let DecoderMethod = "DecodeVPTMaskOperand";
+}
+
+// VPT/VCMP restricted predicate for sign invariant types
+def pred_restricted_i_asmoperand : AsmOperandClass {
+ let Name = "CondCodeRestrictedI";
+ let RenderMethod = "addITCondCodeOperands";
+ let PredicateMethod = "isITCondCodeRestrictedI";
+ let ParserMethod = "parseITCondCode";
+}
+
+// VPT/VCMP restricted predicate for signed types
+def pred_restricted_s_asmoperand : AsmOperandClass {
+ let Name = "CondCodeRestrictedS";
+ let RenderMethod = "addITCondCodeOperands";
+ let PredicateMethod = "isITCondCodeRestrictedS";
+ let ParserMethod = "parseITCondCode";
+}
+
+// VPT/VCMP restricted predicate for unsigned types
+def pred_restricted_u_asmoperand : AsmOperandClass {
+ let Name = "CondCodeRestrictedU";
+ let RenderMethod = "addITCondCodeOperands";
+ let PredicateMethod = "isITCondCodeRestrictedU";
+ let ParserMethod = "parseITCondCode";
+}
+
+// VPT/VCMP restricted predicate for floating point
+def pred_restricted_fp_asmoperand : AsmOperandClass {
+ let Name = "CondCodeRestrictedFP";
+ let RenderMethod = "addITCondCodeOperands";
+ let PredicateMethod = "isITCondCodeRestrictedFP";
+ let ParserMethod = "parseITCondCode";
+}
+
+def pred_basic_i : Operand<i32> {
+ let PrintMethod = "printMandatoryRestrictedPredicateOperand";
+ let ParserMatchClass = pred_restricted_i_asmoperand;
+ let DecoderMethod = "DecodeRestrictedIPredicateOperand";
+ let EncoderMethod = "getRestrictedCondCodeOpValue";
+}
+
+def pred_basic_u : Operand<i32> {
+ let PrintMethod = "printMandatoryRestrictedPredicateOperand";
+ let ParserMatchClass = pred_restricted_u_asmoperand;
+ let DecoderMethod = "DecodeRestrictedUPredicateOperand";
+ let EncoderMethod = "getRestrictedCondCodeOpValue";
+}
+
+def pred_basic_s : Operand<i32> {
+ let PrintMethod = "printMandatoryRestrictedPredicateOperand";
+ let ParserMatchClass = pred_restricted_s_asmoperand;
+ let DecoderMethod = "DecodeRestrictedSPredicateOperand";
+ let EncoderMethod = "getRestrictedCondCodeOpValue";
+}
+
+def pred_basic_fp : Operand<i32> {
+ let PrintMethod = "printMandatoryRestrictedPredicateOperand";
+ let ParserMatchClass = pred_restricted_fp_asmoperand;
+ let DecoderMethod = "DecodeRestrictedFPPredicateOperand";
+ let EncoderMethod = "getRestrictedCondCodeOpValue";
+}
+
+class MVE_MI<dag oops, dag iops, InstrItinClass itin, string asm,
+ string ops, string cstr, list<dag> pattern>
+ : Thumb2XI<oops, iops, AddrModeNone, 4, itin, !strconcat(asm, "\t", ops), cstr,
+ pattern>,
+ Requires<[HasMVEInt]> {
+ let D = MVEDomain;
+ let DecoderNamespace = "MVE";
+}
+
+// MVE_p is used for most predicated instructions, to add the cluster
+// of input operands that provides the VPT suffix (none, T or E) and
+// the input predicate register.
+class MVE_p<dag oops, dag iops, InstrItinClass itin, string iname,
+ string suffix, string ops, vpred_ops vpred, string cstr,
+ list<dag> pattern=[]>
+ : MVE_MI<oops, !con(iops, (ins vpred:$vp)), itin,
+ // If the instruction has a suffix, like vadd.f32, then the
+ // VPT predication suffix goes before the dot, so the full
+ // name has to be "vadd${vp}.f32".
+ !strconcat(iname, "${vp}",
+ !if(!eq(suffix, ""), "", !strconcat(".", suffix))),
+ ops, !strconcat(cstr, vpred.vpred_constraint), pattern> {
+ let Inst{31-29} = 0b111;
+ let Inst{27-26} = 0b11;
+}
+
class MVE_MI_with_pred<dag oops, dag iops, InstrItinClass itin, string asm,
string ops, string cstr, list<dag> pattern>
: Thumb2I<oops, iops, AddrModeNone, 4, itin, asm, !strconcat("\t", ops), cstr,
@@ -128,3 +222,272 @@ def t2SRSHRL : t2MVEShiftDRegImm<"srshrl", 0b10, 0b1>;
def t2UQRSHLL : t2MVEShiftDRegReg<"uqrshll", 0b0, 0b1>;
def t2UQSHLL : t2MVEShiftDRegImm<"uqshll", 0b00, 0b1>;
def t2URSHRL : t2MVEShiftDRegImm<"urshrl", 0b01, 0b1>;
+
+// start of mve_rDest instructions
+
+class MVE_rDest<dag oops, dag iops, InstrItinClass itin, string iname, string suffix,
+ string ops, string cstr, list<dag> pattern=[]>
+// Always use vpred_n and not vpred_r: with the output register being
+// a GPR and not a vector register, there can't be any question of
+// what to put in its inactive lanes.
+ : MVE_p<oops, iops, itin, iname, suffix, ops, vpred_n, cstr, pattern> {
+
+ let Inst{25-23} = 0b101;
+ let Inst{11-9} = 0b111;
+ let Inst{4} = 0b0;
+}
+
+class t2VABAV<string suffix, bit U, bits<2> size, list<dag> pattern=[]>
+ : MVE_rDest<(outs rGPR:$Rda), (ins rGPR:$Rda_src, MQPR:$Qn, MQPR:$Qm),
+ NoItinerary, "vabav", suffix, "$Rda, $Qn, $Qm", "$Rda = $Rda_src",
+ pattern> {
+ bits<4> Qm;
+ bits<4> Qn;
+ bits<4> Rda;
+
+ let Inst{28} = U;
+ let Inst{22} = 0b0;
+ let Inst{21-20} = size{1-0};
+ let Inst{19-17} = Qn{2-0};
+ let Inst{16} = 0b0;
+ let Inst{15-12} = Rda{3-0};
+ let Inst{8} = 0b1;
+ let Inst{7} = Qn{3};
+ let Inst{6} = 0b0;
+ let Inst{5} = Qm{3};
+ let Inst{3-1} = Qm{2-0};
+ let Inst{0} = 0b1;
+}
+
+def VABAVs8 : t2VABAV<"s8", 0b0, 0b00>;
+def VABAVs16 : t2VABAV<"s16", 0b0, 0b01>;
+def VABAVs32 : t2VABAV<"s32", 0b0, 0b10>;
+def VABAVu8 : t2VABAV<"u8", 0b1, 0b00>;
+def VABAVu16 : t2VABAV<"u16", 0b1, 0b01>;
+def VABAVu32 : t2VABAV<"u32", 0b1, 0b10>;
+
+// end of mve_rDest instructions
+
+// start of mve_comp instructions
+
+class MVE_comp<InstrItinClass itin, string iname, string suffix,
+ string cstr, list<dag> pattern=[]>
+ : MVE_p<(outs MQPR:$Qd), (ins MQPR:$Qn, MQPR:$Qm), itin, iname, suffix,
+ "$Qd, $Qn, $Qm", vpred_r, cstr, pattern> {
+ bits<4> Qd;
+ bits<4> Qn;
+ bits<4> Qm;
+
+ let Inst{22} = Qd{3};
+ let Inst{19-17} = Qn{2-0};
+ let Inst{16} = 0b0;
+ let Inst{15-13} = Qd{2-0};
+ let Inst{12} = 0b0;
+ let Inst{10-9} = 0b11;
+ let Inst{7} = Qn{3};
+ let Inst{5} = Qm{3};
+ let Inst{3-1} = Qm{2-0};
+ let Inst{0} = 0b0;
+}
+
+class VMINMAXNM<string iname, string suffix, bit sz, bit bit_21,
+ list<dag> pattern=[]>
+ : MVE_comp<NoItinerary, iname, suffix, "", pattern> {
+
+ let Inst{28} = 0b1;
+ let Inst{25-24} = 0b11;
+ let Inst{23} = 0b0;
+ let Inst{21} = bit_21;
+ let Inst{20} = sz;
+ let Inst{11} = 0b1;
+ let Inst{8} = 0b1;
+ let Inst{6} = 0b1;
+ let Inst{4} = 0b1;
+
+ let Predicates = [HasMVEFloat];
+}
+
+def VMAXNMf32 : VMINMAXNM<"vmaxnm", "f32", 0b0, 0b0>;
+def VMAXNMf16 : VMINMAXNM<"vmaxnm", "f16", 0b1, 0b0>;
+
+def VMINNMf32 : VMINMAXNM<"vminnm", "f32", 0b0, 0b1>;
+def VMINNMf16 : VMINMAXNM<"vminnm", "f16", 0b1, 0b1>;
+
+// end of mve_comp instructions
+
+class t2VPT<string suffix, bits<2> size, dag iops, string asm, list<dag> pattern=[]>
+ : MVE_MI<(outs ), iops, NoItinerary, !strconcat("vpt", "${Mk}", ".", suffix), asm, "", pattern> {
+ bits<3> fc;
+ bits<4> Mk;
+ bits<3> Qn;
+
+ let Inst{31-23} = 0b111111100;
+ let Inst{22} = Mk{3};
+ let Inst{21-20} = size;
+ let Inst{19-17} = Qn{2-0};
+ let Inst{16} = 0b1;
+ let Inst{15-13} = Mk{2-0};
+ let Inst{12} = fc{2};
+ let Inst{11-8} = 0b1111;
+ let Inst{7} = fc{0};
+ let Inst{4} = 0b0;
+
+ let Defs = [VPR, P0];
+}
+
+class t2VPTt1<string suffix, bits<2> size, dag iops>
+ : t2VPT<suffix, size, iops, "$fc, $Qn, $Qm"> {
+ bits<4> Qm;
+ bits<4> Mk;
+
+ let Inst{6} = 0b0;
+ let Inst{5} = Qm{3};
+ let Inst{3-1} = Qm{2-0};
+ let Inst{0} = fc{1};
+}
+
+class t2VPTt1i<string suffix, bits<2> size>
+ : t2VPTt1<suffix, size,
+ (ins vpt_mask:$Mk, pred_basic_i:$fc, MQPR:$Qn, MQPR:$Qm)> {
+ let Inst{12} = 0b0;
+ let Inst{0} = 0b0;
+}
+
+def t2VPTv4i32 : t2VPTt1i<"i32", 0b10>;
+def t2VPTv8i16 : t2VPTt1i<"i16", 0b01>;
+def t2VPTv16i8 : t2VPTt1i<"i8", 0b00>;
+
+class t2VPTt1u<string suffix, bits<2> size>
+ : t2VPTt1<suffix, size,
+ (ins vpt_mask:$Mk, pred_basic_u:$fc, MQPR:$Qn, MQPR:$Qm)> {
+ let Inst{12} = 0b0;
+ let Inst{0} = 0b1;
+}
+
+def t2VPTv4u32 : t2VPTt1u<"u32", 0b10>;
+def t2VPTv8u16 : t2VPTt1u<"u16", 0b01>;
+def t2VPTv16u8 : t2VPTt1u<"u8", 0b00>;
+
+class t2VPTt1s<string suffix, bits<2> size>
+ : t2VPTt1<suffix, size,
+ (ins vpt_mask:$Mk, pred_basic_s:$fc, MQPR:$Qn, MQPR:$Qm)> {
+ let Inst{12} = 0b1;
+}
+
+def t2VPTv4s32 : t2VPTt1s<"s32", 0b10>;
+def t2VPTv8s16 : t2VPTt1s<"s16", 0b01>;
+def t2VPTv16s8 : t2VPTt1s<"s8", 0b00>;
+
+class t2VPTt2<string suffix, bits<2> size, dag iops>
+ : t2VPT<suffix, size, iops,
+ "$fc, $Qn, $Rm"> {
+ bits<4> Rm;
+ bits<3> fc;
+ bits<4> Mk;
+
+ let Inst{6} = 0b1;
+ let Inst{5} = fc{1};
+ let Inst{3-0} = Rm{3-0};
+}
+
+class t2VPTt2i<string suffix, bits<2> size>
+ : t2VPTt2<suffix, size,
+ (ins vpt_mask:$Mk, pred_basic_i:$fc, MQPR:$Qn, GPRwithZR:$Rm)> {
+ let Inst{12} = 0b0;
+ let Inst{5} = 0b0;
+}
+
+def t2VPTv4i32r : t2VPTt2i<"i32", 0b10>;
+def t2VPTv8i16r : t2VPTt2i<"i16", 0b01>;
+def t2VPTv16i8r : t2VPTt2i<"i8", 0b00>;
+
+class t2VPTt2u<string suffix, bits<2> size>
+ : t2VPTt2<suffix, size,
+ (ins vpt_mask:$Mk, pred_basic_u:$fc, MQPR:$Qn, GPRwithZR:$Rm)> {
+ let Inst{12} = 0b0;
+ let Inst{5} = 0b1;
+}
+
+def t2VPTv4u32r : t2VPTt2u<"u32", 0b10>;
+def t2VPTv8u16r : t2VPTt2u<"u16", 0b01>;
+def t2VPTv16u8r : t2VPTt2u<"u8", 0b00>;
+
+class t2VPTt2s<string suffix, bits<2> size>
+ : t2VPTt2<suffix, size,
+ (ins vpt_mask:$Mk, pred_basic_s:$fc, MQPR:$Qn, GPRwithZR:$Rm)> {
+ let Inst{12} = 0b1;
+}
+
+def t2VPTv4s32r : t2VPTt2s<"s32", 0b10>;
+def t2VPTv8s16r : t2VPTt2s<"s16", 0b01>;
+def t2VPTv16s8r : t2VPTt2s<"s8", 0b00>;
+
+
+class t2VPTf<string suffix, bit size, dag iops, string asm, list<dag> pattern=[]>
+ : MVE_MI<(outs ), iops, NoItinerary, !strconcat("vpt", "${Mk}", ".", suffix), asm,
+ "", pattern> {
+ bits<3> fc;
+ bits<4> Mk;
+ bits<3> Qn;
+
+ let Inst{31-29} = 0b111;
+ let Inst{28} = size;
+ let Inst{27-23} = 0b11100;
+ let Inst{22} = Mk{3};
+ let Inst{21-20} = 0b11;
+ let Inst{19-17} = Qn{2-0};
+ let Inst{16} = 0b1;
+ let Inst{15-13} = Mk{2-0};
+ let Inst{12} = fc{2};
+ let Inst{11-8} = 0b1111;
+ let Inst{7} = fc{0};
+ let Inst{4} = 0b0;
+
+ let Defs = [P0];
+ let Predicates = [HasMVEFloat];
+}
+
+class t2VPTft1<string suffix, bit size>
+ : t2VPTf<suffix, size, (ins vpt_mask:$Mk, pred_basic_fp:$fc, MQPR:$Qn, MQPR:$Qm),
+ "$fc, $Qn, $Qm"> {
+ bits<3> fc;
+ bits<4> Qm;
+
+ let Inst{6} = 0b0;
+ let Inst{5} = Qm{3};
+ let Inst{3-1} = Qm{2-0};
+ let Inst{0} = fc{1};
+}
+
+def t2VPTv4f32 : t2VPTft1<"f32", 0b0>;
+def t2VPTv8f16 : t2VPTft1<"f16", 0b1>;
+
+class t2VPTft2<string suffix, bit size>
+ : t2VPTf<suffix, size, (ins vpt_mask:$Mk, pred_basic_fp:$fc, MQPR:$Qn, GPRwithZR:$Rm),
+ "$fc, $Qn, $Rm"> {
+ bits<3> fc;
+ bits<4> Rm;
+
+ let Inst{6} = 0b1;
+ let Inst{5} = fc{1};
+ let Inst{3-0} = Rm{3-0};
+}
+
+def t2VPTv4f32r : t2VPTft2<"f32", 0b0>;
+def t2VPTv8f16r : t2VPTft2<"f16", 0b1>;
+
+def t2VPST : MVE_MI<(outs ), (ins vpt_mask:$Mk), NoItinerary,
+ !strconcat("vpst", "${Mk}"), "", "", []> {
+ bits<4> Mk;
+
+ let Inst{31-23} = 0b111111100;
+ let Inst{22} = Mk{3};
+ let Inst{21-16} = 0b110001;
+ let Inst{15-13} = Mk{2-0};
+ let Inst{12-0} = 0b0111101001101;
+ let Unpredictable{12} = 0b1;
+ let Unpredictable{7} = 0b1;
+ let Unpredictable{5} = 0b1;
+
+ let Defs = [P0];
+}
OpenPOWER on IntegriCloud