[llvm] r366054 - [ARM] Move Shifts after Bits. NFC
David Green via llvm-commits
llvm-commits at lists.llvm.org
Mon Jul 15 04:22:05 PDT 2019
Author: dmgreen
Date: Mon Jul 15 04:22:05 2019
New Revision: 366054
URL: http://llvm.org/viewvc/llvm-project?rev=366054&view=rev
Log:
[ARM] Move Shifts after Bits. NFC
This just moves the shift instruction definitions further down the
ARMInstrMVE.td file, to make positioning patterns slightly more natural.
Modified:
llvm/trunk/lib/Target/ARM/ARMInstrMVE.td
Modified: llvm/trunk/lib/Target/ARM/ARMInstrMVE.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrMVE.td?rev=366054&r1=366053&r2=366054&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMInstrMVE.td (original)
+++ llvm/trunk/lib/Target/ARM/ARMInstrMVE.td Mon Jul 15 04:22:05 2019
@@ -939,30 +939,11 @@ let Predicates = [HasMVEInt] in {
// end of mve_comp instructions
-// start of mve_imm_shift instructions
-
-def MVE_VSHLC : MVE_p<(outs rGPR:$RdmDest, MQPR:$Qd),
- (ins MQPR:$QdSrc, rGPR:$RdmSrc, long_shift:$imm),
- NoItinerary, "vshlc", "", "$QdSrc, $RdmSrc, $imm",
- vpred_n, "$RdmDest = $RdmSrc,$Qd = $QdSrc"> {
- bits<5> imm;
- bits<4> Qd;
- bits<4> RdmDest;
-
- let Inst{28} = 0b0;
- let Inst{25-23} = 0b101;
- let Inst{22} = Qd{3};
- let Inst{21} = 0b1;
- let Inst{20-16} = imm{4-0};
- let Inst{15-13} = Qd{2-0};
- let Inst{12-4} = 0b011111100;
- let Inst{3-0} = RdmDest{3-0};
-}
+// start of mve_bit instructions
-class MVE_shift_imm<dag oops, dag iops, string iname, string suffix,
- string ops, vpred_ops vpred, string cstr,
- list<dag> pattern=[]>
- : MVE_p<oops, iops, NoItinerary, iname, suffix, ops, vpred, cstr, pattern> {
+class MVE_bit_arith<dag oops, dag iops, string iname, string suffix,
+ string ops, string cstr, list<dag> pattern=[]>
+ : MVE_p<oops, iops, NoItinerary, iname, suffix, ops, vpred_r, cstr, pattern> {
bits<4> Qd;
bits<4> Qm;
@@ -972,1378 +953,1398 @@ class MVE_shift_imm<dag oops, dag iops,
let Inst{3-1} = Qm{2-0};
}
-class MVE_VMOVL<string iname, string suffix, bits<2> sz, bit U,
- list<dag> pattern=[]>
- : MVE_shift_imm<(outs MQPR:$Qd), (ins MQPR:$Qm),
- iname, suffix, "$Qd, $Qm", vpred_r, "",
- pattern> {
- let Inst{28} = U;
- let Inst{25-23} = 0b101;
- let Inst{21} = 0b1;
- let Inst{20-19} = sz{1-0};
- let Inst{18-16} = 0b000;
- let Inst{11-6} = 0b111101;
- let Inst{4} = 0b0;
+def MVE_VBIC : MVE_bit_arith<(outs MQPR:$Qd), (ins MQPR:$Qn, MQPR:$Qm),
+ "vbic", "", "$Qd, $Qn, $Qm", ""> {
+ bits<4> Qn;
+
+ let Inst{28} = 0b0;
+ let Inst{25-23} = 0b110;
+ let Inst{21-20} = 0b01;
+ let Inst{19-17} = Qn{2-0};
+ let Inst{16} = 0b0;
+ let Inst{12-8} = 0b00001;
+ let Inst{7} = Qn{3};
+ let Inst{6} = 0b1;
+ let Inst{4} = 0b1;
let Inst{0} = 0b0;
}
-multiclass MVE_VMOVL_shift_half<string iname, string suffix, bits<2> sz, bit U,
- list<dag> pattern=[]> {
- def bh : MVE_VMOVL<!strconcat(iname, "b"), suffix, sz, U, pattern> {
- let Inst{12} = 0b0;
- }
- def th : MVE_VMOVL<!strconcat(iname, "t"), suffix, sz, U, pattern> {
- let Inst{12} = 0b1;
- }
+class MVE_VREV<string iname, string suffix, bits<2> size, bits<2> bit_8_7>
+ : MVE_bit_arith<(outs MQPR:$Qd), (ins MQPR:$Qm), iname,
+ suffix, "$Qd, $Qm", ""> {
+
+ let Inst{28} = 0b1;
+ let Inst{25-23} = 0b111;
+ let Inst{21-20} = 0b11;
+ let Inst{19-18} = size;
+ let Inst{17-16} = 0b00;
+ let Inst{12-9} = 0b0000;
+ let Inst{8-7} = bit_8_7;
+ let Inst{6} = 0b1;
+ let Inst{4} = 0b0;
+ let Inst{0} = 0b0;
}
-defm MVE_VMOVLs8 : MVE_VMOVL_shift_half<"vmovl", "s8", 0b01, 0b0>;
-defm MVE_VMOVLu8 : MVE_VMOVL_shift_half<"vmovl", "u8", 0b01, 0b1>;
-defm MVE_VMOVLs16 : MVE_VMOVL_shift_half<"vmovl", "s16", 0b10, 0b0>;
-defm MVE_VMOVLu16 : MVE_VMOVL_shift_half<"vmovl", "u16", 0b10, 0b1>;
+def MVE_VREV64_8 : MVE_VREV<"vrev64", "8", 0b00, 0b00>;
+def MVE_VREV64_16 : MVE_VREV<"vrev64", "16", 0b01, 0b00>;
+def MVE_VREV64_32 : MVE_VREV<"vrev64", "32", 0b10, 0b00>;
+
+def MVE_VREV32_8 : MVE_VREV<"vrev32", "8", 0b00, 0b01>;
+def MVE_VREV32_16 : MVE_VREV<"vrev32", "16", 0b01, 0b01>;
+
+def MVE_VREV16_8 : MVE_VREV<"vrev16", "8", 0b00, 0b10>;
let Predicates = [HasMVEInt] in {
- def : Pat<(sext_inreg (v4i32 MQPR:$src), v4i16),
- (MVE_VMOVLs16bh MQPR:$src)>;
- def : Pat<(sext_inreg (v8i16 MQPR:$src), v8i8),
- (MVE_VMOVLs8bh MQPR:$src)>;
- def : Pat<(sext_inreg (v4i32 MQPR:$src), v4i8),
- (MVE_VMOVLs16bh (MVE_VMOVLs8bh MQPR:$src))>;
+def : Pat<(v4i32 (ARMvrev64 (v4i32 MQPR:$src))),
+ (v4i32 (MVE_VREV64_32 (v4i32 MQPR:$src)))>;
+def : Pat<(v8i16 (ARMvrev64 (v8i16 MQPR:$src))),
+ (v8i16 (MVE_VREV64_16 (v8i16 MQPR:$src)))>;
+def : Pat<(v16i8 (ARMvrev64 (v16i8 MQPR:$src))),
+ (v16i8 (MVE_VREV64_8 (v16i8 MQPR:$src)))>;
- // zext_inreg 16 -> 32
- def : Pat<(and (v4i32 MQPR:$src), (v4i32 (ARMvmovImm (i32 0xCFF)))),
- (MVE_VMOVLu16bh MQPR:$src)>;
- // zext_inreg 8 -> 16
- def : Pat<(and (v8i16 MQPR:$src), (v8i16 (ARMvmovImm (i32 0x8FF)))),
- (MVE_VMOVLu8bh MQPR:$src)>;
-}
+def : Pat<(v8i16 (ARMvrev32 (v8i16 MQPR:$src))),
+ (v8i16 (MVE_VREV32_16 (v8i16 MQPR:$src)))>;
+def : Pat<(v16i8 (ARMvrev32 (v16i8 MQPR:$src))),
+ (v16i8 (MVE_VREV32_8 (v16i8 MQPR:$src)))>;
+def : Pat<(v16i8 (ARMvrev16 (v16i8 MQPR:$src))),
+ (v16i8 (MVE_VREV16_8 (v16i8 MQPR:$src)))>;
-class MVE_VSHLL_imm<string iname, string suffix, bit U, bit th,
- dag immops, list<dag> pattern=[]>
- : MVE_shift_imm<(outs MQPR:$Qd), !con((ins MQPR:$Qm), immops),
- iname, suffix, "$Qd, $Qm, $imm", vpred_r, "", pattern> {
- let Inst{28} = U;
- let Inst{25-23} = 0b101;
- let Inst{21} = 0b1;
- let Inst{12} = th;
- let Inst{11-6} = 0b111101;
+def : Pat<(v4f32 (ARMvrev64 (v4f32 MQPR:$src))),
+ (v4f32 (MVE_VREV64_32 (v4f32 MQPR:$src)))>;
+def : Pat<(v8f16 (ARMvrev64 (v8f16 MQPR:$src))),
+ (v8f16 (MVE_VREV64_16 (v8f16 MQPR:$src)))>;
+def : Pat<(v8f16 (ARMvrev32 (v8f16 MQPR:$src))),
+ (v8f16 (MVE_VREV32_16 (v8f16 MQPR:$src)))>;
+}
+
+def MVE_VMVN : MVE_bit_arith<(outs MQPR:$Qd), (ins MQPR:$Qm),
+ "vmvn", "", "$Qd, $Qm", ""> {
+ let Inst{28} = 0b1;
+ let Inst{25-23} = 0b111;
+ let Inst{21-16} = 0b110000;
+ let Inst{12-6} = 0b0010111;
let Inst{4} = 0b0;
let Inst{0} = 0b0;
}
-// The immediate VSHLL instructions accept shift counts from 1 up to
-// the lane width (8 or 16), but the full-width shifts have an
-// entirely separate encoding, given below with 'lw' in the name.
-
-class MVE_VSHLL_imm8<string iname, string suffix,
- bit U, bit th, list<dag> pattern=[]>
- : MVE_VSHLL_imm<iname, suffix, U, th, (ins mve_shift_imm1_7:$imm), pattern> {
- bits<3> imm;
- let Inst{20-19} = 0b01;
- let Inst{18-16} = imm;
+let Predicates = [HasMVEInt] in {
+ def : Pat<(v16i8 (vnotq (v16i8 MQPR:$val1))),
+ (v16i8 (MVE_VMVN (v16i8 MQPR:$val1)))>;
+ def : Pat<(v8i16 (vnotq (v8i16 MQPR:$val1))),
+ (v8i16 (MVE_VMVN (v8i16 MQPR:$val1)))>;
+ def : Pat<(v4i32 (vnotq (v4i32 MQPR:$val1))),
+ (v4i32 (MVE_VMVN (v4i32 MQPR:$val1)))>;
}
-class MVE_VSHLL_imm16<string iname, string suffix,
- bit U, bit th, list<dag> pattern=[]>
- : MVE_VSHLL_imm<iname, suffix, U, th, (ins mve_shift_imm1_15:$imm), pattern> {
- bits<4> imm;
- let Inst{20} = 0b1;
- let Inst{19-16} = imm;
+class MVE_bit_ops<string iname, bits<2> bit_21_20, bit bit_28>
+ : MVE_bit_arith<(outs MQPR:$Qd), (ins MQPR:$Qn, MQPR:$Qm),
+ iname, "", "$Qd, $Qn, $Qm", ""> {
+ bits<4> Qn;
+
+ let Inst{28} = bit_28;
+ let Inst{25-23} = 0b110;
+ let Inst{21-20} = bit_21_20;
+ let Inst{19-17} = Qn{2-0};
+ let Inst{16} = 0b0;
+ let Inst{12-8} = 0b00001;
+ let Inst{7} = Qn{3};
+ let Inst{6} = 0b1;
+ let Inst{4} = 0b1;
+ let Inst{0} = 0b0;
}
-def MVE_VSHLL_imms8bh : MVE_VSHLL_imm8 <"vshllb", "s8", 0b0, 0b0>;
-def MVE_VSHLL_imms8th : MVE_VSHLL_imm8 <"vshllt", "s8", 0b0, 0b1>;
-def MVE_VSHLL_immu8bh : MVE_VSHLL_imm8 <"vshllb", "u8", 0b1, 0b0>;
-def MVE_VSHLL_immu8th : MVE_VSHLL_imm8 <"vshllt", "u8", 0b1, 0b1>;
-def MVE_VSHLL_imms16bh : MVE_VSHLL_imm16<"vshllb", "s16", 0b0, 0b0>;
-def MVE_VSHLL_imms16th : MVE_VSHLL_imm16<"vshllt", "s16", 0b0, 0b1>;
-def MVE_VSHLL_immu16bh : MVE_VSHLL_imm16<"vshllb", "u16", 0b1, 0b0>;
-def MVE_VSHLL_immu16th : MVE_VSHLL_imm16<"vshllt", "u16", 0b1, 0b1>;
+def MVE_VEOR : MVE_bit_ops<"veor", 0b00, 0b1>;
+def MVE_VORN : MVE_bit_ops<"vorn", 0b11, 0b0>;
+def MVE_VORR : MVE_bit_ops<"vorr", 0b10, 0b0>;
+def MVE_VAND : MVE_bit_ops<"vand", 0b00, 0b0>;
-class MVE_VSHLL_by_lane_width<string iname, string suffix, bits<2> size,
- bit U, string ops, list<dag> pattern=[]>
- : MVE_shift_imm<(outs MQPR:$Qd), (ins MQPR:$Qm),
- iname, suffix, ops, vpred_r, "", pattern> {
- let Inst{28} = U;
- let Inst{25-23} = 0b100;
- let Inst{21-20} = 0b11;
- let Inst{19-18} = size{1-0};
- let Inst{17-16} = 0b01;
- let Inst{11-6} = 0b111000;
- let Inst{4} = 0b0;
- let Inst{0} = 0b1;
-}
+// add ignored suffixes as aliases
-multiclass MVE_VSHLL_lw<string iname, string suffix, bits<2> sz, bit U,
- string ops, list<dag> pattern=[]> {
- def bh : MVE_VSHLL_by_lane_width<iname#"b", suffix, sz, U, ops, pattern> {
- let Inst{12} = 0b0;
- }
- def th : MVE_VSHLL_by_lane_width<iname#"t", suffix, sz, U, ops, pattern> {
- let Inst{12} = 0b1;
- }
+foreach s=["s8", "s16", "s32", "u8", "u16", "u32", "i8", "i16", "i32", "f16", "f32"] in {
+ def : MVEInstAlias<"vbic${vp}." # s # "\t$QdSrc, $QnSrc, $QmSrc",
+ (MVE_VBIC MQPR:$QdSrc, MQPR:$QnSrc, MQPR:$QmSrc, vpred_r:$vp)>;
+ def : MVEInstAlias<"veor${vp}." # s # "\t$QdSrc, $QnSrc, $QmSrc",
+ (MVE_VEOR MQPR:$QdSrc, MQPR:$QnSrc, MQPR:$QmSrc, vpred_r:$vp)>;
+ def : MVEInstAlias<"vorn${vp}." # s # "\t$QdSrc, $QnSrc, $QmSrc",
+ (MVE_VORN MQPR:$QdSrc, MQPR:$QnSrc, MQPR:$QmSrc, vpred_r:$vp)>;
+ def : MVEInstAlias<"vorr${vp}." # s # "\t$QdSrc, $QnSrc, $QmSrc",
+ (MVE_VORR MQPR:$QdSrc, MQPR:$QnSrc, MQPR:$QmSrc, vpred_r:$vp)>;
+ def : MVEInstAlias<"vand${vp}." # s # "\t$QdSrc, $QnSrc, $QmSrc",
+ (MVE_VAND MQPR:$QdSrc, MQPR:$QnSrc, MQPR:$QmSrc, vpred_r:$vp)>;
}
-defm MVE_VSHLL_lws8 : MVE_VSHLL_lw<"vshll", "s8", 0b00, 0b0, "$Qd, $Qm, #8">;
-defm MVE_VSHLL_lws16 : MVE_VSHLL_lw<"vshll", "s16", 0b01, 0b0, "$Qd, $Qm, #16">;
-defm MVE_VSHLL_lwu8 : MVE_VSHLL_lw<"vshll", "u8", 0b00, 0b1, "$Qd, $Qm, #8">;
-defm MVE_VSHLL_lwu16 : MVE_VSHLL_lw<"vshll", "u16", 0b01, 0b1, "$Qd, $Qm, #16">;
+let Predicates = [HasMVEInt] in {
+ def : Pat<(v16i8 (and (v16i8 MQPR:$val1), (v16i8 MQPR:$val2))),
+ (v16i8 (MVE_VAND (v16i8 MQPR:$val1), (v16i8 MQPR:$val2)))>;
+ def : Pat<(v8i16 (and (v8i16 MQPR:$val1), (v8i16 MQPR:$val2))),
+ (v8i16 (MVE_VAND (v8i16 MQPR:$val1), (v8i16 MQPR:$val2)))>;
+ def : Pat<(v4i32 (and (v4i32 MQPR:$val1), (v4i32 MQPR:$val2))),
+ (v4i32 (MVE_VAND (v4i32 MQPR:$val1), (v4i32 MQPR:$val2)))>;
-class MVE_VxSHRN<string iname, string suffix, bit bit_12, bit bit_28,
- dag immops, list<dag> pattern=[]>
- : MVE_shift_imm<(outs MQPR:$Qd), !con((ins MQPR:$QdSrc, MQPR:$Qm), immops),
- iname, suffix, "$Qd, $Qm, $imm", vpred_n, "$Qd = $QdSrc",
- pattern> {
- bits<5> imm;
+ def : Pat<(v16i8 (or (v16i8 MQPR:$val1), (v16i8 MQPR:$val2))),
+ (v16i8 (MVE_VORR (v16i8 MQPR:$val1), (v16i8 MQPR:$val2)))>;
+ def : Pat<(v8i16 (or (v8i16 MQPR:$val1), (v8i16 MQPR:$val2))),
+ (v8i16 (MVE_VORR (v8i16 MQPR:$val1), (v8i16 MQPR:$val2)))>;
+ def : Pat<(v4i32 (or (v4i32 MQPR:$val1), (v4i32 MQPR:$val2))),
+ (v4i32 (MVE_VORR (v4i32 MQPR:$val1), (v4i32 MQPR:$val2)))>;
- let Inst{28} = bit_28;
- let Inst{25-23} = 0b101;
- let Inst{21} = 0b0;
- let Inst{20-16} = imm{4-0};
- let Inst{12} = bit_12;
- let Inst{11-6} = 0b111111;
- let Inst{4} = 0b0;
- let Inst{0} = 0b1;
-}
+ def : Pat<(v16i8 (xor (v16i8 MQPR:$val1), (v16i8 MQPR:$val2))),
+ (v16i8 (MVE_VEOR (v16i8 MQPR:$val1), (v16i8 MQPR:$val2)))>;
+ def : Pat<(v8i16 (xor (v8i16 MQPR:$val1), (v8i16 MQPR:$val2))),
+ (v8i16 (MVE_VEOR (v8i16 MQPR:$val1), (v8i16 MQPR:$val2)))>;
+ def : Pat<(v4i32 (xor (v4i32 MQPR:$val1), (v4i32 MQPR:$val2))),
+ (v4i32 (MVE_VEOR (v4i32 MQPR:$val1), (v4i32 MQPR:$val2)))>;
-def MVE_VRSHRNi16bh : MVE_VxSHRN<
- "vrshrnb", "i16", 0b0, 0b1, (ins shr_imm8:$imm)> {
- let Inst{20-19} = 0b01;
-}
-def MVE_VRSHRNi16th : MVE_VxSHRN<
- "vrshrnt", "i16", 0b1, 0b1,(ins shr_imm8:$imm)> {
- let Inst{20-19} = 0b01;
-}
-def MVE_VRSHRNi32bh : MVE_VxSHRN<
- "vrshrnb", "i32", 0b0, 0b1, (ins shr_imm16:$imm)> {
- let Inst{20} = 0b1;
-}
-def MVE_VRSHRNi32th : MVE_VxSHRN<
- "vrshrnt", "i32", 0b1, 0b1, (ins shr_imm16:$imm)> {
- let Inst{20} = 0b1;
-}
+ def : Pat<(v16i8 (and (v16i8 MQPR:$val1), (vnotq MQPR:$val2))),
+ (v16i8 (MVE_VBIC (v16i8 MQPR:$val1), (v16i8 MQPR:$val2)))>;
+ def : Pat<(v8i16 (and (v8i16 MQPR:$val1), (vnotq MQPR:$val2))),
+ (v8i16 (MVE_VBIC (v8i16 MQPR:$val1), (v8i16 MQPR:$val2)))>;
+ def : Pat<(v4i32 (and (v4i32 MQPR:$val1), (vnotq MQPR:$val2))),
+ (v4i32 (MVE_VBIC (v4i32 MQPR:$val1), (v4i32 MQPR:$val2)))>;
-def MVE_VSHRNi16bh : MVE_VxSHRN<
- "vshrnb", "i16", 0b0, 0b0, (ins shr_imm8:$imm)> {
- let Inst{20-19} = 0b01;
-}
-def MVE_VSHRNi16th : MVE_VxSHRN<
- "vshrnt", "i16", 0b1, 0b0, (ins shr_imm8:$imm)> {
- let Inst{20-19} = 0b01;
+ def : Pat<(v16i8 (or (v16i8 MQPR:$val1), (vnotq (v16i8 MQPR:$val2)))),
+ (v16i8 (MVE_VORN (v16i8 MQPR:$val1), (v16i8 MQPR:$val2)))>;
+ def : Pat<(v8i16 (or (v8i16 MQPR:$val1), (vnotq MQPR:$val2))),
+ (v8i16 (MVE_VORN (v8i16 MQPR:$val1), (v8i16 MQPR:$val2)))>;
+ def : Pat<(v4i32 (or (v4i32 MQPR:$val1), (vnotq MQPR:$val2))),
+ (v4i32 (MVE_VORN (v4i32 MQPR:$val1), (v4i32 MQPR:$val2)))>;
}
-def MVE_VSHRNi32bh : MVE_VxSHRN<
- "vshrnb", "i32", 0b0, 0b0, (ins shr_imm16:$imm)> {
- let Inst{20} = 0b1;
+
+class MVE_bit_cmode<string iname, string suffix, bits<4> cmode, dag inOps>
+ : MVE_p<(outs MQPR:$Qd), inOps, NoItinerary,
+ iname, suffix, "$Qd, $imm", vpred_n, "$Qd = $Qd_src"> {
+ bits<8> imm;
+ bits<4> Qd;
+
+ let Inst{28} = imm{7};
+ let Inst{27-23} = 0b11111;
+ let Inst{22} = Qd{3};
+ let Inst{21-19} = 0b000;
+ let Inst{18-16} = imm{6-4};
+ let Inst{15-13} = Qd{2-0};
+ let Inst{12} = 0b0;
+ let Inst{11-8} = cmode;
+ let Inst{7-6} = 0b01;
+ let Inst{4} = 0b1;
+ let Inst{3-0} = imm{3-0};
}
-def MVE_VSHRNi32th : MVE_VxSHRN<
- "vshrnt", "i32", 0b1, 0b0, (ins shr_imm16:$imm)> {
- let Inst{20} = 0b1;
+
+class MVE_VORR<string suffix, bits<4> cmode, ExpandImm imm_type>
+ : MVE_bit_cmode<"vorr", suffix, cmode, (ins MQPR:$Qd_src, imm_type:$imm)> {
+ let Inst{5} = 0b0;
}
-class MVE_VxQRSHRUN<string iname, string suffix, bit bit_28, bit bit_12, dag immops,
- list<dag> pattern=[]>
- : MVE_shift_imm<(outs MQPR:$Qd), !con((ins MQPR:$QdSrc, MQPR:$Qm), immops),
- iname, suffix, "$Qd, $Qm, $imm", vpred_n, "$Qd = $QdSrc",
- pattern> {
- bits<5> imm;
+def MVE_VORRIZ0v4i32 : MVE_VORR<"i32", 0b0001, expzero00>;
+def MVE_VORRIZ0v8i16 : MVE_VORR<"i16", 0b1001, expzero00>;
+def MVE_VORRIZ8v4i32 : MVE_VORR<"i32", 0b0011, expzero08>;
+def MVE_VORRIZ8v8i16 : MVE_VORR<"i16", 0b1011, expzero08>;
+def MVE_VORRIZ16v4i32 : MVE_VORR<"i32", 0b0101, expzero16>;
+def MVE_VORRIZ24v4i32 : MVE_VORR<"i32", 0b0111, expzero24>;
- let Inst{28} = bit_28;
- let Inst{25-23} = 0b101;
- let Inst{21} = 0b0;
- let Inst{20-16} = imm{4-0};
- let Inst{12} = bit_12;
- let Inst{11-6} = 0b111111;
- let Inst{4} = 0b0;
- let Inst{0} = 0b0;
-}
+def MVE_VORNIZ0v4i32 : MVEAsmPseudo<"vorn${vp}.i32\t$Qd, $imm",
+ (ins MQPR:$Qd_src, expzero00inv32:$imm, vpred_n:$vp), (outs MQPR:$Qd)>;
+def MVE_VORNIZ0v8i16 : MVEAsmPseudo<"vorn${vp}.i16\t$Qd, $imm",
+ (ins MQPR:$Qd_src, expzero00inv16:$imm, vpred_n:$vp), (outs MQPR:$Qd)>;
+def MVE_VORNIZ8v4i32 : MVEAsmPseudo<"vorn${vp}.i32\t$Qd, $imm",
+ (ins MQPR:$Qd_src, expzero08inv32:$imm, vpred_n:$vp), (outs MQPR:$Qd)>;
+def MVE_VORNIZ8v8i16 : MVEAsmPseudo<"vorn${vp}.i16\t$Qd, $imm",
+ (ins MQPR:$Qd_src, expzero08inv16:$imm, vpred_n:$vp), (outs MQPR:$Qd)>;
+def MVE_VORNIZ16v4i32 : MVEAsmPseudo<"vorn${vp}.i32\t$Qd, $imm",
+ (ins MQPR:$Qd_src, expzero16inv32:$imm, vpred_n:$vp), (outs MQPR:$Qd)>;
+def MVE_VORNIZ24v4i32 : MVEAsmPseudo<"vorn${vp}.i32\t$Qd, $imm",
+ (ins MQPR:$Qd_src, expzero24inv32:$imm, vpred_n:$vp), (outs MQPR:$Qd)>;
-def MVE_VQRSHRUNs16bh : MVE_VxQRSHRUN<
- "vqrshrunb", "s16", 0b1, 0b0, (ins shr_imm8:$imm)> {
- let Inst{20-19} = 0b01;
+def MVE_VMOV : MVEInstAlias<"vmov${vp}\t$Qd, $Qm",
+ (MVE_VORR MQPR:$Qd, MQPR:$Qm, MQPR:$Qm, vpred_r:$vp)>;
+
+class MVE_VBIC<string suffix, bits<4> cmode, ExpandImm imm_type>
+ : MVE_bit_cmode<"vbic", suffix, cmode, (ins MQPR:$Qd_src, imm_type:$imm)> {
+ let Inst{5} = 0b1;
}
-def MVE_VQRSHRUNs16th : MVE_VxQRSHRUN<
- "vqrshrunt", "s16", 0b1, 0b1, (ins shr_imm8:$imm)> {
- let Inst{20-19} = 0b01;
+
+def MVE_VBICIZ0v4i32 : MVE_VBIC<"i32", 0b0001, expzero00>;
+def MVE_VBICIZ0v8i16 : MVE_VBIC<"i16", 0b1001, expzero00>;
+def MVE_VBICIZ8v4i32 : MVE_VBIC<"i32", 0b0011, expzero08>;
+def MVE_VBICIZ8v8i16 : MVE_VBIC<"i16", 0b1011, expzero08>;
+def MVE_VBICIZ16v4i32 : MVE_VBIC<"i32", 0b0101, expzero16>;
+def MVE_VBICIZ24v4i32 : MVE_VBIC<"i32", 0b0111, expzero24>;
+
+def MVE_VANDIZ0v4i32 : MVEAsmPseudo<"vand${vp}.i32\t$Qda, $imm",
+ (ins MQPR:$Qda_src, expzero00inv32:$imm, vpred_n:$vp), (outs MQPR:$Qda)>;
+def MVE_VANDIZ0v8i16 : MVEAsmPseudo<"vand${vp}.i16\t$Qda, $imm",
+ (ins MQPR:$Qda_src, expzero00inv16:$imm, vpred_n:$vp), (outs MQPR:$Qda)>;
+def MVE_VANDIZ8v4i32 : MVEAsmPseudo<"vand${vp}.i32\t$Qda, $imm",
+ (ins MQPR:$Qda_src, expzero08inv32:$imm, vpred_n:$vp), (outs MQPR:$Qda)>;
+def MVE_VANDIZ8v8i16 : MVEAsmPseudo<"vand${vp}.i16\t$Qda, $imm",
+ (ins MQPR:$Qda_src, expzero08inv16:$imm, vpred_n:$vp), (outs MQPR:$Qda)>;
+def MVE_VANDIZ16v4i32 : MVEAsmPseudo<"vand${vp}.i32\t$Qda, $imm",
+ (ins MQPR:$Qda_src, expzero16inv32:$imm, vpred_n:$vp), (outs MQPR:$Qda)>;
+def MVE_VANDIZ24v4i32 : MVEAsmPseudo<"vand${vp}.i32\t$Qda, $imm",
+ (ins MQPR:$Qda_src, expzero24inv32:$imm, vpred_n:$vp), (outs MQPR:$Qda)>;
+
+class MVE_VMOV_lane_direction {
+ bit bit_20;
+ dag oops;
+ dag iops;
+ string ops;
+ string cstr;
}
-def MVE_VQRSHRUNs32bh : MVE_VxQRSHRUN<
- "vqrshrunb", "s32", 0b1, 0b0, (ins shr_imm16:$imm)> {
- let Inst{20} = 0b1;
+def MVE_VMOV_from_lane : MVE_VMOV_lane_direction {
+ let bit_20 = 0b1;
+ let oops = (outs rGPR:$Rt);
+ let iops = (ins MQPR:$Qd);
+ let ops = "$Rt, $Qd$Idx";
+ let cstr = "";
}
-def MVE_VQRSHRUNs32th : MVE_VxQRSHRUN<
- "vqrshrunt", "s32", 0b1, 0b1, (ins shr_imm16:$imm)> {
- let Inst{20} = 0b1;
+def MVE_VMOV_to_lane : MVE_VMOV_lane_direction {
+ let bit_20 = 0b0;
+ let oops = (outs MQPR:$Qd);
+ let iops = (ins MQPR:$Qd_src, rGPR:$Rt);
+ let ops = "$Qd$Idx, $Rt";
+ let cstr = "$Qd = $Qd_src";
}
-def MVE_VQSHRUNs16bh : MVE_VxQRSHRUN<
- "vqshrunb", "s16", 0b0, 0b0, (ins shr_imm8:$imm)> {
- let Inst{20-19} = 0b01;
+class MVE_VMOV_lane<string suffix, bit U, dag indexop,
+ MVE_VMOV_lane_direction dir>
+ : MVE_VMOV_lane_base<dir.oops, !con(dir.iops, indexop), NoItinerary,
+ "vmov", suffix, dir.ops, dir.cstr, []> {
+ bits<4> Qd;
+ bits<4> Rt;
+
+ let Inst{31-24} = 0b11101110;
+ let Inst{23} = U;
+ let Inst{20} = dir.bit_20;
+ let Inst{19-17} = Qd{2-0};
+ let Inst{15-12} = Rt{3-0};
+ let Inst{11-8} = 0b1011;
+ let Inst{7} = Qd{3};
+ let Inst{4-0} = 0b10000;
}
-def MVE_VQSHRUNs16th : MVE_VxQRSHRUN<
- "vqshrunt", "s16", 0b0, 0b1, (ins shr_imm8:$imm)> {
- let Inst{20-19} = 0b01;
+
+class MVE_VMOV_lane_32<MVE_VMOV_lane_direction dir>
+ : MVE_VMOV_lane<"32", 0b0, (ins MVEVectorIndex<4>:$Idx), dir> {
+ bits<2> Idx;
+ let Inst{22} = 0b0;
+ let Inst{6-5} = 0b00;
+ let Inst{16} = Idx{1};
+ let Inst{21} = Idx{0};
+
+ let Predicates = [HasFPRegsV8_1M];
}
-def MVE_VQSHRUNs32bh : MVE_VxQRSHRUN<
- "vqshrunb", "s32", 0b0, 0b0, (ins shr_imm16:$imm)> {
- let Inst{20} = 0b1;
+
+class MVE_VMOV_lane_16<string suffix, bit U, MVE_VMOV_lane_direction dir>
+ : MVE_VMOV_lane<suffix, U, (ins MVEVectorIndex<8>:$Idx), dir> {
+ bits<3> Idx;
+ let Inst{22} = 0b0;
+ let Inst{5} = 0b1;
+ let Inst{16} = Idx{2};
+ let Inst{21} = Idx{1};
+ let Inst{6} = Idx{0};
}
-def MVE_VQSHRUNs32th : MVE_VxQRSHRUN<
- "vqshrunt", "s32", 0b0, 0b1, (ins shr_imm16:$imm)> {
- let Inst{20} = 0b1;
+
+class MVE_VMOV_lane_8<string suffix, bit U, MVE_VMOV_lane_direction dir>
+ : MVE_VMOV_lane<suffix, U, (ins MVEVectorIndex<16>:$Idx), dir> {
+ bits<4> Idx;
+ let Inst{22} = 0b1;
+ let Inst{16} = Idx{3};
+ let Inst{21} = Idx{2};
+ let Inst{6} = Idx{1};
+ let Inst{5} = Idx{0};
}
-class MVE_VxQRSHRN<string iname, string suffix, bit bit_0, bit bit_12,
- dag immops, list<dag> pattern=[]>
- : MVE_shift_imm<(outs MQPR:$Qd), !con((ins MQPR:$QdSrc, MQPR:$Qm), immops),
- iname, suffix, "$Qd, $Qm, $imm", vpred_n, "$Qd = $QdSrc",
- pattern> {
- bits<5> imm;
+def MVE_VMOV_from_lane_32 : MVE_VMOV_lane_32< MVE_VMOV_from_lane>;
+def MVE_VMOV_to_lane_32 : MVE_VMOV_lane_32< MVE_VMOV_to_lane>;
+def MVE_VMOV_from_lane_s16 : MVE_VMOV_lane_16<"s16", 0b0, MVE_VMOV_from_lane>;
+def MVE_VMOV_from_lane_u16 : MVE_VMOV_lane_16<"u16", 0b1, MVE_VMOV_from_lane>;
+def MVE_VMOV_to_lane_16 : MVE_VMOV_lane_16< "16", 0b0, MVE_VMOV_to_lane>;
+def MVE_VMOV_from_lane_s8 : MVE_VMOV_lane_8 < "s8", 0b0, MVE_VMOV_from_lane>;
+def MVE_VMOV_from_lane_u8 : MVE_VMOV_lane_8 < "u8", 0b1, MVE_VMOV_from_lane>;
+def MVE_VMOV_to_lane_8 : MVE_VMOV_lane_8 < "8", 0b0, MVE_VMOV_to_lane>;
- let Inst{25-23} = 0b101;
- let Inst{21} = 0b0;
- let Inst{20-16} = imm{4-0};
- let Inst{12} = bit_12;
- let Inst{11-6} = 0b111101;
- let Inst{4} = 0b0;
- let Inst{0} = bit_0;
-}
+let Predicates = [HasMVEInt] in {
+ def : Pat<(extractelt (v2f64 MQPR:$src), imm:$lane),
+ (f64 (EXTRACT_SUBREG MQPR:$src, (DSubReg_f64_reg imm:$lane)))>;
+ def : Pat<(insertelt (v2f64 MQPR:$src1), DPR:$src2, imm:$lane),
+ (INSERT_SUBREG (v2f64 (COPY_TO_REGCLASS MQPR:$src1, MQPR)), DPR:$src2, (DSubReg_f64_reg imm:$lane))>;
-multiclass MVE_VxQRSHRN_types<string iname, bit bit_0, bit bit_12> {
- def s16 : MVE_VxQRSHRN<iname, "s16", bit_0, bit_12, (ins shr_imm8:$imm)> {
- let Inst{28} = 0b0;
- let Inst{20-19} = 0b01;
- }
- def u16 : MVE_VxQRSHRN<iname, "u16", bit_0, bit_12, (ins shr_imm8:$imm)> {
- let Inst{28} = 0b1;
- let Inst{20-19} = 0b01;
- }
- def s32 : MVE_VxQRSHRN<iname, "s32", bit_0, bit_12, (ins shr_imm16:$imm)> {
- let Inst{28} = 0b0;
- let Inst{20} = 0b1;
- }
- def u32 : MVE_VxQRSHRN<iname, "u32", bit_0, bit_12, (ins shr_imm16:$imm)> {
- let Inst{28} = 0b1;
- let Inst{20} = 0b1;
- }
-}
+ def : Pat<(extractelt (v4i32 MQPR:$src), imm:$lane),
+ (COPY_TO_REGCLASS
+ (i32 (EXTRACT_SUBREG MQPR:$src, (SSubReg_f32_reg imm:$lane))), rGPR)>;
+ def : Pat<(insertelt (v4i32 MQPR:$src1), rGPR:$src2, imm:$lane),
+ (MVE_VMOV_to_lane_32 MQPR:$src1, rGPR:$src2, imm:$lane)>;
-defm MVE_VQRSHRNbh : MVE_VxQRSHRN_types<"vqrshrnb", 0b1, 0b0>;
-defm MVE_VQRSHRNth : MVE_VxQRSHRN_types<"vqrshrnt", 0b1, 0b1>;
-defm MVE_VQSHRNbh : MVE_VxQRSHRN_types<"vqshrnb", 0b0, 0b0>;
-defm MVE_VQSHRNth : MVE_VxQRSHRN_types<"vqshrnt", 0b0, 0b1>;
+ def : Pat<(vector_insert (v16i8 MQPR:$src1), rGPR:$src2, imm:$lane),
+ (MVE_VMOV_to_lane_8 MQPR:$src1, rGPR:$src2, imm:$lane)>;
+ def : Pat<(vector_insert (v8i16 MQPR:$src1), rGPR:$src2, imm:$lane),
+ (MVE_VMOV_to_lane_16 MQPR:$src1, rGPR:$src2, imm:$lane)>;
-// end of mve_imm_shift instructions
+ def : Pat<(ARMvgetlanes (v16i8 MQPR:$src), imm:$lane),
+ (MVE_VMOV_from_lane_s8 MQPR:$src, imm:$lane)>;
+ def : Pat<(ARMvgetlanes (v8i16 MQPR:$src), imm:$lane),
+ (MVE_VMOV_from_lane_s16 MQPR:$src, imm:$lane)>;
+ def : Pat<(ARMvgetlaneu (v16i8 MQPR:$src), imm:$lane),
+ (MVE_VMOV_from_lane_u8 MQPR:$src, imm:$lane)>;
+ def : Pat<(ARMvgetlaneu (v8i16 MQPR:$src), imm:$lane),
+ (MVE_VMOV_from_lane_u16 MQPR:$src, imm:$lane)>;
-// start of mve_shift instructions
+ def : Pat<(v16i8 (scalar_to_vector GPR:$src)),
+ (MVE_VMOV_to_lane_8 (v16i8 (IMPLICIT_DEF)), rGPR:$src, (i32 0))>;
+ def : Pat<(v8i16 (scalar_to_vector GPR:$src)),
+ (MVE_VMOV_to_lane_16 (v8i16 (IMPLICIT_DEF)), rGPR:$src, (i32 0))>;
+ def : Pat<(v4i32 (scalar_to_vector GPR:$src)),
+ (MVE_VMOV_to_lane_32 (v4i32 (IMPLICIT_DEF)), rGPR:$src, (i32 0))>;
-class MVE_shift_by_vec<string iname, string suffix, bit U,
- bits<2> size, bit bit_4, bit bit_8>
- : MVE_p<(outs MQPR:$Qd), (ins MQPR:$Qm, MQPR:$Qn), NoItinerary,
- iname, suffix, "$Qd, $Qm, $Qn", vpred_r, "", []> {
- // Shift instructions which take a vector of shift counts
+ // Floating point patterns, still enabled under HasMVEInt
+ def : Pat<(extractelt (v4f32 MQPR:$src), imm:$lane),
+ (COPY_TO_REGCLASS (f32 (EXTRACT_SUBREG MQPR:$src, (SSubReg_f32_reg imm:$lane))), SPR)>;
+ def : Pat<(insertelt (v4f32 MQPR:$src1), (f32 SPR:$src2), imm:$lane),
+ (INSERT_SUBREG (v4f32 (COPY_TO_REGCLASS MQPR:$src1, MQPR)), SPR:$src2, (SSubReg_f32_reg imm:$lane))>;
+
+ def : Pat<(insertelt (v8f16 MQPR:$src1), HPR:$src2, imm:$lane),
+ (MVE_VMOV_to_lane_16 MQPR:$src1, (COPY_TO_REGCLASS HPR:$src2, rGPR), imm:$lane)>;
+ def : Pat<(extractelt (v8f16 MQPR:$src), imm:$lane),
+ (COPY_TO_REGCLASS (MVE_VMOV_from_lane_u16 MQPR:$src, imm:$lane), HPR)>;
+
+ def : Pat<(v4f32 (scalar_to_vector SPR:$src)),
+ (INSERT_SUBREG (v4f32 (IMPLICIT_DEF)), SPR:$src, ssub_0)>;
+ def : Pat<(v4f32 (scalar_to_vector GPR:$src)),
+ (MVE_VMOV_to_lane_32 (v4f32 (IMPLICIT_DEF)), rGPR:$src, (i32 0))>;
+ def : Pat<(v8f16 (scalar_to_vector HPR:$src)),
+ (INSERT_SUBREG (v8f16 (IMPLICIT_DEF)), HPR:$src, ssub_0)>;
+ def : Pat<(v8f16 (scalar_to_vector GPR:$src)),
+ (MVE_VMOV_to_lane_16 (v8f16 (IMPLICIT_DEF)), rGPR:$src, (i32 0))>;
+}
+
+// end of mve_bit instructions
+
+// start of MVE Integer instructions
+
+class MVE_int<string iname, string suffix, bits<2> size, list<dag> pattern=[]>
+ : MVE_p<(outs MQPR:$Qd), (ins MQPR:$Qn, MQPR:$Qm), NoItinerary,
+ iname, suffix, "$Qd, $Qn, $Qm", vpred_r, "", pattern> {
bits<4> Qd;
- bits<4> Qm;
bits<4> Qn;
+ bits<4> Qm;
- let Inst{28} = U;
- let Inst{25-24} = 0b11;
- let Inst{23} = 0b0;
let Inst{22} = Qd{3};
let Inst{21-20} = size;
let Inst{19-17} = Qn{2-0};
- let Inst{16} = 0b0;
let Inst{15-13} = Qd{2-0};
- let Inst{12-9} = 0b0010;
- let Inst{8} = bit_8;
let Inst{7} = Qn{3};
let Inst{6} = 0b1;
let Inst{5} = Qm{3};
- let Inst{4} = bit_4;
let Inst{3-1} = Qm{2-0};
- let Inst{0} = 0b0;
-}
-
-multiclass mve_shift_by_vec_multi<string iname, bit bit_4, bit bit_8> {
- def s8 : MVE_shift_by_vec<iname, "s8", 0b0, 0b00, bit_4, bit_8>;
- def s16 : MVE_shift_by_vec<iname, "s16", 0b0, 0b01, bit_4, bit_8>;
- def s32 : MVE_shift_by_vec<iname, "s32", 0b0, 0b10, bit_4, bit_8>;
- def u8 : MVE_shift_by_vec<iname, "u8", 0b1, 0b00, bit_4, bit_8>;
- def u16 : MVE_shift_by_vec<iname, "u16", 0b1, 0b01, bit_4, bit_8>;
- def u32 : MVE_shift_by_vec<iname, "u32", 0b1, 0b10, bit_4, bit_8>;
}
-defm MVE_VSHL_by_vec : mve_shift_by_vec_multi<"vshl", 0b0, 0b0>;
-defm MVE_VQSHL_by_vec : mve_shift_by_vec_multi<"vqshl", 0b1, 0b0>;
-defm MVE_VQRSHL_by_vec : mve_shift_by_vec_multi<"vqrshl", 0b1, 0b1>;
-defm MVE_VRSHL_by_vec : mve_shift_by_vec_multi<"vrshl", 0b0, 0b1>;
-
-class MVE_shift_with_imm<string iname, string suffix, dag oops, dag iops,
- string ops, vpred_ops vpred, string cstr,
- list<dag> pattern=[]>
- : MVE_p<oops, iops, NoItinerary, iname, suffix, ops, vpred, cstr, pattern> {
- bits<4> Qd;
- bits<4> Qm;
+class MVE_VMULt1<string suffix, bits<2> size, list<dag> pattern=[]>
+ : MVE_int<"vmul", suffix, size, pattern> {
- let Inst{23} = 0b1;
- let Inst{22} = Qd{3};
- let Inst{15-13} = Qd{2-0};
- let Inst{12-11} = 0b00;
- let Inst{7-6} = 0b01;
- let Inst{5} = Qm{3};
+ let Inst{28} = 0b0;
+ let Inst{25-23} = 0b110;
+ let Inst{16} = 0b0;
+ let Inst{12-8} = 0b01001;
let Inst{4} = 0b1;
- let Inst{3-1} = Qm{2-0};
let Inst{0} = 0b0;
}
-class MVE_VSxI_imm<string iname, string suffix, bit bit_8, dag imm>
- : MVE_shift_with_imm<iname, suffix, (outs MQPR:$Qd),
- !con((ins MQPR:$Qd_src, MQPR:$Qm), imm),
- "$Qd, $Qm, $imm", vpred_n, "$Qd = $Qd_src"> {
- bits<6> imm;
- let Inst{28} = 0b1;
- let Inst{25-24} = 0b11;
- let Inst{21-16} = imm;
- let Inst{10-9} = 0b10;
- let Inst{8} = bit_8;
-}
-
-def MVE_VSRIimm8 : MVE_VSxI_imm<"vsri", "8", 0b0, (ins shr_imm8:$imm)> {
- let Inst{21-19} = 0b001;
-}
-
-def MVE_VSRIimm16 : MVE_VSxI_imm<"vsri", "16", 0b0, (ins shr_imm16:$imm)> {
- let Inst{21-20} = 0b01;
-}
-
-def MVE_VSRIimm32 : MVE_VSxI_imm<"vsri", "32", 0b0, (ins shr_imm32:$imm)> {
- let Inst{21} = 0b1;
-}
-
-def MVE_VSLIimm8 : MVE_VSxI_imm<"vsli", "8", 0b1, (ins imm0_7:$imm)> {
- let Inst{21-19} = 0b001;
-}
-
-def MVE_VSLIimm16 : MVE_VSxI_imm<"vsli", "16", 0b1, (ins imm0_15:$imm)> {
- let Inst{21-20} = 0b01;
-}
+def MVE_VMULt1i8 : MVE_VMULt1<"i8", 0b00>;
+def MVE_VMULt1i16 : MVE_VMULt1<"i16", 0b01>;
+def MVE_VMULt1i32 : MVE_VMULt1<"i32", 0b10>;
-def MVE_VSLIimm32 : MVE_VSxI_imm<"vsli", "32", 0b1,(ins imm0_31:$imm)> {
- let Inst{21} = 0b1;
+let Predicates = [HasMVEInt] in {
+ def : Pat<(v16i8 (mul (v16i8 MQPR:$val1), (v16i8 MQPR:$val2))),
+ (v16i8 (MVE_VMULt1i8 (v16i8 MQPR:$val1), (v16i8 MQPR:$val2)))>;
+ def : Pat<(v8i16 (mul (v8i16 MQPR:$val1), (v8i16 MQPR:$val2))),
+ (v8i16 (MVE_VMULt1i16 (v8i16 MQPR:$val1), (v8i16 MQPR:$val2)))>;
+ def : Pat<(v4i32 (mul (v4i32 MQPR:$val1), (v4i32 MQPR:$val2))),
+ (v4i32 (MVE_VMULt1i32 (v4i32 MQPR:$val1), (v4i32 MQPR:$val2)))>;
}
-class MVE_VQSHL_imm<string suffix, dag imm>
- : MVE_shift_with_imm<"vqshl", suffix, (outs MQPR:$Qd),
- !con((ins MQPR:$Qm), imm), "$Qd, $Qm, $imm",
- vpred_r, ""> {
- bits<6> imm;
-
- let Inst{25-24} = 0b11;
- let Inst{21-16} = imm;
- let Inst{10-8} = 0b111;
-}
+class MVE_VQxDMULH<string iname, string suffix, bits<2> size, bit rounding,
+ list<dag> pattern=[]>
+ : MVE_int<iname, suffix, size, pattern> {
-def MVE_VSLIimms8 : MVE_VQSHL_imm<"s8", (ins imm0_7:$imm)> {
- let Inst{28} = 0b0;
- let Inst{21-19} = 0b001;
+ let Inst{28} = rounding;
+ let Inst{25-23} = 0b110;
+ let Inst{16} = 0b0;
+ let Inst{12-8} = 0b01011;
+ let Inst{4} = 0b0;
+ let Inst{0} = 0b0;
}
-def MVE_VSLIimmu8 : MVE_VQSHL_imm<"u8", (ins imm0_7:$imm)> {
- let Inst{28} = 0b1;
- let Inst{21-19} = 0b001;
-}
+class MVE_VQDMULH<string suffix, bits<2> size, list<dag> pattern=[]>
+ : MVE_VQxDMULH<"vqdmulh", suffix, size, 0b0, pattern>;
+class MVE_VQRDMULH<string suffix, bits<2> size, list<dag> pattern=[]>
+ : MVE_VQxDMULH<"vqrdmulh", suffix, size, 0b1, pattern>;
-def MVE_VSLIimms16 : MVE_VQSHL_imm<"s16", (ins imm0_15:$imm)> {
- let Inst{28} = 0b0;
- let Inst{21-20} = 0b01;
-}
+def MVE_VQDMULHi8 : MVE_VQDMULH<"s8", 0b00>;
+def MVE_VQDMULHi16 : MVE_VQDMULH<"s16", 0b01>;
+def MVE_VQDMULHi32 : MVE_VQDMULH<"s32", 0b10>;
-def MVE_VSLIimmu16 : MVE_VQSHL_imm<"u16", (ins imm0_15:$imm)> {
- let Inst{28} = 0b1;
- let Inst{21-20} = 0b01;
-}
+def MVE_VQRDMULHi8 : MVE_VQRDMULH<"s8", 0b00>;
+def MVE_VQRDMULHi16 : MVE_VQRDMULH<"s16", 0b01>;
+def MVE_VQRDMULHi32 : MVE_VQRDMULH<"s32", 0b10>;
-def MVE_VSLIimms32 : MVE_VQSHL_imm<"s32", (ins imm0_31:$imm)> {
- let Inst{28} = 0b0;
- let Inst{21} = 0b1;
-}
+class MVE_VADDSUB<string iname, string suffix, bits<2> size, bit subtract,
+ list<dag> pattern=[]>
+ : MVE_int<iname, suffix, size, pattern> {
-def MVE_VSLIimmu32 : MVE_VQSHL_imm<"u32", (ins imm0_31:$imm)> {
- let Inst{28} = 0b1;
- let Inst{21} = 0b1;
+ let Inst{28} = subtract;
+ let Inst{25-23} = 0b110;
+ let Inst{16} = 0b0;
+ let Inst{12-8} = 0b01000;
+ let Inst{4} = 0b0;
+ let Inst{0} = 0b0;
}
-class MVE_VQSHLU_imm<string suffix, dag imm>
- : MVE_shift_with_imm<"vqshlu", suffix, (outs MQPR:$Qd),
- !con((ins MQPR:$Qm), imm), "$Qd, $Qm, $imm",
- vpred_r, ""> {
- bits<6> imm;
+class MVE_VADD<string suffix, bits<2> size, list<dag> pattern=[]>
+ : MVE_VADDSUB<"vadd", suffix, size, 0b0, pattern>;
+class MVE_VSUB<string suffix, bits<2> size, list<dag> pattern=[]>
+ : MVE_VADDSUB<"vsub", suffix, size, 0b1, pattern>;
- let Inst{28} = 0b1;
- let Inst{25-24} = 0b11;
- let Inst{21-16} = imm;
- let Inst{10-8} = 0b110;
-}
+def MVE_VADDi8 : MVE_VADD<"i8", 0b00>;
+def MVE_VADDi16 : MVE_VADD<"i16", 0b01>;
+def MVE_VADDi32 : MVE_VADD<"i32", 0b10>;
-def MVE_VQSHLU_imms8 : MVE_VQSHLU_imm<"s8", (ins imm0_7:$imm)> {
- let Inst{21-19} = 0b001;
+let Predicates = [HasMVEInt] in {
+ def : Pat<(v16i8 (add (v16i8 MQPR:$val1), (v16i8 MQPR:$val2))),
+ (v16i8 (MVE_VADDi8 (v16i8 MQPR:$val1), (v16i8 MQPR:$val2)))>;
+ def : Pat<(v8i16 (add (v8i16 MQPR:$val1), (v8i16 MQPR:$val2))),
+ (v8i16 (MVE_VADDi16 (v8i16 MQPR:$val1), (v8i16 MQPR:$val2)))>;
+ def : Pat<(v4i32 (add (v4i32 MQPR:$val1), (v4i32 MQPR:$val2))),
+ (v4i32 (MVE_VADDi32 (v4i32 MQPR:$val1), (v4i32 MQPR:$val2)))>;
}
-def MVE_VQSHLU_imms16 : MVE_VQSHLU_imm<"s16", (ins imm0_15:$imm)> {
- let Inst{21-20} = 0b01;
-}
+def MVE_VSUBi8 : MVE_VSUB<"i8", 0b00>;
+def MVE_VSUBi16 : MVE_VSUB<"i16", 0b01>;
+def MVE_VSUBi32 : MVE_VSUB<"i32", 0b10>;
-def MVE_VQSHLU_imms32 : MVE_VQSHLU_imm<"s32", (ins imm0_31:$imm)> {
- let Inst{21} = 0b1;
+let Predicates = [HasMVEInt] in {
+ def : Pat<(v16i8 (sub (v16i8 MQPR:$val1), (v16i8 MQPR:$val2))),
+ (v16i8 (MVE_VSUBi8 (v16i8 MQPR:$val1), (v16i8 MQPR:$val2)))>;
+ def : Pat<(v8i16 (sub (v8i16 MQPR:$val1), (v8i16 MQPR:$val2))),
+ (v8i16 (MVE_VSUBi16 (v8i16 MQPR:$val1), (v8i16 MQPR:$val2)))>;
+ def : Pat<(v4i32 (sub (v4i32 MQPR:$val1), (v4i32 MQPR:$val2))),
+ (v4i32 (MVE_VSUBi32 (v4i32 MQPR:$val1), (v4i32 MQPR:$val2)))>;
}
-class MVE_VRSHR_imm<string suffix, dag imm>
- : MVE_shift_with_imm<"vrshr", suffix, (outs MQPR:$Qd),
- !con((ins MQPR:$Qm), imm), "$Qd, $Qm, $imm",
- vpred_r, ""> {
- bits<6> imm;
+class MVE_VQADDSUB<string iname, string suffix, bit U, bit subtract,
+ bits<2> size, list<dag> pattern=[]>
+ : MVE_int<iname, suffix, size, pattern> {
- let Inst{25-24} = 0b11;
- let Inst{21-16} = imm;
- let Inst{10-8} = 0b010;
+ let Inst{28} = U;
+ let Inst{25-23} = 0b110;
+ let Inst{16} = 0b0;
+ let Inst{12-10} = 0b000;
+ let Inst{9} = subtract;
+ let Inst{8} = 0b0;
+ let Inst{4} = 0b1;
+ let Inst{0} = 0b0;
}
-def MVE_VRSHR_imms8 : MVE_VRSHR_imm<"s8", (ins shr_imm8:$imm)> {
- let Inst{28} = 0b0;
- let Inst{21-19} = 0b001;
-}
+class MVE_VQADD<string suffix, bit U, bits<2> size, list<dag> pattern=[]>
+ : MVE_VQADDSUB<"vqadd", suffix, U, 0b0, size, pattern>;
+class MVE_VQSUB<string suffix, bit U, bits<2> size, list<dag> pattern=[]>
+ : MVE_VQADDSUB<"vqsub", suffix, U, 0b1, size, pattern>;
-def MVE_VRSHR_immu8 : MVE_VRSHR_imm<"u8", (ins shr_imm8:$imm)> {
- let Inst{28} = 0b1;
- let Inst{21-19} = 0b001;
-}
+def MVE_VQADDs8 : MVE_VQADD<"s8", 0b0, 0b00>;
+def MVE_VQADDs16 : MVE_VQADD<"s16", 0b0, 0b01>;
+def MVE_VQADDs32 : MVE_VQADD<"s32", 0b0, 0b10>;
+def MVE_VQADDu8 : MVE_VQADD<"u8", 0b1, 0b00>;
+def MVE_VQADDu16 : MVE_VQADD<"u16", 0b1, 0b01>;
+def MVE_VQADDu32 : MVE_VQADD<"u32", 0b1, 0b10>;
-def MVE_VRSHR_imms16 : MVE_VRSHR_imm<"s16", (ins shr_imm16:$imm)> {
- let Inst{28} = 0b0;
- let Inst{21-20} = 0b01;
-}
+def MVE_VQSUBs8 : MVE_VQSUB<"s8", 0b0, 0b00>;
+def MVE_VQSUBs16 : MVE_VQSUB<"s16", 0b0, 0b01>;
+def MVE_VQSUBs32 : MVE_VQSUB<"s32", 0b0, 0b10>;
+def MVE_VQSUBu8 : MVE_VQSUB<"u8", 0b1, 0b00>;
+def MVE_VQSUBu16 : MVE_VQSUB<"u16", 0b1, 0b01>;
+def MVE_VQSUBu32 : MVE_VQSUB<"u32", 0b1, 0b10>;
-def MVE_VRSHR_immu16 : MVE_VRSHR_imm<"u16", (ins shr_imm16:$imm)> {
- let Inst{28} = 0b1;
- let Inst{21-20} = 0b01;
-}
+class MVE_VABD_int<string suffix, bit U, bits<2> size, list<dag> pattern=[]>
+ : MVE_int<"vabd", suffix, size, pattern> {
-def MVE_VRSHR_imms32 : MVE_VRSHR_imm<"s32", (ins shr_imm32:$imm)> {
- let Inst{28} = 0b0;
- let Inst{21} = 0b1;
+ let Inst{28} = U;
+ let Inst{25-23} = 0b110;
+ let Inst{16} = 0b0;
+ let Inst{12-8} = 0b00111;
+ let Inst{4} = 0b0;
+ let Inst{0} = 0b0;
}
-def MVE_VRSHR_immu32 : MVE_VRSHR_imm<"u32", (ins shr_imm32:$imm)> {
- let Inst{28} = 0b1;
- let Inst{21} = 0b1;
-}
+def MVE_VABDs8 : MVE_VABD_int<"s8", 0b0, 0b00>;
+def MVE_VABDs16 : MVE_VABD_int<"s16", 0b0, 0b01>;
+def MVE_VABDs32 : MVE_VABD_int<"s32", 0b0, 0b10>;
+def MVE_VABDu8 : MVE_VABD_int<"u8", 0b1, 0b00>;
+def MVE_VABDu16 : MVE_VABD_int<"u16", 0b1, 0b01>;
+def MVE_VABDu32 : MVE_VABD_int<"u32", 0b1, 0b10>;
-class MVE_VSHR_imm<string suffix, dag imm>
- : MVE_shift_with_imm<"vshr", suffix, (outs MQPR:$Qd),
- !con((ins MQPR:$Qm), imm), "$Qd, $Qm, $imm",
- vpred_r, ""> {
- bits<6> imm;
+class MVE_VRHADD<string suffix, bit U, bits<2> size, list<dag> pattern=[]>
+ : MVE_int<"vrhadd", suffix, size, pattern> {
- let Inst{25-24} = 0b11;
- let Inst{21-16} = imm;
- let Inst{10-8} = 0b000;
+ let Inst{28} = U;
+ let Inst{25-23} = 0b110;
+ let Inst{16} = 0b0;
+ let Inst{12-8} = 0b00001;
+ let Inst{4} = 0b0;
+ let Inst{0} = 0b0;
}
-def MVE_VSHR_imms8 : MVE_VSHR_imm<"s8", (ins shr_imm8:$imm)> {
- let Inst{28} = 0b0;
- let Inst{21-19} = 0b001;
-}
+def MVE_VRHADDs8 : MVE_VRHADD<"s8", 0b0, 0b00>;
+def MVE_VRHADDs16 : MVE_VRHADD<"s16", 0b0, 0b01>;
+def MVE_VRHADDs32 : MVE_VRHADD<"s32", 0b0, 0b10>;
+def MVE_VRHADDu8 : MVE_VRHADD<"u8", 0b1, 0b00>;
+def MVE_VRHADDu16 : MVE_VRHADD<"u16", 0b1, 0b01>;
+def MVE_VRHADDu32 : MVE_VRHADD<"u32", 0b1, 0b10>;
-def MVE_VSHR_immu8 : MVE_VSHR_imm<"u8", (ins shr_imm8:$imm)> {
- let Inst{28} = 0b1;
- let Inst{21-19} = 0b001;
-}
+class MVE_VHADDSUB<string iname, string suffix, bit U, bit subtract,
+ bits<2> size, list<dag> pattern=[]>
+ : MVE_int<iname, suffix, size, pattern> {
-def MVE_VSHR_imms16 : MVE_VSHR_imm<"s16", (ins shr_imm16:$imm)> {
- let Inst{28} = 0b0;
- let Inst{21-20} = 0b01;
+ let Inst{28} = U;
+ let Inst{25-23} = 0b110;
+ let Inst{16} = 0b0;
+ let Inst{12-10} = 0b000;
+ let Inst{9} = subtract;
+ let Inst{8} = 0b0;
+ let Inst{4} = 0b0;
+ let Inst{0} = 0b0;
}
-def MVE_VSHR_immu16 : MVE_VSHR_imm<"u16", (ins shr_imm16:$imm)> {
- let Inst{28} = 0b1;
- let Inst{21-20} = 0b01;
-}
+class MVE_VHADD<string suffix, bit U, bits<2> size,
+ list<dag> pattern=[]>
+ : MVE_VHADDSUB<"vhadd", suffix, U, 0b0, size, pattern>;
+class MVE_VHSUB<string suffix, bit U, bits<2> size,
+ list<dag> pattern=[]>
+ : MVE_VHADDSUB<"vhsub", suffix, U, 0b1, size, pattern>;
-def MVE_VSHR_imms32 : MVE_VSHR_imm<"s32", (ins shr_imm32:$imm)> {
- let Inst{28} = 0b0;
- let Inst{21} = 0b1;
-}
+def MVE_VHADDs8 : MVE_VHADD<"s8", 0b0, 0b00>;
+def MVE_VHADDs16 : MVE_VHADD<"s16", 0b0, 0b01>;
+def MVE_VHADDs32 : MVE_VHADD<"s32", 0b0, 0b10>;
+def MVE_VHADDu8 : MVE_VHADD<"u8", 0b1, 0b00>;
+def MVE_VHADDu16 : MVE_VHADD<"u16", 0b1, 0b01>;
+def MVE_VHADDu32 : MVE_VHADD<"u32", 0b1, 0b10>;
-def MVE_VSHR_immu32 : MVE_VSHR_imm<"u32", (ins shr_imm32:$imm)> {
- let Inst{28} = 0b1;
- let Inst{21} = 0b1;
-}
+def MVE_VHSUBs8 : MVE_VHSUB<"s8", 0b0, 0b00>;
+def MVE_VHSUBs16 : MVE_VHSUB<"s16", 0b0, 0b01>;
+def MVE_VHSUBs32 : MVE_VHSUB<"s32", 0b0, 0b10>;
+def MVE_VHSUBu8 : MVE_VHSUB<"u8", 0b1, 0b00>;
+def MVE_VHSUBu16 : MVE_VHSUB<"u16", 0b1, 0b01>;
+def MVE_VHSUBu32 : MVE_VHSUB<"u32", 0b1, 0b10>;
-class MVE_VSHL_imm<string suffix, dag imm>
- : MVE_shift_with_imm<"vshl", suffix, (outs MQPR:$Qd),
- !con((ins MQPR:$Qm), imm), "$Qd, $Qm, $imm",
- vpred_r, ""> {
- bits<6> imm;
+class MVE_VDUP<string suffix, bit B, bit E, list<dag> pattern=[]>
+ : MVE_p<(outs MQPR:$Qd), (ins rGPR:$Rt), NoItinerary,
+ "vdup", suffix, "$Qd, $Rt", vpred_r, "", pattern> {
+ bits<4> Qd;
+ bits<4> Rt;
let Inst{28} = 0b0;
- let Inst{25-24} = 0b11;
- let Inst{21-16} = imm;
- let Inst{10-8} = 0b101;
+ let Inst{25-23} = 0b101;
+ let Inst{22} = B;
+ let Inst{21-20} = 0b10;
+ let Inst{19-17} = Qd{2-0};
+ let Inst{16} = 0b0;
+ let Inst{15-12} = Rt;
+ let Inst{11-8} = 0b1011;
+ let Inst{7} = Qd{3};
+ let Inst{6} = 0b0;
+ let Inst{5} = E;
+ let Inst{4-0} = 0b10000;
}
-def MVE_VSHL_immi8 : MVE_VSHL_imm<"i8", (ins imm0_7:$imm)> {
- let Inst{21-19} = 0b001;
-}
+def MVE_VDUP32 : MVE_VDUP<"32", 0b0, 0b0>;
+def MVE_VDUP16 : MVE_VDUP<"16", 0b0, 0b1>;
+def MVE_VDUP8 : MVE_VDUP<"8", 0b1, 0b0>;
-def MVE_VSHL_immi16 : MVE_VSHL_imm<"i16", (ins imm0_15:$imm)> {
- let Inst{21-20} = 0b01;
-}
+let Predicates = [HasMVEInt] in {
+ def : Pat<(v16i8 (ARMvdup (i32 rGPR:$elem))),
+ (MVE_VDUP8 rGPR:$elem)>;
+ def : Pat<(v8i16 (ARMvdup (i32 rGPR:$elem))),
+ (MVE_VDUP16 rGPR:$elem)>;
+ def : Pat<(v4i32 (ARMvdup (i32 rGPR:$elem))),
+ (MVE_VDUP32 rGPR:$elem)>;
-def MVE_VSHL_immi32 : MVE_VSHL_imm<"i32", (ins imm0_31:$imm)> {
- let Inst{21} = 0b1;
-}
-// end of mve_shift instructions
+ def : Pat<(v4i32 (ARMvduplane (v4i32 MQPR:$src), imm:$lane)),
+ (MVE_VDUP32 (MVE_VMOV_from_lane_32 MQPR:$src, imm:$lane))>;
+ // For the 16-bit and 8-bit vduplanes we don't care about the signedness
+ // of the lane move operation as we only want the lowest 8/16 bits anyway.
+ def : Pat<(v8i16 (ARMvduplane (v8i16 MQPR:$src), imm:$lane)),
+ (MVE_VDUP16 (MVE_VMOV_from_lane_u16 MQPR:$src, imm:$lane))>;
+ def : Pat<(v16i8 (ARMvduplane (v16i8 MQPR:$src), imm:$lane)),
+ (MVE_VDUP8 (MVE_VMOV_from_lane_u8 MQPR:$src, imm:$lane))>;
-// start of mve_bit instructions
+ def : Pat<(v4f32 (ARMvdup (f32 SPR:$elem))),
+ (v4f32 (MVE_VDUP32 (i32 (COPY_TO_REGCLASS (f32 SPR:$elem), rGPR))))>;
+ def : Pat<(v8f16 (ARMvdup (f16 HPR:$elem))),
+ (v8f16 (MVE_VDUP16 (i32 (COPY_TO_REGCLASS (f16 HPR:$elem), rGPR))))>;
-class MVE_bit_arith<dag oops, dag iops, string iname, string suffix,
- string ops, string cstr, list<dag> pattern=[]>
- : MVE_p<oops, iops, NoItinerary, iname, suffix, ops, vpred_r, cstr, pattern> {
+ def : Pat<(v4f32 (ARMvduplane (v4f32 MQPR:$src), imm:$lane)),
+ (MVE_VDUP32 (MVE_VMOV_from_lane_32 MQPR:$src, imm:$lane))>;
+ def : Pat<(v8f16 (ARMvduplane (v8f16 MQPR:$src), imm:$lane)),
+ (MVE_VDUP16 (MVE_VMOV_from_lane_u16 MQPR:$src, imm:$lane))>;
+}
+
+
+class MVEIntSingleSrc<string iname, string suffix, bits<2> size,
+ list<dag> pattern=[]>
+ : MVE_p<(outs MQPR:$Qd), (ins MQPR:$Qm), NoItinerary,
+ iname, suffix, "$Qd, $Qm", vpred_r, "", pattern> {
bits<4> Qd;
bits<4> Qm;
let Inst{22} = Qd{3};
+ let Inst{19-18} = size{1-0};
let Inst{15-13} = Qd{2-0};
let Inst{5} = Qm{3};
let Inst{3-1} = Qm{2-0};
}
-def MVE_VBIC : MVE_bit_arith<(outs MQPR:$Qd), (ins MQPR:$Qn, MQPR:$Qm),
- "vbic", "", "$Qd, $Qn, $Qm", ""> {
- bits<4> Qn;
-
- let Inst{28} = 0b0;
- let Inst{25-23} = 0b110;
- let Inst{21-20} = 0b01;
- let Inst{19-17} = Qn{2-0};
- let Inst{16} = 0b0;
- let Inst{12-8} = 0b00001;
- let Inst{7} = Qn{3};
- let Inst{6} = 0b1;
- let Inst{4} = 0b1;
- let Inst{0} = 0b0;
-}
-
-class MVE_VREV<string iname, string suffix, bits<2> size, bits<2> bit_8_7>
- : MVE_bit_arith<(outs MQPR:$Qd), (ins MQPR:$Qm), iname,
- suffix, "$Qd, $Qm", ""> {
+class MVE_VCLSCLZ<string iname, string suffix, bits<2> size,
+ bit count_zeroes, list<dag> pattern=[]>
+ : MVEIntSingleSrc<iname, suffix, size, pattern> {
let Inst{28} = 0b1;
let Inst{25-23} = 0b111;
let Inst{21-20} = 0b11;
- let Inst{19-18} = size;
let Inst{17-16} = 0b00;
- let Inst{12-9} = 0b0000;
- let Inst{8-7} = bit_8_7;
+ let Inst{12-8} = 0b00100;
+ let Inst{7} = count_zeroes;
let Inst{6} = 0b1;
let Inst{4} = 0b0;
let Inst{0} = 0b0;
}
-def MVE_VREV64_8 : MVE_VREV<"vrev64", "8", 0b00, 0b00>;
-def MVE_VREV64_16 : MVE_VREV<"vrev64", "16", 0b01, 0b00>;
-def MVE_VREV64_32 : MVE_VREV<"vrev64", "32", 0b10, 0b00>;
-
-def MVE_VREV32_8 : MVE_VREV<"vrev32", "8", 0b00, 0b01>;
-def MVE_VREV32_16 : MVE_VREV<"vrev32", "16", 0b01, 0b01>;
-
-def MVE_VREV16_8 : MVE_VREV<"vrev16", "8", 0b00, 0b10>;
-
-let Predicates = [HasMVEInt] in {
-def : Pat<(v4i32 (ARMvrev64 (v4i32 MQPR:$src))),
- (v4i32 (MVE_VREV64_32 (v4i32 MQPR:$src)))>;
-def : Pat<(v8i16 (ARMvrev64 (v8i16 MQPR:$src))),
- (v8i16 (MVE_VREV64_16 (v8i16 MQPR:$src)))>;
-def : Pat<(v16i8 (ARMvrev64 (v16i8 MQPR:$src))),
- (v16i8 (MVE_VREV64_8 (v16i8 MQPR:$src)))>;
-
-def : Pat<(v8i16 (ARMvrev32 (v8i16 MQPR:$src))),
- (v8i16 (MVE_VREV32_16 (v8i16 MQPR:$src)))>;
-def : Pat<(v16i8 (ARMvrev32 (v16i8 MQPR:$src))),
- (v16i8 (MVE_VREV32_8 (v16i8 MQPR:$src)))>;
+def MVE_VCLSs8 : MVE_VCLSCLZ<"vcls", "s8", 0b00, 0b0>;
+def MVE_VCLSs16 : MVE_VCLSCLZ<"vcls", "s16", 0b01, 0b0>;
+def MVE_VCLSs32 : MVE_VCLSCLZ<"vcls", "s32", 0b10, 0b0>;
-def : Pat<(v16i8 (ARMvrev16 (v16i8 MQPR:$src))),
- (v16i8 (MVE_VREV16_8 (v16i8 MQPR:$src)))>;
+def MVE_VCLZs8 : MVE_VCLSCLZ<"vclz", "i8", 0b00, 0b1>;
+def MVE_VCLZs16 : MVE_VCLSCLZ<"vclz", "i16", 0b01, 0b1>;
+def MVE_VCLZs32 : MVE_VCLSCLZ<"vclz", "i32", 0b10, 0b1>;
-def : Pat<(v4f32 (ARMvrev64 (v4f32 MQPR:$src))),
- (v4f32 (MVE_VREV64_32 (v4f32 MQPR:$src)))>;
-def : Pat<(v8f16 (ARMvrev64 (v8f16 MQPR:$src))),
- (v8f16 (MVE_VREV64_16 (v8f16 MQPR:$src)))>;
-def : Pat<(v8f16 (ARMvrev32 (v8f16 MQPR:$src))),
- (v8f16 (MVE_VREV32_16 (v8f16 MQPR:$src)))>;
-}
+class MVE_VABSNEG_int<string iname, string suffix, bits<2> size, bit negate,
+ list<dag> pattern=[]>
+ : MVEIntSingleSrc<iname, suffix, size, pattern> {
-def MVE_VMVN : MVE_bit_arith<(outs MQPR:$Qd), (ins MQPR:$Qm),
- "vmvn", "", "$Qd, $Qm", ""> {
let Inst{28} = 0b1;
let Inst{25-23} = 0b111;
- let Inst{21-16} = 0b110000;
- let Inst{12-6} = 0b0010111;
- let Inst{4} = 0b0;
- let Inst{0} = 0b0;
-}
-
-let Predicates = [HasMVEInt] in {
- def : Pat<(v16i8 (vnotq (v16i8 MQPR:$val1))),
- (v16i8 (MVE_VMVN (v16i8 MQPR:$val1)))>;
- def : Pat<(v8i16 (vnotq (v8i16 MQPR:$val1))),
- (v8i16 (MVE_VMVN (v8i16 MQPR:$val1)))>;
- def : Pat<(v4i32 (vnotq (v4i32 MQPR:$val1))),
- (v4i32 (MVE_VMVN (v4i32 MQPR:$val1)))>;
-}
-
-class MVE_bit_ops<string iname, bits<2> bit_21_20, bit bit_28>
- : MVE_bit_arith<(outs MQPR:$Qd), (ins MQPR:$Qn, MQPR:$Qm),
- iname, "", "$Qd, $Qn, $Qm", ""> {
- bits<4> Qn;
-
- let Inst{28} = bit_28;
- let Inst{25-23} = 0b110;
- let Inst{21-20} = bit_21_20;
- let Inst{19-17} = Qn{2-0};
- let Inst{16} = 0b0;
- let Inst{12-8} = 0b00001;
- let Inst{7} = Qn{3};
+ let Inst{21-20} = 0b11;
+ let Inst{17-16} = 0b01;
+ let Inst{12-8} = 0b00011;
+ let Inst{7} = negate;
let Inst{6} = 0b1;
- let Inst{4} = 0b1;
+ let Inst{4} = 0b0;
let Inst{0} = 0b0;
}
-def MVE_VEOR : MVE_bit_ops<"veor", 0b00, 0b1>;
-def MVE_VORN : MVE_bit_ops<"vorn", 0b11, 0b0>;
-def MVE_VORR : MVE_bit_ops<"vorr", 0b10, 0b0>;
-def MVE_VAND : MVE_bit_ops<"vand", 0b00, 0b0>;
-
-// add ignored suffixes as aliases
-
-foreach s=["s8", "s16", "s32", "u8", "u16", "u32", "i8", "i16", "i32", "f16", "f32"] in {
- def : MVEInstAlias<"vbic${vp}." # s # "\t$QdSrc, $QnSrc, $QmSrc",
- (MVE_VBIC MQPR:$QdSrc, MQPR:$QnSrc, MQPR:$QmSrc, vpred_r:$vp)>;
- def : MVEInstAlias<"veor${vp}." # s # "\t$QdSrc, $QnSrc, $QmSrc",
- (MVE_VEOR MQPR:$QdSrc, MQPR:$QnSrc, MQPR:$QmSrc, vpred_r:$vp)>;
- def : MVEInstAlias<"vorn${vp}." # s # "\t$QdSrc, $QnSrc, $QmSrc",
- (MVE_VORN MQPR:$QdSrc, MQPR:$QnSrc, MQPR:$QmSrc, vpred_r:$vp)>;
- def : MVEInstAlias<"vorr${vp}." # s # "\t$QdSrc, $QnSrc, $QmSrc",
- (MVE_VORR MQPR:$QdSrc, MQPR:$QnSrc, MQPR:$QmSrc, vpred_r:$vp)>;
- def : MVEInstAlias<"vand${vp}." # s # "\t$QdSrc, $QnSrc, $QmSrc",
- (MVE_VAND MQPR:$QdSrc, MQPR:$QnSrc, MQPR:$QmSrc, vpred_r:$vp)>;
-}
+def MVE_VABSs8 : MVE_VABSNEG_int<"vabs", "s8", 0b00, 0b0>;
+def MVE_VABSs16 : MVE_VABSNEG_int<"vabs", "s16", 0b01, 0b0>;
+def MVE_VABSs32 : MVE_VABSNEG_int<"vabs", "s32", 0b10, 0b0>;
let Predicates = [HasMVEInt] in {
- def : Pat<(v16i8 (and (v16i8 MQPR:$val1), (v16i8 MQPR:$val2))),
- (v16i8 (MVE_VAND (v16i8 MQPR:$val1), (v16i8 MQPR:$val2)))>;
- def : Pat<(v8i16 (and (v8i16 MQPR:$val1), (v8i16 MQPR:$val2))),
- (v8i16 (MVE_VAND (v8i16 MQPR:$val1), (v8i16 MQPR:$val2)))>;
- def : Pat<(v4i32 (and (v4i32 MQPR:$val1), (v4i32 MQPR:$val2))),
- (v4i32 (MVE_VAND (v4i32 MQPR:$val1), (v4i32 MQPR:$val2)))>;
-
- def : Pat<(v16i8 (or (v16i8 MQPR:$val1), (v16i8 MQPR:$val2))),
- (v16i8 (MVE_VORR (v16i8 MQPR:$val1), (v16i8 MQPR:$val2)))>;
- def : Pat<(v8i16 (or (v8i16 MQPR:$val1), (v8i16 MQPR:$val2))),
- (v8i16 (MVE_VORR (v8i16 MQPR:$val1), (v8i16 MQPR:$val2)))>;
- def : Pat<(v4i32 (or (v4i32 MQPR:$val1), (v4i32 MQPR:$val2))),
- (v4i32 (MVE_VORR (v4i32 MQPR:$val1), (v4i32 MQPR:$val2)))>;
-
- def : Pat<(v16i8 (xor (v16i8 MQPR:$val1), (v16i8 MQPR:$val2))),
- (v16i8 (MVE_VEOR (v16i8 MQPR:$val1), (v16i8 MQPR:$val2)))>;
- def : Pat<(v8i16 (xor (v8i16 MQPR:$val1), (v8i16 MQPR:$val2))),
- (v8i16 (MVE_VEOR (v8i16 MQPR:$val1), (v8i16 MQPR:$val2)))>;
- def : Pat<(v4i32 (xor (v4i32 MQPR:$val1), (v4i32 MQPR:$val2))),
- (v4i32 (MVE_VEOR (v4i32 MQPR:$val1), (v4i32 MQPR:$val2)))>;
-
- def : Pat<(v16i8 (and (v16i8 MQPR:$val1), (vnotq MQPR:$val2))),
- (v16i8 (MVE_VBIC (v16i8 MQPR:$val1), (v16i8 MQPR:$val2)))>;
- def : Pat<(v8i16 (and (v8i16 MQPR:$val1), (vnotq MQPR:$val2))),
- (v8i16 (MVE_VBIC (v8i16 MQPR:$val1), (v8i16 MQPR:$val2)))>;
- def : Pat<(v4i32 (and (v4i32 MQPR:$val1), (vnotq MQPR:$val2))),
- (v4i32 (MVE_VBIC (v4i32 MQPR:$val1), (v4i32 MQPR:$val2)))>;
-
- def : Pat<(v16i8 (or (v16i8 MQPR:$val1), (vnotq (v16i8 MQPR:$val2)))),
- (v16i8 (MVE_VORN (v16i8 MQPR:$val1), (v16i8 MQPR:$val2)))>;
- def : Pat<(v8i16 (or (v8i16 MQPR:$val1), (vnotq MQPR:$val2))),
- (v8i16 (MVE_VORN (v8i16 MQPR:$val1), (v8i16 MQPR:$val2)))>;
- def : Pat<(v4i32 (or (v4i32 MQPR:$val1), (vnotq MQPR:$val2))),
- (v4i32 (MVE_VORN (v4i32 MQPR:$val1), (v4i32 MQPR:$val2)))>;
-}
-
-class MVE_bit_cmode<string iname, string suffix, bits<4> cmode, dag inOps>
- : MVE_p<(outs MQPR:$Qd), inOps, NoItinerary,
- iname, suffix, "$Qd, $imm", vpred_n, "$Qd = $Qd_src"> {
- bits<8> imm;
- bits<4> Qd;
-
- let Inst{28} = imm{7};
- let Inst{27-23} = 0b11111;
- let Inst{22} = Qd{3};
- let Inst{21-19} = 0b000;
- let Inst{18-16} = imm{6-4};
- let Inst{15-13} = Qd{2-0};
- let Inst{12} = 0b0;
- let Inst{11-8} = cmode;
- let Inst{7-6} = 0b01;
- let Inst{4} = 0b1;
- let Inst{3-0} = imm{3-0};
-}
-
-class MVE_VORR<string suffix, bits<4> cmode, ExpandImm imm_type>
- : MVE_bit_cmode<"vorr", suffix, cmode, (ins MQPR:$Qd_src, imm_type:$imm)> {
- let Inst{5} = 0b0;
-}
-
-def MVE_VORRIZ0v4i32 : MVE_VORR<"i32", 0b0001, expzero00>;
-def MVE_VORRIZ0v8i16 : MVE_VORR<"i16", 0b1001, expzero00>;
-def MVE_VORRIZ8v4i32 : MVE_VORR<"i32", 0b0011, expzero08>;
-def MVE_VORRIZ8v8i16 : MVE_VORR<"i16", 0b1011, expzero08>;
-def MVE_VORRIZ16v4i32 : MVE_VORR<"i32", 0b0101, expzero16>;
-def MVE_VORRIZ24v4i32 : MVE_VORR<"i32", 0b0111, expzero24>;
-
-def MVE_VORNIZ0v4i32 : MVEAsmPseudo<"vorn${vp}.i32\t$Qd, $imm",
- (ins MQPR:$Qd_src, expzero00inv32:$imm, vpred_n:$vp), (outs MQPR:$Qd)>;
-def MVE_VORNIZ0v8i16 : MVEAsmPseudo<"vorn${vp}.i16\t$Qd, $imm",
- (ins MQPR:$Qd_src, expzero00inv16:$imm, vpred_n:$vp), (outs MQPR:$Qd)>;
-def MVE_VORNIZ8v4i32 : MVEAsmPseudo<"vorn${vp}.i32\t$Qd, $imm",
- (ins MQPR:$Qd_src, expzero08inv32:$imm, vpred_n:$vp), (outs MQPR:$Qd)>;
-def MVE_VORNIZ8v8i16 : MVEAsmPseudo<"vorn${vp}.i16\t$Qd, $imm",
- (ins MQPR:$Qd_src, expzero08inv16:$imm, vpred_n:$vp), (outs MQPR:$Qd)>;
-def MVE_VORNIZ16v4i32 : MVEAsmPseudo<"vorn${vp}.i32\t$Qd, $imm",
- (ins MQPR:$Qd_src, expzero16inv32:$imm, vpred_n:$vp), (outs MQPR:$Qd)>;
-def MVE_VORNIZ24v4i32 : MVEAsmPseudo<"vorn${vp}.i32\t$Qd, $imm",
- (ins MQPR:$Qd_src, expzero24inv32:$imm, vpred_n:$vp), (outs MQPR:$Qd)>;
-
-def MVE_VMOV : MVEInstAlias<"vmov${vp}\t$Qd, $Qm",
- (MVE_VORR MQPR:$Qd, MQPR:$Qm, MQPR:$Qm, vpred_r:$vp)>;
-
-class MVE_VBIC<string suffix, bits<4> cmode, ExpandImm imm_type>
- : MVE_bit_cmode<"vbic", suffix, cmode, (ins MQPR:$Qd_src, imm_type:$imm)> {
- let Inst{5} = 0b1;
+ def : Pat<(v16i8 (abs (v16i8 MQPR:$v))),
+ (v16i8 (MVE_VABSs8 $v))>;
+ def : Pat<(v8i16 (abs (v8i16 MQPR:$v))),
+ (v8i16 (MVE_VABSs16 $v))>;
+ def : Pat<(v4i32 (abs (v4i32 MQPR:$v))),
+ (v4i32 (MVE_VABSs32 $v))>;
}
-def MVE_VBICIZ0v4i32 : MVE_VBIC<"i32", 0b0001, expzero00>;
-def MVE_VBICIZ0v8i16 : MVE_VBIC<"i16", 0b1001, expzero00>;
-def MVE_VBICIZ8v4i32 : MVE_VBIC<"i32", 0b0011, expzero08>;
-def MVE_VBICIZ8v8i16 : MVE_VBIC<"i16", 0b1011, expzero08>;
-def MVE_VBICIZ16v4i32 : MVE_VBIC<"i32", 0b0101, expzero16>;
-def MVE_VBICIZ24v4i32 : MVE_VBIC<"i32", 0b0111, expzero24>;
-
-def MVE_VANDIZ0v4i32 : MVEAsmPseudo<"vand${vp}.i32\t$Qda, $imm",
- (ins MQPR:$Qda_src, expzero00inv32:$imm, vpred_n:$vp), (outs MQPR:$Qda)>;
-def MVE_VANDIZ0v8i16 : MVEAsmPseudo<"vand${vp}.i16\t$Qda, $imm",
- (ins MQPR:$Qda_src, expzero00inv16:$imm, vpred_n:$vp), (outs MQPR:$Qda)>;
-def MVE_VANDIZ8v4i32 : MVEAsmPseudo<"vand${vp}.i32\t$Qda, $imm",
- (ins MQPR:$Qda_src, expzero08inv32:$imm, vpred_n:$vp), (outs MQPR:$Qda)>;
-def MVE_VANDIZ8v8i16 : MVEAsmPseudo<"vand${vp}.i16\t$Qda, $imm",
- (ins MQPR:$Qda_src, expzero08inv16:$imm, vpred_n:$vp), (outs MQPR:$Qda)>;
-def MVE_VANDIZ16v4i32 : MVEAsmPseudo<"vand${vp}.i32\t$Qda, $imm",
- (ins MQPR:$Qda_src, expzero16inv32:$imm, vpred_n:$vp), (outs MQPR:$Qda)>;
-def MVE_VANDIZ24v4i32 : MVEAsmPseudo<"vand${vp}.i32\t$Qda, $imm",
- (ins MQPR:$Qda_src, expzero24inv32:$imm, vpred_n:$vp), (outs MQPR:$Qda)>;
+def MVE_VNEGs8 : MVE_VABSNEG_int<"vneg", "s8", 0b00, 0b1>;
+def MVE_VNEGs16 : MVE_VABSNEG_int<"vneg", "s16", 0b01, 0b1>;
+def MVE_VNEGs32 : MVE_VABSNEG_int<"vneg", "s32", 0b10, 0b1>;
-class MVE_VMOV_lane_direction {
- bit bit_20;
- dag oops;
- dag iops;
- string ops;
- string cstr;
-}
-def MVE_VMOV_from_lane : MVE_VMOV_lane_direction {
- let bit_20 = 0b1;
- let oops = (outs rGPR:$Rt);
- let iops = (ins MQPR:$Qd);
- let ops = "$Rt, $Qd$Idx";
- let cstr = "";
+let Predicates = [HasMVEInt] in {
+ def : Pat<(v16i8 (vnegq (v16i8 MQPR:$v))),
+ (v16i8 (MVE_VNEGs8 $v))>;
+ def : Pat<(v8i16 (vnegq (v8i16 MQPR:$v))),
+ (v8i16 (MVE_VNEGs16 $v))>;
+ def : Pat<(v4i32 (vnegq (v4i32 MQPR:$v))),
+ (v4i32 (MVE_VNEGs32 $v))>;
}
-def MVE_VMOV_to_lane : MVE_VMOV_lane_direction {
- let bit_20 = 0b0;
- let oops = (outs MQPR:$Qd);
- let iops = (ins MQPR:$Qd_src, rGPR:$Rt);
- let ops = "$Qd$Idx, $Rt";
- let cstr = "$Qd = $Qd_src";
+
+class MVE_VQABSNEG<string iname, string suffix, bits<2> size,
+ bit negate, list<dag> pattern=[]>
+ : MVEIntSingleSrc<iname, suffix, size, pattern> {
+
+ let Inst{28} = 0b1;
+ let Inst{25-23} = 0b111;
+ let Inst{21-20} = 0b11;
+ let Inst{17-16} = 0b00;
+ let Inst{12-8} = 0b00111;
+ let Inst{7} = negate;
+ let Inst{6} = 0b1;
+ let Inst{4} = 0b0;
+ let Inst{0} = 0b0;
}
-class MVE_VMOV_lane<string suffix, bit U, dag indexop,
- MVE_VMOV_lane_direction dir>
- : MVE_VMOV_lane_base<dir.oops, !con(dir.iops, indexop), NoItinerary,
- "vmov", suffix, dir.ops, dir.cstr, []> {
+def MVE_VQABSs8 : MVE_VQABSNEG<"vqabs", "s8", 0b00, 0b0>;
+def MVE_VQABSs16 : MVE_VQABSNEG<"vqabs", "s16", 0b01, 0b0>;
+def MVE_VQABSs32 : MVE_VQABSNEG<"vqabs", "s32", 0b10, 0b0>;
+
+def MVE_VQNEGs8 : MVE_VQABSNEG<"vqneg", "s8", 0b00, 0b1>;
+def MVE_VQNEGs16 : MVE_VQABSNEG<"vqneg", "s16", 0b01, 0b1>;
+def MVE_VQNEGs32 : MVE_VQABSNEG<"vqneg", "s32", 0b10, 0b1>;
+
+class MVE_mod_imm<string iname, string suffix, bits<4> cmode, bit op,
+ dag iops, list<dag> pattern=[]>
+ : MVE_p<(outs MQPR:$Qd), iops, NoItinerary, iname, suffix, "$Qd, $imm",
+ vpred_r, "", pattern> {
+ bits<13> imm;
bits<4> Qd;
- bits<4> Rt;
- let Inst{31-24} = 0b11101110;
- let Inst{23} = U;
- let Inst{20} = dir.bit_20;
- let Inst{19-17} = Qd{2-0};
- let Inst{15-12} = Rt{3-0};
- let Inst{11-8} = 0b1011;
- let Inst{7} = Qd{3};
- let Inst{4-0} = 0b10000;
+ let Inst{28} = imm{7};
+ let Inst{25-23} = 0b111;
+ let Inst{22} = Qd{3};
+ let Inst{21-19} = 0b000;
+ let Inst{18-16} = imm{6-4};
+ let Inst{15-13} = Qd{2-0};
+ let Inst{12} = 0b0;
+ let Inst{11-8} = cmode{3-0};
+ let Inst{7-6} = 0b01;
+ let Inst{5} = op;
+ let Inst{4} = 0b1;
+ let Inst{3-0} = imm{3-0};
+
+ let DecoderMethod = "DecodeMVEModImmInstruction";
}
-class MVE_VMOV_lane_32<MVE_VMOV_lane_direction dir>
- : MVE_VMOV_lane<"32", 0b0, (ins MVEVectorIndex<4>:$Idx), dir> {
- bits<2> Idx;
- let Inst{22} = 0b0;
- let Inst{6-5} = 0b00;
- let Inst{16} = Idx{1};
- let Inst{21} = Idx{0};
+let isReMaterializable = 1 in {
+let isAsCheapAsAMove = 1 in {
+def MVE_VMOVimmi8 : MVE_mod_imm<"vmov", "i8", {1,1,1,0}, 0b0, (ins nImmSplatI8:$imm)>;
+def MVE_VMOVimmi16 : MVE_mod_imm<"vmov", "i16", {1,0,?,0}, 0b0, (ins nImmSplatI16:$imm)> {
+ let Inst{9} = imm{9};
+}
+def MVE_VMOVimmi32 : MVE_mod_imm<"vmov", "i32", {?,?,?,?}, 0b0, (ins nImmVMOVI32:$imm)> {
+ let Inst{11-8} = imm{11-8};
+}
+def MVE_VMOVimmi64 : MVE_mod_imm<"vmov", "i64", {1,1,1,0}, 0b1, (ins nImmSplatI64:$imm)>;
+def MVE_VMOVimmf32 : MVE_mod_imm<"vmov", "f32", {1,1,1,1}, 0b0, (ins nImmVMOVF32:$imm)>;
+} // let isAsCheapAsAMove = 1
- let Predicates = [HasFPRegsV8_1M];
+def MVE_VMVNimmi16 : MVE_mod_imm<"vmvn", "i16", {1,0,?,0}, 0b1, (ins nImmSplatI16:$imm)> {
+ let Inst{9} = imm{9};
+}
+def MVE_VMVNimmi32 : MVE_mod_imm<"vmvn", "i32", {?,?,?,?}, 0b1, (ins nImmVMOVI32:$imm)> {
+ let Inst{11-8} = imm{11-8};
}
+} // let isReMaterializable = 1
-class MVE_VMOV_lane_16<string suffix, bit U, MVE_VMOV_lane_direction dir>
- : MVE_VMOV_lane<suffix, U, (ins MVEVectorIndex<8>:$Idx), dir> {
- bits<3> Idx;
- let Inst{22} = 0b0;
- let Inst{5} = 0b1;
- let Inst{16} = Idx{2};
- let Inst{21} = Idx{1};
- let Inst{6} = Idx{0};
+let Predicates = [HasMVEInt] in {
+ def : Pat<(v16i8 (ARMvmovImm timm:$simm)),
+ (v16i8 (MVE_VMOVimmi8 nImmSplatI8:$simm))>;
+ def : Pat<(v8i16 (ARMvmovImm timm:$simm)),
+ (v8i16 (MVE_VMOVimmi16 nImmSplatI16:$simm))>;
+ def : Pat<(v4i32 (ARMvmovImm timm:$simm)),
+ (v4i32 (MVE_VMOVimmi32 nImmVMOVI32:$simm))>;
+
+ def : Pat<(v8i16 (ARMvmvnImm timm:$simm)),
+ (v8i16 (MVE_VMVNimmi16 nImmSplatI16:$simm))>;
+ def : Pat<(v4i32 (ARMvmvnImm timm:$simm)),
+ (v4i32 (MVE_VMVNimmi32 nImmVMOVI32:$simm))>;
+
+ def : Pat<(v4f32 (ARMvmovFPImm timm:$simm)),
+ (v4f32 (MVE_VMOVimmf32 nImmVMOVF32:$simm))>;
}
-class MVE_VMOV_lane_8<string suffix, bit U, MVE_VMOV_lane_direction dir>
- : MVE_VMOV_lane<suffix, U, (ins MVEVectorIndex<16>:$Idx), dir> {
- bits<4> Idx;
- let Inst{22} = 0b1;
- let Inst{16} = Idx{3};
- let Inst{21} = Idx{2};
- let Inst{6} = Idx{1};
- let Inst{5} = Idx{0};
+class MVE_VMINMAXA<string iname, string suffix, bits<2> size,
+ bit bit_12, list<dag> pattern=[]>
+ : MVE_p<(outs MQPR:$Qd), (ins MQPR:$Qd_src, MQPR:$Qm),
+ NoItinerary, iname, suffix, "$Qd, $Qm", vpred_n, "$Qd = $Qd_src",
+ pattern> {
+ bits<4> Qd;
+ bits<4> Qm;
+
+ let Inst{28} = 0b0;
+ let Inst{25-23} = 0b100;
+ let Inst{22} = Qd{3};
+ let Inst{21-20} = 0b11;
+ let Inst{19-18} = size;
+ let Inst{17-16} = 0b11;
+ let Inst{15-13} = Qd{2-0};
+ let Inst{12} = bit_12;
+ let Inst{11-6} = 0b111010;
+ let Inst{5} = Qm{3};
+ let Inst{4} = 0b0;
+ let Inst{3-1} = Qm{2-0};
+ let Inst{0} = 0b1;
}
-def MVE_VMOV_from_lane_32 : MVE_VMOV_lane_32< MVE_VMOV_from_lane>;
-def MVE_VMOV_to_lane_32 : MVE_VMOV_lane_32< MVE_VMOV_to_lane>;
-def MVE_VMOV_from_lane_s16 : MVE_VMOV_lane_16<"s16", 0b0, MVE_VMOV_from_lane>;
-def MVE_VMOV_from_lane_u16 : MVE_VMOV_lane_16<"u16", 0b1, MVE_VMOV_from_lane>;
-def MVE_VMOV_to_lane_16 : MVE_VMOV_lane_16< "16", 0b0, MVE_VMOV_to_lane>;
-def MVE_VMOV_from_lane_s8 : MVE_VMOV_lane_8 < "s8", 0b0, MVE_VMOV_from_lane>;
-def MVE_VMOV_from_lane_u8 : MVE_VMOV_lane_8 < "u8", 0b1, MVE_VMOV_from_lane>;
-def MVE_VMOV_to_lane_8 : MVE_VMOV_lane_8 < "8", 0b0, MVE_VMOV_to_lane>;
+def MVE_VMAXAs8 : MVE_VMINMAXA<"vmaxa", "s8", 0b00, 0b0>;
+def MVE_VMAXAs16 : MVE_VMINMAXA<"vmaxa", "s16", 0b01, 0b0>;
+def MVE_VMAXAs32 : MVE_VMINMAXA<"vmaxa", "s32", 0b10, 0b0>;
-let Predicates = [HasMVEInt] in {
- def : Pat<(extractelt (v2f64 MQPR:$src), imm:$lane),
- (f64 (EXTRACT_SUBREG MQPR:$src, (DSubReg_f64_reg imm:$lane)))>;
- def : Pat<(insertelt (v2f64 MQPR:$src1), DPR:$src2, imm:$lane),
- (INSERT_SUBREG (v2f64 (COPY_TO_REGCLASS MQPR:$src1, MQPR)), DPR:$src2, (DSubReg_f64_reg imm:$lane))>;
+def MVE_VMINAs8 : MVE_VMINMAXA<"vmina", "s8", 0b00, 0b1>;
+def MVE_VMINAs16 : MVE_VMINMAXA<"vmina", "s16", 0b01, 0b1>;
+def MVE_VMINAs32 : MVE_VMINMAXA<"vmina", "s32", 0b10, 0b1>;
- def : Pat<(extractelt (v4i32 MQPR:$src), imm:$lane),
- (COPY_TO_REGCLASS
- (i32 (EXTRACT_SUBREG MQPR:$src, (SSubReg_f32_reg imm:$lane))), rGPR)>;
- def : Pat<(insertelt (v4i32 MQPR:$src1), rGPR:$src2, imm:$lane),
- (MVE_VMOV_to_lane_32 MQPR:$src1, rGPR:$src2, imm:$lane)>;
+// end of MVE Integer instructions
- def : Pat<(vector_insert (v16i8 MQPR:$src1), rGPR:$src2, imm:$lane),
- (MVE_VMOV_to_lane_8 MQPR:$src1, rGPR:$src2, imm:$lane)>;
- def : Pat<(vector_insert (v8i16 MQPR:$src1), rGPR:$src2, imm:$lane),
- (MVE_VMOV_to_lane_16 MQPR:$src1, rGPR:$src2, imm:$lane)>;
+// start of mve_imm_shift instructions
- def : Pat<(ARMvgetlanes (v16i8 MQPR:$src), imm:$lane),
- (MVE_VMOV_from_lane_s8 MQPR:$src, imm:$lane)>;
- def : Pat<(ARMvgetlanes (v8i16 MQPR:$src), imm:$lane),
- (MVE_VMOV_from_lane_s16 MQPR:$src, imm:$lane)>;
- def : Pat<(ARMvgetlaneu (v16i8 MQPR:$src), imm:$lane),
- (MVE_VMOV_from_lane_u8 MQPR:$src, imm:$lane)>;
- def : Pat<(ARMvgetlaneu (v8i16 MQPR:$src), imm:$lane),
- (MVE_VMOV_from_lane_u16 MQPR:$src, imm:$lane)>;
+def MVE_VSHLC : MVE_p<(outs rGPR:$RdmDest, MQPR:$Qd),
+ (ins MQPR:$QdSrc, rGPR:$RdmSrc, long_shift:$imm),
+ NoItinerary, "vshlc", "", "$QdSrc, $RdmSrc, $imm",
+ vpred_n, "$RdmDest = $RdmSrc,$Qd = $QdSrc"> {
+ bits<5> imm;
+ bits<4> Qd;
+ bits<4> RdmDest;
- def : Pat<(v16i8 (scalar_to_vector GPR:$src)),
- (MVE_VMOV_to_lane_8 (v16i8 (IMPLICIT_DEF)), rGPR:$src, (i32 0))>;
- def : Pat<(v8i16 (scalar_to_vector GPR:$src)),
- (MVE_VMOV_to_lane_16 (v8i16 (IMPLICIT_DEF)), rGPR:$src, (i32 0))>;
- def : Pat<(v4i32 (scalar_to_vector GPR:$src)),
- (MVE_VMOV_to_lane_32 (v4i32 (IMPLICIT_DEF)), rGPR:$src, (i32 0))>;
+ let Inst{28} = 0b0;
+ let Inst{25-23} = 0b101;
+ let Inst{22} = Qd{3};
+ let Inst{21} = 0b1;
+ let Inst{20-16} = imm{4-0};
+ let Inst{15-13} = Qd{2-0};
+ let Inst{12-4} = 0b011111100;
+ let Inst{3-0} = RdmDest{3-0};
+}
- // Floating point patterns, still enabled under HasMVEInt
- def : Pat<(extractelt (v4f32 MQPR:$src), imm:$lane),
- (COPY_TO_REGCLASS (f32 (EXTRACT_SUBREG MQPR:$src, (SSubReg_f32_reg imm:$lane))), SPR)>;
- def : Pat<(insertelt (v4f32 MQPR:$src1), (f32 SPR:$src2), imm:$lane),
- (INSERT_SUBREG (v4f32 (COPY_TO_REGCLASS MQPR:$src1, MQPR)), SPR:$src2, (SSubReg_f32_reg imm:$lane))>;
+class MVE_shift_imm<dag oops, dag iops, string iname, string suffix,
+ string ops, vpred_ops vpred, string cstr,
+ list<dag> pattern=[]>
+ : MVE_p<oops, iops, NoItinerary, iname, suffix, ops, vpred, cstr, pattern> {
+ bits<4> Qd;
+ bits<4> Qm;
- def : Pat<(insertelt (v8f16 MQPR:$src1), HPR:$src2, imm:$lane),
- (MVE_VMOV_to_lane_16 MQPR:$src1, (COPY_TO_REGCLASS HPR:$src2, rGPR), imm:$lane)>;
- def : Pat<(extractelt (v8f16 MQPR:$src), imm:$lane),
- (COPY_TO_REGCLASS (MVE_VMOV_from_lane_u16 MQPR:$src, imm:$lane), HPR)>;
+ let Inst{22} = Qd{3};
+ let Inst{15-13} = Qd{2-0};
+ let Inst{5} = Qm{3};
+ let Inst{3-1} = Qm{2-0};
+}
- def : Pat<(v4f32 (scalar_to_vector SPR:$src)),
- (INSERT_SUBREG (v4f32 (IMPLICIT_DEF)), SPR:$src, ssub_0)>;
- def : Pat<(v4f32 (scalar_to_vector GPR:$src)),
- (MVE_VMOV_to_lane_32 (v4f32 (IMPLICIT_DEF)), rGPR:$src, (i32 0))>;
- def : Pat<(v8f16 (scalar_to_vector HPR:$src)),
- (INSERT_SUBREG (v8f16 (IMPLICIT_DEF)), HPR:$src, ssub_0)>;
- def : Pat<(v8f16 (scalar_to_vector GPR:$src)),
- (MVE_VMOV_to_lane_16 (v8f16 (IMPLICIT_DEF)), rGPR:$src, (i32 0))>;
+class MVE_VMOVL<string iname, string suffix, bits<2> sz, bit U,
+ list<dag> pattern=[]>
+ : MVE_shift_imm<(outs MQPR:$Qd), (ins MQPR:$Qm),
+ iname, suffix, "$Qd, $Qm", vpred_r, "",
+ pattern> {
+ let Inst{28} = U;
+ let Inst{25-23} = 0b101;
+ let Inst{21} = 0b1;
+ let Inst{20-19} = sz{1-0};
+ let Inst{18-16} = 0b000;
+ let Inst{11-6} = 0b111101;
+ let Inst{4} = 0b0;
+ let Inst{0} = 0b0;
+}
+
+multiclass MVE_VMOVL_shift_half<string iname, string suffix, bits<2> sz, bit U,
+ list<dag> pattern=[]> {
+ def bh : MVE_VMOVL<!strconcat(iname, "b"), suffix, sz, U, pattern> {
+ let Inst{12} = 0b0;
+ }
+ def th : MVE_VMOVL<!strconcat(iname, "t"), suffix, sz, U, pattern> {
+ let Inst{12} = 0b1;
+ }
}
-// end of mve_bit instructions
-
-// start of MVE Integer instructions
+defm MVE_VMOVLs8 : MVE_VMOVL_shift_half<"vmovl", "s8", 0b01, 0b0>;
+defm MVE_VMOVLu8 : MVE_VMOVL_shift_half<"vmovl", "u8", 0b01, 0b1>;
+defm MVE_VMOVLs16 : MVE_VMOVL_shift_half<"vmovl", "s16", 0b10, 0b0>;
+defm MVE_VMOVLu16 : MVE_VMOVL_shift_half<"vmovl", "u16", 0b10, 0b1>;
-class MVE_int<string iname, string suffix, bits<2> size, list<dag> pattern=[]>
- : MVE_p<(outs MQPR:$Qd), (ins MQPR:$Qn, MQPR:$Qm), NoItinerary,
- iname, suffix, "$Qd, $Qn, $Qm", vpred_r, "", pattern> {
- bits<4> Qd;
- bits<4> Qn;
- bits<4> Qm;
+let Predicates = [HasMVEInt] in {
+ def : Pat<(sext_inreg (v4i32 MQPR:$src), v4i16),
+ (MVE_VMOVLs16bh MQPR:$src)>;
+ def : Pat<(sext_inreg (v8i16 MQPR:$src), v8i8),
+ (MVE_VMOVLs8bh MQPR:$src)>;
+ def : Pat<(sext_inreg (v4i32 MQPR:$src), v4i8),
+ (MVE_VMOVLs16bh (MVE_VMOVLs8bh MQPR:$src))>;
- let Inst{22} = Qd{3};
- let Inst{21-20} = size;
- let Inst{19-17} = Qn{2-0};
- let Inst{15-13} = Qd{2-0};
- let Inst{7} = Qn{3};
- let Inst{6} = 0b1;
- let Inst{5} = Qm{3};
- let Inst{3-1} = Qm{2-0};
+ // zext_inreg 16 -> 32
+ def : Pat<(and (v4i32 MQPR:$src), (v4i32 (ARMvmovImm (i32 0xCFF)))),
+ (MVE_VMOVLu16bh MQPR:$src)>;
+ // zext_inreg 8 -> 16
+ def : Pat<(and (v8i16 MQPR:$src), (v8i16 (ARMvmovImm (i32 0x8FF)))),
+ (MVE_VMOVLu8bh MQPR:$src)>;
}
-class MVE_VMULt1<string suffix, bits<2> size, list<dag> pattern=[]>
- : MVE_int<"vmul", suffix, size, pattern> {
- let Inst{28} = 0b0;
- let Inst{25-23} = 0b110;
- let Inst{16} = 0b0;
- let Inst{12-8} = 0b01001;
- let Inst{4} = 0b1;
+class MVE_VSHLL_imm<string iname, string suffix, bit U, bit th,
+ dag immops, list<dag> pattern=[]>
+ : MVE_shift_imm<(outs MQPR:$Qd), !con((ins MQPR:$Qm), immops),
+ iname, suffix, "$Qd, $Qm, $imm", vpred_r, "", pattern> {
+ let Inst{28} = U;
+ let Inst{25-23} = 0b101;
+ let Inst{21} = 0b1;
+ let Inst{12} = th;
+ let Inst{11-6} = 0b111101;
+ let Inst{4} = 0b0;
let Inst{0} = 0b0;
}
-def MVE_VMULt1i8 : MVE_VMULt1<"i8", 0b00>;
-def MVE_VMULt1i16 : MVE_VMULt1<"i16", 0b01>;
-def MVE_VMULt1i32 : MVE_VMULt1<"i32", 0b10>;
+// The immediate VSHLL instructions accept shift counts from 1 up to
+// the lane width (8 or 16), but the full-width shifts have an
+// entirely separate encoding, given below with 'lw' in the name.
-let Predicates = [HasMVEInt] in {
- def : Pat<(v16i8 (mul (v16i8 MQPR:$val1), (v16i8 MQPR:$val2))),
- (v16i8 (MVE_VMULt1i8 (v16i8 MQPR:$val1), (v16i8 MQPR:$val2)))>;
- def : Pat<(v8i16 (mul (v8i16 MQPR:$val1), (v8i16 MQPR:$val2))),
- (v8i16 (MVE_VMULt1i16 (v8i16 MQPR:$val1), (v8i16 MQPR:$val2)))>;
- def : Pat<(v4i32 (mul (v4i32 MQPR:$val1), (v4i32 MQPR:$val2))),
- (v4i32 (MVE_VMULt1i32 (v4i32 MQPR:$val1), (v4i32 MQPR:$val2)))>;
+class MVE_VSHLL_imm8<string iname, string suffix,
+ bit U, bit th, list<dag> pattern=[]>
+ : MVE_VSHLL_imm<iname, suffix, U, th, (ins mve_shift_imm1_7:$imm), pattern> {
+ bits<3> imm;
+ let Inst{20-19} = 0b01;
+ let Inst{18-16} = imm;
}
-class MVE_VQxDMULH<string iname, string suffix, bits<2> size, bit rounding,
- list<dag> pattern=[]>
- : MVE_int<iname, suffix, size, pattern> {
+class MVE_VSHLL_imm16<string iname, string suffix,
+ bit U, bit th, list<dag> pattern=[]>
+ : MVE_VSHLL_imm<iname, suffix, U, th, (ins mve_shift_imm1_15:$imm), pattern> {
+ bits<4> imm;
+ let Inst{20} = 0b1;
+ let Inst{19-16} = imm;
+}
- let Inst{28} = rounding;
- let Inst{25-23} = 0b110;
- let Inst{16} = 0b0;
- let Inst{12-8} = 0b01011;
+def MVE_VSHLL_imms8bh : MVE_VSHLL_imm8 <"vshllb", "s8", 0b0, 0b0>;
+def MVE_VSHLL_imms8th : MVE_VSHLL_imm8 <"vshllt", "s8", 0b0, 0b1>;
+def MVE_VSHLL_immu8bh : MVE_VSHLL_imm8 <"vshllb", "u8", 0b1, 0b0>;
+def MVE_VSHLL_immu8th : MVE_VSHLL_imm8 <"vshllt", "u8", 0b1, 0b1>;
+def MVE_VSHLL_imms16bh : MVE_VSHLL_imm16<"vshllb", "s16", 0b0, 0b0>;
+def MVE_VSHLL_imms16th : MVE_VSHLL_imm16<"vshllt", "s16", 0b0, 0b1>;
+def MVE_VSHLL_immu16bh : MVE_VSHLL_imm16<"vshllb", "u16", 0b1, 0b0>;
+def MVE_VSHLL_immu16th : MVE_VSHLL_imm16<"vshllt", "u16", 0b1, 0b1>;
+
+class MVE_VSHLL_by_lane_width<string iname, string suffix, bits<2> size,
+ bit U, string ops, list<dag> pattern=[]>
+ : MVE_shift_imm<(outs MQPR:$Qd), (ins MQPR:$Qm),
+ iname, suffix, ops, vpred_r, "", pattern> {
+ let Inst{28} = U;
+ let Inst{25-23} = 0b100;
+ let Inst{21-20} = 0b11;
+ let Inst{19-18} = size{1-0};
+ let Inst{17-16} = 0b01;
+ let Inst{11-6} = 0b111000;
let Inst{4} = 0b0;
- let Inst{0} = 0b0;
+ let Inst{0} = 0b1;
}
-class MVE_VQDMULH<string suffix, bits<2> size, list<dag> pattern=[]>
- : MVE_VQxDMULH<"vqdmulh", suffix, size, 0b0, pattern>;
-class MVE_VQRDMULH<string suffix, bits<2> size, list<dag> pattern=[]>
- : MVE_VQxDMULH<"vqrdmulh", suffix, size, 0b1, pattern>;
-
-def MVE_VQDMULHi8 : MVE_VQDMULH<"s8", 0b00>;
-def MVE_VQDMULHi16 : MVE_VQDMULH<"s16", 0b01>;
-def MVE_VQDMULHi32 : MVE_VQDMULH<"s32", 0b10>;
+multiclass MVE_VSHLL_lw<string iname, string suffix, bits<2> sz, bit U,
+ string ops, list<dag> pattern=[]> {
+ def bh : MVE_VSHLL_by_lane_width<iname#"b", suffix, sz, U, ops, pattern> {
+ let Inst{12} = 0b0;
+ }
+ def th : MVE_VSHLL_by_lane_width<iname#"t", suffix, sz, U, ops, pattern> {
+ let Inst{12} = 0b1;
+ }
+}
-def MVE_VQRDMULHi8 : MVE_VQRDMULH<"s8", 0b00>;
-def MVE_VQRDMULHi16 : MVE_VQRDMULH<"s16", 0b01>;
-def MVE_VQRDMULHi32 : MVE_VQRDMULH<"s32", 0b10>;
+defm MVE_VSHLL_lws8 : MVE_VSHLL_lw<"vshll", "s8", 0b00, 0b0, "$Qd, $Qm, #8">;
+defm MVE_VSHLL_lws16 : MVE_VSHLL_lw<"vshll", "s16", 0b01, 0b0, "$Qd, $Qm, #16">;
+defm MVE_VSHLL_lwu8 : MVE_VSHLL_lw<"vshll", "u8", 0b00, 0b1, "$Qd, $Qm, #8">;
+defm MVE_VSHLL_lwu16 : MVE_VSHLL_lw<"vshll", "u16", 0b01, 0b1, "$Qd, $Qm, #16">;
-class MVE_VADDSUB<string iname, string suffix, bits<2> size, bit subtract,
- list<dag> pattern=[]>
- : MVE_int<iname, suffix, size, pattern> {
+class MVE_VxSHRN<string iname, string suffix, bit bit_12, bit bit_28,
+ dag immops, list<dag> pattern=[]>
+ : MVE_shift_imm<(outs MQPR:$Qd), !con((ins MQPR:$QdSrc, MQPR:$Qm), immops),
+ iname, suffix, "$Qd, $Qm, $imm", vpred_n, "$Qd = $QdSrc",
+ pattern> {
+ bits<5> imm;
- let Inst{28} = subtract;
- let Inst{25-23} = 0b110;
- let Inst{16} = 0b0;
- let Inst{12-8} = 0b01000;
+ let Inst{28} = bit_28;
+ let Inst{25-23} = 0b101;
+ let Inst{21} = 0b0;
+ let Inst{20-16} = imm{4-0};
+ let Inst{12} = bit_12;
+ let Inst{11-6} = 0b111111;
let Inst{4} = 0b0;
- let Inst{0} = 0b0;
+ let Inst{0} = 0b1;
}
-class MVE_VADD<string suffix, bits<2> size, list<dag> pattern=[]>
- : MVE_VADDSUB<"vadd", suffix, size, 0b0, pattern>;
-class MVE_VSUB<string suffix, bits<2> size, list<dag> pattern=[]>
- : MVE_VADDSUB<"vsub", suffix, size, 0b1, pattern>;
+def MVE_VRSHRNi16bh : MVE_VxSHRN<
+ "vrshrnb", "i16", 0b0, 0b1, (ins shr_imm8:$imm)> {
+ let Inst{20-19} = 0b01;
+}
+def MVE_VRSHRNi16th : MVE_VxSHRN<
+ "vrshrnt", "i16", 0b1, 0b1,(ins shr_imm8:$imm)> {
+ let Inst{20-19} = 0b01;
+}
+def MVE_VRSHRNi32bh : MVE_VxSHRN<
+ "vrshrnb", "i32", 0b0, 0b1, (ins shr_imm16:$imm)> {
+ let Inst{20} = 0b1;
+}
+def MVE_VRSHRNi32th : MVE_VxSHRN<
+ "vrshrnt", "i32", 0b1, 0b1, (ins shr_imm16:$imm)> {
+ let Inst{20} = 0b1;
+}
-def MVE_VADDi8 : MVE_VADD<"i8", 0b00>;
-def MVE_VADDi16 : MVE_VADD<"i16", 0b01>;
-def MVE_VADDi32 : MVE_VADD<"i32", 0b10>;
+def MVE_VSHRNi16bh : MVE_VxSHRN<
+ "vshrnb", "i16", 0b0, 0b0, (ins shr_imm8:$imm)> {
+ let Inst{20-19} = 0b01;
+}
+def MVE_VSHRNi16th : MVE_VxSHRN<
+ "vshrnt", "i16", 0b1, 0b0, (ins shr_imm8:$imm)> {
+ let Inst{20-19} = 0b01;
+}
+def MVE_VSHRNi32bh : MVE_VxSHRN<
+ "vshrnb", "i32", 0b0, 0b0, (ins shr_imm16:$imm)> {
+ let Inst{20} = 0b1;
+}
+def MVE_VSHRNi32th : MVE_VxSHRN<
+ "vshrnt", "i32", 0b1, 0b0, (ins shr_imm16:$imm)> {
+ let Inst{20} = 0b1;
+}
-let Predicates = [HasMVEInt] in {
- def : Pat<(v16i8 (add (v16i8 MQPR:$val1), (v16i8 MQPR:$val2))),
- (v16i8 (MVE_VADDi8 (v16i8 MQPR:$val1), (v16i8 MQPR:$val2)))>;
- def : Pat<(v8i16 (add (v8i16 MQPR:$val1), (v8i16 MQPR:$val2))),
- (v8i16 (MVE_VADDi16 (v8i16 MQPR:$val1), (v8i16 MQPR:$val2)))>;
- def : Pat<(v4i32 (add (v4i32 MQPR:$val1), (v4i32 MQPR:$val2))),
- (v4i32 (MVE_VADDi32 (v4i32 MQPR:$val1), (v4i32 MQPR:$val2)))>;
+class MVE_VxQRSHRUN<string iname, string suffix, bit bit_28, bit bit_12, dag immops,
+ list<dag> pattern=[]>
+ : MVE_shift_imm<(outs MQPR:$Qd), !con((ins MQPR:$QdSrc, MQPR:$Qm), immops),
+ iname, suffix, "$Qd, $Qm, $imm", vpred_n, "$Qd = $QdSrc",
+ pattern> {
+ bits<5> imm;
+
+ let Inst{28} = bit_28;
+ let Inst{25-23} = 0b101;
+ let Inst{21} = 0b0;
+ let Inst{20-16} = imm{4-0};
+ let Inst{12} = bit_12;
+ let Inst{11-6} = 0b111111;
+ let Inst{4} = 0b0;
+ let Inst{0} = 0b0;
}
-def MVE_VSUBi8 : MVE_VSUB<"i8", 0b00>;
-def MVE_VSUBi16 : MVE_VSUB<"i16", 0b01>;
-def MVE_VSUBi32 : MVE_VSUB<"i32", 0b10>;
+def MVE_VQRSHRUNs16bh : MVE_VxQRSHRUN<
+ "vqrshrunb", "s16", 0b1, 0b0, (ins shr_imm8:$imm)> {
+ let Inst{20-19} = 0b01;
+}
+def MVE_VQRSHRUNs16th : MVE_VxQRSHRUN<
+ "vqrshrunt", "s16", 0b1, 0b1, (ins shr_imm8:$imm)> {
+ let Inst{20-19} = 0b01;
+}
+def MVE_VQRSHRUNs32bh : MVE_VxQRSHRUN<
+ "vqrshrunb", "s32", 0b1, 0b0, (ins shr_imm16:$imm)> {
+ let Inst{20} = 0b1;
+}
+def MVE_VQRSHRUNs32th : MVE_VxQRSHRUN<
+ "vqrshrunt", "s32", 0b1, 0b1, (ins shr_imm16:$imm)> {
+ let Inst{20} = 0b1;
+}
-let Predicates = [HasMVEInt] in {
- def : Pat<(v16i8 (sub (v16i8 MQPR:$val1), (v16i8 MQPR:$val2))),
- (v16i8 (MVE_VSUBi8 (v16i8 MQPR:$val1), (v16i8 MQPR:$val2)))>;
- def : Pat<(v8i16 (sub (v8i16 MQPR:$val1), (v8i16 MQPR:$val2))),
- (v8i16 (MVE_VSUBi16 (v8i16 MQPR:$val1), (v8i16 MQPR:$val2)))>;
- def : Pat<(v4i32 (sub (v4i32 MQPR:$val1), (v4i32 MQPR:$val2))),
- (v4i32 (MVE_VSUBi32 (v4i32 MQPR:$val1), (v4i32 MQPR:$val2)))>;
+def MVE_VQSHRUNs16bh : MVE_VxQRSHRUN<
+ "vqshrunb", "s16", 0b0, 0b0, (ins shr_imm8:$imm)> {
+ let Inst{20-19} = 0b01;
}
+def MVE_VQSHRUNs16th : MVE_VxQRSHRUN<
+ "vqshrunt", "s16", 0b0, 0b1, (ins shr_imm8:$imm)> {
+ let Inst{20-19} = 0b01;
+}
+def MVE_VQSHRUNs32bh : MVE_VxQRSHRUN<
+ "vqshrunb", "s32", 0b0, 0b0, (ins shr_imm16:$imm)> {
+ let Inst{20} = 0b1;
+}
+def MVE_VQSHRUNs32th : MVE_VxQRSHRUN<
+ "vqshrunt", "s32", 0b0, 0b1, (ins shr_imm16:$imm)> {
+ let Inst{20} = 0b1;
+}
+
+class MVE_VxQRSHRN<string iname, string suffix, bit bit_0, bit bit_12,
+ dag immops, list<dag> pattern=[]>
+ : MVE_shift_imm<(outs MQPR:$Qd), !con((ins MQPR:$QdSrc, MQPR:$Qm), immops),
+ iname, suffix, "$Qd, $Qm, $imm", vpred_n, "$Qd = $QdSrc",
+ pattern> {
+ bits<5> imm;
-class MVE_VQADDSUB<string iname, string suffix, bit U, bit subtract,
- bits<2> size, list<dag> pattern=[]>
- : MVE_int<iname, suffix, size, pattern> {
+ let Inst{25-23} = 0b101;
+ let Inst{21} = 0b0;
+ let Inst{20-16} = imm{4-0};
+ let Inst{12} = bit_12;
+ let Inst{11-6} = 0b111101;
+ let Inst{4} = 0b0;
+ let Inst{0} = bit_0;
+}
- let Inst{28} = U;
- let Inst{25-23} = 0b110;
- let Inst{16} = 0b0;
- let Inst{12-10} = 0b000;
- let Inst{9} = subtract;
- let Inst{8} = 0b0;
- let Inst{4} = 0b1;
- let Inst{0} = 0b0;
+multiclass MVE_VxQRSHRN_types<string iname, bit bit_0, bit bit_12> {
+ def s16 : MVE_VxQRSHRN<iname, "s16", bit_0, bit_12, (ins shr_imm8:$imm)> {
+ let Inst{28} = 0b0;
+ let Inst{20-19} = 0b01;
+ }
+ def u16 : MVE_VxQRSHRN<iname, "u16", bit_0, bit_12, (ins shr_imm8:$imm)> {
+ let Inst{28} = 0b1;
+ let Inst{20-19} = 0b01;
+ }
+ def s32 : MVE_VxQRSHRN<iname, "s32", bit_0, bit_12, (ins shr_imm16:$imm)> {
+ let Inst{28} = 0b0;
+ let Inst{20} = 0b1;
+ }
+ def u32 : MVE_VxQRSHRN<iname, "u32", bit_0, bit_12, (ins shr_imm16:$imm)> {
+ let Inst{28} = 0b1;
+ let Inst{20} = 0b1;
+ }
}
-class MVE_VQADD<string suffix, bit U, bits<2> size, list<dag> pattern=[]>
- : MVE_VQADDSUB<"vqadd", suffix, U, 0b0, size, pattern>;
-class MVE_VQSUB<string suffix, bit U, bits<2> size, list<dag> pattern=[]>
- : MVE_VQADDSUB<"vqsub", suffix, U, 0b1, size, pattern>;
+defm MVE_VQRSHRNbh : MVE_VxQRSHRN_types<"vqrshrnb", 0b1, 0b0>;
+defm MVE_VQRSHRNth : MVE_VxQRSHRN_types<"vqrshrnt", 0b1, 0b1>;
+defm MVE_VQSHRNbh : MVE_VxQRSHRN_types<"vqshrnb", 0b0, 0b0>;
+defm MVE_VQSHRNth : MVE_VxQRSHRN_types<"vqshrnt", 0b0, 0b1>;
-def MVE_VQADDs8 : MVE_VQADD<"s8", 0b0, 0b00>;
-def MVE_VQADDs16 : MVE_VQADD<"s16", 0b0, 0b01>;
-def MVE_VQADDs32 : MVE_VQADD<"s32", 0b0, 0b10>;
-def MVE_VQADDu8 : MVE_VQADD<"u8", 0b1, 0b00>;
-def MVE_VQADDu16 : MVE_VQADD<"u16", 0b1, 0b01>;
-def MVE_VQADDu32 : MVE_VQADD<"u32", 0b1, 0b10>;
+// end of mve_imm_shift instructions
-def MVE_VQSUBs8 : MVE_VQSUB<"s8", 0b0, 0b00>;
-def MVE_VQSUBs16 : MVE_VQSUB<"s16", 0b0, 0b01>;
-def MVE_VQSUBs32 : MVE_VQSUB<"s32", 0b0, 0b10>;
-def MVE_VQSUBu8 : MVE_VQSUB<"u8", 0b1, 0b00>;
-def MVE_VQSUBu16 : MVE_VQSUB<"u16", 0b1, 0b01>;
-def MVE_VQSUBu32 : MVE_VQSUB<"u32", 0b1, 0b10>;
+// start of mve_shift instructions
-class MVE_VABD_int<string suffix, bit U, bits<2> size, list<dag> pattern=[]>
- : MVE_int<"vabd", suffix, size, pattern> {
+class MVE_shift_by_vec<string iname, string suffix, bit U,
+ bits<2> size, bit bit_4, bit bit_8>
+ : MVE_p<(outs MQPR:$Qd), (ins MQPR:$Qm, MQPR:$Qn), NoItinerary,
+ iname, suffix, "$Qd, $Qm, $Qn", vpred_r, "", []> {
+ // Shift instructions which take a vector of shift counts
+ bits<4> Qd;
+ bits<4> Qm;
+ bits<4> Qn;
let Inst{28} = U;
- let Inst{25-23} = 0b110;
+ let Inst{25-24} = 0b11;
+ let Inst{23} = 0b0;
+ let Inst{22} = Qd{3};
+ let Inst{21-20} = size;
+ let Inst{19-17} = Qn{2-0};
let Inst{16} = 0b0;
- let Inst{12-8} = 0b00111;
- let Inst{4} = 0b0;
+ let Inst{15-13} = Qd{2-0};
+ let Inst{12-9} = 0b0010;
+ let Inst{8} = bit_8;
+ let Inst{7} = Qn{3};
+ let Inst{6} = 0b1;
+ let Inst{5} = Qm{3};
+ let Inst{4} = bit_4;
+ let Inst{3-1} = Qm{2-0};
let Inst{0} = 0b0;
}
-def MVE_VABDs8 : MVE_VABD_int<"s8", 0b0, 0b00>;
-def MVE_VABDs16 : MVE_VABD_int<"s16", 0b0, 0b01>;
-def MVE_VABDs32 : MVE_VABD_int<"s32", 0b0, 0b10>;
-def MVE_VABDu8 : MVE_VABD_int<"u8", 0b1, 0b00>;
-def MVE_VABDu16 : MVE_VABD_int<"u16", 0b1, 0b01>;
-def MVE_VABDu32 : MVE_VABD_int<"u32", 0b1, 0b10>;
-
-class MVE_VRHADD<string suffix, bit U, bits<2> size, list<dag> pattern=[]>
- : MVE_int<"vrhadd", suffix, size, pattern> {
-
- let Inst{28} = U;
- let Inst{25-23} = 0b110;
- let Inst{16} = 0b0;
- let Inst{12-8} = 0b00001;
- let Inst{4} = 0b0;
- let Inst{0} = 0b0;
+multiclass mve_shift_by_vec_multi<string iname, bit bit_4, bit bit_8> {
+ def s8 : MVE_shift_by_vec<iname, "s8", 0b0, 0b00, bit_4, bit_8>;
+ def s16 : MVE_shift_by_vec<iname, "s16", 0b0, 0b01, bit_4, bit_8>;
+ def s32 : MVE_shift_by_vec<iname, "s32", 0b0, 0b10, bit_4, bit_8>;
+ def u8 : MVE_shift_by_vec<iname, "u8", 0b1, 0b00, bit_4, bit_8>;
+ def u16 : MVE_shift_by_vec<iname, "u16", 0b1, 0b01, bit_4, bit_8>;
+ def u32 : MVE_shift_by_vec<iname, "u32", 0b1, 0b10, bit_4, bit_8>;
}
-def MVE_VRHADDs8 : MVE_VRHADD<"s8", 0b0, 0b00>;
-def MVE_VRHADDs16 : MVE_VRHADD<"s16", 0b0, 0b01>;
-def MVE_VRHADDs32 : MVE_VRHADD<"s32", 0b0, 0b10>;
-def MVE_VRHADDu8 : MVE_VRHADD<"u8", 0b1, 0b00>;
-def MVE_VRHADDu16 : MVE_VRHADD<"u16", 0b1, 0b01>;
-def MVE_VRHADDu32 : MVE_VRHADD<"u32", 0b1, 0b10>;
+defm MVE_VSHL_by_vec : mve_shift_by_vec_multi<"vshl", 0b0, 0b0>;
+defm MVE_VQSHL_by_vec : mve_shift_by_vec_multi<"vqshl", 0b1, 0b0>;
+defm MVE_VQRSHL_by_vec : mve_shift_by_vec_multi<"vqrshl", 0b1, 0b1>;
+defm MVE_VRSHL_by_vec : mve_shift_by_vec_multi<"vrshl", 0b0, 0b1>;
-class MVE_VHADDSUB<string iname, string suffix, bit U, bit subtract,
- bits<2> size, list<dag> pattern=[]>
- : MVE_int<iname, suffix, size, pattern> {
+class MVE_shift_with_imm<string iname, string suffix, dag oops, dag iops,
+ string ops, vpred_ops vpred, string cstr,
+ list<dag> pattern=[]>
+ : MVE_p<oops, iops, NoItinerary, iname, suffix, ops, vpred, cstr, pattern> {
+ bits<4> Qd;
+ bits<4> Qm;
- let Inst{28} = U;
- let Inst{25-23} = 0b110;
- let Inst{16} = 0b0;
- let Inst{12-10} = 0b000;
- let Inst{9} = subtract;
- let Inst{8} = 0b0;
- let Inst{4} = 0b0;
+ let Inst{23} = 0b1;
+ let Inst{22} = Qd{3};
+ let Inst{15-13} = Qd{2-0};
+ let Inst{12-11} = 0b00;
+ let Inst{7-6} = 0b01;
+ let Inst{5} = Qm{3};
+ let Inst{4} = 0b1;
+ let Inst{3-1} = Qm{2-0};
let Inst{0} = 0b0;
}
-class MVE_VHADD<string suffix, bit U, bits<2> size,
- list<dag> pattern=[]>
- : MVE_VHADDSUB<"vhadd", suffix, U, 0b0, size, pattern>;
-class MVE_VHSUB<string suffix, bit U, bits<2> size,
- list<dag> pattern=[]>
- : MVE_VHADDSUB<"vhsub", suffix, U, 0b1, size, pattern>;
-
-def MVE_VHADDs8 : MVE_VHADD<"s8", 0b0, 0b00>;
-def MVE_VHADDs16 : MVE_VHADD<"s16", 0b0, 0b01>;
-def MVE_VHADDs32 : MVE_VHADD<"s32", 0b0, 0b10>;
-def MVE_VHADDu8 : MVE_VHADD<"u8", 0b1, 0b00>;
-def MVE_VHADDu16 : MVE_VHADD<"u16", 0b1, 0b01>;
-def MVE_VHADDu32 : MVE_VHADD<"u32", 0b1, 0b10>;
-
-def MVE_VHSUBs8 : MVE_VHSUB<"s8", 0b0, 0b00>;
-def MVE_VHSUBs16 : MVE_VHSUB<"s16", 0b0, 0b01>;
-def MVE_VHSUBs32 : MVE_VHSUB<"s32", 0b0, 0b10>;
-def MVE_VHSUBu8 : MVE_VHSUB<"u8", 0b1, 0b00>;
-def MVE_VHSUBu16 : MVE_VHSUB<"u16", 0b1, 0b01>;
-def MVE_VHSUBu32 : MVE_VHSUB<"u32", 0b1, 0b10>;
-
-class MVE_VDUP<string suffix, bit B, bit E, list<dag> pattern=[]>
- : MVE_p<(outs MQPR:$Qd), (ins rGPR:$Rt), NoItinerary,
- "vdup", suffix, "$Qd, $Rt", vpred_r, "", pattern> {
- bits<4> Qd;
- bits<4> Rt;
+class MVE_VSxI_imm<string iname, string suffix, bit bit_8, dag imm>
+ : MVE_shift_with_imm<iname, suffix, (outs MQPR:$Qd),
+ !con((ins MQPR:$Qd_src, MQPR:$Qm), imm),
+ "$Qd, $Qm, $imm", vpred_n, "$Qd = $Qd_src"> {
+ bits<6> imm;
+ let Inst{28} = 0b1;
+ let Inst{25-24} = 0b11;
+ let Inst{21-16} = imm;
+ let Inst{10-9} = 0b10;
+ let Inst{8} = bit_8;
+}
- let Inst{28} = 0b0;
- let Inst{25-23} = 0b101;
- let Inst{22} = B;
- let Inst{21-20} = 0b10;
- let Inst{19-17} = Qd{2-0};
- let Inst{16} = 0b0;
- let Inst{15-12} = Rt;
- let Inst{11-8} = 0b1011;
- let Inst{7} = Qd{3};
- let Inst{6} = 0b0;
- let Inst{5} = E;
- let Inst{4-0} = 0b10000;
+def MVE_VSRIimm8 : MVE_VSxI_imm<"vsri", "8", 0b0, (ins shr_imm8:$imm)> {
+ let Inst{21-19} = 0b001;
}
-def MVE_VDUP32 : MVE_VDUP<"32", 0b0, 0b0>;
-def MVE_VDUP16 : MVE_VDUP<"16", 0b0, 0b1>;
-def MVE_VDUP8 : MVE_VDUP<"8", 0b1, 0b0>;
+def MVE_VSRIimm16 : MVE_VSxI_imm<"vsri", "16", 0b0, (ins shr_imm16:$imm)> {
+ let Inst{21-20} = 0b01;
+}
-let Predicates = [HasMVEInt] in {
- def : Pat<(v16i8 (ARMvdup (i32 rGPR:$elem))),
- (MVE_VDUP8 rGPR:$elem)>;
- def : Pat<(v8i16 (ARMvdup (i32 rGPR:$elem))),
- (MVE_VDUP16 rGPR:$elem)>;
- def : Pat<(v4i32 (ARMvdup (i32 rGPR:$elem))),
- (MVE_VDUP32 rGPR:$elem)>;
+def MVE_VSRIimm32 : MVE_VSxI_imm<"vsri", "32", 0b0, (ins shr_imm32:$imm)> {
+ let Inst{21} = 0b1;
+}
- def : Pat<(v4i32 (ARMvduplane (v4i32 MQPR:$src), imm:$lane)),
- (MVE_VDUP32 (MVE_VMOV_from_lane_32 MQPR:$src, imm:$lane))>;
- // For the 16-bit and 8-bit vduplanes we don't care about the signedness
- // of the lane move operation as we only want the lowest 8/16 bits anyway.
- def : Pat<(v8i16 (ARMvduplane (v8i16 MQPR:$src), imm:$lane)),
- (MVE_VDUP16 (MVE_VMOV_from_lane_u16 MQPR:$src, imm:$lane))>;
- def : Pat<(v16i8 (ARMvduplane (v16i8 MQPR:$src), imm:$lane)),
- (MVE_VDUP8 (MVE_VMOV_from_lane_u8 MQPR:$src, imm:$lane))>;
+def MVE_VSLIimm8 : MVE_VSxI_imm<"vsli", "8", 0b1, (ins imm0_7:$imm)> {
+ let Inst{21-19} = 0b001;
+}
- def : Pat<(v4f32 (ARMvdup (f32 SPR:$elem))),
- (v4f32 (MVE_VDUP32 (i32 (COPY_TO_REGCLASS (f32 SPR:$elem), rGPR))))>;
- def : Pat<(v8f16 (ARMvdup (f16 HPR:$elem))),
- (v8f16 (MVE_VDUP16 (i32 (COPY_TO_REGCLASS (f16 HPR:$elem), rGPR))))>;
+def MVE_VSLIimm16 : MVE_VSxI_imm<"vsli", "16", 0b1, (ins imm0_15:$imm)> {
+ let Inst{21-20} = 0b01;
+}
- def : Pat<(v4f32 (ARMvduplane (v4f32 MQPR:$src), imm:$lane)),
- (MVE_VDUP32 (MVE_VMOV_from_lane_32 MQPR:$src, imm:$lane))>;
- def : Pat<(v8f16 (ARMvduplane (v8f16 MQPR:$src), imm:$lane)),
- (MVE_VDUP16 (MVE_VMOV_from_lane_u16 MQPR:$src, imm:$lane))>;
+def MVE_VSLIimm32 : MVE_VSxI_imm<"vsli", "32", 0b1,(ins imm0_31:$imm)> {
+ let Inst{21} = 0b1;
}
+class MVE_VQSHL_imm<string suffix, dag imm>
+ : MVE_shift_with_imm<"vqshl", suffix, (outs MQPR:$Qd),
+ !con((ins MQPR:$Qm), imm), "$Qd, $Qm, $imm",
+ vpred_r, ""> {
+ bits<6> imm;
-class MVEIntSingleSrc<string iname, string suffix, bits<2> size,
- list<dag> pattern=[]>
- : MVE_p<(outs MQPR:$Qd), (ins MQPR:$Qm), NoItinerary,
- iname, suffix, "$Qd, $Qm", vpred_r, "", pattern> {
- bits<4> Qd;
- bits<4> Qm;
+ let Inst{25-24} = 0b11;
+ let Inst{21-16} = imm;
+ let Inst{10-8} = 0b111;
+}
- let Inst{22} = Qd{3};
- let Inst{19-18} = size{1-0};
- let Inst{15-13} = Qd{2-0};
- let Inst{5} = Qm{3};
- let Inst{3-1} = Qm{2-0};
+def MVE_VSLIimms8 : MVE_VQSHL_imm<"s8", (ins imm0_7:$imm)> {
+ let Inst{28} = 0b0;
+ let Inst{21-19} = 0b001;
}
-class MVE_VCLSCLZ<string iname, string suffix, bits<2> size,
- bit count_zeroes, list<dag> pattern=[]>
- : MVEIntSingleSrc<iname, suffix, size, pattern> {
+def MVE_VSLIimmu8 : MVE_VQSHL_imm<"u8", (ins imm0_7:$imm)> {
+ let Inst{28} = 0b1;
+ let Inst{21-19} = 0b001;
+}
+
+def MVE_VSLIimms16 : MVE_VQSHL_imm<"s16", (ins imm0_15:$imm)> {
+ let Inst{28} = 0b0;
+ let Inst{21-20} = 0b01;
+}
+def MVE_VSLIimmu16 : MVE_VQSHL_imm<"u16", (ins imm0_15:$imm)> {
let Inst{28} = 0b1;
- let Inst{25-23} = 0b111;
- let Inst{21-20} = 0b11;
- let Inst{17-16} = 0b00;
- let Inst{12-8} = 0b00100;
- let Inst{7} = count_zeroes;
- let Inst{6} = 0b1;
- let Inst{4} = 0b0;
- let Inst{0} = 0b0;
+ let Inst{21-20} = 0b01;
}
-def MVE_VCLSs8 : MVE_VCLSCLZ<"vcls", "s8", 0b00, 0b0>;
-def MVE_VCLSs16 : MVE_VCLSCLZ<"vcls", "s16", 0b01, 0b0>;
-def MVE_VCLSs32 : MVE_VCLSCLZ<"vcls", "s32", 0b10, 0b0>;
+def MVE_VSLIimms32 : MVE_VQSHL_imm<"s32", (ins imm0_31:$imm)> {
+ let Inst{28} = 0b0;
+ let Inst{21} = 0b1;
+}
-def MVE_VCLZs8 : MVE_VCLSCLZ<"vclz", "i8", 0b00, 0b1>;
-def MVE_VCLZs16 : MVE_VCLSCLZ<"vclz", "i16", 0b01, 0b1>;
-def MVE_VCLZs32 : MVE_VCLSCLZ<"vclz", "i32", 0b10, 0b1>;
+def MVE_VSLIimmu32 : MVE_VQSHL_imm<"u32", (ins imm0_31:$imm)> {
+ let Inst{28} = 0b1;
+ let Inst{21} = 0b1;
+}
-class MVE_VABSNEG_int<string iname, string suffix, bits<2> size, bit negate,
- list<dag> pattern=[]>
- : MVEIntSingleSrc<iname, suffix, size, pattern> {
+class MVE_VQSHLU_imm<string suffix, dag imm>
+ : MVE_shift_with_imm<"vqshlu", suffix, (outs MQPR:$Qd),
+ !con((ins MQPR:$Qm), imm), "$Qd, $Qm, $imm",
+ vpred_r, ""> {
+ bits<6> imm;
let Inst{28} = 0b1;
- let Inst{25-23} = 0b111;
- let Inst{21-20} = 0b11;
- let Inst{17-16} = 0b01;
- let Inst{12-8} = 0b00011;
- let Inst{7} = negate;
- let Inst{6} = 0b1;
- let Inst{4} = 0b0;
- let Inst{0} = 0b0;
+ let Inst{25-24} = 0b11;
+ let Inst{21-16} = imm;
+ let Inst{10-8} = 0b110;
}
-def MVE_VABSs8 : MVE_VABSNEG_int<"vabs", "s8", 0b00, 0b0>;
-def MVE_VABSs16 : MVE_VABSNEG_int<"vabs", "s16", 0b01, 0b0>;
-def MVE_VABSs32 : MVE_VABSNEG_int<"vabs", "s32", 0b10, 0b0>;
+def MVE_VQSHLU_imms8 : MVE_VQSHLU_imm<"s8", (ins imm0_7:$imm)> {
+ let Inst{21-19} = 0b001;
+}
-let Predicates = [HasMVEInt] in {
- def : Pat<(v16i8 (abs (v16i8 MQPR:$v))),
- (v16i8 (MVE_VABSs8 $v))>;
- def : Pat<(v8i16 (abs (v8i16 MQPR:$v))),
- (v8i16 (MVE_VABSs16 $v))>;
- def : Pat<(v4i32 (abs (v4i32 MQPR:$v))),
- (v4i32 (MVE_VABSs32 $v))>;
+def MVE_VQSHLU_imms16 : MVE_VQSHLU_imm<"s16", (ins imm0_15:$imm)> {
+ let Inst{21-20} = 0b01;
}
-def MVE_VNEGs8 : MVE_VABSNEG_int<"vneg", "s8", 0b00, 0b1>;
-def MVE_VNEGs16 : MVE_VABSNEG_int<"vneg", "s16", 0b01, 0b1>;
-def MVE_VNEGs32 : MVE_VABSNEG_int<"vneg", "s32", 0b10, 0b1>;
+def MVE_VQSHLU_imms32 : MVE_VQSHLU_imm<"s32", (ins imm0_31:$imm)> {
+ let Inst{21} = 0b1;
+}
-let Predicates = [HasMVEInt] in {
- def : Pat<(v16i8 (vnegq (v16i8 MQPR:$v))),
- (v16i8 (MVE_VNEGs8 $v))>;
- def : Pat<(v8i16 (vnegq (v8i16 MQPR:$v))),
- (v8i16 (MVE_VNEGs16 $v))>;
- def : Pat<(v4i32 (vnegq (v4i32 MQPR:$v))),
- (v4i32 (MVE_VNEGs32 $v))>;
+class MVE_VRSHR_imm<string suffix, dag imm>
+ : MVE_shift_with_imm<"vrshr", suffix, (outs MQPR:$Qd),
+ !con((ins MQPR:$Qm), imm), "$Qd, $Qm, $imm",
+ vpred_r, ""> {
+ bits<6> imm;
+
+ let Inst{25-24} = 0b11;
+ let Inst{21-16} = imm;
+ let Inst{10-8} = 0b010;
}
-class MVE_VQABSNEG<string iname, string suffix, bits<2> size,
- bit negate, list<dag> pattern=[]>
- : MVEIntSingleSrc<iname, suffix, size, pattern> {
+def MVE_VRSHR_imms8 : MVE_VRSHR_imm<"s8", (ins shr_imm8:$imm)> {
+ let Inst{28} = 0b0;
+ let Inst{21-19} = 0b001;
+}
+def MVE_VRSHR_immu8 : MVE_VRSHR_imm<"u8", (ins shr_imm8:$imm)> {
let Inst{28} = 0b1;
- let Inst{25-23} = 0b111;
- let Inst{21-20} = 0b11;
- let Inst{17-16} = 0b00;
- let Inst{12-8} = 0b00111;
- let Inst{7} = negate;
- let Inst{6} = 0b1;
- let Inst{4} = 0b0;
- let Inst{0} = 0b0;
+ let Inst{21-19} = 0b001;
}
-def MVE_VQABSs8 : MVE_VQABSNEG<"vqabs", "s8", 0b00, 0b0>;
-def MVE_VQABSs16 : MVE_VQABSNEG<"vqabs", "s16", 0b01, 0b0>;
-def MVE_VQABSs32 : MVE_VQABSNEG<"vqabs", "s32", 0b10, 0b0>;
-
-def MVE_VQNEGs8 : MVE_VQABSNEG<"vqneg", "s8", 0b00, 0b1>;
-def MVE_VQNEGs16 : MVE_VQABSNEG<"vqneg", "s16", 0b01, 0b1>;
-def MVE_VQNEGs32 : MVE_VQABSNEG<"vqneg", "s32", 0b10, 0b1>;
+def MVE_VRSHR_imms16 : MVE_VRSHR_imm<"s16", (ins shr_imm16:$imm)> {
+ let Inst{28} = 0b0;
+ let Inst{21-20} = 0b01;
+}
-class MVE_mod_imm<string iname, string suffix, bits<4> cmode, bit op,
- dag iops, list<dag> pattern=[]>
- : MVE_p<(outs MQPR:$Qd), iops, NoItinerary, iname, suffix, "$Qd, $imm",
- vpred_r, "", pattern> {
- bits<13> imm;
- bits<4> Qd;
+def MVE_VRSHR_immu16 : MVE_VRSHR_imm<"u16", (ins shr_imm16:$imm)> {
+ let Inst{28} = 0b1;
+ let Inst{21-20} = 0b01;
+}
- let Inst{28} = imm{7};
- let Inst{25-23} = 0b111;
- let Inst{22} = Qd{3};
- let Inst{21-19} = 0b000;
- let Inst{18-16} = imm{6-4};
- let Inst{15-13} = Qd{2-0};
- let Inst{12} = 0b0;
- let Inst{11-8} = cmode{3-0};
- let Inst{7-6} = 0b01;
- let Inst{5} = op;
- let Inst{4} = 0b1;
- let Inst{3-0} = imm{3-0};
+def MVE_VRSHR_imms32 : MVE_VRSHR_imm<"s32", (ins shr_imm32:$imm)> {
+ let Inst{28} = 0b0;
+ let Inst{21} = 0b1;
+}
- let DecoderMethod = "DecodeMVEModImmInstruction";
+def MVE_VRSHR_immu32 : MVE_VRSHR_imm<"u32", (ins shr_imm32:$imm)> {
+ let Inst{28} = 0b1;
+ let Inst{21} = 0b1;
}
-let isReMaterializable = 1 in {
-let isAsCheapAsAMove = 1 in {
-def MVE_VMOVimmi8 : MVE_mod_imm<"vmov", "i8", {1,1,1,0}, 0b0, (ins nImmSplatI8:$imm)>;
-def MVE_VMOVimmi16 : MVE_mod_imm<"vmov", "i16", {1,0,?,0}, 0b0, (ins nImmSplatI16:$imm)> {
- let Inst{9} = imm{9};
+class MVE_VSHR_imm<string suffix, dag imm>
+ : MVE_shift_with_imm<"vshr", suffix, (outs MQPR:$Qd),
+ !con((ins MQPR:$Qm), imm), "$Qd, $Qm, $imm",
+ vpred_r, ""> {
+ bits<6> imm;
+
+ let Inst{25-24} = 0b11;
+ let Inst{21-16} = imm;
+ let Inst{10-8} = 0b000;
}
-def MVE_VMOVimmi32 : MVE_mod_imm<"vmov", "i32", {?,?,?,?}, 0b0, (ins nImmVMOVI32:$imm)> {
- let Inst{11-8} = imm{11-8};
+
+def MVE_VSHR_imms8 : MVE_VSHR_imm<"s8", (ins shr_imm8:$imm)> {
+ let Inst{28} = 0b0;
+ let Inst{21-19} = 0b001;
}
-def MVE_VMOVimmi64 : MVE_mod_imm<"vmov", "i64", {1,1,1,0}, 0b1, (ins nImmSplatI64:$imm)>;
-def MVE_VMOVimmf32 : MVE_mod_imm<"vmov", "f32", {1,1,1,1}, 0b0, (ins nImmVMOVF32:$imm)>;
-} // let isAsCheapAsAMove = 1
-def MVE_VMVNimmi16 : MVE_mod_imm<"vmvn", "i16", {1,0,?,0}, 0b1, (ins nImmSplatI16:$imm)> {
- let Inst{9} = imm{9};
+def MVE_VSHR_immu8 : MVE_VSHR_imm<"u8", (ins shr_imm8:$imm)> {
+ let Inst{28} = 0b1;
+ let Inst{21-19} = 0b001;
}
-def MVE_VMVNimmi32 : MVE_mod_imm<"vmvn", "i32", {?,?,?,?}, 0b1, (ins nImmVMOVI32:$imm)> {
- let Inst{11-8} = imm{11-8};
+
+def MVE_VSHR_imms16 : MVE_VSHR_imm<"s16", (ins shr_imm16:$imm)> {
+ let Inst{28} = 0b0;
+ let Inst{21-20} = 0b01;
}
-} // let isReMaterializable = 1
-let Predicates = [HasMVEInt] in {
- def : Pat<(v16i8 (ARMvmovImm timm:$simm)),
- (v16i8 (MVE_VMOVimmi8 nImmSplatI8:$simm))>;
- def : Pat<(v8i16 (ARMvmovImm timm:$simm)),
- (v8i16 (MVE_VMOVimmi16 nImmSplatI16:$simm))>;
- def : Pat<(v4i32 (ARMvmovImm timm:$simm)),
- (v4i32 (MVE_VMOVimmi32 nImmVMOVI32:$simm))>;
+def MVE_VSHR_immu16 : MVE_VSHR_imm<"u16", (ins shr_imm16:$imm)> {
+ let Inst{28} = 0b1;
+ let Inst{21-20} = 0b01;
+}
- def : Pat<(v8i16 (ARMvmvnImm timm:$simm)),
- (v8i16 (MVE_VMVNimmi16 nImmSplatI16:$simm))>;
- def : Pat<(v4i32 (ARMvmvnImm timm:$simm)),
- (v4i32 (MVE_VMVNimmi32 nImmVMOVI32:$simm))>;
+def MVE_VSHR_imms32 : MVE_VSHR_imm<"s32", (ins shr_imm32:$imm)> {
+ let Inst{28} = 0b0;
+ let Inst{21} = 0b1;
+}
- def : Pat<(v4f32 (ARMvmovFPImm timm:$simm)),
- (v4f32 (MVE_VMOVimmf32 nImmVMOVF32:$simm))>;
+def MVE_VSHR_immu32 : MVE_VSHR_imm<"u32", (ins shr_imm32:$imm)> {
+ let Inst{28} = 0b1;
+ let Inst{21} = 0b1;
}
-class MVE_VMINMAXA<string iname, string suffix, bits<2> size,
- bit bit_12, list<dag> pattern=[]>
- : MVE_p<(outs MQPR:$Qd), (ins MQPR:$Qd_src, MQPR:$Qm),
- NoItinerary, iname, suffix, "$Qd, $Qm", vpred_n, "$Qd = $Qd_src",
- pattern> {
- bits<4> Qd;
- bits<4> Qm;
+class MVE_VSHL_imm<string suffix, dag imm>
+ : MVE_shift_with_imm<"vshl", suffix, (outs MQPR:$Qd),
+ !con((ins MQPR:$Qm), imm), "$Qd, $Qm, $imm",
+ vpred_r, ""> {
+ bits<6> imm;
let Inst{28} = 0b0;
- let Inst{25-23} = 0b100;
- let Inst{22} = Qd{3};
- let Inst{21-20} = 0b11;
- let Inst{19-18} = size;
- let Inst{17-16} = 0b11;
- let Inst{15-13} = Qd{2-0};
- let Inst{12} = bit_12;
- let Inst{11-6} = 0b111010;
- let Inst{5} = Qm{3};
- let Inst{4} = 0b0;
- let Inst{3-1} = Qm{2-0};
- let Inst{0} = 0b1;
+ let Inst{25-24} = 0b11;
+ let Inst{21-16} = imm;
+ let Inst{10-8} = 0b101;
}
-def MVE_VMAXAs8 : MVE_VMINMAXA<"vmaxa", "s8", 0b00, 0b0>;
-def MVE_VMAXAs16 : MVE_VMINMAXA<"vmaxa", "s16", 0b01, 0b0>;
-def MVE_VMAXAs32 : MVE_VMINMAXA<"vmaxa", "s32", 0b10, 0b0>;
+def MVE_VSHL_immi8 : MVE_VSHL_imm<"i8", (ins imm0_7:$imm)> {
+ let Inst{21-19} = 0b001;
+}
-def MVE_VMINAs8 : MVE_VMINMAXA<"vmina", "s8", 0b00, 0b1>;
-def MVE_VMINAs16 : MVE_VMINMAXA<"vmina", "s16", 0b01, 0b1>;
-def MVE_VMINAs32 : MVE_VMINMAXA<"vmina", "s32", 0b10, 0b1>;
+def MVE_VSHL_immi16 : MVE_VSHL_imm<"i16", (ins imm0_15:$imm)> {
+ let Inst{21-20} = 0b01;
+}
-// end of MVE Integer instructions
+def MVE_VSHL_immi32 : MVE_VSHL_imm<"i32", (ins imm0_31:$imm)> {
+ let Inst{21} = 0b1;
+}
+
+// end of mve_shift instructions
// start of MVE Floating Point instructions
More information about the llvm-commits
mailing list