1259698Sdim//===-- AArch64InstrNEON.td - NEON support for AArch64 -----*- tablegen -*-===// 2259698Sdim// 3259698Sdim// The LLVM Compiler Infrastructure 4259698Sdim// 5259698Sdim// This file is distributed under the University of Illinois Open Source 6259698Sdim// License. See LICENSE.TXT for details. 7259698Sdim// 8259698Sdim//===----------------------------------------------------------------------===// 9259698Sdim// 10259698Sdim// This file describes the AArch64 NEON instruction set. 11259698Sdim// 12259698Sdim//===----------------------------------------------------------------------===// 13259698Sdim 14259698Sdim//===----------------------------------------------------------------------===// 15259698Sdim// NEON-specific DAG Nodes. 16259698Sdim//===----------------------------------------------------------------------===// 17259698Sdimdef Neon_bsl : SDNode<"AArch64ISD::NEON_BSL", SDTypeProfile<1, 3, 18259698Sdim [SDTCisVec<0>, SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>, 19259698Sdim SDTCisSameAs<0, 3>]>>; 20259698Sdim 21259698Sdim// (outs Result), (ins Imm, OpCmode) 22259698Sdimdef SDT_Neon_movi : SDTypeProfile<1, 2, [SDTCisVec<0>, SDTCisVT<1, i32>]>; 23259698Sdim 24259698Sdimdef Neon_movi : SDNode<"AArch64ISD::NEON_MOVIMM", SDT_Neon_movi>; 25259698Sdim 26259698Sdimdef Neon_mvni : SDNode<"AArch64ISD::NEON_MVNIMM", SDT_Neon_movi>; 27259698Sdim 28259698Sdim// (outs Result), (ins Imm) 29259698Sdimdef Neon_fmovi : SDNode<"AArch64ISD::NEON_FMOVIMM", SDTypeProfile<1, 1, 30259698Sdim [SDTCisVec<0>, SDTCisVT<1, i32>]>>; 31259698Sdim 32259698Sdim// (outs Result), (ins LHS, RHS, CondCode) 33259698Sdimdef Neon_cmp : SDNode<"AArch64ISD::NEON_CMP", SDTypeProfile<1, 3, 34259698Sdim [SDTCisVec<0>, SDTCisSameAs<1, 2>]>>; 35259698Sdim 36259698Sdim// (outs Result), (ins LHS, 0/0.0 constant, CondCode) 37259698Sdimdef Neon_cmpz : SDNode<"AArch64ISD::NEON_CMPZ", SDTypeProfile<1, 3, 38259698Sdim [SDTCisVec<0>, SDTCisVec<1>]>>; 39259698Sdim 40259698Sdim// (outs Result), (ins LHS, RHS) 41259698Sdimdef Neon_tst : SDNode<"AArch64ISD::NEON_TST", SDTypeProfile<1, 2, 42259698Sdim [SDTCisVec<0>, SDTCisSameAs<1, 2>]>>; 43259698Sdim 44259698Sdimdef SDTARMVSH : SDTypeProfile<1, 2, [SDTCisVec<0>, SDTCisSameAs<0, 1>, 45259698Sdim SDTCisVT<2, i32>]>; 46259698Sdimdef Neon_sqrshlImm : SDNode<"AArch64ISD::NEON_QSHLs", SDTARMVSH>; 47259698Sdimdef Neon_uqrshlImm : SDNode<"AArch64ISD::NEON_QSHLu", SDTARMVSH>; 48259698Sdim 49259698Sdimdef SDTPERMUTE : SDTypeProfile<1, 2, [SDTCisVec<0>, SDTCisSameAs<0, 1>, 50259698Sdim SDTCisSameAs<0, 2>]>; 51259698Sdimdef Neon_uzp1 : SDNode<"AArch64ISD::NEON_UZP1", SDTPERMUTE>; 52259698Sdimdef Neon_uzp2 : SDNode<"AArch64ISD::NEON_UZP2", SDTPERMUTE>; 53259698Sdimdef Neon_zip1 : SDNode<"AArch64ISD::NEON_ZIP1", SDTPERMUTE>; 54259698Sdimdef Neon_zip2 : SDNode<"AArch64ISD::NEON_ZIP2", SDTPERMUTE>; 55259698Sdimdef Neon_trn1 : SDNode<"AArch64ISD::NEON_TRN1", SDTPERMUTE>; 56259698Sdimdef Neon_trn2 : SDNode<"AArch64ISD::NEON_TRN2", SDTPERMUTE>; 57259698Sdim 58259698Sdimdef SDTVSHUF : SDTypeProfile<1, 1, [SDTCisVec<0>, SDTCisSameAs<0, 1>]>; 59259698Sdimdef Neon_rev64 : SDNode<"AArch64ISD::NEON_REV64", SDTVSHUF>; 60259698Sdimdef Neon_rev32 : SDNode<"AArch64ISD::NEON_REV32", SDTVSHUF>; 61259698Sdimdef Neon_rev16 : SDNode<"AArch64ISD::NEON_REV16", SDTVSHUF>; 62259698Sdimdef Neon_vdup : SDNode<"AArch64ISD::NEON_VDUP", SDTypeProfile<1, 1, 63259698Sdim [SDTCisVec<0>]>>; 64259698Sdimdef Neon_vduplane : SDNode<"AArch64ISD::NEON_VDUPLANE", SDTypeProfile<1, 2, 65259698Sdim [SDTCisVec<0>, SDTCisVec<1>, SDTCisVT<2, i64>]>>; 66259698Sdimdef Neon_vextract : SDNode<"AArch64ISD::NEON_VEXTRACT", SDTypeProfile<1, 3, 67259698Sdim [SDTCisVec<0>, SDTCisSameAs<0, 1>, 68259698Sdim SDTCisSameAs<0, 2>, SDTCisVT<3, i64>]>>; 69259698Sdim 70259698Sdimdef SDT_assertext : SDTypeProfile<1, 1, 71259698Sdim [SDTCisInt<0>, SDTCisInt<1>, SDTCisSameAs<1, 0>]>; 72259698Sdimdef assertsext : SDNode<"ISD::AssertSext", SDT_assertext>; 73259698Sdimdef assertzext : SDNode<"ISD::AssertZext", SDT_assertext>; 74259698Sdim 75259698Sdim//===----------------------------------------------------------------------===// 76259698Sdim// Multiclasses 77259698Sdim//===----------------------------------------------------------------------===// 78259698Sdim 79259698Sdimmulticlass NeonI_3VSame_B_sizes<bit u, bits<2> size, bits<5> opcode, 80259698Sdim string asmop, SDPatternOperator opnode8B, 81259698Sdim SDPatternOperator opnode16B, 82259698Sdim bit Commutable = 0> { 83259698Sdim let isCommutable = Commutable in { 84259698Sdim def _8B : NeonI_3VSame<0b0, u, size, opcode, 85259698Sdim (outs VPR64:$Rd), (ins VPR64:$Rn, VPR64:$Rm), 86259698Sdim asmop # "\t$Rd.8b, $Rn.8b, $Rm.8b", 87259698Sdim [(set (v8i8 VPR64:$Rd), 88259698Sdim (v8i8 (opnode8B (v8i8 VPR64:$Rn), (v8i8 VPR64:$Rm))))], 89259698Sdim NoItinerary>; 90259698Sdim 91259698Sdim def _16B : NeonI_3VSame<0b1, u, size, opcode, 92259698Sdim (outs VPR128:$Rd), (ins VPR128:$Rn, VPR128:$Rm), 93259698Sdim asmop # "\t$Rd.16b, $Rn.16b, $Rm.16b", 94259698Sdim [(set (v16i8 VPR128:$Rd), 95259698Sdim (v16i8 (opnode16B (v16i8 VPR128:$Rn), (v16i8 VPR128:$Rm))))], 96259698Sdim NoItinerary>; 97259698Sdim } 98259698Sdim 99259698Sdim} 100259698Sdim 101259698Sdimmulticlass NeonI_3VSame_HS_sizes<bit u, bits<5> opcode, 102259698Sdim string asmop, SDPatternOperator opnode, 103259698Sdim bit Commutable = 0> { 104259698Sdim let isCommutable = Commutable in { 105259698Sdim def _4H : NeonI_3VSame<0b0, u, 0b01, opcode, 106259698Sdim (outs VPR64:$Rd), (ins VPR64:$Rn, VPR64:$Rm), 107259698Sdim asmop # "\t$Rd.4h, $Rn.4h, $Rm.4h", 108259698Sdim [(set (v4i16 VPR64:$Rd), 109259698Sdim (v4i16 (opnode (v4i16 VPR64:$Rn), (v4i16 VPR64:$Rm))))], 110259698Sdim NoItinerary>; 111259698Sdim 112259698Sdim def _8H : NeonI_3VSame<0b1, u, 0b01, opcode, 113259698Sdim (outs VPR128:$Rd), (ins VPR128:$Rn, VPR128:$Rm), 114259698Sdim asmop # "\t$Rd.8h, $Rn.8h, $Rm.8h", 115259698Sdim [(set (v8i16 VPR128:$Rd), 116259698Sdim (v8i16 (opnode (v8i16 VPR128:$Rn), (v8i16 VPR128:$Rm))))], 117259698Sdim NoItinerary>; 118259698Sdim 119259698Sdim def _2S : NeonI_3VSame<0b0, u, 0b10, opcode, 120259698Sdim (outs VPR64:$Rd), (ins VPR64:$Rn, VPR64:$Rm), 121259698Sdim asmop # "\t$Rd.2s, $Rn.2s, $Rm.2s", 122259698Sdim [(set (v2i32 VPR64:$Rd), 123259698Sdim (v2i32 (opnode (v2i32 VPR64:$Rn), (v2i32 VPR64:$Rm))))], 124259698Sdim NoItinerary>; 125259698Sdim 126259698Sdim def _4S : NeonI_3VSame<0b1, u, 0b10, opcode, 127259698Sdim (outs VPR128:$Rd), (ins VPR128:$Rn, VPR128:$Rm), 128259698Sdim asmop # "\t$Rd.4s, $Rn.4s, $Rm.4s", 129259698Sdim [(set (v4i32 VPR128:$Rd), 130259698Sdim (v4i32 (opnode (v4i32 VPR128:$Rn), (v4i32 VPR128:$Rm))))], 131259698Sdim NoItinerary>; 132259698Sdim } 133259698Sdim} 134259698Sdimmulticlass NeonI_3VSame_BHS_sizes<bit u, bits<5> opcode, 135259698Sdim string asmop, SDPatternOperator opnode, 136259698Sdim bit Commutable = 0> 137259698Sdim : NeonI_3VSame_HS_sizes<u, opcode, asmop, opnode, Commutable> { 138259698Sdim let isCommutable = Commutable in { 139259698Sdim def _8B : NeonI_3VSame<0b0, u, 0b00, opcode, 140259698Sdim (outs VPR64:$Rd), (ins VPR64:$Rn, VPR64:$Rm), 141259698Sdim asmop # "\t$Rd.8b, $Rn.8b, $Rm.8b", 142259698Sdim [(set (v8i8 VPR64:$Rd), 143259698Sdim (v8i8 (opnode (v8i8 VPR64:$Rn), (v8i8 VPR64:$Rm))))], 144259698Sdim NoItinerary>; 145259698Sdim 146259698Sdim def _16B : NeonI_3VSame<0b1, u, 0b00, opcode, 147259698Sdim (outs VPR128:$Rd), (ins VPR128:$Rn, VPR128:$Rm), 148259698Sdim asmop # "\t$Rd.16b, $Rn.16b, $Rm.16b", 149259698Sdim [(set (v16i8 VPR128:$Rd), 150259698Sdim (v16i8 (opnode (v16i8 VPR128:$Rn), (v16i8 VPR128:$Rm))))], 151259698Sdim NoItinerary>; 152259698Sdim } 153259698Sdim} 154259698Sdim 155259698Sdimmulticlass NeonI_3VSame_BHSD_sizes<bit u, bits<5> opcode, 156259698Sdim string asmop, SDPatternOperator opnode, 157259698Sdim bit Commutable = 0> 158259698Sdim : NeonI_3VSame_BHS_sizes<u, opcode, asmop, opnode, Commutable> { 159259698Sdim let isCommutable = Commutable in { 160259698Sdim def _2D : NeonI_3VSame<0b1, u, 0b11, opcode, 161259698Sdim (outs VPR128:$Rd), (ins VPR128:$Rn, VPR128:$Rm), 162259698Sdim asmop # "\t$Rd.2d, $Rn.2d, $Rm.2d", 163259698Sdim [(set (v2i64 VPR128:$Rd), 164259698Sdim (v2i64 (opnode (v2i64 VPR128:$Rn), (v2i64 VPR128:$Rm))))], 165259698Sdim NoItinerary>; 166259698Sdim } 167259698Sdim} 168259698Sdim 169259698Sdim// Multiclass NeonI_3VSame_SD_sizes: Operand types are floating point types, 170259698Sdim// but Result types can be integer or floating point types. 171259698Sdimmulticlass NeonI_3VSame_SD_sizes<bit u, bit size, bits<5> opcode, 172259698Sdim string asmop, SDPatternOperator opnode2S, 173259698Sdim SDPatternOperator opnode4S, 174259698Sdim SDPatternOperator opnode2D, 175259698Sdim ValueType ResTy2S, ValueType ResTy4S, 176259698Sdim ValueType ResTy2D, bit Commutable = 0> { 177259698Sdim let isCommutable = Commutable in { 178259698Sdim def _2S : NeonI_3VSame<0b0, u, {size, 0b0}, opcode, 179259698Sdim (outs VPR64:$Rd), (ins VPR64:$Rn, VPR64:$Rm), 180259698Sdim asmop # "\t$Rd.2s, $Rn.2s, $Rm.2s", 181259698Sdim [(set (ResTy2S VPR64:$Rd), 182259698Sdim (ResTy2S (opnode2S (v2f32 VPR64:$Rn), (v2f32 VPR64:$Rm))))], 183259698Sdim NoItinerary>; 184259698Sdim 185259698Sdim def _4S : NeonI_3VSame<0b1, u, {size, 0b0}, opcode, 186259698Sdim (outs VPR128:$Rd), (ins VPR128:$Rn, VPR128:$Rm), 187259698Sdim asmop # "\t$Rd.4s, $Rn.4s, $Rm.4s", 188259698Sdim [(set (ResTy4S VPR128:$Rd), 189259698Sdim (ResTy4S (opnode4S (v4f32 VPR128:$Rn), (v4f32 VPR128:$Rm))))], 190259698Sdim NoItinerary>; 191259698Sdim 192259698Sdim def _2D : NeonI_3VSame<0b1, u, {size, 0b1}, opcode, 193259698Sdim (outs VPR128:$Rd), (ins VPR128:$Rn, VPR128:$Rm), 194259698Sdim asmop # "\t$Rd.2d, $Rn.2d, $Rm.2d", 195259698Sdim [(set (ResTy2D VPR128:$Rd), 196259698Sdim (ResTy2D (opnode2D (v2f64 VPR128:$Rn), (v2f64 VPR128:$Rm))))], 197259698Sdim NoItinerary>; 198259698Sdim } 199259698Sdim} 200259698Sdim 201259698Sdim//===----------------------------------------------------------------------===// 202259698Sdim// Instruction Definitions 203259698Sdim//===----------------------------------------------------------------------===// 204259698Sdim 205259698Sdim// Vector Arithmetic Instructions 206259698Sdim 207259698Sdim// Vector Add (Integer and Floating-Point) 208259698Sdim 209259698Sdimdefm ADDvvv : NeonI_3VSame_BHSD_sizes<0b0, 0b10000, "add", add, 1>; 210259698Sdimdefm FADDvvv : NeonI_3VSame_SD_sizes<0b0, 0b0, 0b11010, "fadd", fadd, fadd, fadd, 211259698Sdim v2f32, v4f32, v2f64, 1>; 212259698Sdim 213259698Sdim// Vector Sub (Integer and Floating-Point) 214259698Sdim 215259698Sdimdefm SUBvvv : NeonI_3VSame_BHSD_sizes<0b1, 0b10000, "sub", sub, 0>; 216259698Sdimdefm FSUBvvv : NeonI_3VSame_SD_sizes<0b0, 0b1, 0b11010, "fsub", fsub, fsub, fsub, 217259698Sdim v2f32, v4f32, v2f64, 0>; 218259698Sdim 219259698Sdim// Vector Multiply (Integer and Floating-Point) 220259698Sdim 221259698Sdimdefm MULvvv : NeonI_3VSame_BHS_sizes<0b0, 0b10011, "mul", mul, 1>; 222259698Sdimdefm FMULvvv : NeonI_3VSame_SD_sizes<0b1, 0b0, 0b11011, "fmul", fmul, fmul, fmul, 223259698Sdim v2f32, v4f32, v2f64, 1>; 224259698Sdim 225259698Sdim// Vector Multiply (Polynomial) 226259698Sdim 227259698Sdimdefm PMULvvv : NeonI_3VSame_B_sizes<0b1, 0b00, 0b10011, "pmul", 228259698Sdim int_arm_neon_vmulp, int_arm_neon_vmulp, 1>; 229259698Sdim 230259698Sdim// Vector Multiply-accumulate and Multiply-subtract (Integer) 231259698Sdim 232259698Sdim// class NeonI_3VSame_Constraint_impl: NeonI_3VSame with no data type and 233259698Sdim// two operands constraints. 234259698Sdimclass NeonI_3VSame_Constraint_impl<string asmop, string asmlane, 235259698Sdim RegisterOperand VPRC, ValueType OpTy, bit q, bit u, bits<2> size, 236259698Sdim bits<5> opcode, SDPatternOperator opnode> 237259698Sdim : NeonI_3VSame<q, u, size, opcode, 238259698Sdim (outs VPRC:$Rd), (ins VPRC:$src, VPRC:$Rn, VPRC:$Rm), 239259698Sdim asmop # "\t$Rd" # asmlane # ", $Rn" # asmlane # ", $Rm" # asmlane, 240259698Sdim [(set (OpTy VPRC:$Rd), 241259698Sdim (OpTy (opnode (OpTy VPRC:$src), (OpTy VPRC:$Rn), (OpTy VPRC:$Rm))))], 242259698Sdim NoItinerary> { 243259698Sdim let Constraints = "$src = $Rd"; 244259698Sdim} 245259698Sdim 246259698Sdimdef Neon_mla : PatFrag<(ops node:$Ra, node:$Rn, node:$Rm), 247259698Sdim (add node:$Ra, (mul node:$Rn, node:$Rm))>; 248259698Sdim 249259698Sdimdef Neon_mls : PatFrag<(ops node:$Ra, node:$Rn, node:$Rm), 250259698Sdim (sub node:$Ra, (mul node:$Rn, node:$Rm))>; 251259698Sdim 252259698Sdim 253259698Sdimdef MLAvvv_8B: NeonI_3VSame_Constraint_impl<"mla", ".8b", VPR64, v8i8, 254259698Sdim 0b0, 0b0, 0b00, 0b10010, Neon_mla>; 255259698Sdimdef MLAvvv_16B: NeonI_3VSame_Constraint_impl<"mla", ".16b", VPR128, v16i8, 256259698Sdim 0b1, 0b0, 0b00, 0b10010, Neon_mla>; 257259698Sdimdef MLAvvv_4H: NeonI_3VSame_Constraint_impl<"mla", ".4h", VPR64, v4i16, 258259698Sdim 0b0, 0b0, 0b01, 0b10010, Neon_mla>; 259259698Sdimdef MLAvvv_8H: NeonI_3VSame_Constraint_impl<"mla", ".8h", VPR128, v8i16, 260259698Sdim 0b1, 0b0, 0b01, 0b10010, Neon_mla>; 261259698Sdimdef MLAvvv_2S: NeonI_3VSame_Constraint_impl<"mla", ".2s", VPR64, v2i32, 262259698Sdim 0b0, 0b0, 0b10, 0b10010, Neon_mla>; 263259698Sdimdef MLAvvv_4S: NeonI_3VSame_Constraint_impl<"mla", ".4s", VPR128, v4i32, 264259698Sdim 0b1, 0b0, 0b10, 0b10010, Neon_mla>; 265259698Sdim 266259698Sdimdef MLSvvv_8B: NeonI_3VSame_Constraint_impl<"mls", ".8b", VPR64, v8i8, 267259698Sdim 0b0, 0b1, 0b00, 0b10010, Neon_mls>; 268259698Sdimdef MLSvvv_16B: NeonI_3VSame_Constraint_impl<"mls", ".16b", VPR128, v16i8, 269259698Sdim 0b1, 0b1, 0b00, 0b10010, Neon_mls>; 270259698Sdimdef MLSvvv_4H: NeonI_3VSame_Constraint_impl<"mls", ".4h", VPR64, v4i16, 271259698Sdim 0b0, 0b1, 0b01, 0b10010, Neon_mls>; 272259698Sdimdef MLSvvv_8H: NeonI_3VSame_Constraint_impl<"mls", ".8h", VPR128, v8i16, 273259698Sdim 0b1, 0b1, 0b01, 0b10010, Neon_mls>; 274259698Sdimdef MLSvvv_2S: NeonI_3VSame_Constraint_impl<"mls", ".2s", VPR64, v2i32, 275259698Sdim 0b0, 0b1, 0b10, 0b10010, Neon_mls>; 276259698Sdimdef MLSvvv_4S: NeonI_3VSame_Constraint_impl<"mls", ".4s", VPR128, v4i32, 277259698Sdim 0b1, 0b1, 0b10, 0b10010, Neon_mls>; 278259698Sdim 279259698Sdim// Vector Multiply-accumulate and Multiply-subtract (Floating Point) 280259698Sdim 281259698Sdimdef Neon_fmla : PatFrag<(ops node:$Ra, node:$Rn, node:$Rm), 282259698Sdim (fadd node:$Ra, (fmul node:$Rn, node:$Rm))>; 283259698Sdim 284259698Sdimdef Neon_fmls : PatFrag<(ops node:$Ra, node:$Rn, node:$Rm), 285259698Sdim (fsub node:$Ra, (fmul node:$Rn, node:$Rm))>; 286259698Sdim 287259698Sdimlet Predicates = [HasNEON, UseFusedMAC] in { 288259698Sdimdef FMLAvvv_2S: NeonI_3VSame_Constraint_impl<"fmla", ".2s", VPR64, v2f32, 289259698Sdim 0b0, 0b0, 0b00, 0b11001, Neon_fmla>; 290259698Sdimdef FMLAvvv_4S: NeonI_3VSame_Constraint_impl<"fmla", ".4s", VPR128, v4f32, 291259698Sdim 0b1, 0b0, 0b00, 0b11001, Neon_fmla>; 292259698Sdimdef FMLAvvv_2D: NeonI_3VSame_Constraint_impl<"fmla", ".2d", VPR128, v2f64, 293259698Sdim 0b1, 0b0, 0b01, 0b11001, Neon_fmla>; 294259698Sdim 295259698Sdimdef FMLSvvv_2S: NeonI_3VSame_Constraint_impl<"fmls", ".2s", VPR64, v2f32, 296259698Sdim 0b0, 0b0, 0b10, 0b11001, Neon_fmls>; 297259698Sdimdef FMLSvvv_4S: NeonI_3VSame_Constraint_impl<"fmls", ".4s", VPR128, v4f32, 298259698Sdim 0b1, 0b0, 0b10, 0b11001, Neon_fmls>; 299259698Sdimdef FMLSvvv_2D: NeonI_3VSame_Constraint_impl<"fmls", ".2d", VPR128, v2f64, 300259698Sdim 0b1, 0b0, 0b11, 0b11001, Neon_fmls>; 301259698Sdim} 302259698Sdim 303259698Sdim// We're also allowed to match the fma instruction regardless of compile 304259698Sdim// options. 305259698Sdimdef : Pat<(v2f32 (fma VPR64:$Rn, VPR64:$Rm, VPR64:$Ra)), 306259698Sdim (FMLAvvv_2S VPR64:$Ra, VPR64:$Rn, VPR64:$Rm)>; 307259698Sdimdef : Pat<(v4f32 (fma VPR128:$Rn, VPR128:$Rm, VPR128:$Ra)), 308259698Sdim (FMLAvvv_4S VPR128:$Ra, VPR128:$Rn, VPR128:$Rm)>; 309259698Sdimdef : Pat<(v2f64 (fma VPR128:$Rn, VPR128:$Rm, VPR128:$Ra)), 310259698Sdim (FMLAvvv_2D VPR128:$Ra, VPR128:$Rn, VPR128:$Rm)>; 311259698Sdim 312259698Sdimdef : Pat<(v2f32 (fma (fneg VPR64:$Rn), VPR64:$Rm, VPR64:$Ra)), 313259698Sdim (FMLSvvv_2S VPR64:$Ra, VPR64:$Rn, VPR64:$Rm)>; 314259698Sdimdef : Pat<(v4f32 (fma (fneg VPR128:$Rn), VPR128:$Rm, VPR128:$Ra)), 315259698Sdim (FMLSvvv_4S VPR128:$Ra, VPR128:$Rn, VPR128:$Rm)>; 316259698Sdimdef : Pat<(v2f64 (fma (fneg VPR128:$Rn), VPR128:$Rm, VPR128:$Ra)), 317259698Sdim (FMLSvvv_2D VPR128:$Ra, VPR128:$Rn, VPR128:$Rm)>; 318259698Sdim 319259698Sdim// Vector Divide (Floating-Point) 320259698Sdim 321259698Sdimdefm FDIVvvv : NeonI_3VSame_SD_sizes<0b1, 0b0, 0b11111, "fdiv", fdiv, fdiv, fdiv, 322259698Sdim v2f32, v4f32, v2f64, 0>; 323259698Sdim 324259698Sdim// Vector Bitwise Operations 325259698Sdim 326259698Sdim// Vector Bitwise AND 327259698Sdim 328259698Sdimdefm ANDvvv : NeonI_3VSame_B_sizes<0b0, 0b00, 0b00011, "and", and, and, 1>; 329259698Sdim 330259698Sdim// Vector Bitwise Exclusive OR 331259698Sdim 332259698Sdimdefm EORvvv : NeonI_3VSame_B_sizes<0b1, 0b00, 0b00011, "eor", xor, xor, 1>; 333259698Sdim 334259698Sdim// Vector Bitwise OR 335259698Sdim 336259698Sdimdefm ORRvvv : NeonI_3VSame_B_sizes<0b0, 0b10, 0b00011, "orr", or, or, 1>; 337259698Sdim 338259698Sdim// ORR disassembled as MOV if Vn==Vm 339259698Sdim 340259698Sdim// Vector Move - register 341259698Sdim// Alias for ORR if Vn=Vm. 342259698Sdim// FIXME: This is actually the preferred syntax but TableGen can't deal with 343259698Sdim// custom printing of aliases. 344259698Sdimdef : NeonInstAlias<"mov $Rd.8b, $Rn.8b", 345259698Sdim (ORRvvv_8B VPR64:$Rd, VPR64:$Rn, VPR64:$Rn), 0>; 346259698Sdimdef : NeonInstAlias<"mov $Rd.16b, $Rn.16b", 347259698Sdim (ORRvvv_16B VPR128:$Rd, VPR128:$Rn, VPR128:$Rn), 0>; 348259698Sdim 349259698Sdim// The MOVI instruction takes two immediate operands. The first is the 350259698Sdim// immediate encoding, while the second is the cmode. A cmode of 14, or 351259698Sdim// 0b1110, produces a MOVI operation, rather than a MVNI, ORR, or BIC. 352259698Sdimdef Neon_AllZero : PatFrag<(ops), (Neon_movi (i32 0), (i32 14))>; 353259698Sdimdef Neon_AllOne : PatFrag<(ops), (Neon_movi (i32 255), (i32 14))>; 354259698Sdim 355259698Sdimdef Neon_not8B : PatFrag<(ops node:$in), 356259698Sdim (xor node:$in, (bitconvert (v8i8 Neon_AllOne)))>; 357259698Sdimdef Neon_not16B : PatFrag<(ops node:$in), 358259698Sdim (xor node:$in, (bitconvert (v16i8 Neon_AllOne)))>; 359259698Sdim 360259698Sdimdef Neon_orn8B : PatFrag<(ops node:$Rn, node:$Rm), 361259698Sdim (or node:$Rn, (Neon_not8B node:$Rm))>; 362259698Sdim 363259698Sdimdef Neon_orn16B : PatFrag<(ops node:$Rn, node:$Rm), 364259698Sdim (or node:$Rn, (Neon_not16B node:$Rm))>; 365259698Sdim 366259698Sdimdef Neon_bic8B : PatFrag<(ops node:$Rn, node:$Rm), 367259698Sdim (and node:$Rn, (Neon_not8B node:$Rm))>; 368259698Sdim 369259698Sdimdef Neon_bic16B : PatFrag<(ops node:$Rn, node:$Rm), 370259698Sdim (and node:$Rn, (Neon_not16B node:$Rm))>; 371259698Sdim 372259698Sdim 373259698Sdim// Vector Bitwise OR NOT - register 374259698Sdim 375259698Sdimdefm ORNvvv : NeonI_3VSame_B_sizes<0b0, 0b11, 0b00011, "orn", 376259698Sdim Neon_orn8B, Neon_orn16B, 0>; 377259698Sdim 378259698Sdim// Vector Bitwise Bit Clear (AND NOT) - register 379259698Sdim 380259698Sdimdefm BICvvv : NeonI_3VSame_B_sizes<0b0, 0b01, 0b00011, "bic", 381259698Sdim Neon_bic8B, Neon_bic16B, 0>; 382259698Sdim 383259698Sdimmulticlass Neon_bitwise2V_patterns<SDPatternOperator opnode8B, 384259698Sdim SDPatternOperator opnode16B, 385259698Sdim Instruction INST8B, 386259698Sdim Instruction INST16B> { 387259698Sdim def : Pat<(v2i32 (opnode8B VPR64:$Rn, VPR64:$Rm)), 388259698Sdim (INST8B VPR64:$Rn, VPR64:$Rm)>; 389259698Sdim def : Pat<(v4i16 (opnode8B VPR64:$Rn, VPR64:$Rm)), 390259698Sdim (INST8B VPR64:$Rn, VPR64:$Rm)>; 391259698Sdim def : Pat<(v1i64 (opnode8B VPR64:$Rn, VPR64:$Rm)), 392259698Sdim (INST8B VPR64:$Rn, VPR64:$Rm)>; 393259698Sdim def : Pat<(v4i32 (opnode16B VPR128:$Rn, VPR128:$Rm)), 394259698Sdim (INST16B VPR128:$Rn, VPR128:$Rm)>; 395259698Sdim def : Pat<(v8i16 (opnode16B VPR128:$Rn, VPR128:$Rm)), 396259698Sdim (INST16B VPR128:$Rn, VPR128:$Rm)>; 397259698Sdim def : Pat<(v2i64 (opnode16B VPR128:$Rn, VPR128:$Rm)), 398259698Sdim (INST16B VPR128:$Rn, VPR128:$Rm)>; 399259698Sdim} 400259698Sdim 401259698Sdim// Additional patterns for bitwise instructions AND, EOR, ORR, BIC, ORN 402259698Sdimdefm : Neon_bitwise2V_patterns<and, and, ANDvvv_8B, ANDvvv_16B>; 403259698Sdimdefm : Neon_bitwise2V_patterns<or, or, ORRvvv_8B, ORRvvv_16B>; 404259698Sdimdefm : Neon_bitwise2V_patterns<xor, xor, EORvvv_8B, EORvvv_16B>; 405259698Sdimdefm : Neon_bitwise2V_patterns<Neon_bic8B, Neon_bic16B, BICvvv_8B, BICvvv_16B>; 406259698Sdimdefm : Neon_bitwise2V_patterns<Neon_orn8B, Neon_orn16B, ORNvvv_8B, ORNvvv_16B>; 407259698Sdim 408259698Sdim// Vector Bitwise Select 409259698Sdimdef BSLvvv_8B : NeonI_3VSame_Constraint_impl<"bsl", ".8b", VPR64, v8i8, 410259698Sdim 0b0, 0b1, 0b01, 0b00011, Neon_bsl>; 411259698Sdim 412259698Sdimdef BSLvvv_16B : NeonI_3VSame_Constraint_impl<"bsl", ".16b", VPR128, v16i8, 413259698Sdim 0b1, 0b1, 0b01, 0b00011, Neon_bsl>; 414259698Sdim 415259698Sdimmulticlass Neon_bitwise3V_patterns<SDPatternOperator opnode, 416259698Sdim Instruction INST8B, 417259698Sdim Instruction INST16B> { 418259698Sdim // Disassociate type from instruction definition 419259698Sdim def : Pat<(v2i32 (opnode VPR64:$src,VPR64:$Rn, VPR64:$Rm)), 420259698Sdim (INST8B VPR64:$src, VPR64:$Rn, VPR64:$Rm)>; 421259698Sdim def : Pat<(v4i16 (opnode VPR64:$src, VPR64:$Rn, VPR64:$Rm)), 422259698Sdim (INST8B VPR64:$src, VPR64:$Rn, VPR64:$Rm)>; 423259698Sdim def : Pat<(v1i64 (opnode VPR64:$src, VPR64:$Rn, VPR64:$Rm)), 424259698Sdim (INST8B VPR64:$src, VPR64:$Rn, VPR64:$Rm)>; 425259698Sdim def : Pat<(v4i32 (opnode VPR128:$src, VPR128:$Rn, VPR128:$Rm)), 426259698Sdim (INST16B VPR128:$src, VPR128:$Rn, VPR128:$Rm)>; 427259698Sdim def : Pat<(v8i16 (opnode VPR128:$src, VPR128:$Rn, VPR128:$Rm)), 428259698Sdim (INST16B VPR128:$src, VPR128:$Rn, VPR128:$Rm)>; 429259698Sdim def : Pat<(v2i64 (opnode VPR128:$src, VPR128:$Rn, VPR128:$Rm)), 430259698Sdim (INST16B VPR128:$src, VPR128:$Rn, VPR128:$Rm)>; 431259698Sdim 432259698Sdim // Allow to match BSL instruction pattern with non-constant operand 433259698Sdim def : Pat<(v8i8 (or (and VPR64:$Rn, VPR64:$Rd), 434259698Sdim (and VPR64:$Rm, (Neon_not8B VPR64:$Rd)))), 435259698Sdim (INST8B VPR64:$Rd, VPR64:$Rn, VPR64:$Rm)>; 436259698Sdim def : Pat<(v4i16 (or (and VPR64:$Rn, VPR64:$Rd), 437259698Sdim (and VPR64:$Rm, (Neon_not8B VPR64:$Rd)))), 438259698Sdim (INST8B VPR64:$Rd, VPR64:$Rn, VPR64:$Rm)>; 439259698Sdim def : Pat<(v2i32 (or (and VPR64:$Rn, VPR64:$Rd), 440259698Sdim (and VPR64:$Rm, (Neon_not8B VPR64:$Rd)))), 441259698Sdim (INST8B VPR64:$Rd, VPR64:$Rn, VPR64:$Rm)>; 442259698Sdim def : Pat<(v1i64 (or (and VPR64:$Rn, VPR64:$Rd), 443259698Sdim (and VPR64:$Rm, (Neon_not8B VPR64:$Rd)))), 444259698Sdim (INST8B VPR64:$Rd, VPR64:$Rn, VPR64:$Rm)>; 445259698Sdim def : Pat<(v16i8 (or (and VPR128:$Rn, VPR128:$Rd), 446259698Sdim (and VPR128:$Rm, (Neon_not16B VPR128:$Rd)))), 447259698Sdim (INST16B VPR128:$Rd, VPR128:$Rn, VPR128:$Rm)>; 448259698Sdim def : Pat<(v8i16 (or (and VPR128:$Rn, VPR128:$Rd), 449259698Sdim (and VPR128:$Rm, (Neon_not16B VPR128:$Rd)))), 450259698Sdim (INST16B VPR128:$Rd, VPR128:$Rn, VPR128:$Rm)>; 451259698Sdim def : Pat<(v4i32 (or (and VPR128:$Rn, VPR128:$Rd), 452259698Sdim (and VPR128:$Rm, (Neon_not16B VPR128:$Rd)))), 453259698Sdim (INST16B VPR128:$Rd, VPR128:$Rn, VPR128:$Rm)>; 454259698Sdim def : Pat<(v2i64 (or (and VPR128:$Rn, VPR128:$Rd), 455259698Sdim (and VPR128:$Rm, (Neon_not16B VPR128:$Rd)))), 456259698Sdim (INST16B VPR128:$Rd, VPR128:$Rn, VPR128:$Rm)>; 457259698Sdim 458259698Sdim // Allow to match llvm.arm.* intrinsics. 459259698Sdim def : Pat<(v8i8 (int_arm_neon_vbsl (v8i8 VPR64:$src), 460259698Sdim (v8i8 VPR64:$Rn), (v8i8 VPR64:$Rm))), 461259698Sdim (INST8B VPR64:$src, VPR64:$Rn, VPR64:$Rm)>; 462259698Sdim def : Pat<(v4i16 (int_arm_neon_vbsl (v4i16 VPR64:$src), 463259698Sdim (v4i16 VPR64:$Rn), (v4i16 VPR64:$Rm))), 464259698Sdim (INST8B VPR64:$src, VPR64:$Rn, VPR64:$Rm)>; 465259698Sdim def : Pat<(v2i32 (int_arm_neon_vbsl (v2i32 VPR64:$src), 466259698Sdim (v2i32 VPR64:$Rn), (v2i32 VPR64:$Rm))), 467259698Sdim (INST8B VPR64:$src, VPR64:$Rn, VPR64:$Rm)>; 468259698Sdim def : Pat<(v1i64 (int_arm_neon_vbsl (v1i64 VPR64:$src), 469259698Sdim (v1i64 VPR64:$Rn), (v1i64 VPR64:$Rm))), 470259698Sdim (INST8B VPR64:$src, VPR64:$Rn, VPR64:$Rm)>; 471259698Sdim def : Pat<(v2f32 (int_arm_neon_vbsl (v2f32 VPR64:$src), 472259698Sdim (v2f32 VPR64:$Rn), (v2f32 VPR64:$Rm))), 473259698Sdim (INST8B VPR64:$src, VPR64:$Rn, VPR64:$Rm)>; 474259698Sdim def : Pat<(v1f64 (int_arm_neon_vbsl (v1f64 VPR64:$src), 475259698Sdim (v1f64 VPR64:$Rn), (v1f64 VPR64:$Rm))), 476259698Sdim (INST8B VPR64:$src, VPR64:$Rn, VPR64:$Rm)>; 477259698Sdim def : Pat<(v16i8 (int_arm_neon_vbsl (v16i8 VPR128:$src), 478259698Sdim (v16i8 VPR128:$Rn), (v16i8 VPR128:$Rm))), 479259698Sdim (INST16B VPR128:$src, VPR128:$Rn, VPR128:$Rm)>; 480259698Sdim def : Pat<(v8i16 (int_arm_neon_vbsl (v8i16 VPR128:$src), 481259698Sdim (v8i16 VPR128:$Rn), (v8i16 VPR128:$Rm))), 482259698Sdim (INST16B VPR128:$src, VPR128:$Rn, VPR128:$Rm)>; 483259698Sdim def : Pat<(v4i32 (int_arm_neon_vbsl (v4i32 VPR128:$src), 484259698Sdim (v4i32 VPR128:$Rn), (v4i32 VPR128:$Rm))), 485259698Sdim (INST16B VPR128:$src, VPR128:$Rn, VPR128:$Rm)>; 486259698Sdim def : Pat<(v2i64 (int_arm_neon_vbsl (v2i64 VPR128:$src), 487259698Sdim (v2i64 VPR128:$Rn), (v2i64 VPR128:$Rm))), 488259698Sdim (INST16B VPR128:$src, VPR128:$Rn, VPR128:$Rm)>; 489259698Sdim def : Pat<(v4f32 (int_arm_neon_vbsl (v4f32 VPR128:$src), 490259698Sdim (v4f32 VPR128:$Rn), (v4f32 VPR128:$Rm))), 491259698Sdim (INST16B VPR128:$src, VPR128:$Rn, VPR128:$Rm)>; 492259698Sdim def : Pat<(v2f64 (int_arm_neon_vbsl (v2f64 VPR128:$src), 493259698Sdim (v2f64 VPR128:$Rn), (v2f64 VPR128:$Rm))), 494259698Sdim (INST16B VPR128:$src, VPR128:$Rn, VPR128:$Rm)>; 495259698Sdim} 496259698Sdim 497259698Sdim// Additional patterns for bitwise instruction BSL 498259698Sdimdefm: Neon_bitwise3V_patterns<Neon_bsl, BSLvvv_8B, BSLvvv_16B>; 499259698Sdim 500259698Sdimdef Neon_NoBSLop : PatFrag<(ops node:$src, node:$Rn, node:$Rm), 501259698Sdim (Neon_bsl node:$src, node:$Rn, node:$Rm), 502259698Sdim [{ (void)N; return false; }]>; 503259698Sdim 504259698Sdim// Vector Bitwise Insert if True 505259698Sdim 506259698Sdimdef BITvvv_8B : NeonI_3VSame_Constraint_impl<"bit", ".8b", VPR64, v8i8, 507259698Sdim 0b0, 0b1, 0b10, 0b00011, Neon_NoBSLop>; 508259698Sdimdef BITvvv_16B : NeonI_3VSame_Constraint_impl<"bit", ".16b", VPR128, v16i8, 509259698Sdim 0b1, 0b1, 0b10, 0b00011, Neon_NoBSLop>; 510259698Sdim 511259698Sdim// Vector Bitwise Insert if False 512259698Sdim 513259698Sdimdef BIFvvv_8B : NeonI_3VSame_Constraint_impl<"bif", ".8b", VPR64, v8i8, 514259698Sdim 0b0, 0b1, 0b11, 0b00011, Neon_NoBSLop>; 515259698Sdimdef BIFvvv_16B : NeonI_3VSame_Constraint_impl<"bif", ".16b", VPR128, v16i8, 516259698Sdim 0b1, 0b1, 0b11, 0b00011, Neon_NoBSLop>; 517259698Sdim 518259698Sdim// Vector Absolute Difference and Accumulate (Signed, Unsigned) 519259698Sdim 520259698Sdimdef Neon_uaba : PatFrag<(ops node:$Ra, node:$Rn, node:$Rm), 521259698Sdim (add node:$Ra, (int_arm_neon_vabdu node:$Rn, node:$Rm))>; 522259698Sdimdef Neon_saba : PatFrag<(ops node:$Ra, node:$Rn, node:$Rm), 523259698Sdim (add node:$Ra, (int_arm_neon_vabds node:$Rn, node:$Rm))>; 524259698Sdim 525259698Sdim// Vector Absolute Difference and Accumulate (Unsigned) 526259698Sdimdef UABAvvv_8B : NeonI_3VSame_Constraint_impl<"uaba", ".8b", VPR64, v8i8, 527259698Sdim 0b0, 0b1, 0b00, 0b01111, Neon_uaba>; 528259698Sdimdef UABAvvv_16B : NeonI_3VSame_Constraint_impl<"uaba", ".16b", VPR128, v16i8, 529259698Sdim 0b1, 0b1, 0b00, 0b01111, Neon_uaba>; 530259698Sdimdef UABAvvv_4H : NeonI_3VSame_Constraint_impl<"uaba", ".4h", VPR64, v4i16, 531259698Sdim 0b0, 0b1, 0b01, 0b01111, Neon_uaba>; 532259698Sdimdef UABAvvv_8H : NeonI_3VSame_Constraint_impl<"uaba", ".8h", VPR128, v8i16, 533259698Sdim 0b1, 0b1, 0b01, 0b01111, Neon_uaba>; 534259698Sdimdef UABAvvv_2S : NeonI_3VSame_Constraint_impl<"uaba", ".2s", VPR64, v2i32, 535259698Sdim 0b0, 0b1, 0b10, 0b01111, Neon_uaba>; 536259698Sdimdef UABAvvv_4S : NeonI_3VSame_Constraint_impl<"uaba", ".4s", VPR128, v4i32, 537259698Sdim 0b1, 0b1, 0b10, 0b01111, Neon_uaba>; 538259698Sdim 539259698Sdim// Vector Absolute Difference and Accumulate (Signed) 540259698Sdimdef SABAvvv_8B : NeonI_3VSame_Constraint_impl<"saba", ".8b", VPR64, v8i8, 541259698Sdim 0b0, 0b0, 0b00, 0b01111, Neon_saba>; 542259698Sdimdef SABAvvv_16B : NeonI_3VSame_Constraint_impl<"saba", ".16b", VPR128, v16i8, 543259698Sdim 0b1, 0b0, 0b00, 0b01111, Neon_saba>; 544259698Sdimdef SABAvvv_4H : NeonI_3VSame_Constraint_impl<"saba", ".4h", VPR64, v4i16, 545259698Sdim 0b0, 0b0, 0b01, 0b01111, Neon_saba>; 546259698Sdimdef SABAvvv_8H : NeonI_3VSame_Constraint_impl<"saba", ".8h", VPR128, v8i16, 547259698Sdim 0b1, 0b0, 0b01, 0b01111, Neon_saba>; 548259698Sdimdef SABAvvv_2S : NeonI_3VSame_Constraint_impl<"saba", ".2s", VPR64, v2i32, 549259698Sdim 0b0, 0b0, 0b10, 0b01111, Neon_saba>; 550259698Sdimdef SABAvvv_4S : NeonI_3VSame_Constraint_impl<"saba", ".4s", VPR128, v4i32, 551259698Sdim 0b1, 0b0, 0b10, 0b01111, Neon_saba>; 552259698Sdim 553259698Sdim 554259698Sdim// Vector Absolute Difference (Signed, Unsigned) 555259698Sdimdefm UABDvvv : NeonI_3VSame_BHS_sizes<0b1, 0b01110, "uabd", int_arm_neon_vabdu, 0>; 556259698Sdimdefm SABDvvv : NeonI_3VSame_BHS_sizes<0b0, 0b01110, "sabd", int_arm_neon_vabds, 0>; 557259698Sdim 558259698Sdim// Vector Absolute Difference (Floating Point) 559259698Sdimdefm FABDvvv: NeonI_3VSame_SD_sizes<0b1, 0b1, 0b11010, "fabd", 560259698Sdim int_arm_neon_vabds, int_arm_neon_vabds, 561259698Sdim int_arm_neon_vabds, v2f32, v4f32, v2f64, 0>; 562259698Sdim 563259698Sdim// Vector Reciprocal Step (Floating Point) 564259698Sdimdefm FRECPSvvv : NeonI_3VSame_SD_sizes<0b0, 0b0, 0b11111, "frecps", 565259698Sdim int_arm_neon_vrecps, int_arm_neon_vrecps, 566259698Sdim int_arm_neon_vrecps, 567259698Sdim v2f32, v4f32, v2f64, 0>; 568259698Sdim 569259698Sdim// Vector Reciprocal Square Root Step (Floating Point) 570259698Sdimdefm FRSQRTSvvv : NeonI_3VSame_SD_sizes<0b0, 0b1, 0b11111, "frsqrts", 571259698Sdim int_arm_neon_vrsqrts, 572259698Sdim int_arm_neon_vrsqrts, 573259698Sdim int_arm_neon_vrsqrts, 574259698Sdim v2f32, v4f32, v2f64, 0>; 575259698Sdim 576259698Sdim// Vector Comparisons 577259698Sdim 578259698Sdimdef Neon_cmeq : PatFrag<(ops node:$lhs, node:$rhs), 579259698Sdim (Neon_cmp node:$lhs, node:$rhs, SETEQ)>; 580259698Sdimdef Neon_cmphs : PatFrag<(ops node:$lhs, node:$rhs), 581259698Sdim (Neon_cmp node:$lhs, node:$rhs, SETUGE)>; 582259698Sdimdef Neon_cmge : PatFrag<(ops node:$lhs, node:$rhs), 583259698Sdim (Neon_cmp node:$lhs, node:$rhs, SETGE)>; 584259698Sdimdef Neon_cmhi : PatFrag<(ops node:$lhs, node:$rhs), 585259698Sdim (Neon_cmp node:$lhs, node:$rhs, SETUGT)>; 586259698Sdimdef Neon_cmgt : PatFrag<(ops node:$lhs, node:$rhs), 587259698Sdim (Neon_cmp node:$lhs, node:$rhs, SETGT)>; 588259698Sdim 589259698Sdim// NeonI_compare_aliases class: swaps register operands to implement 590259698Sdim// comparison aliases, e.g., CMLE is alias for CMGE with operands reversed. 591259698Sdimclass NeonI_compare_aliases<string asmop, string asmlane, 592259698Sdim Instruction inst, RegisterOperand VPRC> 593259698Sdim : NeonInstAlias<asmop # "\t$Rd" # asmlane #", $Rn" # asmlane # 594259698Sdim ", $Rm" # asmlane, 595259698Sdim (inst VPRC:$Rd, VPRC:$Rm, VPRC:$Rn), 0b0>; 596259698Sdim 597259698Sdim// Vector Comparisons (Integer) 598259698Sdim 599259698Sdim// Vector Compare Mask Equal (Integer) 600259698Sdimlet isCommutable =1 in { 601259698Sdimdefm CMEQvvv : NeonI_3VSame_BHSD_sizes<0b1, 0b10001, "cmeq", Neon_cmeq, 0>; 602259698Sdim} 603259698Sdim 604259698Sdim// Vector Compare Mask Higher or Same (Unsigned Integer) 605259698Sdimdefm CMHSvvv : NeonI_3VSame_BHSD_sizes<0b1, 0b00111, "cmhs", Neon_cmphs, 0>; 606259698Sdim 607259698Sdim// Vector Compare Mask Greater Than or Equal (Integer) 608259698Sdimdefm CMGEvvv : NeonI_3VSame_BHSD_sizes<0b0, 0b00111, "cmge", Neon_cmge, 0>; 609259698Sdim 610259698Sdim// Vector Compare Mask Higher (Unsigned Integer) 611259698Sdimdefm CMHIvvv : NeonI_3VSame_BHSD_sizes<0b1, 0b00110, "cmhi", Neon_cmhi, 0>; 612259698Sdim 613259698Sdim// Vector Compare Mask Greater Than (Integer) 614259698Sdimdefm CMGTvvv : NeonI_3VSame_BHSD_sizes<0b0, 0b00110, "cmgt", Neon_cmgt, 0>; 615259698Sdim 616259698Sdim// Vector Compare Mask Bitwise Test (Integer) 617259698Sdimdefm CMTSTvvv: NeonI_3VSame_BHSD_sizes<0b0, 0b10001, "cmtst", Neon_tst, 0>; 618259698Sdim 619259698Sdim// Vector Compare Mask Less or Same (Unsigned Integer) 620259698Sdim// CMLS is alias for CMHS with operands reversed. 621259698Sdimdef CMLSvvv_8B : NeonI_compare_aliases<"cmls", ".8b", CMHSvvv_8B, VPR64>; 622259698Sdimdef CMLSvvv_16B : NeonI_compare_aliases<"cmls", ".16b", CMHSvvv_16B, VPR128>; 623259698Sdimdef CMLSvvv_4H : NeonI_compare_aliases<"cmls", ".4h", CMHSvvv_4H, VPR64>; 624259698Sdimdef CMLSvvv_8H : NeonI_compare_aliases<"cmls", ".8h", CMHSvvv_8H, VPR128>; 625259698Sdimdef CMLSvvv_2S : NeonI_compare_aliases<"cmls", ".2s", CMHSvvv_2S, VPR64>; 626259698Sdimdef CMLSvvv_4S : NeonI_compare_aliases<"cmls", ".4s", CMHSvvv_4S, VPR128>; 627259698Sdimdef CMLSvvv_2D : NeonI_compare_aliases<"cmls", ".2d", CMHSvvv_2D, VPR128>; 628259698Sdim 629259698Sdim// Vector Compare Mask Less Than or Equal (Integer) 630259698Sdim// CMLE is alias for CMGE with operands reversed. 631259698Sdimdef CMLEvvv_8B : NeonI_compare_aliases<"cmle", ".8b", CMGEvvv_8B, VPR64>; 632259698Sdimdef CMLEvvv_16B : NeonI_compare_aliases<"cmle", ".16b", CMGEvvv_16B, VPR128>; 633259698Sdimdef CMLEvvv_4H : NeonI_compare_aliases<"cmle", ".4h", CMGEvvv_4H, VPR64>; 634259698Sdimdef CMLEvvv_8H : NeonI_compare_aliases<"cmle", ".8h", CMGEvvv_8H, VPR128>; 635259698Sdimdef CMLEvvv_2S : NeonI_compare_aliases<"cmle", ".2s", CMGEvvv_2S, VPR64>; 636259698Sdimdef CMLEvvv_4S : NeonI_compare_aliases<"cmle", ".4s", CMGEvvv_4S, VPR128>; 637259698Sdimdef CMLEvvv_2D : NeonI_compare_aliases<"cmle", ".2d", CMGEvvv_2D, VPR128>; 638259698Sdim 639259698Sdim// Vector Compare Mask Lower (Unsigned Integer) 640259698Sdim// CMLO is alias for CMHI with operands reversed. 641259698Sdimdef CMLOvvv_8B : NeonI_compare_aliases<"cmlo", ".8b", CMHIvvv_8B, VPR64>; 642259698Sdimdef CMLOvvv_16B : NeonI_compare_aliases<"cmlo", ".16b", CMHIvvv_16B, VPR128>; 643259698Sdimdef CMLOvvv_4H : NeonI_compare_aliases<"cmlo", ".4h", CMHIvvv_4H, VPR64>; 644259698Sdimdef CMLOvvv_8H : NeonI_compare_aliases<"cmlo", ".8h", CMHIvvv_8H, VPR128>; 645259698Sdimdef CMLOvvv_2S : NeonI_compare_aliases<"cmlo", ".2s", CMHIvvv_2S, VPR64>; 646259698Sdimdef CMLOvvv_4S : NeonI_compare_aliases<"cmlo", ".4s", CMHIvvv_4S, VPR128>; 647259698Sdimdef CMLOvvv_2D : NeonI_compare_aliases<"cmlo", ".2d", CMHIvvv_2D, VPR128>; 648259698Sdim 649259698Sdim// Vector Compare Mask Less Than (Integer) 650259698Sdim// CMLT is alias for CMGT with operands reversed. 651259698Sdimdef CMLTvvv_8B : NeonI_compare_aliases<"cmlt", ".8b", CMGTvvv_8B, VPR64>; 652259698Sdimdef CMLTvvv_16B : NeonI_compare_aliases<"cmlt", ".16b", CMGTvvv_16B, VPR128>; 653259698Sdimdef CMLTvvv_4H : NeonI_compare_aliases<"cmlt", ".4h", CMGTvvv_4H, VPR64>; 654259698Sdimdef CMLTvvv_8H : NeonI_compare_aliases<"cmlt", ".8h", CMGTvvv_8H, VPR128>; 655259698Sdimdef CMLTvvv_2S : NeonI_compare_aliases<"cmlt", ".2s", CMGTvvv_2S, VPR64>; 656259698Sdimdef CMLTvvv_4S : NeonI_compare_aliases<"cmlt", ".4s", CMGTvvv_4S, VPR128>; 657259698Sdimdef CMLTvvv_2D : NeonI_compare_aliases<"cmlt", ".2d", CMGTvvv_2D, VPR128>; 658259698Sdim 659259698Sdim 660259698Sdimdef neon_uimm0_asmoperand : AsmOperandClass 661259698Sdim{ 662259698Sdim let Name = "UImm0"; 663259698Sdim let PredicateMethod = "isUImm<0>"; 664259698Sdim let RenderMethod = "addImmOperands"; 665259698Sdim} 666259698Sdim 667259698Sdimdef neon_uimm0 : Operand<i32>, ImmLeaf<i32, [{return Imm == 0;}]> { 668259698Sdim let ParserMatchClass = neon_uimm0_asmoperand; 669259698Sdim let PrintMethod = "printNeonUImm0Operand"; 670259698Sdim 671259698Sdim} 672259698Sdim 673259698Sdimmulticlass NeonI_cmpz_sizes<bit u, bits<5> opcode, string asmop, CondCode CC> 674259698Sdim{ 675259698Sdim def _8B : NeonI_2VMisc<0b0, u, 0b00, opcode, 676259698Sdim (outs VPR64:$Rd), (ins VPR64:$Rn, neon_uimm0:$Imm), 677259698Sdim asmop # "\t$Rd.8b, $Rn.8b, $Imm", 678259698Sdim [(set (v8i8 VPR64:$Rd), 679259698Sdim (v8i8 (Neon_cmpz (v8i8 VPR64:$Rn), (i32 imm:$Imm), CC)))], 680259698Sdim NoItinerary>; 681259698Sdim 682259698Sdim def _16B : NeonI_2VMisc<0b1, u, 0b00, opcode, 683259698Sdim (outs VPR128:$Rd), (ins VPR128:$Rn, neon_uimm0:$Imm), 684259698Sdim asmop # "\t$Rd.16b, $Rn.16b, $Imm", 685259698Sdim [(set (v16i8 VPR128:$Rd), 686259698Sdim (v16i8 (Neon_cmpz (v16i8 VPR128:$Rn), (i32 imm:$Imm), CC)))], 687259698Sdim NoItinerary>; 688259698Sdim 689259698Sdim def _4H : NeonI_2VMisc<0b0, u, 0b01, opcode, 690259698Sdim (outs VPR64:$Rd), (ins VPR64:$Rn, neon_uimm0:$Imm), 691259698Sdim asmop # "\t$Rd.4h, $Rn.4h, $Imm", 692259698Sdim [(set (v4i16 VPR64:$Rd), 693259698Sdim (v4i16 (Neon_cmpz (v4i16 VPR64:$Rn), (i32 imm:$Imm), CC)))], 694259698Sdim NoItinerary>; 695259698Sdim 696259698Sdim def _8H : NeonI_2VMisc<0b1, u, 0b01, opcode, 697259698Sdim (outs VPR128:$Rd), (ins VPR128:$Rn, neon_uimm0:$Imm), 698259698Sdim asmop # "\t$Rd.8h, $Rn.8h, $Imm", 699259698Sdim [(set (v8i16 VPR128:$Rd), 700259698Sdim (v8i16 (Neon_cmpz (v8i16 VPR128:$Rn), (i32 imm:$Imm), CC)))], 701259698Sdim NoItinerary>; 702259698Sdim 703259698Sdim def _2S : NeonI_2VMisc<0b0, u, 0b10, opcode, 704259698Sdim (outs VPR64:$Rd), (ins VPR64:$Rn, neon_uimm0:$Imm), 705259698Sdim asmop # "\t$Rd.2s, $Rn.2s, $Imm", 706259698Sdim [(set (v2i32 VPR64:$Rd), 707259698Sdim (v2i32 (Neon_cmpz (v2i32 VPR64:$Rn), (i32 imm:$Imm), CC)))], 708259698Sdim NoItinerary>; 709259698Sdim 710259698Sdim def _4S : NeonI_2VMisc<0b1, u, 0b10, opcode, 711259698Sdim (outs VPR128:$Rd), (ins VPR128:$Rn, neon_uimm0:$Imm), 712259698Sdim asmop # "\t$Rd.4s, $Rn.4s, $Imm", 713259698Sdim [(set (v4i32 VPR128:$Rd), 714259698Sdim (v4i32 (Neon_cmpz (v4i32 VPR128:$Rn), (i32 imm:$Imm), CC)))], 715259698Sdim NoItinerary>; 716259698Sdim 717259698Sdim def _2D : NeonI_2VMisc<0b1, u, 0b11, opcode, 718259698Sdim (outs VPR128:$Rd), (ins VPR128:$Rn, neon_uimm0:$Imm), 719259698Sdim asmop # "\t$Rd.2d, $Rn.2d, $Imm", 720259698Sdim [(set (v2i64 VPR128:$Rd), 721259698Sdim (v2i64 (Neon_cmpz (v2i64 VPR128:$Rn), (i32 imm:$Imm), CC)))], 722259698Sdim NoItinerary>; 723259698Sdim} 724259698Sdim 725259698Sdim// Vector Compare Mask Equal to Zero (Integer) 726259698Sdimdefm CMEQvvi : NeonI_cmpz_sizes<0b0, 0b01001, "cmeq", SETEQ>; 727259698Sdim 728259698Sdim// Vector Compare Mask Greater Than or Equal to Zero (Signed Integer) 729259698Sdimdefm CMGEvvi : NeonI_cmpz_sizes<0b1, 0b01000, "cmge", SETGE>; 730259698Sdim 731259698Sdim// Vector Compare Mask Greater Than Zero (Signed Integer) 732259698Sdimdefm CMGTvvi : NeonI_cmpz_sizes<0b0, 0b01000, "cmgt", SETGT>; 733259698Sdim 734259698Sdim// Vector Compare Mask Less Than or Equal To Zero (Signed Integer) 735259698Sdimdefm CMLEvvi : NeonI_cmpz_sizes<0b1, 0b01001, "cmle", SETLE>; 736259698Sdim 737259698Sdim// Vector Compare Mask Less Than Zero (Signed Integer) 738259698Sdimdefm CMLTvvi : NeonI_cmpz_sizes<0b0, 0b01010, "cmlt", SETLT>; 739259698Sdim 740259698Sdim// Vector Comparisons (Floating Point) 741259698Sdim 742259698Sdim// Vector Compare Mask Equal (Floating Point) 743259698Sdimlet isCommutable =1 in { 744259698Sdimdefm FCMEQvvv : NeonI_3VSame_SD_sizes<0b0, 0b0, 0b11100, "fcmeq", Neon_cmeq, 745259698Sdim Neon_cmeq, Neon_cmeq, 746259698Sdim v2i32, v4i32, v2i64, 0>; 747259698Sdim} 748259698Sdim 749259698Sdim// Vector Compare Mask Greater Than Or Equal (Floating Point) 750259698Sdimdefm FCMGEvvv : NeonI_3VSame_SD_sizes<0b1, 0b0, 0b11100, "fcmge", Neon_cmge, 751259698Sdim Neon_cmge, Neon_cmge, 752259698Sdim v2i32, v4i32, v2i64, 0>; 753259698Sdim 754259698Sdim// Vector Compare Mask Greater Than (Floating Point) 755259698Sdimdefm FCMGTvvv : NeonI_3VSame_SD_sizes<0b1, 0b1, 0b11100, "fcmgt", Neon_cmgt, 756259698Sdim Neon_cmgt, Neon_cmgt, 757259698Sdim v2i32, v4i32, v2i64, 0>; 758259698Sdim 759259698Sdim// Vector Compare Mask Less Than Or Equal (Floating Point) 760259698Sdim// FCMLE is alias for FCMGE with operands reversed. 761259698Sdimdef FCMLEvvv_2S : NeonI_compare_aliases<"fcmle", ".2s", FCMGEvvv_2S, VPR64>; 762259698Sdimdef FCMLEvvv_4S : NeonI_compare_aliases<"fcmle", ".4s", FCMGEvvv_4S, VPR128>; 763259698Sdimdef FCMLEvvv_2D : NeonI_compare_aliases<"fcmle", ".2d", FCMGEvvv_2D, VPR128>; 764259698Sdim 765259698Sdim// Vector Compare Mask Less Than (Floating Point) 766259698Sdim// FCMLT is alias for FCMGT with operands reversed. 767259698Sdimdef FCMLTvvv_2S : NeonI_compare_aliases<"fcmlt", ".2s", FCMGTvvv_2S, VPR64>; 768259698Sdimdef FCMLTvvv_4S : NeonI_compare_aliases<"fcmlt", ".4s", FCMGTvvv_4S, VPR128>; 769259698Sdimdef FCMLTvvv_2D : NeonI_compare_aliases<"fcmlt", ".2d", FCMGTvvv_2D, VPR128>; 770259698Sdim 771259698Sdim 772259698Sdimmulticlass NeonI_fpcmpz_sizes<bit u, bit size, bits<5> opcode, 773259698Sdim string asmop, CondCode CC> 774259698Sdim{ 775259698Sdim def _2S : NeonI_2VMisc<0b0, u, {size, 0b0}, opcode, 776259698Sdim (outs VPR64:$Rd), (ins VPR64:$Rn, fpz32:$FPImm), 777259698Sdim asmop # "\t$Rd.2s, $Rn.2s, $FPImm", 778259698Sdim [(set (v2i32 VPR64:$Rd), 779259698Sdim (v2i32 (Neon_cmpz (v2f32 VPR64:$Rn), (f32 fpimm:$FPImm), CC)))], 780259698Sdim NoItinerary>; 781259698Sdim 782259698Sdim def _4S : NeonI_2VMisc<0b1, u, {size, 0b0}, opcode, 783259698Sdim (outs VPR128:$Rd), (ins VPR128:$Rn, fpz32:$FPImm), 784259698Sdim asmop # "\t$Rd.4s, $Rn.4s, $FPImm", 785259698Sdim [(set (v4i32 VPR128:$Rd), 786259698Sdim (v4i32 (Neon_cmpz (v4f32 VPR128:$Rn), (f32 fpimm:$FPImm), CC)))], 787259698Sdim NoItinerary>; 788259698Sdim 789259698Sdim def _2D : NeonI_2VMisc<0b1, u, {size, 0b1}, opcode, 790259698Sdim (outs VPR128:$Rd), (ins VPR128:$Rn, fpz32:$FPImm), 791259698Sdim asmop # "\t$Rd.2d, $Rn.2d, $FPImm", 792259698Sdim [(set (v2i64 VPR128:$Rd), 793259698Sdim (v2i64 (Neon_cmpz (v2f64 VPR128:$Rn), (f32 fpimm:$FPImm), CC)))], 794259698Sdim NoItinerary>; 795259698Sdim} 796259698Sdim 797259698Sdim// Vector Compare Mask Equal to Zero (Floating Point) 798259698Sdimdefm FCMEQvvi : NeonI_fpcmpz_sizes<0b0, 0b1, 0b01101, "fcmeq", SETEQ>; 799259698Sdim 800259698Sdim// Vector Compare Mask Greater Than or Equal to Zero (Floating Point) 801259698Sdimdefm FCMGEvvi : NeonI_fpcmpz_sizes<0b1, 0b1, 0b01100, "fcmge", SETGE>; 802259698Sdim 803259698Sdim// Vector Compare Mask Greater Than Zero (Floating Point) 804259698Sdimdefm FCMGTvvi : NeonI_fpcmpz_sizes<0b0, 0b1, 0b01100, "fcmgt", SETGT>; 805259698Sdim 806259698Sdim// Vector Compare Mask Less Than or Equal To Zero (Floating Point) 807259698Sdimdefm FCMLEvvi : NeonI_fpcmpz_sizes<0b1, 0b1, 0b01101, "fcmle", SETLE>; 808259698Sdim 809259698Sdim// Vector Compare Mask Less Than Zero (Floating Point) 810259698Sdimdefm FCMLTvvi : NeonI_fpcmpz_sizes<0b0, 0b1, 0b01110, "fcmlt", SETLT>; 811259698Sdim 812259698Sdim// Vector Absolute Comparisons (Floating Point) 813259698Sdim 814259698Sdim// Vector Absolute Compare Mask Greater Than Or Equal (Floating Point) 815259698Sdimdefm FACGEvvv : NeonI_3VSame_SD_sizes<0b1, 0b0, 0b11101, "facge", 816259698Sdim int_arm_neon_vacged, int_arm_neon_vacgeq, 817259698Sdim int_aarch64_neon_vacgeq, 818259698Sdim v2i32, v4i32, v2i64, 0>; 819259698Sdim 820259698Sdim// Vector Absolute Compare Mask Greater Than (Floating Point) 821259698Sdimdefm FACGTvvv : NeonI_3VSame_SD_sizes<0b1, 0b1, 0b11101, "facgt", 822259698Sdim int_arm_neon_vacgtd, int_arm_neon_vacgtq, 823259698Sdim int_aarch64_neon_vacgtq, 824259698Sdim v2i32, v4i32, v2i64, 0>; 825259698Sdim 826259698Sdim// Vector Absolute Compare Mask Less Than Or Equal (Floating Point) 827259698Sdim// FACLE is alias for FACGE with operands reversed. 828259698Sdimdef FACLEvvv_2S : NeonI_compare_aliases<"facle", ".2s", FACGEvvv_2S, VPR64>; 829259698Sdimdef FACLEvvv_4S : NeonI_compare_aliases<"facle", ".4s", FACGEvvv_4S, VPR128>; 830259698Sdimdef FACLEvvv_2D : NeonI_compare_aliases<"facle", ".2d", FACGEvvv_2D, VPR128>; 831259698Sdim 832259698Sdim// Vector Absolute Compare Mask Less Than (Floating Point) 833259698Sdim// FACLT is alias for FACGT with operands reversed. 834259698Sdimdef FACLTvvv_2S : NeonI_compare_aliases<"faclt", ".2s", FACGTvvv_2S, VPR64>; 835259698Sdimdef FACLTvvv_4S : NeonI_compare_aliases<"faclt", ".4s", FACGTvvv_4S, VPR128>; 836259698Sdimdef FACLTvvv_2D : NeonI_compare_aliases<"faclt", ".2d", FACGTvvv_2D, VPR128>; 837259698Sdim 838259698Sdim// Vector halving add (Integer Signed, Unsigned) 839259698Sdimdefm SHADDvvv : NeonI_3VSame_BHS_sizes<0b0, 0b00000, "shadd", 840259698Sdim int_arm_neon_vhadds, 1>; 841259698Sdimdefm UHADDvvv : NeonI_3VSame_BHS_sizes<0b1, 0b00000, "uhadd", 842259698Sdim int_arm_neon_vhaddu, 1>; 843259698Sdim 844259698Sdim// Vector halving sub (Integer Signed, Unsigned) 845259698Sdimdefm SHSUBvvv : NeonI_3VSame_BHS_sizes<0b0, 0b00100, "shsub", 846259698Sdim int_arm_neon_vhsubs, 0>; 847259698Sdimdefm UHSUBvvv : NeonI_3VSame_BHS_sizes<0b1, 0b00100, "uhsub", 848259698Sdim int_arm_neon_vhsubu, 0>; 849259698Sdim 850259698Sdim// Vector rouding halving add (Integer Signed, Unsigned) 851259698Sdimdefm SRHADDvvv : NeonI_3VSame_BHS_sizes<0b0, 0b00010, "srhadd", 852259698Sdim int_arm_neon_vrhadds, 1>; 853259698Sdimdefm URHADDvvv : NeonI_3VSame_BHS_sizes<0b1, 0b00010, "urhadd", 854259698Sdim int_arm_neon_vrhaddu, 1>; 855259698Sdim 856259698Sdim// Vector Saturating add (Integer Signed, Unsigned) 857259698Sdimdefm SQADDvvv : NeonI_3VSame_BHSD_sizes<0b0, 0b00001, "sqadd", 858259698Sdim int_arm_neon_vqadds, 1>; 859259698Sdimdefm UQADDvvv : NeonI_3VSame_BHSD_sizes<0b1, 0b00001, "uqadd", 860259698Sdim int_arm_neon_vqaddu, 1>; 861259698Sdim 862259698Sdim// Vector Saturating sub (Integer Signed, Unsigned) 863259698Sdimdefm SQSUBvvv : NeonI_3VSame_BHSD_sizes<0b0, 0b00101, "sqsub", 864259698Sdim int_arm_neon_vqsubs, 1>; 865259698Sdimdefm UQSUBvvv : NeonI_3VSame_BHSD_sizes<0b1, 0b00101, "uqsub", 866259698Sdim int_arm_neon_vqsubu, 1>; 867259698Sdim 868259698Sdim// Vector Shift Left (Signed and Unsigned Integer) 869259698Sdimdefm SSHLvvv : NeonI_3VSame_BHSD_sizes<0b0, 0b01000, "sshl", 870259698Sdim int_arm_neon_vshifts, 1>; 871259698Sdimdefm USHLvvv : NeonI_3VSame_BHSD_sizes<0b1, 0b01000, "ushl", 872259698Sdim int_arm_neon_vshiftu, 1>; 873259698Sdim 874259698Sdim// Vector Saturating Shift Left (Signed and Unsigned Integer) 875259698Sdimdefm SQSHLvvv : NeonI_3VSame_BHSD_sizes<0b0, 0b01001, "sqshl", 876259698Sdim int_arm_neon_vqshifts, 1>; 877259698Sdimdefm UQSHLvvv : NeonI_3VSame_BHSD_sizes<0b1, 0b01001, "uqshl", 878259698Sdim int_arm_neon_vqshiftu, 1>; 879259698Sdim 880259698Sdim// Vector Rouding Shift Left (Signed and Unsigned Integer) 881259698Sdimdefm SRSHLvvv : NeonI_3VSame_BHSD_sizes<0b0, 0b01010, "srshl", 882259698Sdim int_arm_neon_vrshifts, 1>; 883259698Sdimdefm URSHLvvv : NeonI_3VSame_BHSD_sizes<0b1, 0b01010, "urshl", 884259698Sdim int_arm_neon_vrshiftu, 1>; 885259698Sdim 886259698Sdim// Vector Saturating Rouding Shift Left (Signed and Unsigned Integer) 887259698Sdimdefm SQRSHLvvv : NeonI_3VSame_BHSD_sizes<0b0, 0b01011, "sqrshl", 888259698Sdim int_arm_neon_vqrshifts, 1>; 889259698Sdimdefm UQRSHLvvv : NeonI_3VSame_BHSD_sizes<0b1, 0b01011, "uqrshl", 890259698Sdim int_arm_neon_vqrshiftu, 1>; 891259698Sdim 892259698Sdim// Vector Maximum (Signed and Unsigned Integer) 893259698Sdimdefm SMAXvvv : NeonI_3VSame_BHS_sizes<0b0, 0b01100, "smax", int_arm_neon_vmaxs, 1>; 894259698Sdimdefm UMAXvvv : NeonI_3VSame_BHS_sizes<0b1, 0b01100, "umax", int_arm_neon_vmaxu, 1>; 895259698Sdim 896259698Sdim// Vector Minimum (Signed and Unsigned Integer) 897259698Sdimdefm SMINvvv : NeonI_3VSame_BHS_sizes<0b0, 0b01101, "smin", int_arm_neon_vmins, 1>; 898259698Sdimdefm UMINvvv : NeonI_3VSame_BHS_sizes<0b1, 0b01101, "umin", int_arm_neon_vminu, 1>; 899259698Sdim 900259698Sdim// Vector Maximum (Floating Point) 901259698Sdimdefm FMAXvvv : NeonI_3VSame_SD_sizes<0b0, 0b0, 0b11110, "fmax", 902259698Sdim int_arm_neon_vmaxs, int_arm_neon_vmaxs, 903259698Sdim int_arm_neon_vmaxs, v2f32, v4f32, v2f64, 1>; 904259698Sdim 905259698Sdim// Vector Minimum (Floating Point) 906259698Sdimdefm FMINvvv : NeonI_3VSame_SD_sizes<0b0, 0b1, 0b11110, "fmin", 907259698Sdim int_arm_neon_vmins, int_arm_neon_vmins, 908259698Sdim int_arm_neon_vmins, v2f32, v4f32, v2f64, 1>; 909259698Sdim 910259698Sdim// Vector maxNum (Floating Point) - prefer a number over a quiet NaN) 911259698Sdimdefm FMAXNMvvv : NeonI_3VSame_SD_sizes<0b0, 0b0, 0b11000, "fmaxnm", 912259698Sdim int_aarch64_neon_vmaxnm, 913259698Sdim int_aarch64_neon_vmaxnm, 914259698Sdim int_aarch64_neon_vmaxnm, 915259698Sdim v2f32, v4f32, v2f64, 1>; 916259698Sdim 917259698Sdim// Vector minNum (Floating Point) - prefer a number over a quiet NaN) 918259698Sdimdefm FMINNMvvv : NeonI_3VSame_SD_sizes<0b0, 0b1, 0b11000, "fminnm", 919259698Sdim int_aarch64_neon_vminnm, 920259698Sdim int_aarch64_neon_vminnm, 921259698Sdim int_aarch64_neon_vminnm, 922259698Sdim v2f32, v4f32, v2f64, 1>; 923259698Sdim 924259698Sdim// Vector Maximum Pairwise (Signed and Unsigned Integer) 925259698Sdimdefm SMAXPvvv : NeonI_3VSame_BHS_sizes<0b0, 0b10100, "smaxp", int_arm_neon_vpmaxs, 1>; 926259698Sdimdefm UMAXPvvv : NeonI_3VSame_BHS_sizes<0b1, 0b10100, "umaxp", int_arm_neon_vpmaxu, 1>; 927259698Sdim 928259698Sdim// Vector Minimum Pairwise (Signed and Unsigned Integer) 929259698Sdimdefm SMINPvvv : NeonI_3VSame_BHS_sizes<0b0, 0b10101, "sminp", int_arm_neon_vpmins, 1>; 930259698Sdimdefm UMINPvvv : NeonI_3VSame_BHS_sizes<0b1, 0b10101, "uminp", int_arm_neon_vpminu, 1>; 931259698Sdim 932259698Sdim// Vector Maximum Pairwise (Floating Point) 933259698Sdimdefm FMAXPvvv : NeonI_3VSame_SD_sizes<0b1, 0b0, 0b11110, "fmaxp", 934259698Sdim int_arm_neon_vpmaxs, int_arm_neon_vpmaxs, 935259698Sdim int_arm_neon_vpmaxs, v2f32, v4f32, v2f64, 1>; 936259698Sdim 937259698Sdim// Vector Minimum Pairwise (Floating Point) 938259698Sdimdefm FMINPvvv : NeonI_3VSame_SD_sizes<0b1, 0b1, 0b11110, "fminp", 939259698Sdim int_arm_neon_vpmins, int_arm_neon_vpmins, 940259698Sdim int_arm_neon_vpmins, v2f32, v4f32, v2f64, 1>; 941259698Sdim 942259698Sdim// Vector maxNum Pairwise (Floating Point) - prefer a number over a quiet NaN) 943259698Sdimdefm FMAXNMPvvv : NeonI_3VSame_SD_sizes<0b1, 0b0, 0b11000, "fmaxnmp", 944259698Sdim int_aarch64_neon_vpmaxnm, 945259698Sdim int_aarch64_neon_vpmaxnm, 946259698Sdim int_aarch64_neon_vpmaxnm, 947259698Sdim v2f32, v4f32, v2f64, 1>; 948259698Sdim 949259698Sdim// Vector minNum Pairwise (Floating Point) - prefer a number over a quiet NaN) 950259698Sdimdefm FMINNMPvvv : NeonI_3VSame_SD_sizes<0b1, 0b1, 0b11000, "fminnmp", 951259698Sdim int_aarch64_neon_vpminnm, 952259698Sdim int_aarch64_neon_vpminnm, 953259698Sdim int_aarch64_neon_vpminnm, 954259698Sdim v2f32, v4f32, v2f64, 1>; 955259698Sdim 956259698Sdim// Vector Addition Pairwise (Integer) 957259698Sdimdefm ADDP : NeonI_3VSame_BHSD_sizes<0b0, 0b10111, "addp", int_arm_neon_vpadd, 1>; 958259698Sdim 959259698Sdim// Vector Addition Pairwise (Floating Point) 960259698Sdimdefm FADDP : NeonI_3VSame_SD_sizes<0b1, 0b0, 0b11010, "faddp", 961259698Sdim int_arm_neon_vpadd, 962259698Sdim int_arm_neon_vpadd, 963259698Sdim int_arm_neon_vpadd, 964259698Sdim v2f32, v4f32, v2f64, 1>; 965259698Sdim 966259698Sdim// Vector Saturating Doubling Multiply High 967259698Sdimdefm SQDMULHvvv : NeonI_3VSame_HS_sizes<0b0, 0b10110, "sqdmulh", 968259698Sdim int_arm_neon_vqdmulh, 1>; 969259698Sdim 970259698Sdim// Vector Saturating Rouding Doubling Multiply High 971259698Sdimdefm SQRDMULHvvv : NeonI_3VSame_HS_sizes<0b1, 0b10110, "sqrdmulh", 972259698Sdim int_arm_neon_vqrdmulh, 1>; 973259698Sdim 974259698Sdim// Vector Multiply Extended (Floating Point) 975259698Sdimdefm FMULXvvv : NeonI_3VSame_SD_sizes<0b0, 0b0, 0b11011, "fmulx", 976259698Sdim int_aarch64_neon_vmulx, 977259698Sdim int_aarch64_neon_vmulx, 978259698Sdim int_aarch64_neon_vmulx, 979259698Sdim v2f32, v4f32, v2f64, 1>; 980259698Sdim 981259698Sdim// Vector Immediate Instructions 982259698Sdim 983259698Sdimmulticlass neon_mov_imm_shift_asmoperands<string PREFIX> 984259698Sdim{ 985259698Sdim def _asmoperand : AsmOperandClass 986259698Sdim { 987259698Sdim let Name = "NeonMovImmShift" # PREFIX; 988259698Sdim let RenderMethod = "addNeonMovImmShift" # PREFIX # "Operands"; 989259698Sdim let PredicateMethod = "isNeonMovImmShift" # PREFIX; 990259698Sdim } 991259698Sdim} 992259698Sdim 993259698Sdim// Definition of vector immediates shift operands 994259698Sdim 995259698Sdim// The selectable use-cases extract the shift operation 996259698Sdim// information from the OpCmode fields encoded in the immediate. 997259698Sdimdef neon_mod_shift_imm_XFORM : SDNodeXForm<imm, [{ 998259698Sdim uint64_t OpCmode = N->getZExtValue(); 999259698Sdim unsigned ShiftImm; 1000259698Sdim unsigned ShiftOnesIn; 1001259698Sdim unsigned HasShift = 1002259698Sdim A64Imms::decodeNeonModShiftImm(OpCmode, ShiftImm, ShiftOnesIn); 1003259698Sdim if (!HasShift) return SDValue(); 1004259698Sdim return CurDAG->getTargetConstant(ShiftImm, MVT::i32); 1005259698Sdim}]>; 1006259698Sdim 1007259698Sdim// Vector immediates shift operands which accept LSL and MSL 1008259698Sdim// shift operators with shift value in the range of 0, 8, 16, 24 (LSL), 1009259698Sdim// or 0, 8 (LSLH) or 8, 16 (MSL). 1010259698Sdimdefm neon_mov_imm_LSL : neon_mov_imm_shift_asmoperands<"LSL">; 1011259698Sdimdefm neon_mov_imm_MSL : neon_mov_imm_shift_asmoperands<"MSL">; 1012259698Sdim// LSLH restricts shift amount to 0, 8 out of 0, 8, 16, 24 1013259698Sdimdefm neon_mov_imm_LSLH : neon_mov_imm_shift_asmoperands<"LSLH">; 1014259698Sdim 1015259698Sdimmulticlass neon_mov_imm_shift_operands<string PREFIX, 1016259698Sdim string HALF, string ISHALF, code pred> 1017259698Sdim{ 1018259698Sdim def _operand : Operand<i32>, ImmLeaf<i32, pred, neon_mod_shift_imm_XFORM> 1019259698Sdim { 1020259698Sdim let PrintMethod = 1021259698Sdim "printNeonMovImmShiftOperand<A64SE::" # PREFIX # ", " # ISHALF # ">"; 1022259698Sdim let DecoderMethod = 1023259698Sdim "DecodeNeonMovImmShiftOperand<A64SE::" # PREFIX # ", " # ISHALF # ">"; 1024259698Sdim let ParserMatchClass = 1025259698Sdim !cast<AsmOperandClass>("neon_mov_imm_" # PREFIX # HALF # "_asmoperand"); 1026259698Sdim } 1027259698Sdim} 1028259698Sdim 1029259698Sdimdefm neon_mov_imm_LSL : neon_mov_imm_shift_operands<"LSL", "", "false", [{ 1030259698Sdim unsigned ShiftImm; 1031259698Sdim unsigned ShiftOnesIn; 1032259698Sdim unsigned HasShift = 1033259698Sdim A64Imms::decodeNeonModShiftImm(Imm, ShiftImm, ShiftOnesIn); 1034259698Sdim return (HasShift && !ShiftOnesIn); 1035259698Sdim}]>; 1036259698Sdim 1037259698Sdimdefm neon_mov_imm_MSL : neon_mov_imm_shift_operands<"MSL", "", "false", [{ 1038259698Sdim unsigned ShiftImm; 1039259698Sdim unsigned ShiftOnesIn; 1040259698Sdim unsigned HasShift = 1041259698Sdim A64Imms::decodeNeonModShiftImm(Imm, ShiftImm, ShiftOnesIn); 1042259698Sdim return (HasShift && ShiftOnesIn); 1043259698Sdim}]>; 1044259698Sdim 1045259698Sdimdefm neon_mov_imm_LSLH : neon_mov_imm_shift_operands<"LSL", "H", "true", [{ 1046259698Sdim unsigned ShiftImm; 1047259698Sdim unsigned ShiftOnesIn; 1048259698Sdim unsigned HasShift = 1049259698Sdim A64Imms::decodeNeonModShiftImm(Imm, ShiftImm, ShiftOnesIn); 1050259698Sdim return (HasShift && !ShiftOnesIn); 1051259698Sdim}]>; 1052259698Sdim 1053259698Sdimdef neon_uimm1_asmoperand : AsmOperandClass 1054259698Sdim{ 1055259698Sdim let Name = "UImm1"; 1056259698Sdim let PredicateMethod = "isUImm<1>"; 1057259698Sdim let RenderMethod = "addImmOperands"; 1058259698Sdim} 1059259698Sdim 1060259698Sdimdef neon_uimm2_asmoperand : AsmOperandClass 1061259698Sdim{ 1062259698Sdim let Name = "UImm2"; 1063259698Sdim let PredicateMethod = "isUImm<2>"; 1064259698Sdim let RenderMethod = "addImmOperands"; 1065259698Sdim} 1066259698Sdim 1067259698Sdimdef neon_uimm8_asmoperand : AsmOperandClass 1068259698Sdim{ 1069259698Sdim let Name = "UImm8"; 1070259698Sdim let PredicateMethod = "isUImm<8>"; 1071259698Sdim let RenderMethod = "addImmOperands"; 1072259698Sdim} 1073259698Sdim 1074259698Sdimdef neon_uimm8 : Operand<i32>, ImmLeaf<i32, [{(void)Imm; return true;}]> { 1075259698Sdim let ParserMatchClass = neon_uimm8_asmoperand; 1076259698Sdim let PrintMethod = "printUImmHexOperand"; 1077259698Sdim} 1078259698Sdim 1079259698Sdimdef neon_uimm64_mask_asmoperand : AsmOperandClass 1080259698Sdim{ 1081259698Sdim let Name = "NeonUImm64Mask"; 1082259698Sdim let PredicateMethod = "isNeonUImm64Mask"; 1083259698Sdim let RenderMethod = "addNeonUImm64MaskOperands"; 1084259698Sdim} 1085259698Sdim 1086259698Sdim// MCOperand for 64-bit bytemask with each byte having only the 1087259698Sdim// value 0x00 and 0xff is encoded as an unsigned 8-bit value 1088259698Sdimdef neon_uimm64_mask : Operand<i32>, ImmLeaf<i32, [{(void)Imm; return true;}]> { 1089259698Sdim let ParserMatchClass = neon_uimm64_mask_asmoperand; 1090259698Sdim let PrintMethod = "printNeonUImm64MaskOperand"; 1091259698Sdim} 1092259698Sdim 1093259698Sdimmulticlass NeonI_mov_imm_lsl_sizes<string asmop, bit op, 1094259698Sdim SDPatternOperator opnode> 1095259698Sdim{ 1096259698Sdim // shift zeros, per word 1097259698Sdim def _2S : NeonI_1VModImm<0b0, op, 1098259698Sdim (outs VPR64:$Rd), 1099259698Sdim (ins neon_uimm8:$Imm, 1100259698Sdim neon_mov_imm_LSL_operand:$Simm), 1101259698Sdim !strconcat(asmop, "\t$Rd.2s, $Imm$Simm"), 1102259698Sdim [(set (v2i32 VPR64:$Rd), 1103259698Sdim (v2i32 (opnode (timm:$Imm), 1104259698Sdim (neon_mov_imm_LSL_operand:$Simm))))], 1105259698Sdim NoItinerary> { 1106259698Sdim bits<2> Simm; 1107259698Sdim let cmode = {0b0, Simm{1}, Simm{0}, 0b0}; 1108259698Sdim } 1109259698Sdim 1110259698Sdim def _4S : NeonI_1VModImm<0b1, op, 1111259698Sdim (outs VPR128:$Rd), 1112259698Sdim (ins neon_uimm8:$Imm, 1113259698Sdim neon_mov_imm_LSL_operand:$Simm), 1114259698Sdim !strconcat(asmop, "\t$Rd.4s, $Imm$Simm"), 1115259698Sdim [(set (v4i32 VPR128:$Rd), 1116259698Sdim (v4i32 (opnode (timm:$Imm), 1117259698Sdim (neon_mov_imm_LSL_operand:$Simm))))], 1118259698Sdim NoItinerary> { 1119259698Sdim bits<2> Simm; 1120259698Sdim let cmode = {0b0, Simm{1}, Simm{0}, 0b0}; 1121259698Sdim } 1122259698Sdim 1123259698Sdim // shift zeros, per halfword 1124259698Sdim def _4H : NeonI_1VModImm<0b0, op, 1125259698Sdim (outs VPR64:$Rd), 1126259698Sdim (ins neon_uimm8:$Imm, 1127259698Sdim neon_mov_imm_LSLH_operand:$Simm), 1128259698Sdim !strconcat(asmop, "\t$Rd.4h, $Imm$Simm"), 1129259698Sdim [(set (v4i16 VPR64:$Rd), 1130259698Sdim (v4i16 (opnode (timm:$Imm), 1131259698Sdim (neon_mov_imm_LSLH_operand:$Simm))))], 1132259698Sdim NoItinerary> { 1133259698Sdim bit Simm; 1134259698Sdim let cmode = {0b1, 0b0, Simm, 0b0}; 1135259698Sdim } 1136259698Sdim 1137259698Sdim def _8H : NeonI_1VModImm<0b1, op, 1138259698Sdim (outs VPR128:$Rd), 1139259698Sdim (ins neon_uimm8:$Imm, 1140259698Sdim neon_mov_imm_LSLH_operand:$Simm), 1141259698Sdim !strconcat(asmop, "\t$Rd.8h, $Imm$Simm"), 1142259698Sdim [(set (v8i16 VPR128:$Rd), 1143259698Sdim (v8i16 (opnode (timm:$Imm), 1144259698Sdim (neon_mov_imm_LSLH_operand:$Simm))))], 1145259698Sdim NoItinerary> { 1146259698Sdim bit Simm; 1147259698Sdim let cmode = {0b1, 0b0, Simm, 0b0}; 1148259698Sdim } 1149259698Sdim} 1150259698Sdim 1151259698Sdimmulticlass NeonI_mov_imm_with_constraint_lsl_sizes<string asmop, bit op, 1152259698Sdim SDPatternOperator opnode, 1153259698Sdim SDPatternOperator neonopnode> 1154259698Sdim{ 1155259698Sdim let Constraints = "$src = $Rd" in { 1156259698Sdim // shift zeros, per word 1157259698Sdim def _2S : NeonI_1VModImm<0b0, op, 1158259698Sdim (outs VPR64:$Rd), 1159259698Sdim (ins VPR64:$src, neon_uimm8:$Imm, 1160259698Sdim neon_mov_imm_LSL_operand:$Simm), 1161259698Sdim !strconcat(asmop, "\t$Rd.2s, $Imm$Simm"), 1162259698Sdim [(set (v2i32 VPR64:$Rd), 1163259698Sdim (v2i32 (opnode (v2i32 VPR64:$src), 1164259698Sdim (v2i32 (bitconvert (v2i32 (neonopnode timm:$Imm, 1165259698Sdim neon_mov_imm_LSL_operand:$Simm)))))))], 1166259698Sdim NoItinerary> { 1167259698Sdim bits<2> Simm; 1168259698Sdim let cmode = {0b0, Simm{1}, Simm{0}, 0b1}; 1169259698Sdim } 1170259698Sdim 1171259698Sdim def _4S : NeonI_1VModImm<0b1, op, 1172259698Sdim (outs VPR128:$Rd), 1173259698Sdim (ins VPR128:$src, neon_uimm8:$Imm, 1174259698Sdim neon_mov_imm_LSL_operand:$Simm), 1175259698Sdim !strconcat(asmop, "\t$Rd.4s, $Imm$Simm"), 1176259698Sdim [(set (v4i32 VPR128:$Rd), 1177259698Sdim (v4i32 (opnode (v4i32 VPR128:$src), 1178259698Sdim (v4i32 (bitconvert (v4i32 (neonopnode timm:$Imm, 1179259698Sdim neon_mov_imm_LSL_operand:$Simm)))))))], 1180259698Sdim NoItinerary> { 1181259698Sdim bits<2> Simm; 1182259698Sdim let cmode = {0b0, Simm{1}, Simm{0}, 0b1}; 1183259698Sdim } 1184259698Sdim 1185259698Sdim // shift zeros, per halfword 1186259698Sdim def _4H : NeonI_1VModImm<0b0, op, 1187259698Sdim (outs VPR64:$Rd), 1188259698Sdim (ins VPR64:$src, neon_uimm8:$Imm, 1189259698Sdim neon_mov_imm_LSLH_operand:$Simm), 1190259698Sdim !strconcat(asmop, "\t$Rd.4h, $Imm$Simm"), 1191259698Sdim [(set (v4i16 VPR64:$Rd), 1192259698Sdim (v4i16 (opnode (v4i16 VPR64:$src), 1193259698Sdim (v4i16 (bitconvert (v4i16 (neonopnode timm:$Imm, 1194259698Sdim neon_mov_imm_LSL_operand:$Simm)))))))], 1195259698Sdim NoItinerary> { 1196259698Sdim bit Simm; 1197259698Sdim let cmode = {0b1, 0b0, Simm, 0b1}; 1198259698Sdim } 1199259698Sdim 1200259698Sdim def _8H : NeonI_1VModImm<0b1, op, 1201259698Sdim (outs VPR128:$Rd), 1202259698Sdim (ins VPR128:$src, neon_uimm8:$Imm, 1203259698Sdim neon_mov_imm_LSLH_operand:$Simm), 1204259698Sdim !strconcat(asmop, "\t$Rd.8h, $Imm$Simm"), 1205259698Sdim [(set (v8i16 VPR128:$Rd), 1206259698Sdim (v8i16 (opnode (v8i16 VPR128:$src), 1207259698Sdim (v8i16 (bitconvert (v8i16 (neonopnode timm:$Imm, 1208259698Sdim neon_mov_imm_LSL_operand:$Simm)))))))], 1209259698Sdim NoItinerary> { 1210259698Sdim bit Simm; 1211259698Sdim let cmode = {0b1, 0b0, Simm, 0b1}; 1212259698Sdim } 1213259698Sdim } 1214259698Sdim} 1215259698Sdim 1216259698Sdimmulticlass NeonI_mov_imm_msl_sizes<string asmop, bit op, 1217259698Sdim SDPatternOperator opnode> 1218259698Sdim{ 1219259698Sdim // shift ones, per word 1220259698Sdim def _2S : NeonI_1VModImm<0b0, op, 1221259698Sdim (outs VPR64:$Rd), 1222259698Sdim (ins neon_uimm8:$Imm, 1223259698Sdim neon_mov_imm_MSL_operand:$Simm), 1224259698Sdim !strconcat(asmop, "\t$Rd.2s, $Imm$Simm"), 1225259698Sdim [(set (v2i32 VPR64:$Rd), 1226259698Sdim (v2i32 (opnode (timm:$Imm), 1227259698Sdim (neon_mov_imm_MSL_operand:$Simm))))], 1228259698Sdim NoItinerary> { 1229259698Sdim bit Simm; 1230259698Sdim let cmode = {0b1, 0b1, 0b0, Simm}; 1231259698Sdim } 1232259698Sdim 1233259698Sdim def _4S : NeonI_1VModImm<0b1, op, 1234259698Sdim (outs VPR128:$Rd), 1235259698Sdim (ins neon_uimm8:$Imm, 1236259698Sdim neon_mov_imm_MSL_operand:$Simm), 1237259698Sdim !strconcat(asmop, "\t$Rd.4s, $Imm$Simm"), 1238259698Sdim [(set (v4i32 VPR128:$Rd), 1239259698Sdim (v4i32 (opnode (timm:$Imm), 1240259698Sdim (neon_mov_imm_MSL_operand:$Simm))))], 1241259698Sdim NoItinerary> { 1242259698Sdim bit Simm; 1243259698Sdim let cmode = {0b1, 0b1, 0b0, Simm}; 1244259698Sdim } 1245259698Sdim} 1246259698Sdim 1247259698Sdim// Vector Move Immediate Shifted 1248259698Sdimlet isReMaterializable = 1 in { 1249259698Sdimdefm MOVIvi_lsl : NeonI_mov_imm_lsl_sizes<"movi", 0b0, Neon_movi>; 1250259698Sdim} 1251259698Sdim 1252259698Sdim// Vector Move Inverted Immediate Shifted 1253259698Sdimlet isReMaterializable = 1 in { 1254259698Sdimdefm MVNIvi_lsl : NeonI_mov_imm_lsl_sizes<"mvni", 0b1, Neon_mvni>; 1255259698Sdim} 1256259698Sdim 1257259698Sdim// Vector Bitwise Bit Clear (AND NOT) - immediate 1258259698Sdimlet isReMaterializable = 1 in { 1259259698Sdimdefm BICvi_lsl : NeonI_mov_imm_with_constraint_lsl_sizes<"bic", 0b1, 1260259698Sdim and, Neon_mvni>; 1261259698Sdim} 1262259698Sdim 1263259698Sdim// Vector Bitwise OR - immedidate 1264259698Sdim 1265259698Sdimlet isReMaterializable = 1 in { 1266259698Sdimdefm ORRvi_lsl : NeonI_mov_imm_with_constraint_lsl_sizes<"orr", 0b0, 1267259698Sdim or, Neon_movi>; 1268259698Sdim} 1269259698Sdim 1270259698Sdim// Additional patterns for Vector Bitwise Bit Clear (AND NOT) - immedidate 1271259698Sdim// LowerBUILD_VECTOR favors lowering MOVI over MVNI. 1272259698Sdim// BIC immediate instructions selection requires additional patterns to 1273259698Sdim// transform Neon_movi operands into BIC immediate operands 1274259698Sdim 1275259698Sdimdef neon_mov_imm_LSLH_transform_XFORM : SDNodeXForm<imm, [{ 1276259698Sdim uint64_t OpCmode = N->getZExtValue(); 1277259698Sdim unsigned ShiftImm; 1278259698Sdim unsigned ShiftOnesIn; 1279259698Sdim (void)A64Imms::decodeNeonModShiftImm(OpCmode, ShiftImm, ShiftOnesIn); 1280259698Sdim // LSLH restricts shift amount to 0, 8 which are encoded as 0 and 1 1281259698Sdim // Transform encoded shift amount 0 to 1 and 1 to 0. 1282259698Sdim return CurDAG->getTargetConstant(!ShiftImm, MVT::i32); 1283259698Sdim}]>; 1284259698Sdim 1285259698Sdimdef neon_mov_imm_LSLH_transform_operand 1286259698Sdim : ImmLeaf<i32, [{ 1287259698Sdim unsigned ShiftImm; 1288259698Sdim unsigned ShiftOnesIn; 1289259698Sdim unsigned HasShift = 1290259698Sdim A64Imms::decodeNeonModShiftImm(Imm, ShiftImm, ShiftOnesIn); 1291259698Sdim return (HasShift && !ShiftOnesIn); }], 1292259698Sdim neon_mov_imm_LSLH_transform_XFORM>; 1293259698Sdim 1294259698Sdim// Transform (and A, (4h Neon_movi 0xff)) -> BIC 4h (A, 0x00, LSL 8) 1295259698Sdim// Transform (and A, (4h Neon_movi 0xff LSL #8)) -> BIC 4h (A, 0x00) 1296259698Sdimdef : Pat<(v4i16 (and VPR64:$src, 1297259698Sdim (v4i16 (Neon_movi 255, neon_mov_imm_LSLH_transform_operand:$Simm)))), 1298259698Sdim (BICvi_lsl_4H VPR64:$src, 0, 1299259698Sdim neon_mov_imm_LSLH_transform_operand:$Simm)>; 1300259698Sdim 1301259698Sdim// Transform (and A, (8h Neon_movi 8h 0xff)) -> BIC 8h (A, 0x00, LSL 8) 1302259698Sdim// Transform (and A, (8h Neon_movi 0xff LSL #8)) -> BIC 8h (A, 0x00) 1303259698Sdimdef : Pat<(v8i16 (and VPR128:$src, 1304259698Sdim (v8i16 (Neon_movi 255, neon_mov_imm_LSLH_transform_operand:$Simm)))), 1305259698Sdim (BICvi_lsl_8H VPR128:$src, 0, 1306259698Sdim neon_mov_imm_LSLH_transform_operand:$Simm)>; 1307259698Sdim 1308259698Sdim 1309259698Sdimmulticlass Neon_bitwiseVi_patterns<SDPatternOperator opnode, 1310259698Sdim SDPatternOperator neonopnode, 1311259698Sdim Instruction INST4H, 1312259698Sdim Instruction INST8H> { 1313259698Sdim def : Pat<(v8i8 (opnode VPR64:$src, 1314259698Sdim (bitconvert(v4i16 (neonopnode timm:$Imm, 1315259698Sdim neon_mov_imm_LSLH_operand:$Simm))))), 1316259698Sdim (INST4H VPR64:$src, neon_uimm8:$Imm, 1317259698Sdim neon_mov_imm_LSLH_operand:$Simm)>; 1318259698Sdim def : Pat<(v1i64 (opnode VPR64:$src, 1319259698Sdim (bitconvert(v4i16 (neonopnode timm:$Imm, 1320259698Sdim neon_mov_imm_LSLH_operand:$Simm))))), 1321259698Sdim (INST4H VPR64:$src, neon_uimm8:$Imm, 1322259698Sdim neon_mov_imm_LSLH_operand:$Simm)>; 1323259698Sdim 1324259698Sdim def : Pat<(v16i8 (opnode VPR128:$src, 1325259698Sdim (bitconvert(v8i16 (neonopnode timm:$Imm, 1326259698Sdim neon_mov_imm_LSLH_operand:$Simm))))), 1327259698Sdim (INST8H VPR128:$src, neon_uimm8:$Imm, 1328259698Sdim neon_mov_imm_LSLH_operand:$Simm)>; 1329259698Sdim def : Pat<(v4i32 (opnode VPR128:$src, 1330259698Sdim (bitconvert(v8i16 (neonopnode timm:$Imm, 1331259698Sdim neon_mov_imm_LSLH_operand:$Simm))))), 1332259698Sdim (INST8H VPR128:$src, neon_uimm8:$Imm, 1333259698Sdim neon_mov_imm_LSLH_operand:$Simm)>; 1334259698Sdim def : Pat<(v2i64 (opnode VPR128:$src, 1335259698Sdim (bitconvert(v8i16 (neonopnode timm:$Imm, 1336259698Sdim neon_mov_imm_LSLH_operand:$Simm))))), 1337259698Sdim (INST8H VPR128:$src, neon_uimm8:$Imm, 1338259698Sdim neon_mov_imm_LSLH_operand:$Simm)>; 1339259698Sdim} 1340259698Sdim 1341259698Sdim// Additional patterns for Vector Vector Bitwise Bit Clear (AND NOT) - immediate 1342259698Sdimdefm : Neon_bitwiseVi_patterns<or, Neon_mvni, BICvi_lsl_4H, BICvi_lsl_8H>; 1343259698Sdim 1344259698Sdim// Additional patterns for Vector Bitwise OR - immedidate 1345259698Sdimdefm : Neon_bitwiseVi_patterns<or, Neon_movi, ORRvi_lsl_4H, ORRvi_lsl_8H>; 1346259698Sdim 1347259698Sdim 1348259698Sdim// Vector Move Immediate Masked 1349259698Sdimlet isReMaterializable = 1 in { 1350259698Sdimdefm MOVIvi_msl : NeonI_mov_imm_msl_sizes<"movi", 0b0, Neon_movi>; 1351259698Sdim} 1352259698Sdim 1353259698Sdim// Vector Move Inverted Immediate Masked 1354259698Sdimlet isReMaterializable = 1 in { 1355259698Sdimdefm MVNIvi_msl : NeonI_mov_imm_msl_sizes<"mvni", 0b1, Neon_mvni>; 1356259698Sdim} 1357259698Sdim 1358259698Sdimclass NeonI_mov_imm_lsl_aliases<string asmop, string asmlane, 1359259698Sdim Instruction inst, RegisterOperand VPRC> 1360259698Sdim : NeonInstAlias<!strconcat(asmop, "\t$Rd," # asmlane # ", $Imm"), 1361259698Sdim (inst VPRC:$Rd, neon_uimm8:$Imm, 0), 0b0>; 1362259698Sdim 1363259698Sdim// Aliases for Vector Move Immediate Shifted 1364259698Sdimdef : NeonI_mov_imm_lsl_aliases<"movi", ".2s", MOVIvi_lsl_2S, VPR64>; 1365259698Sdimdef : NeonI_mov_imm_lsl_aliases<"movi", ".4s", MOVIvi_lsl_4S, VPR128>; 1366259698Sdimdef : NeonI_mov_imm_lsl_aliases<"movi", ".4h", MOVIvi_lsl_4H, VPR64>; 1367259698Sdimdef : NeonI_mov_imm_lsl_aliases<"movi", ".8h", MOVIvi_lsl_8H, VPR128>; 1368259698Sdim 1369259698Sdim// Aliases for Vector Move Inverted Immediate Shifted 1370259698Sdimdef : NeonI_mov_imm_lsl_aliases<"mvni", ".2s", MVNIvi_lsl_2S, VPR64>; 1371259698Sdimdef : NeonI_mov_imm_lsl_aliases<"mvni", ".4s", MVNIvi_lsl_4S, VPR128>; 1372259698Sdimdef : NeonI_mov_imm_lsl_aliases<"mvni", ".4h", MVNIvi_lsl_4H, VPR64>; 1373259698Sdimdef : NeonI_mov_imm_lsl_aliases<"mvni", ".8h", MVNIvi_lsl_8H, VPR128>; 1374259698Sdim 1375259698Sdim// Aliases for Vector Bitwise Bit Clear (AND NOT) - immediate 1376259698Sdimdef : NeonI_mov_imm_lsl_aliases<"bic", ".2s", BICvi_lsl_2S, VPR64>; 1377259698Sdimdef : NeonI_mov_imm_lsl_aliases<"bic", ".4s", BICvi_lsl_4S, VPR128>; 1378259698Sdimdef : NeonI_mov_imm_lsl_aliases<"bic", ".4h", BICvi_lsl_4H, VPR64>; 1379259698Sdimdef : NeonI_mov_imm_lsl_aliases<"bic", ".8h", BICvi_lsl_8H, VPR128>; 1380259698Sdim 1381259698Sdim// Aliases for Vector Bitwise OR - immedidate 1382259698Sdimdef : NeonI_mov_imm_lsl_aliases<"orr", ".2s", ORRvi_lsl_2S, VPR64>; 1383259698Sdimdef : NeonI_mov_imm_lsl_aliases<"orr", ".4s", ORRvi_lsl_4S, VPR128>; 1384259698Sdimdef : NeonI_mov_imm_lsl_aliases<"orr", ".4h", ORRvi_lsl_4H, VPR64>; 1385259698Sdimdef : NeonI_mov_imm_lsl_aliases<"orr", ".8h", ORRvi_lsl_8H, VPR128>; 1386259698Sdim 1387259698Sdim// Vector Move Immediate - per byte 1388259698Sdimlet isReMaterializable = 1 in { 1389259698Sdimdef MOVIvi_8B : NeonI_1VModImm<0b0, 0b0, 1390259698Sdim (outs VPR64:$Rd), (ins neon_uimm8:$Imm), 1391259698Sdim "movi\t$Rd.8b, $Imm", 1392259698Sdim [(set (v8i8 VPR64:$Rd), 1393259698Sdim (v8i8 (Neon_movi (timm:$Imm), (i32 imm))))], 1394259698Sdim NoItinerary> { 1395259698Sdim let cmode = 0b1110; 1396259698Sdim} 1397259698Sdim 1398259698Sdimdef MOVIvi_16B : NeonI_1VModImm<0b1, 0b0, 1399259698Sdim (outs VPR128:$Rd), (ins neon_uimm8:$Imm), 1400259698Sdim "movi\t$Rd.16b, $Imm", 1401259698Sdim [(set (v16i8 VPR128:$Rd), 1402259698Sdim (v16i8 (Neon_movi (timm:$Imm), (i32 imm))))], 1403259698Sdim NoItinerary> { 1404259698Sdim let cmode = 0b1110; 1405259698Sdim} 1406259698Sdim} 1407259698Sdim 1408259698Sdim// Vector Move Immediate - bytemask, per double word 1409259698Sdimlet isReMaterializable = 1 in { 1410259698Sdimdef MOVIvi_2D : NeonI_1VModImm<0b1, 0b1, 1411259698Sdim (outs VPR128:$Rd), (ins neon_uimm64_mask:$Imm), 1412259698Sdim "movi\t $Rd.2d, $Imm", 1413259698Sdim [(set (v2i64 VPR128:$Rd), 1414259698Sdim (v2i64 (Neon_movi (timm:$Imm), (i32 imm))))], 1415259698Sdim NoItinerary> { 1416259698Sdim let cmode = 0b1110; 1417259698Sdim} 1418259698Sdim} 1419259698Sdim 1420259698Sdim// Vector Move Immediate - bytemask, one doubleword 1421259698Sdim 1422259698Sdimlet isReMaterializable = 1 in { 1423259698Sdimdef MOVIdi : NeonI_1VModImm<0b0, 0b1, 1424259698Sdim (outs FPR64:$Rd), (ins neon_uimm64_mask:$Imm), 1425259698Sdim "movi\t $Rd, $Imm", 1426259698Sdim [(set (v1i64 FPR64:$Rd), 1427259698Sdim (v1i64 (Neon_movi (timm:$Imm), (i32 imm))))], 1428259698Sdim NoItinerary> { 1429259698Sdim let cmode = 0b1110; 1430259698Sdim} 1431259698Sdim} 1432259698Sdim 1433259698Sdim// Vector Floating Point Move Immediate 1434259698Sdim 1435259698Sdimclass NeonI_FMOV_impl<string asmlane, RegisterOperand VPRC, ValueType OpTy, 1436259698Sdim Operand immOpType, bit q, bit op> 1437259698Sdim : NeonI_1VModImm<q, op, 1438259698Sdim (outs VPRC:$Rd), (ins immOpType:$Imm), 1439259698Sdim "fmov\t$Rd" # asmlane # ", $Imm", 1440259698Sdim [(set (OpTy VPRC:$Rd), 1441259698Sdim (OpTy (Neon_fmovi (timm:$Imm))))], 1442259698Sdim NoItinerary> { 1443259698Sdim let cmode = 0b1111; 1444259698Sdim } 1445259698Sdim 1446259698Sdimlet isReMaterializable = 1 in { 1447259698Sdimdef FMOVvi_2S : NeonI_FMOV_impl<".2s", VPR64, v2f32, fmov32_operand, 0b0, 0b0>; 1448259698Sdimdef FMOVvi_4S : NeonI_FMOV_impl<".4s", VPR128, v4f32, fmov32_operand, 0b1, 0b0>; 1449259698Sdimdef FMOVvi_2D : NeonI_FMOV_impl<".2d", VPR128, v2f64, fmov64_operand, 0b1, 0b1>; 1450259698Sdim} 1451259698Sdim 1452259698Sdim// Vector Shift (Immediate) 1453259698Sdim// Immediate in [0, 63] 1454259698Sdimdef imm0_63 : Operand<i32> { 1455259698Sdim let ParserMatchClass = uimm6_asmoperand; 1456259698Sdim} 1457259698Sdim 1458259698Sdim// Shift Right/Left Immediate - The immh:immb field of these shifts are encoded 1459259698Sdim// as follows: 1460259698Sdim// 1461259698Sdim// Offset Encoding 1462259698Sdim// 8 immh:immb<6:3> = '0001xxx', <imm> is encoded in immh:immb<2:0> 1463259698Sdim// 16 immh:immb<6:4> = '001xxxx', <imm> is encoded in immh:immb<3:0> 1464259698Sdim// 32 immh:immb<6:5> = '01xxxxx', <imm> is encoded in immh:immb<4:0> 1465259698Sdim// 64 immh:immb<6> = '1xxxxxx', <imm> is encoded in immh:immb<5:0> 1466259698Sdim// 1467259698Sdim// The shift right immediate amount, in the range 1 to element bits, is computed 1468259698Sdim// as Offset - UInt(immh:immb). The shift left immediate amount, in the range 0 1469259698Sdim// to element bits - 1, is computed as UInt(immh:immb) - Offset. 1470259698Sdim 1471259698Sdimclass shr_imm_asmoperands<string OFFSET> : AsmOperandClass { 1472259698Sdim let Name = "ShrImm" # OFFSET; 1473259698Sdim let RenderMethod = "addImmOperands"; 1474259698Sdim let DiagnosticType = "ShrImm" # OFFSET; 1475259698Sdim} 1476259698Sdim 1477259698Sdimclass shr_imm<string OFFSET> : Operand<i32> { 1478259698Sdim let EncoderMethod = "getShiftRightImm" # OFFSET; 1479259698Sdim let DecoderMethod = "DecodeShiftRightImm" # OFFSET; 1480259698Sdim let ParserMatchClass = 1481259698Sdim !cast<AsmOperandClass>("shr_imm" # OFFSET # "_asmoperand"); 1482259698Sdim} 1483259698Sdim 1484259698Sdimdef shr_imm8_asmoperand : shr_imm_asmoperands<"8">; 1485259698Sdimdef shr_imm16_asmoperand : shr_imm_asmoperands<"16">; 1486259698Sdimdef shr_imm32_asmoperand : shr_imm_asmoperands<"32">; 1487259698Sdimdef shr_imm64_asmoperand : shr_imm_asmoperands<"64">; 1488259698Sdim 1489259698Sdimdef shr_imm8 : shr_imm<"8">, ImmLeaf<i32, [{return Imm > 0 && Imm <= 8;}]>; 1490259698Sdimdef shr_imm16 : shr_imm<"16">, ImmLeaf<i32, [{return Imm > 0 && Imm <= 16;}]>; 1491259698Sdimdef shr_imm32 : shr_imm<"32">, ImmLeaf<i32, [{return Imm > 0 && Imm <= 32;}]>; 1492259698Sdimdef shr_imm64 : shr_imm<"64">, ImmLeaf<i32, [{return Imm > 0 && Imm <= 64;}]>; 1493259698Sdim 1494259698Sdimclass shl_imm_asmoperands<string OFFSET> : AsmOperandClass { 1495259698Sdim let Name = "ShlImm" # OFFSET; 1496259698Sdim let RenderMethod = "addImmOperands"; 1497259698Sdim let DiagnosticType = "ShlImm" # OFFSET; 1498259698Sdim} 1499259698Sdim 1500259698Sdimclass shl_imm<string OFFSET> : Operand<i32> { 1501259698Sdim let EncoderMethod = "getShiftLeftImm" # OFFSET; 1502259698Sdim let DecoderMethod = "DecodeShiftLeftImm" # OFFSET; 1503259698Sdim let ParserMatchClass = 1504259698Sdim !cast<AsmOperandClass>("shl_imm" # OFFSET # "_asmoperand"); 1505259698Sdim} 1506259698Sdim 1507259698Sdimdef shl_imm8_asmoperand : shl_imm_asmoperands<"8">; 1508259698Sdimdef shl_imm16_asmoperand : shl_imm_asmoperands<"16">; 1509259698Sdimdef shl_imm32_asmoperand : shl_imm_asmoperands<"32">; 1510259698Sdimdef shl_imm64_asmoperand : shl_imm_asmoperands<"64">; 1511259698Sdim 1512259698Sdimdef shl_imm8 : shl_imm<"8">, ImmLeaf<i32, [{return Imm >= 0 && Imm < 8;}]>; 1513259698Sdimdef shl_imm16 : shl_imm<"16">, ImmLeaf<i32, [{return Imm >= 0 && Imm < 16;}]>; 1514259698Sdimdef shl_imm32 : shl_imm<"32">, ImmLeaf<i32, [{return Imm >= 0 && Imm < 32;}]>; 1515259698Sdimdef shl_imm64 : shl_imm<"64">, ImmLeaf<i32, [{return Imm >= 0 && Imm < 64;}]>; 1516259698Sdim 1517259698Sdimclass N2VShift<bit q, bit u, bits<5> opcode, string asmop, string T, 1518259698Sdim RegisterOperand VPRC, ValueType Ty, Operand ImmTy, SDNode OpNode> 1519259698Sdim : NeonI_2VShiftImm<q, u, opcode, 1520259698Sdim (outs VPRC:$Rd), (ins VPRC:$Rn, ImmTy:$Imm), 1521259698Sdim asmop # "\t$Rd." # T # ", $Rn." # T # ", $Imm", 1522259698Sdim [(set (Ty VPRC:$Rd), 1523259698Sdim (Ty (OpNode (Ty VPRC:$Rn), 1524259698Sdim (Ty (Neon_vdup (i32 ImmTy:$Imm))))))], 1525259698Sdim NoItinerary>; 1526259698Sdim 1527259698Sdimmulticlass NeonI_N2VShL<bit u, bits<5> opcode, string asmop> { 1528259698Sdim // 64-bit vector types. 1529259698Sdim def _8B : N2VShift<0b0, u, opcode, asmop, "8b", VPR64, v8i8, shl_imm8, shl> { 1530259698Sdim let Inst{22-19} = 0b0001; // immh:immb = 0001xxx 1531259698Sdim } 1532259698Sdim 1533259698Sdim def _4H : N2VShift<0b0, u, opcode, asmop, "4h", VPR64, v4i16, shl_imm16, shl> { 1534259698Sdim let Inst{22-20} = 0b001; // immh:immb = 001xxxx 1535259698Sdim } 1536259698Sdim 1537259698Sdim def _2S : N2VShift<0b0, u, opcode, asmop, "2s", VPR64, v2i32, shl_imm32, shl> { 1538259698Sdim let Inst{22-21} = 0b01; // immh:immb = 01xxxxx 1539259698Sdim } 1540259698Sdim 1541259698Sdim // 128-bit vector types. 1542259698Sdim def _16B : N2VShift<0b1, u, opcode, asmop, "16b", VPR128, v16i8, shl_imm8, shl> { 1543259698Sdim let Inst{22-19} = 0b0001; // immh:immb = 0001xxx 1544259698Sdim } 1545259698Sdim 1546259698Sdim def _8H : N2VShift<0b1, u, opcode, asmop, "8h", VPR128, v8i16, shl_imm16, shl> { 1547259698Sdim let Inst{22-20} = 0b001; // immh:immb = 001xxxx 1548259698Sdim } 1549259698Sdim 1550259698Sdim def _4S : N2VShift<0b1, u, opcode, asmop, "4s", VPR128, v4i32, shl_imm32, shl> { 1551259698Sdim let Inst{22-21} = 0b01; // immh:immb = 01xxxxx 1552259698Sdim } 1553259698Sdim 1554259698Sdim def _2D : N2VShift<0b1, u, opcode, asmop, "2d", VPR128, v2i64, shl_imm64, shl> { 1555259698Sdim let Inst{22} = 0b1; // immh:immb = 1xxxxxx 1556259698Sdim } 1557259698Sdim} 1558259698Sdim 1559259698Sdimmulticlass NeonI_N2VShR<bit u, bits<5> opcode, string asmop, SDNode OpNode> { 1560259698Sdim def _8B : N2VShift<0b0, u, opcode, asmop, "8b", VPR64, v8i8, shr_imm8, 1561259698Sdim OpNode> { 1562259698Sdim let Inst{22-19} = 0b0001; 1563259698Sdim } 1564259698Sdim 1565259698Sdim def _4H : N2VShift<0b0, u, opcode, asmop, "4h", VPR64, v4i16, shr_imm16, 1566259698Sdim OpNode> { 1567259698Sdim let Inst{22-20} = 0b001; 1568259698Sdim } 1569259698Sdim 1570259698Sdim def _2S : N2VShift<0b0, u, opcode, asmop, "2s", VPR64, v2i32, shr_imm32, 1571259698Sdim OpNode> { 1572259698Sdim let Inst{22-21} = 0b01; 1573259698Sdim } 1574259698Sdim 1575259698Sdim def _16B : N2VShift<0b1, u, opcode, asmop, "16b", VPR128, v16i8, shr_imm8, 1576259698Sdim OpNode> { 1577259698Sdim let Inst{22-19} = 0b0001; 1578259698Sdim } 1579259698Sdim 1580259698Sdim def _8H : N2VShift<0b1, u, opcode, asmop, "8h", VPR128, v8i16, shr_imm16, 1581259698Sdim OpNode> { 1582259698Sdim let Inst{22-20} = 0b001; 1583259698Sdim } 1584259698Sdim 1585259698Sdim def _4S : N2VShift<0b1, u, opcode, asmop, "4s", VPR128, v4i32, shr_imm32, 1586259698Sdim OpNode> { 1587259698Sdim let Inst{22-21} = 0b01; 1588259698Sdim } 1589259698Sdim 1590259698Sdim def _2D : N2VShift<0b1, u, opcode, asmop, "2d", VPR128, v2i64, shr_imm64, 1591259698Sdim OpNode> { 1592259698Sdim let Inst{22} = 0b1; 1593259698Sdim } 1594259698Sdim} 1595259698Sdim 1596259698Sdim// Shift left 1597259698Sdimdefm SHLvvi : NeonI_N2VShL<0b0, 0b01010, "shl">; 1598259698Sdim 1599259698Sdim// Shift right 1600259698Sdimdefm SSHRvvi : NeonI_N2VShR<0b0, 0b00000, "sshr", sra>; 1601259698Sdimdefm USHRvvi : NeonI_N2VShR<0b1, 0b00000, "ushr", srl>; 1602259698Sdim 1603259698Sdimdef Neon_High16B : PatFrag<(ops node:$in), 1604259698Sdim (extract_subvector (v16i8 node:$in), (iPTR 8))>; 1605259698Sdimdef Neon_High8H : PatFrag<(ops node:$in), 1606259698Sdim (extract_subvector (v8i16 node:$in), (iPTR 4))>; 1607259698Sdimdef Neon_High4S : PatFrag<(ops node:$in), 1608259698Sdim (extract_subvector (v4i32 node:$in), (iPTR 2))>; 1609259698Sdimdef Neon_High2D : PatFrag<(ops node:$in), 1610259698Sdim (extract_subvector (v2i64 node:$in), (iPTR 1))>; 1611259698Sdimdef Neon_High4float : PatFrag<(ops node:$in), 1612259698Sdim (extract_subvector (v4f32 node:$in), (iPTR 2))>; 1613259698Sdimdef Neon_High2double : PatFrag<(ops node:$in), 1614259698Sdim (extract_subvector (v2f64 node:$in), (iPTR 1))>; 1615259698Sdim 1616259698Sdimdef Neon_Low16B : PatFrag<(ops node:$in), 1617259698Sdim (v8i8 (extract_subvector (v16i8 node:$in), 1618259698Sdim (iPTR 0)))>; 1619259698Sdimdef Neon_Low8H : PatFrag<(ops node:$in), 1620259698Sdim (v4i16 (extract_subvector (v8i16 node:$in), 1621259698Sdim (iPTR 0)))>; 1622259698Sdimdef Neon_Low4S : PatFrag<(ops node:$in), 1623259698Sdim (v2i32 (extract_subvector (v4i32 node:$in), 1624259698Sdim (iPTR 0)))>; 1625259698Sdimdef Neon_Low2D : PatFrag<(ops node:$in), 1626259698Sdim (v1i64 (extract_subvector (v2i64 node:$in), 1627259698Sdim (iPTR 0)))>; 1628259698Sdimdef Neon_Low4float : PatFrag<(ops node:$in), 1629259698Sdim (v2f32 (extract_subvector (v4f32 node:$in), 1630259698Sdim (iPTR 0)))>; 1631259698Sdimdef Neon_Low2double : PatFrag<(ops node:$in), 1632259698Sdim (v1f64 (extract_subvector (v2f64 node:$in), 1633259698Sdim (iPTR 0)))>; 1634259698Sdim 1635259698Sdimclass N2VShiftLong<bit q, bit u, bits<5> opcode, string asmop, string DestT, 1636259698Sdim string SrcT, ValueType DestTy, ValueType SrcTy, 1637259698Sdim Operand ImmTy, SDPatternOperator ExtOp> 1638259698Sdim : NeonI_2VShiftImm<q, u, opcode, (outs VPR128:$Rd), 1639259698Sdim (ins VPR64:$Rn, ImmTy:$Imm), 1640259698Sdim asmop # "\t$Rd." # DestT # ", $Rn." # SrcT # ", $Imm", 1641259698Sdim [(set (DestTy VPR128:$Rd), 1642259698Sdim (DestTy (shl 1643259698Sdim (DestTy (ExtOp (SrcTy VPR64:$Rn))), 1644259698Sdim (DestTy (Neon_vdup (i32 ImmTy:$Imm))))))], 1645259698Sdim NoItinerary>; 1646259698Sdim 1647259698Sdimclass N2VShiftLongHigh<bit q, bit u, bits<5> opcode, string asmop, string DestT, 1648259698Sdim string SrcT, ValueType DestTy, ValueType SrcTy, 1649259698Sdim int StartIndex, Operand ImmTy, 1650259698Sdim SDPatternOperator ExtOp, PatFrag getTop> 1651259698Sdim : NeonI_2VShiftImm<q, u, opcode, (outs VPR128:$Rd), 1652259698Sdim (ins VPR128:$Rn, ImmTy:$Imm), 1653259698Sdim asmop # "2\t$Rd." # DestT # ", $Rn." # SrcT # ", $Imm", 1654259698Sdim [(set (DestTy VPR128:$Rd), 1655259698Sdim (DestTy (shl 1656259698Sdim (DestTy (ExtOp 1657259698Sdim (SrcTy (getTop VPR128:$Rn)))), 1658259698Sdim (DestTy (Neon_vdup (i32 ImmTy:$Imm))))))], 1659259698Sdim NoItinerary>; 1660259698Sdim 1661259698Sdimmulticlass NeonI_N2VShLL<string prefix, bit u, bits<5> opcode, string asmop, 1662259698Sdim SDNode ExtOp> { 1663259698Sdim // 64-bit vector types. 1664259698Sdim def _8B : N2VShiftLong<0b0, u, opcode, asmop, "8h", "8b", v8i16, v8i8, 1665259698Sdim shl_imm8, ExtOp> { 1666259698Sdim let Inst{22-19} = 0b0001; // immh:immb = 0001xxx 1667259698Sdim } 1668259698Sdim 1669259698Sdim def _4H : N2VShiftLong<0b0, u, opcode, asmop, "4s", "4h", v4i32, v4i16, 1670259698Sdim shl_imm16, ExtOp> { 1671259698Sdim let Inst{22-20} = 0b001; // immh:immb = 001xxxx 1672259698Sdim } 1673259698Sdim 1674259698Sdim def _2S : N2VShiftLong<0b0, u, opcode, asmop, "2d", "2s", v2i64, v2i32, 1675259698Sdim shl_imm32, ExtOp> { 1676259698Sdim let Inst{22-21} = 0b01; // immh:immb = 01xxxxx 1677259698Sdim } 1678259698Sdim 1679259698Sdim // 128-bit vector types 1680259698Sdim def _16B : N2VShiftLongHigh<0b1, u, opcode, asmop, "8h", "16b", v8i16, v8i8, 1681259698Sdim 8, shl_imm8, ExtOp, Neon_High16B> { 1682259698Sdim let Inst{22-19} = 0b0001; // immh:immb = 0001xxx 1683259698Sdim } 1684259698Sdim 1685259698Sdim def _8H : N2VShiftLongHigh<0b1, u, opcode, asmop, "4s", "8h", v4i32, v4i16, 1686259698Sdim 4, shl_imm16, ExtOp, Neon_High8H> { 1687259698Sdim let Inst{22-20} = 0b001; // immh:immb = 001xxxx 1688259698Sdim } 1689259698Sdim 1690259698Sdim def _4S : N2VShiftLongHigh<0b1, u, opcode, asmop, "2d", "4s", v2i64, v2i32, 1691259698Sdim 2, shl_imm32, ExtOp, Neon_High4S> { 1692259698Sdim let Inst{22-21} = 0b01; // immh:immb = 01xxxxx 1693259698Sdim } 1694259698Sdim 1695259698Sdim // Use other patterns to match when the immediate is 0. 1696259698Sdim def : Pat<(v8i16 (ExtOp (v8i8 VPR64:$Rn))), 1697259698Sdim (!cast<Instruction>(prefix # "_8B") VPR64:$Rn, 0)>; 1698259698Sdim 1699259698Sdim def : Pat<(v4i32 (ExtOp (v4i16 VPR64:$Rn))), 1700259698Sdim (!cast<Instruction>(prefix # "_4H") VPR64:$Rn, 0)>; 1701259698Sdim 1702259698Sdim def : Pat<(v2i64 (ExtOp (v2i32 VPR64:$Rn))), 1703259698Sdim (!cast<Instruction>(prefix # "_2S") VPR64:$Rn, 0)>; 1704259698Sdim 1705259698Sdim def : Pat<(v8i16 (ExtOp (v8i8 (Neon_High16B VPR128:$Rn)))), 1706259698Sdim (!cast<Instruction>(prefix # "_16B") VPR128:$Rn, 0)>; 1707259698Sdim 1708259698Sdim def : Pat<(v4i32 (ExtOp (v4i16 (Neon_High8H VPR128:$Rn)))), 1709259698Sdim (!cast<Instruction>(prefix # "_8H") VPR128:$Rn, 0)>; 1710259698Sdim 1711259698Sdim def : Pat<(v2i64 (ExtOp (v2i32 (Neon_High4S VPR128:$Rn)))), 1712259698Sdim (!cast<Instruction>(prefix # "_4S") VPR128:$Rn, 0)>; 1713259698Sdim} 1714259698Sdim 1715259698Sdim// Shift left long 1716259698Sdimdefm SSHLLvvi : NeonI_N2VShLL<"SSHLLvvi", 0b0, 0b10100, "sshll", sext>; 1717259698Sdimdefm USHLLvvi : NeonI_N2VShLL<"USHLLvvi", 0b1, 0b10100, "ushll", zext>; 1718259698Sdim 1719259698Sdim// Rounding/Saturating shift 1720259698Sdimclass N2VShift_RQ<bit q, bit u, bits<5> opcode, string asmop, string T, 1721259698Sdim RegisterOperand VPRC, ValueType Ty, Operand ImmTy, 1722259698Sdim SDPatternOperator OpNode> 1723259698Sdim : NeonI_2VShiftImm<q, u, opcode, 1724259698Sdim (outs VPRC:$Rd), (ins VPRC:$Rn, ImmTy:$Imm), 1725259698Sdim asmop # "\t$Rd." # T # ", $Rn." # T # ", $Imm", 1726259698Sdim [(set (Ty VPRC:$Rd), (Ty (OpNode (Ty VPRC:$Rn), 1727259698Sdim (i32 ImmTy:$Imm))))], 1728259698Sdim NoItinerary>; 1729259698Sdim 1730259698Sdim// shift right (vector by immediate) 1731259698Sdimmulticlass NeonI_N2VShR_RQ<bit u, bits<5> opcode, string asmop, 1732259698Sdim SDPatternOperator OpNode> { 1733259698Sdim def _8B : N2VShift_RQ<0b0, u, opcode, asmop, "8b", VPR64, v8i8, shr_imm8, 1734259698Sdim OpNode> { 1735259698Sdim let Inst{22-19} = 0b0001; 1736259698Sdim } 1737259698Sdim 1738259698Sdim def _4H : N2VShift_RQ<0b0, u, opcode, asmop, "4h", VPR64, v4i16, shr_imm16, 1739259698Sdim OpNode> { 1740259698Sdim let Inst{22-20} = 0b001; 1741259698Sdim } 1742259698Sdim 1743259698Sdim def _2S : N2VShift_RQ<0b0, u, opcode, asmop, "2s", VPR64, v2i32, shr_imm32, 1744259698Sdim OpNode> { 1745259698Sdim let Inst{22-21} = 0b01; 1746259698Sdim } 1747259698Sdim 1748259698Sdim def _16B : N2VShift_RQ<0b1, u, opcode, asmop, "16b", VPR128, v16i8, shr_imm8, 1749259698Sdim OpNode> { 1750259698Sdim let Inst{22-19} = 0b0001; 1751259698Sdim } 1752259698Sdim 1753259698Sdim def _8H : N2VShift_RQ<0b1, u, opcode, asmop, "8h", VPR128, v8i16, shr_imm16, 1754259698Sdim OpNode> { 1755259698Sdim let Inst{22-20} = 0b001; 1756259698Sdim } 1757259698Sdim 1758259698Sdim def _4S : N2VShift_RQ<0b1, u, opcode, asmop, "4s", VPR128, v4i32, shr_imm32, 1759259698Sdim OpNode> { 1760259698Sdim let Inst{22-21} = 0b01; 1761259698Sdim } 1762259698Sdim 1763259698Sdim def _2D : N2VShift_RQ<0b1, u, opcode, asmop, "2d", VPR128, v2i64, shr_imm64, 1764259698Sdim OpNode> { 1765259698Sdim let Inst{22} = 0b1; 1766259698Sdim } 1767259698Sdim} 1768259698Sdim 1769259698Sdimmulticlass NeonI_N2VShL_Q<bit u, bits<5> opcode, string asmop, 1770259698Sdim SDPatternOperator OpNode> { 1771259698Sdim // 64-bit vector types. 1772259698Sdim def _8B : N2VShift_RQ<0b0, u, opcode, asmop, "8b", VPR64, v8i8, shl_imm8, 1773259698Sdim OpNode> { 1774259698Sdim let Inst{22-19} = 0b0001; 1775259698Sdim } 1776259698Sdim 1777259698Sdim def _4H : N2VShift_RQ<0b0, u, opcode, asmop, "4h", VPR64, v4i16, shl_imm16, 1778259698Sdim OpNode> { 1779259698Sdim let Inst{22-20} = 0b001; 1780259698Sdim } 1781259698Sdim 1782259698Sdim def _2S : N2VShift_RQ<0b0, u, opcode, asmop, "2s", VPR64, v2i32, shl_imm32, 1783259698Sdim OpNode> { 1784259698Sdim let Inst{22-21} = 0b01; 1785259698Sdim } 1786259698Sdim 1787259698Sdim // 128-bit vector types. 1788259698Sdim def _16B : N2VShift_RQ<0b1, u, opcode, asmop, "16b", VPR128, v16i8, shl_imm8, 1789259698Sdim OpNode> { 1790259698Sdim let Inst{22-19} = 0b0001; 1791259698Sdim } 1792259698Sdim 1793259698Sdim def _8H : N2VShift_RQ<0b1, u, opcode, asmop, "8h", VPR128, v8i16, shl_imm16, 1794259698Sdim OpNode> { 1795259698Sdim let Inst{22-20} = 0b001; 1796259698Sdim } 1797259698Sdim 1798259698Sdim def _4S : N2VShift_RQ<0b1, u, opcode, asmop, "4s", VPR128, v4i32, shl_imm32, 1799259698Sdim OpNode> { 1800259698Sdim let Inst{22-21} = 0b01; 1801259698Sdim } 1802259698Sdim 1803259698Sdim def _2D : N2VShift_RQ<0b1, u, opcode, asmop, "2d", VPR128, v2i64, shl_imm64, 1804259698Sdim OpNode> { 1805259698Sdim let Inst{22} = 0b1; 1806259698Sdim } 1807259698Sdim} 1808259698Sdim 1809259698Sdim// Rounding shift right 1810259698Sdimdefm SRSHRvvi : NeonI_N2VShR_RQ<0b0, 0b00100, "srshr", 1811259698Sdim int_aarch64_neon_vsrshr>; 1812259698Sdimdefm URSHRvvi : NeonI_N2VShR_RQ<0b1, 0b00100, "urshr", 1813259698Sdim int_aarch64_neon_vurshr>; 1814259698Sdim 1815259698Sdim// Saturating shift left unsigned 1816259698Sdimdefm SQSHLUvvi : NeonI_N2VShL_Q<0b1, 0b01100, "sqshlu", int_aarch64_neon_vsqshlu>; 1817259698Sdim 1818259698Sdim// Saturating shift left 1819259698Sdimdefm SQSHLvvi : NeonI_N2VShL_Q<0b0, 0b01110, "sqshl", Neon_sqrshlImm>; 1820259698Sdimdefm UQSHLvvi : NeonI_N2VShL_Q<0b1, 0b01110, "uqshl", Neon_uqrshlImm>; 1821259698Sdim 1822259698Sdimclass N2VShiftAdd<bit q, bit u, bits<5> opcode, string asmop, string T, 1823259698Sdim RegisterOperand VPRC, ValueType Ty, Operand ImmTy, 1824259698Sdim SDNode OpNode> 1825259698Sdim : NeonI_2VShiftImm<q, u, opcode, 1826259698Sdim (outs VPRC:$Rd), (ins VPRC:$src, VPRC:$Rn, ImmTy:$Imm), 1827259698Sdim asmop # "\t$Rd." # T # ", $Rn." # T # ", $Imm", 1828259698Sdim [(set (Ty VPRC:$Rd), (Ty (add (Ty VPRC:$src), 1829259698Sdim (Ty (OpNode (Ty VPRC:$Rn), 1830259698Sdim (Ty (Neon_vdup (i32 ImmTy:$Imm))))))))], 1831259698Sdim NoItinerary> { 1832259698Sdim let Constraints = "$src = $Rd"; 1833259698Sdim} 1834259698Sdim 1835259698Sdim// Shift Right accumulate 1836259698Sdimmulticlass NeonI_N2VShRAdd<bit u, bits<5> opcode, string asmop, SDNode OpNode> { 1837259698Sdim def _8B : N2VShiftAdd<0b0, u, opcode, asmop, "8b", VPR64, v8i8, shr_imm8, 1838259698Sdim OpNode> { 1839259698Sdim let Inst{22-19} = 0b0001; 1840259698Sdim } 1841259698Sdim 1842259698Sdim def _4H : N2VShiftAdd<0b0, u, opcode, asmop, "4h", VPR64, v4i16, shr_imm16, 1843259698Sdim OpNode> { 1844259698Sdim let Inst{22-20} = 0b001; 1845259698Sdim } 1846259698Sdim 1847259698Sdim def _2S : N2VShiftAdd<0b0, u, opcode, asmop, "2s", VPR64, v2i32, shr_imm32, 1848259698Sdim OpNode> { 1849259698Sdim let Inst{22-21} = 0b01; 1850259698Sdim } 1851259698Sdim 1852259698Sdim def _16B : N2VShiftAdd<0b1, u, opcode, asmop, "16b", VPR128, v16i8, shr_imm8, 1853259698Sdim OpNode> { 1854259698Sdim let Inst{22-19} = 0b0001; 1855259698Sdim } 1856259698Sdim 1857259698Sdim def _8H : N2VShiftAdd<0b1, u, opcode, asmop, "8h", VPR128, v8i16, shr_imm16, 1858259698Sdim OpNode> { 1859259698Sdim let Inst{22-20} = 0b001; 1860259698Sdim } 1861259698Sdim 1862259698Sdim def _4S : N2VShiftAdd<0b1, u, opcode, asmop, "4s", VPR128, v4i32, shr_imm32, 1863259698Sdim OpNode> { 1864259698Sdim let Inst{22-21} = 0b01; 1865259698Sdim } 1866259698Sdim 1867259698Sdim def _2D : N2VShiftAdd<0b1, u, opcode, asmop, "2d", VPR128, v2i64, shr_imm64, 1868259698Sdim OpNode> { 1869259698Sdim let Inst{22} = 0b1; 1870259698Sdim } 1871259698Sdim} 1872259698Sdim 1873259698Sdim// Shift right and accumulate 1874259698Sdimdefm SSRAvvi : NeonI_N2VShRAdd<0, 0b00010, "ssra", sra>; 1875259698Sdimdefm USRAvvi : NeonI_N2VShRAdd<1, 0b00010, "usra", srl>; 1876259698Sdim 1877259698Sdim// Rounding shift accumulate 1878259698Sdimclass N2VShiftAdd_R<bit q, bit u, bits<5> opcode, string asmop, string T, 1879259698Sdim RegisterOperand VPRC, ValueType Ty, Operand ImmTy, 1880259698Sdim SDPatternOperator OpNode> 1881259698Sdim : NeonI_2VShiftImm<q, u, opcode, 1882259698Sdim (outs VPRC:$Rd), (ins VPRC:$src, VPRC:$Rn, ImmTy:$Imm), 1883259698Sdim asmop # "\t$Rd." # T # ", $Rn." # T # ", $Imm", 1884259698Sdim [(set (Ty VPRC:$Rd), (Ty (add (Ty VPRC:$src), 1885259698Sdim (Ty (OpNode (Ty VPRC:$Rn), (i32 ImmTy:$Imm))))))], 1886259698Sdim NoItinerary> { 1887259698Sdim let Constraints = "$src = $Rd"; 1888259698Sdim} 1889259698Sdim 1890259698Sdimmulticlass NeonI_N2VShRAdd_R<bit u, bits<5> opcode, string asmop, 1891259698Sdim SDPatternOperator OpNode> { 1892259698Sdim def _8B : N2VShiftAdd_R<0b0, u, opcode, asmop, "8b", VPR64, v8i8, shr_imm8, 1893259698Sdim OpNode> { 1894259698Sdim let Inst{22-19} = 0b0001; 1895259698Sdim } 1896259698Sdim 1897259698Sdim def _4H : N2VShiftAdd_R<0b0, u, opcode, asmop, "4h", VPR64, v4i16, shr_imm16, 1898259698Sdim OpNode> { 1899259698Sdim let Inst{22-20} = 0b001; 1900259698Sdim } 1901259698Sdim 1902259698Sdim def _2S : N2VShiftAdd_R<0b0, u, opcode, asmop, "2s", VPR64, v2i32, shr_imm32, 1903259698Sdim OpNode> { 1904259698Sdim let Inst{22-21} = 0b01; 1905259698Sdim } 1906259698Sdim 1907259698Sdim def _16B : N2VShiftAdd_R<0b1, u, opcode, asmop, "16b", VPR128, v16i8, shr_imm8, 1908259698Sdim OpNode> { 1909259698Sdim let Inst{22-19} = 0b0001; 1910259698Sdim } 1911259698Sdim 1912259698Sdim def _8H : N2VShiftAdd_R<0b1, u, opcode, asmop, "8h", VPR128, v8i16, shr_imm16, 1913259698Sdim OpNode> { 1914259698Sdim let Inst{22-20} = 0b001; 1915259698Sdim } 1916259698Sdim 1917259698Sdim def _4S : N2VShiftAdd_R<0b1, u, opcode, asmop, "4s", VPR128, v4i32, shr_imm32, 1918259698Sdim OpNode> { 1919259698Sdim let Inst{22-21} = 0b01; 1920259698Sdim } 1921259698Sdim 1922259698Sdim def _2D : N2VShiftAdd_R<0b1, u, opcode, asmop, "2d", VPR128, v2i64, shr_imm64, 1923259698Sdim OpNode> { 1924259698Sdim let Inst{22} = 0b1; 1925259698Sdim } 1926259698Sdim} 1927259698Sdim 1928259698Sdim// Rounding shift right and accumulate 1929259698Sdimdefm SRSRAvvi : NeonI_N2VShRAdd_R<0, 0b00110, "srsra", int_aarch64_neon_vsrshr>; 1930259698Sdimdefm URSRAvvi : NeonI_N2VShRAdd_R<1, 0b00110, "ursra", int_aarch64_neon_vurshr>; 1931259698Sdim 1932259698Sdim// Shift insert by immediate 1933259698Sdimclass N2VShiftIns<bit q, bit u, bits<5> opcode, string asmop, string T, 1934259698Sdim RegisterOperand VPRC, ValueType Ty, Operand ImmTy, 1935259698Sdim SDPatternOperator OpNode> 1936259698Sdim : NeonI_2VShiftImm<q, u, opcode, 1937259698Sdim (outs VPRC:$Rd), (ins VPRC:$src, VPRC:$Rn, ImmTy:$Imm), 1938259698Sdim asmop # "\t$Rd." # T # ", $Rn." # T # ", $Imm", 1939259698Sdim [(set (Ty VPRC:$Rd), (Ty (OpNode (Ty VPRC:$src), (Ty VPRC:$Rn), 1940259698Sdim (i32 ImmTy:$Imm))))], 1941259698Sdim NoItinerary> { 1942259698Sdim let Constraints = "$src = $Rd"; 1943259698Sdim} 1944259698Sdim 1945259698Sdim// shift left insert (vector by immediate) 1946259698Sdimmulticlass NeonI_N2VShLIns<bit u, bits<5> opcode, string asmop> { 1947259698Sdim def _8B : N2VShiftIns<0b0, u, opcode, asmop, "8b", VPR64, v8i8, shl_imm8, 1948259698Sdim int_aarch64_neon_vsli> { 1949259698Sdim let Inst{22-19} = 0b0001; 1950259698Sdim } 1951259698Sdim 1952259698Sdim def _4H : N2VShiftIns<0b0, u, opcode, asmop, "4h", VPR64, v4i16, shl_imm16, 1953259698Sdim int_aarch64_neon_vsli> { 1954259698Sdim let Inst{22-20} = 0b001; 1955259698Sdim } 1956259698Sdim 1957259698Sdim def _2S : N2VShiftIns<0b0, u, opcode, asmop, "2s", VPR64, v2i32, shl_imm32, 1958259698Sdim int_aarch64_neon_vsli> { 1959259698Sdim let Inst{22-21} = 0b01; 1960259698Sdim } 1961259698Sdim 1962259698Sdim // 128-bit vector types 1963259698Sdim def _16B : N2VShiftIns<0b1, u, opcode, asmop, "16b", VPR128, v16i8, shl_imm8, 1964259698Sdim int_aarch64_neon_vsli> { 1965259698Sdim let Inst{22-19} = 0b0001; 1966259698Sdim } 1967259698Sdim 1968259698Sdim def _8H : N2VShiftIns<0b1, u, opcode, asmop, "8h", VPR128, v8i16, shl_imm16, 1969259698Sdim int_aarch64_neon_vsli> { 1970259698Sdim let Inst{22-20} = 0b001; 1971259698Sdim } 1972259698Sdim 1973259698Sdim def _4S : N2VShiftIns<0b1, u, opcode, asmop, "4s", VPR128, v4i32, shl_imm32, 1974259698Sdim int_aarch64_neon_vsli> { 1975259698Sdim let Inst{22-21} = 0b01; 1976259698Sdim } 1977259698Sdim 1978259698Sdim def _2D : N2VShiftIns<0b1, u, opcode, asmop, "2d", VPR128, v2i64, shl_imm64, 1979259698Sdim int_aarch64_neon_vsli> { 1980259698Sdim let Inst{22} = 0b1; 1981259698Sdim } 1982259698Sdim} 1983259698Sdim 1984259698Sdim// shift right insert (vector by immediate) 1985259698Sdimmulticlass NeonI_N2VShRIns<bit u, bits<5> opcode, string asmop> { 1986259698Sdim // 64-bit vector types. 1987259698Sdim def _8B : N2VShiftIns<0b0, u, opcode, asmop, "8b", VPR64, v8i8, shr_imm8, 1988259698Sdim int_aarch64_neon_vsri> { 1989259698Sdim let Inst{22-19} = 0b0001; 1990259698Sdim } 1991259698Sdim 1992259698Sdim def _4H : N2VShiftIns<0b0, u, opcode, asmop, "4h", VPR64, v4i16, shr_imm16, 1993259698Sdim int_aarch64_neon_vsri> { 1994259698Sdim let Inst{22-20} = 0b001; 1995259698Sdim } 1996259698Sdim 1997259698Sdim def _2S : N2VShiftIns<0b0, u, opcode, asmop, "2s", VPR64, v2i32, shr_imm32, 1998259698Sdim int_aarch64_neon_vsri> { 1999259698Sdim let Inst{22-21} = 0b01; 2000259698Sdim } 2001259698Sdim 2002259698Sdim // 128-bit vector types 2003259698Sdim def _16B : N2VShiftIns<0b1, u, opcode, asmop, "16b", VPR128, v16i8, shr_imm8, 2004259698Sdim int_aarch64_neon_vsri> { 2005259698Sdim let Inst{22-19} = 0b0001; 2006259698Sdim } 2007259698Sdim 2008259698Sdim def _8H : N2VShiftIns<0b1, u, opcode, asmop, "8h", VPR128, v8i16, shr_imm16, 2009259698Sdim int_aarch64_neon_vsri> { 2010259698Sdim let Inst{22-20} = 0b001; 2011259698Sdim } 2012259698Sdim 2013259698Sdim def _4S : N2VShiftIns<0b1, u, opcode, asmop, "4s", VPR128, v4i32, shr_imm32, 2014259698Sdim int_aarch64_neon_vsri> { 2015259698Sdim let Inst{22-21} = 0b01; 2016259698Sdim } 2017259698Sdim 2018259698Sdim def _2D : N2VShiftIns<0b1, u, opcode, asmop, "2d", VPR128, v2i64, shr_imm64, 2019259698Sdim int_aarch64_neon_vsri> { 2020259698Sdim let Inst{22} = 0b1; 2021259698Sdim } 2022259698Sdim} 2023259698Sdim 2024259698Sdim// Shift left and insert 2025259698Sdimdefm SLIvvi : NeonI_N2VShLIns<0b1, 0b01010, "sli">; 2026259698Sdim 2027259698Sdim// Shift right and insert 2028259698Sdimdefm SRIvvi : NeonI_N2VShRIns<0b1, 0b01000, "sri">; 2029259698Sdim 2030259698Sdimclass N2VShR_Narrow<bit q, bit u, bits<5> opcode, string asmop, string DestT, 2031259698Sdim string SrcT, Operand ImmTy> 2032259698Sdim : NeonI_2VShiftImm<q, u, opcode, 2033259698Sdim (outs VPR64:$Rd), (ins VPR128:$Rn, ImmTy:$Imm), 2034259698Sdim asmop # "\t$Rd." # DestT # ", $Rn." # SrcT # ", $Imm", 2035259698Sdim [], NoItinerary>; 2036259698Sdim 2037259698Sdimclass N2VShR_Narrow_Hi<bit q, bit u, bits<5> opcode, string asmop, string DestT, 2038259698Sdim string SrcT, Operand ImmTy> 2039259698Sdim : NeonI_2VShiftImm<q, u, opcode, (outs VPR128:$Rd), 2040259698Sdim (ins VPR128:$src, VPR128:$Rn, ImmTy:$Imm), 2041259698Sdim asmop # "\t$Rd." # DestT # ", $Rn." # SrcT # ", $Imm", 2042259698Sdim [], NoItinerary> { 2043259698Sdim let Constraints = "$src = $Rd"; 2044259698Sdim} 2045259698Sdim 2046259698Sdim// left long shift by immediate 2047259698Sdimmulticlass NeonI_N2VShR_Narrow<bit u, bits<5> opcode, string asmop> { 2048259698Sdim def _8B : N2VShR_Narrow<0b0, u, opcode, asmop, "8b", "8h", shr_imm8> { 2049259698Sdim let Inst{22-19} = 0b0001; 2050259698Sdim } 2051259698Sdim 2052259698Sdim def _4H : N2VShR_Narrow<0b0, u, opcode, asmop, "4h", "4s", shr_imm16> { 2053259698Sdim let Inst{22-20} = 0b001; 2054259698Sdim } 2055259698Sdim 2056259698Sdim def _2S : N2VShR_Narrow<0b0, u, opcode, asmop, "2s", "2d", shr_imm32> { 2057259698Sdim let Inst{22-21} = 0b01; 2058259698Sdim } 2059259698Sdim 2060259698Sdim // Shift Narrow High 2061259698Sdim def _16B : N2VShR_Narrow_Hi<0b1, u, opcode, asmop # "2", "16b", "8h", 2062259698Sdim shr_imm8> { 2063259698Sdim let Inst{22-19} = 0b0001; 2064259698Sdim } 2065259698Sdim 2066259698Sdim def _8H : N2VShR_Narrow_Hi<0b1, u, opcode, asmop # "2", "8h", "4s", 2067259698Sdim shr_imm16> { 2068259698Sdim let Inst{22-20} = 0b001; 2069259698Sdim } 2070259698Sdim 2071259698Sdim def _4S : N2VShR_Narrow_Hi<0b1, u, opcode, asmop # "2", "4s", "2d", 2072259698Sdim shr_imm32> { 2073259698Sdim let Inst{22-21} = 0b01; 2074259698Sdim } 2075259698Sdim} 2076259698Sdim 2077259698Sdim// Shift right narrow 2078259698Sdimdefm SHRNvvi : NeonI_N2VShR_Narrow<0b0, 0b10000, "shrn">; 2079259698Sdim 2080259698Sdim// Shift right narrow (prefix Q is saturating, prefix R is rounding) 2081259698Sdimdefm QSHRUNvvi :NeonI_N2VShR_Narrow<0b1, 0b10000, "sqshrun">; 2082259698Sdimdefm RSHRNvvi : NeonI_N2VShR_Narrow<0b0, 0b10001, "rshrn">; 2083259698Sdimdefm QRSHRUNvvi : NeonI_N2VShR_Narrow<0b1, 0b10001, "sqrshrun">; 2084259698Sdimdefm SQSHRNvvi : NeonI_N2VShR_Narrow<0b0, 0b10010, "sqshrn">; 2085259698Sdimdefm UQSHRNvvi : NeonI_N2VShR_Narrow<0b1, 0b10010, "uqshrn">; 2086259698Sdimdefm SQRSHRNvvi : NeonI_N2VShR_Narrow<0b0, 0b10011, "sqrshrn">; 2087259698Sdimdefm UQRSHRNvvi : NeonI_N2VShR_Narrow<0b1, 0b10011, "uqrshrn">; 2088259698Sdim 2089259698Sdimdef Neon_combine_2D : PatFrag<(ops node:$Rm, node:$Rn), 2090259698Sdim (v2i64 (concat_vectors (v1i64 node:$Rm), 2091259698Sdim (v1i64 node:$Rn)))>; 2092259698Sdimdef Neon_combine_8H : PatFrag<(ops node:$Rm, node:$Rn), 2093259698Sdim (v8i16 (concat_vectors (v4i16 node:$Rm), 2094259698Sdim (v4i16 node:$Rn)))>; 2095259698Sdimdef Neon_combine_4S : PatFrag<(ops node:$Rm, node:$Rn), 2096259698Sdim (v4i32 (concat_vectors (v2i32 node:$Rm), 2097259698Sdim (v2i32 node:$Rn)))>; 2098259698Sdimdef Neon_combine_4f : PatFrag<(ops node:$Rm, node:$Rn), 2099259698Sdim (v4f32 (concat_vectors (v2f32 node:$Rm), 2100259698Sdim (v2f32 node:$Rn)))>; 2101259698Sdimdef Neon_combine_2d : PatFrag<(ops node:$Rm, node:$Rn), 2102259698Sdim (v2f64 (concat_vectors (v1f64 node:$Rm), 2103259698Sdim (v1f64 node:$Rn)))>; 2104259698Sdim 2105259698Sdimdef Neon_lshrImm8H : PatFrag<(ops node:$lhs, node:$rhs), 2106259698Sdim (v8i16 (srl (v8i16 node:$lhs), 2107259698Sdim (v8i16 (Neon_vdup (i32 node:$rhs)))))>; 2108259698Sdimdef Neon_lshrImm4S : PatFrag<(ops node:$lhs, node:$rhs), 2109259698Sdim (v4i32 (srl (v4i32 node:$lhs), 2110259698Sdim (v4i32 (Neon_vdup (i32 node:$rhs)))))>; 2111259698Sdimdef Neon_lshrImm2D : PatFrag<(ops node:$lhs, node:$rhs), 2112259698Sdim (v2i64 (srl (v2i64 node:$lhs), 2113259698Sdim (v2i64 (Neon_vdup (i32 node:$rhs)))))>; 2114259698Sdimdef Neon_ashrImm8H : PatFrag<(ops node:$lhs, node:$rhs), 2115259698Sdim (v8i16 (sra (v8i16 node:$lhs), 2116259698Sdim (v8i16 (Neon_vdup (i32 node:$rhs)))))>; 2117259698Sdimdef Neon_ashrImm4S : PatFrag<(ops node:$lhs, node:$rhs), 2118259698Sdim (v4i32 (sra (v4i32 node:$lhs), 2119259698Sdim (v4i32 (Neon_vdup (i32 node:$rhs)))))>; 2120259698Sdimdef Neon_ashrImm2D : PatFrag<(ops node:$lhs, node:$rhs), 2121259698Sdim (v2i64 (sra (v2i64 node:$lhs), 2122259698Sdim (v2i64 (Neon_vdup (i32 node:$rhs)))))>; 2123259698Sdim 2124259698Sdim// Normal shift right narrow is matched by IR (srl/sra, trunc, concat_vectors) 2125259698Sdimmulticlass Neon_shiftNarrow_patterns<string shr> { 2126259698Sdim def : Pat<(v8i8 (trunc (!cast<PatFrag>("Neon_" # shr # "Imm8H") VPR128:$Rn, 2127259698Sdim (i32 shr_imm8:$Imm)))), 2128259698Sdim (SHRNvvi_8B VPR128:$Rn, imm:$Imm)>; 2129259698Sdim def : Pat<(v4i16 (trunc (!cast<PatFrag>("Neon_" # shr # "Imm4S") VPR128:$Rn, 2130259698Sdim (i32 shr_imm16:$Imm)))), 2131259698Sdim (SHRNvvi_4H VPR128:$Rn, imm:$Imm)>; 2132259698Sdim def : Pat<(v2i32 (trunc (!cast<PatFrag>("Neon_" # shr # "Imm2D") VPR128:$Rn, 2133259698Sdim (i32 shr_imm32:$Imm)))), 2134259698Sdim (SHRNvvi_2S VPR128:$Rn, imm:$Imm)>; 2135259698Sdim 2136259698Sdim def : Pat<(Neon_combine_2D (v1i64 VPR64:$src), (v1i64 (bitconvert 2137259698Sdim (v8i8 (trunc (!cast<PatFrag>("Neon_" # shr # "Imm8H") 2138259698Sdim VPR128:$Rn, (i32 shr_imm8:$Imm))))))), 2139259698Sdim (SHRNvvi_16B (v2i64 (SUBREG_TO_REG (i64 0), VPR64:$src, sub_64)), 2140259698Sdim VPR128:$Rn, imm:$Imm)>; 2141259698Sdim def : Pat<(Neon_combine_2D (v1i64 VPR64:$src), (v1i64 (bitconvert 2142259698Sdim (v4i16 (trunc (!cast<PatFrag>("Neon_" # shr # "Imm4S") 2143259698Sdim VPR128:$Rn, (i32 shr_imm16:$Imm))))))), 2144259698Sdim (SHRNvvi_8H (SUBREG_TO_REG (i64 0), VPR64:$src, sub_64), 2145259698Sdim VPR128:$Rn, imm:$Imm)>; 2146259698Sdim def : Pat<(Neon_combine_2D (v1i64 VPR64:$src), (v1i64 (bitconvert 2147259698Sdim (v2i32 (trunc (!cast<PatFrag>("Neon_" # shr # "Imm2D") 2148259698Sdim VPR128:$Rn, (i32 shr_imm32:$Imm))))))), 2149259698Sdim (SHRNvvi_4S (SUBREG_TO_REG (i64 0), VPR64:$src, sub_64), 2150259698Sdim VPR128:$Rn, imm:$Imm)>; 2151259698Sdim} 2152259698Sdim 2153259698Sdimmulticlass Neon_shiftNarrow_QR_patterns<SDPatternOperator op, string prefix> { 2154259698Sdim def : Pat<(v8i8 (op (v8i16 VPR128:$Rn), shr_imm8:$Imm)), 2155259698Sdim (!cast<Instruction>(prefix # "_8B") VPR128:$Rn, imm:$Imm)>; 2156259698Sdim def : Pat<(v4i16 (op (v4i32 VPR128:$Rn), shr_imm16:$Imm)), 2157259698Sdim (!cast<Instruction>(prefix # "_4H") VPR128:$Rn, imm:$Imm)>; 2158259698Sdim def : Pat<(v2i32 (op (v2i64 VPR128:$Rn), shr_imm32:$Imm)), 2159259698Sdim (!cast<Instruction>(prefix # "_2S") VPR128:$Rn, imm:$Imm)>; 2160259698Sdim 2161259698Sdim def : Pat<(Neon_combine_2D (v1i64 VPR64:$src), 2162259698Sdim (v1i64 (bitconvert (v8i8 2163259698Sdim (op (v8i16 VPR128:$Rn), shr_imm8:$Imm))))), 2164259698Sdim (!cast<Instruction>(prefix # "_16B") 2165259698Sdim (SUBREG_TO_REG (i64 0), VPR64:$src, sub_64), 2166259698Sdim VPR128:$Rn, imm:$Imm)>; 2167259698Sdim def : Pat<(Neon_combine_2D (v1i64 VPR64:$src), 2168259698Sdim (v1i64 (bitconvert (v4i16 2169259698Sdim (op (v4i32 VPR128:$Rn), shr_imm16:$Imm))))), 2170259698Sdim (!cast<Instruction>(prefix # "_8H") 2171259698Sdim (SUBREG_TO_REG (i64 0), VPR64:$src, sub_64), 2172259698Sdim VPR128:$Rn, imm:$Imm)>; 2173259698Sdim def : Pat<(Neon_combine_2D (v1i64 VPR64:$src), 2174259698Sdim (v1i64 (bitconvert (v2i32 2175259698Sdim (op (v2i64 VPR128:$Rn), shr_imm32:$Imm))))), 2176259698Sdim (!cast<Instruction>(prefix # "_4S") 2177259698Sdim (SUBREG_TO_REG (i64 0), VPR64:$src, sub_64), 2178259698Sdim VPR128:$Rn, imm:$Imm)>; 2179259698Sdim} 2180259698Sdim 2181259698Sdimdefm : Neon_shiftNarrow_patterns<"lshr">; 2182259698Sdimdefm : Neon_shiftNarrow_patterns<"ashr">; 2183259698Sdim 2184259698Sdimdefm : Neon_shiftNarrow_QR_patterns<int_aarch64_neon_vsqshrun, "QSHRUNvvi">; 2185259698Sdimdefm : Neon_shiftNarrow_QR_patterns<int_aarch64_neon_vrshrn, "RSHRNvvi">; 2186259698Sdimdefm : Neon_shiftNarrow_QR_patterns<int_aarch64_neon_vsqrshrun, "QRSHRUNvvi">; 2187259698Sdimdefm : Neon_shiftNarrow_QR_patterns<int_aarch64_neon_vsqshrn, "SQSHRNvvi">; 2188259698Sdimdefm : Neon_shiftNarrow_QR_patterns<int_aarch64_neon_vuqshrn, "UQSHRNvvi">; 2189259698Sdimdefm : Neon_shiftNarrow_QR_patterns<int_aarch64_neon_vsqrshrn, "SQRSHRNvvi">; 2190259698Sdimdefm : Neon_shiftNarrow_QR_patterns<int_aarch64_neon_vuqrshrn, "UQRSHRNvvi">; 2191259698Sdim 2192259698Sdim// Convert fix-point and float-pointing 2193259698Sdimclass N2VCvt_Fx<bit q, bit u, bits<5> opcode, string asmop, string T, 2194259698Sdim RegisterOperand VPRC, ValueType DestTy, ValueType SrcTy, 2195259698Sdim Operand ImmTy, SDPatternOperator IntOp> 2196259698Sdim : NeonI_2VShiftImm<q, u, opcode, 2197259698Sdim (outs VPRC:$Rd), (ins VPRC:$Rn, ImmTy:$Imm), 2198259698Sdim asmop # "\t$Rd." # T # ", $Rn." # T # ", $Imm", 2199259698Sdim [(set (DestTy VPRC:$Rd), (DestTy (IntOp (SrcTy VPRC:$Rn), 2200259698Sdim (i32 ImmTy:$Imm))))], 2201259698Sdim NoItinerary>; 2202259698Sdim 2203259698Sdimmulticlass NeonI_N2VCvt_Fx2fp<bit u, bits<5> opcode, string asmop, 2204259698Sdim SDPatternOperator IntOp> { 2205259698Sdim def _2S : N2VCvt_Fx<0, u, opcode, asmop, "2s", VPR64, v2f32, v2i32, 2206259698Sdim shr_imm32, IntOp> { 2207259698Sdim let Inst{22-21} = 0b01; 2208259698Sdim } 2209259698Sdim 2210259698Sdim def _4S : N2VCvt_Fx<1, u, opcode, asmop, "4s", VPR128, v4f32, v4i32, 2211259698Sdim shr_imm32, IntOp> { 2212259698Sdim let Inst{22-21} = 0b01; 2213259698Sdim } 2214259698Sdim 2215259698Sdim def _2D : N2VCvt_Fx<1, u, opcode, asmop, "2d", VPR128, v2f64, v2i64, 2216259698Sdim shr_imm64, IntOp> { 2217259698Sdim let Inst{22} = 0b1; 2218259698Sdim } 2219259698Sdim} 2220259698Sdim 2221259698Sdimmulticlass NeonI_N2VCvt_Fp2fx<bit u, bits<5> opcode, string asmop, 2222259698Sdim SDPatternOperator IntOp> { 2223259698Sdim def _2S : N2VCvt_Fx<0, u, opcode, asmop, "2s", VPR64, v2i32, v2f32, 2224259698Sdim shr_imm32, IntOp> { 2225259698Sdim let Inst{22-21} = 0b01; 2226259698Sdim } 2227259698Sdim 2228259698Sdim def _4S : N2VCvt_Fx<1, u, opcode, asmop, "4s", VPR128, v4i32, v4f32, 2229259698Sdim shr_imm32, IntOp> { 2230259698Sdim let Inst{22-21} = 0b01; 2231259698Sdim } 2232259698Sdim 2233259698Sdim def _2D : N2VCvt_Fx<1, u, opcode, asmop, "2d", VPR128, v2i64, v2f64, 2234259698Sdim shr_imm64, IntOp> { 2235259698Sdim let Inst{22} = 0b1; 2236259698Sdim } 2237259698Sdim} 2238259698Sdim 2239259698Sdim// Convert fixed-point to floating-point 2240259698Sdimdefm VCVTxs2f : NeonI_N2VCvt_Fx2fp<0, 0b11100, "scvtf", 2241259698Sdim int_arm_neon_vcvtfxs2fp>; 2242259698Sdimdefm VCVTxu2f : NeonI_N2VCvt_Fx2fp<1, 0b11100, "ucvtf", 2243259698Sdim int_arm_neon_vcvtfxu2fp>; 2244259698Sdim 2245259698Sdim// Convert floating-point to fixed-point 2246259698Sdimdefm VCVTf2xs : NeonI_N2VCvt_Fp2fx<0, 0b11111, "fcvtzs", 2247259698Sdim int_arm_neon_vcvtfp2fxs>; 2248259698Sdimdefm VCVTf2xu : NeonI_N2VCvt_Fp2fx<1, 0b11111, "fcvtzu", 2249259698Sdim int_arm_neon_vcvtfp2fxu>; 2250259698Sdim 2251259698Sdimmulticlass Neon_sshll2_0<SDNode ext> 2252259698Sdim{ 2253259698Sdim def _v8i8 : PatFrag<(ops node:$Rn), 2254259698Sdim (v8i16 (ext (v8i8 (Neon_High16B node:$Rn))))>; 2255259698Sdim def _v4i16 : PatFrag<(ops node:$Rn), 2256259698Sdim (v4i32 (ext (v4i16 (Neon_High8H node:$Rn))))>; 2257259698Sdim def _v2i32 : PatFrag<(ops node:$Rn), 2258259698Sdim (v2i64 (ext (v2i32 (Neon_High4S node:$Rn))))>; 2259259698Sdim} 2260259698Sdim 2261259698Sdimdefm NI_sext_high : Neon_sshll2_0<sext>; 2262259698Sdimdefm NI_zext_high : Neon_sshll2_0<zext>; 2263259698Sdim 2264259698Sdim 2265259698Sdim//===----------------------------------------------------------------------===// 2266259698Sdim// Multiclasses for NeonI_Across 2267259698Sdim//===----------------------------------------------------------------------===// 2268259698Sdim 2269259698Sdim// Variant 1 2270259698Sdim 2271259698Sdimmulticlass NeonI_2VAcross_1<bit u, bits<5> opcode, 2272259698Sdim string asmop, SDPatternOperator opnode> 2273259698Sdim{ 2274259698Sdim def _1h8b: NeonI_2VAcross<0b0, u, 0b00, opcode, 2275259698Sdim (outs FPR16:$Rd), (ins VPR64:$Rn), 2276259698Sdim asmop # "\t$Rd, $Rn.8b", 2277259698Sdim [(set (v1i16 FPR16:$Rd), 2278259698Sdim (v1i16 (opnode (v8i8 VPR64:$Rn))))], 2279259698Sdim NoItinerary>; 2280259698Sdim 2281259698Sdim def _1h16b: NeonI_2VAcross<0b1, u, 0b00, opcode, 2282259698Sdim (outs FPR16:$Rd), (ins VPR128:$Rn), 2283259698Sdim asmop # "\t$Rd, $Rn.16b", 2284259698Sdim [(set (v1i16 FPR16:$Rd), 2285259698Sdim (v1i16 (opnode (v16i8 VPR128:$Rn))))], 2286259698Sdim NoItinerary>; 2287259698Sdim 2288259698Sdim def _1s4h: NeonI_2VAcross<0b0, u, 0b01, opcode, 2289259698Sdim (outs FPR32:$Rd), (ins VPR64:$Rn), 2290259698Sdim asmop # "\t$Rd, $Rn.4h", 2291259698Sdim [(set (v1i32 FPR32:$Rd), 2292259698Sdim (v1i32 (opnode (v4i16 VPR64:$Rn))))], 2293259698Sdim NoItinerary>; 2294259698Sdim 2295259698Sdim def _1s8h: NeonI_2VAcross<0b1, u, 0b01, opcode, 2296259698Sdim (outs FPR32:$Rd), (ins VPR128:$Rn), 2297259698Sdim asmop # "\t$Rd, $Rn.8h", 2298259698Sdim [(set (v1i32 FPR32:$Rd), 2299259698Sdim (v1i32 (opnode (v8i16 VPR128:$Rn))))], 2300259698Sdim NoItinerary>; 2301259698Sdim 2302259698Sdim // _1d2s doesn't exist! 2303259698Sdim 2304259698Sdim def _1d4s: NeonI_2VAcross<0b1, u, 0b10, opcode, 2305259698Sdim (outs FPR64:$Rd), (ins VPR128:$Rn), 2306259698Sdim asmop # "\t$Rd, $Rn.4s", 2307259698Sdim [(set (v1i64 FPR64:$Rd), 2308259698Sdim (v1i64 (opnode (v4i32 VPR128:$Rn))))], 2309259698Sdim NoItinerary>; 2310259698Sdim} 2311259698Sdim 2312259698Sdimdefm SADDLV : NeonI_2VAcross_1<0b0, 0b00011, "saddlv", int_aarch64_neon_saddlv>; 2313259698Sdimdefm UADDLV : NeonI_2VAcross_1<0b1, 0b00011, "uaddlv", int_aarch64_neon_uaddlv>; 2314259698Sdim 2315259698Sdim// Variant 2 2316259698Sdim 2317259698Sdimmulticlass NeonI_2VAcross_2<bit u, bits<5> opcode, 2318259698Sdim string asmop, SDPatternOperator opnode> 2319259698Sdim{ 2320259698Sdim def _1b8b: NeonI_2VAcross<0b0, u, 0b00, opcode, 2321259698Sdim (outs FPR8:$Rd), (ins VPR64:$Rn), 2322259698Sdim asmop # "\t$Rd, $Rn.8b", 2323259698Sdim [(set (v1i8 FPR8:$Rd), 2324259698Sdim (v1i8 (opnode (v8i8 VPR64:$Rn))))], 2325259698Sdim NoItinerary>; 2326259698Sdim 2327259698Sdim def _1b16b: NeonI_2VAcross<0b1, u, 0b00, opcode, 2328259698Sdim (outs FPR8:$Rd), (ins VPR128:$Rn), 2329259698Sdim asmop # "\t$Rd, $Rn.16b", 2330259698Sdim [(set (v1i8 FPR8:$Rd), 2331259698Sdim (v1i8 (opnode (v16i8 VPR128:$Rn))))], 2332259698Sdim NoItinerary>; 2333259698Sdim 2334259698Sdim def _1h4h: NeonI_2VAcross<0b0, u, 0b01, opcode, 2335259698Sdim (outs FPR16:$Rd), (ins VPR64:$Rn), 2336259698Sdim asmop # "\t$Rd, $Rn.4h", 2337259698Sdim [(set (v1i16 FPR16:$Rd), 2338259698Sdim (v1i16 (opnode (v4i16 VPR64:$Rn))))], 2339259698Sdim NoItinerary>; 2340259698Sdim 2341259698Sdim def _1h8h: NeonI_2VAcross<0b1, u, 0b01, opcode, 2342259698Sdim (outs FPR16:$Rd), (ins VPR128:$Rn), 2343259698Sdim asmop # "\t$Rd, $Rn.8h", 2344259698Sdim [(set (v1i16 FPR16:$Rd), 2345259698Sdim (v1i16 (opnode (v8i16 VPR128:$Rn))))], 2346259698Sdim NoItinerary>; 2347259698Sdim 2348259698Sdim // _1s2s doesn't exist! 2349259698Sdim 2350259698Sdim def _1s4s: NeonI_2VAcross<0b1, u, 0b10, opcode, 2351259698Sdim (outs FPR32:$Rd), (ins VPR128:$Rn), 2352259698Sdim asmop # "\t$Rd, $Rn.4s", 2353259698Sdim [(set (v1i32 FPR32:$Rd), 2354259698Sdim (v1i32 (opnode (v4i32 VPR128:$Rn))))], 2355259698Sdim NoItinerary>; 2356259698Sdim} 2357259698Sdim 2358259698Sdimdefm SMAXV : NeonI_2VAcross_2<0b0, 0b01010, "smaxv", int_aarch64_neon_smaxv>; 2359259698Sdimdefm UMAXV : NeonI_2VAcross_2<0b1, 0b01010, "umaxv", int_aarch64_neon_umaxv>; 2360259698Sdim 2361259698Sdimdefm SMINV : NeonI_2VAcross_2<0b0, 0b11010, "sminv", int_aarch64_neon_sminv>; 2362259698Sdimdefm UMINV : NeonI_2VAcross_2<0b1, 0b11010, "uminv", int_aarch64_neon_uminv>; 2363259698Sdim 2364259698Sdimdefm ADDV : NeonI_2VAcross_2<0b0, 0b11011, "addv", int_aarch64_neon_vaddv>; 2365259698Sdim 2366259698Sdim// Variant 3 2367259698Sdim 2368259698Sdimmulticlass NeonI_2VAcross_3<bit u, bits<5> opcode, bits<2> size, 2369259698Sdim string asmop, SDPatternOperator opnode> { 2370259698Sdim def _1s4s: NeonI_2VAcross<0b1, u, size, opcode, 2371259698Sdim (outs FPR32:$Rd), (ins VPR128:$Rn), 2372259698Sdim asmop # "\t$Rd, $Rn.4s", 2373259698Sdim [(set (v1f32 FPR32:$Rd), 2374259698Sdim (v1f32 (opnode (v4f32 VPR128:$Rn))))], 2375259698Sdim NoItinerary>; 2376259698Sdim} 2377259698Sdim 2378259698Sdimdefm FMAXNMV : NeonI_2VAcross_3<0b1, 0b01100, 0b00, "fmaxnmv", 2379259698Sdim int_aarch64_neon_vmaxnmv>; 2380259698Sdimdefm FMINNMV : NeonI_2VAcross_3<0b1, 0b01100, 0b10, "fminnmv", 2381259698Sdim int_aarch64_neon_vminnmv>; 2382259698Sdim 2383259698Sdimdefm FMAXV : NeonI_2VAcross_3<0b1, 0b01111, 0b00, "fmaxv", 2384259698Sdim int_aarch64_neon_vmaxv>; 2385259698Sdimdefm FMINV : NeonI_2VAcross_3<0b1, 0b01111, 0b10, "fminv", 2386259698Sdim int_aarch64_neon_vminv>; 2387259698Sdim 2388259698Sdim// The followings are for instruction class (Perm) 2389259698Sdim 2390259698Sdimclass NeonI_Permute<bit q, bits<2> size, bits<3> opcode, 2391259698Sdim string asmop, RegisterOperand OpVPR, string OpS, 2392259698Sdim SDPatternOperator opnode, ValueType Ty> 2393259698Sdim : NeonI_Perm<q, size, opcode, 2394259698Sdim (outs OpVPR:$Rd), (ins OpVPR:$Rn, OpVPR:$Rm), 2395259698Sdim asmop # "\t$Rd." # OpS # ", $Rn." # OpS # ", $Rm." # OpS, 2396259698Sdim [(set (Ty OpVPR:$Rd), 2397259698Sdim (Ty (opnode (Ty OpVPR:$Rn), (Ty OpVPR:$Rm))))], 2398259698Sdim NoItinerary>; 2399259698Sdim 2400259698Sdimmulticlass NeonI_Perm_pat<bits<3> opcode, string asmop, 2401259698Sdim SDPatternOperator opnode> { 2402259698Sdim def _8b : NeonI_Permute<0b0, 0b00, opcode, asmop, 2403259698Sdim VPR64, "8b", opnode, v8i8>; 2404259698Sdim def _16b : NeonI_Permute<0b1, 0b00, opcode, asmop, 2405259698Sdim VPR128, "16b",opnode, v16i8>; 2406259698Sdim def _4h : NeonI_Permute<0b0, 0b01, opcode, asmop, 2407259698Sdim VPR64, "4h", opnode, v4i16>; 2408259698Sdim def _8h : NeonI_Permute<0b1, 0b01, opcode, asmop, 2409259698Sdim VPR128, "8h", opnode, v8i16>; 2410259698Sdim def _2s : NeonI_Permute<0b0, 0b10, opcode, asmop, 2411259698Sdim VPR64, "2s", opnode, v2i32>; 2412259698Sdim def _4s : NeonI_Permute<0b1, 0b10, opcode, asmop, 2413259698Sdim VPR128, "4s", opnode, v4i32>; 2414259698Sdim def _2d : NeonI_Permute<0b1, 0b11, opcode, asmop, 2415259698Sdim VPR128, "2d", opnode, v2i64>; 2416259698Sdim} 2417259698Sdim 2418259698Sdimdefm UZP1vvv : NeonI_Perm_pat<0b001, "uzp1", Neon_uzp1>; 2419259698Sdimdefm TRN1vvv : NeonI_Perm_pat<0b010, "trn1", Neon_trn1>; 2420259698Sdimdefm ZIP1vvv : NeonI_Perm_pat<0b011, "zip1", Neon_zip1>; 2421259698Sdimdefm UZP2vvv : NeonI_Perm_pat<0b101, "uzp2", Neon_uzp2>; 2422259698Sdimdefm TRN2vvv : NeonI_Perm_pat<0b110, "trn2", Neon_trn2>; 2423259698Sdimdefm ZIP2vvv : NeonI_Perm_pat<0b111, "zip2", Neon_zip2>; 2424259698Sdim 2425259698Sdimmulticlass NeonI_Perm_float_pat<string INS, SDPatternOperator opnode> { 2426259698Sdim def : Pat<(v2f32 (opnode (v2f32 VPR64:$Rn), (v2f32 VPR64:$Rm))), 2427259698Sdim (!cast<Instruction>(INS # "_2s") VPR64:$Rn, VPR64:$Rm)>; 2428259698Sdim 2429259698Sdim def : Pat<(v4f32 (opnode (v4f32 VPR128:$Rn), (v4f32 VPR128:$Rm))), 2430259698Sdim (!cast<Instruction>(INS # "_4s") VPR128:$Rn, VPR128:$Rm)>; 2431259698Sdim 2432259698Sdim def : Pat<(v2f64 (opnode (v2f64 VPR128:$Rn), (v2f64 VPR128:$Rm))), 2433259698Sdim (!cast<Instruction>(INS # "_2d") VPR128:$Rn, VPR128:$Rm)>; 2434259698Sdim} 2435259698Sdim 2436259698Sdimdefm : NeonI_Perm_float_pat<"UZP1vvv", Neon_uzp1>; 2437259698Sdimdefm : NeonI_Perm_float_pat<"UZP2vvv", Neon_uzp2>; 2438259698Sdimdefm : NeonI_Perm_float_pat<"ZIP1vvv", Neon_zip1>; 2439259698Sdimdefm : NeonI_Perm_float_pat<"ZIP2vvv", Neon_zip2>; 2440259698Sdimdefm : NeonI_Perm_float_pat<"TRN1vvv", Neon_trn1>; 2441259698Sdimdefm : NeonI_Perm_float_pat<"TRN2vvv", Neon_trn2>; 2442259698Sdim 2443259698Sdim// The followings are for instruction class (3V Diff) 2444259698Sdim 2445259698Sdim// normal long/long2 pattern 2446259698Sdimclass NeonI_3VDL<bit q, bit u, bits<2> size, bits<4> opcode, 2447259698Sdim string asmop, string ResS, string OpS, 2448259698Sdim SDPatternOperator opnode, SDPatternOperator ext, 2449259698Sdim RegisterOperand OpVPR, 2450259698Sdim ValueType ResTy, ValueType OpTy> 2451259698Sdim : NeonI_3VDiff<q, u, size, opcode, 2452259698Sdim (outs VPR128:$Rd), (ins OpVPR:$Rn, OpVPR:$Rm), 2453259698Sdim asmop # "\t$Rd." # ResS # ", $Rn." # OpS # ", $Rm." # OpS, 2454259698Sdim [(set (ResTy VPR128:$Rd), 2455259698Sdim (ResTy (opnode (ResTy (ext (OpTy OpVPR:$Rn))), 2456259698Sdim (ResTy (ext (OpTy OpVPR:$Rm))))))], 2457259698Sdim NoItinerary>; 2458259698Sdim 2459259698Sdimmulticlass NeonI_3VDL_s<bit u, bits<4> opcode, 2460259698Sdim string asmop, SDPatternOperator opnode, 2461259698Sdim bit Commutable = 0> { 2462259698Sdim let isCommutable = Commutable in { 2463259698Sdim def _8h8b : NeonI_3VDL<0b0, u, 0b00, opcode, asmop, "8h", "8b", 2464259698Sdim opnode, sext, VPR64, v8i16, v8i8>; 2465259698Sdim def _4s4h : NeonI_3VDL<0b0, u, 0b01, opcode, asmop, "4s", "4h", 2466259698Sdim opnode, sext, VPR64, v4i32, v4i16>; 2467259698Sdim def _2d2s : NeonI_3VDL<0b0, u, 0b10, opcode, asmop, "2d", "2s", 2468259698Sdim opnode, sext, VPR64, v2i64, v2i32>; 2469259698Sdim } 2470259698Sdim} 2471259698Sdim 2472259698Sdimmulticlass NeonI_3VDL2_s<bit u, bits<4> opcode, string asmop, 2473259698Sdim SDPatternOperator opnode, bit Commutable = 0> { 2474259698Sdim let isCommutable = Commutable in { 2475259698Sdim def _8h16b : NeonI_3VDL<0b1, u, 0b00, opcode, asmop, "8h", "16b", 2476259698Sdim opnode, NI_sext_high_v8i8, VPR128, v8i16, v16i8>; 2477259698Sdim def _4s8h : NeonI_3VDL<0b1, u, 0b01, opcode, asmop, "4s", "8h", 2478259698Sdim opnode, NI_sext_high_v4i16, VPR128, v4i32, v8i16>; 2479259698Sdim def _2d4s : NeonI_3VDL<0b1, u, 0b10, opcode, asmop, "2d", "4s", 2480259698Sdim opnode, NI_sext_high_v2i32, VPR128, v2i64, v4i32>; 2481259698Sdim } 2482259698Sdim} 2483259698Sdim 2484259698Sdimmulticlass NeonI_3VDL_u<bit u, bits<4> opcode, string asmop, 2485259698Sdim SDPatternOperator opnode, bit Commutable = 0> { 2486259698Sdim let isCommutable = Commutable in { 2487259698Sdim def _8h8b : NeonI_3VDL<0b0, u, 0b00, opcode, asmop, "8h", "8b", 2488259698Sdim opnode, zext, VPR64, v8i16, v8i8>; 2489259698Sdim def _4s4h : NeonI_3VDL<0b0, u, 0b01, opcode, asmop, "4s", "4h", 2490259698Sdim opnode, zext, VPR64, v4i32, v4i16>; 2491259698Sdim def _2d2s : NeonI_3VDL<0b0, u, 0b10, opcode, asmop, "2d", "2s", 2492259698Sdim opnode, zext, VPR64, v2i64, v2i32>; 2493259698Sdim } 2494259698Sdim} 2495259698Sdim 2496259698Sdimmulticlass NeonI_3VDL2_u<bit u, bits<4> opcode, string asmop, 2497259698Sdim SDPatternOperator opnode, bit Commutable = 0> { 2498259698Sdim let isCommutable = Commutable in { 2499259698Sdim def _8h16b : NeonI_3VDL<0b1, u, 0b00, opcode, asmop, "8h", "16b", 2500259698Sdim opnode, NI_zext_high_v8i8, VPR128, v8i16, v16i8>; 2501259698Sdim def _4s8h : NeonI_3VDL<0b1, u, 0b01, opcode, asmop, "4s", "8h", 2502259698Sdim opnode, NI_zext_high_v4i16, VPR128, v4i32, v8i16>; 2503259698Sdim def _2d4s : NeonI_3VDL<0b1, u, 0b10, opcode, asmop, "2d", "4s", 2504259698Sdim opnode, NI_zext_high_v2i32, VPR128, v2i64, v4i32>; 2505259698Sdim } 2506259698Sdim} 2507259698Sdim 2508259698Sdimdefm SADDLvvv : NeonI_3VDL_s<0b0, 0b0000, "saddl", add, 1>; 2509259698Sdimdefm UADDLvvv : NeonI_3VDL_u<0b1, 0b0000, "uaddl", add, 1>; 2510259698Sdim 2511259698Sdimdefm SADDL2vvv : NeonI_3VDL2_s<0b0, 0b0000, "saddl2", add, 1>; 2512259698Sdimdefm UADDL2vvv : NeonI_3VDL2_u<0b1, 0b0000, "uaddl2", add, 1>; 2513259698Sdim 2514259698Sdimdefm SSUBLvvv : NeonI_3VDL_s<0b0, 0b0010, "ssubl", sub, 0>; 2515259698Sdimdefm USUBLvvv : NeonI_3VDL_u<0b1, 0b0010, "usubl", sub, 0>; 2516259698Sdim 2517259698Sdimdefm SSUBL2vvv : NeonI_3VDL2_s<0b0, 0b0010, "ssubl2", sub, 0>; 2518259698Sdimdefm USUBL2vvv : NeonI_3VDL2_u<0b1, 0b0010, "usubl2", sub, 0>; 2519259698Sdim 2520259698Sdim// normal wide/wide2 pattern 2521259698Sdimclass NeonI_3VDW<bit q, bit u, bits<2> size, bits<4> opcode, 2522259698Sdim string asmop, string ResS, string OpS, 2523259698Sdim SDPatternOperator opnode, SDPatternOperator ext, 2524259698Sdim RegisterOperand OpVPR, 2525259698Sdim ValueType ResTy, ValueType OpTy> 2526259698Sdim : NeonI_3VDiff<q, u, size, opcode, 2527259698Sdim (outs VPR128:$Rd), (ins VPR128:$Rn, OpVPR:$Rm), 2528259698Sdim asmop # "\t$Rd." # ResS # ", $Rn." # ResS # ", $Rm." # OpS, 2529259698Sdim [(set (ResTy VPR128:$Rd), 2530259698Sdim (ResTy (opnode (ResTy VPR128:$Rn), 2531259698Sdim (ResTy (ext (OpTy OpVPR:$Rm))))))], 2532259698Sdim NoItinerary>; 2533259698Sdim 2534259698Sdimmulticlass NeonI_3VDW_s<bit u, bits<4> opcode, string asmop, 2535259698Sdim SDPatternOperator opnode> { 2536259698Sdim def _8h8b : NeonI_3VDW<0b0, u, 0b00, opcode, asmop, "8h", "8b", 2537259698Sdim opnode, sext, VPR64, v8i16, v8i8>; 2538259698Sdim def _4s4h : NeonI_3VDW<0b0, u, 0b01, opcode, asmop, "4s", "4h", 2539259698Sdim opnode, sext, VPR64, v4i32, v4i16>; 2540259698Sdim def _2d2s : NeonI_3VDW<0b0, u, 0b10, opcode, asmop, "2d", "2s", 2541259698Sdim opnode, sext, VPR64, v2i64, v2i32>; 2542259698Sdim} 2543259698Sdim 2544259698Sdimdefm SADDWvvv : NeonI_3VDW_s<0b0, 0b0001, "saddw", add>; 2545259698Sdimdefm SSUBWvvv : NeonI_3VDW_s<0b0, 0b0011, "ssubw", sub>; 2546259698Sdim 2547259698Sdimmulticlass NeonI_3VDW2_s<bit u, bits<4> opcode, string asmop, 2548259698Sdim SDPatternOperator opnode> { 2549259698Sdim def _8h16b : NeonI_3VDW<0b1, u, 0b00, opcode, asmop, "8h", "16b", 2550259698Sdim opnode, NI_sext_high_v8i8, VPR128, v8i16, v16i8>; 2551259698Sdim def _4s8h : NeonI_3VDW<0b1, u, 0b01, opcode, asmop, "4s", "8h", 2552259698Sdim opnode, NI_sext_high_v4i16, VPR128, v4i32, v8i16>; 2553259698Sdim def _2d4s : NeonI_3VDW<0b1, u, 0b10, opcode, asmop, "2d", "4s", 2554259698Sdim opnode, NI_sext_high_v2i32, VPR128, v2i64, v4i32>; 2555259698Sdim} 2556259698Sdim 2557259698Sdimdefm SADDW2vvv : NeonI_3VDW2_s<0b0, 0b0001, "saddw2", add>; 2558259698Sdimdefm SSUBW2vvv : NeonI_3VDW2_s<0b0, 0b0011, "ssubw2", sub>; 2559259698Sdim 2560259698Sdimmulticlass NeonI_3VDW_u<bit u, bits<4> opcode, string asmop, 2561259698Sdim SDPatternOperator opnode> { 2562259698Sdim def _8h8b : NeonI_3VDW<0b0, u, 0b00, opcode, asmop, "8h", "8b", 2563259698Sdim opnode, zext, VPR64, v8i16, v8i8>; 2564259698Sdim def _4s4h : NeonI_3VDW<0b0, u, 0b01, opcode, asmop, "4s", "4h", 2565259698Sdim opnode, zext, VPR64, v4i32, v4i16>; 2566259698Sdim def _2d2s : NeonI_3VDW<0b0, u, 0b10, opcode, asmop, "2d", "2s", 2567259698Sdim opnode, zext, VPR64, v2i64, v2i32>; 2568259698Sdim} 2569259698Sdim 2570259698Sdimdefm UADDWvvv : NeonI_3VDW_u<0b1, 0b0001, "uaddw", add>; 2571259698Sdimdefm USUBWvvv : NeonI_3VDW_u<0b1, 0b0011, "usubw", sub>; 2572259698Sdim 2573259698Sdimmulticlass NeonI_3VDW2_u<bit u, bits<4> opcode, string asmop, 2574259698Sdim SDPatternOperator opnode> { 2575259698Sdim def _8h16b : NeonI_3VDW<0b1, u, 0b00, opcode, asmop, "8h", "16b", 2576259698Sdim opnode, NI_zext_high_v8i8, VPR128, v8i16, v16i8>; 2577259698Sdim def _4s8h : NeonI_3VDW<0b1, u, 0b01, opcode, asmop, "4s", "8h", 2578259698Sdim opnode, NI_zext_high_v4i16, VPR128, v4i32, v8i16>; 2579259698Sdim def _2d4s : NeonI_3VDW<0b1, u, 0b10, opcode, asmop, "2d", "4s", 2580259698Sdim opnode, NI_zext_high_v2i32, VPR128, v2i64, v4i32>; 2581259698Sdim} 2582259698Sdim 2583259698Sdimdefm UADDW2vvv : NeonI_3VDW2_u<0b1, 0b0001, "uaddw2", add>; 2584259698Sdimdefm USUBW2vvv : NeonI_3VDW2_u<0b1, 0b0011, "usubw2", sub>; 2585259698Sdim 2586259698Sdim// Get the high half part of the vector element. 2587259698Sdimmulticlass NeonI_get_high { 2588259698Sdim def _8h : PatFrag<(ops node:$Rn), 2589259698Sdim (v8i8 (trunc (v8i16 (srl (v8i16 node:$Rn), 2590259698Sdim (v8i16 (Neon_vdup (i32 8)))))))>; 2591259698Sdim def _4s : PatFrag<(ops node:$Rn), 2592259698Sdim (v4i16 (trunc (v4i32 (srl (v4i32 node:$Rn), 2593259698Sdim (v4i32 (Neon_vdup (i32 16)))))))>; 2594259698Sdim def _2d : PatFrag<(ops node:$Rn), 2595259698Sdim (v2i32 (trunc (v2i64 (srl (v2i64 node:$Rn), 2596259698Sdim (v2i64 (Neon_vdup (i32 32)))))))>; 2597259698Sdim} 2598259698Sdim 2599259698Sdimdefm NI_get_hi : NeonI_get_high; 2600259698Sdim 2601259698Sdim// pattern for addhn/subhn with 2 operands 2602259698Sdimclass NeonI_3VDN_addhn_2Op<bit q, bit u, bits<2> size, bits<4> opcode, 2603259698Sdim string asmop, string ResS, string OpS, 2604259698Sdim SDPatternOperator opnode, SDPatternOperator get_hi, 2605259698Sdim ValueType ResTy, ValueType OpTy> 2606259698Sdim : NeonI_3VDiff<q, u, size, opcode, 2607259698Sdim (outs VPR64:$Rd), (ins VPR128:$Rn, VPR128:$Rm), 2608259698Sdim asmop # "\t$Rd." # ResS # ", $Rn." # OpS # ", $Rm." # OpS, 2609259698Sdim [(set (ResTy VPR64:$Rd), 2610259698Sdim (ResTy (get_hi 2611259698Sdim (OpTy (opnode (OpTy VPR128:$Rn), 2612259698Sdim (OpTy VPR128:$Rm))))))], 2613259698Sdim NoItinerary>; 2614259698Sdim 2615259698Sdimmulticlass NeonI_3VDN_addhn_2Op<bit u, bits<4> opcode, string asmop, 2616259698Sdim SDPatternOperator opnode, bit Commutable = 0> { 2617259698Sdim let isCommutable = Commutable in { 2618259698Sdim def _8b8h : NeonI_3VDN_addhn_2Op<0b0, u, 0b00, opcode, asmop, "8b", "8h", 2619259698Sdim opnode, NI_get_hi_8h, v8i8, v8i16>; 2620259698Sdim def _4h4s : NeonI_3VDN_addhn_2Op<0b0, u, 0b01, opcode, asmop, "4h", "4s", 2621259698Sdim opnode, NI_get_hi_4s, v4i16, v4i32>; 2622259698Sdim def _2s2d : NeonI_3VDN_addhn_2Op<0b0, u, 0b10, opcode, asmop, "2s", "2d", 2623259698Sdim opnode, NI_get_hi_2d, v2i32, v2i64>; 2624259698Sdim } 2625259698Sdim} 2626259698Sdim 2627259698Sdimdefm ADDHNvvv : NeonI_3VDN_addhn_2Op<0b0, 0b0100, "addhn", add, 1>; 2628259698Sdimdefm SUBHNvvv : NeonI_3VDN_addhn_2Op<0b0, 0b0110, "subhn", sub, 0>; 2629259698Sdim 2630259698Sdim// pattern for operation with 2 operands 2631259698Sdimclass NeonI_3VD_2Op<bit q, bit u, bits<2> size, bits<4> opcode, 2632259698Sdim string asmop, string ResS, string OpS, 2633259698Sdim SDPatternOperator opnode, 2634259698Sdim RegisterOperand ResVPR, RegisterOperand OpVPR, 2635259698Sdim ValueType ResTy, ValueType OpTy> 2636259698Sdim : NeonI_3VDiff<q, u, size, opcode, 2637259698Sdim (outs ResVPR:$Rd), (ins OpVPR:$Rn, OpVPR:$Rm), 2638259698Sdim asmop # "\t$Rd." # ResS # ", $Rn." # OpS # ", $Rm." # OpS, 2639259698Sdim [(set (ResTy ResVPR:$Rd), 2640259698Sdim (ResTy (opnode (OpTy OpVPR:$Rn), (OpTy OpVPR:$Rm))))], 2641259698Sdim NoItinerary>; 2642259698Sdim 2643259698Sdim// normal narrow pattern 2644259698Sdimmulticlass NeonI_3VDN_2Op<bit u, bits<4> opcode, string asmop, 2645259698Sdim SDPatternOperator opnode, bit Commutable = 0> { 2646259698Sdim let isCommutable = Commutable in { 2647259698Sdim def _8b8h : NeonI_3VD_2Op<0b0, u, 0b00, opcode, asmop, "8b", "8h", 2648259698Sdim opnode, VPR64, VPR128, v8i8, v8i16>; 2649259698Sdim def _4h4s : NeonI_3VD_2Op<0b0, u, 0b01, opcode, asmop, "4h", "4s", 2650259698Sdim opnode, VPR64, VPR128, v4i16, v4i32>; 2651259698Sdim def _2s2d : NeonI_3VD_2Op<0b0, u, 0b10, opcode, asmop, "2s", "2d", 2652259698Sdim opnode, VPR64, VPR128, v2i32, v2i64>; 2653259698Sdim } 2654259698Sdim} 2655259698Sdim 2656259698Sdimdefm RADDHNvvv : NeonI_3VDN_2Op<0b1, 0b0100, "raddhn", int_arm_neon_vraddhn, 1>; 2657259698Sdimdefm RSUBHNvvv : NeonI_3VDN_2Op<0b1, 0b0110, "rsubhn", int_arm_neon_vrsubhn, 0>; 2658259698Sdim 2659259698Sdim// pattern for acle intrinsic with 3 operands 2660259698Sdimclass NeonI_3VDN_3Op<bit q, bit u, bits<2> size, bits<4> opcode, 2661259698Sdim string asmop, string ResS, string OpS> 2662259698Sdim : NeonI_3VDiff<q, u, size, opcode, 2663259698Sdim (outs VPR128:$Rd), (ins VPR128:$src, VPR128:$Rn, VPR128:$Rm), 2664259698Sdim asmop # "\t$Rd." # ResS # ", $Rn." # OpS # ", $Rm." # OpS, 2665259698Sdim [], NoItinerary> { 2666259698Sdim let Constraints = "$src = $Rd"; 2667259698Sdim let neverHasSideEffects = 1; 2668259698Sdim} 2669259698Sdim 2670259698Sdimmulticlass NeonI_3VDN_3Op_v1<bit u, bits<4> opcode, string asmop> { 2671259698Sdim def _16b8h : NeonI_3VDN_3Op<0b1, u, 0b00, opcode, asmop, "16b", "8h">; 2672259698Sdim def _8h4s : NeonI_3VDN_3Op<0b1, u, 0b01, opcode, asmop, "8h", "4s">; 2673259698Sdim def _4s2d : NeonI_3VDN_3Op<0b1, u, 0b10, opcode, asmop, "4s", "2d">; 2674259698Sdim} 2675259698Sdim 2676259698Sdimdefm ADDHN2vvv : NeonI_3VDN_3Op_v1<0b0, 0b0100, "addhn2">; 2677259698Sdimdefm SUBHN2vvv : NeonI_3VDN_3Op_v1<0b0, 0b0110, "subhn2">; 2678259698Sdim 2679259698Sdimdefm RADDHN2vvv : NeonI_3VDN_3Op_v1<0b1, 0b0100, "raddhn2">; 2680259698Sdimdefm RSUBHN2vvv : NeonI_3VDN_3Op_v1<0b1, 0b0110, "rsubhn2">; 2681259698Sdim 2682259698Sdim// Patterns have to be separate because there's a SUBREG_TO_REG in the output 2683259698Sdim// part. 2684259698Sdimclass NarrowHighHalfPat<Instruction INST, ValueType DstTy, ValueType SrcTy, 2685259698Sdim SDPatternOperator coreop> 2686259698Sdim : Pat<(Neon_combine_2D (v1i64 VPR64:$src), 2687259698Sdim (v1i64 (bitconvert (DstTy (coreop (SrcTy VPR128:$Rn), 2688259698Sdim (SrcTy VPR128:$Rm)))))), 2689259698Sdim (INST (SUBREG_TO_REG (i64 0), VPR64:$src, sub_64), 2690259698Sdim VPR128:$Rn, VPR128:$Rm)>; 2691259698Sdim 2692259698Sdim// addhn2 patterns 2693259698Sdimdef : NarrowHighHalfPat<ADDHN2vvv_16b8h, v8i8, v8i16, 2694259698Sdim BinOpFrag<(NI_get_hi_8h (add node:$LHS, node:$RHS))>>; 2695259698Sdimdef : NarrowHighHalfPat<ADDHN2vvv_8h4s, v4i16, v4i32, 2696259698Sdim BinOpFrag<(NI_get_hi_4s (add node:$LHS, node:$RHS))>>; 2697259698Sdimdef : NarrowHighHalfPat<ADDHN2vvv_4s2d, v2i32, v2i64, 2698259698Sdim BinOpFrag<(NI_get_hi_2d (add node:$LHS, node:$RHS))>>; 2699259698Sdim 2700259698Sdim// subhn2 patterns 2701259698Sdimdef : NarrowHighHalfPat<SUBHN2vvv_16b8h, v8i8, v8i16, 2702259698Sdim BinOpFrag<(NI_get_hi_8h (sub node:$LHS, node:$RHS))>>; 2703259698Sdimdef : NarrowHighHalfPat<SUBHN2vvv_8h4s, v4i16, v4i32, 2704259698Sdim BinOpFrag<(NI_get_hi_4s (sub node:$LHS, node:$RHS))>>; 2705259698Sdimdef : NarrowHighHalfPat<SUBHN2vvv_4s2d, v2i32, v2i64, 2706259698Sdim BinOpFrag<(NI_get_hi_2d (sub node:$LHS, node:$RHS))>>; 2707259698Sdim 2708259698Sdim// raddhn2 patterns 2709259698Sdimdef : NarrowHighHalfPat<RADDHN2vvv_16b8h, v8i8, v8i16, int_arm_neon_vraddhn>; 2710259698Sdimdef : NarrowHighHalfPat<RADDHN2vvv_8h4s, v4i16, v4i32, int_arm_neon_vraddhn>; 2711259698Sdimdef : NarrowHighHalfPat<RADDHN2vvv_4s2d, v2i32, v2i64, int_arm_neon_vraddhn>; 2712259698Sdim 2713259698Sdim// rsubhn2 patterns 2714259698Sdimdef : NarrowHighHalfPat<RSUBHN2vvv_16b8h, v8i8, v8i16, int_arm_neon_vrsubhn>; 2715259698Sdimdef : NarrowHighHalfPat<RSUBHN2vvv_8h4s, v4i16, v4i32, int_arm_neon_vrsubhn>; 2716259698Sdimdef : NarrowHighHalfPat<RSUBHN2vvv_4s2d, v2i32, v2i64, int_arm_neon_vrsubhn>; 2717259698Sdim 2718259698Sdim// pattern that need to extend result 2719259698Sdimclass NeonI_3VDL_Ext<bit q, bit u, bits<2> size, bits<4> opcode, 2720259698Sdim string asmop, string ResS, string OpS, 2721259698Sdim SDPatternOperator opnode, 2722259698Sdim RegisterOperand OpVPR, 2723259698Sdim ValueType ResTy, ValueType OpTy, ValueType OpSTy> 2724259698Sdim : NeonI_3VDiff<q, u, size, opcode, 2725259698Sdim (outs VPR128:$Rd), (ins OpVPR:$Rn, OpVPR:$Rm), 2726259698Sdim asmop # "\t$Rd." # ResS # ", $Rn." # OpS # ", $Rm." # OpS, 2727259698Sdim [(set (ResTy VPR128:$Rd), 2728259698Sdim (ResTy (zext (OpSTy (opnode (OpTy OpVPR:$Rn), 2729259698Sdim (OpTy OpVPR:$Rm))))))], 2730259698Sdim NoItinerary>; 2731259698Sdim 2732259698Sdimmulticlass NeonI_3VDL_zext<bit u, bits<4> opcode, string asmop, 2733259698Sdim SDPatternOperator opnode, bit Commutable = 0> { 2734259698Sdim let isCommutable = Commutable in { 2735259698Sdim def _8h8b : NeonI_3VDL_Ext<0b0, u, 0b00, opcode, asmop, "8h", "8b", 2736259698Sdim opnode, VPR64, v8i16, v8i8, v8i8>; 2737259698Sdim def _4s4h : NeonI_3VDL_Ext<0b0, u, 0b01, opcode, asmop, "4s", "4h", 2738259698Sdim opnode, VPR64, v4i32, v4i16, v4i16>; 2739259698Sdim def _2d2s : NeonI_3VDL_Ext<0b0, u, 0b10, opcode, asmop, "2d", "2s", 2740259698Sdim opnode, VPR64, v2i64, v2i32, v2i32>; 2741259698Sdim } 2742259698Sdim} 2743259698Sdim 2744259698Sdimdefm SABDLvvv : NeonI_3VDL_zext<0b0, 0b0111, "sabdl", int_arm_neon_vabds, 1>; 2745259698Sdimdefm UABDLvvv : NeonI_3VDL_zext<0b1, 0b0111, "uabdl", int_arm_neon_vabdu, 1>; 2746259698Sdim 2747259698Sdimmulticlass NeonI_Op_High<SDPatternOperator op> { 2748259698Sdim def _16B : PatFrag<(ops node:$Rn, node:$Rm), 2749259698Sdim (op (v8i8 (Neon_High16B node:$Rn)), 2750259698Sdim (v8i8 (Neon_High16B node:$Rm)))>; 2751259698Sdim def _8H : PatFrag<(ops node:$Rn, node:$Rm), 2752259698Sdim (op (v4i16 (Neon_High8H node:$Rn)), 2753259698Sdim (v4i16 (Neon_High8H node:$Rm)))>; 2754259698Sdim def _4S : PatFrag<(ops node:$Rn, node:$Rm), 2755259698Sdim (op (v2i32 (Neon_High4S node:$Rn)), 2756259698Sdim (v2i32 (Neon_High4S node:$Rm)))>; 2757259698Sdim} 2758259698Sdim 2759259698Sdimdefm NI_sabdl_hi : NeonI_Op_High<int_arm_neon_vabds>; 2760259698Sdimdefm NI_uabdl_hi : NeonI_Op_High<int_arm_neon_vabdu>; 2761259698Sdimdefm NI_smull_hi : NeonI_Op_High<int_arm_neon_vmulls>; 2762259698Sdimdefm NI_umull_hi : NeonI_Op_High<int_arm_neon_vmullu>; 2763259698Sdimdefm NI_qdmull_hi : NeonI_Op_High<int_arm_neon_vqdmull>; 2764259698Sdimdefm NI_pmull_hi : NeonI_Op_High<int_arm_neon_vmullp>; 2765259698Sdim 2766259698Sdimmulticlass NeonI_3VDL_Abd_u<bit u, bits<4> opcode, string asmop, string opnode, 2767259698Sdim bit Commutable = 0> { 2768259698Sdim let isCommutable = Commutable in { 2769259698Sdim def _8h8b : NeonI_3VDL_Ext<0b1, u, 0b00, opcode, asmop, "8h", "16b", 2770259698Sdim !cast<PatFrag>(opnode # "_16B"), 2771259698Sdim VPR128, v8i16, v16i8, v8i8>; 2772259698Sdim def _4s4h : NeonI_3VDL_Ext<0b1, u, 0b01, opcode, asmop, "4s", "8h", 2773259698Sdim !cast<PatFrag>(opnode # "_8H"), 2774259698Sdim VPR128, v4i32, v8i16, v4i16>; 2775259698Sdim def _2d2s : NeonI_3VDL_Ext<0b1, u, 0b10, opcode, asmop, "2d", "4s", 2776259698Sdim !cast<PatFrag>(opnode # "_4S"), 2777259698Sdim VPR128, v2i64, v4i32, v2i32>; 2778259698Sdim } 2779259698Sdim} 2780259698Sdim 2781259698Sdimdefm SABDL2vvv : NeonI_3VDL_Abd_u<0b0, 0b0111, "sabdl2", "NI_sabdl_hi", 1>; 2782259698Sdimdefm UABDL2vvv : NeonI_3VDL_Abd_u<0b1, 0b0111, "uabdl2", "NI_uabdl_hi", 1>; 2783259698Sdim 2784259698Sdim// For pattern that need two operators being chained. 2785259698Sdimclass NeonI_3VDL_Aba<bit q, bit u, bits<2> size, bits<4> opcode, 2786259698Sdim string asmop, string ResS, string OpS, 2787259698Sdim SDPatternOperator opnode, SDPatternOperator subop, 2788259698Sdim RegisterOperand OpVPR, 2789259698Sdim ValueType ResTy, ValueType OpTy, ValueType OpSTy> 2790259698Sdim : NeonI_3VDiff<q, u, size, opcode, 2791259698Sdim (outs VPR128:$Rd), (ins VPR128:$src, OpVPR:$Rn, OpVPR:$Rm), 2792259698Sdim asmop # "\t$Rd." # ResS # ", $Rn." # OpS # ", $Rm." # OpS, 2793259698Sdim [(set (ResTy VPR128:$Rd), 2794259698Sdim (ResTy (opnode 2795259698Sdim (ResTy VPR128:$src), 2796259698Sdim (ResTy (zext (OpSTy (subop (OpTy OpVPR:$Rn), 2797259698Sdim (OpTy OpVPR:$Rm))))))))], 2798259698Sdim NoItinerary> { 2799259698Sdim let Constraints = "$src = $Rd"; 2800259698Sdim} 2801259698Sdim 2802259698Sdimmulticlass NeonI_3VDL_Aba_v1<bit u, bits<4> opcode, string asmop, 2803259698Sdim SDPatternOperator opnode, SDPatternOperator subop>{ 2804259698Sdim def _8h8b : NeonI_3VDL_Aba<0b0, u, 0b00, opcode, asmop, "8h", "8b", 2805259698Sdim opnode, subop, VPR64, v8i16, v8i8, v8i8>; 2806259698Sdim def _4s4h : NeonI_3VDL_Aba<0b0, u, 0b01, opcode, asmop, "4s", "4h", 2807259698Sdim opnode, subop, VPR64, v4i32, v4i16, v4i16>; 2808259698Sdim def _2d2s : NeonI_3VDL_Aba<0b0, u, 0b10, opcode, asmop, "2d", "2s", 2809259698Sdim opnode, subop, VPR64, v2i64, v2i32, v2i32>; 2810259698Sdim} 2811259698Sdim 2812259698Sdimdefm SABALvvv : NeonI_3VDL_Aba_v1<0b0, 0b0101, "sabal", 2813259698Sdim add, int_arm_neon_vabds>; 2814259698Sdimdefm UABALvvv : NeonI_3VDL_Aba_v1<0b1, 0b0101, "uabal", 2815259698Sdim add, int_arm_neon_vabdu>; 2816259698Sdim 2817259698Sdimmulticlass NeonI_3VDL2_Aba_v1<bit u, bits<4> opcode, string asmop, 2818259698Sdim SDPatternOperator opnode, string subop> { 2819259698Sdim def _8h8b : NeonI_3VDL_Aba<0b1, u, 0b00, opcode, asmop, "8h", "16b", 2820259698Sdim opnode, !cast<PatFrag>(subop # "_16B"), 2821259698Sdim VPR128, v8i16, v16i8, v8i8>; 2822259698Sdim def _4s4h : NeonI_3VDL_Aba<0b1, u, 0b01, opcode, asmop, "4s", "8h", 2823259698Sdim opnode, !cast<PatFrag>(subop # "_8H"), 2824259698Sdim VPR128, v4i32, v8i16, v4i16>; 2825259698Sdim def _2d2s : NeonI_3VDL_Aba<0b1, u, 0b10, opcode, asmop, "2d", "4s", 2826259698Sdim opnode, !cast<PatFrag>(subop # "_4S"), 2827259698Sdim VPR128, v2i64, v4i32, v2i32>; 2828259698Sdim} 2829259698Sdim 2830259698Sdimdefm SABAL2vvv : NeonI_3VDL2_Aba_v1<0b0, 0b0101, "sabal2", add, 2831259698Sdim "NI_sabdl_hi">; 2832259698Sdimdefm UABAL2vvv : NeonI_3VDL2_Aba_v1<0b1, 0b0101, "uabal2", add, 2833259698Sdim "NI_uabdl_hi">; 2834259698Sdim 2835259698Sdim// Long pattern with 2 operands 2836259698Sdimmulticlass NeonI_3VDL_2Op<bit u, bits<4> opcode, string asmop, 2837259698Sdim SDPatternOperator opnode, bit Commutable = 0> { 2838259698Sdim let isCommutable = Commutable in { 2839259698Sdim def _8h8b : NeonI_3VD_2Op<0b0, u, 0b00, opcode, asmop, "8h", "8b", 2840259698Sdim opnode, VPR128, VPR64, v8i16, v8i8>; 2841259698Sdim def _4s4h : NeonI_3VD_2Op<0b0, u, 0b01, opcode, asmop, "4s", "4h", 2842259698Sdim opnode, VPR128, VPR64, v4i32, v4i16>; 2843259698Sdim def _2d2s : NeonI_3VD_2Op<0b0, u, 0b10, opcode, asmop, "2d", "2s", 2844259698Sdim opnode, VPR128, VPR64, v2i64, v2i32>; 2845259698Sdim } 2846259698Sdim} 2847259698Sdim 2848259698Sdimdefm SMULLvvv : NeonI_3VDL_2Op<0b0, 0b1100, "smull", int_arm_neon_vmulls, 1>; 2849259698Sdimdefm UMULLvvv : NeonI_3VDL_2Op<0b1, 0b1100, "umull", int_arm_neon_vmullu, 1>; 2850259698Sdim 2851259698Sdimclass NeonI_3VDL2_2Op_mull<bit q, bit u, bits<2> size, bits<4> opcode, 2852259698Sdim string asmop, string ResS, string OpS, 2853259698Sdim SDPatternOperator opnode, 2854259698Sdim ValueType ResTy, ValueType OpTy> 2855259698Sdim : NeonI_3VDiff<q, u, size, opcode, 2856259698Sdim (outs VPR128:$Rd), (ins VPR128:$Rn, VPR128:$Rm), 2857259698Sdim asmop # "\t$Rd." # ResS # ", $Rn." # OpS # ", $Rm." # OpS, 2858259698Sdim [(set (ResTy VPR128:$Rd), 2859259698Sdim (ResTy (opnode (OpTy VPR128:$Rn), (OpTy VPR128:$Rm))))], 2860259698Sdim NoItinerary>; 2861259698Sdim 2862259698Sdimmulticlass NeonI_3VDL2_2Op_mull_v1<bit u, bits<4> opcode, string asmop, 2863259698Sdim string opnode, bit Commutable = 0> { 2864259698Sdim let isCommutable = Commutable in { 2865259698Sdim def _8h16b : NeonI_3VDL2_2Op_mull<0b1, u, 0b00, opcode, asmop, "8h", "16b", 2866259698Sdim !cast<PatFrag>(opnode # "_16B"), 2867259698Sdim v8i16, v16i8>; 2868259698Sdim def _4s8h : NeonI_3VDL2_2Op_mull<0b1, u, 0b01, opcode, asmop, "4s", "8h", 2869259698Sdim !cast<PatFrag>(opnode # "_8H"), 2870259698Sdim v4i32, v8i16>; 2871259698Sdim def _2d4s : NeonI_3VDL2_2Op_mull<0b1, u, 0b10, opcode, asmop, "2d", "4s", 2872259698Sdim !cast<PatFrag>(opnode # "_4S"), 2873259698Sdim v2i64, v4i32>; 2874259698Sdim } 2875259698Sdim} 2876259698Sdim 2877259698Sdimdefm SMULL2vvv : NeonI_3VDL2_2Op_mull_v1<0b0, 0b1100, "smull2", 2878259698Sdim "NI_smull_hi", 1>; 2879259698Sdimdefm UMULL2vvv : NeonI_3VDL2_2Op_mull_v1<0b1, 0b1100, "umull2", 2880259698Sdim "NI_umull_hi", 1>; 2881259698Sdim 2882259698Sdim// Long pattern with 3 operands 2883259698Sdimclass NeonI_3VDL_3Op<bit q, bit u, bits<2> size, bits<4> opcode, 2884259698Sdim string asmop, string ResS, string OpS, 2885259698Sdim SDPatternOperator opnode, 2886259698Sdim ValueType ResTy, ValueType OpTy> 2887259698Sdim : NeonI_3VDiff<q, u, size, opcode, 2888259698Sdim (outs VPR128:$Rd), (ins VPR128:$src, VPR64:$Rn, VPR64:$Rm), 2889259698Sdim asmop # "\t$Rd." # ResS # ", $Rn." # OpS # ", $Rm." # OpS, 2890259698Sdim [(set (ResTy VPR128:$Rd), 2891259698Sdim (ResTy (opnode 2892259698Sdim (ResTy VPR128:$src), 2893259698Sdim (OpTy VPR64:$Rn), (OpTy VPR64:$Rm))))], 2894259698Sdim NoItinerary> { 2895259698Sdim let Constraints = "$src = $Rd"; 2896259698Sdim} 2897259698Sdim 2898259698Sdimmulticlass NeonI_3VDL_3Op_v1<bit u, bits<4> opcode, string asmop, 2899259698Sdim SDPatternOperator opnode> { 2900259698Sdim def _8h8b : NeonI_3VDL_3Op<0b0, u, 0b00, opcode, asmop, "8h", "8b", 2901259698Sdim opnode, v8i16, v8i8>; 2902259698Sdim def _4s4h : NeonI_3VDL_3Op<0b0, u, 0b01, opcode, asmop, "4s", "4h", 2903259698Sdim opnode, v4i32, v4i16>; 2904259698Sdim def _2d2s : NeonI_3VDL_3Op<0b0, u, 0b10, opcode, asmop, "2d", "2s", 2905259698Sdim opnode, v2i64, v2i32>; 2906259698Sdim} 2907259698Sdim 2908259698Sdimdef Neon_smlal : PatFrag<(ops node:$Rd, node:$Rn, node:$Rm), 2909259698Sdim (add node:$Rd, 2910259698Sdim (int_arm_neon_vmulls node:$Rn, node:$Rm))>; 2911259698Sdim 2912259698Sdimdef Neon_umlal : PatFrag<(ops node:$Rd, node:$Rn, node:$Rm), 2913259698Sdim (add node:$Rd, 2914259698Sdim (int_arm_neon_vmullu node:$Rn, node:$Rm))>; 2915259698Sdim 2916259698Sdimdef Neon_smlsl : PatFrag<(ops node:$Rd, node:$Rn, node:$Rm), 2917259698Sdim (sub node:$Rd, 2918259698Sdim (int_arm_neon_vmulls node:$Rn, node:$Rm))>; 2919259698Sdim 2920259698Sdimdef Neon_umlsl : PatFrag<(ops node:$Rd, node:$Rn, node:$Rm), 2921259698Sdim (sub node:$Rd, 2922259698Sdim (int_arm_neon_vmullu node:$Rn, node:$Rm))>; 2923259698Sdim 2924259698Sdimdefm SMLALvvv : NeonI_3VDL_3Op_v1<0b0, 0b1000, "smlal", Neon_smlal>; 2925259698Sdimdefm UMLALvvv : NeonI_3VDL_3Op_v1<0b1, 0b1000, "umlal", Neon_umlal>; 2926259698Sdim 2927259698Sdimdefm SMLSLvvv : NeonI_3VDL_3Op_v1<0b0, 0b1010, "smlsl", Neon_smlsl>; 2928259698Sdimdefm UMLSLvvv : NeonI_3VDL_3Op_v1<0b1, 0b1010, "umlsl", Neon_umlsl>; 2929259698Sdim 2930259698Sdimclass NeonI_3VDL2_3Op_mlas<bit q, bit u, bits<2> size, bits<4> opcode, 2931259698Sdim string asmop, string ResS, string OpS, 2932259698Sdim SDPatternOperator subop, SDPatternOperator opnode, 2933259698Sdim RegisterOperand OpVPR, 2934259698Sdim ValueType ResTy, ValueType OpTy> 2935259698Sdim : NeonI_3VDiff<q, u, size, opcode, 2936259698Sdim (outs VPR128:$Rd), (ins VPR128:$src, OpVPR:$Rn, OpVPR:$Rm), 2937259698Sdim asmop # "\t$Rd." # ResS # ", $Rn." # OpS # ", $Rm." # OpS, 2938259698Sdim [(set (ResTy VPR128:$Rd), 2939259698Sdim (ResTy (subop 2940259698Sdim (ResTy VPR128:$src), 2941259698Sdim (ResTy (opnode (OpTy OpVPR:$Rn), (OpTy OpVPR:$Rm))))))], 2942259698Sdim NoItinerary> { 2943259698Sdim let Constraints = "$src = $Rd"; 2944259698Sdim} 2945259698Sdim 2946259698Sdimmulticlass NeonI_3VDL2_3Op_mlas_v1<bit u, bits<4> opcode, string asmop, 2947259698Sdim SDPatternOperator subop, string opnode> { 2948259698Sdim def _8h16b : NeonI_3VDL2_3Op_mlas<0b1, u, 0b00, opcode, asmop, "8h", "16b", 2949259698Sdim subop, !cast<PatFrag>(opnode # "_16B"), 2950259698Sdim VPR128, v8i16, v16i8>; 2951259698Sdim def _4s8h : NeonI_3VDL2_3Op_mlas<0b1, u, 0b01, opcode, asmop, "4s", "8h", 2952259698Sdim subop, !cast<PatFrag>(opnode # "_8H"), 2953259698Sdim VPR128, v4i32, v8i16>; 2954259698Sdim def _2d4s : NeonI_3VDL2_3Op_mlas<0b1, u, 0b10, opcode, asmop, "2d", "4s", 2955259698Sdim subop, !cast<PatFrag>(opnode # "_4S"), 2956259698Sdim VPR128, v2i64, v4i32>; 2957259698Sdim} 2958259698Sdim 2959259698Sdimdefm SMLAL2vvv : NeonI_3VDL2_3Op_mlas_v1<0b0, 0b1000, "smlal2", 2960259698Sdim add, "NI_smull_hi">; 2961259698Sdimdefm UMLAL2vvv : NeonI_3VDL2_3Op_mlas_v1<0b1, 0b1000, "umlal2", 2962259698Sdim add, "NI_umull_hi">; 2963259698Sdim 2964259698Sdimdefm SMLSL2vvv : NeonI_3VDL2_3Op_mlas_v1<0b0, 0b1010, "smlsl2", 2965259698Sdim sub, "NI_smull_hi">; 2966259698Sdimdefm UMLSL2vvv : NeonI_3VDL2_3Op_mlas_v1<0b1, 0b1010, "umlsl2", 2967259698Sdim sub, "NI_umull_hi">; 2968259698Sdim 2969259698Sdimmulticlass NeonI_3VDL_qdmlal_3Op_v2<bit u, bits<4> opcode, string asmop, 2970259698Sdim SDPatternOperator opnode> { 2971259698Sdim def _4s4h : NeonI_3VDL2_3Op_mlas<0b0, u, 0b01, opcode, asmop, "4s", "4h", 2972259698Sdim opnode, int_arm_neon_vqdmull, 2973259698Sdim VPR64, v4i32, v4i16>; 2974259698Sdim def _2d2s : NeonI_3VDL2_3Op_mlas<0b0, u, 0b10, opcode, asmop, "2d", "2s", 2975259698Sdim opnode, int_arm_neon_vqdmull, 2976259698Sdim VPR64, v2i64, v2i32>; 2977259698Sdim} 2978259698Sdim 2979259698Sdimdefm SQDMLALvvv : NeonI_3VDL_qdmlal_3Op_v2<0b0, 0b1001, "sqdmlal", 2980259698Sdim int_arm_neon_vqadds>; 2981259698Sdimdefm SQDMLSLvvv : NeonI_3VDL_qdmlal_3Op_v2<0b0, 0b1011, "sqdmlsl", 2982259698Sdim int_arm_neon_vqsubs>; 2983259698Sdim 2984259698Sdimmulticlass NeonI_3VDL_v2<bit u, bits<4> opcode, string asmop, 2985259698Sdim SDPatternOperator opnode, bit Commutable = 0> { 2986259698Sdim let isCommutable = Commutable in { 2987259698Sdim def _4s4h : NeonI_3VD_2Op<0b0, u, 0b01, opcode, asmop, "4s", "4h", 2988259698Sdim opnode, VPR128, VPR64, v4i32, v4i16>; 2989259698Sdim def _2d2s : NeonI_3VD_2Op<0b0, u, 0b10, opcode, asmop, "2d", "2s", 2990259698Sdim opnode, VPR128, VPR64, v2i64, v2i32>; 2991259698Sdim } 2992259698Sdim} 2993259698Sdim 2994259698Sdimdefm SQDMULLvvv : NeonI_3VDL_v2<0b0, 0b1101, "sqdmull", 2995259698Sdim int_arm_neon_vqdmull, 1>; 2996259698Sdim 2997259698Sdimmulticlass NeonI_3VDL2_2Op_mull_v2<bit u, bits<4> opcode, string asmop, 2998259698Sdim string opnode, bit Commutable = 0> { 2999259698Sdim let isCommutable = Commutable in { 3000259698Sdim def _4s8h : NeonI_3VDL2_2Op_mull<0b1, u, 0b01, opcode, asmop, "4s", "8h", 3001259698Sdim !cast<PatFrag>(opnode # "_8H"), 3002259698Sdim v4i32, v8i16>; 3003259698Sdim def _2d4s : NeonI_3VDL2_2Op_mull<0b1, u, 0b10, opcode, asmop, "2d", "4s", 3004259698Sdim !cast<PatFrag>(opnode # "_4S"), 3005259698Sdim v2i64, v4i32>; 3006259698Sdim } 3007259698Sdim} 3008259698Sdim 3009259698Sdimdefm SQDMULL2vvv : NeonI_3VDL2_2Op_mull_v2<0b0, 0b1101, "sqdmull2", 3010259698Sdim "NI_qdmull_hi", 1>; 3011259698Sdim 3012259698Sdimmulticlass NeonI_3VDL2_3Op_qdmlal_v2<bit u, bits<4> opcode, string asmop, 3013259698Sdim SDPatternOperator opnode> { 3014259698Sdim def _4s8h : NeonI_3VDL2_3Op_mlas<0b1, u, 0b01, opcode, asmop, "4s", "8h", 3015259698Sdim opnode, NI_qdmull_hi_8H, 3016259698Sdim VPR128, v4i32, v8i16>; 3017259698Sdim def _2d4s : NeonI_3VDL2_3Op_mlas<0b1, u, 0b10, opcode, asmop, "2d", "4s", 3018259698Sdim opnode, NI_qdmull_hi_4S, 3019259698Sdim VPR128, v2i64, v4i32>; 3020259698Sdim} 3021259698Sdim 3022259698Sdimdefm SQDMLAL2vvv : NeonI_3VDL2_3Op_qdmlal_v2<0b0, 0b1001, "sqdmlal2", 3023259698Sdim int_arm_neon_vqadds>; 3024259698Sdimdefm SQDMLSL2vvv : NeonI_3VDL2_3Op_qdmlal_v2<0b0, 0b1011, "sqdmlsl2", 3025259698Sdim int_arm_neon_vqsubs>; 3026259698Sdim 3027259698Sdimmulticlass NeonI_3VDL_v3<bit u, bits<4> opcode, string asmop, 3028259698Sdim SDPatternOperator opnode, bit Commutable = 0> { 3029259698Sdim let isCommutable = Commutable in { 3030259698Sdim def _8h8b : NeonI_3VD_2Op<0b0, u, 0b00, opcode, asmop, "8h", "8b", 3031259698Sdim opnode, VPR128, VPR64, v8i16, v8i8>; 3032259698Sdim 3033259698Sdim def _1q1d : NeonI_3VDiff<0b0, u, 0b11, opcode, 3034259698Sdim (outs VPR128:$Rd), (ins VPR64:$Rn, VPR64:$Rm), 3035259698Sdim asmop # "\t$Rd.1q, $Rn.1d, $Rm.1d", 3036259698Sdim [], NoItinerary>; 3037259698Sdim } 3038259698Sdim} 3039259698Sdim 3040259698Sdimdefm PMULLvvv : NeonI_3VDL_v3<0b0, 0b1110, "pmull", int_arm_neon_vmullp, 1>; 3041259698Sdim 3042259698Sdimmulticlass NeonI_3VDL2_2Op_mull_v3<bit u, bits<4> opcode, string asmop, 3043259698Sdim string opnode, bit Commutable = 0> { 3044259698Sdim let isCommutable = Commutable in { 3045259698Sdim def _8h16b : NeonI_3VDL2_2Op_mull<0b1, u, 0b00, opcode, asmop, "8h", "16b", 3046259698Sdim !cast<PatFrag>(opnode # "_16B"), 3047259698Sdim v8i16, v16i8>; 3048259698Sdim 3049259698Sdim def _1q2d : NeonI_3VDiff<0b1, u, 0b11, opcode, 3050259698Sdim (outs VPR128:$Rd), (ins VPR128:$Rn, VPR128:$Rm), 3051259698Sdim asmop # "\t$Rd.1q, $Rn.2d, $Rm.2d", 3052259698Sdim [], NoItinerary>; 3053259698Sdim } 3054259698Sdim} 3055259698Sdim 3056259698Sdimdefm PMULL2vvv : NeonI_3VDL2_2Op_mull_v3<0b0, 0b1110, "pmull2", "NI_pmull_hi", 3057259698Sdim 1>; 3058259698Sdim 3059259698Sdim// End of implementation for instruction class (3V Diff) 3060259698Sdim 3061259698Sdim// The followings are vector load/store multiple N-element structure 3062259698Sdim// (class SIMD lselem). 3063259698Sdim 3064259698Sdim// ld1: load multiple 1-element structure to 1/2/3/4 registers. 3065259698Sdim// ld2/ld3/ld4: load multiple N-element structure to N registers (N = 2, 3, 4). 3066259698Sdim// The structure consists of a sequence of sets of N values. 3067259698Sdim// The first element of the structure is placed in the first lane 3068259698Sdim// of the first first vector, the second element in the first lane 3069259698Sdim// of the second vector, and so on. 3070259698Sdim// E.g. LD1_3V_2S will load 32-bit elements {A, B, C, D, E, F} sequentially into 3071259698Sdim// the three 64-bit vectors list {BA, DC, FE}. 3072259698Sdim// E.g. LD3_2S will load 32-bit elements {A, B, C, D, E, F} into the three 3073259698Sdim// 64-bit vectors list {DA, EB, FC}. 3074259698Sdim// Store instructions store multiple structure to N registers like load. 3075259698Sdim 3076259698Sdim 3077259698Sdimclass NeonI_LDVList<bit q, bits<4> opcode, bits<2> size, 3078259698Sdim RegisterOperand VecList, string asmop> 3079259698Sdim : NeonI_LdStMult<q, 1, opcode, size, 3080259698Sdim (outs VecList:$Rt), (ins GPR64xsp:$Rn), 3081259698Sdim asmop # "\t$Rt, [$Rn]", 3082259698Sdim [], 3083259698Sdim NoItinerary> { 3084259698Sdim let mayLoad = 1; 3085259698Sdim let neverHasSideEffects = 1; 3086259698Sdim} 3087259698Sdim 3088259698Sdimmulticlass LDVList_BHSD<bits<4> opcode, string List, string asmop> { 3089259698Sdim def _8B : NeonI_LDVList<0, opcode, 0b00, 3090259698Sdim !cast<RegisterOperand>(List # "8B_operand"), asmop>; 3091259698Sdim 3092259698Sdim def _4H : NeonI_LDVList<0, opcode, 0b01, 3093259698Sdim !cast<RegisterOperand>(List # "4H_operand"), asmop>; 3094259698Sdim 3095259698Sdim def _2S : NeonI_LDVList<0, opcode, 0b10, 3096259698Sdim !cast<RegisterOperand>(List # "2S_operand"), asmop>; 3097259698Sdim 3098259698Sdim def _16B : NeonI_LDVList<1, opcode, 0b00, 3099259698Sdim !cast<RegisterOperand>(List # "16B_operand"), asmop>; 3100259698Sdim 3101259698Sdim def _8H : NeonI_LDVList<1, opcode, 0b01, 3102259698Sdim !cast<RegisterOperand>(List # "8H_operand"), asmop>; 3103259698Sdim 3104259698Sdim def _4S : NeonI_LDVList<1, opcode, 0b10, 3105259698Sdim !cast<RegisterOperand>(List # "4S_operand"), asmop>; 3106259698Sdim 3107259698Sdim def _2D : NeonI_LDVList<1, opcode, 0b11, 3108259698Sdim !cast<RegisterOperand>(List # "2D_operand"), asmop>; 3109259698Sdim} 3110259698Sdim 3111259698Sdim// Load multiple N-element structure to N consecutive registers (N = 1,2,3,4) 3112259698Sdimdefm LD1 : LDVList_BHSD<0b0111, "VOne", "ld1">; 3113259698Sdimdef LD1_1D : NeonI_LDVList<0, 0b0111, 0b11, VOne1D_operand, "ld1">; 3114259698Sdim 3115259698Sdimdefm LD2 : LDVList_BHSD<0b1000, "VPair", "ld2">; 3116259698Sdim 3117259698Sdimdefm LD3 : LDVList_BHSD<0b0100, "VTriple", "ld3">; 3118259698Sdim 3119259698Sdimdefm LD4 : LDVList_BHSD<0b0000, "VQuad", "ld4">; 3120259698Sdim 3121259698Sdim// Load multiple 1-element structure to N consecutive registers (N = 2,3,4) 3122259698Sdimdefm LD1x2 : LDVList_BHSD<0b1010, "VPair", "ld1">; 3123259698Sdimdef LD1x2_1D : NeonI_LDVList<0, 0b1010, 0b11, VPair1D_operand, "ld1">; 3124259698Sdim 3125259698Sdimdefm LD1x3 : LDVList_BHSD<0b0110, "VTriple", "ld1">; 3126259698Sdimdef LD1x3_1D : NeonI_LDVList<0, 0b0110, 0b11, VTriple1D_operand, "ld1">; 3127259698Sdim 3128259698Sdimdefm LD1x4 : LDVList_BHSD<0b0010, "VQuad", "ld1">; 3129259698Sdimdef LD1x4_1D : NeonI_LDVList<0, 0b0010, 0b11, VQuad1D_operand, "ld1">; 3130259698Sdim 3131259698Sdimclass NeonI_STVList<bit q, bits<4> opcode, bits<2> size, 3132259698Sdim RegisterOperand VecList, string asmop> 3133259698Sdim : NeonI_LdStMult<q, 0, opcode, size, 3134259698Sdim (outs), (ins GPR64xsp:$Rn, VecList:$Rt), 3135259698Sdim asmop # "\t$Rt, [$Rn]", 3136259698Sdim [], 3137259698Sdim NoItinerary> { 3138259698Sdim let mayStore = 1; 3139259698Sdim let neverHasSideEffects = 1; 3140259698Sdim} 3141259698Sdim 3142259698Sdimmulticlass STVList_BHSD<bits<4> opcode, string List, string asmop> { 3143259698Sdim def _8B : NeonI_STVList<0, opcode, 0b00, 3144259698Sdim !cast<RegisterOperand>(List # "8B_operand"), asmop>; 3145259698Sdim 3146259698Sdim def _4H : NeonI_STVList<0, opcode, 0b01, 3147259698Sdim !cast<RegisterOperand>(List # "4H_operand"), asmop>; 3148259698Sdim 3149259698Sdim def _2S : NeonI_STVList<0, opcode, 0b10, 3150259698Sdim !cast<RegisterOperand>(List # "2S_operand"), asmop>; 3151259698Sdim 3152259698Sdim def _16B : NeonI_STVList<1, opcode, 0b00, 3153259698Sdim !cast<RegisterOperand>(List # "16B_operand"), asmop>; 3154259698Sdim 3155259698Sdim def _8H : NeonI_STVList<1, opcode, 0b01, 3156259698Sdim !cast<RegisterOperand>(List # "8H_operand"), asmop>; 3157259698Sdim 3158259698Sdim def _4S : NeonI_STVList<1, opcode, 0b10, 3159259698Sdim !cast<RegisterOperand>(List # "4S_operand"), asmop>; 3160259698Sdim 3161259698Sdim def _2D : NeonI_STVList<1, opcode, 0b11, 3162259698Sdim !cast<RegisterOperand>(List # "2D_operand"), asmop>; 3163259698Sdim} 3164259698Sdim 3165259698Sdim// Store multiple N-element structures from N registers (N = 1,2,3,4) 3166259698Sdimdefm ST1 : STVList_BHSD<0b0111, "VOne", "st1">; 3167259698Sdimdef ST1_1D : NeonI_STVList<0, 0b0111, 0b11, VOne1D_operand, "st1">; 3168259698Sdim 3169259698Sdimdefm ST2 : STVList_BHSD<0b1000, "VPair", "st2">; 3170259698Sdim 3171259698Sdimdefm ST3 : STVList_BHSD<0b0100, "VTriple", "st3">; 3172259698Sdim 3173259698Sdimdefm ST4 : STVList_BHSD<0b0000, "VQuad", "st4">; 3174259698Sdim 3175259698Sdim// Store multiple 1-element structures from N consecutive registers (N = 2,3,4) 3176259698Sdimdefm ST1x2 : STVList_BHSD<0b1010, "VPair", "st1">; 3177259698Sdimdef ST1x2_1D : NeonI_STVList<0, 0b1010, 0b11, VPair1D_operand, "st1">; 3178259698Sdim 3179259698Sdimdefm ST1x3 : STVList_BHSD<0b0110, "VTriple", "st1">; 3180259698Sdimdef ST1x3_1D : NeonI_STVList<0, 0b0110, 0b11, VTriple1D_operand, "st1">; 3181259698Sdim 3182259698Sdimdefm ST1x4 : STVList_BHSD<0b0010, "VQuad", "st1">; 3183259698Sdimdef ST1x4_1D : NeonI_STVList<0, 0b0010, 0b11, VQuad1D_operand, "st1">; 3184259698Sdim 3185259698Sdimdef : Pat<(v2f64 (load GPR64xsp:$addr)), (LD1_2D GPR64xsp:$addr)>; 3186259698Sdimdef : Pat<(v2i64 (load GPR64xsp:$addr)), (LD1_2D GPR64xsp:$addr)>; 3187259698Sdim 3188259698Sdimdef : Pat<(v4f32 (load GPR64xsp:$addr)), (LD1_4S GPR64xsp:$addr)>; 3189259698Sdimdef : Pat<(v4i32 (load GPR64xsp:$addr)), (LD1_4S GPR64xsp:$addr)>; 3190259698Sdim 3191259698Sdimdef : Pat<(v8i16 (load GPR64xsp:$addr)), (LD1_8H GPR64xsp:$addr)>; 3192259698Sdimdef : Pat<(v16i8 (load GPR64xsp:$addr)), (LD1_16B GPR64xsp:$addr)>; 3193259698Sdim 3194259698Sdimdef : Pat<(v1f64 (load GPR64xsp:$addr)), (LD1_1D GPR64xsp:$addr)>; 3195259698Sdimdef : Pat<(v1i64 (load GPR64xsp:$addr)), (LD1_1D GPR64xsp:$addr)>; 3196259698Sdim 3197259698Sdimdef : Pat<(v2f32 (load GPR64xsp:$addr)), (LD1_2S GPR64xsp:$addr)>; 3198259698Sdimdef : Pat<(v2i32 (load GPR64xsp:$addr)), (LD1_2S GPR64xsp:$addr)>; 3199259698Sdim 3200259698Sdimdef : Pat<(v4i16 (load GPR64xsp:$addr)), (LD1_4H GPR64xsp:$addr)>; 3201259698Sdimdef : Pat<(v8i8 (load GPR64xsp:$addr)), (LD1_8B GPR64xsp:$addr)>; 3202259698Sdim 3203259698Sdimdef : Pat<(store (v2i64 VPR128:$value), GPR64xsp:$addr), 3204259698Sdim (ST1_2D GPR64xsp:$addr, VPR128:$value)>; 3205259698Sdimdef : Pat<(store (v2f64 VPR128:$value), GPR64xsp:$addr), 3206259698Sdim (ST1_2D GPR64xsp:$addr, VPR128:$value)>; 3207259698Sdim 3208259698Sdimdef : Pat<(store (v4i32 VPR128:$value), GPR64xsp:$addr), 3209259698Sdim (ST1_4S GPR64xsp:$addr, VPR128:$value)>; 3210259698Sdimdef : Pat<(store (v4f32 VPR128:$value), GPR64xsp:$addr), 3211259698Sdim (ST1_4S GPR64xsp:$addr, VPR128:$value)>; 3212259698Sdim 3213259698Sdimdef : Pat<(store (v8i16 VPR128:$value), GPR64xsp:$addr), 3214259698Sdim (ST1_8H GPR64xsp:$addr, VPR128:$value)>; 3215259698Sdimdef : Pat<(store (v16i8 VPR128:$value), GPR64xsp:$addr), 3216259698Sdim (ST1_16B GPR64xsp:$addr, VPR128:$value)>; 3217259698Sdim 3218259698Sdimdef : Pat<(store (v1i64 VPR64:$value), GPR64xsp:$addr), 3219259698Sdim (ST1_1D GPR64xsp:$addr, VPR64:$value)>; 3220259698Sdimdef : Pat<(store (v1f64 VPR64:$value), GPR64xsp:$addr), 3221259698Sdim (ST1_1D GPR64xsp:$addr, VPR64:$value)>; 3222259698Sdim 3223259698Sdimdef : Pat<(store (v2i32 VPR64:$value), GPR64xsp:$addr), 3224259698Sdim (ST1_2S GPR64xsp:$addr, VPR64:$value)>; 3225259698Sdimdef : Pat<(store (v2f32 VPR64:$value), GPR64xsp:$addr), 3226259698Sdim (ST1_2S GPR64xsp:$addr, VPR64:$value)>; 3227259698Sdim 3228259698Sdimdef : Pat<(store (v4i16 VPR64:$value), GPR64xsp:$addr), 3229259698Sdim (ST1_4H GPR64xsp:$addr, VPR64:$value)>; 3230259698Sdimdef : Pat<(store (v8i8 VPR64:$value), GPR64xsp:$addr), 3231259698Sdim (ST1_8B GPR64xsp:$addr, VPR64:$value)>; 3232259698Sdim 3233259698Sdim// End of vector load/store multiple N-element structure(class SIMD lselem) 3234259698Sdim 3235259698Sdim// The followings are post-index vector load/store multiple N-element 3236259698Sdim// structure(class SIMD lselem-post) 3237259698Sdimdef exact1_asmoperand : AsmOperandClass { 3238259698Sdim let Name = "Exact1"; 3239259698Sdim let PredicateMethod = "isExactImm<1>"; 3240259698Sdim let RenderMethod = "addImmOperands"; 3241259698Sdim} 3242259698Sdimdef uimm_exact1 : Operand<i32>, ImmLeaf<i32, [{return Imm == 1;}]> { 3243259698Sdim let ParserMatchClass = exact1_asmoperand; 3244259698Sdim} 3245259698Sdim 3246259698Sdimdef exact2_asmoperand : AsmOperandClass { 3247259698Sdim let Name = "Exact2"; 3248259698Sdim let PredicateMethod = "isExactImm<2>"; 3249259698Sdim let RenderMethod = "addImmOperands"; 3250259698Sdim} 3251259698Sdimdef uimm_exact2 : Operand<i32>, ImmLeaf<i32, [{return Imm == 2;}]> { 3252259698Sdim let ParserMatchClass = exact2_asmoperand; 3253259698Sdim} 3254259698Sdim 3255259698Sdimdef exact3_asmoperand : AsmOperandClass { 3256259698Sdim let Name = "Exact3"; 3257259698Sdim let PredicateMethod = "isExactImm<3>"; 3258259698Sdim let RenderMethod = "addImmOperands"; 3259259698Sdim} 3260259698Sdimdef uimm_exact3 : Operand<i32>, ImmLeaf<i32, [{return Imm == 3;}]> { 3261259698Sdim let ParserMatchClass = exact3_asmoperand; 3262259698Sdim} 3263259698Sdim 3264259698Sdimdef exact4_asmoperand : AsmOperandClass { 3265259698Sdim let Name = "Exact4"; 3266259698Sdim let PredicateMethod = "isExactImm<4>"; 3267259698Sdim let RenderMethod = "addImmOperands"; 3268259698Sdim} 3269259698Sdimdef uimm_exact4 : Operand<i32>, ImmLeaf<i32, [{return Imm == 4;}]> { 3270259698Sdim let ParserMatchClass = exact4_asmoperand; 3271259698Sdim} 3272259698Sdim 3273259698Sdimdef exact6_asmoperand : AsmOperandClass { 3274259698Sdim let Name = "Exact6"; 3275259698Sdim let PredicateMethod = "isExactImm<6>"; 3276259698Sdim let RenderMethod = "addImmOperands"; 3277259698Sdim} 3278259698Sdimdef uimm_exact6 : Operand<i32>, ImmLeaf<i32, [{return Imm == 6;}]> { 3279259698Sdim let ParserMatchClass = exact6_asmoperand; 3280259698Sdim} 3281259698Sdim 3282259698Sdimdef exact8_asmoperand : AsmOperandClass { 3283259698Sdim let Name = "Exact8"; 3284259698Sdim let PredicateMethod = "isExactImm<8>"; 3285259698Sdim let RenderMethod = "addImmOperands"; 3286259698Sdim} 3287259698Sdimdef uimm_exact8 : Operand<i32>, ImmLeaf<i32, [{return Imm == 8;}]> { 3288259698Sdim let ParserMatchClass = exact8_asmoperand; 3289259698Sdim} 3290259698Sdim 3291259698Sdimdef exact12_asmoperand : AsmOperandClass { 3292259698Sdim let Name = "Exact12"; 3293259698Sdim let PredicateMethod = "isExactImm<12>"; 3294259698Sdim let RenderMethod = "addImmOperands"; 3295259698Sdim} 3296259698Sdimdef uimm_exact12 : Operand<i32>, ImmLeaf<i32, [{return Imm == 12;}]> { 3297259698Sdim let ParserMatchClass = exact12_asmoperand; 3298259698Sdim} 3299259698Sdim 3300259698Sdimdef exact16_asmoperand : AsmOperandClass { 3301259698Sdim let Name = "Exact16"; 3302259698Sdim let PredicateMethod = "isExactImm<16>"; 3303259698Sdim let RenderMethod = "addImmOperands"; 3304259698Sdim} 3305259698Sdimdef uimm_exact16 : Operand<i32>, ImmLeaf<i32, [{return Imm == 16;}]> { 3306259698Sdim let ParserMatchClass = exact16_asmoperand; 3307259698Sdim} 3308259698Sdim 3309259698Sdimdef exact24_asmoperand : AsmOperandClass { 3310259698Sdim let Name = "Exact24"; 3311259698Sdim let PredicateMethod = "isExactImm<24>"; 3312259698Sdim let RenderMethod = "addImmOperands"; 3313259698Sdim} 3314259698Sdimdef uimm_exact24 : Operand<i32>, ImmLeaf<i32, [{return Imm == 24;}]> { 3315259698Sdim let ParserMatchClass = exact24_asmoperand; 3316259698Sdim} 3317259698Sdim 3318259698Sdimdef exact32_asmoperand : AsmOperandClass { 3319259698Sdim let Name = "Exact32"; 3320259698Sdim let PredicateMethod = "isExactImm<32>"; 3321259698Sdim let RenderMethod = "addImmOperands"; 3322259698Sdim} 3323259698Sdimdef uimm_exact32 : Operand<i32>, ImmLeaf<i32, [{return Imm == 32;}]> { 3324259698Sdim let ParserMatchClass = exact32_asmoperand; 3325259698Sdim} 3326259698Sdim 3327259698Sdimdef exact48_asmoperand : AsmOperandClass { 3328259698Sdim let Name = "Exact48"; 3329259698Sdim let PredicateMethod = "isExactImm<48>"; 3330259698Sdim let RenderMethod = "addImmOperands"; 3331259698Sdim} 3332259698Sdimdef uimm_exact48 : Operand<i32>, ImmLeaf<i32, [{return Imm == 48;}]> { 3333259698Sdim let ParserMatchClass = exact48_asmoperand; 3334259698Sdim} 3335259698Sdim 3336259698Sdimdef exact64_asmoperand : AsmOperandClass { 3337259698Sdim let Name = "Exact64"; 3338259698Sdim let PredicateMethod = "isExactImm<64>"; 3339259698Sdim let RenderMethod = "addImmOperands"; 3340259698Sdim} 3341259698Sdimdef uimm_exact64 : Operand<i32>, ImmLeaf<i32, [{return Imm == 64;}]> { 3342259698Sdim let ParserMatchClass = exact64_asmoperand; 3343259698Sdim} 3344259698Sdim 3345259698Sdimmulticlass NeonI_LDWB_VList<bit q, bits<4> opcode, bits<2> size, 3346259698Sdim RegisterOperand VecList, Operand ImmTy, 3347259698Sdim string asmop> { 3348259698Sdim let Constraints = "$Rn = $wb", mayLoad = 1, neverHasSideEffects = 1, 3349259698Sdim DecoderMethod = "DecodeVLDSTPostInstruction" in { 3350259698Sdim def _fixed : NeonI_LdStMult_Post<q, 1, opcode, size, 3351259698Sdim (outs VecList:$Rt, GPR64xsp:$wb), 3352259698Sdim (ins GPR64xsp:$Rn, ImmTy:$amt), 3353259698Sdim asmop # "\t$Rt, [$Rn], $amt", 3354259698Sdim [], 3355259698Sdim NoItinerary> { 3356259698Sdim let Rm = 0b11111; 3357259698Sdim } 3358259698Sdim 3359259698Sdim def _register : NeonI_LdStMult_Post<q, 1, opcode, size, 3360259698Sdim (outs VecList:$Rt, GPR64xsp:$wb), 3361259698Sdim (ins GPR64xsp:$Rn, GPR64noxzr:$Rm), 3362259698Sdim asmop # "\t$Rt, [$Rn], $Rm", 3363259698Sdim [], 3364259698Sdim NoItinerary>; 3365259698Sdim } 3366259698Sdim} 3367259698Sdim 3368259698Sdimmulticlass LDWB_VList_BHSD<bits<4> opcode, string List, Operand ImmTy, 3369259698Sdim Operand ImmTy2, string asmop> { 3370259698Sdim defm _8B : NeonI_LDWB_VList<0, opcode, 0b00, 3371259698Sdim !cast<RegisterOperand>(List # "8B_operand"), 3372259698Sdim ImmTy, asmop>; 3373259698Sdim 3374259698Sdim defm _4H : NeonI_LDWB_VList<0, opcode, 0b01, 3375259698Sdim !cast<RegisterOperand>(List # "4H_operand"), 3376259698Sdim ImmTy, asmop>; 3377259698Sdim 3378259698Sdim defm _2S : NeonI_LDWB_VList<0, opcode, 0b10, 3379259698Sdim !cast<RegisterOperand>(List # "2S_operand"), 3380259698Sdim ImmTy, asmop>; 3381259698Sdim 3382259698Sdim defm _16B : NeonI_LDWB_VList<1, opcode, 0b00, 3383259698Sdim !cast<RegisterOperand>(List # "16B_operand"), 3384259698Sdim ImmTy2, asmop>; 3385259698Sdim 3386259698Sdim defm _8H : NeonI_LDWB_VList<1, opcode, 0b01, 3387259698Sdim !cast<RegisterOperand>(List # "8H_operand"), 3388259698Sdim ImmTy2, asmop>; 3389259698Sdim 3390259698Sdim defm _4S : NeonI_LDWB_VList<1, opcode, 0b10, 3391259698Sdim !cast<RegisterOperand>(List # "4S_operand"), 3392259698Sdim ImmTy2, asmop>; 3393259698Sdim 3394259698Sdim defm _2D : NeonI_LDWB_VList<1, opcode, 0b11, 3395259698Sdim !cast<RegisterOperand>(List # "2D_operand"), 3396259698Sdim ImmTy2, asmop>; 3397259698Sdim} 3398259698Sdim 3399259698Sdim// Post-index load multiple N-element structures from N registers (N = 1,2,3,4) 3400259698Sdimdefm LD1WB : LDWB_VList_BHSD<0b0111, "VOne", uimm_exact8, uimm_exact16, "ld1">; 3401259698Sdimdefm LD1WB_1D : NeonI_LDWB_VList<0, 0b0111, 0b11, VOne1D_operand, uimm_exact8, 3402259698Sdim "ld1">; 3403259698Sdim 3404259698Sdimdefm LD2WB : LDWB_VList_BHSD<0b1000, "VPair", uimm_exact16, uimm_exact32, "ld2">; 3405259698Sdim 3406259698Sdimdefm LD3WB : LDWB_VList_BHSD<0b0100, "VTriple", uimm_exact24, uimm_exact48, 3407259698Sdim "ld3">; 3408259698Sdim 3409259698Sdimdefm LD4WB : LDWB_VList_BHSD<0b0000, "VQuad", uimm_exact32, uimm_exact64, "ld4">; 3410259698Sdim 3411259698Sdim// Post-index load multiple 1-element structures from N consecutive registers 3412259698Sdim// (N = 2,3,4) 3413259698Sdimdefm LD1x2WB : LDWB_VList_BHSD<0b1010, "VPair", uimm_exact16, uimm_exact32, 3414259698Sdim "ld1">; 3415259698Sdimdefm LD1x2WB_1D : NeonI_LDWB_VList<0, 0b1010, 0b11, VPair1D_operand, 3416259698Sdim uimm_exact16, "ld1">; 3417259698Sdim 3418259698Sdimdefm LD1x3WB : LDWB_VList_BHSD<0b0110, "VTriple", uimm_exact24, uimm_exact48, 3419259698Sdim "ld1">; 3420259698Sdimdefm LD1x3WB_1D : NeonI_LDWB_VList<0, 0b0110, 0b11, VTriple1D_operand, 3421259698Sdim uimm_exact24, "ld1">; 3422259698Sdim 3423259698Sdimdefm LD1x4WB : LDWB_VList_BHSD<0b0010, "VQuad", uimm_exact32, uimm_exact64, 3424259698Sdim "ld1">; 3425259698Sdimdefm LD1x4WB_1D : NeonI_LDWB_VList<0, 0b0010, 0b11, VQuad1D_operand, 3426259698Sdim uimm_exact32, "ld1">; 3427259698Sdim 3428259698Sdimmulticlass NeonI_STWB_VList<bit q, bits<4> opcode, bits<2> size, 3429259698Sdim RegisterOperand VecList, Operand ImmTy, 3430259698Sdim string asmop> { 3431259698Sdim let Constraints = "$Rn = $wb", mayStore = 1, neverHasSideEffects = 1, 3432259698Sdim DecoderMethod = "DecodeVLDSTPostInstruction" in { 3433259698Sdim def _fixed : NeonI_LdStMult_Post<q, 0, opcode, size, 3434259698Sdim (outs GPR64xsp:$wb), 3435259698Sdim (ins GPR64xsp:$Rn, ImmTy:$amt, VecList:$Rt), 3436259698Sdim asmop # "\t$Rt, [$Rn], $amt", 3437259698Sdim [], 3438259698Sdim NoItinerary> { 3439259698Sdim let Rm = 0b11111; 3440259698Sdim } 3441259698Sdim 3442259698Sdim def _register : NeonI_LdStMult_Post<q, 0, opcode, size, 3443259698Sdim (outs GPR64xsp:$wb), 3444259698Sdim (ins GPR64xsp:$Rn, GPR64noxzr:$Rm, VecList:$Rt), 3445259698Sdim asmop # "\t$Rt, [$Rn], $Rm", 3446259698Sdim [], 3447259698Sdim NoItinerary>; 3448259698Sdim } 3449259698Sdim} 3450259698Sdim 3451259698Sdimmulticlass STWB_VList_BHSD<bits<4> opcode, string List, Operand ImmTy, 3452259698Sdim Operand ImmTy2, string asmop> { 3453259698Sdim defm _8B : NeonI_STWB_VList<0, opcode, 0b00, 3454259698Sdim !cast<RegisterOperand>(List # "8B_operand"), ImmTy, asmop>; 3455259698Sdim 3456259698Sdim defm _4H : NeonI_STWB_VList<0, opcode, 0b01, 3457259698Sdim !cast<RegisterOperand>(List # "4H_operand"), 3458259698Sdim ImmTy, asmop>; 3459259698Sdim 3460259698Sdim defm _2S : NeonI_STWB_VList<0, opcode, 0b10, 3461259698Sdim !cast<RegisterOperand>(List # "2S_operand"), 3462259698Sdim ImmTy, asmop>; 3463259698Sdim 3464259698Sdim defm _16B : NeonI_STWB_VList<1, opcode, 0b00, 3465259698Sdim !cast<RegisterOperand>(List # "16B_operand"), 3466259698Sdim ImmTy2, asmop>; 3467259698Sdim 3468259698Sdim defm _8H : NeonI_STWB_VList<1, opcode, 0b01, 3469259698Sdim !cast<RegisterOperand>(List # "8H_operand"), 3470259698Sdim ImmTy2, asmop>; 3471259698Sdim 3472259698Sdim defm _4S : NeonI_STWB_VList<1, opcode, 0b10, 3473259698Sdim !cast<RegisterOperand>(List # "4S_operand"), 3474259698Sdim ImmTy2, asmop>; 3475259698Sdim 3476259698Sdim defm _2D : NeonI_STWB_VList<1, opcode, 0b11, 3477259698Sdim !cast<RegisterOperand>(List # "2D_operand"), 3478259698Sdim ImmTy2, asmop>; 3479259698Sdim} 3480259698Sdim 3481259698Sdim// Post-index load multiple N-element structures from N registers (N = 1,2,3,4) 3482259698Sdimdefm ST1WB : STWB_VList_BHSD<0b0111, "VOne", uimm_exact8, uimm_exact16, "st1">; 3483259698Sdimdefm ST1WB_1D : NeonI_STWB_VList<0, 0b0111, 0b11, VOne1D_operand, uimm_exact8, 3484259698Sdim "st1">; 3485259698Sdim 3486259698Sdimdefm ST2WB : STWB_VList_BHSD<0b1000, "VPair", uimm_exact16, uimm_exact32, "st2">; 3487259698Sdim 3488259698Sdimdefm ST3WB : STWB_VList_BHSD<0b0100, "VTriple", uimm_exact24, uimm_exact48, 3489259698Sdim "st3">; 3490259698Sdim 3491259698Sdimdefm ST4WB : STWB_VList_BHSD<0b0000, "VQuad", uimm_exact32, uimm_exact64, "st4">; 3492259698Sdim 3493259698Sdim// Post-index load multiple 1-element structures from N consecutive registers 3494259698Sdim// (N = 2,3,4) 3495259698Sdimdefm ST1x2WB : STWB_VList_BHSD<0b1010, "VPair", uimm_exact16, uimm_exact32, 3496259698Sdim "st1">; 3497259698Sdimdefm ST1x2WB_1D : NeonI_STWB_VList<0, 0b1010, 0b11, VPair1D_operand, 3498259698Sdim uimm_exact16, "st1">; 3499259698Sdim 3500259698Sdimdefm ST1x3WB : STWB_VList_BHSD<0b0110, "VTriple", uimm_exact24, uimm_exact48, 3501259698Sdim "st1">; 3502259698Sdimdefm ST1x3WB_1D : NeonI_STWB_VList<0, 0b0110, 0b11, VTriple1D_operand, 3503259698Sdim uimm_exact24, "st1">; 3504259698Sdim 3505259698Sdimdefm ST1x4WB : STWB_VList_BHSD<0b0010, "VQuad", uimm_exact32, uimm_exact64, 3506259698Sdim "st1">; 3507259698Sdimdefm ST1x4WB_1D : NeonI_STWB_VList<0, 0b0010, 0b11, VQuad1D_operand, 3508259698Sdim uimm_exact32, "st1">; 3509259698Sdim 3510259698Sdim// End of post-index vector load/store multiple N-element structure 3511259698Sdim// (class SIMD lselem-post) 3512259698Sdim 3513259698Sdim// The followings are vector load/store single N-element structure 3514259698Sdim// (class SIMD lsone). 3515259698Sdimdef neon_uimm0_bare : Operand<i64>, 3516259698Sdim ImmLeaf<i64, [{return Imm == 0;}]> { 3517259698Sdim let ParserMatchClass = neon_uimm0_asmoperand; 3518259698Sdim let PrintMethod = "printUImmBareOperand"; 3519259698Sdim} 3520259698Sdim 3521259698Sdimdef neon_uimm1_bare : Operand<i64>, 3522259698Sdim ImmLeaf<i64, [{return Imm < 2;}]> { 3523259698Sdim let ParserMatchClass = neon_uimm1_asmoperand; 3524259698Sdim let PrintMethod = "printUImmBareOperand"; 3525259698Sdim} 3526259698Sdim 3527259698Sdimdef neon_uimm2_bare : Operand<i64>, 3528259698Sdim ImmLeaf<i64, [{return Imm < 4;}]> { 3529259698Sdim let ParserMatchClass = neon_uimm2_asmoperand; 3530259698Sdim let PrintMethod = "printUImmBareOperand"; 3531259698Sdim} 3532259698Sdim 3533259698Sdimdef neon_uimm3_bare : Operand<i64>, 3534259698Sdim ImmLeaf<i64, [{return Imm < 8;}]> { 3535259698Sdim let ParserMatchClass = uimm3_asmoperand; 3536259698Sdim let PrintMethod = "printUImmBareOperand"; 3537259698Sdim} 3538259698Sdim 3539259698Sdimdef neon_uimm4_bare : Operand<i64>, 3540259698Sdim ImmLeaf<i64, [{return Imm < 16;}]> { 3541259698Sdim let ParserMatchClass = uimm4_asmoperand; 3542259698Sdim let PrintMethod = "printUImmBareOperand"; 3543259698Sdim} 3544259698Sdim 3545259698Sdimclass NeonI_LDN_Dup<bit q, bit r, bits<3> opcode, bits<2> size, 3546259698Sdim RegisterOperand VecList, string asmop> 3547259698Sdim : NeonI_LdOne_Dup<q, r, opcode, size, 3548259698Sdim (outs VecList:$Rt), (ins GPR64xsp:$Rn), 3549259698Sdim asmop # "\t$Rt, [$Rn]", 3550259698Sdim [], 3551259698Sdim NoItinerary> { 3552259698Sdim let mayLoad = 1; 3553259698Sdim let neverHasSideEffects = 1; 3554259698Sdim} 3555259698Sdim 3556259698Sdimmulticlass LDN_Dup_BHSD<bit r, bits<3> opcode, string List, string asmop> { 3557259698Sdim def _8B : NeonI_LDN_Dup<0, r, opcode, 0b00, 3558259698Sdim !cast<RegisterOperand>(List # "8B_operand"), asmop>; 3559259698Sdim 3560259698Sdim def _4H : NeonI_LDN_Dup<0, r, opcode, 0b01, 3561259698Sdim !cast<RegisterOperand>(List # "4H_operand"), asmop>; 3562259698Sdim 3563259698Sdim def _2S : NeonI_LDN_Dup<0, r, opcode, 0b10, 3564259698Sdim !cast<RegisterOperand>(List # "2S_operand"), asmop>; 3565259698Sdim 3566259698Sdim def _1D : NeonI_LDN_Dup<0, r, opcode, 0b11, 3567259698Sdim !cast<RegisterOperand>(List # "1D_operand"), asmop>; 3568259698Sdim 3569259698Sdim def _16B : NeonI_LDN_Dup<1, r, opcode, 0b00, 3570259698Sdim !cast<RegisterOperand>(List # "16B_operand"), asmop>; 3571259698Sdim 3572259698Sdim def _8H : NeonI_LDN_Dup<1, r, opcode, 0b01, 3573259698Sdim !cast<RegisterOperand>(List # "8H_operand"), asmop>; 3574259698Sdim 3575259698Sdim def _4S : NeonI_LDN_Dup<1, r, opcode, 0b10, 3576259698Sdim !cast<RegisterOperand>(List # "4S_operand"), asmop>; 3577259698Sdim 3578259698Sdim def _2D : NeonI_LDN_Dup<1, r, opcode, 0b11, 3579259698Sdim !cast<RegisterOperand>(List # "2D_operand"), asmop>; 3580259698Sdim} 3581259698Sdim 3582259698Sdim// Load single 1-element structure to all lanes of 1 register 3583259698Sdimdefm LD1R : LDN_Dup_BHSD<0b0, 0b110, "VOne", "ld1r">; 3584259698Sdim 3585259698Sdim// Load single N-element structure to all lanes of N consecutive 3586259698Sdim// registers (N = 2,3,4) 3587259698Sdimdefm LD2R : LDN_Dup_BHSD<0b1, 0b110, "VPair", "ld2r">; 3588259698Sdimdefm LD3R : LDN_Dup_BHSD<0b0, 0b111, "VTriple", "ld3r">; 3589259698Sdimdefm LD4R : LDN_Dup_BHSD<0b1, 0b111, "VQuad", "ld4r">; 3590259698Sdim 3591259698Sdim 3592259698Sdimclass LD1R_pattern <ValueType VTy, ValueType DTy, PatFrag LoadOp, 3593259698Sdim Instruction INST> 3594259698Sdim : Pat<(VTy (Neon_vdup (DTy (LoadOp GPR64xsp:$Rn)))), 3595259698Sdim (VTy (INST GPR64xsp:$Rn))>; 3596259698Sdim 3597259698Sdim// Match all LD1R instructions 3598259698Sdimdef : LD1R_pattern<v8i8, i32, extloadi8, LD1R_8B>; 3599259698Sdim 3600259698Sdimdef : LD1R_pattern<v16i8, i32, extloadi8, LD1R_16B>; 3601259698Sdim 3602259698Sdimdef : LD1R_pattern<v4i16, i32, extloadi16, LD1R_4H>; 3603259698Sdim 3604259698Sdimdef : LD1R_pattern<v8i16, i32, extloadi16, LD1R_8H>; 3605259698Sdim 3606259698Sdimdef : LD1R_pattern<v2i32, i32, load, LD1R_2S>; 3607259698Sdimdef : LD1R_pattern<v2f32, f32, load, LD1R_2S>; 3608259698Sdim 3609259698Sdimdef : LD1R_pattern<v4i32, i32, load, LD1R_4S>; 3610259698Sdimdef : LD1R_pattern<v4f32, f32, load, LD1R_4S>; 3611259698Sdim 3612259698Sdimdef : LD1R_pattern<v1i64, i64, load, LD1R_1D>; 3613259698Sdimdef : LD1R_pattern<v1f64, f64, load, LD1R_1D>; 3614259698Sdim 3615259698Sdimdef : LD1R_pattern<v2i64, i64, load, LD1R_2D>; 3616259698Sdimdef : LD1R_pattern<v2f64, f64, load, LD1R_2D>; 3617259698Sdim 3618259698Sdim 3619259698Sdimmulticlass VectorList_Bare_BHSD<string PREFIX, int Count, 3620259698Sdim RegisterClass RegList> { 3621259698Sdim defm B : VectorList_operands<PREFIX, "B", Count, RegList>; 3622259698Sdim defm H : VectorList_operands<PREFIX, "H", Count, RegList>; 3623259698Sdim defm S : VectorList_operands<PREFIX, "S", Count, RegList>; 3624259698Sdim defm D : VectorList_operands<PREFIX, "D", Count, RegList>; 3625259698Sdim} 3626259698Sdim 3627259698Sdim// Special vector list operand of 128-bit vectors with bare layout. 3628259698Sdim// i.e. only show ".b", ".h", ".s", ".d" 3629259698Sdimdefm VOne : VectorList_Bare_BHSD<"VOne", 1, FPR128>; 3630259698Sdimdefm VPair : VectorList_Bare_BHSD<"VPair", 2, QPair>; 3631259698Sdimdefm VTriple : VectorList_Bare_BHSD<"VTriple", 3, QTriple>; 3632259698Sdimdefm VQuad : VectorList_Bare_BHSD<"VQuad", 4, QQuad>; 3633259698Sdim 3634259698Sdimclass NeonI_LDN_Lane<bit r, bits<2> op2_1, bit op0, RegisterOperand VList, 3635259698Sdim Operand ImmOp, string asmop> 3636259698Sdim : NeonI_LdStOne_Lane<1, r, op2_1, op0, 3637259698Sdim (outs VList:$Rt), 3638259698Sdim (ins GPR64xsp:$Rn, VList:$src, ImmOp:$lane), 3639259698Sdim asmop # "\t$Rt[$lane], [$Rn]", 3640259698Sdim [], 3641259698Sdim NoItinerary> { 3642259698Sdim let mayLoad = 1; 3643259698Sdim let neverHasSideEffects = 1; 3644259698Sdim let hasExtraDefRegAllocReq = 1; 3645259698Sdim let Constraints = "$src = $Rt"; 3646259698Sdim} 3647259698Sdim 3648259698Sdimmulticlass LDN_Lane_BHSD<bit r, bit op0, string List, string asmop> { 3649259698Sdim def _B : NeonI_LDN_Lane<r, 0b00, op0, 3650259698Sdim !cast<RegisterOperand>(List # "B_operand"), 3651259698Sdim neon_uimm4_bare, asmop> { 3652259698Sdim let Inst{12-10} = lane{2-0}; 3653259698Sdim let Inst{30} = lane{3}; 3654259698Sdim } 3655259698Sdim 3656259698Sdim def _H : NeonI_LDN_Lane<r, 0b01, op0, 3657259698Sdim !cast<RegisterOperand>(List # "H_operand"), 3658259698Sdim neon_uimm3_bare, asmop> { 3659259698Sdim let Inst{12-10} = {lane{1}, lane{0}, 0b0}; 3660259698Sdim let Inst{30} = lane{2}; 3661259698Sdim } 3662259698Sdim 3663259698Sdim def _S : NeonI_LDN_Lane<r, 0b10, op0, 3664259698Sdim !cast<RegisterOperand>(List # "S_operand"), 3665259698Sdim neon_uimm2_bare, asmop> { 3666259698Sdim let Inst{12-10} = {lane{0}, 0b0, 0b0}; 3667259698Sdim let Inst{30} = lane{1}; 3668259698Sdim } 3669259698Sdim 3670259698Sdim def _D : NeonI_LDN_Lane<r, 0b10, op0, 3671259698Sdim !cast<RegisterOperand>(List # "D_operand"), 3672259698Sdim neon_uimm1_bare, asmop> { 3673259698Sdim let Inst{12-10} = 0b001; 3674259698Sdim let Inst{30} = lane{0}; 3675259698Sdim } 3676259698Sdim} 3677259698Sdim 3678259698Sdim// Load single 1-element structure to one lane of 1 register. 3679259698Sdimdefm LD1LN : LDN_Lane_BHSD<0b0, 0b0, "VOne", "ld1">; 3680259698Sdim 3681259698Sdim// Load single N-element structure to one lane of N consecutive registers 3682259698Sdim// (N = 2,3,4) 3683259698Sdimdefm LD2LN : LDN_Lane_BHSD<0b1, 0b0, "VPair", "ld2">; 3684259698Sdimdefm LD3LN : LDN_Lane_BHSD<0b0, 0b1, "VTriple", "ld3">; 3685259698Sdimdefm LD4LN : LDN_Lane_BHSD<0b1, 0b1, "VQuad", "ld4">; 3686259698Sdim 3687259698Sdimmulticlass LD1LN_patterns<ValueType VTy, ValueType VTy2, ValueType DTy, 3688259698Sdim Operand ImmOp, Operand ImmOp2, PatFrag LoadOp, 3689259698Sdim Instruction INST> { 3690259698Sdim def : Pat<(VTy (vector_insert (VTy VPR64:$src), 3691259698Sdim (DTy (LoadOp GPR64xsp:$Rn)), (ImmOp:$lane))), 3692259698Sdim (VTy (EXTRACT_SUBREG 3693259698Sdim (INST GPR64xsp:$Rn, 3694259698Sdim (SUBREG_TO_REG (i64 0), VPR64:$src, sub_64), 3695259698Sdim ImmOp:$lane), 3696259698Sdim sub_64))>; 3697259698Sdim 3698259698Sdim def : Pat<(VTy2 (vector_insert (VTy2 VPR128:$src), 3699259698Sdim (DTy (LoadOp GPR64xsp:$Rn)), (ImmOp2:$lane))), 3700259698Sdim (VTy2 (INST GPR64xsp:$Rn, VPR128:$src, ImmOp2:$lane))>; 3701259698Sdim} 3702259698Sdim 3703259698Sdim// Match all LD1LN instructions 3704259698Sdimdefm : LD1LN_patterns<v8i8, v16i8, i32, neon_uimm3_bare, neon_uimm4_bare, 3705259698Sdim extloadi8, LD1LN_B>; 3706259698Sdim 3707259698Sdimdefm : LD1LN_patterns<v4i16, v8i16, i32, neon_uimm2_bare, neon_uimm3_bare, 3708259698Sdim extloadi16, LD1LN_H>; 3709259698Sdim 3710259698Sdimdefm : LD1LN_patterns<v2i32, v4i32, i32, neon_uimm1_bare, neon_uimm2_bare, 3711259698Sdim load, LD1LN_S>; 3712259698Sdimdefm : LD1LN_patterns<v2f32, v4f32, f32, neon_uimm1_bare, neon_uimm2_bare, 3713259698Sdim load, LD1LN_S>; 3714259698Sdim 3715259698Sdimdefm : LD1LN_patterns<v1i64, v2i64, i64, neon_uimm0_bare, neon_uimm1_bare, 3716259698Sdim load, LD1LN_D>; 3717259698Sdimdefm : LD1LN_patterns<v1f64, v2f64, f64, neon_uimm0_bare, neon_uimm1_bare, 3718259698Sdim load, LD1LN_D>; 3719259698Sdim 3720259698Sdimclass NeonI_STN_Lane<bit r, bits<2> op2_1, bit op0, RegisterOperand VList, 3721259698Sdim Operand ImmOp, string asmop> 3722259698Sdim : NeonI_LdStOne_Lane<0, r, op2_1, op0, 3723259698Sdim (outs), (ins GPR64xsp:$Rn, VList:$Rt, ImmOp:$lane), 3724259698Sdim asmop # "\t$Rt[$lane], [$Rn]", 3725259698Sdim [], 3726259698Sdim NoItinerary> { 3727259698Sdim let mayStore = 1; 3728259698Sdim let neverHasSideEffects = 1; 3729259698Sdim let hasExtraDefRegAllocReq = 1; 3730259698Sdim} 3731259698Sdim 3732259698Sdimmulticlass STN_Lane_BHSD<bit r, bit op0, string List, string asmop> { 3733259698Sdim def _B : NeonI_STN_Lane<r, 0b00, op0, 3734259698Sdim !cast<RegisterOperand>(List # "B_operand"), 3735259698Sdim neon_uimm4_bare, asmop> { 3736259698Sdim let Inst{12-10} = lane{2-0}; 3737259698Sdim let Inst{30} = lane{3}; 3738259698Sdim } 3739259698Sdim 3740259698Sdim def _H : NeonI_STN_Lane<r, 0b01, op0, 3741259698Sdim !cast<RegisterOperand>(List # "H_operand"), 3742259698Sdim neon_uimm3_bare, asmop> { 3743259698Sdim let Inst{12-10} = {lane{1}, lane{0}, 0b0}; 3744259698Sdim let Inst{30} = lane{2}; 3745259698Sdim } 3746259698Sdim 3747259698Sdim def _S : NeonI_STN_Lane<r, 0b10, op0, 3748259698Sdim !cast<RegisterOperand>(List # "S_operand"), 3749259698Sdim neon_uimm2_bare, asmop> { 3750259698Sdim let Inst{12-10} = {lane{0}, 0b0, 0b0}; 3751259698Sdim let Inst{30} = lane{1}; 3752259698Sdim } 3753259698Sdim 3754259698Sdim def _D : NeonI_STN_Lane<r, 0b10, op0, 3755259698Sdim !cast<RegisterOperand>(List # "D_operand"), 3756259698Sdim neon_uimm1_bare, asmop>{ 3757259698Sdim let Inst{12-10} = 0b001; 3758259698Sdim let Inst{30} = lane{0}; 3759259698Sdim } 3760259698Sdim} 3761259698Sdim 3762259698Sdim// Store single 1-element structure from one lane of 1 register. 3763259698Sdimdefm ST1LN : STN_Lane_BHSD<0b0, 0b0, "VOne", "st1">; 3764259698Sdim 3765259698Sdim// Store single N-element structure from one lane of N consecutive registers 3766259698Sdim// (N = 2,3,4) 3767259698Sdimdefm ST2LN : STN_Lane_BHSD<0b1, 0b0, "VPair", "st2">; 3768259698Sdimdefm ST3LN : STN_Lane_BHSD<0b0, 0b1, "VTriple", "st3">; 3769259698Sdimdefm ST4LN : STN_Lane_BHSD<0b1, 0b1, "VQuad", "st4">; 3770259698Sdim 3771259698Sdimmulticlass ST1LN_patterns<ValueType VTy, ValueType VTy2, ValueType DTy, 3772259698Sdim Operand ImmOp, Operand ImmOp2, PatFrag StoreOp, 3773259698Sdim Instruction INST> { 3774259698Sdim def : Pat<(StoreOp (DTy (vector_extract (VTy VPR64:$Rt), ImmOp:$lane)), 3775259698Sdim GPR64xsp:$Rn), 3776259698Sdim (INST GPR64xsp:$Rn, 3777259698Sdim (SUBREG_TO_REG (i64 0), VPR64:$Rt, sub_64), 3778259698Sdim ImmOp:$lane)>; 3779259698Sdim 3780259698Sdim def : Pat<(StoreOp (DTy (vector_extract (VTy2 VPR128:$Rt), ImmOp2:$lane)), 3781259698Sdim GPR64xsp:$Rn), 3782259698Sdim (INST GPR64xsp:$Rn, VPR128:$Rt, ImmOp2:$lane)>; 3783259698Sdim} 3784259698Sdim 3785259698Sdim// Match all ST1LN instructions 3786259698Sdimdefm : ST1LN_patterns<v8i8, v16i8, i32, neon_uimm3_bare, neon_uimm4_bare, 3787259698Sdim truncstorei8, ST1LN_B>; 3788259698Sdim 3789259698Sdimdefm : ST1LN_patterns<v4i16, v8i16, i32, neon_uimm2_bare, neon_uimm3_bare, 3790259698Sdim truncstorei16, ST1LN_H>; 3791259698Sdim 3792259698Sdimdefm : ST1LN_patterns<v2i32, v4i32, i32, neon_uimm1_bare, neon_uimm2_bare, 3793259698Sdim store, ST1LN_S>; 3794259698Sdimdefm : ST1LN_patterns<v2f32, v4f32, f32, neon_uimm1_bare, neon_uimm2_bare, 3795259698Sdim store, ST1LN_S>; 3796259698Sdim 3797259698Sdimdefm : ST1LN_patterns<v1i64, v2i64, i64, neon_uimm0_bare, neon_uimm1_bare, 3798259698Sdim store, ST1LN_D>; 3799259698Sdimdefm : ST1LN_patterns<v1f64, v2f64, f64, neon_uimm0_bare, neon_uimm1_bare, 3800259698Sdim store, ST1LN_D>; 3801259698Sdim 3802259698Sdim// End of vector load/store single N-element structure (class SIMD lsone). 3803259698Sdim 3804259698Sdim 3805259698Sdim// The following are post-index load/store single N-element instructions 3806259698Sdim// (class SIMD lsone-post) 3807259698Sdim 3808259698Sdimmulticlass NeonI_LDN_WB_Dup<bit q, bit r, bits<3> opcode, bits<2> size, 3809259698Sdim RegisterOperand VecList, Operand ImmTy, 3810259698Sdim string asmop> { 3811259698Sdim let mayLoad = 1, neverHasSideEffects = 1, Constraints = "$wb = $Rn", 3812259698Sdim DecoderMethod = "DecodeVLDSTLanePostInstruction" in { 3813259698Sdim def _fixed : NeonI_LdOne_Dup_Post<q, r, opcode, size, 3814259698Sdim (outs VecList:$Rt, GPR64xsp:$wb), 3815259698Sdim (ins GPR64xsp:$Rn, ImmTy:$amt), 3816259698Sdim asmop # "\t$Rt, [$Rn], $amt", 3817259698Sdim [], 3818259698Sdim NoItinerary> { 3819259698Sdim let Rm = 0b11111; 3820259698Sdim } 3821259698Sdim 3822259698Sdim def _register : NeonI_LdOne_Dup_Post<q, r, opcode, size, 3823259698Sdim (outs VecList:$Rt, GPR64xsp:$wb), 3824259698Sdim (ins GPR64xsp:$Rn, GPR64noxzr:$Rm), 3825259698Sdim asmop # "\t$Rt, [$Rn], $Rm", 3826259698Sdim [], 3827259698Sdim NoItinerary>; 3828259698Sdim } 3829259698Sdim} 3830259698Sdim 3831259698Sdimmulticlass LDWB_Dup_BHSD<bit r, bits<3> opcode, string List, string asmop, 3832259698Sdim Operand uimm_b, Operand uimm_h, 3833259698Sdim Operand uimm_s, Operand uimm_d> { 3834259698Sdim defm _8B : NeonI_LDN_WB_Dup<0, r, opcode, 0b00, 3835259698Sdim !cast<RegisterOperand>(List # "8B_operand"), 3836259698Sdim uimm_b, asmop>; 3837259698Sdim 3838259698Sdim defm _4H : NeonI_LDN_WB_Dup<0, r, opcode, 0b01, 3839259698Sdim !cast<RegisterOperand>(List # "4H_operand"), 3840259698Sdim uimm_h, asmop>; 3841259698Sdim 3842259698Sdim defm _2S : NeonI_LDN_WB_Dup<0, r, opcode, 0b10, 3843259698Sdim !cast<RegisterOperand>(List # "2S_operand"), 3844259698Sdim uimm_s, asmop>; 3845259698Sdim 3846259698Sdim defm _1D : NeonI_LDN_WB_Dup<0, r, opcode, 0b11, 3847259698Sdim !cast<RegisterOperand>(List # "1D_operand"), 3848259698Sdim uimm_d, asmop>; 3849259698Sdim 3850259698Sdim defm _16B : NeonI_LDN_WB_Dup<1, r, opcode, 0b00, 3851259698Sdim !cast<RegisterOperand>(List # "16B_operand"), 3852259698Sdim uimm_b, asmop>; 3853259698Sdim 3854259698Sdim defm _8H : NeonI_LDN_WB_Dup<1, r, opcode, 0b01, 3855259698Sdim !cast<RegisterOperand>(List # "8H_operand"), 3856259698Sdim uimm_h, asmop>; 3857259698Sdim 3858259698Sdim defm _4S : NeonI_LDN_WB_Dup<1, r, opcode, 0b10, 3859259698Sdim !cast<RegisterOperand>(List # "4S_operand"), 3860259698Sdim uimm_s, asmop>; 3861259698Sdim 3862259698Sdim defm _2D : NeonI_LDN_WB_Dup<1, r, opcode, 0b11, 3863259698Sdim !cast<RegisterOperand>(List # "2D_operand"), 3864259698Sdim uimm_d, asmop>; 3865259698Sdim} 3866259698Sdim 3867259698Sdim// Post-index load single 1-element structure to all lanes of 1 register 3868259698Sdimdefm LD1R_WB : LDWB_Dup_BHSD<0b0, 0b110, "VOne", "ld1r", uimm_exact1, 3869259698Sdim uimm_exact2, uimm_exact4, uimm_exact8>; 3870259698Sdim 3871259698Sdim// Post-index load single N-element structure to all lanes of N consecutive 3872259698Sdim// registers (N = 2,3,4) 3873259698Sdimdefm LD2R_WB : LDWB_Dup_BHSD<0b1, 0b110, "VPair", "ld2r", uimm_exact2, 3874259698Sdim uimm_exact4, uimm_exact8, uimm_exact16>; 3875259698Sdimdefm LD3R_WB : LDWB_Dup_BHSD<0b0, 0b111, "VTriple", "ld3r", uimm_exact3, 3876259698Sdim uimm_exact6, uimm_exact12, uimm_exact24>; 3877259698Sdimdefm LD4R_WB : LDWB_Dup_BHSD<0b1, 0b111, "VQuad", "ld4r", uimm_exact4, 3878259698Sdim uimm_exact8, uimm_exact16, uimm_exact32>; 3879259698Sdim 3880259698Sdimlet mayLoad = 1, neverHasSideEffects = 1, hasExtraDefRegAllocReq = 1, 3881259698Sdim Constraints = "$Rn = $wb, $Rt = $src", 3882259698Sdim DecoderMethod = "DecodeVLDSTLanePostInstruction" in { 3883259698Sdim class LDN_WBFx_Lane<bit r, bits<2> op2_1, bit op0, RegisterOperand VList, 3884259698Sdim Operand ImmTy, Operand ImmOp, string asmop> 3885259698Sdim : NeonI_LdStOne_Lane_Post<1, r, op2_1, op0, 3886259698Sdim (outs VList:$Rt, GPR64xsp:$wb), 3887259698Sdim (ins GPR64xsp:$Rn, ImmTy:$amt, 3888259698Sdim VList:$src, ImmOp:$lane), 3889259698Sdim asmop # "\t$Rt[$lane], [$Rn], $amt", 3890259698Sdim [], 3891259698Sdim NoItinerary> { 3892259698Sdim let Rm = 0b11111; 3893259698Sdim } 3894259698Sdim 3895259698Sdim class LDN_WBReg_Lane<bit r, bits<2> op2_1, bit op0, RegisterOperand VList, 3896259698Sdim Operand ImmTy, Operand ImmOp, string asmop> 3897259698Sdim : NeonI_LdStOne_Lane_Post<1, r, op2_1, op0, 3898259698Sdim (outs VList:$Rt, GPR64xsp:$wb), 3899259698Sdim (ins GPR64xsp:$Rn, GPR64noxzr:$Rm, 3900259698Sdim VList:$src, ImmOp:$lane), 3901259698Sdim asmop # "\t$Rt[$lane], [$Rn], $Rm", 3902259698Sdim [], 3903259698Sdim NoItinerary>; 3904259698Sdim} 3905259698Sdim 3906259698Sdimmulticlass LD_Lane_WB_BHSD<bit r, bit op0, string List, string asmop, 3907259698Sdim Operand uimm_b, Operand uimm_h, 3908259698Sdim Operand uimm_s, Operand uimm_d> { 3909259698Sdim def _B_fixed : LDN_WBFx_Lane<r, 0b00, op0, 3910259698Sdim !cast<RegisterOperand>(List # "B_operand"), 3911259698Sdim uimm_b, neon_uimm4_bare, asmop> { 3912259698Sdim let Inst{12-10} = lane{2-0}; 3913259698Sdim let Inst{30} = lane{3}; 3914259698Sdim } 3915259698Sdim 3916259698Sdim def _B_register : LDN_WBReg_Lane<r, 0b00, op0, 3917259698Sdim !cast<RegisterOperand>(List # "B_operand"), 3918259698Sdim uimm_b, neon_uimm4_bare, asmop> { 3919259698Sdim let Inst{12-10} = lane{2-0}; 3920259698Sdim let Inst{30} = lane{3}; 3921259698Sdim } 3922259698Sdim 3923259698Sdim def _H_fixed : LDN_WBFx_Lane<r, 0b01, op0, 3924259698Sdim !cast<RegisterOperand>(List # "H_operand"), 3925259698Sdim uimm_h, neon_uimm3_bare, asmop> { 3926259698Sdim let Inst{12-10} = {lane{1}, lane{0}, 0b0}; 3927259698Sdim let Inst{30} = lane{2}; 3928259698Sdim } 3929259698Sdim 3930259698Sdim def _H_register : LDN_WBReg_Lane<r, 0b01, op0, 3931259698Sdim !cast<RegisterOperand>(List # "H_operand"), 3932259698Sdim uimm_h, neon_uimm3_bare, asmop> { 3933259698Sdim let Inst{12-10} = {lane{1}, lane{0}, 0b0}; 3934259698Sdim let Inst{30} = lane{2}; 3935259698Sdim } 3936259698Sdim 3937259698Sdim def _S_fixed : LDN_WBFx_Lane<r, 0b10, op0, 3938259698Sdim !cast<RegisterOperand>(List # "S_operand"), 3939259698Sdim uimm_s, neon_uimm2_bare, asmop> { 3940259698Sdim let Inst{12-10} = {lane{0}, 0b0, 0b0}; 3941259698Sdim let Inst{30} = lane{1}; 3942259698Sdim } 3943259698Sdim 3944259698Sdim def _S_register : LDN_WBReg_Lane<r, 0b10, op0, 3945259698Sdim !cast<RegisterOperand>(List # "S_operand"), 3946259698Sdim uimm_s, neon_uimm2_bare, asmop> { 3947259698Sdim let Inst{12-10} = {lane{0}, 0b0, 0b0}; 3948259698Sdim let Inst{30} = lane{1}; 3949259698Sdim } 3950259698Sdim 3951259698Sdim def _D_fixed : LDN_WBFx_Lane<r, 0b10, op0, 3952259698Sdim !cast<RegisterOperand>(List # "D_operand"), 3953259698Sdim uimm_d, neon_uimm1_bare, asmop> { 3954259698Sdim let Inst{12-10} = 0b001; 3955259698Sdim let Inst{30} = lane{0}; 3956259698Sdim } 3957259698Sdim 3958259698Sdim def _D_register : LDN_WBReg_Lane<r, 0b10, op0, 3959259698Sdim !cast<RegisterOperand>(List # "D_operand"), 3960259698Sdim uimm_d, neon_uimm1_bare, asmop> { 3961259698Sdim let Inst{12-10} = 0b001; 3962259698Sdim let Inst{30} = lane{0}; 3963259698Sdim } 3964259698Sdim} 3965259698Sdim 3966259698Sdim// Post-index load single 1-element structure to one lane of 1 register. 3967259698Sdimdefm LD1LN_WB : LD_Lane_WB_BHSD<0b0, 0b0, "VOne", "ld1", uimm_exact1, 3968259698Sdim uimm_exact2, uimm_exact4, uimm_exact8>; 3969259698Sdim 3970259698Sdim// Post-index load single N-element structure to one lane of N consecutive 3971259698Sdim// registers 3972259698Sdim// (N = 2,3,4) 3973259698Sdimdefm LD2LN_WB : LD_Lane_WB_BHSD<0b1, 0b0, "VPair", "ld2", uimm_exact2, 3974259698Sdim uimm_exact4, uimm_exact8, uimm_exact16>; 3975259698Sdimdefm LD3LN_WB : LD_Lane_WB_BHSD<0b0, 0b1, "VTriple", "ld3", uimm_exact3, 3976259698Sdim uimm_exact6, uimm_exact12, uimm_exact24>; 3977259698Sdimdefm LD4LN_WB : LD_Lane_WB_BHSD<0b1, 0b1, "VQuad", "ld4", uimm_exact4, 3978259698Sdim uimm_exact8, uimm_exact16, uimm_exact32>; 3979259698Sdim 3980259698Sdimlet mayStore = 1, neverHasSideEffects = 1, 3981259698Sdim hasExtraDefRegAllocReq = 1, Constraints = "$Rn = $wb", 3982259698Sdim DecoderMethod = "DecodeVLDSTLanePostInstruction" in { 3983259698Sdim class STN_WBFx_Lane<bit r, bits<2> op2_1, bit op0, RegisterOperand VList, 3984259698Sdim Operand ImmTy, Operand ImmOp, string asmop> 3985259698Sdim : NeonI_LdStOne_Lane_Post<0, r, op2_1, op0, 3986259698Sdim (outs GPR64xsp:$wb), 3987259698Sdim (ins GPR64xsp:$Rn, ImmTy:$amt, 3988259698Sdim VList:$Rt, ImmOp:$lane), 3989259698Sdim asmop # "\t$Rt[$lane], [$Rn], $amt", 3990259698Sdim [], 3991259698Sdim NoItinerary> { 3992259698Sdim let Rm = 0b11111; 3993259698Sdim } 3994259698Sdim 3995259698Sdim class STN_WBReg_Lane<bit r, bits<2> op2_1, bit op0, RegisterOperand VList, 3996259698Sdim Operand ImmTy, Operand ImmOp, string asmop> 3997259698Sdim : NeonI_LdStOne_Lane_Post<0, r, op2_1, op0, 3998259698Sdim (outs GPR64xsp:$wb), 3999259698Sdim (ins GPR64xsp:$Rn, GPR64noxzr:$Rm, VList:$Rt, 4000259698Sdim ImmOp:$lane), 4001259698Sdim asmop # "\t$Rt[$lane], [$Rn], $Rm", 4002259698Sdim [], 4003259698Sdim NoItinerary>; 4004259698Sdim} 4005259698Sdim 4006259698Sdimmulticlass ST_Lane_WB_BHSD<bit r, bit op0, string List, string asmop, 4007259698Sdim Operand uimm_b, Operand uimm_h, 4008259698Sdim Operand uimm_s, Operand uimm_d> { 4009259698Sdim def _B_fixed : STN_WBFx_Lane<r, 0b00, op0, 4010259698Sdim !cast<RegisterOperand>(List # "B_operand"), 4011259698Sdim uimm_b, neon_uimm4_bare, asmop> { 4012259698Sdim let Inst{12-10} = lane{2-0}; 4013259698Sdim let Inst{30} = lane{3}; 4014259698Sdim } 4015259698Sdim 4016259698Sdim def _B_register : STN_WBReg_Lane<r, 0b00, op0, 4017259698Sdim !cast<RegisterOperand>(List # "B_operand"), 4018259698Sdim uimm_b, neon_uimm4_bare, asmop> { 4019259698Sdim let Inst{12-10} = lane{2-0}; 4020259698Sdim let Inst{30} = lane{3}; 4021259698Sdim } 4022259698Sdim 4023259698Sdim def _H_fixed : STN_WBFx_Lane<r, 0b01, op0, 4024259698Sdim !cast<RegisterOperand>(List # "H_operand"), 4025259698Sdim uimm_h, neon_uimm3_bare, asmop> { 4026259698Sdim let Inst{12-10} = {lane{1}, lane{0}, 0b0}; 4027259698Sdim let Inst{30} = lane{2}; 4028259698Sdim } 4029259698Sdim 4030259698Sdim def _H_register : STN_WBReg_Lane<r, 0b01, op0, 4031259698Sdim !cast<RegisterOperand>(List # "H_operand"), 4032259698Sdim uimm_h, neon_uimm3_bare, asmop> { 4033259698Sdim let Inst{12-10} = {lane{1}, lane{0}, 0b0}; 4034259698Sdim let Inst{30} = lane{2}; 4035259698Sdim } 4036259698Sdim 4037259698Sdim def _S_fixed : STN_WBFx_Lane<r, 0b10, op0, 4038259698Sdim !cast<RegisterOperand>(List # "S_operand"), 4039259698Sdim uimm_s, neon_uimm2_bare, asmop> { 4040259698Sdim let Inst{12-10} = {lane{0}, 0b0, 0b0}; 4041259698Sdim let Inst{30} = lane{1}; 4042259698Sdim } 4043259698Sdim 4044259698Sdim def _S_register : STN_WBReg_Lane<r, 0b10, op0, 4045259698Sdim !cast<RegisterOperand>(List # "S_operand"), 4046259698Sdim uimm_s, neon_uimm2_bare, asmop> { 4047259698Sdim let Inst{12-10} = {lane{0}, 0b0, 0b0}; 4048259698Sdim let Inst{30} = lane{1}; 4049259698Sdim } 4050259698Sdim 4051259698Sdim def _D_fixed : STN_WBFx_Lane<r, 0b10, op0, 4052259698Sdim !cast<RegisterOperand>(List # "D_operand"), 4053259698Sdim uimm_d, neon_uimm1_bare, asmop> { 4054259698Sdim let Inst{12-10} = 0b001; 4055259698Sdim let Inst{30} = lane{0}; 4056259698Sdim } 4057259698Sdim 4058259698Sdim def _D_register : STN_WBReg_Lane<r, 0b10, op0, 4059259698Sdim !cast<RegisterOperand>(List # "D_operand"), 4060259698Sdim uimm_d, neon_uimm1_bare, asmop> { 4061259698Sdim let Inst{12-10} = 0b001; 4062259698Sdim let Inst{30} = lane{0}; 4063259698Sdim } 4064259698Sdim} 4065259698Sdim 4066259698Sdim// Post-index store single 1-element structure from one lane of 1 register. 4067259698Sdimdefm ST1LN_WB : ST_Lane_WB_BHSD<0b0, 0b0, "VOne", "st1", uimm_exact1, 4068259698Sdim uimm_exact2, uimm_exact4, uimm_exact8>; 4069259698Sdim 4070259698Sdim// Post-index store single N-element structure from one lane of N consecutive 4071259698Sdim// registers (N = 2,3,4) 4072259698Sdimdefm ST2LN_WB : ST_Lane_WB_BHSD<0b1, 0b0, "VPair", "st2", uimm_exact2, 4073259698Sdim uimm_exact4, uimm_exact8, uimm_exact16>; 4074259698Sdimdefm ST3LN_WB : ST_Lane_WB_BHSD<0b0, 0b1, "VTriple", "st3", uimm_exact3, 4075259698Sdim uimm_exact6, uimm_exact12, uimm_exact24>; 4076259698Sdimdefm ST4LN_WB : ST_Lane_WB_BHSD<0b1, 0b1, "VQuad", "st4", uimm_exact4, 4077259698Sdim uimm_exact8, uimm_exact16, uimm_exact32>; 4078259698Sdim 4079259698Sdim// End of post-index load/store single N-element instructions 4080259698Sdim// (class SIMD lsone-post) 4081259698Sdim 4082259698Sdim// Neon Scalar instructions implementation 4083259698Sdim// Scalar Three Same 4084259698Sdim 4085259698Sdimclass NeonI_Scalar3Same_size<bit u, bits<2> size, bits<5> opcode, string asmop, 4086259698Sdim RegisterClass FPRC> 4087259698Sdim : NeonI_Scalar3Same<u, size, opcode, 4088259698Sdim (outs FPRC:$Rd), (ins FPRC:$Rn, FPRC:$Rm), 4089259698Sdim !strconcat(asmop, "\t$Rd, $Rn, $Rm"), 4090259698Sdim [], 4091259698Sdim NoItinerary>; 4092259698Sdim 4093259698Sdimclass NeonI_Scalar3Same_D_size<bit u, bits<5> opcode, string asmop> 4094259698Sdim : NeonI_Scalar3Same_size<u, 0b11, opcode, asmop, FPR64>; 4095259698Sdim 4096259698Sdimmulticlass NeonI_Scalar3Same_HS_sizes<bit u, bits<5> opcode, string asmop, 4097259698Sdim bit Commutable = 0> { 4098259698Sdim let isCommutable = Commutable in { 4099259698Sdim def hhh : NeonI_Scalar3Same_size<u, 0b01, opcode, asmop, FPR16>; 4100259698Sdim def sss : NeonI_Scalar3Same_size<u, 0b10, opcode, asmop, FPR32>; 4101259698Sdim } 4102259698Sdim} 4103259698Sdim 4104259698Sdimmulticlass NeonI_Scalar3Same_SD_sizes<bit u, bit size_high, bits<5> opcode, 4105259698Sdim string asmop, bit Commutable = 0> { 4106259698Sdim let isCommutable = Commutable in { 4107259698Sdim def sss : NeonI_Scalar3Same_size<u, {size_high, 0b0}, opcode, asmop, FPR32>; 4108259698Sdim def ddd : NeonI_Scalar3Same_size<u, {size_high, 0b1}, opcode, asmop, FPR64>; 4109259698Sdim } 4110259698Sdim} 4111259698Sdim 4112259698Sdimmulticlass NeonI_Scalar3Same_BHSD_sizes<bit u, bits<5> opcode, 4113259698Sdim string asmop, bit Commutable = 0> { 4114259698Sdim let isCommutable = Commutable in { 4115259698Sdim def bbb : NeonI_Scalar3Same_size<u, 0b00, opcode, asmop, FPR8>; 4116259698Sdim def hhh : NeonI_Scalar3Same_size<u, 0b01, opcode, asmop, FPR16>; 4117259698Sdim def sss : NeonI_Scalar3Same_size<u, 0b10, opcode, asmop, FPR32>; 4118259698Sdim def ddd : NeonI_Scalar3Same_size<u, 0b11, opcode, asmop, FPR64>; 4119259698Sdim } 4120259698Sdim} 4121259698Sdim 4122259698Sdimmulticlass Neon_Scalar3Same_D_size_patterns<SDPatternOperator opnode, 4123259698Sdim Instruction INSTD> { 4124259698Sdim def : Pat<(v1i64 (opnode (v1i64 FPR64:$Rn), (v1i64 FPR64:$Rm))), 4125259698Sdim (INSTD FPR64:$Rn, FPR64:$Rm)>; 4126259698Sdim} 4127259698Sdim 4128259698Sdimmulticlass Neon_Scalar3Same_BHSD_size_patterns<SDPatternOperator opnode, 4129259698Sdim Instruction INSTB, 4130259698Sdim Instruction INSTH, 4131259698Sdim Instruction INSTS, 4132259698Sdim Instruction INSTD> 4133259698Sdim : Neon_Scalar3Same_D_size_patterns<opnode, INSTD> { 4134259698Sdim def: Pat<(v1i8 (opnode (v1i8 FPR8:$Rn), (v1i8 FPR8:$Rm))), 4135259698Sdim (INSTB FPR8:$Rn, FPR8:$Rm)>; 4136259698Sdim 4137259698Sdim def: Pat<(v1i16 (opnode (v1i16 FPR16:$Rn), (v1i16 FPR16:$Rm))), 4138259698Sdim (INSTH FPR16:$Rn, FPR16:$Rm)>; 4139259698Sdim 4140259698Sdim def: Pat<(v1i32 (opnode (v1i32 FPR32:$Rn), (v1i32 FPR32:$Rm))), 4141259698Sdim (INSTS FPR32:$Rn, FPR32:$Rm)>; 4142259698Sdim} 4143259698Sdim 4144259698Sdimclass Neon_Scalar3Same_cmp_D_size_patterns<SDPatternOperator opnode, 4145259698Sdim Instruction INSTD> 4146259698Sdim : Pat<(v1i64 (opnode (v1i64 FPR64:$Rn), (v1i64 FPR64:$Rm))), 4147259698Sdim (INSTD FPR64:$Rn, FPR64:$Rm)>; 4148259698Sdim 4149259698Sdimmulticlass Neon_Scalar3Same_HS_size_patterns<SDPatternOperator opnode, 4150259698Sdim Instruction INSTH, 4151259698Sdim Instruction INSTS> { 4152259698Sdim def : Pat<(v1i16 (opnode (v1i16 FPR16:$Rn), (v1i16 FPR16:$Rm))), 4153259698Sdim (INSTH FPR16:$Rn, FPR16:$Rm)>; 4154259698Sdim def : Pat<(v1i32 (opnode (v1i32 FPR32:$Rn), (v1i32 FPR32:$Rm))), 4155259698Sdim (INSTS FPR32:$Rn, FPR32:$Rm)>; 4156259698Sdim} 4157259698Sdim 4158259698Sdimmulticlass Neon_Scalar3Same_SD_size_patterns<SDPatternOperator opnode, 4159259698Sdim Instruction INSTS, 4160259698Sdim Instruction INSTD> { 4161259698Sdim def : Pat<(v1f32 (opnode (v1f32 FPR32:$Rn), (v1f32 FPR32:$Rm))), 4162259698Sdim (INSTS FPR32:$Rn, FPR32:$Rm)>; 4163259698Sdim def : Pat<(v1f64 (opnode (v1f64 FPR64:$Rn), (v1f64 FPR64:$Rm))), 4164259698Sdim (INSTD FPR64:$Rn, FPR64:$Rm)>; 4165259698Sdim} 4166259698Sdim 4167259698Sdimmulticlass Neon_Scalar3Same_cmp_SD_size_patterns<SDPatternOperator opnode, 4168259698Sdim Instruction INSTS, 4169259698Sdim Instruction INSTD> { 4170259698Sdim def : Pat<(v1i32 (opnode (v1f32 FPR32:$Rn), (v1f32 FPR32:$Rm))), 4171259698Sdim (INSTS FPR32:$Rn, FPR32:$Rm)>; 4172259698Sdim def : Pat<(v1i64 (opnode (v1f64 FPR64:$Rn), (v1f64 FPR64:$Rm))), 4173259698Sdim (INSTD FPR64:$Rn, FPR64:$Rm)>; 4174259698Sdim} 4175259698Sdim 4176259698Sdimclass Neon_Scalar3Same_cmp_V1_D_size_patterns<CondCode CC, 4177259698Sdim Instruction INSTD> 4178259698Sdim : Pat<(v1i64 (Neon_cmp (v1f64 FPR64:$Rn), (v1f64 FPR64:$Rm), CC)), 4179259698Sdim (INSTD FPR64:$Rn, FPR64:$Rm)>; 4180259698Sdim 4181259698Sdim// Scalar Three Different 4182259698Sdim 4183259698Sdimclass NeonI_Scalar3Diff_size<bit u, bits<2> size, bits<4> opcode, string asmop, 4184259698Sdim RegisterClass FPRCD, RegisterClass FPRCS> 4185259698Sdim : NeonI_Scalar3Diff<u, size, opcode, 4186259698Sdim (outs FPRCD:$Rd), (ins FPRCS:$Rn, FPRCS:$Rm), 4187259698Sdim !strconcat(asmop, "\t$Rd, $Rn, $Rm"), 4188259698Sdim [], 4189259698Sdim NoItinerary>; 4190259698Sdim 4191259698Sdimmulticlass NeonI_Scalar3Diff_HS_size<bit u, bits<4> opcode, string asmop> { 4192259698Sdim def shh : NeonI_Scalar3Diff_size<u, 0b01, opcode, asmop, FPR32, FPR16>; 4193259698Sdim def dss : NeonI_Scalar3Diff_size<u, 0b10, opcode, asmop, FPR64, FPR32>; 4194259698Sdim} 4195259698Sdim 4196259698Sdimmulticlass NeonI_Scalar3Diff_ml_HS_size<bit u, bits<4> opcode, string asmop> { 4197259698Sdim let Constraints = "$Src = $Rd" in { 4198259698Sdim def shh : NeonI_Scalar3Diff<u, 0b01, opcode, 4199259698Sdim (outs FPR32:$Rd), (ins FPR32:$Src, FPR16:$Rn, FPR16:$Rm), 4200259698Sdim !strconcat(asmop, "\t$Rd, $Rn, $Rm"), 4201259698Sdim [], 4202259698Sdim NoItinerary>; 4203259698Sdim def dss : NeonI_Scalar3Diff<u, 0b10, opcode, 4204259698Sdim (outs FPR64:$Rd), (ins FPR64:$Src, FPR32:$Rn, FPR32:$Rm), 4205259698Sdim !strconcat(asmop, "\t$Rd, $Rn, $Rm"), 4206259698Sdim [], 4207259698Sdim NoItinerary>; 4208259698Sdim } 4209259698Sdim} 4210259698Sdim 4211259698Sdimmulticlass Neon_Scalar3Diff_HS_size_patterns<SDPatternOperator opnode, 4212259698Sdim Instruction INSTH, 4213259698Sdim Instruction INSTS> { 4214259698Sdim def : Pat<(v1i32 (opnode (v1i16 FPR16:$Rn), (v1i16 FPR16:$Rm))), 4215259698Sdim (INSTH FPR16:$Rn, FPR16:$Rm)>; 4216259698Sdim def : Pat<(v1i64 (opnode (v1i32 FPR32:$Rn), (v1i32 FPR32:$Rm))), 4217259698Sdim (INSTS FPR32:$Rn, FPR32:$Rm)>; 4218259698Sdim} 4219259698Sdim 4220259698Sdimmulticlass Neon_Scalar3Diff_ml_HS_size_patterns<SDPatternOperator opnode, 4221259698Sdim Instruction INSTH, 4222259698Sdim Instruction INSTS> { 4223259698Sdim def : Pat<(v1i32 (opnode (v1i32 FPR32:$Src), (v1i16 FPR16:$Rn), (v1i16 FPR16:$Rm))), 4224259698Sdim (INSTH FPR32:$Src, FPR16:$Rn, FPR16:$Rm)>; 4225259698Sdim def : Pat<(v1i64 (opnode (v1i64 FPR64:$Src), (v1i32 FPR32:$Rn), (v1i32 FPR32:$Rm))), 4226259698Sdim (INSTS FPR64:$Src, FPR32:$Rn, FPR32:$Rm)>; 4227259698Sdim} 4228259698Sdim 4229259698Sdim// Scalar Two Registers Miscellaneous 4230259698Sdim 4231259698Sdimclass NeonI_Scalar2SameMisc_size<bit u, bits<2> size, bits<5> opcode, string asmop, 4232259698Sdim RegisterClass FPRCD, RegisterClass FPRCS> 4233259698Sdim : NeonI_Scalar2SameMisc<u, size, opcode, 4234259698Sdim (outs FPRCD:$Rd), (ins FPRCS:$Rn), 4235259698Sdim !strconcat(asmop, "\t$Rd, $Rn"), 4236259698Sdim [], 4237259698Sdim NoItinerary>; 4238259698Sdim 4239259698Sdimmulticlass NeonI_Scalar2SameMisc_SD_size<bit u, bit size_high, bits<5> opcode, 4240259698Sdim string asmop> { 4241259698Sdim def ss : NeonI_Scalar2SameMisc_size<u, {size_high, 0b0}, opcode, asmop, FPR32, 4242259698Sdim FPR32>; 4243259698Sdim def dd : NeonI_Scalar2SameMisc_size<u, {size_high, 0b1}, opcode, asmop, FPR64, 4244259698Sdim FPR64>; 4245259698Sdim} 4246259698Sdim 4247259698Sdimmulticlass NeonI_Scalar2SameMisc_D_size<bit u, bits<5> opcode, string asmop> { 4248259698Sdim def dd : NeonI_Scalar2SameMisc_size<u, 0b11, opcode, asmop, FPR64, FPR64>; 4249259698Sdim} 4250259698Sdim 4251259698Sdimmulticlass NeonI_Scalar2SameMisc_BHSD_size<bit u, bits<5> opcode, string asmop> 4252259698Sdim : NeonI_Scalar2SameMisc_D_size<u, opcode, asmop> { 4253259698Sdim def bb : NeonI_Scalar2SameMisc_size<u, 0b00, opcode, asmop, FPR8, FPR8>; 4254259698Sdim def hh : NeonI_Scalar2SameMisc_size<u, 0b01, opcode, asmop, FPR16, FPR16>; 4255259698Sdim def ss : NeonI_Scalar2SameMisc_size<u, 0b10, opcode, asmop, FPR32, FPR32>; 4256259698Sdim} 4257259698Sdim 4258259698Sdimclass NeonI_Scalar2SameMisc_fcvtxn_D_size<bit u, bits<5> opcode, string asmop> 4259259698Sdim : NeonI_Scalar2SameMisc_size<u, 0b01, opcode, asmop, FPR32, FPR64>; 4260259698Sdim 4261259698Sdimmulticlass NeonI_Scalar2SameMisc_narrow_HSD_size<bit u, bits<5> opcode, 4262259698Sdim string asmop> { 4263259698Sdim def bh : NeonI_Scalar2SameMisc_size<u, 0b00, opcode, asmop, FPR8, FPR16>; 4264259698Sdim def hs : NeonI_Scalar2SameMisc_size<u, 0b01, opcode, asmop, FPR16, FPR32>; 4265259698Sdim def sd : NeonI_Scalar2SameMisc_size<u, 0b10, opcode, asmop, FPR32, FPR64>; 4266259698Sdim} 4267259698Sdim 4268259698Sdimclass NeonI_Scalar2SameMisc_accum_size<bit u, bits<2> size, bits<5> opcode, 4269259698Sdim string asmop, RegisterClass FPRC> 4270259698Sdim : NeonI_Scalar2SameMisc<u, size, opcode, 4271259698Sdim (outs FPRC:$Rd), (ins FPRC:$Src, FPRC:$Rn), 4272259698Sdim !strconcat(asmop, "\t$Rd, $Rn"), 4273259698Sdim [], 4274259698Sdim NoItinerary>; 4275259698Sdim 4276259698Sdimmulticlass NeonI_Scalar2SameMisc_accum_BHSD_size<bit u, bits<5> opcode, 4277259698Sdim string asmop> { 4278259698Sdim 4279259698Sdim let Constraints = "$Src = $Rd" in { 4280259698Sdim def bb : NeonI_Scalar2SameMisc_accum_size<u, 0b00, opcode, asmop, FPR8>; 4281259698Sdim def hh : NeonI_Scalar2SameMisc_accum_size<u, 0b01, opcode, asmop, FPR16>; 4282259698Sdim def ss : NeonI_Scalar2SameMisc_accum_size<u, 0b10, opcode, asmop, FPR32>; 4283259698Sdim def dd : NeonI_Scalar2SameMisc_accum_size<u, 0b11, opcode, asmop, FPR64>; 4284259698Sdim } 4285259698Sdim} 4286259698Sdim 4287259698Sdimclass Neon_Scalar2SameMisc_fcvtxn_D_size_patterns<SDPatternOperator opnode, 4288259698Sdim Instruction INSTD> 4289259698Sdim : Pat<(v1f32 (opnode (v1f64 FPR64:$Rn))), 4290259698Sdim (INSTD FPR64:$Rn)>; 4291259698Sdim 4292259698Sdimmulticlass Neon_Scalar2SameMisc_fcvt_SD_size_patterns<SDPatternOperator opnode, 4293259698Sdim Instruction INSTS, 4294259698Sdim Instruction INSTD> { 4295259698Sdim def : Pat<(v1i32 (opnode (v1f32 FPR32:$Rn))), 4296259698Sdim (INSTS FPR32:$Rn)>; 4297259698Sdim def : Pat<(v1i64 (opnode (v1f64 FPR64:$Rn))), 4298259698Sdim (INSTD FPR64:$Rn)>; 4299259698Sdim} 4300259698Sdim 4301259698Sdimmulticlass Neon_Scalar2SameMisc_cvt_SD_size_patterns<SDPatternOperator Sopnode, 4302259698Sdim SDPatternOperator Dopnode, 4303259698Sdim Instruction INSTS, 4304259698Sdim Instruction INSTD> { 4305259698Sdim def : Pat<(f32 (Sopnode (v1i32 FPR32:$Rn))), 4306259698Sdim (INSTS FPR32:$Rn)>; 4307259698Sdim def : Pat<(f64 (Dopnode (v1i64 FPR64:$Rn))), 4308259698Sdim (INSTD FPR64:$Rn)>; 4309259698Sdim} 4310259698Sdim 4311259698Sdimmulticlass Neon_Scalar2SameMisc_SD_size_patterns<SDPatternOperator opnode, 4312259698Sdim Instruction INSTS, 4313259698Sdim Instruction INSTD> { 4314259698Sdim def : Pat<(v1f32 (opnode (v1f32 FPR32:$Rn))), 4315259698Sdim (INSTS FPR32:$Rn)>; 4316259698Sdim def : Pat<(v1f64 (opnode (v1f64 FPR64:$Rn))), 4317259698Sdim (INSTD FPR64:$Rn)>; 4318259698Sdim} 4319259698Sdim 4320259698Sdimclass NeonI_Scalar2SameMisc_cmpz_D_size<bit u, bits<5> opcode, string asmop> 4321259698Sdim : NeonI_Scalar2SameMisc<u, 0b11, opcode, 4322259698Sdim (outs FPR64:$Rd), (ins FPR64:$Rn, neon_uimm0:$Imm), 4323259698Sdim !strconcat(asmop, "\t$Rd, $Rn, $Imm"), 4324259698Sdim [], 4325259698Sdim NoItinerary>; 4326259698Sdim 4327259698Sdimmulticlass NeonI_Scalar2SameMisc_cmpz_SD_size<bit u, bits<5> opcode, 4328259698Sdim string asmop> { 4329259698Sdim def ssi : NeonI_Scalar2SameMisc<u, 0b10, opcode, 4330259698Sdim (outs FPR32:$Rd), (ins FPR32:$Rn, fpz32:$FPImm), 4331259698Sdim !strconcat(asmop, "\t$Rd, $Rn, $FPImm"), 4332259698Sdim [], 4333259698Sdim NoItinerary>; 4334259698Sdim def ddi : NeonI_Scalar2SameMisc<u, 0b11, opcode, 4335259698Sdim (outs FPR64:$Rd), (ins FPR64:$Rn, fpz32:$FPImm), 4336259698Sdim !strconcat(asmop, "\t$Rd, $Rn, $FPImm"), 4337259698Sdim [], 4338259698Sdim NoItinerary>; 4339259698Sdim} 4340259698Sdim 4341259698Sdimclass Neon_Scalar2SameMisc_cmpz_D_size_patterns<SDPatternOperator opnode, 4342259698Sdim Instruction INSTD> 4343259698Sdim : Pat<(v1i64 (opnode (v1i64 FPR64:$Rn), 4344259698Sdim (v1i64 (bitconvert (v8i8 Neon_AllZero))))), 4345259698Sdim (INSTD FPR64:$Rn, 0)>; 4346259698Sdim 4347259698Sdimclass Neon_Scalar2SameMisc_cmpz_D_V1_size_patterns<CondCode CC, 4348259698Sdim Instruction INSTD> 4349259698Sdim : Pat<(v1i64 (Neon_cmpz (v1i64 FPR64:$Rn), 4350259698Sdim (i32 neon_uimm0:$Imm), CC)), 4351259698Sdim (INSTD FPR64:$Rn, neon_uimm0:$Imm)>; 4352259698Sdim 4353259698Sdimmulticlass Neon_Scalar2SameMisc_cmpz_SD_size_patterns<SDPatternOperator opnode, 4354259698Sdim Instruction INSTS, 4355259698Sdim Instruction INSTD> { 4356259698Sdim def : Pat<(v1i32 (opnode (v1f32 FPR32:$Rn), 4357259698Sdim (v1f32 (scalar_to_vector (f32 fpz32:$FPImm))))), 4358259698Sdim (INSTS FPR32:$Rn, fpz32:$FPImm)>; 4359259698Sdim def : Pat<(v1i64 (opnode (v1f64 FPR64:$Rn), 4360259698Sdim (v1f32 (scalar_to_vector (f32 fpz32:$FPImm))))), 4361259698Sdim (INSTD FPR64:$Rn, fpz32:$FPImm)>; 4362259698Sdim} 4363259698Sdim 4364259698Sdimmulticlass Neon_Scalar2SameMisc_D_size_patterns<SDPatternOperator opnode, 4365259698Sdim Instruction INSTD> { 4366259698Sdim def : Pat<(v1i64 (opnode (v1i64 FPR64:$Rn))), 4367259698Sdim (INSTD FPR64:$Rn)>; 4368259698Sdim} 4369259698Sdim 4370259698Sdimmulticlass Neon_Scalar2SameMisc_BHSD_size_patterns<SDPatternOperator opnode, 4371259698Sdim Instruction INSTB, 4372259698Sdim Instruction INSTH, 4373259698Sdim Instruction INSTS, 4374259698Sdim Instruction INSTD> 4375259698Sdim : Neon_Scalar2SameMisc_D_size_patterns<opnode, INSTD> { 4376259698Sdim def : Pat<(v1i8 (opnode (v1i8 FPR8:$Rn))), 4377259698Sdim (INSTB FPR8:$Rn)>; 4378259698Sdim def : Pat<(v1i16 (opnode (v1i16 FPR16:$Rn))), 4379259698Sdim (INSTH FPR16:$Rn)>; 4380259698Sdim def : Pat<(v1i32 (opnode (v1i32 FPR32:$Rn))), 4381259698Sdim (INSTS FPR32:$Rn)>; 4382259698Sdim} 4383259698Sdim 4384259698Sdimmulticlass Neon_Scalar2SameMisc_narrow_HSD_size_patterns< 4385259698Sdim SDPatternOperator opnode, 4386259698Sdim Instruction INSTH, 4387259698Sdim Instruction INSTS, 4388259698Sdim Instruction INSTD> { 4389259698Sdim def : Pat<(v1i8 (opnode (v1i16 FPR16:$Rn))), 4390259698Sdim (INSTH FPR16:$Rn)>; 4391259698Sdim def : Pat<(v1i16 (opnode (v1i32 FPR32:$Rn))), 4392259698Sdim (INSTS FPR32:$Rn)>; 4393259698Sdim def : Pat<(v1i32 (opnode (v1i64 FPR64:$Rn))), 4394259698Sdim (INSTD FPR64:$Rn)>; 4395259698Sdim 4396259698Sdim} 4397259698Sdim 4398259698Sdimmulticlass Neon_Scalar2SameMisc_accum_BHSD_size_patterns< 4399259698Sdim SDPatternOperator opnode, 4400259698Sdim Instruction INSTB, 4401259698Sdim Instruction INSTH, 4402259698Sdim Instruction INSTS, 4403259698Sdim Instruction INSTD> { 4404259698Sdim def : Pat<(v1i8 (opnode (v1i8 FPR8:$Src), (v1i8 FPR8:$Rn))), 4405259698Sdim (INSTB FPR8:$Src, FPR8:$Rn)>; 4406259698Sdim def : Pat<(v1i16 (opnode (v1i16 FPR16:$Src), (v1i16 FPR16:$Rn))), 4407259698Sdim (INSTH FPR16:$Src, FPR16:$Rn)>; 4408259698Sdim def : Pat<(v1i32 (opnode (v1i32 FPR32:$Src), (v1i32 FPR32:$Rn))), 4409259698Sdim (INSTS FPR32:$Src, FPR32:$Rn)>; 4410259698Sdim def : Pat<(v1i64 (opnode (v1i64 FPR64:$Src), (v1i64 FPR64:$Rn))), 4411259698Sdim (INSTD FPR64:$Src, FPR64:$Rn)>; 4412259698Sdim} 4413259698Sdim 4414259698Sdim// Scalar Shift By Immediate 4415259698Sdim 4416259698Sdimclass NeonI_ScalarShiftImm_size<bit u, bits<5> opcode, string asmop, 4417259698Sdim RegisterClass FPRC, Operand ImmTy> 4418259698Sdim : NeonI_ScalarShiftImm<u, opcode, 4419259698Sdim (outs FPRC:$Rd), (ins FPRC:$Rn, ImmTy:$Imm), 4420259698Sdim !strconcat(asmop, "\t$Rd, $Rn, $Imm"), 4421259698Sdim [], NoItinerary>; 4422259698Sdim 4423259698Sdimmulticlass NeonI_ScalarShiftRightImm_D_size<bit u, bits<5> opcode, 4424259698Sdim string asmop> { 4425259698Sdim def ddi : NeonI_ScalarShiftImm_size<u, opcode, asmop, FPR64, shr_imm64> { 4426259698Sdim bits<6> Imm; 4427259698Sdim let Inst{22} = 0b1; // immh:immb = 1xxxxxx 4428259698Sdim let Inst{21-16} = Imm; 4429259698Sdim } 4430259698Sdim} 4431259698Sdim 4432259698Sdimmulticlass NeonI_ScalarShiftRightImm_BHSD_size<bit u, bits<5> opcode, 4433259698Sdim string asmop> 4434259698Sdim : NeonI_ScalarShiftRightImm_D_size<u, opcode, asmop> { 4435259698Sdim def bbi : NeonI_ScalarShiftImm_size<u, opcode, asmop, FPR8, shr_imm8> { 4436259698Sdim bits<3> Imm; 4437259698Sdim let Inst{22-19} = 0b0001; // immh:immb = 0001xxx 4438259698Sdim let Inst{18-16} = Imm; 4439259698Sdim } 4440259698Sdim def hhi : NeonI_ScalarShiftImm_size<u, opcode, asmop, FPR16, shr_imm16> { 4441259698Sdim bits<4> Imm; 4442259698Sdim let Inst{22-20} = 0b001; // immh:immb = 001xxxx 4443259698Sdim let Inst{19-16} = Imm; 4444259698Sdim } 4445259698Sdim def ssi : NeonI_ScalarShiftImm_size<u, opcode, asmop, FPR32, shr_imm32> { 4446259698Sdim bits<5> Imm; 4447259698Sdim let Inst{22-21} = 0b01; // immh:immb = 01xxxxx 4448259698Sdim let Inst{20-16} = Imm; 4449259698Sdim } 4450259698Sdim} 4451259698Sdim 4452259698Sdimmulticlass NeonI_ScalarShiftLeftImm_D_size<bit u, bits<5> opcode, 4453259698Sdim string asmop> { 4454259698Sdim def ddi : NeonI_ScalarShiftImm_size<u, opcode, asmop, FPR64, shl_imm64> { 4455259698Sdim bits<6> Imm; 4456259698Sdim let Inst{22} = 0b1; // immh:immb = 1xxxxxx 4457259698Sdim let Inst{21-16} = Imm; 4458259698Sdim } 4459259698Sdim} 4460259698Sdim 4461259698Sdimmulticlass NeonI_ScalarShiftLeftImm_BHSD_size<bit u, bits<5> opcode, 4462259698Sdim string asmop> 4463259698Sdim : NeonI_ScalarShiftLeftImm_D_size<u, opcode, asmop> { 4464259698Sdim def bbi : NeonI_ScalarShiftImm_size<u, opcode, asmop, FPR8, shl_imm8> { 4465259698Sdim bits<3> Imm; 4466259698Sdim let Inst{22-19} = 0b0001; // immh:immb = 0001xxx 4467259698Sdim let Inst{18-16} = Imm; 4468259698Sdim } 4469259698Sdim def hhi : NeonI_ScalarShiftImm_size<u, opcode, asmop, FPR16, shl_imm16> { 4470259698Sdim bits<4> Imm; 4471259698Sdim let Inst{22-20} = 0b001; // immh:immb = 001xxxx 4472259698Sdim let Inst{19-16} = Imm; 4473259698Sdim } 4474259698Sdim def ssi : NeonI_ScalarShiftImm_size<u, opcode, asmop, FPR32, shl_imm32> { 4475259698Sdim bits<5> Imm; 4476259698Sdim let Inst{22-21} = 0b01; // immh:immb = 01xxxxx 4477259698Sdim let Inst{20-16} = Imm; 4478259698Sdim } 4479259698Sdim} 4480259698Sdim 4481259698Sdimclass NeonI_ScalarShiftRightImm_accum_D_size<bit u, bits<5> opcode, string asmop> 4482259698Sdim : NeonI_ScalarShiftImm<u, opcode, 4483259698Sdim (outs FPR64:$Rd), 4484259698Sdim (ins FPR64:$Src, FPR64:$Rn, shr_imm64:$Imm), 4485259698Sdim !strconcat(asmop, "\t$Rd, $Rn, $Imm"), 4486259698Sdim [], NoItinerary> { 4487259698Sdim bits<6> Imm; 4488259698Sdim let Inst{22} = 0b1; // immh:immb = 1xxxxxx 4489259698Sdim let Inst{21-16} = Imm; 4490259698Sdim let Constraints = "$Src = $Rd"; 4491259698Sdim} 4492259698Sdim 4493259698Sdimclass NeonI_ScalarShiftLeftImm_accum_D_size<bit u, bits<5> opcode, string asmop> 4494259698Sdim : NeonI_ScalarShiftImm<u, opcode, 4495259698Sdim (outs FPR64:$Rd), 4496259698Sdim (ins FPR64:$Src, FPR64:$Rn, shl_imm64:$Imm), 4497259698Sdim !strconcat(asmop, "\t$Rd, $Rn, $Imm"), 4498259698Sdim [], NoItinerary> { 4499259698Sdim bits<6> Imm; 4500259698Sdim let Inst{22} = 0b1; // immh:immb = 1xxxxxx 4501259698Sdim let Inst{21-16} = Imm; 4502259698Sdim let Constraints = "$Src = $Rd"; 4503259698Sdim} 4504259698Sdim 4505259698Sdimclass NeonI_ScalarShiftImm_narrow_size<bit u, bits<5> opcode, string asmop, 4506259698Sdim RegisterClass FPRCD, RegisterClass FPRCS, 4507259698Sdim Operand ImmTy> 4508259698Sdim : NeonI_ScalarShiftImm<u, opcode, 4509259698Sdim (outs FPRCD:$Rd), (ins FPRCS:$Rn, ImmTy:$Imm), 4510259698Sdim !strconcat(asmop, "\t$Rd, $Rn, $Imm"), 4511259698Sdim [], NoItinerary>; 4512259698Sdim 4513259698Sdimmulticlass NeonI_ScalarShiftImm_narrow_HSD_size<bit u, bits<5> opcode, 4514259698Sdim string asmop> { 4515259698Sdim def bhi : NeonI_ScalarShiftImm_narrow_size<u, opcode, asmop, FPR8, FPR16, 4516259698Sdim shr_imm8> { 4517259698Sdim bits<3> Imm; 4518259698Sdim let Inst{22-19} = 0b0001; // immh:immb = 0001xxx 4519259698Sdim let Inst{18-16} = Imm; 4520259698Sdim } 4521259698Sdim def hsi : NeonI_ScalarShiftImm_narrow_size<u, opcode, asmop, FPR16, FPR32, 4522259698Sdim shr_imm16> { 4523259698Sdim bits<4> Imm; 4524259698Sdim let Inst{22-20} = 0b001; // immh:immb = 001xxxx 4525259698Sdim let Inst{19-16} = Imm; 4526259698Sdim } 4527259698Sdim def sdi : NeonI_ScalarShiftImm_narrow_size<u, opcode, asmop, FPR32, FPR64, 4528259698Sdim shr_imm32> { 4529259698Sdim bits<5> Imm; 4530259698Sdim let Inst{22-21} = 0b01; // immh:immb = 01xxxxx 4531259698Sdim let Inst{20-16} = Imm; 4532259698Sdim } 4533259698Sdim} 4534259698Sdim 4535259698Sdimmulticlass NeonI_ScalarShiftImm_cvt_SD_size<bit u, bits<5> opcode, string asmop> { 4536259698Sdim def ssi : NeonI_ScalarShiftImm_size<u, opcode, asmop, FPR32, shr_imm32> { 4537259698Sdim bits<5> Imm; 4538259698Sdim let Inst{22-21} = 0b01; // immh:immb = 01xxxxx 4539259698Sdim let Inst{20-16} = Imm; 4540259698Sdim } 4541259698Sdim def ddi : NeonI_ScalarShiftImm_size<u, opcode, asmop, FPR64, shr_imm64> { 4542259698Sdim bits<6> Imm; 4543259698Sdim let Inst{22} = 0b1; // immh:immb = 1xxxxxx 4544259698Sdim let Inst{21-16} = Imm; 4545259698Sdim } 4546259698Sdim} 4547259698Sdim 4548259698Sdimmulticlass Neon_ScalarShiftRImm_D_size_patterns<SDPatternOperator opnode, 4549259698Sdim Instruction INSTD> { 4550259698Sdim def ddi : Pat<(v1i64 (opnode (v1i64 FPR64:$Rn), (i32 shr_imm64:$Imm))), 4551259698Sdim (INSTD FPR64:$Rn, imm:$Imm)>; 4552259698Sdim} 4553259698Sdim 4554259698Sdimmulticlass Neon_ScalarShiftLImm_D_size_patterns<SDPatternOperator opnode, 4555259698Sdim Instruction INSTD> { 4556259698Sdim def ddi : Pat<(v1i64 (opnode (v1i64 FPR64:$Rn), (i32 shl_imm64:$Imm))), 4557259698Sdim (INSTD FPR64:$Rn, imm:$Imm)>; 4558259698Sdim} 4559259698Sdim 4560259698Sdimclass Neon_ScalarShiftImm_arm_D_size_patterns<SDPatternOperator opnode, 4561259698Sdim Instruction INSTD> 4562259698Sdim : Pat<(v1i64 (opnode (v1i64 FPR64:$Rn), 4563259698Sdim (v1i64 (Neon_vdup (i32 shr_imm64:$Imm))))), 4564259698Sdim (INSTD FPR64:$Rn, imm:$Imm)>; 4565259698Sdim 4566259698Sdimmulticlass Neon_ScalarShiftLImm_BHSD_size_patterns<SDPatternOperator opnode, 4567259698Sdim Instruction INSTB, 4568259698Sdim Instruction INSTH, 4569259698Sdim Instruction INSTS, 4570259698Sdim Instruction INSTD> 4571259698Sdim : Neon_ScalarShiftLImm_D_size_patterns<opnode, INSTD> { 4572259698Sdim def bbi : Pat<(v1i8 (opnode (v1i8 FPR8:$Rn), (i32 shl_imm8:$Imm))), 4573259698Sdim (INSTB FPR8:$Rn, imm:$Imm)>; 4574259698Sdim def hhi : Pat<(v1i16 (opnode (v1i16 FPR16:$Rn), (i32 shl_imm16:$Imm))), 4575259698Sdim (INSTH FPR16:$Rn, imm:$Imm)>; 4576259698Sdim def ssi : Pat<(v1i32 (opnode (v1i32 FPR32:$Rn), (i32 shl_imm32:$Imm))), 4577259698Sdim (INSTS FPR32:$Rn, imm:$Imm)>; 4578259698Sdim} 4579259698Sdim 4580259698Sdimclass Neon_ScalarShiftLImm_accum_D_size_patterns<SDPatternOperator opnode, 4581259698Sdim Instruction INSTD> 4582259698Sdim : Pat<(v1i64 (opnode (v1i64 FPR64:$Src), (v1i64 FPR64:$Rn), 4583259698Sdim (i32 shl_imm64:$Imm))), 4584259698Sdim (INSTD FPR64:$Src, FPR64:$Rn, imm:$Imm)>; 4585259698Sdim 4586259698Sdimclass Neon_ScalarShiftRImm_accum_D_size_patterns<SDPatternOperator opnode, 4587259698Sdim Instruction INSTD> 4588259698Sdim : Pat<(v1i64 (opnode (v1i64 FPR64:$Src), (v1i64 FPR64:$Rn), 4589259698Sdim (i32 shr_imm64:$Imm))), 4590259698Sdim (INSTD FPR64:$Src, FPR64:$Rn, imm:$Imm)>; 4591259698Sdim 4592259698Sdimmulticlass Neon_ScalarShiftImm_narrow_HSD_size_patterns< 4593259698Sdim SDPatternOperator opnode, 4594259698Sdim Instruction INSTH, 4595259698Sdim Instruction INSTS, 4596259698Sdim Instruction INSTD> { 4597259698Sdim def bhi : Pat<(v1i8 (opnode (v1i16 FPR16:$Rn), (i32 shr_imm16:$Imm))), 4598259698Sdim (INSTH FPR16:$Rn, imm:$Imm)>; 4599259698Sdim def hsi : Pat<(v1i16 (opnode (v1i32 FPR32:$Rn), (i32 shr_imm32:$Imm))), 4600259698Sdim (INSTS FPR32:$Rn, imm:$Imm)>; 4601259698Sdim def sdi : Pat<(v1i32 (opnode (v1i64 FPR64:$Rn), (i32 shr_imm64:$Imm))), 4602259698Sdim (INSTD FPR64:$Rn, imm:$Imm)>; 4603259698Sdim} 4604259698Sdim 4605259698Sdimmulticlass Neon_ScalarShiftImm_scvtf_SD_size_patterns<SDPatternOperator Sopnode, 4606259698Sdim SDPatternOperator Dopnode, 4607259698Sdim Instruction INSTS, 4608259698Sdim Instruction INSTD> { 4609259698Sdim def ssi : Pat<(f32 (Sopnode (v1i32 FPR32:$Rn), (i32 shr_imm32:$Imm))), 4610259698Sdim (INSTS FPR32:$Rn, imm:$Imm)>; 4611259698Sdim def ddi : Pat<(f64 (Dopnode (v1i64 FPR64:$Rn), (i32 shr_imm64:$Imm))), 4612259698Sdim (INSTD FPR64:$Rn, imm:$Imm)>; 4613259698Sdim} 4614259698Sdim 4615259698Sdimmulticlass Neon_ScalarShiftImm_fcvts_SD_size_patterns<SDPatternOperator Sopnode, 4616259698Sdim SDPatternOperator Dopnode, 4617259698Sdim Instruction INSTS, 4618259698Sdim Instruction INSTD> { 4619259698Sdim def ssi : Pat<(v1i32 (Sopnode (v1f32 FPR32:$Rn), (i32 shr_imm32:$Imm))), 4620259698Sdim (INSTS FPR32:$Rn, imm:$Imm)>; 4621259698Sdim def ddi : Pat<(v1i64 (Dopnode (v1f64 FPR64:$Rn), (i32 shr_imm64:$Imm))), 4622259698Sdim (INSTD FPR64:$Rn, imm:$Imm)>; 4623259698Sdim} 4624259698Sdim 4625259698Sdim// Scalar Signed Shift Right (Immediate) 4626259698Sdimdefm SSHR : NeonI_ScalarShiftRightImm_D_size<0b0, 0b00000, "sshr">; 4627259698Sdimdefm : Neon_ScalarShiftRImm_D_size_patterns<int_aarch64_neon_vshrds_n, SSHRddi>; 4628259698Sdim// Pattern to match llvm.arm.* intrinsic. 4629259698Sdimdef : Neon_ScalarShiftImm_arm_D_size_patterns<sra, SSHRddi>; 4630259698Sdim 4631259698Sdim// Scalar Unsigned Shift Right (Immediate) 4632259698Sdimdefm USHR : NeonI_ScalarShiftRightImm_D_size<0b1, 0b00000, "ushr">; 4633259698Sdimdefm : Neon_ScalarShiftRImm_D_size_patterns<int_aarch64_neon_vshrdu_n, USHRddi>; 4634259698Sdim// Pattern to match llvm.arm.* intrinsic. 4635259698Sdimdef : Neon_ScalarShiftImm_arm_D_size_patterns<srl, USHRddi>; 4636259698Sdim 4637259698Sdim// Scalar Signed Rounding Shift Right (Immediate) 4638259698Sdimdefm SRSHR : NeonI_ScalarShiftRightImm_D_size<0b0, 0b00100, "srshr">; 4639259698Sdimdefm : Neon_ScalarShiftRImm_D_size_patterns<int_aarch64_neon_vsrshr, SRSHRddi>; 4640259698Sdim 4641259698Sdim// Scalar Unigned Rounding Shift Right (Immediate) 4642259698Sdimdefm URSHR : NeonI_ScalarShiftRightImm_D_size<0b1, 0b00100, "urshr">; 4643259698Sdimdefm : Neon_ScalarShiftRImm_D_size_patterns<int_aarch64_neon_vurshr, URSHRddi>; 4644259698Sdim 4645259698Sdim// Scalar Signed Shift Right and Accumulate (Immediate) 4646259698Sdimdef SSRA : NeonI_ScalarShiftRightImm_accum_D_size<0b0, 0b00010, "ssra">; 4647259698Sdimdef : Neon_ScalarShiftRImm_accum_D_size_patterns 4648259698Sdim <int_aarch64_neon_vsrads_n, SSRA>; 4649259698Sdim 4650259698Sdim// Scalar Unsigned Shift Right and Accumulate (Immediate) 4651259698Sdimdef USRA : NeonI_ScalarShiftRightImm_accum_D_size<0b1, 0b00010, "usra">; 4652259698Sdimdef : Neon_ScalarShiftRImm_accum_D_size_patterns 4653259698Sdim <int_aarch64_neon_vsradu_n, USRA>; 4654259698Sdim 4655259698Sdim// Scalar Signed Rounding Shift Right and Accumulate (Immediate) 4656259698Sdimdef SRSRA : NeonI_ScalarShiftRightImm_accum_D_size<0b0, 0b00110, "srsra">; 4657259698Sdimdef : Neon_ScalarShiftRImm_accum_D_size_patterns 4658259698Sdim <int_aarch64_neon_vrsrads_n, SRSRA>; 4659259698Sdim 4660259698Sdim// Scalar Unsigned Rounding Shift Right and Accumulate (Immediate) 4661259698Sdimdef URSRA : NeonI_ScalarShiftRightImm_accum_D_size<0b1, 0b00110, "ursra">; 4662259698Sdimdef : Neon_ScalarShiftRImm_accum_D_size_patterns 4663259698Sdim <int_aarch64_neon_vrsradu_n, URSRA>; 4664259698Sdim 4665259698Sdim// Scalar Shift Left (Immediate) 4666259698Sdimdefm SHL : NeonI_ScalarShiftLeftImm_D_size<0b0, 0b01010, "shl">; 4667259698Sdimdefm : Neon_ScalarShiftLImm_D_size_patterns<int_aarch64_neon_vshld_n, SHLddi>; 4668259698Sdim// Pattern to match llvm.arm.* intrinsic. 4669259698Sdimdef : Neon_ScalarShiftImm_arm_D_size_patterns<shl, SHLddi>; 4670259698Sdim 4671259698Sdim// Signed Saturating Shift Left (Immediate) 4672259698Sdimdefm SQSHL : NeonI_ScalarShiftLeftImm_BHSD_size<0b0, 0b01110, "sqshl">; 4673259698Sdimdefm : Neon_ScalarShiftLImm_BHSD_size_patterns<int_aarch64_neon_vqshls_n, 4674259698Sdim SQSHLbbi, SQSHLhhi, 4675259698Sdim SQSHLssi, SQSHLddi>; 4676259698Sdim// Pattern to match llvm.arm.* intrinsic. 4677259698Sdimdefm : Neon_ScalarShiftLImm_D_size_patterns<Neon_sqrshlImm, SQSHLddi>; 4678259698Sdim 4679259698Sdim// Unsigned Saturating Shift Left (Immediate) 4680259698Sdimdefm UQSHL : NeonI_ScalarShiftLeftImm_BHSD_size<0b1, 0b01110, "uqshl">; 4681259698Sdimdefm : Neon_ScalarShiftLImm_BHSD_size_patterns<int_aarch64_neon_vqshlu_n, 4682259698Sdim UQSHLbbi, UQSHLhhi, 4683259698Sdim UQSHLssi, UQSHLddi>; 4684259698Sdim// Pattern to match llvm.arm.* intrinsic. 4685259698Sdimdefm : Neon_ScalarShiftLImm_D_size_patterns<Neon_uqrshlImm, UQSHLddi>; 4686259698Sdim 4687259698Sdim// Signed Saturating Shift Left Unsigned (Immediate) 4688259698Sdimdefm SQSHLU : NeonI_ScalarShiftLeftImm_BHSD_size<0b1, 0b01100, "sqshlu">; 4689259698Sdimdefm : Neon_ScalarShiftLImm_BHSD_size_patterns<int_aarch64_neon_vsqshlu, 4690259698Sdim SQSHLUbbi, SQSHLUhhi, 4691259698Sdim SQSHLUssi, SQSHLUddi>; 4692259698Sdim 4693259698Sdim// Shift Right And Insert (Immediate) 4694259698Sdimdef SRI : NeonI_ScalarShiftRightImm_accum_D_size<0b1, 0b01000, "sri">; 4695259698Sdimdef : Neon_ScalarShiftRImm_accum_D_size_patterns 4696259698Sdim <int_aarch64_neon_vsri, SRI>; 4697259698Sdim 4698259698Sdim// Shift Left And Insert (Immediate) 4699259698Sdimdef SLI : NeonI_ScalarShiftLeftImm_accum_D_size<0b1, 0b01010, "sli">; 4700259698Sdimdef : Neon_ScalarShiftLImm_accum_D_size_patterns 4701259698Sdim <int_aarch64_neon_vsli, SLI>; 4702259698Sdim 4703259698Sdim// Signed Saturating Shift Right Narrow (Immediate) 4704259698Sdimdefm SQSHRN : NeonI_ScalarShiftImm_narrow_HSD_size<0b0, 0b10010, "sqshrn">; 4705259698Sdimdefm : Neon_ScalarShiftImm_narrow_HSD_size_patterns<int_aarch64_neon_vsqshrn, 4706259698Sdim SQSHRNbhi, SQSHRNhsi, 4707259698Sdim SQSHRNsdi>; 4708259698Sdim 4709259698Sdim// Unsigned Saturating Shift Right Narrow (Immediate) 4710259698Sdimdefm UQSHRN : NeonI_ScalarShiftImm_narrow_HSD_size<0b1, 0b10010, "uqshrn">; 4711259698Sdimdefm : Neon_ScalarShiftImm_narrow_HSD_size_patterns<int_aarch64_neon_vuqshrn, 4712259698Sdim UQSHRNbhi, UQSHRNhsi, 4713259698Sdim UQSHRNsdi>; 4714259698Sdim 4715259698Sdim// Signed Saturating Rounded Shift Right Narrow (Immediate) 4716259698Sdimdefm SQRSHRN : NeonI_ScalarShiftImm_narrow_HSD_size<0b0, 0b10011, "sqrshrn">; 4717259698Sdimdefm : Neon_ScalarShiftImm_narrow_HSD_size_patterns<int_aarch64_neon_vsqrshrn, 4718259698Sdim SQRSHRNbhi, SQRSHRNhsi, 4719259698Sdim SQRSHRNsdi>; 4720259698Sdim 4721259698Sdim// Unsigned Saturating Rounded Shift Right Narrow (Immediate) 4722259698Sdimdefm UQRSHRN : NeonI_ScalarShiftImm_narrow_HSD_size<0b1, 0b10011, "uqrshrn">; 4723259698Sdimdefm : Neon_ScalarShiftImm_narrow_HSD_size_patterns<int_aarch64_neon_vuqrshrn, 4724259698Sdim UQRSHRNbhi, UQRSHRNhsi, 4725259698Sdim UQRSHRNsdi>; 4726259698Sdim 4727259698Sdim// Signed Saturating Shift Right Unsigned Narrow (Immediate) 4728259698Sdimdefm SQSHRUN : NeonI_ScalarShiftImm_narrow_HSD_size<0b1, 0b10000, "sqshrun">; 4729259698Sdimdefm : Neon_ScalarShiftImm_narrow_HSD_size_patterns<int_aarch64_neon_vsqshrun, 4730259698Sdim SQSHRUNbhi, SQSHRUNhsi, 4731259698Sdim SQSHRUNsdi>; 4732259698Sdim 4733259698Sdim// Signed Saturating Rounded Shift Right Unsigned Narrow (Immediate) 4734259698Sdimdefm SQRSHRUN : NeonI_ScalarShiftImm_narrow_HSD_size<0b1, 0b10001, "sqrshrun">; 4735259698Sdimdefm : Neon_ScalarShiftImm_narrow_HSD_size_patterns<int_aarch64_neon_vsqrshrun, 4736259698Sdim SQRSHRUNbhi, SQRSHRUNhsi, 4737259698Sdim SQRSHRUNsdi>; 4738259698Sdim 4739259698Sdim// Scalar Signed Fixed-point Convert To Floating-Point (Immediate) 4740259698Sdimdefm SCVTF_N : NeonI_ScalarShiftImm_cvt_SD_size<0b0, 0b11100, "scvtf">; 4741259698Sdimdefm : Neon_ScalarShiftImm_scvtf_SD_size_patterns<int_aarch64_neon_vcvtf32_n_s32, 4742259698Sdim int_aarch64_neon_vcvtf64_n_s64, 4743259698Sdim SCVTF_Nssi, SCVTF_Nddi>; 4744259698Sdim 4745259698Sdim// Scalar Unsigned Fixed-point Convert To Floating-Point (Immediate) 4746259698Sdimdefm UCVTF_N : NeonI_ScalarShiftImm_cvt_SD_size<0b1, 0b11100, "ucvtf">; 4747259698Sdimdefm : Neon_ScalarShiftImm_scvtf_SD_size_patterns<int_aarch64_neon_vcvtf32_n_u32, 4748259698Sdim int_aarch64_neon_vcvtf64_n_u64, 4749259698Sdim UCVTF_Nssi, UCVTF_Nddi>; 4750259698Sdim 4751259698Sdim// Scalar Floating-point Convert To Signed Fixed-point (Immediate) 4752259698Sdimdefm FCVTZS_N : NeonI_ScalarShiftImm_cvt_SD_size<0b0, 0b11111, "fcvtzs">; 4753259698Sdimdefm : Neon_ScalarShiftImm_fcvts_SD_size_patterns<int_aarch64_neon_vcvts_n_s32_f32, 4754259698Sdim int_aarch64_neon_vcvtd_n_s64_f64, 4755259698Sdim FCVTZS_Nssi, FCVTZS_Nddi>; 4756259698Sdim 4757259698Sdim// Scalar Floating-point Convert To Unsigned Fixed-point (Immediate) 4758259698Sdimdefm FCVTZU_N : NeonI_ScalarShiftImm_cvt_SD_size<0b1, 0b11111, "fcvtzu">; 4759259698Sdimdefm : Neon_ScalarShiftImm_fcvts_SD_size_patterns<int_aarch64_neon_vcvts_n_u32_f32, 4760259698Sdim int_aarch64_neon_vcvtd_n_u64_f64, 4761259698Sdim FCVTZU_Nssi, FCVTZU_Nddi>; 4762259698Sdim 4763259698Sdim// Patterns For Convert Instructions Between v1f64 and v1i64 4764259698Sdimclass Neon_ScalarShiftImm_cvtf_v1f64_pattern<SDPatternOperator opnode, 4765259698Sdim Instruction INST> 4766259698Sdim : Pat<(v1f64 (opnode (v1i64 FPR64:$Rn), (i32 shr_imm64:$Imm))), 4767259698Sdim (INST FPR64:$Rn, imm:$Imm)>; 4768259698Sdim 4769259698Sdimclass Neon_ScalarShiftImm_fcvt_v1f64_pattern<SDPatternOperator opnode, 4770259698Sdim Instruction INST> 4771259698Sdim : Pat<(v1i64 (opnode (v1f64 FPR64:$Rn), (i32 shr_imm64:$Imm))), 4772259698Sdim (INST FPR64:$Rn, imm:$Imm)>; 4773259698Sdim 4774259698Sdimdef : Neon_ScalarShiftImm_cvtf_v1f64_pattern<int_arm_neon_vcvtfxs2fp, 4775259698Sdim SCVTF_Nddi>; 4776259698Sdim 4777259698Sdimdef : Neon_ScalarShiftImm_cvtf_v1f64_pattern<int_arm_neon_vcvtfxu2fp, 4778259698Sdim UCVTF_Nddi>; 4779259698Sdim 4780259698Sdimdef : Neon_ScalarShiftImm_fcvt_v1f64_pattern<int_arm_neon_vcvtfp2fxs, 4781259698Sdim FCVTZS_Nddi>; 4782259698Sdim 4783259698Sdimdef : Neon_ScalarShiftImm_fcvt_v1f64_pattern<int_arm_neon_vcvtfp2fxu, 4784259698Sdim FCVTZU_Nddi>; 4785259698Sdim 4786259698Sdim// Scalar Integer Add 4787259698Sdimlet isCommutable = 1 in { 4788259698Sdimdef ADDddd : NeonI_Scalar3Same_D_size<0b0, 0b10000, "add">; 4789259698Sdim} 4790259698Sdim 4791259698Sdim// Scalar Integer Sub 4792259698Sdimdef SUBddd : NeonI_Scalar3Same_D_size<0b1, 0b10000, "sub">; 4793259698Sdim 4794259698Sdim// Pattern for Scalar Integer Add and Sub with D register only 4795259698Sdimdefm : Neon_Scalar3Same_D_size_patterns<add, ADDddd>; 4796259698Sdimdefm : Neon_Scalar3Same_D_size_patterns<sub, SUBddd>; 4797259698Sdim 4798259698Sdim// Patterns to match llvm.aarch64.* intrinsic for Scalar Add, Sub 4799259698Sdimdefm : Neon_Scalar3Same_D_size_patterns<int_aarch64_neon_vaddds, ADDddd>; 4800259698Sdimdefm : Neon_Scalar3Same_D_size_patterns<int_aarch64_neon_vadddu, ADDddd>; 4801259698Sdimdefm : Neon_Scalar3Same_D_size_patterns<int_aarch64_neon_vsubds, SUBddd>; 4802259698Sdimdefm : Neon_Scalar3Same_D_size_patterns<int_aarch64_neon_vsubdu, SUBddd>; 4803259698Sdim 4804259698Sdim// Scalar Integer Saturating Add (Signed, Unsigned) 4805259698Sdimdefm SQADD : NeonI_Scalar3Same_BHSD_sizes<0b0, 0b00001, "sqadd", 1>; 4806259698Sdimdefm UQADD : NeonI_Scalar3Same_BHSD_sizes<0b1, 0b00001, "uqadd", 1>; 4807259698Sdim 4808259698Sdim// Scalar Integer Saturating Sub (Signed, Unsigned) 4809259698Sdimdefm SQSUB : NeonI_Scalar3Same_BHSD_sizes<0b0, 0b00101, "sqsub", 0>; 4810259698Sdimdefm UQSUB : NeonI_Scalar3Same_BHSD_sizes<0b1, 0b00101, "uqsub", 0>; 4811259698Sdim 4812259698Sdim 4813259698Sdim// Patterns to match llvm.aarch64.* intrinsic for 4814259698Sdim// Scalar Integer Saturating Add, Sub (Signed, Unsigned) 4815259698Sdimdefm : Neon_Scalar3Same_BHSD_size_patterns<int_arm_neon_vqadds, SQADDbbb, 4816259698Sdim SQADDhhh, SQADDsss, SQADDddd>; 4817259698Sdimdefm : Neon_Scalar3Same_BHSD_size_patterns<int_arm_neon_vqaddu, UQADDbbb, 4818259698Sdim UQADDhhh, UQADDsss, UQADDddd>; 4819259698Sdimdefm : Neon_Scalar3Same_BHSD_size_patterns<int_arm_neon_vqsubs, SQSUBbbb, 4820259698Sdim SQSUBhhh, SQSUBsss, SQSUBddd>; 4821259698Sdimdefm : Neon_Scalar3Same_BHSD_size_patterns<int_arm_neon_vqsubu, UQSUBbbb, 4822259698Sdim UQSUBhhh, UQSUBsss, UQSUBddd>; 4823259698Sdim 4824259698Sdim// Scalar Integer Saturating Doubling Multiply Half High 4825259698Sdimdefm SQDMULH : NeonI_Scalar3Same_HS_sizes<0b0, 0b10110, "sqdmulh", 1>; 4826259698Sdim 4827259698Sdim// Scalar Integer Saturating Rounding Doubling Multiply Half High 4828259698Sdimdefm SQRDMULH : NeonI_Scalar3Same_HS_sizes<0b1, 0b10110, "sqrdmulh", 1>; 4829259698Sdim 4830259698Sdim// Patterns to match llvm.arm.* intrinsic for 4831259698Sdim// Scalar Integer Saturating Doubling Multiply Half High and 4832259698Sdim// Scalar Integer Saturating Rounding Doubling Multiply Half High 4833259698Sdimdefm : Neon_Scalar3Same_HS_size_patterns<int_arm_neon_vqdmulh, SQDMULHhhh, 4834259698Sdim SQDMULHsss>; 4835259698Sdimdefm : Neon_Scalar3Same_HS_size_patterns<int_arm_neon_vqrdmulh, SQRDMULHhhh, 4836259698Sdim SQRDMULHsss>; 4837259698Sdim 4838259698Sdim// Scalar Floating-point Multiply Extended 4839259698Sdimdefm FMULX : NeonI_Scalar3Same_SD_sizes<0b0, 0b0, 0b11011, "fmulx", 1>; 4840259698Sdim 4841259698Sdim// Scalar Floating-point Reciprocal Step 4842259698Sdimdefm FRECPS : NeonI_Scalar3Same_SD_sizes<0b0, 0b0, 0b11111, "frecps", 0>; 4843259698Sdim 4844259698Sdim// Scalar Floating-point Reciprocal Square Root Step 4845259698Sdimdefm FRSQRTS : NeonI_Scalar3Same_SD_sizes<0b0, 0b1, 0b11111, "frsqrts", 0>; 4846259698Sdim 4847259698Sdim// Patterns to match llvm.arm.* intrinsic for 4848259698Sdim// Scalar Floating-point Reciprocal Step and 4849259698Sdim// Scalar Floating-point Reciprocal Square Root Step 4850259698Sdimdefm : Neon_Scalar3Same_SD_size_patterns<int_arm_neon_vrecps, FRECPSsss, 4851259698Sdim FRECPSddd>; 4852259698Sdimdefm : Neon_Scalar3Same_SD_size_patterns<int_arm_neon_vrsqrts, FRSQRTSsss, 4853259698Sdim FRSQRTSddd>; 4854259698Sdim 4855259698Sdimdef : Pat<(v1f64 (fsqrt (v1f64 FPR64:$Rn))), (FSQRTdd FPR64:$Rn)>; 4856259698Sdim 4857259698Sdim// Patterns to match llvm.aarch64.* intrinsic for 4858259698Sdim// Scalar Floating-point Multiply Extended, 4859259698Sdimmulticlass Neon_Scalar3Same_MULX_SD_size_patterns<SDPatternOperator opnode, 4860259698Sdim Instruction INSTS, 4861259698Sdim Instruction INSTD> { 4862259698Sdim def : Pat<(f32 (opnode (f32 FPR32:$Rn), (f32 FPR32:$Rm))), 4863259698Sdim (INSTS FPR32:$Rn, FPR32:$Rm)>; 4864259698Sdim def : Pat<(f64 (opnode (f64 FPR64:$Rn), (f64 FPR64:$Rm))), 4865259698Sdim (INSTD FPR64:$Rn, FPR64:$Rm)>; 4866259698Sdim} 4867259698Sdim 4868259698Sdimdefm : Neon_Scalar3Same_MULX_SD_size_patterns<int_aarch64_neon_vmulx, 4869259698Sdim FMULXsss,FMULXddd>; 4870259698Sdim 4871259698Sdim// Scalar Integer Shift Left (Signed, Unsigned) 4872259698Sdimdef SSHLddd : NeonI_Scalar3Same_D_size<0b0, 0b01000, "sshl">; 4873259698Sdimdef USHLddd : NeonI_Scalar3Same_D_size<0b1, 0b01000, "ushl">; 4874259698Sdim 4875259698Sdim// Patterns to match llvm.arm.* intrinsic for 4876259698Sdim// Scalar Integer Shift Left (Signed, Unsigned) 4877259698Sdimdefm : Neon_Scalar3Same_D_size_patterns<int_arm_neon_vshifts, SSHLddd>; 4878259698Sdimdefm : Neon_Scalar3Same_D_size_patterns<int_arm_neon_vshiftu, USHLddd>; 4879259698Sdim 4880259698Sdim// Patterns to match llvm.aarch64.* intrinsic for 4881259698Sdim// Scalar Integer Shift Left (Signed, Unsigned) 4882259698Sdimdefm : Neon_Scalar3Same_D_size_patterns<int_aarch64_neon_vshlds, SSHLddd>; 4883259698Sdimdefm : Neon_Scalar3Same_D_size_patterns<int_aarch64_neon_vshldu, USHLddd>; 4884259698Sdim 4885259698Sdim// Scalar Integer Saturating Shift Left (Signed, Unsigned) 4886259698Sdimdefm SQSHL: NeonI_Scalar3Same_BHSD_sizes<0b0, 0b01001, "sqshl", 0>; 4887259698Sdimdefm UQSHL: NeonI_Scalar3Same_BHSD_sizes<0b1, 0b01001, "uqshl", 0>; 4888259698Sdim 4889259698Sdim// Patterns to match llvm.aarch64.* intrinsic for 4890259698Sdim// Scalar Integer Saturating Shift Letf (Signed, Unsigned) 4891259698Sdimdefm : Neon_Scalar3Same_BHSD_size_patterns<int_aarch64_neon_vqshls, SQSHLbbb, 4892259698Sdim SQSHLhhh, SQSHLsss, SQSHLddd>; 4893259698Sdimdefm : Neon_Scalar3Same_BHSD_size_patterns<int_aarch64_neon_vqshlu, UQSHLbbb, 4894259698Sdim UQSHLhhh, UQSHLsss, UQSHLddd>; 4895259698Sdim 4896259698Sdim// Patterns to match llvm.arm.* intrinsic for 4897259698Sdim// Scalar Integer Saturating Shift Letf (Signed, Unsigned) 4898259698Sdimdefm : Neon_Scalar3Same_D_size_patterns<int_arm_neon_vqshifts, SQSHLddd>; 4899259698Sdimdefm : Neon_Scalar3Same_D_size_patterns<int_arm_neon_vqshiftu, UQSHLddd>; 4900259698Sdim 4901259698Sdim// Scalar Integer Rounding Shift Left (Signed, Unsigned) 4902259698Sdimdef SRSHLddd: NeonI_Scalar3Same_D_size<0b0, 0b01010, "srshl">; 4903259698Sdimdef URSHLddd: NeonI_Scalar3Same_D_size<0b1, 0b01010, "urshl">; 4904259698Sdim 4905259698Sdim// Patterns to match llvm.aarch64.* intrinsic for 4906259698Sdim// Scalar Integer Rounding Shift Left (Signed, Unsigned) 4907259698Sdimdefm : Neon_Scalar3Same_D_size_patterns<int_aarch64_neon_vrshlds, SRSHLddd>; 4908259698Sdimdefm : Neon_Scalar3Same_D_size_patterns<int_aarch64_neon_vrshldu, URSHLddd>; 4909259698Sdim 4910259698Sdim// Patterns to match llvm.arm.* intrinsic for 4911259698Sdim// Scalar Integer Rounding Shift Left (Signed, Unsigned) 4912259698Sdimdefm : Neon_Scalar3Same_D_size_patterns<int_arm_neon_vrshifts, SRSHLddd>; 4913259698Sdimdefm : Neon_Scalar3Same_D_size_patterns<int_arm_neon_vrshiftu, URSHLddd>; 4914259698Sdim 4915259698Sdim// Scalar Integer Saturating Rounding Shift Left (Signed, Unsigned) 4916259698Sdimdefm SQRSHL: NeonI_Scalar3Same_BHSD_sizes<0b0, 0b01011, "sqrshl", 0>; 4917259698Sdimdefm UQRSHL: NeonI_Scalar3Same_BHSD_sizes<0b1, 0b01011, "uqrshl", 0>; 4918259698Sdim 4919259698Sdim// Patterns to match llvm.aarch64.* intrinsic for 4920259698Sdim// Scalar Integer Saturating Rounding Shift Left (Signed, Unsigned) 4921259698Sdimdefm : Neon_Scalar3Same_BHSD_size_patterns<int_aarch64_neon_vqrshls, SQRSHLbbb, 4922259698Sdim SQRSHLhhh, SQRSHLsss, SQRSHLddd>; 4923259698Sdimdefm : Neon_Scalar3Same_BHSD_size_patterns<int_aarch64_neon_vqrshlu, UQRSHLbbb, 4924259698Sdim UQRSHLhhh, UQRSHLsss, UQRSHLddd>; 4925259698Sdim 4926259698Sdim// Patterns to match llvm.arm.* intrinsic for 4927259698Sdim// Scalar Integer Saturating Rounding Shift Left (Signed, Unsigned) 4928259698Sdimdefm : Neon_Scalar3Same_D_size_patterns<int_arm_neon_vqrshifts, SQRSHLddd>; 4929259698Sdimdefm : Neon_Scalar3Same_D_size_patterns<int_arm_neon_vqrshiftu, UQRSHLddd>; 4930259698Sdim 4931259698Sdim// Signed Saturating Doubling Multiply-Add Long 4932259698Sdimdefm SQDMLAL : NeonI_Scalar3Diff_ml_HS_size<0b0, 0b1001, "sqdmlal">; 4933259698Sdimdefm : Neon_Scalar3Diff_ml_HS_size_patterns<int_aarch64_neon_vqdmlal, 4934259698Sdim SQDMLALshh, SQDMLALdss>; 4935259698Sdim 4936259698Sdim// Signed Saturating Doubling Multiply-Subtract Long 4937259698Sdimdefm SQDMLSL : NeonI_Scalar3Diff_ml_HS_size<0b0, 0b1011, "sqdmlsl">; 4938259698Sdimdefm : Neon_Scalar3Diff_ml_HS_size_patterns<int_aarch64_neon_vqdmlsl, 4939259698Sdim SQDMLSLshh, SQDMLSLdss>; 4940259698Sdim 4941259698Sdim// Signed Saturating Doubling Multiply Long 4942259698Sdimdefm SQDMULL : NeonI_Scalar3Diff_HS_size<0b0, 0b1101, "sqdmull">; 4943259698Sdimdefm : Neon_Scalar3Diff_HS_size_patterns<int_arm_neon_vqdmull, 4944259698Sdim SQDMULLshh, SQDMULLdss>; 4945259698Sdim 4946259698Sdim// Scalar Signed Integer Convert To Floating-point 4947259698Sdimdefm SCVTF : NeonI_Scalar2SameMisc_SD_size<0b0, 0b0, 0b11101, "scvtf">; 4948259698Sdimdefm : Neon_Scalar2SameMisc_cvt_SD_size_patterns<int_aarch64_neon_vcvtf32_s32, 4949259698Sdim int_aarch64_neon_vcvtf64_s64, 4950259698Sdim SCVTFss, SCVTFdd>; 4951259698Sdim 4952259698Sdim// Scalar Unsigned Integer Convert To Floating-point 4953259698Sdimdefm UCVTF : NeonI_Scalar2SameMisc_SD_size<0b1, 0b0, 0b11101, "ucvtf">; 4954259698Sdimdefm : Neon_Scalar2SameMisc_cvt_SD_size_patterns<int_aarch64_neon_vcvtf32_u32, 4955259698Sdim int_aarch64_neon_vcvtf64_u64, 4956259698Sdim UCVTFss, UCVTFdd>; 4957259698Sdim 4958259698Sdim// Scalar Floating-point Converts 4959259698Sdimdef FCVTXN : NeonI_Scalar2SameMisc_fcvtxn_D_size<0b1, 0b10110, "fcvtxn">; 4960259698Sdimdef : Neon_Scalar2SameMisc_fcvtxn_D_size_patterns<int_aarch64_neon_fcvtxn, 4961259698Sdim FCVTXN>; 4962259698Sdim 4963259698Sdimdefm FCVTNS : NeonI_Scalar2SameMisc_SD_size<0b0, 0b0, 0b11010, "fcvtns">; 4964259698Sdimdefm : Neon_Scalar2SameMisc_fcvt_SD_size_patterns<int_aarch64_neon_fcvtns, 4965259698Sdim FCVTNSss, FCVTNSdd>; 4966259698Sdim 4967259698Sdimdefm FCVTNU : NeonI_Scalar2SameMisc_SD_size<0b1, 0b0, 0b11010, "fcvtnu">; 4968259698Sdimdefm : Neon_Scalar2SameMisc_fcvt_SD_size_patterns<int_aarch64_neon_fcvtnu, 4969259698Sdim FCVTNUss, FCVTNUdd>; 4970259698Sdim 4971259698Sdimdefm FCVTMS : NeonI_Scalar2SameMisc_SD_size<0b0, 0b0, 0b11011, "fcvtms">; 4972259698Sdimdefm : Neon_Scalar2SameMisc_fcvt_SD_size_patterns<int_aarch64_neon_fcvtms, 4973259698Sdim FCVTMSss, FCVTMSdd>; 4974259698Sdim 4975259698Sdimdefm FCVTMU : NeonI_Scalar2SameMisc_SD_size<0b1, 0b0, 0b11011, "fcvtmu">; 4976259698Sdimdefm : Neon_Scalar2SameMisc_fcvt_SD_size_patterns<int_aarch64_neon_fcvtmu, 4977259698Sdim FCVTMUss, FCVTMUdd>; 4978259698Sdim 4979259698Sdimdefm FCVTAS : NeonI_Scalar2SameMisc_SD_size<0b0, 0b0, 0b11100, "fcvtas">; 4980259698Sdimdefm : Neon_Scalar2SameMisc_fcvt_SD_size_patterns<int_aarch64_neon_fcvtas, 4981259698Sdim FCVTASss, FCVTASdd>; 4982259698Sdim 4983259698Sdimdefm FCVTAU : NeonI_Scalar2SameMisc_SD_size<0b1, 0b0, 0b11100, "fcvtau">; 4984259698Sdimdefm : Neon_Scalar2SameMisc_fcvt_SD_size_patterns<int_aarch64_neon_fcvtau, 4985259698Sdim FCVTAUss, FCVTAUdd>; 4986259698Sdim 4987259698Sdimdefm FCVTPS : NeonI_Scalar2SameMisc_SD_size<0b0, 0b1, 0b11010, "fcvtps">; 4988259698Sdimdefm : Neon_Scalar2SameMisc_fcvt_SD_size_patterns<int_aarch64_neon_fcvtps, 4989259698Sdim FCVTPSss, FCVTPSdd>; 4990259698Sdim 4991259698Sdimdefm FCVTPU : NeonI_Scalar2SameMisc_SD_size<0b1, 0b1, 0b11010, "fcvtpu">; 4992259698Sdimdefm : Neon_Scalar2SameMisc_fcvt_SD_size_patterns<int_aarch64_neon_fcvtpu, 4993259698Sdim FCVTPUss, FCVTPUdd>; 4994259698Sdim 4995259698Sdimdefm FCVTZS : NeonI_Scalar2SameMisc_SD_size<0b0, 0b1, 0b11011, "fcvtzs">; 4996259698Sdimdefm : Neon_Scalar2SameMisc_fcvt_SD_size_patterns<int_aarch64_neon_fcvtzs, 4997259698Sdim FCVTZSss, FCVTZSdd>; 4998259698Sdim 4999259698Sdimdefm FCVTZU : NeonI_Scalar2SameMisc_SD_size<0b1, 0b1, 0b11011, "fcvtzu">; 5000259698Sdimdefm : Neon_Scalar2SameMisc_fcvt_SD_size_patterns<int_aarch64_neon_fcvtzu, 5001259698Sdim FCVTZUss, FCVTZUdd>; 5002259698Sdim 5003259698Sdim// Patterns For Convert Instructions Between v1f64 and v1i64 5004259698Sdimclass Neon_Scalar2SameMisc_cvtf_v1f64_pattern<SDPatternOperator opnode, 5005259698Sdim Instruction INST> 5006259698Sdim : Pat<(v1f64 (opnode (v1i64 FPR64:$Rn))), (INST FPR64:$Rn)>; 5007259698Sdim 5008259698Sdimclass Neon_Scalar2SameMisc_fcvt_v1f64_pattern<SDPatternOperator opnode, 5009259698Sdim Instruction INST> 5010259698Sdim : Pat<(v1i64 (opnode (v1f64 FPR64:$Rn))), (INST FPR64:$Rn)>; 5011259698Sdim 5012259698Sdimdef : Neon_Scalar2SameMisc_cvtf_v1f64_pattern<sint_to_fp, SCVTFdd>; 5013259698Sdimdef : Neon_Scalar2SameMisc_cvtf_v1f64_pattern<uint_to_fp, UCVTFdd>; 5014259698Sdim 5015259698Sdimdef : Neon_Scalar2SameMisc_fcvt_v1f64_pattern<fp_to_sint, FCVTZSdd>; 5016259698Sdimdef : Neon_Scalar2SameMisc_fcvt_v1f64_pattern<fp_to_uint, FCVTZUdd>; 5017259698Sdim 5018259698Sdim// Scalar Floating-point Reciprocal Estimate 5019259698Sdimdefm FRECPE : NeonI_Scalar2SameMisc_SD_size<0b0, 0b1, 0b11101, "frecpe">; 5020259698Sdimdefm : Neon_Scalar2SameMisc_SD_size_patterns<int_arm_neon_vrecpe, 5021259698Sdim FRECPEss, FRECPEdd>; 5022259698Sdim 5023259698Sdim// Scalar Floating-point Reciprocal Exponent 5024259698Sdimdefm FRECPX : NeonI_Scalar2SameMisc_SD_size<0b0, 0b1, 0b11111, "frecpx">; 5025259698Sdimdefm : Neon_Scalar2SameMisc_SD_size_patterns<int_aarch64_neon_vrecpx, 5026259698Sdim FRECPXss, FRECPXdd>; 5027259698Sdim 5028259698Sdim// Scalar Floating-point Reciprocal Square Root Estimate 5029259698Sdimdefm FRSQRTE: NeonI_Scalar2SameMisc_SD_size<0b1, 0b1, 0b11101, "frsqrte">; 5030259698Sdimdefm : Neon_Scalar2SameMisc_SD_size_patterns<int_arm_neon_vrsqrte, 5031259698Sdim FRSQRTEss, FRSQRTEdd>; 5032259698Sdim 5033259698Sdim// Scalar Floating-point Round 5034259698Sdimclass Neon_ScalarFloatRound_pattern<SDPatternOperator opnode, Instruction INST> 5035259698Sdim : Pat<(v1f64 (opnode (v1f64 FPR64:$Rn))), (INST FPR64:$Rn)>; 5036259698Sdim 5037259698Sdimdef : Neon_ScalarFloatRound_pattern<fceil, FRINTPdd>; 5038259698Sdimdef : Neon_ScalarFloatRound_pattern<ffloor, FRINTMdd>; 5039259698Sdimdef : Neon_ScalarFloatRound_pattern<ftrunc, FRINTZdd>; 5040259698Sdimdef : Neon_ScalarFloatRound_pattern<frint, FRINTXdd>; 5041259698Sdimdef : Neon_ScalarFloatRound_pattern<fnearbyint, FRINTIdd>; 5042259698Sdimdef : Neon_ScalarFloatRound_pattern<frnd, FRINTAdd>; 5043259698Sdimdef : Neon_ScalarFloatRound_pattern<int_aarch64_neon_frintn, FRINTNdd>; 5044259698Sdim 5045259698Sdim// Scalar Integer Compare 5046259698Sdim 5047259698Sdim// Scalar Compare Bitwise Equal 5048259698Sdimdef CMEQddd: NeonI_Scalar3Same_D_size<0b1, 0b10001, "cmeq">; 5049259698Sdimdef : Neon_Scalar3Same_cmp_D_size_patterns<int_aarch64_neon_vceq, CMEQddd>; 5050259698Sdim 5051259698Sdimclass Neon_Scalar3Same_cmp_D_size_v1_patterns<SDPatternOperator opnode, 5052259698Sdim Instruction INSTD, 5053259698Sdim CondCode CC> 5054259698Sdim : Pat<(v1i64 (opnode (v1i64 FPR64:$Rn), (v1i64 FPR64:$Rm), CC)), 5055259698Sdim (INSTD FPR64:$Rn, FPR64:$Rm)>; 5056259698Sdim 5057259698Sdimdef : Neon_Scalar3Same_cmp_D_size_v1_patterns<Neon_cmp, CMEQddd, SETEQ>; 5058259698Sdim 5059259698Sdim// Scalar Compare Signed Greather Than Or Equal 5060259698Sdimdef CMGEddd: NeonI_Scalar3Same_D_size<0b0, 0b00111, "cmge">; 5061259698Sdimdef : Neon_Scalar3Same_cmp_D_size_patterns<int_aarch64_neon_vcge, CMGEddd>; 5062259698Sdimdef : Neon_Scalar3Same_cmp_D_size_v1_patterns<Neon_cmp, CMGEddd, SETGE>; 5063259698Sdim 5064259698Sdim// Scalar Compare Unsigned Higher Or Same 5065259698Sdimdef CMHSddd: NeonI_Scalar3Same_D_size<0b1, 0b00111, "cmhs">; 5066259698Sdimdef : Neon_Scalar3Same_cmp_D_size_patterns<int_aarch64_neon_vchs, CMHSddd>; 5067259698Sdimdef : Neon_Scalar3Same_cmp_D_size_v1_patterns<Neon_cmp, CMHSddd, SETUGE>; 5068259698Sdim 5069259698Sdim// Scalar Compare Unsigned Higher 5070259698Sdimdef CMHIddd: NeonI_Scalar3Same_D_size<0b1, 0b00110, "cmhi">; 5071259698Sdimdef : Neon_Scalar3Same_cmp_D_size_patterns<int_aarch64_neon_vchi, CMHIddd>; 5072259698Sdimdef : Neon_Scalar3Same_cmp_D_size_v1_patterns<Neon_cmp, CMHIddd, SETUGT>; 5073259698Sdim 5074259698Sdim// Scalar Compare Signed Greater Than 5075259698Sdimdef CMGTddd: NeonI_Scalar3Same_D_size<0b0, 0b00110, "cmgt">; 5076259698Sdimdef : Neon_Scalar3Same_cmp_D_size_patterns<int_aarch64_neon_vcgt, CMGTddd>; 5077259698Sdimdef : Neon_Scalar3Same_cmp_D_size_v1_patterns<Neon_cmp, CMGTddd, SETGT>; 5078259698Sdim 5079259698Sdim// Scalar Compare Bitwise Test Bits 5080259698Sdimdef CMTSTddd: NeonI_Scalar3Same_D_size<0b0, 0b10001, "cmtst">; 5081259698Sdimdef : Neon_Scalar3Same_cmp_D_size_patterns<int_aarch64_neon_vtstd, CMTSTddd>; 5082259698Sdimdef : Neon_Scalar3Same_cmp_D_size_patterns<Neon_tst, CMTSTddd>; 5083259698Sdim 5084259698Sdim// Scalar Compare Bitwise Equal To Zero 5085259698Sdimdef CMEQddi: NeonI_Scalar2SameMisc_cmpz_D_size<0b0, 0b01001, "cmeq">; 5086259698Sdimdef : Neon_Scalar2SameMisc_cmpz_D_size_patterns<int_aarch64_neon_vceq, 5087259698Sdim CMEQddi>; 5088259698Sdimdef : Neon_Scalar2SameMisc_cmpz_D_V1_size_patterns<SETEQ, CMEQddi>; 5089259698Sdim 5090259698Sdim// Scalar Compare Signed Greather Than Or Equal To Zero 5091259698Sdimdef CMGEddi: NeonI_Scalar2SameMisc_cmpz_D_size<0b1, 0b01000, "cmge">; 5092259698Sdimdef : Neon_Scalar2SameMisc_cmpz_D_size_patterns<int_aarch64_neon_vcge, 5093259698Sdim CMGEddi>; 5094259698Sdimdef : Neon_Scalar2SameMisc_cmpz_D_V1_size_patterns<SETGE, CMGEddi>; 5095259698Sdim 5096259698Sdim// Scalar Compare Signed Greater Than Zero 5097259698Sdimdef CMGTddi: NeonI_Scalar2SameMisc_cmpz_D_size<0b0, 0b01000, "cmgt">; 5098259698Sdimdef : Neon_Scalar2SameMisc_cmpz_D_size_patterns<int_aarch64_neon_vcgt, 5099259698Sdim CMGTddi>; 5100259698Sdimdef : Neon_Scalar2SameMisc_cmpz_D_V1_size_patterns<SETGT, CMGTddi>; 5101259698Sdim 5102259698Sdim// Scalar Compare Signed Less Than Or Equal To Zero 5103259698Sdimdef CMLEddi: NeonI_Scalar2SameMisc_cmpz_D_size<0b1, 0b01001, "cmle">; 5104259698Sdimdef : Neon_Scalar2SameMisc_cmpz_D_size_patterns<int_aarch64_neon_vclez, 5105259698Sdim CMLEddi>; 5106259698Sdimdef : Neon_Scalar2SameMisc_cmpz_D_V1_size_patterns<SETLE, CMLEddi>; 5107259698Sdim 5108259698Sdim// Scalar Compare Less Than Zero 5109259698Sdimdef CMLTddi: NeonI_Scalar2SameMisc_cmpz_D_size<0b0, 0b01010, "cmlt">; 5110259698Sdimdef : Neon_Scalar2SameMisc_cmpz_D_size_patterns<int_aarch64_neon_vcltz, 5111259698Sdim CMLTddi>; 5112259698Sdimdef : Neon_Scalar2SameMisc_cmpz_D_V1_size_patterns<SETLT, CMLTddi>; 5113259698Sdim 5114259698Sdim// Scalar Floating-point Compare 5115259698Sdim 5116259698Sdim// Scalar Floating-point Compare Mask Equal 5117259698Sdimdefm FCMEQ: NeonI_Scalar3Same_SD_sizes<0b0, 0b0, 0b11100, "fcmeq">; 5118259698Sdimdefm : Neon_Scalar3Same_cmp_SD_size_patterns<int_aarch64_neon_vceq, 5119259698Sdim FCMEQsss, FCMEQddd>; 5120259698Sdimdef : Neon_Scalar3Same_cmp_V1_D_size_patterns<SETEQ, FCMEQddd>; 5121259698Sdim 5122259698Sdim// Scalar Floating-point Compare Mask Equal To Zero 5123259698Sdimdefm FCMEQZ: NeonI_Scalar2SameMisc_cmpz_SD_size<0b0, 0b01101, "fcmeq">; 5124259698Sdimdefm : Neon_Scalar2SameMisc_cmpz_SD_size_patterns<int_aarch64_neon_vceq, 5125259698Sdim FCMEQZssi, FCMEQZddi>; 5126259698Sdimdef : Pat<(v1i64 (Neon_cmpz (v1f64 FPR64:$Rn), (f32 fpz32:$FPImm), SETEQ)), 5127259698Sdim (FCMEQZddi FPR64:$Rn, fpz32:$FPImm)>; 5128259698Sdim 5129259698Sdim// Scalar Floating-point Compare Mask Greater Than Or Equal 5130259698Sdimdefm FCMGE: NeonI_Scalar3Same_SD_sizes<0b1, 0b0, 0b11100, "fcmge">; 5131259698Sdimdefm : Neon_Scalar3Same_cmp_SD_size_patterns<int_aarch64_neon_vcge, 5132259698Sdim FCMGEsss, FCMGEddd>; 5133259698Sdimdef : Neon_Scalar3Same_cmp_V1_D_size_patterns<SETGE, FCMGEddd>; 5134259698Sdim 5135259698Sdim// Scalar Floating-point Compare Mask Greater Than Or Equal To Zero 5136259698Sdimdefm FCMGEZ: NeonI_Scalar2SameMisc_cmpz_SD_size<0b1, 0b01100, "fcmge">; 5137259698Sdimdefm : Neon_Scalar2SameMisc_cmpz_SD_size_patterns<int_aarch64_neon_vcge, 5138259698Sdim FCMGEZssi, FCMGEZddi>; 5139259698Sdim 5140259698Sdim// Scalar Floating-point Compare Mask Greather Than 5141259698Sdimdefm FCMGT: NeonI_Scalar3Same_SD_sizes<0b1, 0b1, 0b11100, "fcmgt">; 5142259698Sdimdefm : Neon_Scalar3Same_cmp_SD_size_patterns<int_aarch64_neon_vcgt, 5143259698Sdim FCMGTsss, FCMGTddd>; 5144259698Sdimdef : Neon_Scalar3Same_cmp_V1_D_size_patterns<SETGT, FCMGTddd>; 5145259698Sdim 5146259698Sdim// Scalar Floating-point Compare Mask Greather Than Zero 5147259698Sdimdefm FCMGTZ: NeonI_Scalar2SameMisc_cmpz_SD_size<0b0, 0b01100, "fcmgt">; 5148259698Sdimdefm : Neon_Scalar2SameMisc_cmpz_SD_size_patterns<int_aarch64_neon_vcgt, 5149259698Sdim FCMGTZssi, FCMGTZddi>; 5150259698Sdim 5151259698Sdim// Scalar Floating-point Compare Mask Less Than Or Equal To Zero 5152259698Sdimdefm FCMLEZ: NeonI_Scalar2SameMisc_cmpz_SD_size<0b1, 0b01101, "fcmle">; 5153259698Sdimdefm : Neon_Scalar2SameMisc_cmpz_SD_size_patterns<int_aarch64_neon_vclez, 5154259698Sdim FCMLEZssi, FCMLEZddi>; 5155259698Sdim 5156259698Sdim// Scalar Floating-point Compare Mask Less Than Zero 5157259698Sdimdefm FCMLTZ: NeonI_Scalar2SameMisc_cmpz_SD_size<0b0, 0b01110, "fcmlt">; 5158259698Sdimdefm : Neon_Scalar2SameMisc_cmpz_SD_size_patterns<int_aarch64_neon_vcltz, 5159259698Sdim FCMLTZssi, FCMLTZddi>; 5160259698Sdim 5161259698Sdim// Scalar Floating-point Absolute Compare Mask Greater Than Or Equal 5162259698Sdimdefm FACGE: NeonI_Scalar3Same_SD_sizes<0b1, 0b0, 0b11101, "facge">; 5163259698Sdimdefm : Neon_Scalar3Same_cmp_SD_size_patterns<int_aarch64_neon_vcage, 5164259698Sdim FACGEsss, FACGEddd>; 5165259698Sdim 5166259698Sdim// Scalar Floating-point Absolute Compare Mask Greater Than 5167259698Sdimdefm FACGT: NeonI_Scalar3Same_SD_sizes<0b1, 0b1, 0b11101, "facgt">; 5168259698Sdimdefm : Neon_Scalar3Same_cmp_SD_size_patterns<int_aarch64_neon_vcagt, 5169259698Sdim FACGTsss, FACGTddd>; 5170259698Sdim 5171259698Sdim// Scakar Floating-point Absolute Difference 5172259698Sdimdefm FABD: NeonI_Scalar3Same_SD_sizes<0b1, 0b1, 0b11010, "fabd">; 5173259698Sdimdefm : Neon_Scalar3Same_SD_size_patterns<int_aarch64_neon_vabd, 5174259698Sdim FABDsss, FABDddd>; 5175259698Sdim 5176259698Sdim// Scalar Absolute Value 5177259698Sdimdefm ABS : NeonI_Scalar2SameMisc_D_size<0b0, 0b01011, "abs">; 5178259698Sdimdefm : Neon_Scalar2SameMisc_D_size_patterns<int_aarch64_neon_vabs, ABSdd>; 5179259698Sdim 5180259698Sdim// Scalar Signed Saturating Absolute Value 5181259698Sdimdefm SQABS : NeonI_Scalar2SameMisc_BHSD_size<0b0, 0b00111, "sqabs">; 5182259698Sdimdefm : Neon_Scalar2SameMisc_BHSD_size_patterns<int_arm_neon_vqabs, 5183259698Sdim SQABSbb, SQABShh, SQABSss, SQABSdd>; 5184259698Sdim 5185259698Sdim// Scalar Negate 5186259698Sdimdefm NEG : NeonI_Scalar2SameMisc_D_size<0b1, 0b01011, "neg">; 5187259698Sdimdefm : Neon_Scalar2SameMisc_D_size_patterns<int_aarch64_neon_vneg, NEGdd>; 5188259698Sdim 5189259698Sdim// Scalar Signed Saturating Negate 5190259698Sdimdefm SQNEG : NeonI_Scalar2SameMisc_BHSD_size<0b1, 0b00111, "sqneg">; 5191259698Sdimdefm : Neon_Scalar2SameMisc_BHSD_size_patterns<int_arm_neon_vqneg, 5192259698Sdim SQNEGbb, SQNEGhh, SQNEGss, SQNEGdd>; 5193259698Sdim 5194259698Sdim// Scalar Signed Saturating Accumulated of Unsigned Value 5195259698Sdimdefm SUQADD : NeonI_Scalar2SameMisc_accum_BHSD_size<0b0, 0b00011, "suqadd">; 5196259698Sdimdefm : Neon_Scalar2SameMisc_accum_BHSD_size_patterns<int_aarch64_neon_vuqadd, 5197259698Sdim SUQADDbb, SUQADDhh, 5198259698Sdim SUQADDss, SUQADDdd>; 5199259698Sdim 5200259698Sdim// Scalar Unsigned Saturating Accumulated of Signed Value 5201259698Sdimdefm USQADD : NeonI_Scalar2SameMisc_accum_BHSD_size<0b1, 0b00011, "usqadd">; 5202259698Sdimdefm : Neon_Scalar2SameMisc_accum_BHSD_size_patterns<int_aarch64_neon_vsqadd, 5203259698Sdim USQADDbb, USQADDhh, 5204259698Sdim USQADDss, USQADDdd>; 5205259698Sdim 5206259698Sdimdef : Pat<(v1i64 (int_aarch64_neon_suqadd (v1i64 FPR64:$Src), 5207259698Sdim (v1i64 FPR64:$Rn))), 5208259698Sdim (SUQADDdd FPR64:$Src, FPR64:$Rn)>; 5209259698Sdim 5210259698Sdimdef : Pat<(v1i64 (int_aarch64_neon_usqadd (v1i64 FPR64:$Src), 5211259698Sdim (v1i64 FPR64:$Rn))), 5212259698Sdim (USQADDdd FPR64:$Src, FPR64:$Rn)>; 5213259698Sdim 5214259698Sdimdef : Pat<(v1i64 (int_arm_neon_vabs (v1i64 FPR64:$Rn))), 5215259698Sdim (ABSdd FPR64:$Rn)>; 5216259698Sdim 5217259698Sdimdef : Pat<(v1i64 (int_arm_neon_vqabs (v1i64 FPR64:$Rn))), 5218259698Sdim (SQABSdd FPR64:$Rn)>; 5219259698Sdim 5220259698Sdimdef : Pat<(v1i64 (int_arm_neon_vqneg (v1i64 FPR64:$Rn))), 5221259698Sdim (SQNEGdd FPR64:$Rn)>; 5222259698Sdim 5223259698Sdimdef : Pat<(v1i64 (sub (v1i64 (bitconvert (v8i8 Neon_AllZero))), 5224259698Sdim (v1i64 FPR64:$Rn))), 5225259698Sdim (NEGdd FPR64:$Rn)>; 5226259698Sdim 5227259698Sdim// Scalar Signed Saturating Extract Unsigned Narrow 5228259698Sdimdefm SQXTUN : NeonI_Scalar2SameMisc_narrow_HSD_size<0b1, 0b10010, "sqxtun">; 5229259698Sdimdefm : Neon_Scalar2SameMisc_narrow_HSD_size_patterns<int_arm_neon_vqmovnsu, 5230259698Sdim SQXTUNbh, SQXTUNhs, 5231259698Sdim SQXTUNsd>; 5232259698Sdim 5233259698Sdim// Scalar Signed Saturating Extract Narrow 5234259698Sdimdefm SQXTN : NeonI_Scalar2SameMisc_narrow_HSD_size<0b0, 0b10100, "sqxtn">; 5235259698Sdimdefm : Neon_Scalar2SameMisc_narrow_HSD_size_patterns<int_arm_neon_vqmovns, 5236259698Sdim SQXTNbh, SQXTNhs, 5237259698Sdim SQXTNsd>; 5238259698Sdim 5239259698Sdim// Scalar Unsigned Saturating Extract Narrow 5240259698Sdimdefm UQXTN : NeonI_Scalar2SameMisc_narrow_HSD_size<0b1, 0b10100, "uqxtn">; 5241259698Sdimdefm : Neon_Scalar2SameMisc_narrow_HSD_size_patterns<int_arm_neon_vqmovnu, 5242259698Sdim UQXTNbh, UQXTNhs, 5243259698Sdim UQXTNsd>; 5244259698Sdim 5245259698Sdim// Scalar Reduce Pairwise 5246259698Sdim 5247259698Sdimmulticlass NeonI_ScalarPair_D_sizes<bit u, bit size, bits<5> opcode, 5248259698Sdim string asmop, bit Commutable = 0> { 5249259698Sdim let isCommutable = Commutable in { 5250259698Sdim def _D_2D : NeonI_ScalarPair<u, {size, 0b1}, opcode, 5251259698Sdim (outs FPR64:$Rd), (ins VPR128:$Rn), 5252259698Sdim !strconcat(asmop, "\t$Rd, $Rn.2d"), 5253259698Sdim [], 5254259698Sdim NoItinerary>; 5255259698Sdim } 5256259698Sdim} 5257259698Sdim 5258259698Sdimmulticlass NeonI_ScalarPair_SD_sizes<bit u, bit size, bits<5> opcode, 5259259698Sdim string asmop, bit Commutable = 0> 5260259698Sdim : NeonI_ScalarPair_D_sizes<u, size, opcode, asmop, Commutable> { 5261259698Sdim let isCommutable = Commutable in { 5262259698Sdim def _S_2S : NeonI_ScalarPair<u, {size, 0b0}, opcode, 5263259698Sdim (outs FPR32:$Rd), (ins VPR64:$Rn), 5264259698Sdim !strconcat(asmop, "\t$Rd, $Rn.2s"), 5265259698Sdim [], 5266259698Sdim NoItinerary>; 5267259698Sdim } 5268259698Sdim} 5269259698Sdim 5270259698Sdim// Scalar Reduce Addition Pairwise (Integer) with 5271259698Sdim// Pattern to match llvm.arm.* intrinsic 5272259698Sdimdefm ADDPvv : NeonI_ScalarPair_D_sizes<0b0, 0b1, 0b11011, "addp", 0>; 5273259698Sdim 5274259698Sdim// Pattern to match llvm.aarch64.* intrinsic for 5275259698Sdim// Scalar Reduce Addition Pairwise (Integer) 5276259698Sdimdef : Pat<(v1i64 (int_aarch64_neon_vpadd (v2i64 VPR128:$Rn))), 5277259698Sdim (ADDPvv_D_2D VPR128:$Rn)>; 5278259698Sdimdef : Pat<(v1i64 (int_aarch64_neon_vaddv (v2i64 VPR128:$Rn))), 5279259698Sdim (ADDPvv_D_2D VPR128:$Rn)>; 5280259698Sdim 5281259698Sdim// Scalar Reduce Addition Pairwise (Floating Point) 5282259698Sdimdefm FADDPvv : NeonI_ScalarPair_SD_sizes<0b1, 0b0, 0b01101, "faddp", 0>; 5283259698Sdim 5284259698Sdim// Scalar Reduce Maximum Pairwise (Floating Point) 5285259698Sdimdefm FMAXPvv : NeonI_ScalarPair_SD_sizes<0b1, 0b0, 0b01111, "fmaxp", 0>; 5286259698Sdim 5287259698Sdim// Scalar Reduce Minimum Pairwise (Floating Point) 5288259698Sdimdefm FMINPvv : NeonI_ScalarPair_SD_sizes<0b1, 0b1, 0b01111, "fminp", 0>; 5289259698Sdim 5290259698Sdim// Scalar Reduce maxNum Pairwise (Floating Point) 5291259698Sdimdefm FMAXNMPvv : NeonI_ScalarPair_SD_sizes<0b1, 0b0, 0b01100, "fmaxnmp", 0>; 5292259698Sdim 5293259698Sdim// Scalar Reduce minNum Pairwise (Floating Point) 5294259698Sdimdefm FMINNMPvv : NeonI_ScalarPair_SD_sizes<0b1, 0b1, 0b01100, "fminnmp", 0>; 5295259698Sdim 5296259698Sdimmulticlass Neon_ScalarPair_SD_size_patterns<SDPatternOperator opnodeS, 5297259698Sdim SDPatternOperator opnodeD, 5298259698Sdim Instruction INSTS, 5299259698Sdim Instruction INSTD> { 5300259698Sdim def : Pat<(v1f32 (opnodeS (v2f32 VPR64:$Rn))), 5301259698Sdim (INSTS VPR64:$Rn)>; 5302259698Sdim def : Pat<(v1f64 (opnodeD (v2f64 VPR128:$Rn))), 5303259698Sdim (INSTD VPR128:$Rn)>; 5304259698Sdim} 5305259698Sdim 5306259698Sdim// Patterns to match llvm.aarch64.* intrinsic for 5307259698Sdim// Scalar Reduce Add, Max, Min, MaxiNum, MinNum Pairwise (Floating Point) 5308259698Sdimdefm : Neon_ScalarPair_SD_size_patterns<int_aarch64_neon_vpfadd, 5309259698Sdim int_aarch64_neon_vpfaddq, FADDPvv_S_2S, FADDPvv_D_2D>; 5310259698Sdim 5311259698Sdimdefm : Neon_ScalarPair_SD_size_patterns<int_aarch64_neon_vpmax, 5312259698Sdim int_aarch64_neon_vpmaxq, FMAXPvv_S_2S, FMAXPvv_D_2D>; 5313259698Sdim 5314259698Sdimdefm : Neon_ScalarPair_SD_size_patterns<int_aarch64_neon_vpmin, 5315259698Sdim int_aarch64_neon_vpminq, FMINPvv_S_2S, FMINPvv_D_2D>; 5316259698Sdim 5317259698Sdimdefm : Neon_ScalarPair_SD_size_patterns<int_aarch64_neon_vpfmaxnm, 5318259698Sdim int_aarch64_neon_vpfmaxnmq, FMAXNMPvv_S_2S, FMAXNMPvv_D_2D>; 5319259698Sdim 5320259698Sdimdefm : Neon_ScalarPair_SD_size_patterns<int_aarch64_neon_vpfminnm, 5321259698Sdim int_aarch64_neon_vpfminnmq, FMINNMPvv_S_2S, FMINNMPvv_D_2D>; 5322259698Sdim 5323259698Sdimdefm : Neon_ScalarPair_SD_size_patterns<int_aarch64_neon_vaddv, 5324259698Sdim int_aarch64_neon_vaddv, FADDPvv_S_2S, FADDPvv_D_2D>; 5325259698Sdim 5326259698Sdimdef : Pat<(v1f32 (int_aarch64_neon_vaddv (v4f32 VPR128:$Rn))), 5327259698Sdim (FADDPvv_S_2S (v2f32 5328259698Sdim (EXTRACT_SUBREG 5329259698Sdim (v4f32 (FADDP_4S (v4f32 VPR128:$Rn), (v4f32 VPR128:$Rn))), 5330259698Sdim sub_64)))>; 5331259698Sdim 5332259698Sdimdefm : Neon_ScalarPair_SD_size_patterns<int_aarch64_neon_vmaxv, 5333259698Sdim int_aarch64_neon_vmaxv, FMAXPvv_S_2S, FMAXPvv_D_2D>; 5334259698Sdim 5335259698Sdimdefm : Neon_ScalarPair_SD_size_patterns<int_aarch64_neon_vminv, 5336259698Sdim int_aarch64_neon_vminv, FMINPvv_S_2S, FMINPvv_D_2D>; 5337259698Sdim 5338259698Sdimdefm : Neon_ScalarPair_SD_size_patterns<int_aarch64_neon_vmaxnmv, 5339259698Sdim int_aarch64_neon_vmaxnmv, FMAXNMPvv_S_2S, FMAXNMPvv_D_2D>; 5340259698Sdim 5341259698Sdimdefm : Neon_ScalarPair_SD_size_patterns<int_aarch64_neon_vminnmv, 5342259698Sdim int_aarch64_neon_vminnmv, FMINNMPvv_S_2S, FMINNMPvv_D_2D>; 5343259698Sdim 5344259698Sdim// Scalar by element Arithmetic 5345259698Sdim 5346259698Sdimclass NeonI_ScalarXIndexedElemArith<string asmop, bits<4> opcode, 5347259698Sdim string rmlane, bit u, bit szhi, bit szlo, 5348259698Sdim RegisterClass ResFPR, RegisterClass OpFPR, 5349259698Sdim RegisterOperand OpVPR, Operand OpImm> 5350259698Sdim : NeonI_ScalarXIndexedElem<u, szhi, szlo, opcode, 5351259698Sdim (outs ResFPR:$Rd), 5352259698Sdim (ins OpFPR:$Rn, OpVPR:$MRm, OpImm:$Imm), 5353259698Sdim asmop # "\t$Rd, $Rn, $MRm" # rmlane # "[$Imm]", 5354259698Sdim [], 5355259698Sdim NoItinerary> { 5356259698Sdim bits<3> Imm; 5357259698Sdim bits<5> MRm; 5358259698Sdim} 5359259698Sdim 5360259698Sdimclass NeonI_ScalarXIndexedElemArith_Constraint_Impl<string asmop, bits<4> opcode, 5361259698Sdim string rmlane, 5362259698Sdim bit u, bit szhi, bit szlo, 5363259698Sdim RegisterClass ResFPR, 5364259698Sdim RegisterClass OpFPR, 5365259698Sdim RegisterOperand OpVPR, 5366259698Sdim Operand OpImm> 5367259698Sdim : NeonI_ScalarXIndexedElem<u, szhi, szlo, opcode, 5368259698Sdim (outs ResFPR:$Rd), 5369259698Sdim (ins ResFPR:$src, OpFPR:$Rn, OpVPR:$MRm, OpImm:$Imm), 5370259698Sdim asmop # "\t$Rd, $Rn, $MRm" # rmlane # "[$Imm]", 5371259698Sdim [], 5372259698Sdim NoItinerary> { 5373259698Sdim let Constraints = "$src = $Rd"; 5374259698Sdim bits<3> Imm; 5375259698Sdim bits<5> MRm; 5376259698Sdim} 5377259698Sdim 5378259698Sdim// Scalar Floating Point multiply (scalar, by element) 5379259698Sdimdef FMULssv_4S : NeonI_ScalarXIndexedElemArith<"fmul", 5380259698Sdim 0b1001, ".s", 0b0, 0b1, 0b0, FPR32, FPR32, VPR128, neon_uimm2_bare> { 5381259698Sdim let Inst{11} = Imm{1}; // h 5382259698Sdim let Inst{21} = Imm{0}; // l 5383259698Sdim let Inst{20-16} = MRm; 5384259698Sdim} 5385259698Sdimdef FMULddv_2D : NeonI_ScalarXIndexedElemArith<"fmul", 5386259698Sdim 0b1001, ".d", 0b0, 0b1, 0b1, FPR64, FPR64, VPR128, neon_uimm1_bare> { 5387259698Sdim let Inst{11} = Imm{0}; // h 5388259698Sdim let Inst{21} = 0b0; // l 5389259698Sdim let Inst{20-16} = MRm; 5390259698Sdim} 5391259698Sdim 5392259698Sdim// Scalar Floating Point multiply extended (scalar, by element) 5393259698Sdimdef FMULXssv_4S : NeonI_ScalarXIndexedElemArith<"fmulx", 5394259698Sdim 0b1001, ".s", 0b1, 0b1, 0b0, FPR32, FPR32, VPR128, neon_uimm2_bare> { 5395259698Sdim let Inst{11} = Imm{1}; // h 5396259698Sdim let Inst{21} = Imm{0}; // l 5397259698Sdim let Inst{20-16} = MRm; 5398259698Sdim} 5399259698Sdimdef FMULXddv_2D : NeonI_ScalarXIndexedElemArith<"fmulx", 5400259698Sdim 0b1001, ".d", 0b1, 0b1, 0b1, FPR64, FPR64, VPR128, neon_uimm1_bare> { 5401259698Sdim let Inst{11} = Imm{0}; // h 5402259698Sdim let Inst{21} = 0b0; // l 5403259698Sdim let Inst{20-16} = MRm; 5404259698Sdim} 5405259698Sdim 5406259698Sdimmulticlass Neon_ScalarXIndexedElem_MUL_MULX_Patterns< 5407259698Sdim SDPatternOperator opnode, 5408259698Sdim Instruction INST, 5409259698Sdim ValueType ResTy, RegisterClass FPRC, ValueType OpTy, Operand OpImm, 5410259698Sdim ValueType OpNTy, ValueType ExTy, Operand OpNImm> { 5411259698Sdim 5412259698Sdim def : Pat<(ResTy (opnode (ResTy FPRC:$Rn), 5413259698Sdim (ResTy (vector_extract (OpTy VPR128:$MRm), OpImm:$Imm)))), 5414259698Sdim (ResTy (INST (ResTy FPRC:$Rn), (OpTy VPR128:$MRm), OpImm:$Imm))>; 5415259698Sdim 5416259698Sdim def : Pat<(ResTy (opnode (ResTy FPRC:$Rn), 5417259698Sdim (ResTy (vector_extract (OpNTy VPR64:$MRm), OpNImm:$Imm)))), 5418259698Sdim (ResTy (INST (ResTy FPRC:$Rn), 5419259698Sdim (ExTy (SUBREG_TO_REG (i64 0), VPR64:$MRm, sub_64)), 5420259698Sdim OpNImm:$Imm))>; 5421259698Sdim 5422259698Sdim // swapped operands 5423259698Sdim def : Pat<(ResTy (opnode 5424259698Sdim (ResTy (vector_extract (OpTy VPR128:$MRm), OpImm:$Imm)), 5425259698Sdim (ResTy FPRC:$Rn))), 5426259698Sdim (ResTy (INST (ResTy FPRC:$Rn), (OpTy VPR128:$MRm), OpImm:$Imm))>; 5427259698Sdim 5428259698Sdim def : Pat<(ResTy (opnode 5429259698Sdim (ResTy (vector_extract (OpNTy VPR64:$MRm), OpNImm:$Imm)), 5430259698Sdim (ResTy FPRC:$Rn))), 5431259698Sdim (ResTy (INST (ResTy FPRC:$Rn), 5432259698Sdim (ExTy (SUBREG_TO_REG (i64 0), VPR64:$MRm, sub_64)), 5433259698Sdim OpNImm:$Imm))>; 5434259698Sdim} 5435259698Sdim 5436259698Sdim// Patterns for Scalar Floating Point multiply (scalar, by element) 5437259698Sdimdefm : Neon_ScalarXIndexedElem_MUL_MULX_Patterns<fmul, FMULssv_4S, 5438259698Sdim f32, FPR32, v4f32, neon_uimm2_bare, v2f32, v4f32, neon_uimm1_bare>; 5439259698Sdimdefm : Neon_ScalarXIndexedElem_MUL_MULX_Patterns<fmul, FMULddv_2D, 5440259698Sdim f64, FPR64, v2f64, neon_uimm1_bare, v1f64, v2f64, neon_uimm0_bare>; 5441259698Sdim 5442259698Sdim// Patterns for Scalar Floating Point multiply extended (scalar, by element) 5443259698Sdimdefm : Neon_ScalarXIndexedElem_MUL_MULX_Patterns<int_aarch64_neon_vmulx, 5444259698Sdim FMULXssv_4S, f32, FPR32, v4f32, neon_uimm2_bare, 5445259698Sdim v2f32, v4f32, neon_uimm1_bare>; 5446259698Sdimdefm : Neon_ScalarXIndexedElem_MUL_MULX_Patterns<int_aarch64_neon_vmulx, 5447259698Sdim FMULXddv_2D, f64, FPR64, v2f64, neon_uimm1_bare, 5448259698Sdim v1f64, v2f64, neon_uimm0_bare>; 5449259698Sdim 5450259698Sdim 5451259698Sdim// Scalar Floating Point fused multiply-add (scalar, by element) 5452259698Sdimdef FMLAssv_4S : NeonI_ScalarXIndexedElemArith_Constraint_Impl<"fmla", 5453259698Sdim 0b0001, ".s", 0b0, 0b1, 0b0, FPR32, FPR32, VPR128, neon_uimm2_bare> { 5454259698Sdim let Inst{11} = Imm{1}; // h 5455259698Sdim let Inst{21} = Imm{0}; // l 5456259698Sdim let Inst{20-16} = MRm; 5457259698Sdim} 5458259698Sdimdef FMLAddv_2D : NeonI_ScalarXIndexedElemArith_Constraint_Impl<"fmla", 5459259698Sdim 0b0001, ".d", 0b0, 0b1, 0b1, FPR64, FPR64, VPR128, neon_uimm1_bare> { 5460259698Sdim let Inst{11} = Imm{0}; // h 5461259698Sdim let Inst{21} = 0b0; // l 5462259698Sdim let Inst{20-16} = MRm; 5463259698Sdim} 5464259698Sdim 5465259698Sdim// Scalar Floating Point fused multiply-subtract (scalar, by element) 5466259698Sdimdef FMLSssv_4S : NeonI_ScalarXIndexedElemArith_Constraint_Impl<"fmls", 5467259698Sdim 0b0101, ".s", 0b0, 0b1, 0b0, FPR32, FPR32, VPR128, neon_uimm2_bare> { 5468259698Sdim let Inst{11} = Imm{1}; // h 5469259698Sdim let Inst{21} = Imm{0}; // l 5470259698Sdim let Inst{20-16} = MRm; 5471259698Sdim} 5472259698Sdimdef FMLSddv_2D : NeonI_ScalarXIndexedElemArith_Constraint_Impl<"fmls", 5473259698Sdim 0b0101, ".d", 0b0, 0b1, 0b1, FPR64, FPR64, VPR128, neon_uimm1_bare> { 5474259698Sdim let Inst{11} = Imm{0}; // h 5475259698Sdim let Inst{21} = 0b0; // l 5476259698Sdim let Inst{20-16} = MRm; 5477259698Sdim} 5478259698Sdim// We are allowed to match the fma instruction regardless of compile options. 5479259698Sdimmulticlass Neon_ScalarXIndexedElem_FMA_Patterns< 5480259698Sdim Instruction FMLAI, Instruction FMLSI, 5481259698Sdim ValueType ResTy, RegisterClass FPRC, ValueType OpTy, Operand OpImm, 5482259698Sdim ValueType OpNTy, ValueType ExTy, Operand OpNImm> { 5483259698Sdim // fmla 5484259698Sdim def : Pat<(ResTy (fma (ResTy FPRC:$Rn), 5485259698Sdim (ResTy (vector_extract (OpTy VPR128:$MRm), OpImm:$Imm)), 5486259698Sdim (ResTy FPRC:$Ra))), 5487259698Sdim (ResTy (FMLAI (ResTy FPRC:$Ra), 5488259698Sdim (ResTy FPRC:$Rn), (OpTy VPR128:$MRm), OpImm:$Imm))>; 5489259698Sdim 5490259698Sdim def : Pat<(ResTy (fma (ResTy FPRC:$Rn), 5491259698Sdim (ResTy (vector_extract (OpNTy VPR64:$MRm), OpNImm:$Imm)), 5492259698Sdim (ResTy FPRC:$Ra))), 5493259698Sdim (ResTy (FMLAI (ResTy FPRC:$Ra), 5494259698Sdim (ResTy FPRC:$Rn), 5495259698Sdim (ExTy (SUBREG_TO_REG (i64 0), VPR64:$MRm, sub_64)), 5496259698Sdim OpNImm:$Imm))>; 5497259698Sdim 5498259698Sdim // swapped fmla operands 5499259698Sdim def : Pat<(ResTy (fma 5500259698Sdim (ResTy (vector_extract (OpTy VPR128:$MRm), OpImm:$Imm)), 5501259698Sdim (ResTy FPRC:$Rn), 5502259698Sdim (ResTy FPRC:$Ra))), 5503259698Sdim (ResTy (FMLAI (ResTy FPRC:$Ra), 5504259698Sdim (ResTy FPRC:$Rn), (OpTy VPR128:$MRm), OpImm:$Imm))>; 5505259698Sdim 5506259698Sdim def : Pat<(ResTy (fma 5507259698Sdim (ResTy (vector_extract (OpNTy VPR64:$MRm), OpNImm:$Imm)), 5508259698Sdim (ResTy FPRC:$Rn), 5509259698Sdim (ResTy FPRC:$Ra))), 5510259698Sdim (ResTy (FMLAI (ResTy FPRC:$Ra), 5511259698Sdim (ResTy FPRC:$Rn), 5512259698Sdim (ExTy (SUBREG_TO_REG (i64 0), VPR64:$MRm, sub_64)), 5513259698Sdim OpNImm:$Imm))>; 5514259698Sdim 5515259698Sdim // fmls 5516259698Sdim def : Pat<(ResTy (fma (ResTy FPRC:$Rn), 5517259698Sdim (fneg (ResTy (vector_extract (OpTy VPR128:$MRm), OpImm:$Imm))), 5518259698Sdim (ResTy FPRC:$Ra))), 5519259698Sdim (ResTy (FMLSI (ResTy FPRC:$Ra), 5520259698Sdim (ResTy FPRC:$Rn), (OpTy VPR128:$MRm), OpImm:$Imm))>; 5521259698Sdim 5522259698Sdim def : Pat<(ResTy (fma (ResTy FPRC:$Rn), 5523259698Sdim (fneg (ResTy (vector_extract (OpNTy VPR64:$MRm), OpNImm:$Imm))), 5524259698Sdim (ResTy FPRC:$Ra))), 5525259698Sdim (ResTy (FMLSI (ResTy FPRC:$Ra), 5526259698Sdim (ResTy FPRC:$Rn), 5527259698Sdim (ExTy (SUBREG_TO_REG (i64 0), VPR64:$MRm, sub_64)), 5528259698Sdim OpNImm:$Imm))>; 5529259698Sdim 5530259698Sdim // swapped fmls operands 5531259698Sdim def : Pat<(ResTy (fma 5532259698Sdim (fneg (ResTy (vector_extract (OpTy VPR128:$MRm), OpImm:$Imm))), 5533259698Sdim (ResTy FPRC:$Rn), 5534259698Sdim (ResTy FPRC:$Ra))), 5535259698Sdim (ResTy (FMLSI (ResTy FPRC:$Ra), 5536259698Sdim (ResTy FPRC:$Rn), (OpTy VPR128:$MRm), OpImm:$Imm))>; 5537259698Sdim 5538259698Sdim def : Pat<(ResTy (fma 5539259698Sdim (fneg (ResTy (vector_extract (OpNTy VPR64:$MRm), OpNImm:$Imm))), 5540259698Sdim (ResTy FPRC:$Rn), 5541259698Sdim (ResTy FPRC:$Ra))), 5542259698Sdim (ResTy (FMLSI (ResTy FPRC:$Ra), 5543259698Sdim (ResTy FPRC:$Rn), 5544259698Sdim (ExTy (SUBREG_TO_REG (i64 0), VPR64:$MRm, sub_64)), 5545259698Sdim OpNImm:$Imm))>; 5546259698Sdim} 5547259698Sdim 5548259698Sdim// Scalar Floating Point fused multiply-add and 5549259698Sdim// multiply-subtract (scalar, by element) 5550259698Sdimdefm : Neon_ScalarXIndexedElem_FMA_Patterns<FMLAssv_4S, FMLSssv_4S, 5551259698Sdim f32, FPR32, v4f32, neon_uimm2_bare, v2f32, v4f32, neon_uimm1_bare>; 5552259698Sdimdefm : Neon_ScalarXIndexedElem_FMA_Patterns<FMLAddv_2D, FMLSddv_2D, 5553259698Sdim f64, FPR64, v2f64, neon_uimm1_bare, v1f64, v2f64, neon_uimm0_bare>; 5554259698Sdimdefm : Neon_ScalarXIndexedElem_FMA_Patterns<FMLAddv_2D, FMLSddv_2D, 5555259698Sdim f64, FPR64, v2f64, neon_uimm1_bare, v1f64, v2f64, neon_uimm0_bare>; 5556259698Sdim 5557259698Sdim// Scalar Signed saturating doubling multiply long (scalar, by element) 5558259698Sdimdef SQDMULLshv_4H : NeonI_ScalarXIndexedElemArith<"sqdmull", 5559259698Sdim 0b1011, ".h", 0b0, 0b0, 0b1, FPR32, FPR16, VPR64Lo, neon_uimm2_bare> { 5560259698Sdim let Inst{11} = 0b0; // h 5561259698Sdim let Inst{21} = Imm{1}; // l 5562259698Sdim let Inst{20} = Imm{0}; // m 5563259698Sdim let Inst{19-16} = MRm{3-0}; 5564259698Sdim} 5565259698Sdimdef SQDMULLshv_8H : NeonI_ScalarXIndexedElemArith<"sqdmull", 5566259698Sdim 0b1011, ".h", 0b0, 0b0, 0b1, FPR32, FPR16, VPR128Lo, neon_uimm3_bare> { 5567259698Sdim let Inst{11} = Imm{2}; // h 5568259698Sdim let Inst{21} = Imm{1}; // l 5569259698Sdim let Inst{20} = Imm{0}; // m 5570259698Sdim let Inst{19-16} = MRm{3-0}; 5571259698Sdim} 5572259698Sdimdef SQDMULLdsv_2S : NeonI_ScalarXIndexedElemArith<"sqdmull", 5573259698Sdim 0b1011, ".s", 0b0, 0b1, 0b0, FPR64, FPR32, VPR64, neon_uimm1_bare> { 5574259698Sdim let Inst{11} = 0b0; // h 5575259698Sdim let Inst{21} = Imm{0}; // l 5576259698Sdim let Inst{20-16} = MRm; 5577259698Sdim} 5578259698Sdimdef SQDMULLdsv_4S : NeonI_ScalarXIndexedElemArith<"sqdmull", 5579259698Sdim 0b1011, ".s", 0b0, 0b1, 0b0, FPR64, FPR32, VPR128, neon_uimm2_bare> { 5580259698Sdim let Inst{11} = Imm{1}; // h 5581259698Sdim let Inst{21} = Imm{0}; // l 5582259698Sdim let Inst{20-16} = MRm; 5583259698Sdim} 5584259698Sdim 5585259698Sdimmulticlass Neon_ScalarXIndexedElem_MUL_Patterns< 5586259698Sdim SDPatternOperator opnode, 5587259698Sdim Instruction INST, 5588259698Sdim ValueType ResTy, RegisterClass FPRC, 5589259698Sdim ValueType OpVTy, ValueType OpTy, 5590259698Sdim ValueType VecOpTy, ValueType ExTy, RegisterOperand VPRC, Operand OpImm> { 5591259698Sdim 5592259698Sdim def : Pat<(ResTy (opnode (OpVTy FPRC:$Rn), 5593259698Sdim (OpVTy (scalar_to_vector 5594259698Sdim (ExTy (vector_extract (VecOpTy VPRC:$MRm), OpImm:$Imm)))))), 5595259698Sdim (ResTy (INST (OpVTy FPRC:$Rn), (VecOpTy VPRC:$MRm), OpImm:$Imm))>; 5596259698Sdim 5597259698Sdim //swapped operands 5598259698Sdim def : Pat<(ResTy (opnode 5599259698Sdim (OpVTy (scalar_to_vector 5600259698Sdim (ExTy (vector_extract (VecOpTy VPRC:$MRm), OpImm:$Imm)))), 5601259698Sdim (OpVTy FPRC:$Rn))), 5602259698Sdim (ResTy (INST (OpVTy FPRC:$Rn), (VecOpTy VPRC:$MRm), OpImm:$Imm))>; 5603259698Sdim} 5604259698Sdim 5605259698Sdim 5606259698Sdim// Patterns for Scalar Signed saturating doubling 5607259698Sdim// multiply long (scalar, by element) 5608259698Sdimdefm : Neon_ScalarXIndexedElem_MUL_Patterns<int_arm_neon_vqdmull, 5609259698Sdim SQDMULLshv_4H, v1i32, FPR16, v1i16, i16, v4i16, 5610259698Sdim i32, VPR64Lo, neon_uimm2_bare>; 5611259698Sdimdefm : Neon_ScalarXIndexedElem_MUL_Patterns<int_arm_neon_vqdmull, 5612259698Sdim SQDMULLshv_8H, v1i32, FPR16, v1i16, i16, v8i16, 5613259698Sdim i32, VPR128Lo, neon_uimm3_bare>; 5614259698Sdimdefm : Neon_ScalarXIndexedElem_MUL_Patterns<int_arm_neon_vqdmull, 5615259698Sdim SQDMULLdsv_2S, v1i64, FPR32, v1i32, i32, v2i32, 5616259698Sdim i32, VPR64Lo, neon_uimm1_bare>; 5617259698Sdimdefm : Neon_ScalarXIndexedElem_MUL_Patterns<int_arm_neon_vqdmull, 5618259698Sdim SQDMULLdsv_4S, v1i64, FPR32, v1i32, i32, v4i32, 5619259698Sdim i32, VPR128Lo, neon_uimm2_bare>; 5620259698Sdim 5621259698Sdim// Scalar Signed saturating doubling multiply-add long (scalar, by element) 5622259698Sdimdef SQDMLALshv_4H : NeonI_ScalarXIndexedElemArith_Constraint_Impl<"sqdmlal", 5623259698Sdim 0b0011, ".h", 0b0, 0b0, 0b1, FPR32, FPR16, VPR64Lo, neon_uimm2_bare> { 5624259698Sdim let Inst{11} = 0b0; // h 5625259698Sdim let Inst{21} = Imm{1}; // l 5626259698Sdim let Inst{20} = Imm{0}; // m 5627259698Sdim let Inst{19-16} = MRm{3-0}; 5628259698Sdim} 5629259698Sdimdef SQDMLALshv_8H : NeonI_ScalarXIndexedElemArith_Constraint_Impl<"sqdmlal", 5630259698Sdim 0b0011, ".h", 0b0, 0b0, 0b1, FPR32, FPR16, VPR128Lo, neon_uimm3_bare> { 5631259698Sdim let Inst{11} = Imm{2}; // h 5632259698Sdim let Inst{21} = Imm{1}; // l 5633259698Sdim let Inst{20} = Imm{0}; // m 5634259698Sdim let Inst{19-16} = MRm{3-0}; 5635259698Sdim} 5636259698Sdimdef SQDMLALdsv_2S : NeonI_ScalarXIndexedElemArith_Constraint_Impl<"sqdmlal", 5637259698Sdim 0b0011, ".s", 0b0, 0b1, 0b0, FPR64, FPR32, VPR64, neon_uimm1_bare> { 5638259698Sdim let Inst{11} = 0b0; // h 5639259698Sdim let Inst{21} = Imm{0}; // l 5640259698Sdim let Inst{20-16} = MRm; 5641259698Sdim} 5642259698Sdimdef SQDMLALdsv_4S : NeonI_ScalarXIndexedElemArith_Constraint_Impl<"sqdmlal", 5643259698Sdim 0b0011, ".s", 0b0, 0b1, 0b0, FPR64, FPR32, VPR128, neon_uimm2_bare> { 5644259698Sdim let Inst{11} = Imm{1}; // h 5645259698Sdim let Inst{21} = Imm{0}; // l 5646259698Sdim let Inst{20-16} = MRm; 5647259698Sdim} 5648259698Sdim 5649259698Sdim// Scalar Signed saturating doubling 5650259698Sdim// multiply-subtract long (scalar, by element) 5651259698Sdimdef SQDMLSLshv_4H : NeonI_ScalarXIndexedElemArith_Constraint_Impl<"sqdmlsl", 5652259698Sdim 0b0111, ".h", 0b0, 0b0, 0b1, FPR32, FPR16, VPR64Lo, neon_uimm2_bare> { 5653259698Sdim let Inst{11} = 0b0; // h 5654259698Sdim let Inst{21} = Imm{1}; // l 5655259698Sdim let Inst{20} = Imm{0}; // m 5656259698Sdim let Inst{19-16} = MRm{3-0}; 5657259698Sdim} 5658259698Sdimdef SQDMLSLshv_8H : NeonI_ScalarXIndexedElemArith_Constraint_Impl<"sqdmlsl", 5659259698Sdim 0b0111, ".h", 0b0, 0b0, 0b1, FPR32, FPR16, VPR128Lo, neon_uimm3_bare> { 5660259698Sdim let Inst{11} = Imm{2}; // h 5661259698Sdim let Inst{21} = Imm{1}; // l 5662259698Sdim let Inst{20} = Imm{0}; // m 5663259698Sdim let Inst{19-16} = MRm{3-0}; 5664259698Sdim} 5665259698Sdimdef SQDMLSLdsv_2S : NeonI_ScalarXIndexedElemArith_Constraint_Impl<"sqdmlsl", 5666259698Sdim 0b0111, ".s", 0b0, 0b1, 0b0, FPR64, FPR32, VPR64, neon_uimm1_bare> { 5667259698Sdim let Inst{11} = 0b0; // h 5668259698Sdim let Inst{21} = Imm{0}; // l 5669259698Sdim let Inst{20-16} = MRm; 5670259698Sdim} 5671259698Sdimdef SQDMLSLdsv_4S : NeonI_ScalarXIndexedElemArith_Constraint_Impl<"sqdmlsl", 5672259698Sdim 0b0111, ".s", 0b0, 0b1, 0b0, FPR64, FPR32, VPR128, neon_uimm2_bare> { 5673259698Sdim let Inst{11} = Imm{1}; // h 5674259698Sdim let Inst{21} = Imm{0}; // l 5675259698Sdim let Inst{20-16} = MRm; 5676259698Sdim} 5677259698Sdim 5678259698Sdimmulticlass Neon_ScalarXIndexedElem_MLAL_Patterns< 5679259698Sdim SDPatternOperator opnode, 5680259698Sdim SDPatternOperator coreopnode, 5681259698Sdim Instruction INST, 5682259698Sdim ValueType ResTy, RegisterClass ResFPRC, RegisterClass FPRC, 5683259698Sdim ValueType OpTy, 5684259698Sdim ValueType OpVTy, ValueType ExTy, RegisterOperand VPRC, Operand OpImm> { 5685259698Sdim 5686259698Sdim def : Pat<(ResTy (opnode 5687259698Sdim (ResTy ResFPRC:$Ra), 5688259698Sdim (ResTy (coreopnode (OpTy FPRC:$Rn), 5689259698Sdim (OpTy (scalar_to_vector 5690259698Sdim (ExTy (vector_extract (OpVTy VPRC:$MRm), OpImm:$Imm)))))))), 5691259698Sdim (ResTy (INST (ResTy ResFPRC:$Ra), 5692259698Sdim (OpTy FPRC:$Rn), (OpVTy VPRC:$MRm), OpImm:$Imm))>; 5693259698Sdim 5694259698Sdim // swapped operands 5695259698Sdim def : Pat<(ResTy (opnode 5696259698Sdim (ResTy ResFPRC:$Ra), 5697259698Sdim (ResTy (coreopnode 5698259698Sdim (OpTy (scalar_to_vector 5699259698Sdim (ExTy (vector_extract (OpVTy VPRC:$MRm), OpImm:$Imm)))), 5700259698Sdim (OpTy FPRC:$Rn))))), 5701259698Sdim (ResTy (INST (ResTy ResFPRC:$Ra), 5702259698Sdim (OpTy FPRC:$Rn), (OpVTy VPRC:$MRm), OpImm:$Imm))>; 5703259698Sdim} 5704259698Sdim 5705259698Sdim// Patterns for Scalar Signed saturating 5706259698Sdim// doubling multiply-add long (scalar, by element) 5707259698Sdimdefm : Neon_ScalarXIndexedElem_MLAL_Patterns<int_arm_neon_vqadds, 5708259698Sdim int_arm_neon_vqdmull, SQDMLALshv_4H, v1i32, FPR32, FPR16, v1i16, v4i16, 5709259698Sdim i32, VPR64Lo, neon_uimm2_bare>; 5710259698Sdimdefm : Neon_ScalarXIndexedElem_MLAL_Patterns<int_arm_neon_vqadds, 5711259698Sdim int_arm_neon_vqdmull, SQDMLALshv_8H, v1i32, FPR32, FPR16, v1i16, v8i16, 5712259698Sdim i32, VPR128Lo, neon_uimm3_bare>; 5713259698Sdimdefm : Neon_ScalarXIndexedElem_MLAL_Patterns<int_arm_neon_vqadds, 5714259698Sdim int_arm_neon_vqdmull, SQDMLALdsv_2S, v1i64, FPR64, FPR32, v1i32, v2i32, 5715259698Sdim i32, VPR64Lo, neon_uimm1_bare>; 5716259698Sdimdefm : Neon_ScalarXIndexedElem_MLAL_Patterns<int_arm_neon_vqadds, 5717259698Sdim int_arm_neon_vqdmull, SQDMLALdsv_4S, v1i64, FPR64, FPR32, v1i32, v4i32, 5718259698Sdim i32, VPR128Lo, neon_uimm2_bare>; 5719259698Sdim 5720259698Sdim// Patterns for Scalar Signed saturating 5721259698Sdim// doubling multiply-sub long (scalar, by element) 5722259698Sdimdefm : Neon_ScalarXIndexedElem_MLAL_Patterns<int_arm_neon_vqsubs, 5723259698Sdim int_arm_neon_vqdmull, SQDMLSLshv_4H, v1i32, FPR32, FPR16, v1i16, v4i16, 5724259698Sdim i32, VPR64Lo, neon_uimm2_bare>; 5725259698Sdimdefm : Neon_ScalarXIndexedElem_MLAL_Patterns<int_arm_neon_vqsubs, 5726259698Sdim int_arm_neon_vqdmull, SQDMLSLshv_8H, v1i32, FPR32, FPR16, v1i16, v8i16, 5727259698Sdim i32, VPR128Lo, neon_uimm3_bare>; 5728259698Sdimdefm : Neon_ScalarXIndexedElem_MLAL_Patterns<int_arm_neon_vqsubs, 5729259698Sdim int_arm_neon_vqdmull, SQDMLSLdsv_2S, v1i64, FPR64, FPR32, v1i32, v2i32, 5730259698Sdim i32, VPR64Lo, neon_uimm1_bare>; 5731259698Sdimdefm : Neon_ScalarXIndexedElem_MLAL_Patterns<int_arm_neon_vqsubs, 5732259698Sdim int_arm_neon_vqdmull, SQDMLSLdsv_4S, v1i64, FPR64, FPR32, v1i32, v4i32, 5733259698Sdim i32, VPR128Lo, neon_uimm2_bare>; 5734259698Sdim 5735259698Sdim// Scalar general arithmetic operation 5736259698Sdimclass Neon_Scalar_GeneralMath2D_pattern<SDPatternOperator opnode, 5737259698Sdim Instruction INST> 5738259698Sdim : Pat<(v1f64 (opnode (v1f64 FPR64:$Rn))), (INST FPR64:$Rn)>; 5739259698Sdim 5740259698Sdimclass Neon_Scalar_GeneralMath3D_pattern<SDPatternOperator opnode, 5741259698Sdim Instruction INST> 5742259698Sdim : Pat<(v1f64 (opnode (v1f64 FPR64:$Rn), (v1f64 FPR64:$Rm))), 5743259698Sdim (INST FPR64:$Rn, FPR64:$Rm)>; 5744259698Sdim 5745259698Sdimclass Neon_Scalar_GeneralMath4D_pattern<SDPatternOperator opnode, 5746259698Sdim Instruction INST> 5747259698Sdim : Pat<(v1f64 (opnode (v1f64 FPR64:$Rn), (v1f64 FPR64:$Rm), 5748259698Sdim (v1f64 FPR64:$Ra))), 5749259698Sdim (INST FPR64:$Rn, FPR64:$Rm, FPR64:$Ra)>; 5750259698Sdim 5751259698Sdimdef : Neon_Scalar_GeneralMath3D_pattern<fadd, FADDddd>; 5752259698Sdimdef : Neon_Scalar_GeneralMath3D_pattern<fmul, FMULddd>; 5753259698Sdimdef : Neon_Scalar_GeneralMath3D_pattern<fsub, FSUBddd>; 5754259698Sdimdef : Neon_Scalar_GeneralMath3D_pattern<fdiv, FDIVddd>; 5755259698Sdimdef : Neon_Scalar_GeneralMath3D_pattern<int_arm_neon_vabds, FABDddd>; 5756259698Sdimdef : Neon_Scalar_GeneralMath3D_pattern<int_arm_neon_vmaxs, FMAXddd>; 5757259698Sdimdef : Neon_Scalar_GeneralMath3D_pattern<int_arm_neon_vmins, FMINddd>; 5758259698Sdimdef : Neon_Scalar_GeneralMath3D_pattern<int_aarch64_neon_vmaxnm, FMAXNMddd>; 5759259698Sdimdef : Neon_Scalar_GeneralMath3D_pattern<int_aarch64_neon_vminnm, FMINNMddd>; 5760259698Sdim 5761259698Sdimdef : Neon_Scalar_GeneralMath2D_pattern<fabs, FABSdd>; 5762259698Sdimdef : Neon_Scalar_GeneralMath2D_pattern<fneg, FNEGdd>; 5763259698Sdim 5764259698Sdimdef : Neon_Scalar_GeneralMath4D_pattern<fma, FMADDdddd>; 5765259698Sdimdef : Neon_Scalar_GeneralMath4D_pattern<fmsub, FMSUBdddd>; 5766259698Sdim 5767259698Sdim// Scalar Signed saturating doubling multiply returning 5768259698Sdim// high half (scalar, by element) 5769259698Sdimdef SQDMULHhhv_4H : NeonI_ScalarXIndexedElemArith<"sqdmulh", 5770259698Sdim 0b1100, ".h", 0b0, 0b0, 0b1, FPR16, FPR16, VPR64Lo, neon_uimm2_bare> { 5771259698Sdim let Inst{11} = 0b0; // h 5772259698Sdim let Inst{21} = Imm{1}; // l 5773259698Sdim let Inst{20} = Imm{0}; // m 5774259698Sdim let Inst{19-16} = MRm{3-0}; 5775259698Sdim} 5776259698Sdimdef SQDMULHhhv_8H : NeonI_ScalarXIndexedElemArith<"sqdmulh", 5777259698Sdim 0b1100, ".h", 0b0, 0b0, 0b1, FPR16, FPR16, VPR128Lo, neon_uimm3_bare> { 5778259698Sdim let Inst{11} = Imm{2}; // h 5779259698Sdim let Inst{21} = Imm{1}; // l 5780259698Sdim let Inst{20} = Imm{0}; // m 5781259698Sdim let Inst{19-16} = MRm{3-0}; 5782259698Sdim} 5783259698Sdimdef SQDMULHssv_2S : NeonI_ScalarXIndexedElemArith<"sqdmulh", 5784259698Sdim 0b1100, ".s", 0b0, 0b1, 0b0, FPR32, FPR32, VPR64, neon_uimm1_bare> { 5785259698Sdim let Inst{11} = 0b0; // h 5786259698Sdim let Inst{21} = Imm{0}; // l 5787259698Sdim let Inst{20-16} = MRm; 5788259698Sdim} 5789259698Sdimdef SQDMULHssv_4S : NeonI_ScalarXIndexedElemArith<"sqdmulh", 5790259698Sdim 0b1100, ".s", 0b0, 0b1, 0b0, FPR32, FPR32, VPR128, neon_uimm2_bare> { 5791259698Sdim let Inst{11} = Imm{1}; // h 5792259698Sdim let Inst{21} = Imm{0}; // l 5793259698Sdim let Inst{20-16} = MRm; 5794259698Sdim} 5795259698Sdim 5796259698Sdim// Patterns for Scalar Signed saturating doubling multiply returning 5797259698Sdim// high half (scalar, by element) 5798259698Sdimdefm : Neon_ScalarXIndexedElem_MUL_Patterns<int_arm_neon_vqdmulh, 5799259698Sdim SQDMULHhhv_4H, v1i16, FPR16, v1i16, i16, v4i16, 5800259698Sdim i32, VPR64Lo, neon_uimm2_bare>; 5801259698Sdimdefm : Neon_ScalarXIndexedElem_MUL_Patterns<int_arm_neon_vqdmulh, 5802259698Sdim SQDMULHhhv_8H, v1i16, FPR16, v1i16, i16, v8i16, 5803259698Sdim i32, VPR128Lo, neon_uimm3_bare>; 5804259698Sdimdefm : Neon_ScalarXIndexedElem_MUL_Patterns<int_arm_neon_vqdmulh, 5805259698Sdim SQDMULHssv_2S, v1i32, FPR32, v1i32, i32, v2i32, 5806259698Sdim i32, VPR64Lo, neon_uimm1_bare>; 5807259698Sdimdefm : Neon_ScalarXIndexedElem_MUL_Patterns<int_arm_neon_vqdmulh, 5808259698Sdim SQDMULHssv_4S, v1i32, FPR32, v1i32, i32, v4i32, 5809259698Sdim i32, VPR128Lo, neon_uimm2_bare>; 5810259698Sdim 5811259698Sdim// Scalar Signed saturating rounding doubling multiply 5812259698Sdim// returning high half (scalar, by element) 5813259698Sdimdef SQRDMULHhhv_4H : NeonI_ScalarXIndexedElemArith<"sqrdmulh", 5814259698Sdim 0b1101, ".h", 0b0, 0b0, 0b1, FPR16, FPR16, VPR64Lo, neon_uimm2_bare> { 5815259698Sdim let Inst{11} = 0b0; // h 5816259698Sdim let Inst{21} = Imm{1}; // l 5817259698Sdim let Inst{20} = Imm{0}; // m 5818259698Sdim let Inst{19-16} = MRm{3-0}; 5819259698Sdim} 5820259698Sdimdef SQRDMULHhhv_8H : NeonI_ScalarXIndexedElemArith<"sqrdmulh", 5821259698Sdim 0b1101, ".h", 0b0, 0b0, 0b1, FPR16, FPR16, VPR128Lo, neon_uimm3_bare> { 5822259698Sdim let Inst{11} = Imm{2}; // h 5823259698Sdim let Inst{21} = Imm{1}; // l 5824259698Sdim let Inst{20} = Imm{0}; // m 5825259698Sdim let Inst{19-16} = MRm{3-0}; 5826259698Sdim} 5827259698Sdimdef SQRDMULHssv_2S : NeonI_ScalarXIndexedElemArith<"sqrdmulh", 5828259698Sdim 0b1101, ".s", 0b0, 0b1, 0b0, FPR32, FPR32, VPR64, neon_uimm1_bare> { 5829259698Sdim let Inst{11} = 0b0; // h 5830259698Sdim let Inst{21} = Imm{0}; // l 5831259698Sdim let Inst{20-16} = MRm; 5832259698Sdim} 5833259698Sdimdef SQRDMULHssv_4S : NeonI_ScalarXIndexedElemArith<"sqrdmulh", 5834259698Sdim 0b1101, ".s", 0b0, 0b1, 0b0, FPR32, FPR32, VPR128, neon_uimm2_bare> { 5835259698Sdim let Inst{11} = Imm{1}; // h 5836259698Sdim let Inst{21} = Imm{0}; // l 5837259698Sdim let Inst{20-16} = MRm; 5838259698Sdim} 5839259698Sdim 5840259698Sdimdefm : Neon_ScalarXIndexedElem_MUL_Patterns<int_arm_neon_vqrdmulh, 5841259698Sdim SQRDMULHhhv_4H, v1i16, FPR16, v1i16, i16, v4i16, i32, 5842259698Sdim VPR64Lo, neon_uimm2_bare>; 5843259698Sdimdefm : Neon_ScalarXIndexedElem_MUL_Patterns<int_arm_neon_vqrdmulh, 5844259698Sdim SQRDMULHhhv_8H, v1i16, FPR16, v1i16, i16, v8i16, i32, 5845259698Sdim VPR128Lo, neon_uimm3_bare>; 5846259698Sdimdefm : Neon_ScalarXIndexedElem_MUL_Patterns<int_arm_neon_vqrdmulh, 5847259698Sdim SQRDMULHssv_2S, v1i32, FPR32, v1i32, i32, v2i32, i32, 5848259698Sdim VPR64Lo, neon_uimm1_bare>; 5849259698Sdimdefm : Neon_ScalarXIndexedElem_MUL_Patterns<int_arm_neon_vqrdmulh, 5850259698Sdim SQRDMULHssv_4S, v1i32, FPR32, v1i32, i32, v4i32, i32, 5851259698Sdim VPR128Lo, neon_uimm2_bare>; 5852259698Sdim 5853259698Sdim// Scalar Copy - DUP element to scalar 5854259698Sdimclass NeonI_Scalar_DUP<string asmop, string asmlane, 5855259698Sdim RegisterClass ResRC, RegisterOperand VPRC, 5856259698Sdim Operand OpImm> 5857259698Sdim : NeonI_ScalarCopy<(outs ResRC:$Rd), (ins VPRC:$Rn, OpImm:$Imm), 5858259698Sdim asmop # "\t$Rd, $Rn." # asmlane # "[$Imm]", 5859259698Sdim [], 5860259698Sdim NoItinerary> { 5861259698Sdim bits<4> Imm; 5862259698Sdim} 5863259698Sdim 5864259698Sdimdef DUPbv_B : NeonI_Scalar_DUP<"dup", "b", FPR8, VPR128, neon_uimm4_bare> { 5865259698Sdim let Inst{20-16} = {Imm{3}, Imm{2}, Imm{1}, Imm{0}, 0b1}; 5866259698Sdim} 5867259698Sdimdef DUPhv_H : NeonI_Scalar_DUP<"dup", "h", FPR16, VPR128, neon_uimm3_bare> { 5868259698Sdim let Inst{20-16} = {Imm{2}, Imm{1}, Imm{0}, 0b1, 0b0}; 5869259698Sdim} 5870259698Sdimdef DUPsv_S : NeonI_Scalar_DUP<"dup", "s", FPR32, VPR128, neon_uimm2_bare> { 5871259698Sdim let Inst{20-16} = {Imm{1}, Imm{0}, 0b1, 0b0, 0b0}; 5872259698Sdim} 5873259698Sdimdef DUPdv_D : NeonI_Scalar_DUP<"dup", "d", FPR64, VPR128, neon_uimm1_bare> { 5874259698Sdim let Inst{20-16} = {Imm, 0b1, 0b0, 0b0, 0b0}; 5875259698Sdim} 5876259698Sdim 5877259698Sdimmulticlass NeonI_Scalar_DUP_Elt_pattern<Instruction DUPI, ValueType ResTy, 5878259698Sdim ValueType OpTy, Operand OpImm, 5879259698Sdim ValueType OpNTy, ValueType ExTy, Operand OpNImm> { 5880259698Sdim def : Pat<(ResTy (vector_extract (OpTy VPR128:$Rn), OpImm:$Imm)), 5881259698Sdim (ResTy (DUPI (OpTy VPR128:$Rn), OpImm:$Imm))>; 5882259698Sdim 5883259698Sdim def : Pat<(ResTy (vector_extract (OpNTy VPR64:$Rn), OpNImm:$Imm)), 5884259698Sdim (ResTy (DUPI 5885259698Sdim (ExTy (SUBREG_TO_REG (i64 0), VPR64:$Rn, sub_64)), 5886259698Sdim OpNImm:$Imm))>; 5887259698Sdim} 5888259698Sdim 5889259698Sdim// Patterns for vector extract of FP data using scalar DUP instructions 5890259698Sdimdefm : NeonI_Scalar_DUP_Elt_pattern<DUPsv_S, f32, 5891259698Sdim v4f32, neon_uimm2_bare, v2f32, v4f32, neon_uimm1_bare>; 5892259698Sdimdefm : NeonI_Scalar_DUP_Elt_pattern<DUPdv_D, f64, 5893259698Sdim v2f64, neon_uimm1_bare, v1f64, v2f64, neon_uimm0_bare>; 5894259698Sdim 5895259698Sdimmulticlass NeonI_Scalar_DUP_Ext_Vec_pattern<Instruction DUPI, 5896259698Sdim ValueType ResTy, ValueType OpTy,Operand OpLImm, 5897259698Sdim ValueType NOpTy, ValueType ExTy, Operand OpNImm> { 5898259698Sdim 5899259698Sdim def : Pat<(ResTy (extract_subvector (OpTy VPR128:$Rn), OpLImm:$Imm)), 5900259698Sdim (ResTy (DUPI VPR128:$Rn, OpLImm:$Imm))>; 5901259698Sdim 5902259698Sdim def : Pat<(ResTy (extract_subvector (NOpTy VPR64:$Rn), OpNImm:$Imm)), 5903259698Sdim (ResTy (DUPI 5904259698Sdim (ExTy (SUBREG_TO_REG (i64 0), VPR64:$Rn, sub_64)), 5905259698Sdim OpNImm:$Imm))>; 5906259698Sdim} 5907259698Sdim 5908259698Sdim// Patterns for extract subvectors of v1ix data using scalar DUP instructions. 5909259698Sdimdefm : NeonI_Scalar_DUP_Ext_Vec_pattern<DUPbv_B, v1i8, v16i8, neon_uimm4_bare, 5910259698Sdim v8i8, v16i8, neon_uimm3_bare>; 5911259698Sdimdefm : NeonI_Scalar_DUP_Ext_Vec_pattern<DUPhv_H, v1i16, v8i16, neon_uimm3_bare, 5912259698Sdim v4i16, v8i16, neon_uimm2_bare>; 5913259698Sdimdefm : NeonI_Scalar_DUP_Ext_Vec_pattern<DUPsv_S, v1i32, v4i32, neon_uimm2_bare, 5914259698Sdim v2i32, v4i32, neon_uimm1_bare>; 5915259698Sdim 5916259698Sdimmulticlass NeonI_Scalar_DUP_Copy_pattern1<Instruction DUPI, ValueType ResTy, 5917259698Sdim ValueType OpTy, ValueType ElemTy, 5918259698Sdim Operand OpImm, ValueType OpNTy, 5919259698Sdim ValueType ExTy, Operand OpNImm> { 5920259698Sdim 5921259698Sdim def : Pat<(ResTy (vector_insert (ResTy undef), 5922259698Sdim (ElemTy (vector_extract (OpTy VPR128:$Rn), OpImm:$Imm)), 5923259698Sdim (neon_uimm0_bare:$Imm))), 5924259698Sdim (ResTy (DUPI (OpTy VPR128:$Rn), OpImm:$Imm))>; 5925259698Sdim 5926259698Sdim def : Pat<(ResTy (vector_insert (ResTy undef), 5927259698Sdim (ElemTy (vector_extract (OpNTy VPR64:$Rn), OpNImm:$Imm)), 5928259698Sdim (OpNImm:$Imm))), 5929259698Sdim (ResTy (DUPI 5930259698Sdim (ExTy (SUBREG_TO_REG (i64 0), VPR64:$Rn, sub_64)), 5931259698Sdim OpNImm:$Imm))>; 5932259698Sdim} 5933259698Sdim 5934259698Sdimmulticlass NeonI_Scalar_DUP_Copy_pattern2<Instruction DUPI, ValueType ResTy, 5935259698Sdim ValueType OpTy, ValueType ElemTy, 5936259698Sdim Operand OpImm, ValueType OpNTy, 5937259698Sdim ValueType ExTy, Operand OpNImm> { 5938259698Sdim 5939259698Sdim def : Pat<(ResTy (scalar_to_vector 5940259698Sdim (ElemTy (vector_extract (OpTy VPR128:$Rn), OpImm:$Imm)))), 5941259698Sdim (ResTy (DUPI (OpTy VPR128:$Rn), OpImm:$Imm))>; 5942259698Sdim 5943259698Sdim def : Pat<(ResTy (scalar_to_vector 5944259698Sdim (ElemTy (vector_extract (OpNTy VPR64:$Rn), OpNImm:$Imm)))), 5945259698Sdim (ResTy (DUPI 5946259698Sdim (ExTy (SUBREG_TO_REG (i64 0), VPR64:$Rn, sub_64)), 5947259698Sdim OpNImm:$Imm))>; 5948259698Sdim} 5949259698Sdim 5950259698Sdim// Patterns for vector copy to v1ix and v1fx vectors using scalar DUP 5951259698Sdim// instructions. 5952259698Sdimdefm : NeonI_Scalar_DUP_Copy_pattern1<DUPdv_D, 5953259698Sdim v1i64, v2i64, i64, neon_uimm1_bare, 5954259698Sdim v1i64, v2i64, neon_uimm0_bare>; 5955259698Sdimdefm : NeonI_Scalar_DUP_Copy_pattern1<DUPsv_S, 5956259698Sdim v1i32, v4i32, i32, neon_uimm2_bare, 5957259698Sdim v2i32, v4i32, neon_uimm1_bare>; 5958259698Sdimdefm : NeonI_Scalar_DUP_Copy_pattern1<DUPhv_H, 5959259698Sdim v1i16, v8i16, i32, neon_uimm3_bare, 5960259698Sdim v4i16, v8i16, neon_uimm2_bare>; 5961259698Sdimdefm : NeonI_Scalar_DUP_Copy_pattern1<DUPbv_B, 5962259698Sdim v1i8, v16i8, i32, neon_uimm4_bare, 5963259698Sdim v8i8, v16i8, neon_uimm3_bare>; 5964259698Sdimdefm : NeonI_Scalar_DUP_Copy_pattern1<DUPdv_D, 5965259698Sdim v1f64, v2f64, f64, neon_uimm1_bare, 5966259698Sdim v1f64, v2f64, neon_uimm0_bare>; 5967259698Sdimdefm : NeonI_Scalar_DUP_Copy_pattern1<DUPsv_S, 5968259698Sdim v1f32, v4f32, f32, neon_uimm2_bare, 5969259698Sdim v2f32, v4f32, neon_uimm1_bare>; 5970259698Sdimdefm : NeonI_Scalar_DUP_Copy_pattern2<DUPdv_D, 5971259698Sdim v1i64, v2i64, i64, neon_uimm1_bare, 5972259698Sdim v1i64, v2i64, neon_uimm0_bare>; 5973259698Sdimdefm : NeonI_Scalar_DUP_Copy_pattern2<DUPsv_S, 5974259698Sdim v1i32, v4i32, i32, neon_uimm2_bare, 5975259698Sdim v2i32, v4i32, neon_uimm1_bare>; 5976259698Sdimdefm : NeonI_Scalar_DUP_Copy_pattern2<DUPhv_H, 5977259698Sdim v1i16, v8i16, i32, neon_uimm3_bare, 5978259698Sdim v4i16, v8i16, neon_uimm2_bare>; 5979259698Sdimdefm : NeonI_Scalar_DUP_Copy_pattern2<DUPbv_B, 5980259698Sdim v1i8, v16i8, i32, neon_uimm4_bare, 5981259698Sdim v8i8, v16i8, neon_uimm3_bare>; 5982259698Sdimdefm : NeonI_Scalar_DUP_Copy_pattern2<DUPdv_D, 5983259698Sdim v1f64, v2f64, f64, neon_uimm1_bare, 5984259698Sdim v1f64, v2f64, neon_uimm0_bare>; 5985259698Sdimdefm : NeonI_Scalar_DUP_Copy_pattern2<DUPsv_S, 5986259698Sdim v1f32, v4f32, f32, neon_uimm2_bare, 5987259698Sdim v2f32, v4f32, neon_uimm1_bare>; 5988259698Sdim 5989259698Sdimmulticlass NeonI_Scalar_DUP_alias<string asmop, string asmlane, 5990259698Sdim Instruction DUPI, Operand OpImm, 5991259698Sdim RegisterClass ResRC> { 5992259698Sdim def : NeonInstAlias<!strconcat(asmop, "$Rd, $Rn" # asmlane # "[$Imm]"), 5993259698Sdim (DUPI ResRC:$Rd, VPR128:$Rn, OpImm:$Imm), 0b0>; 5994259698Sdim} 5995259698Sdim 5996259698Sdim// Aliases for Scalar copy - DUP element (scalar) 5997259698Sdim// FIXME: This is actually the preferred syntax but TableGen can't deal with 5998259698Sdim// custom printing of aliases. 5999259698Sdimdefm : NeonI_Scalar_DUP_alias<"mov", ".b", DUPbv_B, neon_uimm4_bare, FPR8>; 6000259698Sdimdefm : NeonI_Scalar_DUP_alias<"mov", ".h", DUPhv_H, neon_uimm3_bare, FPR16>; 6001259698Sdimdefm : NeonI_Scalar_DUP_alias<"mov", ".s", DUPsv_S, neon_uimm2_bare, FPR32>; 6002259698Sdimdefm : NeonI_Scalar_DUP_alias<"mov", ".d", DUPdv_D, neon_uimm1_bare, FPR64>; 6003259698Sdim 6004259698Sdimmulticlass NeonI_SDUP<PatFrag GetLow, PatFrag GetHigh, ValueType ResTy, 6005259698Sdim ValueType OpTy> { 6006259698Sdim def : Pat<(ResTy (GetLow VPR128:$Rn)), 6007259698Sdim (ResTy (EXTRACT_SUBREG (OpTy VPR128:$Rn), sub_64))>; 6008259698Sdim def : Pat<(ResTy (GetHigh VPR128:$Rn)), 6009259698Sdim (ResTy (DUPdv_D (OpTy VPR128:$Rn), 1))>; 6010259698Sdim} 6011259698Sdim 6012259698Sdimdefm : NeonI_SDUP<Neon_Low16B, Neon_High16B, v8i8, v16i8>; 6013259698Sdimdefm : NeonI_SDUP<Neon_Low8H, Neon_High8H, v4i16, v8i16>; 6014259698Sdimdefm : NeonI_SDUP<Neon_Low4S, Neon_High4S, v2i32, v4i32>; 6015259698Sdimdefm : NeonI_SDUP<Neon_Low2D, Neon_High2D, v1i64, v2i64>; 6016259698Sdimdefm : NeonI_SDUP<Neon_Low4float, Neon_High4float, v2f32, v4f32>; 6017259698Sdimdefm : NeonI_SDUP<Neon_Low2double, Neon_High2double, v1f64, v2f64>; 6018259698Sdim 6019259698Sdim//===----------------------------------------------------------------------===// 6020259698Sdim// Non-Instruction Patterns 6021259698Sdim//===----------------------------------------------------------------------===// 6022259698Sdim 6023259698Sdim// 64-bit vector bitcasts... 6024259698Sdim 6025259698Sdimdef : Pat<(v1i64 (bitconvert (v8i8 VPR64:$src))), (v1i64 VPR64:$src)>; 6026259698Sdimdef : Pat<(v2f32 (bitconvert (v8i8 VPR64:$src))), (v2f32 VPR64:$src)>; 6027259698Sdimdef : Pat<(v2i32 (bitconvert (v8i8 VPR64:$src))), (v2i32 VPR64:$src)>; 6028259698Sdimdef : Pat<(v4i16 (bitconvert (v8i8 VPR64:$src))), (v4i16 VPR64:$src)>; 6029259698Sdim 6030259698Sdimdef : Pat<(v1i64 (bitconvert (v4i16 VPR64:$src))), (v1i64 VPR64:$src)>; 6031259698Sdimdef : Pat<(v2i32 (bitconvert (v4i16 VPR64:$src))), (v2i32 VPR64:$src)>; 6032259698Sdimdef : Pat<(v2f32 (bitconvert (v4i16 VPR64:$src))), (v2f32 VPR64:$src)>; 6033259698Sdimdef : Pat<(v8i8 (bitconvert (v4i16 VPR64:$src))), (v8i8 VPR64:$src)>; 6034259698Sdim 6035259698Sdimdef : Pat<(v1i64 (bitconvert (v2i32 VPR64:$src))), (v1i64 VPR64:$src)>; 6036259698Sdimdef : Pat<(v2f32 (bitconvert (v2i32 VPR64:$src))), (v2f32 VPR64:$src)>; 6037259698Sdimdef : Pat<(v4i16 (bitconvert (v2i32 VPR64:$src))), (v4i16 VPR64:$src)>; 6038259698Sdimdef : Pat<(v8i8 (bitconvert (v2i32 VPR64:$src))), (v8i8 VPR64:$src)>; 6039259698Sdim 6040259698Sdimdef : Pat<(v1i64 (bitconvert (v2f32 VPR64:$src))), (v1i64 VPR64:$src)>; 6041259698Sdimdef : Pat<(v2i32 (bitconvert (v2f32 VPR64:$src))), (v2i32 VPR64:$src)>; 6042259698Sdimdef : Pat<(v4i16 (bitconvert (v2f32 VPR64:$src))), (v4i16 VPR64:$src)>; 6043259698Sdimdef : Pat<(v8i8 (bitconvert (v2f32 VPR64:$src))), (v8i8 VPR64:$src)>; 6044259698Sdim 6045259698Sdimdef : Pat<(v2f32 (bitconvert (v1i64 VPR64:$src))), (v2f32 VPR64:$src)>; 6046259698Sdimdef : Pat<(v2i32 (bitconvert (v1i64 VPR64:$src))), (v2i32 VPR64:$src)>; 6047259698Sdimdef : Pat<(v4i16 (bitconvert (v1i64 VPR64:$src))), (v4i16 VPR64:$src)>; 6048259698Sdimdef : Pat<(v8i8 (bitconvert (v1i64 VPR64:$src))), (v8i8 VPR64:$src)>; 6049259698Sdim 6050259698Sdim// ..and 128-bit vector bitcasts... 6051259698Sdim 6052259698Sdimdef : Pat<(v2f64 (bitconvert (v16i8 VPR128:$src))), (v2f64 VPR128:$src)>; 6053259698Sdimdef : Pat<(v2i64 (bitconvert (v16i8 VPR128:$src))), (v2i64 VPR128:$src)>; 6054259698Sdimdef : Pat<(v4f32 (bitconvert (v16i8 VPR128:$src))), (v4f32 VPR128:$src)>; 6055259698Sdimdef : Pat<(v4i32 (bitconvert (v16i8 VPR128:$src))), (v4i32 VPR128:$src)>; 6056259698Sdimdef : Pat<(v8i16 (bitconvert (v16i8 VPR128:$src))), (v8i16 VPR128:$src)>; 6057259698Sdim 6058259698Sdimdef : Pat<(v2f64 (bitconvert (v8i16 VPR128:$src))), (v2f64 VPR128:$src)>; 6059259698Sdimdef : Pat<(v2i64 (bitconvert (v8i16 VPR128:$src))), (v2i64 VPR128:$src)>; 6060259698Sdimdef : Pat<(v4i32 (bitconvert (v8i16 VPR128:$src))), (v4i32 VPR128:$src)>; 6061259698Sdimdef : Pat<(v4f32 (bitconvert (v8i16 VPR128:$src))), (v4f32 VPR128:$src)>; 6062259698Sdimdef : Pat<(v16i8 (bitconvert (v8i16 VPR128:$src))), (v16i8 VPR128:$src)>; 6063259698Sdim 6064259698Sdimdef : Pat<(v2f64 (bitconvert (v4i32 VPR128:$src))), (v2f64 VPR128:$src)>; 6065259698Sdimdef : Pat<(v2i64 (bitconvert (v4i32 VPR128:$src))), (v2i64 VPR128:$src)>; 6066259698Sdimdef : Pat<(v4f32 (bitconvert (v4i32 VPR128:$src))), (v4f32 VPR128:$src)>; 6067259698Sdimdef : Pat<(v8i16 (bitconvert (v4i32 VPR128:$src))), (v8i16 VPR128:$src)>; 6068259698Sdimdef : Pat<(v16i8 (bitconvert (v4i32 VPR128:$src))), (v16i8 VPR128:$src)>; 6069259698Sdim 6070259698Sdimdef : Pat<(v2f64 (bitconvert (v4f32 VPR128:$src))), (v2f64 VPR128:$src)>; 6071259698Sdimdef : Pat<(v2i64 (bitconvert (v4f32 VPR128:$src))), (v2i64 VPR128:$src)>; 6072259698Sdimdef : Pat<(v4i32 (bitconvert (v4f32 VPR128:$src))), (v4i32 VPR128:$src)>; 6073259698Sdimdef : Pat<(v8i16 (bitconvert (v4f32 VPR128:$src))), (v8i16 VPR128:$src)>; 6074259698Sdimdef : Pat<(v16i8 (bitconvert (v4f32 VPR128:$src))), (v16i8 VPR128:$src)>; 6075259698Sdim 6076259698Sdimdef : Pat<(v2f64 (bitconvert (v2i64 VPR128:$src))), (v2f64 VPR128:$src)>; 6077259698Sdimdef : Pat<(v4f32 (bitconvert (v2i64 VPR128:$src))), (v4f32 VPR128:$src)>; 6078259698Sdimdef : Pat<(v4i32 (bitconvert (v2i64 VPR128:$src))), (v4i32 VPR128:$src)>; 6079259698Sdimdef : Pat<(v8i16 (bitconvert (v2i64 VPR128:$src))), (v8i16 VPR128:$src)>; 6080259698Sdimdef : Pat<(v16i8 (bitconvert (v2i64 VPR128:$src))), (v16i8 VPR128:$src)>; 6081259698Sdim 6082259698Sdimdef : Pat<(v2i64 (bitconvert (v2f64 VPR128:$src))), (v2i64 VPR128:$src)>; 6083259698Sdimdef : Pat<(v4f32 (bitconvert (v2f64 VPR128:$src))), (v4f32 VPR128:$src)>; 6084259698Sdimdef : Pat<(v4i32 (bitconvert (v2f64 VPR128:$src))), (v4i32 VPR128:$src)>; 6085259698Sdimdef : Pat<(v8i16 (bitconvert (v2f64 VPR128:$src))), (v8i16 VPR128:$src)>; 6086259698Sdimdef : Pat<(v16i8 (bitconvert (v2f64 VPR128:$src))), (v16i8 VPR128:$src)>; 6087259698Sdim 6088259698Sdim// ...and scalar bitcasts... 6089259698Sdimdef : Pat<(f16 (bitconvert (v1i16 FPR16:$src))), (f16 FPR16:$src)>; 6090259698Sdimdef : Pat<(f32 (bitconvert (v1i32 FPR32:$src))), (f32 FPR32:$src)>; 6091259698Sdimdef : Pat<(f64 (bitconvert (v1i64 FPR64:$src))), (f64 FPR64:$src)>; 6092259698Sdimdef : Pat<(f32 (bitconvert (v1f32 FPR32:$src))), (f32 FPR32:$src)>; 6093259698Sdimdef : Pat<(f64 (bitconvert (v1f64 FPR64:$src))), (f64 FPR64:$src)>; 6094259698Sdim 6095259698Sdimdef : Pat<(i64 (bitconvert (v1i64 FPR64:$src))), (FMOVxd $src)>; 6096259698Sdimdef : Pat<(i64 (bitconvert (v1f64 FPR64:$src))), (FMOVxd $src)>; 6097259698Sdimdef : Pat<(i64 (bitconvert (v2i32 FPR64:$src))), (FMOVxd $src)>; 6098259698Sdimdef : Pat<(i64 (bitconvert (v2f32 FPR64:$src))), (FMOVxd $src)>; 6099259698Sdimdef : Pat<(i64 (bitconvert (v4i16 FPR64:$src))), (FMOVxd $src)>; 6100259698Sdimdef : Pat<(i64 (bitconvert (v8i8 FPR64:$src))), (FMOVxd $src)>; 6101259698Sdim 6102259698Sdimdef : Pat<(i32 (bitconvert (v1i32 FPR32:$src))), (FMOVws $src)>; 6103259698Sdim 6104259698Sdimdef : Pat<(v8i8 (bitconvert (v1i64 VPR64:$src))), (v8i8 VPR64:$src)>; 6105259698Sdimdef : Pat<(v4i16 (bitconvert (v1i64 VPR64:$src))), (v4i16 VPR64:$src)>; 6106259698Sdimdef : Pat<(v2i32 (bitconvert (v1i64 VPR64:$src))), (v2i32 VPR64:$src)>; 6107259698Sdim 6108259698Sdimdef : Pat<(f64 (bitconvert (v8i8 VPR64:$src))), (f64 VPR64:$src)>; 6109259698Sdimdef : Pat<(f64 (bitconvert (v4i16 VPR64:$src))), (f64 VPR64:$src)>; 6110259698Sdimdef : Pat<(f64 (bitconvert (v2i32 VPR64:$src))), (f64 VPR64:$src)>; 6111259698Sdimdef : Pat<(f64 (bitconvert (v2f32 VPR64:$src))), (f64 VPR64:$src)>; 6112259698Sdimdef : Pat<(f64 (bitconvert (v1i64 VPR64:$src))), (f64 VPR64:$src)>; 6113259698Sdim 6114259698Sdimdef : Pat<(f128 (bitconvert (v16i8 VPR128:$src))), (f128 VPR128:$src)>; 6115259698Sdimdef : Pat<(f128 (bitconvert (v8i16 VPR128:$src))), (f128 VPR128:$src)>; 6116259698Sdimdef : Pat<(f128 (bitconvert (v4i32 VPR128:$src))), (f128 VPR128:$src)>; 6117259698Sdimdef : Pat<(f128 (bitconvert (v2i64 VPR128:$src))), (f128 VPR128:$src)>; 6118259698Sdimdef : Pat<(f128 (bitconvert (v4f32 VPR128:$src))), (f128 VPR128:$src)>; 6119259698Sdimdef : Pat<(f128 (bitconvert (v2f64 VPR128:$src))), (f128 VPR128:$src)>; 6120259698Sdim 6121259698Sdimdef : Pat<(v1i16 (bitconvert (f16 FPR16:$src))), (v1i16 FPR16:$src)>; 6122259698Sdimdef : Pat<(v1i32 (bitconvert (f32 FPR32:$src))), (v1i32 FPR32:$src)>; 6123259698Sdimdef : Pat<(v1i64 (bitconvert (f64 FPR64:$src))), (v1i64 FPR64:$src)>; 6124259698Sdimdef : Pat<(v1f32 (bitconvert (f32 FPR32:$src))), (v1f32 FPR32:$src)>; 6125259698Sdimdef : Pat<(v1f64 (bitconvert (f64 FPR64:$src))), (v1f64 FPR64:$src)>; 6126259698Sdim 6127259698Sdimdef : Pat<(v1i64 (bitconvert (i64 GPR64:$src))), (FMOVdx $src)>; 6128259698Sdimdef : Pat<(v1f64 (bitconvert (i64 GPR64:$src))), (FMOVdx $src)>; 6129259698Sdimdef : Pat<(v2i32 (bitconvert (i64 GPR64:$src))), (FMOVdx $src)>; 6130259698Sdimdef : Pat<(v2f32 (bitconvert (i64 GPR64:$src))), (FMOVdx $src)>; 6131259698Sdimdef : Pat<(v4i16 (bitconvert (i64 GPR64:$src))), (FMOVdx $src)>; 6132259698Sdimdef : Pat<(v8i8 (bitconvert (i64 GPR64:$src))), (FMOVdx $src)>; 6133259698Sdim 6134259698Sdimdef : Pat<(v1i32 (bitconvert (i32 GPR32:$src))), (FMOVsw $src)>; 6135259698Sdim 6136259698Sdimdef : Pat<(v8i8 (bitconvert (f64 FPR64:$src))), (v8i8 FPR64:$src)>; 6137259698Sdimdef : Pat<(v4i16 (bitconvert (f64 FPR64:$src))), (v4i16 FPR64:$src)>; 6138259698Sdimdef : Pat<(v2i32 (bitconvert (f64 FPR64:$src))), (v2i32 FPR64:$src)>; 6139259698Sdimdef : Pat<(v2f32 (bitconvert (f64 FPR64:$src))), (v2f32 FPR64:$src)>; 6140259698Sdimdef : Pat<(v1i64 (bitconvert (f64 FPR64:$src))), (v1i64 FPR64:$src)>; 6141259698Sdim 6142259698Sdimdef : Pat<(v16i8 (bitconvert (f128 FPR128:$src))), (v16i8 FPR128:$src)>; 6143259698Sdimdef : Pat<(v8i16 (bitconvert (f128 FPR128:$src))), (v8i16 FPR128:$src)>; 6144259698Sdimdef : Pat<(v4i32 (bitconvert (f128 FPR128:$src))), (v4i32 FPR128:$src)>; 6145259698Sdimdef : Pat<(v2i64 (bitconvert (f128 FPR128:$src))), (v2i64 FPR128:$src)>; 6146259698Sdimdef : Pat<(v4f32 (bitconvert (f128 FPR128:$src))), (v4f32 FPR128:$src)>; 6147259698Sdimdef : Pat<(v2f64 (bitconvert (f128 FPR128:$src))), (v2f64 FPR128:$src)>; 6148259698Sdim 6149259698Sdim// Scalar Three Same 6150259698Sdim 6151259698Sdimdef neon_uimm3 : Operand<i64>, 6152259698Sdim ImmLeaf<i64, [{return Imm < 8;}]> { 6153259698Sdim let ParserMatchClass = uimm3_asmoperand; 6154259698Sdim let PrintMethod = "printUImmHexOperand"; 6155259698Sdim} 6156259698Sdim 6157259698Sdimdef neon_uimm4 : Operand<i64>, 6158259698Sdim ImmLeaf<i64, [{return Imm < 16;}]> { 6159259698Sdim let ParserMatchClass = uimm4_asmoperand; 6160259698Sdim let PrintMethod = "printUImmHexOperand"; 6161259698Sdim} 6162259698Sdim 6163259698Sdim// Bitwise Extract 6164259698Sdimclass NeonI_Extract<bit q, bits<2> op2, string asmop, 6165259698Sdim string OpS, RegisterOperand OpVPR, Operand OpImm> 6166259698Sdim : NeonI_BitExtract<q, op2, (outs OpVPR:$Rd), 6167259698Sdim (ins OpVPR:$Rn, OpVPR:$Rm, OpImm:$Index), 6168259698Sdim asmop # "\t$Rd." # OpS # ", $Rn." # OpS # 6169259698Sdim ", $Rm." # OpS # ", $Index", 6170259698Sdim [], 6171259698Sdim NoItinerary>{ 6172259698Sdim bits<4> Index; 6173259698Sdim} 6174259698Sdim 6175259698Sdimdef EXTvvvi_8b : NeonI_Extract<0b0, 0b00, "ext", "8b", 6176259698Sdim VPR64, neon_uimm3> { 6177259698Sdim let Inst{14-11} = {0b0, Index{2}, Index{1}, Index{0}}; 6178259698Sdim} 6179259698Sdim 6180259698Sdimdef EXTvvvi_16b: NeonI_Extract<0b1, 0b00, "ext", "16b", 6181259698Sdim VPR128, neon_uimm4> { 6182259698Sdim let Inst{14-11} = Index; 6183259698Sdim} 6184259698Sdim 6185259698Sdimclass NI_Extract<ValueType OpTy, RegisterOperand OpVPR, Instruction INST, 6186259698Sdim Operand OpImm> 6187259698Sdim : Pat<(OpTy (Neon_vextract (OpTy OpVPR:$Rn), (OpTy OpVPR:$Rm), 6188259698Sdim (i64 OpImm:$Imm))), 6189259698Sdim (INST OpVPR:$Rn, OpVPR:$Rm, OpImm:$Imm)>; 6190259698Sdim 6191259698Sdimdef : NI_Extract<v8i8, VPR64, EXTvvvi_8b, neon_uimm3>; 6192259698Sdimdef : NI_Extract<v4i16, VPR64, EXTvvvi_8b, neon_uimm3>; 6193259698Sdimdef : NI_Extract<v2i32, VPR64, EXTvvvi_8b, neon_uimm3>; 6194259698Sdimdef : NI_Extract<v1i64, VPR64, EXTvvvi_8b, neon_uimm3>; 6195259698Sdimdef : NI_Extract<v2f32, VPR64, EXTvvvi_8b, neon_uimm3>; 6196259698Sdimdef : NI_Extract<v1f64, VPR64, EXTvvvi_8b, neon_uimm3>; 6197259698Sdimdef : NI_Extract<v16i8, VPR128, EXTvvvi_16b, neon_uimm4>; 6198259698Sdimdef : NI_Extract<v8i16, VPR128, EXTvvvi_16b, neon_uimm4>; 6199259698Sdimdef : NI_Extract<v4i32, VPR128, EXTvvvi_16b, neon_uimm4>; 6200259698Sdimdef : NI_Extract<v2i64, VPR128, EXTvvvi_16b, neon_uimm4>; 6201259698Sdimdef : NI_Extract<v4f32, VPR128, EXTvvvi_16b, neon_uimm4>; 6202259698Sdimdef : NI_Extract<v2f64, VPR128, EXTvvvi_16b, neon_uimm4>; 6203259698Sdim 6204259698Sdim// Table lookup 6205259698Sdimclass NI_TBL<bit q, bits<2> op2, bits<2> len, bit op, 6206259698Sdim string asmop, string OpS, RegisterOperand OpVPR, 6207259698Sdim RegisterOperand VecList> 6208259698Sdim : NeonI_TBL<q, op2, len, op, 6209259698Sdim (outs OpVPR:$Rd), (ins VecList:$Rn, OpVPR:$Rm), 6210259698Sdim asmop # "\t$Rd." # OpS # ", $Rn, $Rm." # OpS, 6211259698Sdim [], 6212259698Sdim NoItinerary>; 6213259698Sdim 6214259698Sdim// The vectors in look up table are always 16b 6215259698Sdimmulticlass NI_TBL_pat<bits<2> len, bit op, string asmop, string List> { 6216259698Sdim def _8b : NI_TBL<0, 0b00, len, op, asmop, "8b", VPR64, 6217259698Sdim !cast<RegisterOperand>(List # "16B_operand")>; 6218259698Sdim 6219259698Sdim def _16b : NI_TBL<1, 0b00, len, op, asmop, "16b", VPR128, 6220259698Sdim !cast<RegisterOperand>(List # "16B_operand")>; 6221259698Sdim} 6222259698Sdim 6223259698Sdimdefm TBL1 : NI_TBL_pat<0b00, 0b0, "tbl", "VOne">; 6224259698Sdimdefm TBL2 : NI_TBL_pat<0b01, 0b0, "tbl", "VPair">; 6225259698Sdimdefm TBL3 : NI_TBL_pat<0b10, 0b0, "tbl", "VTriple">; 6226259698Sdimdefm TBL4 : NI_TBL_pat<0b11, 0b0, "tbl", "VQuad">; 6227259698Sdim 6228259698Sdim// Table lookup extention 6229259698Sdimclass NI_TBX<bit q, bits<2> op2, bits<2> len, bit op, 6230259698Sdim string asmop, string OpS, RegisterOperand OpVPR, 6231259698Sdim RegisterOperand VecList> 6232259698Sdim : NeonI_TBL<q, op2, len, op, 6233259698Sdim (outs OpVPR:$Rd), (ins OpVPR:$src, VecList:$Rn, OpVPR:$Rm), 6234259698Sdim asmop # "\t$Rd." # OpS # ", $Rn, $Rm." # OpS, 6235259698Sdim [], 6236259698Sdim NoItinerary> { 6237259698Sdim let Constraints = "$src = $Rd"; 6238259698Sdim} 6239259698Sdim 6240259698Sdim// The vectors in look up table are always 16b 6241259698Sdimmulticlass NI_TBX_pat<bits<2> len, bit op, string asmop, string List> { 6242259698Sdim def _8b : NI_TBX<0, 0b00, len, op, asmop, "8b", VPR64, 6243259698Sdim !cast<RegisterOperand>(List # "16B_operand")>; 6244259698Sdim 6245259698Sdim def _16b : NI_TBX<1, 0b00, len, op, asmop, "16b", VPR128, 6246259698Sdim !cast<RegisterOperand>(List # "16B_operand")>; 6247259698Sdim} 6248259698Sdim 6249259698Sdimdefm TBX1 : NI_TBX_pat<0b00, 0b1, "tbx", "VOne">; 6250259698Sdimdefm TBX2 : NI_TBX_pat<0b01, 0b1, "tbx", "VPair">; 6251259698Sdimdefm TBX3 : NI_TBX_pat<0b10, 0b1, "tbx", "VTriple">; 6252259698Sdimdefm TBX4 : NI_TBX_pat<0b11, 0b1, "tbx", "VQuad">; 6253259698Sdim 6254259698Sdimclass NeonI_INS_main<string asmop, string Res, ValueType ResTy, 6255259698Sdim RegisterClass OpGPR, ValueType OpTy, Operand OpImm> 6256259698Sdim : NeonI_copy<0b1, 0b0, 0b0011, 6257259698Sdim (outs VPR128:$Rd), (ins VPR128:$src, OpGPR:$Rn, OpImm:$Imm), 6258259698Sdim asmop # "\t$Rd." # Res # "[$Imm], $Rn", 6259259698Sdim [(set (ResTy VPR128:$Rd), 6260259698Sdim (ResTy (vector_insert 6261259698Sdim (ResTy VPR128:$src), 6262259698Sdim (OpTy OpGPR:$Rn), 6263259698Sdim (OpImm:$Imm))))], 6264259698Sdim NoItinerary> { 6265259698Sdim bits<4> Imm; 6266259698Sdim let Constraints = "$src = $Rd"; 6267259698Sdim} 6268259698Sdim 6269259698Sdim//Insert element (vector, from main) 6270259698Sdimdef INSbw : NeonI_INS_main<"ins", "b", v16i8, GPR32, i32, 6271259698Sdim neon_uimm4_bare> { 6272259698Sdim let Inst{20-16} = {Imm{3}, Imm{2}, Imm{1}, Imm{0}, 0b1}; 6273259698Sdim} 6274259698Sdimdef INShw : NeonI_INS_main<"ins", "h", v8i16, GPR32, i32, 6275259698Sdim neon_uimm3_bare> { 6276259698Sdim let Inst{20-16} = {Imm{2}, Imm{1}, Imm{0}, 0b1, 0b0}; 6277259698Sdim} 6278259698Sdimdef INSsw : NeonI_INS_main<"ins", "s", v4i32, GPR32, i32, 6279259698Sdim neon_uimm2_bare> { 6280259698Sdim let Inst{20-16} = {Imm{1}, Imm{0}, 0b1, 0b0, 0b0}; 6281259698Sdim} 6282259698Sdimdef INSdx : NeonI_INS_main<"ins", "d", v2i64, GPR64, i64, 6283259698Sdim neon_uimm1_bare> { 6284259698Sdim let Inst{20-16} = {Imm, 0b1, 0b0, 0b0, 0b0}; 6285259698Sdim} 6286259698Sdim 6287259698Sdimdef : NeonInstAlias<"mov $Rd.b[$Imm], $Rn", 6288259698Sdim (INSbw VPR128:$Rd, GPR32:$Rn, neon_uimm4_bare:$Imm), 0>; 6289259698Sdimdef : NeonInstAlias<"mov $Rd.h[$Imm], $Rn", 6290259698Sdim (INShw VPR128:$Rd, GPR32:$Rn, neon_uimm3_bare:$Imm), 0>; 6291259698Sdimdef : NeonInstAlias<"mov $Rd.s[$Imm], $Rn", 6292259698Sdim (INSsw VPR128:$Rd, GPR32:$Rn, neon_uimm2_bare:$Imm), 0>; 6293259698Sdimdef : NeonInstAlias<"mov $Rd.d[$Imm], $Rn", 6294259698Sdim (INSdx VPR128:$Rd, GPR64:$Rn, neon_uimm1_bare:$Imm), 0>; 6295259698Sdim 6296259698Sdimclass Neon_INS_main_pattern <ValueType ResTy,ValueType ExtResTy, 6297259698Sdim RegisterClass OpGPR, ValueType OpTy, 6298259698Sdim Operand OpImm, Instruction INS> 6299259698Sdim : Pat<(ResTy (vector_insert 6300259698Sdim (ResTy VPR64:$src), 6301259698Sdim (OpTy OpGPR:$Rn), 6302259698Sdim (OpImm:$Imm))), 6303259698Sdim (ResTy (EXTRACT_SUBREG 6304259698Sdim (ExtResTy (INS (ExtResTy (SUBREG_TO_REG (i64 0), VPR64:$src, sub_64)), 6305259698Sdim OpGPR:$Rn, OpImm:$Imm)), sub_64))>; 6306259698Sdim 6307259698Sdimdef INSbw_pattern : Neon_INS_main_pattern<v8i8, v16i8, GPR32, i32, 6308259698Sdim neon_uimm3_bare, INSbw>; 6309259698Sdimdef INShw_pattern : Neon_INS_main_pattern<v4i16, v8i16, GPR32, i32, 6310259698Sdim neon_uimm2_bare, INShw>; 6311259698Sdimdef INSsw_pattern : Neon_INS_main_pattern<v2i32, v4i32, GPR32, i32, 6312259698Sdim neon_uimm1_bare, INSsw>; 6313259698Sdimdef INSdx_pattern : Neon_INS_main_pattern<v1i64, v2i64, GPR64, i64, 6314259698Sdim neon_uimm0_bare, INSdx>; 6315259698Sdim 6316259698Sdimclass NeonI_INS_element<string asmop, string Res, Operand ResImm> 6317259698Sdim : NeonI_insert<0b1, 0b1, 6318259698Sdim (outs VPR128:$Rd), (ins VPR128:$src, VPR128:$Rn, 6319259698Sdim ResImm:$Immd, ResImm:$Immn), 6320259698Sdim asmop # "\t$Rd." # Res # "[$Immd], $Rn." # Res # "[$Immn]", 6321259698Sdim [], 6322259698Sdim NoItinerary> { 6323259698Sdim let Constraints = "$src = $Rd"; 6324259698Sdim bits<4> Immd; 6325259698Sdim bits<4> Immn; 6326259698Sdim} 6327259698Sdim 6328259698Sdim//Insert element (vector, from element) 6329259698Sdimdef INSELb : NeonI_INS_element<"ins", "b", neon_uimm4_bare> { 6330259698Sdim let Inst{20-16} = {Immd{3}, Immd{2}, Immd{1}, Immd{0}, 0b1}; 6331259698Sdim let Inst{14-11} = {Immn{3}, Immn{2}, Immn{1}, Immn{0}}; 6332259698Sdim} 6333259698Sdimdef INSELh : NeonI_INS_element<"ins", "h", neon_uimm3_bare> { 6334259698Sdim let Inst{20-16} = {Immd{2}, Immd{1}, Immd{0}, 0b1, 0b0}; 6335259698Sdim let Inst{14-11} = {Immn{2}, Immn{1}, Immn{0}, 0b0}; 6336259698Sdim // bit 11 is unspecified, but should be set to zero. 6337259698Sdim} 6338259698Sdimdef INSELs : NeonI_INS_element<"ins", "s", neon_uimm2_bare> { 6339259698Sdim let Inst{20-16} = {Immd{1}, Immd{0}, 0b1, 0b0, 0b0}; 6340259698Sdim let Inst{14-11} = {Immn{1}, Immn{0}, 0b0, 0b0}; 6341259698Sdim // bits 11-12 are unspecified, but should be set to zero. 6342259698Sdim} 6343259698Sdimdef INSELd : NeonI_INS_element<"ins", "d", neon_uimm1_bare> { 6344259698Sdim let Inst{20-16} = {Immd, 0b1, 0b0, 0b0, 0b0}; 6345259698Sdim let Inst{14-11} = {Immn{0}, 0b0, 0b0, 0b0}; 6346259698Sdim // bits 11-13 are unspecified, but should be set to zero. 6347259698Sdim} 6348259698Sdim 6349259698Sdimdef : NeonInstAlias<"mov $Rd.b[$Immd], $Rn.b[$Immn]", 6350259698Sdim (INSELb VPR128:$Rd, VPR128:$Rn, 6351259698Sdim neon_uimm4_bare:$Immd, neon_uimm4_bare:$Immn), 0>; 6352259698Sdimdef : NeonInstAlias<"mov $Rd.h[$Immd], $Rn.h[$Immn]", 6353259698Sdim (INSELh VPR128:$Rd, VPR128:$Rn, 6354259698Sdim neon_uimm3_bare:$Immd, neon_uimm3_bare:$Immn), 0>; 6355259698Sdimdef : NeonInstAlias<"mov $Rd.s[$Immd], $Rn.s[$Immn]", 6356259698Sdim (INSELs VPR128:$Rd, VPR128:$Rn, 6357259698Sdim neon_uimm2_bare:$Immd, neon_uimm2_bare:$Immn), 0>; 6358259698Sdimdef : NeonInstAlias<"mov $Rd.d[$Immd], $Rn.d[$Immn]", 6359259698Sdim (INSELd VPR128:$Rd, VPR128:$Rn, 6360259698Sdim neon_uimm1_bare:$Immd, neon_uimm1_bare:$Immn), 0>; 6361259698Sdim 6362259698Sdimmulticlass Neon_INS_elt_pattern<ValueType ResTy, ValueType NaTy, 6363259698Sdim ValueType MidTy, Operand StImm, Operand NaImm, 6364259698Sdim Instruction INS> { 6365259698Sdimdef : Pat<(ResTy (vector_insert 6366259698Sdim (ResTy VPR128:$src), 6367259698Sdim (MidTy (vector_extract 6368259698Sdim (ResTy VPR128:$Rn), 6369259698Sdim (StImm:$Immn))), 6370259698Sdim (StImm:$Immd))), 6371259698Sdim (INS (ResTy VPR128:$src), (ResTy VPR128:$Rn), 6372259698Sdim StImm:$Immd, StImm:$Immn)>; 6373259698Sdim 6374259698Sdimdef : Pat <(ResTy (vector_insert 6375259698Sdim (ResTy VPR128:$src), 6376259698Sdim (MidTy (vector_extract 6377259698Sdim (NaTy VPR64:$Rn), 6378259698Sdim (NaImm:$Immn))), 6379259698Sdim (StImm:$Immd))), 6380259698Sdim (INS (ResTy VPR128:$src), 6381259698Sdim (ResTy (SUBREG_TO_REG (i64 0), (NaTy VPR64:$Rn), sub_64)), 6382259698Sdim StImm:$Immd, NaImm:$Immn)>; 6383259698Sdim 6384259698Sdimdef : Pat <(NaTy (vector_insert 6385259698Sdim (NaTy VPR64:$src), 6386259698Sdim (MidTy (vector_extract 6387259698Sdim (ResTy VPR128:$Rn), 6388259698Sdim (StImm:$Immn))), 6389259698Sdim (NaImm:$Immd))), 6390259698Sdim (NaTy (EXTRACT_SUBREG 6391259698Sdim (ResTy (INS 6392259698Sdim (ResTy (SUBREG_TO_REG (i64 0), (NaTy VPR64:$src), sub_64)), 6393259698Sdim (ResTy VPR128:$Rn), 6394259698Sdim NaImm:$Immd, StImm:$Immn)), 6395259698Sdim sub_64))>; 6396259698Sdim 6397259698Sdimdef : Pat <(NaTy (vector_insert 6398259698Sdim (NaTy VPR64:$src), 6399259698Sdim (MidTy (vector_extract 6400259698Sdim (NaTy VPR64:$Rn), 6401259698Sdim (NaImm:$Immn))), 6402259698Sdim (NaImm:$Immd))), 6403259698Sdim (NaTy (EXTRACT_SUBREG 6404259698Sdim (ResTy (INS 6405259698Sdim (ResTy (SUBREG_TO_REG (i64 0), (NaTy VPR64:$src), sub_64)), 6406259698Sdim (ResTy (SUBREG_TO_REG (i64 0), (NaTy VPR64:$Rn), sub_64)), 6407259698Sdim NaImm:$Immd, NaImm:$Immn)), 6408259698Sdim sub_64))>; 6409259698Sdim} 6410259698Sdim 6411259698Sdimdefm : Neon_INS_elt_pattern<v4f32, v2f32, f32, neon_uimm2_bare, 6412259698Sdim neon_uimm1_bare, INSELs>; 6413259698Sdimdefm : Neon_INS_elt_pattern<v2f64, v1f64, f64, neon_uimm1_bare, 6414259698Sdim neon_uimm0_bare, INSELd>; 6415259698Sdimdefm : Neon_INS_elt_pattern<v16i8, v8i8, i32, neon_uimm4_bare, 6416259698Sdim neon_uimm3_bare, INSELb>; 6417259698Sdimdefm : Neon_INS_elt_pattern<v8i16, v4i16, i32, neon_uimm3_bare, 6418259698Sdim neon_uimm2_bare, INSELh>; 6419259698Sdimdefm : Neon_INS_elt_pattern<v4i32, v2i32, i32, neon_uimm2_bare, 6420259698Sdim neon_uimm1_bare, INSELs>; 6421259698Sdimdefm : Neon_INS_elt_pattern<v2i64, v1i64, i64, neon_uimm1_bare, 6422259698Sdim neon_uimm0_bare, INSELd>; 6423259698Sdim 6424259698Sdimmulticlass Neon_INS_elt_float_pattern<ValueType ResTy, ValueType NaTy, 6425259698Sdim ValueType MidTy, 6426259698Sdim RegisterClass OpFPR, Operand ResImm, 6427259698Sdim SubRegIndex SubIndex, Instruction INS> { 6428259698Sdimdef : Pat <(ResTy (vector_insert 6429259698Sdim (ResTy VPR128:$src), 6430259698Sdim (MidTy OpFPR:$Rn), 6431259698Sdim (ResImm:$Imm))), 6432259698Sdim (INS (ResTy VPR128:$src), 6433259698Sdim (ResTy (SUBREG_TO_REG (i64 0), OpFPR:$Rn, SubIndex)), 6434259698Sdim ResImm:$Imm, 6435259698Sdim (i64 0))>; 6436259698Sdim 6437259698Sdimdef : Pat <(NaTy (vector_insert 6438259698Sdim (NaTy VPR64:$src), 6439259698Sdim (MidTy OpFPR:$Rn), 6440259698Sdim (ResImm:$Imm))), 6441259698Sdim (NaTy (EXTRACT_SUBREG 6442259698Sdim (ResTy (INS 6443259698Sdim (ResTy (SUBREG_TO_REG (i64 0), (NaTy VPR64:$src), sub_64)), 6444259698Sdim (ResTy (SUBREG_TO_REG (i64 0), (MidTy OpFPR:$Rn), SubIndex)), 6445259698Sdim ResImm:$Imm, 6446259698Sdim (i64 0))), 6447259698Sdim sub_64))>; 6448259698Sdim} 6449259698Sdim 6450259698Sdimdefm : Neon_INS_elt_float_pattern<v4f32, v2f32, f32, FPR32, neon_uimm2_bare, 6451259698Sdim sub_32, INSELs>; 6452259698Sdimdefm : Neon_INS_elt_float_pattern<v2f64, v1f64, f64, FPR64, neon_uimm1_bare, 6453259698Sdim sub_64, INSELd>; 6454259698Sdim 6455259698Sdimclass NeonI_SMOV<string asmop, string Res, bit Q, 6456259698Sdim ValueType OpTy, ValueType eleTy, 6457259698Sdim Operand OpImm, RegisterClass ResGPR, ValueType ResTy> 6458259698Sdim : NeonI_copy<Q, 0b0, 0b0101, 6459259698Sdim (outs ResGPR:$Rd), (ins VPR128:$Rn, OpImm:$Imm), 6460259698Sdim asmop # "\t$Rd, $Rn." # Res # "[$Imm]", 6461259698Sdim [(set (ResTy ResGPR:$Rd), 6462259698Sdim (ResTy (sext_inreg 6463259698Sdim (ResTy (vector_extract 6464259698Sdim (OpTy VPR128:$Rn), (OpImm:$Imm))), 6465259698Sdim eleTy)))], 6466259698Sdim NoItinerary> { 6467259698Sdim bits<4> Imm; 6468259698Sdim} 6469259698Sdim 6470259698Sdim//Signed integer move (main, from element) 6471259698Sdimdef SMOVwb : NeonI_SMOV<"smov", "b", 0b0, v16i8, i8, neon_uimm4_bare, 6472259698Sdim GPR32, i32> { 6473259698Sdim let Inst{20-16} = {Imm{3}, Imm{2}, Imm{1}, Imm{0}, 0b1}; 6474259698Sdim} 6475259698Sdimdef SMOVwh : NeonI_SMOV<"smov", "h", 0b0, v8i16, i16, neon_uimm3_bare, 6476259698Sdim GPR32, i32> { 6477259698Sdim let Inst{20-16} = {Imm{2}, Imm{1}, Imm{0}, 0b1, 0b0}; 6478259698Sdim} 6479259698Sdimdef SMOVxb : NeonI_SMOV<"smov", "b", 0b1, v16i8, i8, neon_uimm4_bare, 6480259698Sdim GPR64, i64> { 6481259698Sdim let Inst{20-16} = {Imm{3}, Imm{2}, Imm{1}, Imm{0}, 0b1}; 6482259698Sdim} 6483259698Sdimdef SMOVxh : NeonI_SMOV<"smov", "h", 0b1, v8i16, i16, neon_uimm3_bare, 6484259698Sdim GPR64, i64> { 6485259698Sdim let Inst{20-16} = {Imm{2}, Imm{1}, Imm{0}, 0b1, 0b0}; 6486259698Sdim} 6487259698Sdimdef SMOVxs : NeonI_SMOV<"smov", "s", 0b1, v4i32, i32, neon_uimm2_bare, 6488259698Sdim GPR64, i64> { 6489259698Sdim let Inst{20-16} = {Imm{1}, Imm{0}, 0b1, 0b0, 0b0}; 6490259698Sdim} 6491259698Sdim 6492259698Sdimmulticlass Neon_SMOVx_pattern <ValueType StTy, ValueType NaTy, 6493259698Sdim ValueType eleTy, Operand StImm, Operand NaImm, 6494259698Sdim Instruction SMOVI> { 6495259698Sdim def : Pat<(i64 (sext_inreg 6496259698Sdim (i64 (anyext 6497259698Sdim (i32 (vector_extract 6498259698Sdim (StTy VPR128:$Rn), (StImm:$Imm))))), 6499259698Sdim eleTy)), 6500259698Sdim (SMOVI VPR128:$Rn, StImm:$Imm)>; 6501259698Sdim 6502259698Sdim def : Pat<(i64 (sext 6503259698Sdim (i32 (vector_extract 6504259698Sdim (StTy VPR128:$Rn), (StImm:$Imm))))), 6505259698Sdim (SMOVI VPR128:$Rn, StImm:$Imm)>; 6506259698Sdim 6507259698Sdim def : Pat<(i64 (sext_inreg 6508259698Sdim (i64 (vector_extract 6509259698Sdim (NaTy VPR64:$Rn), (NaImm:$Imm))), 6510259698Sdim eleTy)), 6511259698Sdim (SMOVI (StTy (SUBREG_TO_REG (i64 0), VPR64:$Rn, sub_64)), 6512259698Sdim NaImm:$Imm)>; 6513259698Sdim 6514259698Sdim def : Pat<(i64 (sext_inreg 6515259698Sdim (i64 (anyext 6516259698Sdim (i32 (vector_extract 6517259698Sdim (NaTy VPR64:$Rn), (NaImm:$Imm))))), 6518259698Sdim eleTy)), 6519259698Sdim (SMOVI (StTy (SUBREG_TO_REG (i64 0), VPR64:$Rn, sub_64)), 6520259698Sdim NaImm:$Imm)>; 6521259698Sdim 6522259698Sdim def : Pat<(i64 (sext 6523259698Sdim (i32 (vector_extract 6524259698Sdim (NaTy VPR64:$Rn), (NaImm:$Imm))))), 6525259698Sdim (SMOVI (StTy (SUBREG_TO_REG (i64 0), VPR64:$Rn, sub_64)), 6526259698Sdim NaImm:$Imm)>; 6527259698Sdim} 6528259698Sdim 6529259698Sdimdefm : Neon_SMOVx_pattern<v16i8, v8i8, i8, neon_uimm4_bare, 6530259698Sdim neon_uimm3_bare, SMOVxb>; 6531259698Sdimdefm : Neon_SMOVx_pattern<v8i16, v4i16, i16, neon_uimm3_bare, 6532259698Sdim neon_uimm2_bare, SMOVxh>; 6533259698Sdimdefm : Neon_SMOVx_pattern<v4i32, v2i32, i32, neon_uimm2_bare, 6534259698Sdim neon_uimm1_bare, SMOVxs>; 6535259698Sdim 6536259698Sdimclass Neon_SMOVw_pattern <ValueType StTy, ValueType NaTy, 6537259698Sdim ValueType eleTy, Operand StImm, Operand NaImm, 6538259698Sdim Instruction SMOVI> 6539259698Sdim : Pat<(i32 (sext_inreg 6540259698Sdim (i32 (vector_extract 6541259698Sdim (NaTy VPR64:$Rn), (NaImm:$Imm))), 6542259698Sdim eleTy)), 6543259698Sdim (SMOVI (StTy (SUBREG_TO_REG (i64 0), VPR64:$Rn, sub_64)), 6544259698Sdim NaImm:$Imm)>; 6545259698Sdim 6546259698Sdimdef : Neon_SMOVw_pattern<v16i8, v8i8, i8, neon_uimm4_bare, 6547259698Sdim neon_uimm3_bare, SMOVwb>; 6548259698Sdimdef : Neon_SMOVw_pattern<v8i16, v4i16, i16, neon_uimm3_bare, 6549259698Sdim neon_uimm2_bare, SMOVwh>; 6550259698Sdim 6551259698Sdimclass NeonI_UMOV<string asmop, string Res, bit Q, 6552259698Sdim ValueType OpTy, Operand OpImm, 6553259698Sdim RegisterClass ResGPR, ValueType ResTy> 6554259698Sdim : NeonI_copy<Q, 0b0, 0b0111, 6555259698Sdim (outs ResGPR:$Rd), (ins VPR128:$Rn, OpImm:$Imm), 6556259698Sdim asmop # "\t$Rd, $Rn." # Res # "[$Imm]", 6557259698Sdim [(set (ResTy ResGPR:$Rd), 6558259698Sdim (ResTy (vector_extract 6559259698Sdim (OpTy VPR128:$Rn), (OpImm:$Imm))))], 6560259698Sdim NoItinerary> { 6561259698Sdim bits<4> Imm; 6562259698Sdim} 6563259698Sdim 6564259698Sdim//Unsigned integer move (main, from element) 6565259698Sdimdef UMOVwb : NeonI_UMOV<"umov", "b", 0b0, v16i8, neon_uimm4_bare, 6566259698Sdim GPR32, i32> { 6567259698Sdim let Inst{20-16} = {Imm{3}, Imm{2}, Imm{1}, Imm{0}, 0b1}; 6568259698Sdim} 6569259698Sdimdef UMOVwh : NeonI_UMOV<"umov", "h", 0b0, v8i16, neon_uimm3_bare, 6570259698Sdim GPR32, i32> { 6571259698Sdim let Inst{20-16} = {Imm{2}, Imm{1}, Imm{0}, 0b1, 0b0}; 6572259698Sdim} 6573259698Sdimdef UMOVws : NeonI_UMOV<"umov", "s", 0b0, v4i32, neon_uimm2_bare, 6574259698Sdim GPR32, i32> { 6575259698Sdim let Inst{20-16} = {Imm{1}, Imm{0}, 0b1, 0b0, 0b0}; 6576259698Sdim} 6577259698Sdimdef UMOVxd : NeonI_UMOV<"umov", "d", 0b1, v2i64, neon_uimm1_bare, 6578259698Sdim GPR64, i64> { 6579259698Sdim let Inst{20-16} = {Imm, 0b1, 0b0, 0b0, 0b0}; 6580259698Sdim} 6581259698Sdim 6582259698Sdimdef : NeonInstAlias<"mov $Rd, $Rn.s[$Imm]", 6583259698Sdim (UMOVws GPR32:$Rd, VPR128:$Rn, neon_uimm2_bare:$Imm), 0>; 6584259698Sdimdef : NeonInstAlias<"mov $Rd, $Rn.d[$Imm]", 6585259698Sdim (UMOVxd GPR64:$Rd, VPR128:$Rn, neon_uimm1_bare:$Imm), 0>; 6586259698Sdim 6587259698Sdimclass Neon_UMOV_pattern <ValueType StTy, ValueType NaTy, ValueType ResTy, 6588259698Sdim Operand StImm, Operand NaImm, 6589259698Sdim Instruction SMOVI> 6590259698Sdim : Pat<(ResTy (vector_extract 6591259698Sdim (NaTy VPR64:$Rn), NaImm:$Imm)), 6592259698Sdim (SMOVI (StTy (SUBREG_TO_REG (i64 0), VPR64:$Rn, sub_64)), 6593259698Sdim NaImm:$Imm)>; 6594259698Sdim 6595259698Sdimdef : Neon_UMOV_pattern<v16i8, v8i8, i32, neon_uimm4_bare, 6596259698Sdim neon_uimm3_bare, UMOVwb>; 6597259698Sdimdef : Neon_UMOV_pattern<v8i16, v4i16, i32, neon_uimm3_bare, 6598259698Sdim neon_uimm2_bare, UMOVwh>; 6599259698Sdimdef : Neon_UMOV_pattern<v4i32, v2i32, i32, neon_uimm2_bare, 6600259698Sdim neon_uimm1_bare, UMOVws>; 6601259698Sdim 6602259698Sdimdef : Pat<(i32 (and 6603259698Sdim (i32 (vector_extract 6604259698Sdim (v16i8 VPR128:$Rn), (neon_uimm4_bare:$Imm))), 6605259698Sdim 255)), 6606259698Sdim (UMOVwb VPR128:$Rn, neon_uimm4_bare:$Imm)>; 6607259698Sdim 6608259698Sdimdef : Pat<(i32 (and 6609259698Sdim (i32 (vector_extract 6610259698Sdim (v8i16 VPR128:$Rn), (neon_uimm3_bare:$Imm))), 6611259698Sdim 65535)), 6612259698Sdim (UMOVwh VPR128:$Rn, neon_uimm3_bare:$Imm)>; 6613259698Sdim 6614259698Sdimdef : Pat<(i64 (zext 6615259698Sdim (i32 (vector_extract 6616259698Sdim (v2i64 VPR128:$Rn), (neon_uimm1_bare:$Imm))))), 6617259698Sdim (UMOVxd VPR128:$Rn, neon_uimm1_bare:$Imm)>; 6618259698Sdim 6619259698Sdimdef : Pat<(i32 (and 6620259698Sdim (i32 (vector_extract 6621259698Sdim (v8i8 VPR64:$Rn), (neon_uimm3_bare:$Imm))), 6622259698Sdim 255)), 6623259698Sdim (UMOVwb (SUBREG_TO_REG (i64 0), VPR64:$Rn, sub_64), 6624259698Sdim neon_uimm3_bare:$Imm)>; 6625259698Sdim 6626259698Sdimdef : Pat<(i32 (and 6627259698Sdim (i32 (vector_extract 6628259698Sdim (v4i16 VPR64:$Rn), (neon_uimm2_bare:$Imm))), 6629259698Sdim 65535)), 6630259698Sdim (UMOVwh (SUBREG_TO_REG (i64 0), VPR64:$Rn, sub_64), 6631259698Sdim neon_uimm2_bare:$Imm)>; 6632259698Sdim 6633259698Sdimdef : Pat<(i64 (zext 6634259698Sdim (i32 (vector_extract 6635259698Sdim (v1i64 VPR64:$Rn), (neon_uimm0_bare:$Imm))))), 6636259698Sdim (UMOVxd (SUBREG_TO_REG (i64 0), VPR64:$Rn, sub_64), 6637259698Sdim neon_uimm0_bare:$Imm)>; 6638259698Sdim 6639259698Sdim// Additional copy patterns for scalar types 6640259698Sdimdef : Pat<(i32 (vector_extract (v1i8 FPR8:$Rn), (i64 0))), 6641259698Sdim (UMOVwb (v16i8 6642259698Sdim (SUBREG_TO_REG (i64 0), FPR8:$Rn, sub_8)), (i64 0))>; 6643259698Sdim 6644259698Sdimdef : Pat<(i32 (vector_extract (v1i16 FPR16:$Rn), (i64 0))), 6645259698Sdim (UMOVwh (v8i16 6646259698Sdim (SUBREG_TO_REG (i64 0), FPR16:$Rn, sub_16)), (i64 0))>; 6647259698Sdim 6648259698Sdimdef : Pat<(i32 (vector_extract (v1i32 FPR32:$Rn), (i64 0))), 6649259698Sdim (FMOVws FPR32:$Rn)>; 6650259698Sdim 6651259698Sdimdef : Pat<(i64 (vector_extract (v1i64 FPR64:$Rn), (i64 0))), 6652259698Sdim (FMOVxd FPR64:$Rn)>; 6653259698Sdim 6654259698Sdimdef : Pat<(f64 (vector_extract (v1f64 FPR64:$Rn), (i64 0))), 6655259698Sdim (f64 FPR64:$Rn)>; 6656259698Sdim 6657259698Sdimdef : Pat<(f32 (vector_extract (v1f32 FPR32:$Rn), (i64 0))), 6658259698Sdim (f32 FPR32:$Rn)>; 6659259698Sdim 6660259698Sdimdef : Pat<(v1i8 (scalar_to_vector GPR32:$Rn)), 6661259698Sdim (v1i8 (EXTRACT_SUBREG (v16i8 6662259698Sdim (INSbw (v16i8 (IMPLICIT_DEF)), $Rn, (i64 0))), 6663259698Sdim sub_8))>; 6664259698Sdim 6665259698Sdimdef : Pat<(v1i16 (scalar_to_vector GPR32:$Rn)), 6666259698Sdim (v1i16 (EXTRACT_SUBREG (v8i16 6667259698Sdim (INShw (v8i16 (IMPLICIT_DEF)), $Rn, (i64 0))), 6668259698Sdim sub_16))>; 6669259698Sdim 6670259698Sdimdef : Pat<(v1i32 (scalar_to_vector GPR32:$src)), 6671259698Sdim (FMOVsw $src)>; 6672259698Sdim 6673259698Sdimdef : Pat<(v1i64 (scalar_to_vector GPR64:$src)), 6674259698Sdim (FMOVdx $src)>; 6675259698Sdim 6676259698Sdimdef : Pat<(v1f32 (scalar_to_vector (f32 FPR32:$Rn))), 6677259698Sdim (v1f32 FPR32:$Rn)>; 6678259698Sdimdef : Pat<(v1f64 (scalar_to_vector (f64 FPR64:$Rn))), 6679259698Sdim (v1f64 FPR64:$Rn)>; 6680259698Sdim 6681259698Sdimdef : Pat<(v1f64 (scalar_to_vector (f64 FPR64:$src))), 6682259698Sdim (FMOVdd $src)>; 6683259698Sdim 6684259698Sdimdef : Pat<(v2f64 (scalar_to_vector (f64 FPR64:$src))), 6685259698Sdim (INSERT_SUBREG (v2f64 (IMPLICIT_DEF)), 6686259698Sdim (f64 FPR64:$src), sub_64)>; 6687259698Sdim 6688259698Sdimclass NeonI_DUP_Elt<bit Q, string asmop, string rdlane, string rnlane, 6689259698Sdim RegisterOperand ResVPR, Operand OpImm> 6690259698Sdim : NeonI_copy<Q, 0b0, 0b0000, (outs ResVPR:$Rd), 6691259698Sdim (ins VPR128:$Rn, OpImm:$Imm), 6692259698Sdim asmop # "\t$Rd" # rdlane # ", $Rn" # rnlane # "[$Imm]", 6693259698Sdim [], 6694259698Sdim NoItinerary> { 6695259698Sdim bits<4> Imm; 6696259698Sdim} 6697259698Sdim 6698259698Sdimdef DUPELT16b : NeonI_DUP_Elt<0b1, "dup", ".16b", ".b", VPR128, 6699259698Sdim neon_uimm4_bare> { 6700259698Sdim let Inst{20-16} = {Imm{3}, Imm{2}, Imm{1}, Imm{0}, 0b1}; 6701259698Sdim} 6702259698Sdim 6703259698Sdimdef DUPELT8h : NeonI_DUP_Elt<0b1, "dup", ".8h", ".h", VPR128, 6704259698Sdim neon_uimm3_bare> { 6705259698Sdim let Inst{20-16} = {Imm{2}, Imm{1}, Imm{0}, 0b1, 0b0}; 6706259698Sdim} 6707259698Sdim 6708259698Sdimdef DUPELT4s : NeonI_DUP_Elt<0b1, "dup", ".4s", ".s", VPR128, 6709259698Sdim neon_uimm2_bare> { 6710259698Sdim let Inst{20-16} = {Imm{1}, Imm{0}, 0b1, 0b0, 0b0}; 6711259698Sdim} 6712259698Sdim 6713259698Sdimdef DUPELT2d : NeonI_DUP_Elt<0b1, "dup", ".2d", ".d", VPR128, 6714259698Sdim neon_uimm1_bare> { 6715259698Sdim let Inst{20-16} = {Imm, 0b1, 0b0, 0b0, 0b0}; 6716259698Sdim} 6717259698Sdim 6718259698Sdimdef DUPELT8b : NeonI_DUP_Elt<0b0, "dup", ".8b", ".b", VPR64, 6719259698Sdim neon_uimm4_bare> { 6720259698Sdim let Inst{20-16} = {Imm{3}, Imm{2}, Imm{1}, Imm{0}, 0b1}; 6721259698Sdim} 6722259698Sdim 6723259698Sdimdef DUPELT4h : NeonI_DUP_Elt<0b0, "dup", ".4h", ".h", VPR64, 6724259698Sdim neon_uimm3_bare> { 6725259698Sdim let Inst{20-16} = {Imm{2}, Imm{1}, Imm{0}, 0b1, 0b0}; 6726259698Sdim} 6727259698Sdim 6728259698Sdimdef DUPELT2s : NeonI_DUP_Elt<0b0, "dup", ".2s", ".s", VPR64, 6729259698Sdim neon_uimm2_bare> { 6730259698Sdim let Inst{20-16} = {Imm{1}, Imm{0}, 0b1, 0b0, 0b0}; 6731259698Sdim} 6732259698Sdim 6733259698Sdimmulticlass NeonI_DUP_Elt_pattern<Instruction DUPELT, ValueType ResTy, 6734259698Sdim ValueType OpTy,ValueType NaTy, 6735259698Sdim ValueType ExTy, Operand OpLImm, 6736259698Sdim Operand OpNImm> { 6737259698Sdimdef : Pat<(ResTy (Neon_vduplane (OpTy VPR128:$Rn), OpLImm:$Imm)), 6738259698Sdim (ResTy (DUPELT (OpTy VPR128:$Rn), OpLImm:$Imm))>; 6739259698Sdim 6740259698Sdimdef : Pat<(ResTy (Neon_vduplane 6741259698Sdim (NaTy VPR64:$Rn), OpNImm:$Imm)), 6742259698Sdim (ResTy (DUPELT 6743259698Sdim (ExTy (SUBREG_TO_REG (i64 0), VPR64:$Rn, sub_64)), OpNImm:$Imm))>; 6744259698Sdim} 6745259698Sdimdefm : NeonI_DUP_Elt_pattern<DUPELT16b, v16i8, v16i8, v8i8, v16i8, 6746259698Sdim neon_uimm4_bare, neon_uimm3_bare>; 6747259698Sdimdefm : NeonI_DUP_Elt_pattern<DUPELT8b, v8i8, v16i8, v8i8, v16i8, 6748259698Sdim neon_uimm4_bare, neon_uimm3_bare>; 6749259698Sdimdefm : NeonI_DUP_Elt_pattern<DUPELT8h, v8i16, v8i16, v4i16, v8i16, 6750259698Sdim neon_uimm3_bare, neon_uimm2_bare>; 6751259698Sdimdefm : NeonI_DUP_Elt_pattern<DUPELT4h, v4i16, v8i16, v4i16, v8i16, 6752259698Sdim neon_uimm3_bare, neon_uimm2_bare>; 6753259698Sdimdefm : NeonI_DUP_Elt_pattern<DUPELT4s, v4i32, v4i32, v2i32, v4i32, 6754259698Sdim neon_uimm2_bare, neon_uimm1_bare>; 6755259698Sdimdefm : NeonI_DUP_Elt_pattern<DUPELT2s, v2i32, v4i32, v2i32, v4i32, 6756259698Sdim neon_uimm2_bare, neon_uimm1_bare>; 6757259698Sdimdefm : NeonI_DUP_Elt_pattern<DUPELT2d, v2i64, v2i64, v1i64, v2i64, 6758259698Sdim neon_uimm1_bare, neon_uimm0_bare>; 6759259698Sdimdefm : NeonI_DUP_Elt_pattern<DUPELT4s, v4f32, v4f32, v2f32, v4f32, 6760259698Sdim neon_uimm2_bare, neon_uimm1_bare>; 6761259698Sdimdefm : NeonI_DUP_Elt_pattern<DUPELT2s, v2f32, v4f32, v2f32, v4f32, 6762259698Sdim neon_uimm2_bare, neon_uimm1_bare>; 6763259698Sdimdefm : NeonI_DUP_Elt_pattern<DUPELT2d, v2f64, v2f64, v1f64, v2f64, 6764259698Sdim neon_uimm1_bare, neon_uimm0_bare>; 6765259698Sdim 6766259698Sdimdef : Pat<(v2f32 (Neon_vdup (f32 FPR32:$Rn))), 6767259698Sdim (v2f32 (DUPELT2s 6768259698Sdim (SUBREG_TO_REG (i64 0), FPR32:$Rn, sub_32), 6769259698Sdim (i64 0)))>; 6770259698Sdimdef : Pat<(v4f32 (Neon_vdup (f32 FPR32:$Rn))), 6771259698Sdim (v4f32 (DUPELT4s 6772259698Sdim (SUBREG_TO_REG (i64 0), FPR32:$Rn, sub_32), 6773259698Sdim (i64 0)))>; 6774259698Sdimdef : Pat<(v2f64 (Neon_vdup (f64 FPR64:$Rn))), 6775259698Sdim (v2f64 (DUPELT2d 6776259698Sdim (SUBREG_TO_REG (i64 0), FPR64:$Rn, sub_64), 6777259698Sdim (i64 0)))>; 6778259698Sdim 6779259698Sdimclass NeonI_DUP<bit Q, string asmop, string rdlane, 6780259698Sdim RegisterOperand ResVPR, ValueType ResTy, 6781259698Sdim RegisterClass OpGPR, ValueType OpTy> 6782259698Sdim : NeonI_copy<Q, 0b0, 0b0001, (outs ResVPR:$Rd), (ins OpGPR:$Rn), 6783259698Sdim asmop # "\t$Rd" # rdlane # ", $Rn", 6784259698Sdim [(set (ResTy ResVPR:$Rd), 6785259698Sdim (ResTy (Neon_vdup (OpTy OpGPR:$Rn))))], 6786259698Sdim NoItinerary>; 6787259698Sdim 6788259698Sdimdef DUP16b : NeonI_DUP<0b1, "dup", ".16b", VPR128, v16i8, GPR32, i32> { 6789259698Sdim let Inst{20-16} = 0b00001; 6790259698Sdim // bits 17-20 are unspecified, but should be set to zero. 6791259698Sdim} 6792259698Sdim 6793259698Sdimdef DUP8h : NeonI_DUP<0b1, "dup", ".8h", VPR128, v8i16, GPR32, i32> { 6794259698Sdim let Inst{20-16} = 0b00010; 6795259698Sdim // bits 18-20 are unspecified, but should be set to zero. 6796259698Sdim} 6797259698Sdim 6798259698Sdimdef DUP4s : NeonI_DUP<0b1, "dup", ".4s", VPR128, v4i32, GPR32, i32> { 6799259698Sdim let Inst{20-16} = 0b00100; 6800259698Sdim // bits 19-20 are unspecified, but should be set to zero. 6801259698Sdim} 6802259698Sdim 6803259698Sdimdef DUP2d : NeonI_DUP<0b1, "dup", ".2d", VPR128, v2i64, GPR64, i64> { 6804259698Sdim let Inst{20-16} = 0b01000; 6805259698Sdim // bit 20 is unspecified, but should be set to zero. 6806259698Sdim} 6807259698Sdim 6808259698Sdimdef DUP8b : NeonI_DUP<0b0, "dup", ".8b", VPR64, v8i8, GPR32, i32> { 6809259698Sdim let Inst{20-16} = 0b00001; 6810259698Sdim // bits 17-20 are unspecified, but should be set to zero. 6811259698Sdim} 6812259698Sdim 6813259698Sdimdef DUP4h : NeonI_DUP<0b0, "dup", ".4h", VPR64, v4i16, GPR32, i32> { 6814259698Sdim let Inst{20-16} = 0b00010; 6815259698Sdim // bits 18-20 are unspecified, but should be set to zero. 6816259698Sdim} 6817259698Sdim 6818259698Sdimdef DUP2s : NeonI_DUP<0b0, "dup", ".2s", VPR64, v2i32, GPR32, i32> { 6819259698Sdim let Inst{20-16} = 0b00100; 6820259698Sdim // bits 19-20 are unspecified, but should be set to zero. 6821259698Sdim} 6822259698Sdim 6823259698Sdim// patterns for CONCAT_VECTORS 6824259698Sdimmulticlass Concat_Vector_Pattern<ValueType ResTy, ValueType OpTy> { 6825259698Sdimdef : Pat<(ResTy (concat_vectors (OpTy VPR64:$Rn), undef)), 6826259698Sdim (SUBREG_TO_REG (i64 0), VPR64:$Rn, sub_64)>; 6827259698Sdimdef : Pat<(ResTy (concat_vectors (OpTy VPR64:$Rn), (OpTy VPR64:$Rm))), 6828259698Sdim (INSELd 6829259698Sdim (v2i64 (SUBREG_TO_REG (i64 0), VPR64:$Rn, sub_64)), 6830259698Sdim (v2i64 (SUBREG_TO_REG (i64 0), VPR64:$Rm, sub_64)), 6831259698Sdim (i64 1), 6832259698Sdim (i64 0))>; 6833259698Sdimdef : Pat<(ResTy (concat_vectors (OpTy VPR64:$Rn), (OpTy VPR64:$Rn))), 6834259698Sdim (DUPELT2d 6835259698Sdim (v2i64 (SUBREG_TO_REG (i64 0), VPR64:$Rn, sub_64)), 6836259698Sdim (i64 0))> ; 6837259698Sdim} 6838259698Sdim 6839259698Sdimdefm : Concat_Vector_Pattern<v16i8, v8i8>; 6840259698Sdimdefm : Concat_Vector_Pattern<v8i16, v4i16>; 6841259698Sdimdefm : Concat_Vector_Pattern<v4i32, v2i32>; 6842259698Sdimdefm : Concat_Vector_Pattern<v2i64, v1i64>; 6843259698Sdimdefm : Concat_Vector_Pattern<v4f32, v2f32>; 6844259698Sdimdefm : Concat_Vector_Pattern<v2f64, v1f64>; 6845259698Sdim 6846259698Sdim//patterns for EXTRACT_SUBVECTOR 6847259698Sdimdef : Pat<(v8i8 (extract_subvector (v16i8 VPR128:$Rn), (i64 0))), 6848259698Sdim (v8i8 (EXTRACT_SUBREG VPR128:$Rn, sub_64))>; 6849259698Sdimdef : Pat<(v4i16 (extract_subvector (v8i16 VPR128:$Rn), (i64 0))), 6850259698Sdim (v4i16 (EXTRACT_SUBREG VPR128:$Rn, sub_64))>; 6851259698Sdimdef : Pat<(v2i32 (extract_subvector (v4i32 VPR128:$Rn), (i64 0))), 6852259698Sdim (v2i32 (EXTRACT_SUBREG VPR128:$Rn, sub_64))>; 6853259698Sdimdef : Pat<(v1i64 (extract_subvector (v2i64 VPR128:$Rn), (i64 0))), 6854259698Sdim (v1i64 (EXTRACT_SUBREG VPR128:$Rn, sub_64))>; 6855259698Sdimdef : Pat<(v2f32 (extract_subvector (v4f32 VPR128:$Rn), (i64 0))), 6856259698Sdim (v2f32 (EXTRACT_SUBREG VPR128:$Rn, sub_64))>; 6857259698Sdimdef : Pat<(v1f64 (extract_subvector (v2f64 VPR128:$Rn), (i64 0))), 6858259698Sdim (v1f64 (EXTRACT_SUBREG VPR128:$Rn, sub_64))>; 6859259698Sdim 6860259698Sdim// The followings are for instruction class (3V Elem) 6861259698Sdim 6862259698Sdim// Variant 1 6863259698Sdim 6864259698Sdimclass NI_2VE<bit q, bit u, bits<2> size, bits<4> opcode, 6865259698Sdim string asmop, string ResS, string OpS, string EleOpS, 6866259698Sdim Operand OpImm, RegisterOperand ResVPR, 6867259698Sdim RegisterOperand OpVPR, RegisterOperand EleOpVPR> 6868259698Sdim : NeonI_2VElem<q, u, size, opcode, 6869259698Sdim (outs ResVPR:$Rd), (ins ResVPR:$src, OpVPR:$Rn, 6870259698Sdim EleOpVPR:$Re, OpImm:$Index), 6871259698Sdim asmop # "\t$Rd." # ResS # ", $Rn." # OpS # 6872259698Sdim ", $Re." # EleOpS # "[$Index]", 6873259698Sdim [], 6874259698Sdim NoItinerary> { 6875259698Sdim bits<3> Index; 6876259698Sdim bits<5> Re; 6877259698Sdim 6878259698Sdim let Constraints = "$src = $Rd"; 6879259698Sdim} 6880259698Sdim 6881259698Sdimmulticlass NI_2VE_v1<bit u, bits<4> opcode, string asmop> { 6882259698Sdim // vector register class for element is always 128-bit to cover the max index 6883259698Sdim def _2s4s : NI_2VE<0b0, u, 0b10, opcode, asmop, "2s", "2s", "s", 6884259698Sdim neon_uimm2_bare, VPR64, VPR64, VPR128> { 6885259698Sdim let Inst{11} = {Index{1}}; 6886259698Sdim let Inst{21} = {Index{0}}; 6887259698Sdim let Inst{20-16} = Re; 6888259698Sdim } 6889259698Sdim 6890259698Sdim def _4s4s : NI_2VE<0b1, u, 0b10, opcode, asmop, "4s", "4s", "s", 6891259698Sdim neon_uimm2_bare, VPR128, VPR128, VPR128> { 6892259698Sdim let Inst{11} = {Index{1}}; 6893259698Sdim let Inst{21} = {Index{0}}; 6894259698Sdim let Inst{20-16} = Re; 6895259698Sdim } 6896259698Sdim 6897259698Sdim // Index operations on 16-bit(H) elements are restricted to using v0-v15. 6898259698Sdim def _4h8h : NI_2VE<0b0, u, 0b01, opcode, asmop, "4h", "4h", "h", 6899259698Sdim neon_uimm3_bare, VPR64, VPR64, VPR128Lo> { 6900259698Sdim let Inst{11} = {Index{2}}; 6901259698Sdim let Inst{21} = {Index{1}}; 6902259698Sdim let Inst{20} = {Index{0}}; 6903259698Sdim let Inst{19-16} = Re{3-0}; 6904259698Sdim } 6905259698Sdim 6906259698Sdim def _8h8h : NI_2VE<0b1, u, 0b01, opcode, asmop, "8h", "8h", "h", 6907259698Sdim neon_uimm3_bare, VPR128, VPR128, VPR128Lo> { 6908259698Sdim let Inst{11} = {Index{2}}; 6909259698Sdim let Inst{21} = {Index{1}}; 6910259698Sdim let Inst{20} = {Index{0}}; 6911259698Sdim let Inst{19-16} = Re{3-0}; 6912259698Sdim } 6913259698Sdim} 6914259698Sdim 6915259698Sdimdefm MLAvve : NI_2VE_v1<0b1, 0b0000, "mla">; 6916259698Sdimdefm MLSvve : NI_2VE_v1<0b1, 0b0100, "mls">; 6917259698Sdim 6918259698Sdim// Pattern for lane in 128-bit vector 6919259698Sdimclass NI_2VE_laneq<Instruction INST, Operand OpImm, SDPatternOperator op, 6920259698Sdim RegisterOperand ResVPR, RegisterOperand OpVPR, 6921259698Sdim RegisterOperand EleOpVPR, ValueType ResTy, ValueType OpTy, 6922259698Sdim ValueType EleOpTy> 6923259698Sdim : Pat<(ResTy (op (ResTy ResVPR:$src), (OpTy OpVPR:$Rn), 6924259698Sdim (OpTy (Neon_vduplane (EleOpTy EleOpVPR:$Re), (i64 OpImm:$Index))))), 6925259698Sdim (INST ResVPR:$src, OpVPR:$Rn, EleOpVPR:$Re, OpImm:$Index)>; 6926259698Sdim 6927259698Sdim// Pattern for lane in 64-bit vector 6928259698Sdimclass NI_2VE_lane<Instruction INST, Operand OpImm, SDPatternOperator op, 6929259698Sdim RegisterOperand ResVPR, RegisterOperand OpVPR, 6930259698Sdim RegisterOperand EleOpVPR, ValueType ResTy, ValueType OpTy, 6931259698Sdim ValueType EleOpTy> 6932259698Sdim : Pat<(ResTy (op (ResTy ResVPR:$src), (OpTy OpVPR:$Rn), 6933259698Sdim (OpTy (Neon_vduplane (EleOpTy EleOpVPR:$Re), (i64 OpImm:$Index))))), 6934259698Sdim (INST ResVPR:$src, OpVPR:$Rn, 6935259698Sdim (SUBREG_TO_REG (i64 0), EleOpVPR:$Re, sub_64), OpImm:$Index)>; 6936259698Sdim 6937259698Sdimmulticlass NI_2VE_v1_pat<string subop, SDPatternOperator op> 6938259698Sdim{ 6939259698Sdim def : NI_2VE_laneq<!cast<Instruction>(subop # "_2s4s"), neon_uimm2_bare, 6940259698Sdim op, VPR64, VPR64, VPR128, v2i32, v2i32, v4i32>; 6941259698Sdim 6942259698Sdim def : NI_2VE_laneq<!cast<Instruction>(subop # "_4s4s"), neon_uimm2_bare, 6943259698Sdim op, VPR128, VPR128, VPR128, v4i32, v4i32, v4i32>; 6944259698Sdim 6945259698Sdim def : NI_2VE_laneq<!cast<Instruction>(subop # "_4h8h"), neon_uimm3_bare, 6946259698Sdim op, VPR64, VPR64, VPR128Lo, v4i16, v4i16, v8i16>; 6947259698Sdim 6948259698Sdim def : NI_2VE_laneq<!cast<Instruction>(subop # "_8h8h"), neon_uimm3_bare, 6949259698Sdim op, VPR128, VPR128, VPR128Lo, v8i16, v8i16, v8i16>; 6950259698Sdim 6951259698Sdim // Index can only be half of the max value for lane in 64-bit vector 6952259698Sdim 6953259698Sdim def : NI_2VE_lane<!cast<Instruction>(subop # "_2s4s"), neon_uimm1_bare, 6954259698Sdim op, VPR64, VPR64, VPR64, v2i32, v2i32, v2i32>; 6955259698Sdim 6956259698Sdim def : NI_2VE_lane<!cast<Instruction>(subop # "_4h8h"), neon_uimm2_bare, 6957259698Sdim op, VPR64, VPR64, VPR64Lo, v4i16, v4i16, v4i16>; 6958259698Sdim} 6959259698Sdim 6960259698Sdimdefm MLA_lane_v1 : NI_2VE_v1_pat<"MLAvve", Neon_mla>; 6961259698Sdimdefm MLS_lane_v1 : NI_2VE_v1_pat<"MLSvve", Neon_mls>; 6962259698Sdim 6963259698Sdimclass NI_2VE_2op<bit q, bit u, bits<2> size, bits<4> opcode, 6964259698Sdim string asmop, string ResS, string OpS, string EleOpS, 6965259698Sdim Operand OpImm, RegisterOperand ResVPR, 6966259698Sdim RegisterOperand OpVPR, RegisterOperand EleOpVPR> 6967259698Sdim : NeonI_2VElem<q, u, size, opcode, 6968259698Sdim (outs ResVPR:$Rd), (ins OpVPR:$Rn, 6969259698Sdim EleOpVPR:$Re, OpImm:$Index), 6970259698Sdim asmop # "\t$Rd." # ResS # ", $Rn." # OpS # 6971259698Sdim ", $Re." # EleOpS # "[$Index]", 6972259698Sdim [], 6973259698Sdim NoItinerary> { 6974259698Sdim bits<3> Index; 6975259698Sdim bits<5> Re; 6976259698Sdim} 6977259698Sdim 6978259698Sdimmulticlass NI_2VE_v1_2op<bit u, bits<4> opcode, string asmop> { 6979259698Sdim // vector register class for element is always 128-bit to cover the max index 6980259698Sdim def _2s4s : NI_2VE_2op<0b0, u, 0b10, opcode, asmop, "2s", "2s", "s", 6981259698Sdim neon_uimm2_bare, VPR64, VPR64, VPR128> { 6982259698Sdim let Inst{11} = {Index{1}}; 6983259698Sdim let Inst{21} = {Index{0}}; 6984259698Sdim let Inst{20-16} = Re; 6985259698Sdim } 6986259698Sdim 6987259698Sdim def _4s4s : NI_2VE_2op<0b1, u, 0b10, opcode, asmop, "4s", "4s", "s", 6988259698Sdim neon_uimm2_bare, VPR128, VPR128, VPR128> { 6989259698Sdim let Inst{11} = {Index{1}}; 6990259698Sdim let Inst{21} = {Index{0}}; 6991259698Sdim let Inst{20-16} = Re; 6992259698Sdim } 6993259698Sdim 6994259698Sdim // Index operations on 16-bit(H) elements are restricted to using v0-v15. 6995259698Sdim def _4h8h : NI_2VE_2op<0b0, u, 0b01, opcode, asmop, "4h", "4h", "h", 6996259698Sdim neon_uimm3_bare, VPR64, VPR64, VPR128Lo> { 6997259698Sdim let Inst{11} = {Index{2}}; 6998259698Sdim let Inst{21} = {Index{1}}; 6999259698Sdim let Inst{20} = {Index{0}}; 7000259698Sdim let Inst{19-16} = Re{3-0}; 7001259698Sdim } 7002259698Sdim 7003259698Sdim def _8h8h : NI_2VE_2op<0b1, u, 0b01, opcode, asmop, "8h", "8h", "h", 7004259698Sdim neon_uimm3_bare, VPR128, VPR128, VPR128Lo> { 7005259698Sdim let Inst{11} = {Index{2}}; 7006259698Sdim let Inst{21} = {Index{1}}; 7007259698Sdim let Inst{20} = {Index{0}}; 7008259698Sdim let Inst{19-16} = Re{3-0}; 7009259698Sdim } 7010259698Sdim} 7011259698Sdim 7012259698Sdimdefm MULve : NI_2VE_v1_2op<0b0, 0b1000, "mul">; 7013259698Sdimdefm SQDMULHve : NI_2VE_v1_2op<0b0, 0b1100, "sqdmulh">; 7014259698Sdimdefm SQRDMULHve : NI_2VE_v1_2op<0b0, 0b1101, "sqrdmulh">; 7015259698Sdim 7016259698Sdim// Pattern for lane in 128-bit vector 7017259698Sdimclass NI_2VE_mul_laneq<Instruction INST, Operand OpImm, SDPatternOperator op, 7018259698Sdim RegisterOperand OpVPR, RegisterOperand EleOpVPR, 7019259698Sdim ValueType ResTy, ValueType OpTy, ValueType EleOpTy> 7020259698Sdim : Pat<(ResTy (op (OpTy OpVPR:$Rn), 7021259698Sdim (OpTy (Neon_vduplane (EleOpTy EleOpVPR:$Re), (i64 OpImm:$Index))))), 7022259698Sdim (INST OpVPR:$Rn, EleOpVPR:$Re, OpImm:$Index)>; 7023259698Sdim 7024259698Sdim// Pattern for lane in 64-bit vector 7025259698Sdimclass NI_2VE_mul_lane<Instruction INST, Operand OpImm, SDPatternOperator op, 7026259698Sdim RegisterOperand OpVPR, RegisterOperand EleOpVPR, 7027259698Sdim ValueType ResTy, ValueType OpTy, ValueType EleOpTy> 7028259698Sdim : Pat<(ResTy (op (OpTy OpVPR:$Rn), 7029259698Sdim (OpTy (Neon_vduplane (EleOpTy EleOpVPR:$Re), (i64 OpImm:$Index))))), 7030259698Sdim (INST OpVPR:$Rn, 7031259698Sdim (SUBREG_TO_REG (i64 0), EleOpVPR:$Re, sub_64), OpImm:$Index)>; 7032259698Sdim 7033259698Sdimmulticlass NI_2VE_mul_v1_pat<string subop, SDPatternOperator op> { 7034259698Sdim def : NI_2VE_mul_laneq<!cast<Instruction>(subop # "_2s4s"), neon_uimm2_bare, 7035259698Sdim op, VPR64, VPR128, v2i32, v2i32, v4i32>; 7036259698Sdim 7037259698Sdim def : NI_2VE_mul_laneq<!cast<Instruction>(subop # "_4s4s"), neon_uimm2_bare, 7038259698Sdim op, VPR128, VPR128, v4i32, v4i32, v4i32>; 7039259698Sdim 7040259698Sdim def : NI_2VE_mul_laneq<!cast<Instruction>(subop # "_4h8h"), neon_uimm3_bare, 7041259698Sdim op, VPR64, VPR128Lo, v4i16, v4i16, v8i16>; 7042259698Sdim 7043259698Sdim def : NI_2VE_mul_laneq<!cast<Instruction>(subop # "_8h8h"), neon_uimm3_bare, 7044259698Sdim op, VPR128, VPR128Lo, v8i16, v8i16, v8i16>; 7045259698Sdim 7046259698Sdim // Index can only be half of the max value for lane in 64-bit vector 7047259698Sdim 7048259698Sdim def : NI_2VE_mul_lane<!cast<Instruction>(subop # "_2s4s"), neon_uimm1_bare, 7049259698Sdim op, VPR64, VPR64, v2i32, v2i32, v2i32>; 7050259698Sdim 7051259698Sdim def : NI_2VE_mul_lane<!cast<Instruction>(subop # "_4h8h"), neon_uimm2_bare, 7052259698Sdim op, VPR64, VPR64Lo, v4i16, v4i16, v4i16>; 7053259698Sdim} 7054259698Sdim 7055259698Sdimdefm MUL_lane_v1 : NI_2VE_mul_v1_pat<"MULve", mul>; 7056259698Sdimdefm SQDMULH_lane_v1 : NI_2VE_mul_v1_pat<"SQDMULHve", int_arm_neon_vqdmulh>; 7057259698Sdimdefm SQRDMULH_lane_v1 : NI_2VE_mul_v1_pat<"SQRDMULHve", int_arm_neon_vqrdmulh>; 7058259698Sdim 7059259698Sdim// Variant 2 7060259698Sdim 7061259698Sdimmulticlass NI_2VE_v2_2op<bit u, bits<4> opcode, string asmop> { 7062259698Sdim // vector register class for element is always 128-bit to cover the max index 7063259698Sdim def _2s4s : NI_2VE_2op<0b0, u, 0b10, opcode, asmop, "2s", "2s", "s", 7064259698Sdim neon_uimm2_bare, VPR64, VPR64, VPR128> { 7065259698Sdim let Inst{11} = {Index{1}}; 7066259698Sdim let Inst{21} = {Index{0}}; 7067259698Sdim let Inst{20-16} = Re; 7068259698Sdim } 7069259698Sdim 7070259698Sdim def _4s4s : NI_2VE_2op<0b1, u, 0b10, opcode, asmop, "4s", "4s", "s", 7071259698Sdim neon_uimm2_bare, VPR128, VPR128, VPR128> { 7072259698Sdim let Inst{11} = {Index{1}}; 7073259698Sdim let Inst{21} = {Index{0}}; 7074259698Sdim let Inst{20-16} = Re; 7075259698Sdim } 7076259698Sdim 7077259698Sdim // _1d2d doesn't exist! 7078259698Sdim 7079259698Sdim def _2d2d : NI_2VE_2op<0b1, u, 0b11, opcode, asmop, "2d", "2d", "d", 7080259698Sdim neon_uimm1_bare, VPR128, VPR128, VPR128> { 7081259698Sdim let Inst{11} = {Index{0}}; 7082259698Sdim let Inst{21} = 0b0; 7083259698Sdim let Inst{20-16} = Re; 7084259698Sdim } 7085259698Sdim} 7086259698Sdim 7087259698Sdimdefm FMULve : NI_2VE_v2_2op<0b0, 0b1001, "fmul">; 7088259698Sdimdefm FMULXve : NI_2VE_v2_2op<0b1, 0b1001, "fmulx">; 7089259698Sdim 7090259698Sdimclass NI_2VE_mul_lane_2d<Instruction INST, Operand OpImm, SDPatternOperator op, 7091259698Sdim RegisterOperand OpVPR, RegisterOperand EleOpVPR, 7092259698Sdim ValueType ResTy, ValueType OpTy, ValueType EleOpTy, 7093259698Sdim SDPatternOperator coreop> 7094259698Sdim : Pat<(ResTy (op (OpTy OpVPR:$Rn), 7095259698Sdim (OpTy (coreop (EleOpTy EleOpVPR:$Re), (EleOpTy EleOpVPR:$Re))))), 7096259698Sdim (INST OpVPR:$Rn, 7097259698Sdim (SUBREG_TO_REG (i64 0), EleOpVPR:$Re, sub_64), 0)>; 7098259698Sdim 7099259698Sdimmulticlass NI_2VE_mul_v2_pat<string subop, SDPatternOperator op> { 7100259698Sdim def : NI_2VE_mul_laneq<!cast<Instruction>(subop # "_2s4s"), neon_uimm2_bare, 7101259698Sdim op, VPR64, VPR128, v2f32, v2f32, v4f32>; 7102259698Sdim 7103259698Sdim def : NI_2VE_mul_laneq<!cast<Instruction>(subop # "_4s4s"), neon_uimm2_bare, 7104259698Sdim op, VPR128, VPR128, v4f32, v4f32, v4f32>; 7105259698Sdim 7106259698Sdim def : NI_2VE_mul_laneq<!cast<Instruction>(subop # "_2d2d"), neon_uimm1_bare, 7107259698Sdim op, VPR128, VPR128, v2f64, v2f64, v2f64>; 7108259698Sdim 7109259698Sdim // Index can only be half of the max value for lane in 64-bit vector 7110259698Sdim 7111259698Sdim def : NI_2VE_mul_lane<!cast<Instruction>(subop # "_2s4s"), neon_uimm1_bare, 7112259698Sdim op, VPR64, VPR64, v2f32, v2f32, v2f32>; 7113259698Sdim 7114259698Sdim def : NI_2VE_mul_lane_2d<!cast<Instruction>(subop # "_2d2d"), neon_uimm1_bare, 7115259698Sdim op, VPR128, VPR64, v2f64, v2f64, v1f64, 7116259698Sdim BinOpFrag<(Neon_combine_2d node:$LHS, node:$RHS)>>; 7117259698Sdim} 7118259698Sdim 7119259698Sdimdefm FMUL_lane_v2 : NI_2VE_mul_v2_pat<"FMULve", fmul>; 7120259698Sdimdefm FMULX_lane_v2 : NI_2VE_mul_v2_pat<"FMULXve", int_aarch64_neon_vmulx>; 7121259698Sdim 7122259698Sdimdef : Pat<(v2f32 (fmul (v2f32 (Neon_vdup (f32 FPR32:$Re))), 7123259698Sdim (v2f32 VPR64:$Rn))), 7124259698Sdim (FMULve_2s4s VPR64:$Rn, (SUBREG_TO_REG (i32 0), $Re, sub_32), 0)>; 7125259698Sdim 7126259698Sdimdef : Pat<(v4f32 (fmul (v4f32 (Neon_vdup (f32 FPR32:$Re))), 7127259698Sdim (v4f32 VPR128:$Rn))), 7128259698Sdim (FMULve_4s4s VPR128:$Rn, (SUBREG_TO_REG (i32 0), $Re, sub_32), 0)>; 7129259698Sdim 7130259698Sdimdef : Pat<(v2f64 (fmul (v2f64 (Neon_vdup (f64 FPR64:$Re))), 7131259698Sdim (v2f64 VPR128:$Rn))), 7132259698Sdim (FMULve_2d2d VPR128:$Rn, (SUBREG_TO_REG (i64 0), $Re, sub_64), 0)>; 7133259698Sdim 7134259698Sdim// The followings are patterns using fma 7135259698Sdim// -ffp-contract=fast generates fma 7136259698Sdim 7137259698Sdimmulticlass NI_2VE_v2<bit u, bits<4> opcode, string asmop> { 7138259698Sdim // vector register class for element is always 128-bit to cover the max index 7139259698Sdim def _2s4s : NI_2VE<0b0, u, 0b10, opcode, asmop, "2s", "2s", "s", 7140259698Sdim neon_uimm2_bare, VPR64, VPR64, VPR128> { 7141259698Sdim let Inst{11} = {Index{1}}; 7142259698Sdim let Inst{21} = {Index{0}}; 7143259698Sdim let Inst{20-16} = Re; 7144259698Sdim } 7145259698Sdim 7146259698Sdim def _4s4s : NI_2VE<0b1, u, 0b10, opcode, asmop, "4s", "4s", "s", 7147259698Sdim neon_uimm2_bare, VPR128, VPR128, VPR128> { 7148259698Sdim let Inst{11} = {Index{1}}; 7149259698Sdim let Inst{21} = {Index{0}}; 7150259698Sdim let Inst{20-16} = Re; 7151259698Sdim } 7152259698Sdim 7153259698Sdim // _1d2d doesn't exist! 7154259698Sdim 7155259698Sdim def _2d2d : NI_2VE<0b1, u, 0b11, opcode, asmop, "2d", "2d", "d", 7156259698Sdim neon_uimm1_bare, VPR128, VPR128, VPR128> { 7157259698Sdim let Inst{11} = {Index{0}}; 7158259698Sdim let Inst{21} = 0b0; 7159259698Sdim let Inst{20-16} = Re; 7160259698Sdim } 7161259698Sdim} 7162259698Sdim 7163259698Sdimdefm FMLAvve : NI_2VE_v2<0b0, 0b0001, "fmla">; 7164259698Sdimdefm FMLSvve : NI_2VE_v2<0b0, 0b0101, "fmls">; 7165259698Sdim 7166259698Sdim// Pattern for lane in 128-bit vector 7167259698Sdimclass NI_2VEswap_laneq<Instruction INST, Operand OpImm, SDPatternOperator op, 7168259698Sdim RegisterOperand ResVPR, RegisterOperand OpVPR, 7169259698Sdim ValueType ResTy, ValueType OpTy, 7170259698Sdim SDPatternOperator coreop> 7171259698Sdim : Pat<(ResTy (op (ResTy (coreop (OpTy OpVPR:$Re), (i64 OpImm:$Index))), 7172259698Sdim (ResTy ResVPR:$src), (ResTy ResVPR:$Rn))), 7173259698Sdim (INST ResVPR:$src, ResVPR:$Rn, OpVPR:$Re, OpImm:$Index)>; 7174259698Sdim 7175259698Sdim// Pattern for lane 0 7176259698Sdimclass NI_2VEfma_lane0<Instruction INST, SDPatternOperator op, 7177259698Sdim RegisterOperand ResVPR, ValueType ResTy> 7178259698Sdim : Pat<(ResTy (op (ResTy ResVPR:$Rn), 7179259698Sdim (ResTy (Neon_vdup (f32 FPR32:$Re))), 7180259698Sdim (ResTy ResVPR:$src))), 7181259698Sdim (INST ResVPR:$src, ResVPR:$Rn, 7182259698Sdim (SUBREG_TO_REG (i32 0), $Re, sub_32), 0)>; 7183259698Sdim 7184259698Sdim// Pattern for lane in 64-bit vector 7185259698Sdimclass NI_2VEswap_lane<Instruction INST, Operand OpImm, SDPatternOperator op, 7186259698Sdim RegisterOperand ResVPR, RegisterOperand OpVPR, 7187259698Sdim ValueType ResTy, ValueType OpTy, 7188259698Sdim SDPatternOperator coreop> 7189259698Sdim : Pat<(ResTy (op (ResTy (coreop (OpTy OpVPR:$Re), (i64 OpImm:$Index))), 7190259698Sdim (ResTy ResVPR:$Rn), (ResTy ResVPR:$src))), 7191259698Sdim (INST ResVPR:$src, ResVPR:$Rn, 7192259698Sdim (SUBREG_TO_REG (i64 0), OpVPR:$Re, sub_64), OpImm:$Index)>; 7193259698Sdim 7194259698Sdim// Pattern for lane in 64-bit vector 7195259698Sdimclass NI_2VEswap_lane_2d2d<Instruction INST, Operand OpImm, 7196259698Sdim SDPatternOperator op, 7197259698Sdim RegisterOperand ResVPR, RegisterOperand OpVPR, 7198259698Sdim ValueType ResTy, ValueType OpTy, 7199259698Sdim SDPatternOperator coreop> 7200259698Sdim : Pat<(ResTy (op (ResTy (coreop (OpTy OpVPR:$Re), (OpTy OpVPR:$Re))), 7201259698Sdim (ResTy ResVPR:$Rn), (ResTy ResVPR:$src))), 7202259698Sdim (INST ResVPR:$src, ResVPR:$Rn, 7203259698Sdim (SUBREG_TO_REG (i64 0), OpVPR:$Re, sub_64), 0)>; 7204259698Sdim 7205259698Sdim 7206259698Sdimmulticlass NI_2VE_fma_v2_pat<string subop, SDPatternOperator op> { 7207259698Sdim def : NI_2VEswap_laneq<!cast<Instruction>(subop # "_2s4s"), 7208259698Sdim neon_uimm2_bare, op, VPR64, VPR128, v2f32, v4f32, 7209259698Sdim BinOpFrag<(Neon_vduplane node:$LHS, node:$RHS)>>; 7210259698Sdim 7211259698Sdim def : NI_2VEfma_lane0<!cast<Instruction>(subop # "_2s4s"), 7212259698Sdim op, VPR64, v2f32>; 7213259698Sdim 7214259698Sdim def : NI_2VEswap_laneq<!cast<Instruction>(subop # "_4s4s"), 7215259698Sdim neon_uimm2_bare, op, VPR128, VPR128, v4f32, v4f32, 7216259698Sdim BinOpFrag<(Neon_vduplane node:$LHS, node:$RHS)>>; 7217259698Sdim 7218259698Sdim def : NI_2VEfma_lane0<!cast<Instruction>(subop # "_4s4s"), 7219259698Sdim op, VPR128, v4f32>; 7220259698Sdim 7221259698Sdim def : NI_2VEswap_laneq<!cast<Instruction>(subop # "_2d2d"), 7222259698Sdim neon_uimm1_bare, op, VPR128, VPR128, v2f64, v2f64, 7223259698Sdim BinOpFrag<(Neon_vduplane node:$LHS, node:$RHS)>>; 7224259698Sdim 7225259698Sdim // Index can only be half of the max value for lane in 64-bit vector 7226259698Sdim 7227259698Sdim def : NI_2VEswap_lane<!cast<Instruction>(subop # "_2s4s"), 7228259698Sdim neon_uimm1_bare, op, VPR64, VPR64, v2f32, v2f32, 7229259698Sdim BinOpFrag<(Neon_vduplane node:$LHS, node:$RHS)>>; 7230259698Sdim 7231259698Sdim def : NI_2VEswap_lane_2d2d<!cast<Instruction>(subop # "_2d2d"), 7232259698Sdim neon_uimm1_bare, op, VPR128, VPR64, v2f64, v1f64, 7233259698Sdim BinOpFrag<(Neon_combine_2d node:$LHS, node:$RHS)>>; 7234259698Sdim} 7235259698Sdim 7236259698Sdimdefm FMLA_lane_v2_s : NI_2VE_fma_v2_pat<"FMLAvve", fma>; 7237259698Sdim 7238259698Sdim// Pattern for lane 0 7239259698Sdimclass NI_2VEfms_lane0<Instruction INST, SDPatternOperator op, 7240259698Sdim RegisterOperand ResVPR, ValueType ResTy> 7241259698Sdim : Pat<(ResTy (op (ResTy (fneg ResVPR:$Rn)), 7242259698Sdim (ResTy (Neon_vdup (f32 FPR32:$Re))), 7243259698Sdim (ResTy ResVPR:$src))), 7244259698Sdim (INST ResVPR:$src, ResVPR:$Rn, 7245259698Sdim (SUBREG_TO_REG (i32 0), $Re, sub_32), 0)>; 7246259698Sdim 7247259698Sdimmulticlass NI_2VE_fms_v2_pat<string subop, SDPatternOperator op> 7248259698Sdim{ 7249259698Sdim def : NI_2VEswap_laneq<!cast<Instruction>(subop # "_2s4s"), 7250259698Sdim neon_uimm2_bare, op, VPR64, VPR128, v2f32, v4f32, 7251259698Sdim BinOpFrag<(fneg (Neon_vduplane node:$LHS, node:$RHS))>>; 7252259698Sdim 7253259698Sdim def : NI_2VEswap_laneq<!cast<Instruction>(subop # "_2s4s"), 7254259698Sdim neon_uimm2_bare, op, VPR64, VPR128, v2f32, v4f32, 7255259698Sdim BinOpFrag<(Neon_vduplane 7256259698Sdim (fneg node:$LHS), node:$RHS)>>; 7257259698Sdim 7258259698Sdim def : NI_2VEfms_lane0<!cast<Instruction>(subop # "_2s4s"), 7259259698Sdim op, VPR64, v2f32>; 7260259698Sdim 7261259698Sdim def : NI_2VEswap_laneq<!cast<Instruction>(subop # "_4s4s"), 7262259698Sdim neon_uimm2_bare, op, VPR128, VPR128, v4f32, v4f32, 7263259698Sdim BinOpFrag<(fneg (Neon_vduplane 7264259698Sdim node:$LHS, node:$RHS))>>; 7265259698Sdim 7266259698Sdim def : NI_2VEswap_laneq<!cast<Instruction>(subop # "_4s4s"), 7267259698Sdim neon_uimm2_bare, op, VPR128, VPR128, v4f32, v4f32, 7268259698Sdim BinOpFrag<(Neon_vduplane 7269259698Sdim (fneg node:$LHS), node:$RHS)>>; 7270259698Sdim 7271259698Sdim def : NI_2VEfms_lane0<!cast<Instruction>(subop # "_4s4s"), 7272259698Sdim op, VPR128, v4f32>; 7273259698Sdim 7274259698Sdim def : NI_2VEswap_laneq<!cast<Instruction>(subop # "_2d2d"), 7275259698Sdim neon_uimm1_bare, op, VPR128, VPR128, v2f64, v2f64, 7276259698Sdim BinOpFrag<(fneg (Neon_vduplane 7277259698Sdim node:$LHS, node:$RHS))>>; 7278259698Sdim 7279259698Sdim def : NI_2VEswap_laneq<!cast<Instruction>(subop # "_2d2d"), 7280259698Sdim neon_uimm1_bare, op, VPR128, VPR128, v2f64, v2f64, 7281259698Sdim BinOpFrag<(Neon_vduplane 7282259698Sdim (fneg node:$LHS), node:$RHS)>>; 7283259698Sdim 7284259698Sdim // Index can only be half of the max value for lane in 64-bit vector 7285259698Sdim 7286259698Sdim def : NI_2VEswap_lane<!cast<Instruction>(subop # "_2s4s"), 7287259698Sdim neon_uimm1_bare, op, VPR64, VPR64, v2f32, v2f32, 7288259698Sdim BinOpFrag<(fneg (Neon_vduplane 7289259698Sdim node:$LHS, node:$RHS))>>; 7290259698Sdim 7291259698Sdim def : NI_2VEswap_lane<!cast<Instruction>(subop # "_2s4s"), 7292259698Sdim neon_uimm1_bare, op, VPR64, VPR64, v2f32, v2f32, 7293259698Sdim BinOpFrag<(Neon_vduplane 7294259698Sdim (fneg node:$LHS), node:$RHS)>>; 7295259698Sdim 7296259698Sdim def : NI_2VEswap_lane<!cast<Instruction>(subop # "_4s4s"), 7297259698Sdim neon_uimm1_bare, op, VPR128, VPR64, v4f32, v2f32, 7298259698Sdim BinOpFrag<(fneg (Neon_vduplane node:$LHS, node:$RHS))>>; 7299259698Sdim 7300259698Sdim def : NI_2VEswap_lane<!cast<Instruction>(subop # "_4s4s"), 7301259698Sdim neon_uimm1_bare, op, VPR128, VPR64, v4f32, v2f32, 7302259698Sdim BinOpFrag<(Neon_vduplane (fneg node:$LHS), node:$RHS)>>; 7303259698Sdim 7304259698Sdim def : NI_2VEswap_lane_2d2d<!cast<Instruction>(subop # "_2d2d"), 7305259698Sdim neon_uimm1_bare, op, VPR128, VPR64, v2f64, v1f64, 7306259698Sdim BinOpFrag<(fneg (Neon_combine_2d 7307259698Sdim node:$LHS, node:$RHS))>>; 7308259698Sdim 7309259698Sdim def : NI_2VEswap_lane_2d2d<!cast<Instruction>(subop # "_2d2d"), 7310259698Sdim neon_uimm1_bare, op, VPR128, VPR64, v2f64, v1f64, 7311259698Sdim BinOpFrag<(Neon_combine_2d 7312259698Sdim (fneg node:$LHS), (fneg node:$RHS))>>; 7313259698Sdim} 7314259698Sdim 7315259698Sdimdefm FMLS_lane_v2_s : NI_2VE_fms_v2_pat<"FMLSvve", fma>; 7316259698Sdim 7317259698Sdim// Variant 3: Long type 7318259698Sdim// E.g. SMLAL : 4S/4H/H (v0-v15), 2D/2S/S 7319259698Sdim// SMLAL2: 4S/8H/H (v0-v15), 2D/4S/S 7320259698Sdim 7321259698Sdimmulticlass NI_2VE_v3<bit u, bits<4> opcode, string asmop> { 7322259698Sdim // vector register class for element is always 128-bit to cover the max index 7323259698Sdim def _2d2s : NI_2VE<0b0, u, 0b10, opcode, asmop, "2d", "2s", "s", 7324259698Sdim neon_uimm2_bare, VPR128, VPR64, VPR128> { 7325259698Sdim let Inst{11} = {Index{1}}; 7326259698Sdim let Inst{21} = {Index{0}}; 7327259698Sdim let Inst{20-16} = Re; 7328259698Sdim } 7329259698Sdim 7330259698Sdim def _2d4s : NI_2VE<0b1, u, 0b10, opcode, asmop # "2", "2d", "4s", "s", 7331259698Sdim neon_uimm2_bare, VPR128, VPR128, VPR128> { 7332259698Sdim let Inst{11} = {Index{1}}; 7333259698Sdim let Inst{21} = {Index{0}}; 7334259698Sdim let Inst{20-16} = Re; 7335259698Sdim } 7336259698Sdim 7337259698Sdim // Index operations on 16-bit(H) elements are restricted to using v0-v15. 7338259698Sdim def _4s8h : NI_2VE<0b1, u, 0b01, opcode, asmop # "2", "4s", "8h", "h", 7339259698Sdim neon_uimm3_bare, VPR128, VPR128, VPR128Lo> { 7340259698Sdim let Inst{11} = {Index{2}}; 7341259698Sdim let Inst{21} = {Index{1}}; 7342259698Sdim let Inst{20} = {Index{0}}; 7343259698Sdim let Inst{19-16} = Re{3-0}; 7344259698Sdim } 7345259698Sdim 7346259698Sdim def _4s4h : NI_2VE<0b0, u, 0b01, opcode, asmop, "4s", "4h", "h", 7347259698Sdim neon_uimm3_bare, VPR128, VPR64, VPR128Lo> { 7348259698Sdim let Inst{11} = {Index{2}}; 7349259698Sdim let Inst{21} = {Index{1}}; 7350259698Sdim let Inst{20} = {Index{0}}; 7351259698Sdim let Inst{19-16} = Re{3-0}; 7352259698Sdim } 7353259698Sdim} 7354259698Sdim 7355259698Sdimdefm SMLALvve : NI_2VE_v3<0b0, 0b0010, "smlal">; 7356259698Sdimdefm UMLALvve : NI_2VE_v3<0b1, 0b0010, "umlal">; 7357259698Sdimdefm SMLSLvve : NI_2VE_v3<0b0, 0b0110, "smlsl">; 7358259698Sdimdefm UMLSLvve : NI_2VE_v3<0b1, 0b0110, "umlsl">; 7359259698Sdimdefm SQDMLALvve : NI_2VE_v3<0b0, 0b0011, "sqdmlal">; 7360259698Sdimdefm SQDMLSLvve : NI_2VE_v3<0b0, 0b0111, "sqdmlsl">; 7361259698Sdim 7362259698Sdimmulticlass NI_2VE_v3_2op<bit u, bits<4> opcode, string asmop> { 7363259698Sdim // vector register class for element is always 128-bit to cover the max index 7364259698Sdim def _2d2s : NI_2VE_2op<0b0, u, 0b10, opcode, asmop, "2d", "2s", "s", 7365259698Sdim neon_uimm2_bare, VPR128, VPR64, VPR128> { 7366259698Sdim let Inst{11} = {Index{1}}; 7367259698Sdim let Inst{21} = {Index{0}}; 7368259698Sdim let Inst{20-16} = Re; 7369259698Sdim } 7370259698Sdim 7371259698Sdim def _2d4s : NI_2VE_2op<0b1, u, 0b10, opcode, asmop # "2", "2d", "4s", "s", 7372259698Sdim neon_uimm2_bare, VPR128, VPR128, VPR128> { 7373259698Sdim let Inst{11} = {Index{1}}; 7374259698Sdim let Inst{21} = {Index{0}}; 7375259698Sdim let Inst{20-16} = Re; 7376259698Sdim } 7377259698Sdim 7378259698Sdim // Index operations on 16-bit(H) elements are restricted to using v0-v15. 7379259698Sdim def _4s8h : NI_2VE_2op<0b1, u, 0b01, opcode, asmop # "2", "4s", "8h", "h", 7380259698Sdim neon_uimm3_bare, VPR128, VPR128, VPR128Lo> { 7381259698Sdim let Inst{11} = {Index{2}}; 7382259698Sdim let Inst{21} = {Index{1}}; 7383259698Sdim let Inst{20} = {Index{0}}; 7384259698Sdim let Inst{19-16} = Re{3-0}; 7385259698Sdim } 7386259698Sdim 7387259698Sdim def _4s4h : NI_2VE_2op<0b0, u, 0b01, opcode, asmop, "4s", "4h", "h", 7388259698Sdim neon_uimm3_bare, VPR128, VPR64, VPR128Lo> { 7389259698Sdim let Inst{11} = {Index{2}}; 7390259698Sdim let Inst{21} = {Index{1}}; 7391259698Sdim let Inst{20} = {Index{0}}; 7392259698Sdim let Inst{19-16} = Re{3-0}; 7393259698Sdim } 7394259698Sdim} 7395259698Sdim 7396259698Sdimdefm SMULLve : NI_2VE_v3_2op<0b0, 0b1010, "smull">; 7397259698Sdimdefm UMULLve : NI_2VE_v3_2op<0b1, 0b1010, "umull">; 7398259698Sdimdefm SQDMULLve : NI_2VE_v3_2op<0b0, 0b1011, "sqdmull">; 7399259698Sdim 7400259698Sdimdef : Pat<(v1f64 (scalar_to_vector (f64 FPR64:$src))), 7401259698Sdim (FMOVdd $src)>; 7402259698Sdimdef : Pat<(v1f32 (scalar_to_vector (f32 FPR32:$src))), 7403259698Sdim (FMOVss $src)>; 7404259698Sdim 7405259698Sdim// Pattern for lane in 128-bit vector 7406259698Sdimclass NI_2VEL2_laneq<Instruction INST, Operand OpImm, SDPatternOperator op, 7407259698Sdim RegisterOperand EleOpVPR, ValueType ResTy, 7408259698Sdim ValueType OpTy, ValueType EleOpTy, ValueType HalfOpTy, 7409259698Sdim SDPatternOperator hiop> 7410259698Sdim : Pat<(ResTy (op (ResTy VPR128:$src), 7411259698Sdim (HalfOpTy (hiop (OpTy VPR128:$Rn))), 7412259698Sdim (HalfOpTy (Neon_vduplane 7413259698Sdim (EleOpTy EleOpVPR:$Re), (i64 OpImm:$Index))))), 7414259698Sdim (INST VPR128:$src, VPR128:$Rn, EleOpVPR:$Re, OpImm:$Index)>; 7415259698Sdim 7416259698Sdim// Pattern for lane in 64-bit vector 7417259698Sdimclass NI_2VEL2_lane<Instruction INST, Operand OpImm, SDPatternOperator op, 7418259698Sdim RegisterOperand EleOpVPR, ValueType ResTy, 7419259698Sdim ValueType OpTy, ValueType EleOpTy, ValueType HalfOpTy, 7420259698Sdim SDPatternOperator hiop> 7421259698Sdim : Pat<(ResTy (op (ResTy VPR128:$src), 7422259698Sdim (HalfOpTy (hiop (OpTy VPR128:$Rn))), 7423259698Sdim (HalfOpTy (Neon_vduplane 7424259698Sdim (EleOpTy EleOpVPR:$Re), (i64 OpImm:$Index))))), 7425259698Sdim (INST VPR128:$src, VPR128:$Rn, 7426259698Sdim (SUBREG_TO_REG (i64 0), EleOpVPR:$Re, sub_64), OpImm:$Index)>; 7427259698Sdim 7428259698Sdimclass NI_2VEL2_lane0<Instruction INST, SDPatternOperator op, 7429259698Sdim ValueType ResTy, ValueType OpTy, ValueType HalfOpTy, 7430259698Sdim SDPatternOperator hiop, Instruction DupInst> 7431259698Sdim : Pat<(ResTy (op (ResTy VPR128:$src), 7432259698Sdim (HalfOpTy (hiop (OpTy VPR128:$Rn))), 7433259698Sdim (HalfOpTy (Neon_vdup (i32 GPR32:$Re))))), 7434259698Sdim (INST VPR128:$src, VPR128:$Rn, (DupInst $Re), 0)>; 7435259698Sdim 7436259698Sdimmulticlass NI_2VEL_v3_pat<string subop, SDPatternOperator op> { 7437259698Sdim def : NI_2VE_laneq<!cast<Instruction>(subop # "_4s4h"), neon_uimm3_bare, 7438259698Sdim op, VPR128, VPR64, VPR128Lo, v4i32, v4i16, v8i16>; 7439259698Sdim 7440259698Sdim def : NI_2VE_laneq<!cast<Instruction>(subop # "_2d2s"), neon_uimm2_bare, 7441259698Sdim op, VPR128, VPR64, VPR128, v2i64, v2i32, v4i32>; 7442259698Sdim 7443259698Sdim def : NI_2VEL2_laneq<!cast<Instruction>(subop # "_4s8h"), neon_uimm3_bare, 7444259698Sdim op, VPR128Lo, v4i32, v8i16, v8i16, v4i16, Neon_High8H>; 7445259698Sdim 7446259698Sdim def : NI_2VEL2_laneq<!cast<Instruction>(subop # "_2d4s"), neon_uimm2_bare, 7447259698Sdim op, VPR128, v2i64, v4i32, v4i32, v2i32, Neon_High4S>; 7448259698Sdim 7449259698Sdim def : NI_2VEL2_lane0<!cast<Instruction>(subop # "_4s8h"), 7450259698Sdim op, v4i32, v8i16, v4i16, Neon_High8H, DUP8h>; 7451259698Sdim 7452259698Sdim def : NI_2VEL2_lane0<!cast<Instruction>(subop # "_2d4s"), 7453259698Sdim op, v2i64, v4i32, v2i32, Neon_High4S, DUP4s>; 7454259698Sdim 7455259698Sdim // Index can only be half of the max value for lane in 64-bit vector 7456259698Sdim 7457259698Sdim def : NI_2VE_lane<!cast<Instruction>(subop # "_4s4h"), neon_uimm2_bare, 7458259698Sdim op, VPR128, VPR64, VPR64Lo, v4i32, v4i16, v4i16>; 7459259698Sdim 7460259698Sdim def : NI_2VE_lane<!cast<Instruction>(subop # "_2d2s"), neon_uimm1_bare, 7461259698Sdim op, VPR128, VPR64, VPR64, v2i64, v2i32, v2i32>; 7462259698Sdim 7463259698Sdim def : NI_2VEL2_lane<!cast<Instruction>(subop # "_4s8h"), neon_uimm2_bare, 7464259698Sdim op, VPR64Lo, v4i32, v8i16, v4i16, v4i16, Neon_High8H>; 7465259698Sdim 7466259698Sdim def : NI_2VEL2_lane<!cast<Instruction>(subop # "_2d4s"), neon_uimm1_bare, 7467259698Sdim op, VPR64, v2i64, v4i32, v2i32, v2i32, Neon_High4S>; 7468259698Sdim} 7469259698Sdim 7470259698Sdimdefm SMLAL_lane_v3 : NI_2VEL_v3_pat<"SMLALvve", Neon_smlal>; 7471259698Sdimdefm UMLAL_lane_v3 : NI_2VEL_v3_pat<"UMLALvve", Neon_umlal>; 7472259698Sdimdefm SMLSL_lane_v3 : NI_2VEL_v3_pat<"SMLSLvve", Neon_smlsl>; 7473259698Sdimdefm UMLSL_lane_v3 : NI_2VEL_v3_pat<"UMLSLvve", Neon_umlsl>; 7474259698Sdim 7475259698Sdim// Pattern for lane in 128-bit vector 7476259698Sdimclass NI_2VEL2_mul_laneq<Instruction INST, Operand OpImm, SDPatternOperator op, 7477259698Sdim RegisterOperand EleOpVPR, ValueType ResTy, 7478259698Sdim ValueType OpTy, ValueType EleOpTy, ValueType HalfOpTy, 7479259698Sdim SDPatternOperator hiop> 7480259698Sdim : Pat<(ResTy (op 7481259698Sdim (HalfOpTy (hiop (OpTy VPR128:$Rn))), 7482259698Sdim (HalfOpTy (Neon_vduplane 7483259698Sdim (EleOpTy EleOpVPR:$Re), (i64 OpImm:$Index))))), 7484259698Sdim (INST VPR128:$Rn, EleOpVPR:$Re, OpImm:$Index)>; 7485259698Sdim 7486259698Sdim// Pattern for lane in 64-bit vector 7487259698Sdimclass NI_2VEL2_mul_lane<Instruction INST, Operand OpImm, SDPatternOperator op, 7488259698Sdim RegisterOperand EleOpVPR, ValueType ResTy, 7489259698Sdim ValueType OpTy, ValueType EleOpTy, ValueType HalfOpTy, 7490259698Sdim SDPatternOperator hiop> 7491259698Sdim : Pat<(ResTy (op 7492259698Sdim (HalfOpTy (hiop (OpTy VPR128:$Rn))), 7493259698Sdim (HalfOpTy (Neon_vduplane 7494259698Sdim (EleOpTy EleOpVPR:$Re), (i64 OpImm:$Index))))), 7495259698Sdim (INST VPR128:$Rn, 7496259698Sdim (SUBREG_TO_REG (i64 0), EleOpVPR:$Re, sub_64), OpImm:$Index)>; 7497259698Sdim 7498259698Sdim// Pattern for fixed lane 0 7499259698Sdimclass NI_2VEL2_mul_lane0<Instruction INST, SDPatternOperator op, 7500259698Sdim ValueType ResTy, ValueType OpTy, ValueType HalfOpTy, 7501259698Sdim SDPatternOperator hiop, Instruction DupInst> 7502259698Sdim : Pat<(ResTy (op 7503259698Sdim (HalfOpTy (hiop (OpTy VPR128:$Rn))), 7504259698Sdim (HalfOpTy (Neon_vdup (i32 GPR32:$Re))))), 7505259698Sdim (INST VPR128:$Rn, (DupInst $Re), 0)>; 7506259698Sdim 7507259698Sdimmulticlass NI_2VEL_mul_v3_pat<string subop, SDPatternOperator op> { 7508259698Sdim def : NI_2VE_mul_laneq<!cast<Instruction>(subop # "_4s4h"), neon_uimm3_bare, 7509259698Sdim op, VPR64, VPR128Lo, v4i32, v4i16, v8i16>; 7510259698Sdim 7511259698Sdim def : NI_2VE_mul_laneq<!cast<Instruction>(subop # "_2d2s"), neon_uimm2_bare, 7512259698Sdim op, VPR64, VPR128, v2i64, v2i32, v4i32>; 7513259698Sdim 7514259698Sdim def : NI_2VEL2_mul_laneq<!cast<Instruction>(subop # "_4s8h"), neon_uimm3_bare, 7515259698Sdim op, VPR128Lo, v4i32, v8i16, v8i16, v4i16, Neon_High8H>; 7516259698Sdim 7517259698Sdim def : NI_2VEL2_mul_laneq<!cast<Instruction>(subop # "_2d4s"), neon_uimm2_bare, 7518259698Sdim op, VPR128, v2i64, v4i32, v4i32, v2i32, Neon_High4S>; 7519259698Sdim 7520259698Sdim def : NI_2VEL2_mul_lane0<!cast<Instruction>(subop # "_4s8h"), 7521259698Sdim op, v4i32, v8i16, v4i16, Neon_High8H, DUP8h>; 7522259698Sdim 7523259698Sdim def : NI_2VEL2_mul_lane0<!cast<Instruction>(subop # "_2d4s"), 7524259698Sdim op, v2i64, v4i32, v2i32, Neon_High4S, DUP4s>; 7525259698Sdim 7526259698Sdim // Index can only be half of the max value for lane in 64-bit vector 7527259698Sdim 7528259698Sdim def : NI_2VE_mul_lane<!cast<Instruction>(subop # "_4s4h"), neon_uimm2_bare, 7529259698Sdim op, VPR64, VPR64Lo, v4i32, v4i16, v4i16>; 7530259698Sdim 7531259698Sdim def : NI_2VE_mul_lane<!cast<Instruction>(subop # "_2d2s"), neon_uimm1_bare, 7532259698Sdim op, VPR64, VPR64, v2i64, v2i32, v2i32>; 7533259698Sdim 7534259698Sdim def : NI_2VEL2_mul_lane<!cast<Instruction>(subop # "_4s8h"), neon_uimm2_bare, 7535259698Sdim op, VPR64Lo, v4i32, v8i16, v4i16, v4i16, Neon_High8H>; 7536259698Sdim 7537259698Sdim def : NI_2VEL2_mul_lane<!cast<Instruction>(subop # "_2d4s"), neon_uimm1_bare, 7538259698Sdim op, VPR64, v2i64, v4i32, v2i32, v2i32, Neon_High4S>; 7539259698Sdim} 7540259698Sdim 7541259698Sdimdefm SMULL_lane_v3 : NI_2VEL_mul_v3_pat<"SMULLve", int_arm_neon_vmulls>; 7542259698Sdimdefm UMULL_lane_v3 : NI_2VEL_mul_v3_pat<"UMULLve", int_arm_neon_vmullu>; 7543259698Sdimdefm SQDMULL_lane_v3 : NI_2VEL_mul_v3_pat<"SQDMULLve", int_arm_neon_vqdmull>; 7544259698Sdim 7545259698Sdimmulticlass NI_qdma<SDPatternOperator op> { 7546259698Sdim def _4s : PatFrag<(ops node:$Ra, node:$Rn, node:$Rm), 7547259698Sdim (op node:$Ra, 7548259698Sdim (v4i32 (int_arm_neon_vqdmull node:$Rn, node:$Rm)))>; 7549259698Sdim 7550259698Sdim def _2d : PatFrag<(ops node:$Ra, node:$Rn, node:$Rm), 7551259698Sdim (op node:$Ra, 7552259698Sdim (v2i64 (int_arm_neon_vqdmull node:$Rn, node:$Rm)))>; 7553259698Sdim} 7554259698Sdim 7555259698Sdimdefm Neon_qdmlal : NI_qdma<int_arm_neon_vqadds>; 7556259698Sdimdefm Neon_qdmlsl : NI_qdma<int_arm_neon_vqsubs>; 7557259698Sdim 7558259698Sdimmulticlass NI_2VEL_v3_qdma_pat<string subop, string op> { 7559259698Sdim def : NI_2VE_laneq<!cast<Instruction>(subop # "_4s4h"), neon_uimm3_bare, 7560259698Sdim !cast<PatFrag>(op # "_4s"), VPR128, VPR64, VPR128Lo, 7561259698Sdim v4i32, v4i16, v8i16>; 7562259698Sdim 7563259698Sdim def : NI_2VE_laneq<!cast<Instruction>(subop # "_2d2s"), neon_uimm2_bare, 7564259698Sdim !cast<PatFrag>(op # "_2d"), VPR128, VPR64, VPR128, 7565259698Sdim v2i64, v2i32, v4i32>; 7566259698Sdim 7567259698Sdim def : NI_2VEL2_laneq<!cast<Instruction>(subop # "_4s8h"), neon_uimm3_bare, 7568259698Sdim !cast<PatFrag>(op # "_4s"), VPR128Lo, 7569259698Sdim v4i32, v8i16, v8i16, v4i16, Neon_High8H>; 7570259698Sdim 7571259698Sdim def : NI_2VEL2_laneq<!cast<Instruction>(subop # "_2d4s"), neon_uimm2_bare, 7572259698Sdim !cast<PatFrag>(op # "_2d"), VPR128, 7573259698Sdim v2i64, v4i32, v4i32, v2i32, Neon_High4S>; 7574259698Sdim 7575259698Sdim def : NI_2VEL2_lane0<!cast<Instruction>(subop # "_4s8h"), 7576259698Sdim !cast<PatFrag>(op # "_4s"), 7577259698Sdim v4i32, v8i16, v4i16, Neon_High8H, DUP8h>; 7578259698Sdim 7579259698Sdim def : NI_2VEL2_lane0<!cast<Instruction>(subop # "_2d4s"), 7580259698Sdim !cast<PatFrag>(op # "_2d"), 7581259698Sdim v2i64, v4i32, v2i32, Neon_High4S, DUP4s>; 7582259698Sdim 7583259698Sdim // Index can only be half of the max value for lane in 64-bit vector 7584259698Sdim 7585259698Sdim def : NI_2VE_lane<!cast<Instruction>(subop # "_4s4h"), neon_uimm2_bare, 7586259698Sdim !cast<PatFrag>(op # "_4s"), VPR128, VPR64, VPR64Lo, 7587259698Sdim v4i32, v4i16, v4i16>; 7588259698Sdim 7589259698Sdim def : NI_2VE_lane<!cast<Instruction>(subop # "_2d2s"), neon_uimm1_bare, 7590259698Sdim !cast<PatFrag>(op # "_2d"), VPR128, VPR64, VPR64, 7591259698Sdim v2i64, v2i32, v2i32>; 7592259698Sdim 7593259698Sdim def : NI_2VEL2_lane<!cast<Instruction>(subop # "_4s8h"), neon_uimm2_bare, 7594259698Sdim !cast<PatFrag>(op # "_4s"), VPR64Lo, 7595259698Sdim v4i32, v8i16, v4i16, v4i16, Neon_High8H>; 7596259698Sdim 7597259698Sdim def : NI_2VEL2_lane<!cast<Instruction>(subop # "_2d4s"), neon_uimm1_bare, 7598259698Sdim !cast<PatFrag>(op # "_2d"), VPR64, 7599259698Sdim v2i64, v4i32, v2i32, v2i32, Neon_High4S>; 7600259698Sdim} 7601259698Sdim 7602259698Sdimdefm SQDMLAL_lane_v3 : NI_2VEL_v3_qdma_pat<"SQDMLALvve", "Neon_qdmlal">; 7603259698Sdimdefm SQDMLSL_lane_v3 : NI_2VEL_v3_qdma_pat<"SQDMLSLvve", "Neon_qdmlsl">; 7604259698Sdim 7605259698Sdim// End of implementation for instruction class (3V Elem) 7606259698Sdim 7607259698Sdimclass NeonI_REV<string asmop, string Res, bits<2> size, bit Q, bit U, 7608259698Sdim bits<5> opcode, RegisterOperand ResVPR, ValueType ResTy, 7609259698Sdim SDPatternOperator Neon_Rev> 7610259698Sdim : NeonI_2VMisc<Q, U, size, opcode, 7611259698Sdim (outs ResVPR:$Rd), (ins ResVPR:$Rn), 7612259698Sdim asmop # "\t$Rd." # Res # ", $Rn." # Res, 7613259698Sdim [(set (ResTy ResVPR:$Rd), 7614259698Sdim (ResTy (Neon_Rev (ResTy ResVPR:$Rn))))], 7615259698Sdim NoItinerary> ; 7616259698Sdim 7617259698Sdimdef REV64_16b : NeonI_REV<"rev64", "16b", 0b00, 0b1, 0b0, 0b00000, VPR128, 7618259698Sdim v16i8, Neon_rev64>; 7619259698Sdimdef REV64_8h : NeonI_REV<"rev64", "8h", 0b01, 0b1, 0b0, 0b00000, VPR128, 7620259698Sdim v8i16, Neon_rev64>; 7621259698Sdimdef REV64_4s : NeonI_REV<"rev64", "4s", 0b10, 0b1, 0b0, 0b00000, VPR128, 7622259698Sdim v4i32, Neon_rev64>; 7623259698Sdimdef REV64_8b : NeonI_REV<"rev64", "8b", 0b00, 0b0, 0b0, 0b00000, VPR64, 7624259698Sdim v8i8, Neon_rev64>; 7625259698Sdimdef REV64_4h : NeonI_REV<"rev64", "4h", 0b01, 0b0, 0b0, 0b00000, VPR64, 7626259698Sdim v4i16, Neon_rev64>; 7627259698Sdimdef REV64_2s : NeonI_REV<"rev64", "2s", 0b10, 0b0, 0b0, 0b00000, VPR64, 7628259698Sdim v2i32, Neon_rev64>; 7629259698Sdim 7630259698Sdimdef : Pat<(v4f32 (Neon_rev64 (v4f32 VPR128:$Rn))), (REV64_4s VPR128:$Rn)>; 7631259698Sdimdef : Pat<(v2f32 (Neon_rev64 (v2f32 VPR64:$Rn))), (REV64_2s VPR64:$Rn)>; 7632259698Sdim 7633259698Sdimdef REV32_16b : NeonI_REV<"rev32", "16b", 0b00, 0b1, 0b1, 0b00000, VPR128, 7634259698Sdim v16i8, Neon_rev32>; 7635259698Sdimdef REV32_8h : NeonI_REV<"rev32", "8h", 0b01, 0b1, 0b1, 0b00000, VPR128, 7636259698Sdim v8i16, Neon_rev32>; 7637259698Sdimdef REV32_8b : NeonI_REV<"rev32", "8b", 0b00, 0b0, 0b1, 0b00000, VPR64, 7638259698Sdim v8i8, Neon_rev32>; 7639259698Sdimdef REV32_4h : NeonI_REV<"rev32", "4h", 0b01, 0b0, 0b1, 0b00000, VPR64, 7640259698Sdim v4i16, Neon_rev32>; 7641259698Sdim 7642259698Sdimdef REV16_16b : NeonI_REV<"rev16", "16b", 0b00, 0b1, 0b0, 0b00001, VPR128, 7643259698Sdim v16i8, Neon_rev16>; 7644259698Sdimdef REV16_8b : NeonI_REV<"rev16", "8b", 0b00, 0b0, 0b0, 0b00001, VPR64, 7645259698Sdim v8i8, Neon_rev16>; 7646259698Sdim 7647259698Sdimmulticlass NeonI_PairwiseAdd<string asmop, bit U, bits<5> opcode, 7648259698Sdim SDPatternOperator Neon_Padd> { 7649259698Sdim def 16b8h : NeonI_2VMisc<0b1, U, 0b00, opcode, 7650259698Sdim (outs VPR128:$Rd), (ins VPR128:$Rn), 7651259698Sdim asmop # "\t$Rd.8h, $Rn.16b", 7652259698Sdim [(set (v8i16 VPR128:$Rd), 7653259698Sdim (v8i16 (Neon_Padd (v16i8 VPR128:$Rn))))], 7654259698Sdim NoItinerary>; 7655259698Sdim 7656259698Sdim def 8b4h : NeonI_2VMisc<0b0, U, 0b00, opcode, 7657259698Sdim (outs VPR64:$Rd), (ins VPR64:$Rn), 7658259698Sdim asmop # "\t$Rd.4h, $Rn.8b", 7659259698Sdim [(set (v4i16 VPR64:$Rd), 7660259698Sdim (v4i16 (Neon_Padd (v8i8 VPR64:$Rn))))], 7661259698Sdim NoItinerary>; 7662259698Sdim 7663259698Sdim def 8h4s : NeonI_2VMisc<0b1, U, 0b01, opcode, 7664259698Sdim (outs VPR128:$Rd), (ins VPR128:$Rn), 7665259698Sdim asmop # "\t$Rd.4s, $Rn.8h", 7666259698Sdim [(set (v4i32 VPR128:$Rd), 7667259698Sdim (v4i32 (Neon_Padd (v8i16 VPR128:$Rn))))], 7668259698Sdim NoItinerary>; 7669259698Sdim 7670259698Sdim def 4h2s : NeonI_2VMisc<0b0, U, 0b01, opcode, 7671259698Sdim (outs VPR64:$Rd), (ins VPR64:$Rn), 7672259698Sdim asmop # "\t$Rd.2s, $Rn.4h", 7673259698Sdim [(set (v2i32 VPR64:$Rd), 7674259698Sdim (v2i32 (Neon_Padd (v4i16 VPR64:$Rn))))], 7675259698Sdim NoItinerary>; 7676259698Sdim 7677259698Sdim def 4s2d : NeonI_2VMisc<0b1, U, 0b10, opcode, 7678259698Sdim (outs VPR128:$Rd), (ins VPR128:$Rn), 7679259698Sdim asmop # "\t$Rd.2d, $Rn.4s", 7680259698Sdim [(set (v2i64 VPR128:$Rd), 7681259698Sdim (v2i64 (Neon_Padd (v4i32 VPR128:$Rn))))], 7682259698Sdim NoItinerary>; 7683259698Sdim 7684259698Sdim def 2s1d : NeonI_2VMisc<0b0, U, 0b10, opcode, 7685259698Sdim (outs VPR64:$Rd), (ins VPR64:$Rn), 7686259698Sdim asmop # "\t$Rd.1d, $Rn.2s", 7687259698Sdim [(set (v1i64 VPR64:$Rd), 7688259698Sdim (v1i64 (Neon_Padd (v2i32 VPR64:$Rn))))], 7689259698Sdim NoItinerary>; 7690259698Sdim} 7691259698Sdim 7692259698Sdimdefm SADDLP : NeonI_PairwiseAdd<"saddlp", 0b0, 0b00010, 7693259698Sdim int_arm_neon_vpaddls>; 7694259698Sdimdefm UADDLP : NeonI_PairwiseAdd<"uaddlp", 0b1, 0b00010, 7695259698Sdim int_arm_neon_vpaddlu>; 7696259698Sdim 7697259698Sdimmulticlass NeonI_PairwiseAddAcc<string asmop, bit U, bits<5> opcode, 7698259698Sdim SDPatternOperator Neon_Padd> { 7699259698Sdim let Constraints = "$src = $Rd" in { 7700259698Sdim def 16b8h : NeonI_2VMisc<0b1, U, 0b00, opcode, 7701259698Sdim (outs VPR128:$Rd), (ins VPR128:$src, VPR128:$Rn), 7702259698Sdim asmop # "\t$Rd.8h, $Rn.16b", 7703259698Sdim [(set (v8i16 VPR128:$Rd), 7704259698Sdim (v8i16 (Neon_Padd 7705259698Sdim (v8i16 VPR128:$src), (v16i8 VPR128:$Rn))))], 7706259698Sdim NoItinerary>; 7707259698Sdim 7708259698Sdim def 8b4h : NeonI_2VMisc<0b0, U, 0b00, opcode, 7709259698Sdim (outs VPR64:$Rd), (ins VPR64:$src, VPR64:$Rn), 7710259698Sdim asmop # "\t$Rd.4h, $Rn.8b", 7711259698Sdim [(set (v4i16 VPR64:$Rd), 7712259698Sdim (v4i16 (Neon_Padd 7713259698Sdim (v4i16 VPR64:$src), (v8i8 VPR64:$Rn))))], 7714259698Sdim NoItinerary>; 7715259698Sdim 7716259698Sdim def 8h4s : NeonI_2VMisc<0b1, U, 0b01, opcode, 7717259698Sdim (outs VPR128:$Rd), (ins VPR128:$src, VPR128:$Rn), 7718259698Sdim asmop # "\t$Rd.4s, $Rn.8h", 7719259698Sdim [(set (v4i32 VPR128:$Rd), 7720259698Sdim (v4i32 (Neon_Padd 7721259698Sdim (v4i32 VPR128:$src), (v8i16 VPR128:$Rn))))], 7722259698Sdim NoItinerary>; 7723259698Sdim 7724259698Sdim def 4h2s : NeonI_2VMisc<0b0, U, 0b01, opcode, 7725259698Sdim (outs VPR64:$Rd), (ins VPR64:$src, VPR64:$Rn), 7726259698Sdim asmop # "\t$Rd.2s, $Rn.4h", 7727259698Sdim [(set (v2i32 VPR64:$Rd), 7728259698Sdim (v2i32 (Neon_Padd 7729259698Sdim (v2i32 VPR64:$src), (v4i16 VPR64:$Rn))))], 7730259698Sdim NoItinerary>; 7731259698Sdim 7732259698Sdim def 4s2d : NeonI_2VMisc<0b1, U, 0b10, opcode, 7733259698Sdim (outs VPR128:$Rd), (ins VPR128:$src, VPR128:$Rn), 7734259698Sdim asmop # "\t$Rd.2d, $Rn.4s", 7735259698Sdim [(set (v2i64 VPR128:$Rd), 7736259698Sdim (v2i64 (Neon_Padd 7737259698Sdim (v2i64 VPR128:$src), (v4i32 VPR128:$Rn))))], 7738259698Sdim NoItinerary>; 7739259698Sdim 7740259698Sdim def 2s1d : NeonI_2VMisc<0b0, U, 0b10, opcode, 7741259698Sdim (outs VPR64:$Rd), (ins VPR64:$src, VPR64:$Rn), 7742259698Sdim asmop # "\t$Rd.1d, $Rn.2s", 7743259698Sdim [(set (v1i64 VPR64:$Rd), 7744259698Sdim (v1i64 (Neon_Padd 7745259698Sdim (v1i64 VPR64:$src), (v2i32 VPR64:$Rn))))], 7746259698Sdim NoItinerary>; 7747259698Sdim } 7748259698Sdim} 7749259698Sdim 7750259698Sdimdefm SADALP : NeonI_PairwiseAddAcc<"sadalp", 0b0, 0b00110, 7751259698Sdim int_arm_neon_vpadals>; 7752259698Sdimdefm UADALP : NeonI_PairwiseAddAcc<"uadalp", 0b1, 0b00110, 7753259698Sdim int_arm_neon_vpadalu>; 7754259698Sdim 7755259698Sdimmulticlass NeonI_2VMisc_BHSDsize_1Arg<string asmop, bit U, bits<5> opcode> { 7756259698Sdim def 16b : NeonI_2VMisc<0b1, U, 0b00, opcode, 7757259698Sdim (outs VPR128:$Rd), (ins VPR128:$Rn), 7758259698Sdim asmop # "\t$Rd.16b, $Rn.16b", 7759259698Sdim [], NoItinerary>; 7760259698Sdim 7761259698Sdim def 8h : NeonI_2VMisc<0b1, U, 0b01, opcode, 7762259698Sdim (outs VPR128:$Rd), (ins VPR128:$Rn), 7763259698Sdim asmop # "\t$Rd.8h, $Rn.8h", 7764259698Sdim [], NoItinerary>; 7765259698Sdim 7766259698Sdim def 4s : NeonI_2VMisc<0b1, U, 0b10, opcode, 7767259698Sdim (outs VPR128:$Rd), (ins VPR128:$Rn), 7768259698Sdim asmop # "\t$Rd.4s, $Rn.4s", 7769259698Sdim [], NoItinerary>; 7770259698Sdim 7771259698Sdim def 2d : NeonI_2VMisc<0b1, U, 0b11, opcode, 7772259698Sdim (outs VPR128:$Rd), (ins VPR128:$Rn), 7773259698Sdim asmop # "\t$Rd.2d, $Rn.2d", 7774259698Sdim [], NoItinerary>; 7775259698Sdim 7776259698Sdim def 8b : NeonI_2VMisc<0b0, U, 0b00, opcode, 7777259698Sdim (outs VPR64:$Rd), (ins VPR64:$Rn), 7778259698Sdim asmop # "\t$Rd.8b, $Rn.8b", 7779259698Sdim [], NoItinerary>; 7780259698Sdim 7781259698Sdim def 4h : NeonI_2VMisc<0b0, U, 0b01, opcode, 7782259698Sdim (outs VPR64:$Rd), (ins VPR64:$Rn), 7783259698Sdim asmop # "\t$Rd.4h, $Rn.4h", 7784259698Sdim [], NoItinerary>; 7785259698Sdim 7786259698Sdim def 2s : NeonI_2VMisc<0b0, U, 0b10, opcode, 7787259698Sdim (outs VPR64:$Rd), (ins VPR64:$Rn), 7788259698Sdim asmop # "\t$Rd.2s, $Rn.2s", 7789259698Sdim [], NoItinerary>; 7790259698Sdim} 7791259698Sdim 7792259698Sdimdefm SQABS : NeonI_2VMisc_BHSDsize_1Arg<"sqabs", 0b0, 0b00111>; 7793259698Sdimdefm SQNEG : NeonI_2VMisc_BHSDsize_1Arg<"sqneg", 0b1, 0b00111>; 7794259698Sdimdefm ABS : NeonI_2VMisc_BHSDsize_1Arg<"abs", 0b0, 0b01011>; 7795259698Sdimdefm NEG : NeonI_2VMisc_BHSDsize_1Arg<"neg", 0b1, 0b01011>; 7796259698Sdim 7797259698Sdimmulticlass NeonI_2VMisc_BHSD_1Arg_Pattern<string Prefix, 7798259698Sdim SDPatternOperator Neon_Op> { 7799259698Sdim def : Pat<(v16i8 (Neon_Op (v16i8 VPR128:$Rn))), 7800259698Sdim (v16i8 (!cast<Instruction>(Prefix # 16b) (v16i8 VPR128:$Rn)))>; 7801259698Sdim 7802259698Sdim def : Pat<(v8i16 (Neon_Op (v8i16 VPR128:$Rn))), 7803259698Sdim (v8i16 (!cast<Instruction>(Prefix # 8h) (v8i16 VPR128:$Rn)))>; 7804259698Sdim 7805259698Sdim def : Pat<(v4i32 (Neon_Op (v4i32 VPR128:$Rn))), 7806259698Sdim (v4i32 (!cast<Instruction>(Prefix # 4s) (v4i32 VPR128:$Rn)))>; 7807259698Sdim 7808259698Sdim def : Pat<(v2i64 (Neon_Op (v2i64 VPR128:$Rn))), 7809259698Sdim (v2i64 (!cast<Instruction>(Prefix # 2d) (v2i64 VPR128:$Rn)))>; 7810259698Sdim 7811259698Sdim def : Pat<(v8i8 (Neon_Op (v8i8 VPR64:$Rn))), 7812259698Sdim (v8i8 (!cast<Instruction>(Prefix # 8b) (v8i8 VPR64:$Rn)))>; 7813259698Sdim 7814259698Sdim def : Pat<(v4i16 (Neon_Op (v4i16 VPR64:$Rn))), 7815259698Sdim (v4i16 (!cast<Instruction>(Prefix # 4h) (v4i16 VPR64:$Rn)))>; 7816259698Sdim 7817259698Sdim def : Pat<(v2i32 (Neon_Op (v2i32 VPR64:$Rn))), 7818259698Sdim (v2i32 (!cast<Instruction>(Prefix # 2s) (v2i32 VPR64:$Rn)))>; 7819259698Sdim} 7820259698Sdim 7821259698Sdimdefm : NeonI_2VMisc_BHSD_1Arg_Pattern<"SQABS", int_arm_neon_vqabs>; 7822259698Sdimdefm : NeonI_2VMisc_BHSD_1Arg_Pattern<"SQNEG", int_arm_neon_vqneg>; 7823259698Sdimdefm : NeonI_2VMisc_BHSD_1Arg_Pattern<"ABS", int_arm_neon_vabs>; 7824259698Sdim 7825259698Sdimdef : Pat<(v16i8 (sub 7826259698Sdim (v16i8 Neon_AllZero), 7827259698Sdim (v16i8 VPR128:$Rn))), 7828259698Sdim (v16i8 (NEG16b (v16i8 VPR128:$Rn)))>; 7829259698Sdimdef : Pat<(v8i8 (sub 7830259698Sdim (v8i8 Neon_AllZero), 7831259698Sdim (v8i8 VPR64:$Rn))), 7832259698Sdim (v8i8 (NEG8b (v8i8 VPR64:$Rn)))>; 7833259698Sdimdef : Pat<(v8i16 (sub 7834259698Sdim (v8i16 (bitconvert (v16i8 Neon_AllZero))), 7835259698Sdim (v8i16 VPR128:$Rn))), 7836259698Sdim (v8i16 (NEG8h (v8i16 VPR128:$Rn)))>; 7837259698Sdimdef : Pat<(v4i16 (sub 7838259698Sdim (v4i16 (bitconvert (v8i8 Neon_AllZero))), 7839259698Sdim (v4i16 VPR64:$Rn))), 7840259698Sdim (v4i16 (NEG4h (v4i16 VPR64:$Rn)))>; 7841259698Sdimdef : Pat<(v4i32 (sub 7842259698Sdim (v4i32 (bitconvert (v16i8 Neon_AllZero))), 7843259698Sdim (v4i32 VPR128:$Rn))), 7844259698Sdim (v4i32 (NEG4s (v4i32 VPR128:$Rn)))>; 7845259698Sdimdef : Pat<(v2i32 (sub 7846259698Sdim (v2i32 (bitconvert (v8i8 Neon_AllZero))), 7847259698Sdim (v2i32 VPR64:$Rn))), 7848259698Sdim (v2i32 (NEG2s (v2i32 VPR64:$Rn)))>; 7849259698Sdimdef : Pat<(v2i64 (sub 7850259698Sdim (v2i64 (bitconvert (v16i8 Neon_AllZero))), 7851259698Sdim (v2i64 VPR128:$Rn))), 7852259698Sdim (v2i64 (NEG2d (v2i64 VPR128:$Rn)))>; 7853259698Sdim 7854259698Sdimmulticlass NeonI_2VMisc_BHSDsize_2Args<string asmop, bit U, bits<5> opcode> { 7855259698Sdim let Constraints = "$src = $Rd" in { 7856259698Sdim def 16b : NeonI_2VMisc<0b1, U, 0b00, opcode, 7857259698Sdim (outs VPR128:$Rd), (ins VPR128:$src, VPR128:$Rn), 7858259698Sdim asmop # "\t$Rd.16b, $Rn.16b", 7859259698Sdim [], NoItinerary>; 7860259698Sdim 7861259698Sdim def 8h : NeonI_2VMisc<0b1, U, 0b01, opcode, 7862259698Sdim (outs VPR128:$Rd), (ins VPR128:$src, VPR128:$Rn), 7863259698Sdim asmop # "\t$Rd.8h, $Rn.8h", 7864259698Sdim [], NoItinerary>; 7865259698Sdim 7866259698Sdim def 4s : NeonI_2VMisc<0b1, U, 0b10, opcode, 7867259698Sdim (outs VPR128:$Rd), (ins VPR128:$src, VPR128:$Rn), 7868259698Sdim asmop # "\t$Rd.4s, $Rn.4s", 7869259698Sdim [], NoItinerary>; 7870259698Sdim 7871259698Sdim def 2d : NeonI_2VMisc<0b1, U, 0b11, opcode, 7872259698Sdim (outs VPR128:$Rd), (ins VPR128:$src, VPR128:$Rn), 7873259698Sdim asmop # "\t$Rd.2d, $Rn.2d", 7874259698Sdim [], NoItinerary>; 7875259698Sdim 7876259698Sdim def 8b : NeonI_2VMisc<0b0, U, 0b00, opcode, 7877259698Sdim (outs VPR64:$Rd), (ins VPR64:$src, VPR64:$Rn), 7878259698Sdim asmop # "\t$Rd.8b, $Rn.8b", 7879259698Sdim [], NoItinerary>; 7880259698Sdim 7881259698Sdim def 4h : NeonI_2VMisc<0b0, U, 0b01, opcode, 7882259698Sdim (outs VPR64:$Rd), (ins VPR64:$src, VPR64:$Rn), 7883259698Sdim asmop # "\t$Rd.4h, $Rn.4h", 7884259698Sdim [], NoItinerary>; 7885259698Sdim 7886259698Sdim def 2s : NeonI_2VMisc<0b0, U, 0b10, opcode, 7887259698Sdim (outs VPR64:$Rd), (ins VPR64:$src, VPR64:$Rn), 7888259698Sdim asmop # "\t$Rd.2s, $Rn.2s", 7889259698Sdim [], NoItinerary>; 7890259698Sdim } 7891259698Sdim} 7892259698Sdim 7893259698Sdimdefm SUQADD : NeonI_2VMisc_BHSDsize_2Args<"suqadd", 0b0, 0b00011>; 7894259698Sdimdefm USQADD : NeonI_2VMisc_BHSDsize_2Args<"usqadd", 0b1, 0b00011>; 7895259698Sdim 7896259698Sdimmulticlass NeonI_2VMisc_BHSD_2Args_Pattern<string Prefix, 7897259698Sdim SDPatternOperator Neon_Op> { 7898259698Sdim def : Pat<(v16i8 (Neon_Op (v16i8 VPR128:$src), (v16i8 VPR128:$Rn))), 7899259698Sdim (v16i8 (!cast<Instruction>(Prefix # 16b) 7900259698Sdim (v16i8 VPR128:$src), (v16i8 VPR128:$Rn)))>; 7901259698Sdim 7902259698Sdim def : Pat<(v8i16 (Neon_Op (v8i16 VPR128:$src), (v8i16 VPR128:$Rn))), 7903259698Sdim (v8i16 (!cast<Instruction>(Prefix # 8h) 7904259698Sdim (v8i16 VPR128:$src), (v8i16 VPR128:$Rn)))>; 7905259698Sdim 7906259698Sdim def : Pat<(v4i32 (Neon_Op (v4i32 VPR128:$src), (v4i32 VPR128:$Rn))), 7907259698Sdim (v4i32 (!cast<Instruction>(Prefix # 4s) 7908259698Sdim (v4i32 VPR128:$src), (v4i32 VPR128:$Rn)))>; 7909259698Sdim 7910259698Sdim def : Pat<(v2i64 (Neon_Op (v2i64 VPR128:$src), (v2i64 VPR128:$Rn))), 7911259698Sdim (v2i64 (!cast<Instruction>(Prefix # 2d) 7912259698Sdim (v2i64 VPR128:$src), (v2i64 VPR128:$Rn)))>; 7913259698Sdim 7914259698Sdim def : Pat<(v8i8 (Neon_Op (v8i8 VPR64:$src), (v8i8 VPR64:$Rn))), 7915259698Sdim (v8i8 (!cast<Instruction>(Prefix # 8b) 7916259698Sdim (v8i8 VPR64:$src), (v8i8 VPR64:$Rn)))>; 7917259698Sdim 7918259698Sdim def : Pat<(v4i16 (Neon_Op (v4i16 VPR64:$src), (v4i16 VPR64:$Rn))), 7919259698Sdim (v4i16 (!cast<Instruction>(Prefix # 4h) 7920259698Sdim (v4i16 VPR64:$src), (v4i16 VPR64:$Rn)))>; 7921259698Sdim 7922259698Sdim def : Pat<(v2i32 (Neon_Op (v2i32 VPR64:$src), (v2i32 VPR64:$Rn))), 7923259698Sdim (v2i32 (!cast<Instruction>(Prefix # 2s) 7924259698Sdim (v2i32 VPR64:$src), (v2i32 VPR64:$Rn)))>; 7925259698Sdim} 7926259698Sdim 7927259698Sdimdefm : NeonI_2VMisc_BHSD_2Args_Pattern<"SUQADD", int_aarch64_neon_suqadd>; 7928259698Sdimdefm : NeonI_2VMisc_BHSD_2Args_Pattern<"USQADD", int_aarch64_neon_usqadd>; 7929259698Sdim 7930259698Sdimmulticlass NeonI_2VMisc_BHSsizes<string asmop, bit U, 7931259698Sdim SDPatternOperator Neon_Op> { 7932259698Sdim def 16b : NeonI_2VMisc<0b1, U, 0b00, 0b00100, 7933259698Sdim (outs VPR128:$Rd), (ins VPR128:$Rn), 7934259698Sdim asmop # "\t$Rd.16b, $Rn.16b", 7935259698Sdim [(set (v16i8 VPR128:$Rd), 7936259698Sdim (v16i8 (Neon_Op (v16i8 VPR128:$Rn))))], 7937259698Sdim NoItinerary>; 7938259698Sdim 7939259698Sdim def 8h : NeonI_2VMisc<0b1, U, 0b01, 0b00100, 7940259698Sdim (outs VPR128:$Rd), (ins VPR128:$Rn), 7941259698Sdim asmop # "\t$Rd.8h, $Rn.8h", 7942259698Sdim [(set (v8i16 VPR128:$Rd), 7943259698Sdim (v8i16 (Neon_Op (v8i16 VPR128:$Rn))))], 7944259698Sdim NoItinerary>; 7945259698Sdim 7946259698Sdim def 4s : NeonI_2VMisc<0b1, U, 0b10, 0b00100, 7947259698Sdim (outs VPR128:$Rd), (ins VPR128:$Rn), 7948259698Sdim asmop # "\t$Rd.4s, $Rn.4s", 7949259698Sdim [(set (v4i32 VPR128:$Rd), 7950259698Sdim (v4i32 (Neon_Op (v4i32 VPR128:$Rn))))], 7951259698Sdim NoItinerary>; 7952259698Sdim 7953259698Sdim def 8b : NeonI_2VMisc<0b0, U, 0b00, 0b00100, 7954259698Sdim (outs VPR64:$Rd), (ins VPR64:$Rn), 7955259698Sdim asmop # "\t$Rd.8b, $Rn.8b", 7956259698Sdim [(set (v8i8 VPR64:$Rd), 7957259698Sdim (v8i8 (Neon_Op (v8i8 VPR64:$Rn))))], 7958259698Sdim NoItinerary>; 7959259698Sdim 7960259698Sdim def 4h : NeonI_2VMisc<0b0, U, 0b01, 0b00100, 7961259698Sdim (outs VPR64:$Rd), (ins VPR64:$Rn), 7962259698Sdim asmop # "\t$Rd.4h, $Rn.4h", 7963259698Sdim [(set (v4i16 VPR64:$Rd), 7964259698Sdim (v4i16 (Neon_Op (v4i16 VPR64:$Rn))))], 7965259698Sdim NoItinerary>; 7966259698Sdim 7967259698Sdim def 2s : NeonI_2VMisc<0b0, U, 0b10, 0b00100, 7968259698Sdim (outs VPR64:$Rd), (ins VPR64:$Rn), 7969259698Sdim asmop # "\t$Rd.2s, $Rn.2s", 7970259698Sdim [(set (v2i32 VPR64:$Rd), 7971259698Sdim (v2i32 (Neon_Op (v2i32 VPR64:$Rn))))], 7972259698Sdim NoItinerary>; 7973259698Sdim} 7974259698Sdim 7975259698Sdimdefm CLS : NeonI_2VMisc_BHSsizes<"cls", 0b0, int_arm_neon_vcls>; 7976259698Sdimdefm CLZ : NeonI_2VMisc_BHSsizes<"clz", 0b1, ctlz>; 7977259698Sdim 7978259698Sdimmulticlass NeonI_2VMisc_Bsize<string asmop, bit U, bits<2> size, 7979259698Sdim bits<5> Opcode> { 7980259698Sdim def 16b : NeonI_2VMisc<0b1, U, size, Opcode, 7981259698Sdim (outs VPR128:$Rd), (ins VPR128:$Rn), 7982259698Sdim asmop # "\t$Rd.16b, $Rn.16b", 7983259698Sdim [], NoItinerary>; 7984259698Sdim 7985259698Sdim def 8b : NeonI_2VMisc<0b0, U, size, Opcode, 7986259698Sdim (outs VPR64:$Rd), (ins VPR64:$Rn), 7987259698Sdim asmop # "\t$Rd.8b, $Rn.8b", 7988259698Sdim [], NoItinerary>; 7989259698Sdim} 7990259698Sdim 7991259698Sdimdefm CNT : NeonI_2VMisc_Bsize<"cnt", 0b0, 0b00, 0b00101>; 7992259698Sdimdefm NOT : NeonI_2VMisc_Bsize<"not", 0b1, 0b00, 0b00101>; 7993259698Sdimdefm RBIT : NeonI_2VMisc_Bsize<"rbit", 0b1, 0b01, 0b00101>; 7994259698Sdim 7995259698Sdimdef : NeonInstAlias<"mvn $Rd.16b, $Rn.16b", 7996259698Sdim (NOT16b VPR128:$Rd, VPR128:$Rn), 0>; 7997259698Sdimdef : NeonInstAlias<"mvn $Rd.8b, $Rn.8b", 7998259698Sdim (NOT8b VPR64:$Rd, VPR64:$Rn), 0>; 7999259698Sdim 8000259698Sdimdef : Pat<(v16i8 (ctpop (v16i8 VPR128:$Rn))), 8001259698Sdim (v16i8 (CNT16b (v16i8 VPR128:$Rn)))>; 8002259698Sdimdef : Pat<(v8i8 (ctpop (v8i8 VPR64:$Rn))), 8003259698Sdim (v8i8 (CNT8b (v8i8 VPR64:$Rn)))>; 8004259698Sdim 8005259698Sdimdef : Pat<(v16i8 (xor 8006259698Sdim (v16i8 VPR128:$Rn), 8007259698Sdim (v16i8 Neon_AllOne))), 8008259698Sdim (v16i8 (NOT16b (v16i8 VPR128:$Rn)))>; 8009259698Sdimdef : Pat<(v8i8 (xor 8010259698Sdim (v8i8 VPR64:$Rn), 8011259698Sdim (v8i8 Neon_AllOne))), 8012259698Sdim (v8i8 (NOT8b (v8i8 VPR64:$Rn)))>; 8013259698Sdimdef : Pat<(v8i16 (xor 8014259698Sdim (v8i16 VPR128:$Rn), 8015259698Sdim (v8i16 (bitconvert (v16i8 Neon_AllOne))))), 8016259698Sdim (NOT16b VPR128:$Rn)>; 8017259698Sdimdef : Pat<(v4i16 (xor 8018259698Sdim (v4i16 VPR64:$Rn), 8019259698Sdim (v4i16 (bitconvert (v8i8 Neon_AllOne))))), 8020259698Sdim (NOT8b VPR64:$Rn)>; 8021259698Sdimdef : Pat<(v4i32 (xor 8022259698Sdim (v4i32 VPR128:$Rn), 8023259698Sdim (v4i32 (bitconvert (v16i8 Neon_AllOne))))), 8024259698Sdim (NOT16b VPR128:$Rn)>; 8025259698Sdimdef : Pat<(v2i32 (xor 8026259698Sdim (v2i32 VPR64:$Rn), 8027259698Sdim (v2i32 (bitconvert (v8i8 Neon_AllOne))))), 8028259698Sdim (NOT8b VPR64:$Rn)>; 8029259698Sdimdef : Pat<(v2i64 (xor 8030259698Sdim (v2i64 VPR128:$Rn), 8031259698Sdim (v2i64 (bitconvert (v16i8 Neon_AllOne))))), 8032259698Sdim (NOT16b VPR128:$Rn)>; 8033259698Sdim 8034259698Sdimdef : Pat<(v16i8 (int_aarch64_neon_rbit (v16i8 VPR128:$Rn))), 8035259698Sdim (v16i8 (RBIT16b (v16i8 VPR128:$Rn)))>; 8036259698Sdimdef : Pat<(v8i8 (int_aarch64_neon_rbit (v8i8 VPR64:$Rn))), 8037259698Sdim (v8i8 (RBIT8b (v8i8 VPR64:$Rn)))>; 8038259698Sdim 8039259698Sdimmulticlass NeonI_2VMisc_SDsizes<string asmop, bit U, bits<5> opcode, 8040259698Sdim SDPatternOperator Neon_Op> { 8041259698Sdim def 4s : NeonI_2VMisc<0b1, U, 0b10, opcode, 8042259698Sdim (outs VPR128:$Rd), (ins VPR128:$Rn), 8043259698Sdim asmop # "\t$Rd.4s, $Rn.4s", 8044259698Sdim [(set (v4f32 VPR128:$Rd), 8045259698Sdim (v4f32 (Neon_Op (v4f32 VPR128:$Rn))))], 8046259698Sdim NoItinerary>; 8047259698Sdim 8048259698Sdim def 2d : NeonI_2VMisc<0b1, U, 0b11, opcode, 8049259698Sdim (outs VPR128:$Rd), (ins VPR128:$Rn), 8050259698Sdim asmop # "\t$Rd.2d, $Rn.2d", 8051259698Sdim [(set (v2f64 VPR128:$Rd), 8052259698Sdim (v2f64 (Neon_Op (v2f64 VPR128:$Rn))))], 8053259698Sdim NoItinerary>; 8054259698Sdim 8055259698Sdim def 2s : NeonI_2VMisc<0b0, U, 0b10, opcode, 8056259698Sdim (outs VPR64:$Rd), (ins VPR64:$Rn), 8057259698Sdim asmop # "\t$Rd.2s, $Rn.2s", 8058259698Sdim [(set (v2f32 VPR64:$Rd), 8059259698Sdim (v2f32 (Neon_Op (v2f32 VPR64:$Rn))))], 8060259698Sdim NoItinerary>; 8061259698Sdim} 8062259698Sdim 8063259698Sdimdefm FABS : NeonI_2VMisc_SDsizes<"fabs", 0b0, 0b01111, fabs>; 8064259698Sdimdefm FNEG : NeonI_2VMisc_SDsizes<"fneg", 0b1, 0b01111, fneg>; 8065259698Sdim 8066259698Sdimmulticlass NeonI_2VMisc_HSD_Narrow<string asmop, bit U, bits<5> opcode> { 8067259698Sdim def 8h8b : NeonI_2VMisc<0b0, U, 0b00, opcode, 8068259698Sdim (outs VPR64:$Rd), (ins VPR128:$Rn), 8069259698Sdim asmop # "\t$Rd.8b, $Rn.8h", 8070259698Sdim [], NoItinerary>; 8071259698Sdim 8072259698Sdim def 4s4h : NeonI_2VMisc<0b0, U, 0b01, opcode, 8073259698Sdim (outs VPR64:$Rd), (ins VPR128:$Rn), 8074259698Sdim asmop # "\t$Rd.4h, $Rn.4s", 8075259698Sdim [], NoItinerary>; 8076259698Sdim 8077259698Sdim def 2d2s : NeonI_2VMisc<0b0, U, 0b10, opcode, 8078259698Sdim (outs VPR64:$Rd), (ins VPR128:$Rn), 8079259698Sdim asmop # "\t$Rd.2s, $Rn.2d", 8080259698Sdim [], NoItinerary>; 8081259698Sdim 8082259698Sdim let Constraints = "$Rd = $src" in { 8083259698Sdim def 8h16b : NeonI_2VMisc<0b1, U, 0b00, opcode, 8084259698Sdim (outs VPR128:$Rd), (ins VPR128:$src, VPR128:$Rn), 8085259698Sdim asmop # "2\t$Rd.16b, $Rn.8h", 8086259698Sdim [], NoItinerary>; 8087259698Sdim 8088259698Sdim def 4s8h : NeonI_2VMisc<0b1, U, 0b01, opcode, 8089259698Sdim (outs VPR128:$Rd), (ins VPR128:$src, VPR128:$Rn), 8090259698Sdim asmop # "2\t$Rd.8h, $Rn.4s", 8091259698Sdim [], NoItinerary>; 8092259698Sdim 8093259698Sdim def 2d4s : NeonI_2VMisc<0b1, U, 0b10, opcode, 8094259698Sdim (outs VPR128:$Rd), (ins VPR128:$src, VPR128:$Rn), 8095259698Sdim asmop # "2\t$Rd.4s, $Rn.2d", 8096259698Sdim [], NoItinerary>; 8097259698Sdim } 8098259698Sdim} 8099259698Sdim 8100259698Sdimdefm XTN : NeonI_2VMisc_HSD_Narrow<"xtn", 0b0, 0b10010>; 8101259698Sdimdefm SQXTUN : NeonI_2VMisc_HSD_Narrow<"sqxtun", 0b1, 0b10010>; 8102259698Sdimdefm SQXTN : NeonI_2VMisc_HSD_Narrow<"sqxtn", 0b0, 0b10100>; 8103259698Sdimdefm UQXTN : NeonI_2VMisc_HSD_Narrow<"uqxtn", 0b1, 0b10100>; 8104259698Sdim 8105259698Sdimmulticlass NeonI_2VMisc_Narrow_Patterns<string Prefix, 8106259698Sdim SDPatternOperator Neon_Op> { 8107259698Sdim def : Pat<(v8i8 (Neon_Op (v8i16 VPR128:$Rn))), 8108259698Sdim (v8i8 (!cast<Instruction>(Prefix # 8h8b) (v8i16 VPR128:$Rn)))>; 8109259698Sdim 8110259698Sdim def : Pat<(v4i16 (Neon_Op (v4i32 VPR128:$Rn))), 8111259698Sdim (v4i16 (!cast<Instruction>(Prefix # 4s4h) (v4i32 VPR128:$Rn)))>; 8112259698Sdim 8113259698Sdim def : Pat<(v2i32 (Neon_Op (v2i64 VPR128:$Rn))), 8114259698Sdim (v2i32 (!cast<Instruction>(Prefix # 2d2s) (v2i64 VPR128:$Rn)))>; 8115259698Sdim 8116259698Sdim def : Pat<(v16i8 (concat_vectors 8117259698Sdim (v8i8 VPR64:$src), 8118259698Sdim (v8i8 (Neon_Op (v8i16 VPR128:$Rn))))), 8119259698Sdim (!cast<Instruction>(Prefix # 8h16b) 8120259698Sdim (SUBREG_TO_REG (i32 0), VPR64:$src, sub_64), 8121259698Sdim VPR128:$Rn)>; 8122259698Sdim 8123259698Sdim def : Pat<(v8i16 (concat_vectors 8124259698Sdim (v4i16 VPR64:$src), 8125259698Sdim (v4i16 (Neon_Op (v4i32 VPR128:$Rn))))), 8126259698Sdim (!cast<Instruction>(Prefix # 4s8h) 8127259698Sdim (SUBREG_TO_REG (i32 0), VPR64:$src, sub_64), 8128259698Sdim VPR128:$Rn)>; 8129259698Sdim 8130259698Sdim def : Pat<(v4i32 (concat_vectors 8131259698Sdim (v2i32 VPR64:$src), 8132259698Sdim (v2i32 (Neon_Op (v2i64 VPR128:$Rn))))), 8133259698Sdim (!cast<Instruction>(Prefix # 2d4s) 8134259698Sdim (SUBREG_TO_REG (i32 0), VPR64:$src, sub_64), 8135259698Sdim VPR128:$Rn)>; 8136259698Sdim} 8137259698Sdim 8138259698Sdimdefm : NeonI_2VMisc_Narrow_Patterns<"XTN", trunc>; 8139259698Sdimdefm : NeonI_2VMisc_Narrow_Patterns<"SQXTUN", int_arm_neon_vqmovnsu>; 8140259698Sdimdefm : NeonI_2VMisc_Narrow_Patterns<"SQXTN", int_arm_neon_vqmovns>; 8141259698Sdimdefm : NeonI_2VMisc_Narrow_Patterns<"UQXTN", int_arm_neon_vqmovnu>; 8142259698Sdim 8143259698Sdimmulticlass NeonI_2VMisc_SHIFT<string asmop, bit U, bits<5> opcode> { 8144259698Sdim let DecoderMethod = "DecodeSHLLInstruction" in { 8145259698Sdim def 8b8h : NeonI_2VMisc<0b0, U, 0b00, opcode, 8146259698Sdim (outs VPR128:$Rd), 8147259698Sdim (ins VPR64:$Rn, uimm_exact8:$Imm), 8148259698Sdim asmop # "\t$Rd.8h, $Rn.8b, $Imm", 8149259698Sdim [], NoItinerary>; 8150259698Sdim 8151259698Sdim def 4h4s : NeonI_2VMisc<0b0, U, 0b01, opcode, 8152259698Sdim (outs VPR128:$Rd), 8153259698Sdim (ins VPR64:$Rn, uimm_exact16:$Imm), 8154259698Sdim asmop # "\t$Rd.4s, $Rn.4h, $Imm", 8155259698Sdim [], NoItinerary>; 8156259698Sdim 8157259698Sdim def 2s2d : NeonI_2VMisc<0b0, U, 0b10, opcode, 8158259698Sdim (outs VPR128:$Rd), 8159259698Sdim (ins VPR64:$Rn, uimm_exact32:$Imm), 8160259698Sdim asmop # "\t$Rd.2d, $Rn.2s, $Imm", 8161259698Sdim [], NoItinerary>; 8162259698Sdim 8163259698Sdim def 16b8h : NeonI_2VMisc<0b1, U, 0b00, opcode, 8164259698Sdim (outs VPR128:$Rd), 8165259698Sdim (ins VPR128:$Rn, uimm_exact8:$Imm), 8166259698Sdim asmop # "2\t$Rd.8h, $Rn.16b, $Imm", 8167259698Sdim [], NoItinerary>; 8168259698Sdim 8169259698Sdim def 8h4s : NeonI_2VMisc<0b1, U, 0b01, opcode, 8170259698Sdim (outs VPR128:$Rd), 8171259698Sdim (ins VPR128:$Rn, uimm_exact16:$Imm), 8172259698Sdim asmop # "2\t$Rd.4s, $Rn.8h, $Imm", 8173259698Sdim [], NoItinerary>; 8174259698Sdim 8175259698Sdim def 4s2d : NeonI_2VMisc<0b1, U, 0b10, opcode, 8176259698Sdim (outs VPR128:$Rd), 8177259698Sdim (ins VPR128:$Rn, uimm_exact32:$Imm), 8178259698Sdim asmop # "2\t$Rd.2d, $Rn.4s, $Imm", 8179259698Sdim [], NoItinerary>; 8180259698Sdim } 8181259698Sdim} 8182259698Sdim 8183259698Sdimdefm SHLL : NeonI_2VMisc_SHIFT<"shll", 0b1, 0b10011>; 8184259698Sdim 8185259698Sdimclass NeonI_SHLL_Patterns<ValueType OpTy, ValueType DesTy, 8186259698Sdim SDPatternOperator ExtOp, Operand Neon_Imm, 8187259698Sdim string suffix> 8188259698Sdim : Pat<(DesTy (shl 8189259698Sdim (DesTy (ExtOp (OpTy VPR64:$Rn))), 8190259698Sdim (DesTy (Neon_vdup 8191259698Sdim (i32 Neon_Imm:$Imm))))), 8192259698Sdim (!cast<Instruction>("SHLL" # suffix) VPR64:$Rn, Neon_Imm:$Imm)>; 8193259698Sdim 8194259698Sdimclass NeonI_SHLL_High_Patterns<ValueType OpTy, ValueType DesTy, 8195259698Sdim SDPatternOperator ExtOp, Operand Neon_Imm, 8196259698Sdim string suffix, PatFrag GetHigh> 8197259698Sdim : Pat<(DesTy (shl 8198259698Sdim (DesTy (ExtOp 8199259698Sdim (OpTy (GetHigh VPR128:$Rn)))), 8200259698Sdim (DesTy (Neon_vdup 8201259698Sdim (i32 Neon_Imm:$Imm))))), 8202259698Sdim (!cast<Instruction>("SHLL" # suffix) VPR128:$Rn, Neon_Imm:$Imm)>; 8203259698Sdim 8204259698Sdimdef : NeonI_SHLL_Patterns<v8i8, v8i16, zext, uimm_exact8, "8b8h">; 8205259698Sdimdef : NeonI_SHLL_Patterns<v8i8, v8i16, sext, uimm_exact8, "8b8h">; 8206259698Sdimdef : NeonI_SHLL_Patterns<v4i16, v4i32, zext, uimm_exact16, "4h4s">; 8207259698Sdimdef : NeonI_SHLL_Patterns<v4i16, v4i32, sext, uimm_exact16, "4h4s">; 8208259698Sdimdef : NeonI_SHLL_Patterns<v2i32, v2i64, zext, uimm_exact32, "2s2d">; 8209259698Sdimdef : NeonI_SHLL_Patterns<v2i32, v2i64, sext, uimm_exact32, "2s2d">; 8210259698Sdimdef : NeonI_SHLL_High_Patterns<v8i8, v8i16, zext, uimm_exact8, "16b8h", 8211259698Sdim Neon_High16B>; 8212259698Sdimdef : NeonI_SHLL_High_Patterns<v8i8, v8i16, sext, uimm_exact8, "16b8h", 8213259698Sdim Neon_High16B>; 8214259698Sdimdef : NeonI_SHLL_High_Patterns<v4i16, v4i32, zext, uimm_exact16, "8h4s", 8215259698Sdim Neon_High8H>; 8216259698Sdimdef : NeonI_SHLL_High_Patterns<v4i16, v4i32, sext, uimm_exact16, "8h4s", 8217259698Sdim Neon_High8H>; 8218259698Sdimdef : NeonI_SHLL_High_Patterns<v2i32, v2i64, zext, uimm_exact32, "4s2d", 8219259698Sdim Neon_High4S>; 8220259698Sdimdef : NeonI_SHLL_High_Patterns<v2i32, v2i64, sext, uimm_exact32, "4s2d", 8221259698Sdim Neon_High4S>; 8222259698Sdim 8223259698Sdimmulticlass NeonI_2VMisc_SD_Narrow<string asmop, bit U, bits<5> opcode> { 8224259698Sdim def 4s4h : NeonI_2VMisc<0b0, U, 0b00, opcode, 8225259698Sdim (outs VPR64:$Rd), (ins VPR128:$Rn), 8226259698Sdim asmop # "\t$Rd.4h, $Rn.4s", 8227259698Sdim [], NoItinerary>; 8228259698Sdim 8229259698Sdim def 2d2s : NeonI_2VMisc<0b0, U, 0b01, opcode, 8230259698Sdim (outs VPR64:$Rd), (ins VPR128:$Rn), 8231259698Sdim asmop # "\t$Rd.2s, $Rn.2d", 8232259698Sdim [], NoItinerary>; 8233259698Sdim 8234259698Sdim let Constraints = "$src = $Rd" in { 8235259698Sdim def 4s8h : NeonI_2VMisc<0b1, U, 0b00, opcode, 8236259698Sdim (outs VPR128:$Rd), (ins VPR128:$src, VPR128:$Rn), 8237259698Sdim asmop # "2\t$Rd.8h, $Rn.4s", 8238259698Sdim [], NoItinerary>; 8239259698Sdim 8240259698Sdim def 2d4s : NeonI_2VMisc<0b1, U, 0b01, opcode, 8241259698Sdim (outs VPR128:$Rd), (ins VPR128:$src, VPR128:$Rn), 8242259698Sdim asmop # "2\t$Rd.4s, $Rn.2d", 8243259698Sdim [], NoItinerary>; 8244259698Sdim } 8245259698Sdim} 8246259698Sdim 8247259698Sdimdefm FCVTN : NeonI_2VMisc_SD_Narrow<"fcvtn", 0b0, 0b10110>; 8248259698Sdim 8249259698Sdimmulticlass NeonI_2VMisc_Narrow_Pattern<string prefix, 8250259698Sdim SDPatternOperator f32_to_f16_Op, 8251259698Sdim SDPatternOperator f64_to_f32_Op> { 8252259698Sdim 8253259698Sdim def : Pat<(v4i16 (f32_to_f16_Op (v4f32 VPR128:$Rn))), 8254259698Sdim (!cast<Instruction>(prefix # "4s4h") (v4f32 VPR128:$Rn))>; 8255259698Sdim 8256259698Sdim def : Pat<(v8i16 (concat_vectors 8257259698Sdim (v4i16 VPR64:$src), 8258259698Sdim (v4i16 (f32_to_f16_Op (v4f32 VPR128:$Rn))))), 8259259698Sdim (!cast<Instruction>(prefix # "4s8h") 8260259698Sdim (v4f32 (SUBREG_TO_REG (i32 0), VPR64:$src, sub_64)), 8261259698Sdim (v4f32 VPR128:$Rn))>; 8262259698Sdim 8263259698Sdim def : Pat<(v2f32 (f64_to_f32_Op (v2f64 VPR128:$Rn))), 8264259698Sdim (!cast<Instruction>(prefix # "2d2s") (v2f64 VPR128:$Rn))>; 8265259698Sdim 8266259698Sdim def : Pat<(v4f32 (concat_vectors 8267259698Sdim (v2f32 VPR64:$src), 8268259698Sdim (v2f32 (f64_to_f32_Op (v2f64 VPR128:$Rn))))), 8269259698Sdim (!cast<Instruction>(prefix # "2d4s") 8270259698Sdim (v4f32 (SUBREG_TO_REG (i32 0), VPR64:$src, sub_64)), 8271259698Sdim (v2f64 VPR128:$Rn))>; 8272259698Sdim} 8273259698Sdim 8274259698Sdimdefm : NeonI_2VMisc_Narrow_Pattern<"FCVTN", int_arm_neon_vcvtfp2hf, fround>; 8275259698Sdim 8276259698Sdimmulticlass NeonI_2VMisc_D_Narrow<string asmop, string prefix, bit U, 8277259698Sdim bits<5> opcode> { 8278259698Sdim def 2d2s : NeonI_2VMisc<0b0, U, 0b01, opcode, 8279259698Sdim (outs VPR64:$Rd), (ins VPR128:$Rn), 8280259698Sdim asmop # "\t$Rd.2s, $Rn.2d", 8281259698Sdim [], NoItinerary>; 8282259698Sdim 8283259698Sdim def 2d4s : NeonI_2VMisc<0b1, U, 0b01, opcode, 8284259698Sdim (outs VPR128:$Rd), (ins VPR128:$src, VPR128:$Rn), 8285259698Sdim asmop # "2\t$Rd.4s, $Rn.2d", 8286259698Sdim [], NoItinerary> { 8287259698Sdim let Constraints = "$src = $Rd"; 8288259698Sdim } 8289259698Sdim 8290259698Sdim def : Pat<(v2f32 (int_aarch64_neon_fcvtxn (v2f64 VPR128:$Rn))), 8291259698Sdim (!cast<Instruction>(prefix # "2d2s") VPR128:$Rn)>; 8292259698Sdim 8293259698Sdim def : Pat<(v4f32 (concat_vectors 8294259698Sdim (v2f32 VPR64:$src), 8295259698Sdim (v2f32 (int_aarch64_neon_fcvtxn (v2f64 VPR128:$Rn))))), 8296259698Sdim (!cast<Instruction>(prefix # "2d4s") 8297259698Sdim (v4f32 (SUBREG_TO_REG (i32 0), VPR64:$src, sub_64)), 8298259698Sdim VPR128:$Rn)>; 8299259698Sdim} 8300259698Sdim 8301259698Sdimdefm FCVTXN : NeonI_2VMisc_D_Narrow<"fcvtxn","FCVTXN", 0b1, 0b10110>; 8302259698Sdim 8303259698Sdimdef Neon_High4Float : PatFrag<(ops node:$in), 8304259698Sdim (extract_subvector (v4f32 node:$in), (iPTR 2))>; 8305259698Sdim 8306259698Sdimmulticlass NeonI_2VMisc_HS_Extend<string asmop, bit U, bits<5> opcode> { 8307259698Sdim def 4h4s : NeonI_2VMisc<0b0, U, 0b00, opcode, 8308259698Sdim (outs VPR128:$Rd), (ins VPR64:$Rn), 8309259698Sdim asmop # "\t$Rd.4s, $Rn.4h", 8310259698Sdim [], NoItinerary>; 8311259698Sdim 8312259698Sdim def 2s2d : NeonI_2VMisc<0b0, U, 0b01, opcode, 8313259698Sdim (outs VPR128:$Rd), (ins VPR64:$Rn), 8314259698Sdim asmop # "\t$Rd.2d, $Rn.2s", 8315259698Sdim [], NoItinerary>; 8316259698Sdim 8317259698Sdim def 8h4s : NeonI_2VMisc<0b1, U, 0b00, opcode, 8318259698Sdim (outs VPR128:$Rd), (ins VPR128:$Rn), 8319259698Sdim asmop # "2\t$Rd.4s, $Rn.8h", 8320259698Sdim [], NoItinerary>; 8321259698Sdim 8322259698Sdim def 4s2d : NeonI_2VMisc<0b1, U, 0b01, opcode, 8323259698Sdim (outs VPR128:$Rd), (ins VPR128:$Rn), 8324259698Sdim asmop # "2\t$Rd.2d, $Rn.4s", 8325259698Sdim [], NoItinerary>; 8326259698Sdim} 8327259698Sdim 8328259698Sdimdefm FCVTL : NeonI_2VMisc_HS_Extend<"fcvtl", 0b0, 0b10111>; 8329259698Sdim 8330259698Sdimmulticlass NeonI_2VMisc_Extend_Pattern<string prefix> { 8331259698Sdim def : Pat<(v4f32 (int_arm_neon_vcvthf2fp (v4i16 VPR64:$Rn))), 8332259698Sdim (!cast<Instruction>(prefix # "4h4s") VPR64:$Rn)>; 8333259698Sdim 8334259698Sdim def : Pat<(v4f32 (int_arm_neon_vcvthf2fp 8335259698Sdim (v4i16 (Neon_High8H 8336259698Sdim (v8i16 VPR128:$Rn))))), 8337259698Sdim (!cast<Instruction>(prefix # "8h4s") VPR128:$Rn)>; 8338259698Sdim 8339259698Sdim def : Pat<(v2f64 (fextend (v2f32 VPR64:$Rn))), 8340259698Sdim (!cast<Instruction>(prefix # "2s2d") VPR64:$Rn)>; 8341259698Sdim 8342259698Sdim def : Pat<(v2f64 (fextend 8343259698Sdim (v2f32 (Neon_High4Float 8344259698Sdim (v4f32 VPR128:$Rn))))), 8345259698Sdim (!cast<Instruction>(prefix # "4s2d") VPR128:$Rn)>; 8346259698Sdim} 8347259698Sdim 8348259698Sdimdefm : NeonI_2VMisc_Extend_Pattern<"FCVTL">; 8349259698Sdim 8350259698Sdimmulticlass NeonI_2VMisc_SD_Conv<string asmop, bit Size, bit U, bits<5> opcode, 8351259698Sdim ValueType ResTy4s, ValueType OpTy4s, 8352259698Sdim ValueType ResTy2d, ValueType OpTy2d, 8353259698Sdim ValueType ResTy2s, ValueType OpTy2s, 8354259698Sdim SDPatternOperator Neon_Op> { 8355259698Sdim 8356259698Sdim def 4s : NeonI_2VMisc<0b1, U, {Size, 0b0}, opcode, 8357259698Sdim (outs VPR128:$Rd), (ins VPR128:$Rn), 8358259698Sdim asmop # "\t$Rd.4s, $Rn.4s", 8359259698Sdim [(set (ResTy4s VPR128:$Rd), 8360259698Sdim (ResTy4s (Neon_Op (OpTy4s VPR128:$Rn))))], 8361259698Sdim NoItinerary>; 8362259698Sdim 8363259698Sdim def 2d : NeonI_2VMisc<0b1, U, {Size, 0b1}, opcode, 8364259698Sdim (outs VPR128:$Rd), (ins VPR128:$Rn), 8365259698Sdim asmop # "\t$Rd.2d, $Rn.2d", 8366259698Sdim [(set (ResTy2d VPR128:$Rd), 8367259698Sdim (ResTy2d (Neon_Op (OpTy2d VPR128:$Rn))))], 8368259698Sdim NoItinerary>; 8369259698Sdim 8370259698Sdim def 2s : NeonI_2VMisc<0b0, U, {Size, 0b0}, opcode, 8371259698Sdim (outs VPR64:$Rd), (ins VPR64:$Rn), 8372259698Sdim asmop # "\t$Rd.2s, $Rn.2s", 8373259698Sdim [(set (ResTy2s VPR64:$Rd), 8374259698Sdim (ResTy2s (Neon_Op (OpTy2s VPR64:$Rn))))], 8375259698Sdim NoItinerary>; 8376259698Sdim} 8377259698Sdim 8378259698Sdimmulticlass NeonI_2VMisc_fp_to_int<string asmop, bit Size, bit U, 8379259698Sdim bits<5> opcode, SDPatternOperator Neon_Op> { 8380259698Sdim defm _ : NeonI_2VMisc_SD_Conv<asmop, Size, U, opcode, v4i32, v4f32, v2i64, 8381259698Sdim v2f64, v2i32, v2f32, Neon_Op>; 8382259698Sdim} 8383259698Sdim 8384259698Sdimdefm FCVTNS : NeonI_2VMisc_fp_to_int<"fcvtns", 0b0, 0b0, 0b11010, 8385259698Sdim int_aarch64_neon_fcvtns>; 8386259698Sdimdefm FCVTNU : NeonI_2VMisc_fp_to_int<"fcvtnu", 0b0, 0b1, 0b11010, 8387259698Sdim int_aarch64_neon_fcvtnu>; 8388259698Sdimdefm FCVTPS : NeonI_2VMisc_fp_to_int<"fcvtps", 0b1, 0b0, 0b11010, 8389259698Sdim int_aarch64_neon_fcvtps>; 8390259698Sdimdefm FCVTPU : NeonI_2VMisc_fp_to_int<"fcvtpu", 0b1, 0b1, 0b11010, 8391259698Sdim int_aarch64_neon_fcvtpu>; 8392259698Sdimdefm FCVTMS : NeonI_2VMisc_fp_to_int<"fcvtms", 0b0, 0b0, 0b11011, 8393259698Sdim int_aarch64_neon_fcvtms>; 8394259698Sdimdefm FCVTMU : NeonI_2VMisc_fp_to_int<"fcvtmu", 0b0, 0b1, 0b11011, 8395259698Sdim int_aarch64_neon_fcvtmu>; 8396259698Sdimdefm FCVTZS : NeonI_2VMisc_fp_to_int<"fcvtzs", 0b1, 0b0, 0b11011, fp_to_sint>; 8397259698Sdimdefm FCVTZU : NeonI_2VMisc_fp_to_int<"fcvtzu", 0b1, 0b1, 0b11011, fp_to_uint>; 8398259698Sdimdefm FCVTAS : NeonI_2VMisc_fp_to_int<"fcvtas", 0b0, 0b0, 0b11100, 8399259698Sdim int_aarch64_neon_fcvtas>; 8400259698Sdimdefm FCVTAU : NeonI_2VMisc_fp_to_int<"fcvtau", 0b0, 0b1, 0b11100, 8401259698Sdim int_aarch64_neon_fcvtau>; 8402259698Sdim 8403259698Sdimmulticlass NeonI_2VMisc_int_to_fp<string asmop, bit Size, bit U, 8404259698Sdim bits<5> opcode, SDPatternOperator Neon_Op> { 8405259698Sdim defm _ : NeonI_2VMisc_SD_Conv<asmop, Size, U, opcode, v4f32, v4i32, v2f64, 8406259698Sdim v2i64, v2f32, v2i32, Neon_Op>; 8407259698Sdim} 8408259698Sdim 8409259698Sdimdefm SCVTF : NeonI_2VMisc_int_to_fp<"scvtf", 0b0, 0b0, 0b11101, sint_to_fp>; 8410259698Sdimdefm UCVTF : NeonI_2VMisc_int_to_fp<"ucvtf", 0b0, 0b1, 0b11101, uint_to_fp>; 8411259698Sdim 8412259698Sdimmulticlass NeonI_2VMisc_fp_to_fp<string asmop, bit Size, bit U, 8413259698Sdim bits<5> opcode, SDPatternOperator Neon_Op> { 8414259698Sdim defm _ : NeonI_2VMisc_SD_Conv<asmop, Size, U, opcode, v4f32, v4f32, v2f64, 8415259698Sdim v2f64, v2f32, v2f32, Neon_Op>; 8416259698Sdim} 8417259698Sdim 8418259698Sdimdefm FRINTN : NeonI_2VMisc_fp_to_fp<"frintn", 0b0, 0b0, 0b11000, 8419259698Sdim int_aarch64_neon_frintn>; 8420259698Sdimdefm FRINTA : NeonI_2VMisc_fp_to_fp<"frinta", 0b0, 0b1, 0b11000, frnd>; 8421259698Sdimdefm FRINTP : NeonI_2VMisc_fp_to_fp<"frintp", 0b1, 0b0, 0b11000, fceil>; 8422259698Sdimdefm FRINTM : NeonI_2VMisc_fp_to_fp<"frintm", 0b0, 0b0, 0b11001, ffloor>; 8423259698Sdimdefm FRINTX : NeonI_2VMisc_fp_to_fp<"frintx", 0b0, 0b1, 0b11001, frint>; 8424259698Sdimdefm FRINTZ : NeonI_2VMisc_fp_to_fp<"frintz", 0b1, 0b0, 0b11001, ftrunc>; 8425259698Sdimdefm FRINTI : NeonI_2VMisc_fp_to_fp<"frinti", 0b1, 0b1, 0b11001, fnearbyint>; 8426259698Sdimdefm FRECPE : NeonI_2VMisc_fp_to_fp<"frecpe", 0b1, 0b0, 0b11101, 8427259698Sdim int_arm_neon_vrecpe>; 8428259698Sdimdefm FRSQRTE : NeonI_2VMisc_fp_to_fp<"frsqrte", 0b1, 0b1, 0b11101, 8429259698Sdim int_arm_neon_vrsqrte>; 8430259698Sdimdefm FSQRT : NeonI_2VMisc_fp_to_fp<"fsqrt", 0b1, 0b1, 0b11111, fsqrt>; 8431259698Sdim 8432259698Sdimmulticlass NeonI_2VMisc_S_Conv<string asmop, bit Size, bit U, 8433259698Sdim bits<5> opcode, SDPatternOperator Neon_Op> { 8434259698Sdim def 4s : NeonI_2VMisc<0b1, U, {Size, 0b0}, opcode, 8435259698Sdim (outs VPR128:$Rd), (ins VPR128:$Rn), 8436259698Sdim asmop # "\t$Rd.4s, $Rn.4s", 8437259698Sdim [(set (v4i32 VPR128:$Rd), 8438259698Sdim (v4i32 (Neon_Op (v4i32 VPR128:$Rn))))], 8439259698Sdim NoItinerary>; 8440259698Sdim 8441259698Sdim def 2s : NeonI_2VMisc<0b0, U, {Size, 0b0}, opcode, 8442259698Sdim (outs VPR64:$Rd), (ins VPR64:$Rn), 8443259698Sdim asmop # "\t$Rd.2s, $Rn.2s", 8444259698Sdim [(set (v2i32 VPR64:$Rd), 8445259698Sdim (v2i32 (Neon_Op (v2i32 VPR64:$Rn))))], 8446259698Sdim NoItinerary>; 8447259698Sdim} 8448259698Sdim 8449259698Sdimdefm URECPE : NeonI_2VMisc_S_Conv<"urecpe", 0b1, 0b0, 0b11100, 8450259698Sdim int_arm_neon_vrecpe>; 8451259698Sdimdefm URSQRTE : NeonI_2VMisc_S_Conv<"ursqrte", 0b1, 0b1, 0b11100, 8452259698Sdim int_arm_neon_vrsqrte>; 8453259698Sdim 8454259698Sdim// Crypto Class 8455259698Sdimclass NeonI_Cryptoaes_2v<bits<2> size, bits<5> opcode, 8456259698Sdim string asmop, SDPatternOperator opnode> 8457259698Sdim : NeonI_Crypto_AES<size, opcode, 8458259698Sdim (outs VPR128:$Rd), (ins VPR128:$src, VPR128:$Rn), 8459259698Sdim asmop # "\t$Rd.16b, $Rn.16b", 8460259698Sdim [(set (v16i8 VPR128:$Rd), 8461259698Sdim (v16i8 (opnode (v16i8 VPR128:$src), 8462259698Sdim (v16i8 VPR128:$Rn))))], 8463259698Sdim NoItinerary>{ 8464259698Sdim let Constraints = "$src = $Rd"; 8465259698Sdim let Predicates = [HasNEON, HasCrypto]; 8466259698Sdim} 8467259698Sdim 8468259698Sdimdef AESE : NeonI_Cryptoaes_2v<0b00, 0b00100, "aese", int_arm_neon_aese>; 8469259698Sdimdef AESD : NeonI_Cryptoaes_2v<0b00, 0b00101, "aesd", int_arm_neon_aesd>; 8470259698Sdim 8471259698Sdimclass NeonI_Cryptoaes<bits<2> size, bits<5> opcode, 8472259698Sdim string asmop, SDPatternOperator opnode> 8473259698Sdim : NeonI_Crypto_AES<size, opcode, 8474259698Sdim (outs VPR128:$Rd), (ins VPR128:$Rn), 8475259698Sdim asmop # "\t$Rd.16b, $Rn.16b", 8476259698Sdim [(set (v16i8 VPR128:$Rd), 8477259698Sdim (v16i8 (opnode (v16i8 VPR128:$Rn))))], 8478259698Sdim NoItinerary>; 8479259698Sdim 8480259698Sdimdef AESMC : NeonI_Cryptoaes<0b00, 0b00110, "aesmc", int_arm_neon_aesmc>; 8481259698Sdimdef AESIMC : NeonI_Cryptoaes<0b00, 0b00111, "aesimc", int_arm_neon_aesimc>; 8482259698Sdim 8483259698Sdimclass NeonI_Cryptosha_vv<bits<2> size, bits<5> opcode, 8484259698Sdim string asmop, SDPatternOperator opnode> 8485259698Sdim : NeonI_Crypto_SHA<size, opcode, 8486259698Sdim (outs VPR128:$Rd), (ins VPR128:$src, VPR128:$Rn), 8487259698Sdim asmop # "\t$Rd.4s, $Rn.4s", 8488259698Sdim [(set (v4i32 VPR128:$Rd), 8489259698Sdim (v4i32 (opnode (v4i32 VPR128:$src), 8490259698Sdim (v4i32 VPR128:$Rn))))], 8491259698Sdim NoItinerary> { 8492259698Sdim let Constraints = "$src = $Rd"; 8493259698Sdim let Predicates = [HasNEON, HasCrypto]; 8494259698Sdim} 8495259698Sdim 8496259698Sdimdef SHA1SU1 : NeonI_Cryptosha_vv<0b00, 0b00001, "sha1su1", 8497259698Sdim int_arm_neon_sha1su1>; 8498259698Sdimdef SHA256SU0 : NeonI_Cryptosha_vv<0b00, 0b00010, "sha256su0", 8499259698Sdim int_arm_neon_sha256su0>; 8500259698Sdim 8501259698Sdimclass NeonI_Cryptosha_ss<bits<2> size, bits<5> opcode, 8502259698Sdim string asmop, SDPatternOperator opnode> 8503259698Sdim : NeonI_Crypto_SHA<size, opcode, 8504259698Sdim (outs FPR32:$Rd), (ins FPR32:$Rn), 8505259698Sdim asmop # "\t$Rd, $Rn", 8506259698Sdim [(set (v1i32 FPR32:$Rd), 8507259698Sdim (v1i32 (opnode (v1i32 FPR32:$Rn))))], 8508259698Sdim NoItinerary> { 8509259698Sdim let Predicates = [HasNEON, HasCrypto]; 8510259698Sdim} 8511259698Sdim 8512259698Sdimdef SHA1H : NeonI_Cryptosha_ss<0b00, 0b00000, "sha1h", int_arm_neon_sha1h>; 8513259698Sdim 8514259698Sdimclass NeonI_Cryptosha3_vvv<bits<2> size, bits<3> opcode, string asmop, 8515259698Sdim SDPatternOperator opnode> 8516259698Sdim : NeonI_Crypto_3VSHA<size, opcode, 8517259698Sdim (outs VPR128:$Rd), 8518259698Sdim (ins VPR128:$src, VPR128:$Rn, VPR128:$Rm), 8519259698Sdim asmop # "\t$Rd.4s, $Rn.4s, $Rm.4s", 8520259698Sdim [(set (v4i32 VPR128:$Rd), 8521259698Sdim (v4i32 (opnode (v4i32 VPR128:$src), 8522259698Sdim (v4i32 VPR128:$Rn), 8523259698Sdim (v4i32 VPR128:$Rm))))], 8524259698Sdim NoItinerary> { 8525259698Sdim let Constraints = "$src = $Rd"; 8526259698Sdim let Predicates = [HasNEON, HasCrypto]; 8527259698Sdim} 8528259698Sdim 8529259698Sdimdef SHA1SU0 : NeonI_Cryptosha3_vvv<0b00, 0b011, "sha1su0", 8530259698Sdim int_arm_neon_sha1su0>; 8531259698Sdimdef SHA256SU1 : NeonI_Cryptosha3_vvv<0b00, 0b110, "sha256su1", 8532259698Sdim int_arm_neon_sha256su1>; 8533259698Sdim 8534259698Sdimclass NeonI_Cryptosha3_qqv<bits<2> size, bits<3> opcode, string asmop, 8535259698Sdim SDPatternOperator opnode> 8536259698Sdim : NeonI_Crypto_3VSHA<size, opcode, 8537259698Sdim (outs FPR128:$Rd), 8538259698Sdim (ins FPR128:$src, FPR128:$Rn, VPR128:$Rm), 8539259698Sdim asmop # "\t$Rd, $Rn, $Rm.4s", 8540259698Sdim [(set (v4i32 FPR128:$Rd), 8541259698Sdim (v4i32 (opnode (v4i32 FPR128:$src), 8542259698Sdim (v4i32 FPR128:$Rn), 8543259698Sdim (v4i32 VPR128:$Rm))))], 8544259698Sdim NoItinerary> { 8545259698Sdim let Constraints = "$src = $Rd"; 8546259698Sdim let Predicates = [HasNEON, HasCrypto]; 8547259698Sdim} 8548259698Sdim 8549259698Sdimdef SHA256H : NeonI_Cryptosha3_qqv<0b00, 0b100, "sha256h", 8550259698Sdim int_arm_neon_sha256h>; 8551259698Sdimdef SHA256H2 : NeonI_Cryptosha3_qqv<0b00, 0b101, "sha256h2", 8552259698Sdim int_arm_neon_sha256h2>; 8553259698Sdim 8554259698Sdimclass NeonI_Cryptosha3_qsv<bits<2> size, bits<3> opcode, string asmop, 8555259698Sdim SDPatternOperator opnode> 8556259698Sdim : NeonI_Crypto_3VSHA<size, opcode, 8557259698Sdim (outs FPR128:$Rd), 8558259698Sdim (ins FPR128:$src, FPR32:$Rn, VPR128:$Rm), 8559259698Sdim asmop # "\t$Rd, $Rn, $Rm.4s", 8560259698Sdim [(set (v4i32 FPR128:$Rd), 8561259698Sdim (v4i32 (opnode (v4i32 FPR128:$src), 8562259698Sdim (v1i32 FPR32:$Rn), 8563259698Sdim (v4i32 VPR128:$Rm))))], 8564259698Sdim NoItinerary> { 8565259698Sdim let Constraints = "$src = $Rd"; 8566259698Sdim let Predicates = [HasNEON, HasCrypto]; 8567259698Sdim} 8568259698Sdim 8569259698Sdimdef SHA1C : NeonI_Cryptosha3_qsv<0b00, 0b000, "sha1c", int_aarch64_neon_sha1c>; 8570259698Sdimdef SHA1P : NeonI_Cryptosha3_qsv<0b00, 0b001, "sha1p", int_aarch64_neon_sha1p>; 8571259698Sdimdef SHA1M : NeonI_Cryptosha3_qsv<0b00, 0b010, "sha1m", int_aarch64_neon_sha1m>; 8572259698Sdim 8573259698Sdim// 8574259698Sdim// Patterns for handling half-precision values 8575259698Sdim// 8576259698Sdim 8577259698Sdim// Convert f16 value coming in as i16 value to f32 8578259698Sdimdef : Pat<(f32 (f16_to_f32 (i32 (and (i32 GPR32:$Rn), 65535)))), 8579259698Sdim (FCVTsh (EXTRACT_SUBREG (FMOVsw GPR32:$Rn), sub_16))>; 8580259698Sdimdef : Pat<(f32 (f16_to_f32 (i32 (assertzext GPR32:$Rn)))), 8581259698Sdim (FCVTsh (EXTRACT_SUBREG (FMOVsw GPR32:$Rn), sub_16))>; 8582259698Sdim 8583259698Sdimdef : Pat<(f32 (f16_to_f32 (i32 (assertzext (i32 ( 8584259698Sdim f32_to_f16 (f32 FPR32:$Rn))))))), 8585259698Sdim (f32 FPR32:$Rn)>; 8586259698Sdim 8587259698Sdim// Patterns for vector extract of half-precision FP value in i16 storage type 8588259698Sdimdef : Pat<(f32 (f16_to_f32 ( i32 (and (i32 (vector_extract 8589259698Sdim (v4i16 VPR64:$Rn), neon_uimm2_bare:$Imm)), 65535)))), 8590259698Sdim (FCVTsh (f16 (DUPhv_H 8591259698Sdim (v8i16 (SUBREG_TO_REG (i64 0), VPR64:$Rn, sub_64)), 8592259698Sdim neon_uimm2_bare:$Imm)))>; 8593259698Sdim 8594259698Sdimdef : Pat<(f32 (f16_to_f32 ( i32 (and (i32 (vector_extract 8595259698Sdim (v8i16 VPR128:$Rn), neon_uimm3_bare:$Imm)), 65535)))), 8596259698Sdim (FCVTsh (f16 (DUPhv_H (v8i16 VPR128:$Rn), neon_uimm3_bare:$Imm)))>; 8597259698Sdim 8598259698Sdim// Patterns for vector insert of half-precision FP value 0 in i16 storage type 8599259698Sdimdef : Pat<(v8i16 (vector_insert (v8i16 VPR128:$Rn), 8600259698Sdim (i32 (assertsext (i32 (fp_to_sint(f32 (f16_to_f32 (i32 0))))))), 8601259698Sdim (neon_uimm3_bare:$Imm))), 8602259698Sdim (v8i16 (INSELh (v8i16 VPR128:$Rn), 8603259698Sdim (v8i16 (SUBREG_TO_REG (i64 0), 8604259698Sdim (f16 (EXTRACT_SUBREG (f32 (FMOVsw (i32 WZR))), sub_16)), 8605259698Sdim sub_16)), 8606259698Sdim neon_uimm3_bare:$Imm, 0))>; 8607259698Sdim 8608259698Sdimdef : Pat<(v4i16 (vector_insert (v4i16 VPR64:$Rn), 8609259698Sdim (i32 (assertsext (i32 (fp_to_sint(f32 (f16_to_f32 (i32 0))))))), 8610259698Sdim (neon_uimm2_bare:$Imm))), 8611259698Sdim (v4i16 (EXTRACT_SUBREG 8612259698Sdim (v8i16 (INSELh 8613259698Sdim (v8i16 (SUBREG_TO_REG (i64 0), VPR64:$Rn, sub_64)), 8614259698Sdim (v8i16 (SUBREG_TO_REG (i64 0), 8615259698Sdim (f16 (EXTRACT_SUBREG (f32 (FMOVsw (i32 WZR))), sub_16)), 8616259698Sdim sub_16)), 8617259698Sdim neon_uimm2_bare:$Imm, 0)), 8618259698Sdim sub_64))>; 8619259698Sdim 8620259698Sdim// Patterns for vector insert of half-precision FP value in i16 storage type 8621259698Sdimdef : Pat<(v8i16 (vector_insert (v8i16 VPR128:$Rn), 8622259698Sdim (i32 (assertsext (i32 (fp_to_sint 8623259698Sdim (f32 (f16_to_f32 (i32 (and (i32 GPR32:$src), 65535)))))))), 8624259698Sdim (neon_uimm3_bare:$Imm))), 8625259698Sdim (v8i16 (INSELh (v8i16 VPR128:$Rn), 8626259698Sdim (v8i16 (SUBREG_TO_REG (i64 0), 8627259698Sdim (f16 (EXTRACT_SUBREG (f32 (FMOVsw (i32 GPR32:$src))), sub_16)), 8628259698Sdim sub_16)), 8629259698Sdim neon_uimm3_bare:$Imm, 0))>; 8630259698Sdim 8631259698Sdimdef : Pat<(v4i16 (vector_insert (v4i16 VPR64:$Rn), 8632259698Sdim (i32 (assertsext (i32 (fp_to_sint 8633259698Sdim (f32 (f16_to_f32 (i32 (and (i32 GPR32:$src), 65535)))))))), 8634259698Sdim (neon_uimm2_bare:$Imm))), 8635259698Sdim (v4i16 (EXTRACT_SUBREG 8636259698Sdim (v8i16 (INSELh 8637259698Sdim (v8i16 (SUBREG_TO_REG (i64 0), VPR64:$Rn, sub_64)), 8638259698Sdim (v8i16 (SUBREG_TO_REG (i64 0), 8639259698Sdim (f16 (EXTRACT_SUBREG (f32 (FMOVsw (i32 GPR32:$src))), sub_16)), 8640259698Sdim sub_16)), 8641259698Sdim neon_uimm2_bare:$Imm, 0)), 8642259698Sdim sub_64))>; 8643259698Sdim 8644259698Sdimdef : Pat<(v8i16 (vector_insert (v8i16 VPR128:$Rn), 8645259698Sdim (i32 (vector_extract (v8i16 VPR128:$src), neon_uimm3_bare:$Imm2)), 8646259698Sdim (neon_uimm3_bare:$Imm1))), 8647259698Sdim (v8i16 (INSELh (v8i16 VPR128:$Rn), (v8i16 VPR128:$src), 8648259698Sdim neon_uimm3_bare:$Imm1, neon_uimm3_bare:$Imm2))>; 8649259698Sdim 8650259698Sdim// Patterns for vector copy of half-precision FP value in i16 storage type 8651259698Sdimdef : Pat<(v8i16 (vector_insert (v8i16 VPR128:$Rn), 8652259698Sdim (i32 (assertsext (i32 (fp_to_sint(f32 (f16_to_f32 (i32 (and (i32 8653259698Sdim (vector_extract (v8i16 VPR128:$src), neon_uimm3_bare:$Imm2)), 8654259698Sdim 65535)))))))), 8655259698Sdim (neon_uimm3_bare:$Imm1))), 8656259698Sdim (v8i16 (INSELh (v8i16 VPR128:$Rn), (v8i16 VPR128:$src), 8657259698Sdim neon_uimm3_bare:$Imm1, neon_uimm3_bare:$Imm2))>; 8658259698Sdim 8659259698Sdimdef : Pat<(v4i16 (vector_insert (v4i16 VPR64:$Rn), 8660259698Sdim (i32 (assertsext (i32 (fp_to_sint(f32 (f16_to_f32 (i32 (and (i32 8661259698Sdim (vector_extract (v4i16 VPR64:$src), neon_uimm3_bare:$Imm2)), 8662259698Sdim 65535)))))))), 8663259698Sdim (neon_uimm3_bare:$Imm1))), 8664259698Sdim (v4i16 (EXTRACT_SUBREG 8665259698Sdim (v8i16 (INSELh 8666259698Sdim (v8i16 (SUBREG_TO_REG (i64 0), VPR64:$Rn, sub_64)), 8667259698Sdim (v8i16 (SUBREG_TO_REG (i64 0), VPR64:$src, sub_64)), 8668259698Sdim neon_uimm3_bare:$Imm1, neon_uimm3_bare:$Imm2)), 8669259698Sdim sub_64))>; 8670259698Sdim 8671259698Sdim 8672