1 //=----- AArch64InstrGISel.td - AArch64 GISel target pseudos -*- tablegen -*-=//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 // AArch64 GlobalISel target pseudo instruction definitions. This is kept
10 // separately from the other tablegen files for organizational purposes, but
11 // share the same infrastructure.
13 //===----------------------------------------------------------------------===//
16 class AArch64GenericInstruction : GenericInstruction {
17 let Namespace = "AArch64";
20 // A pseudo to represent a relocatable add instruction as part of address
22 def G_ADD_LOW : AArch64GenericInstruction {
23 let OutOperandList = (outs type0:$dst);
24 let InOperandList = (ins type1:$src, type2:$imm);
25 let hasSideEffects = 0;
28 // Pseudo for a rev16 instruction. Produced post-legalization from
29 // G_SHUFFLE_VECTORs with appropriate masks.
30 def G_REV16 : AArch64GenericInstruction {
31 let OutOperandList = (outs type0:$dst);
32 let InOperandList = (ins type0:$src);
33 let hasSideEffects = 0;
36 // Pseudo for a rev32 instruction. Produced post-legalization from
37 // G_SHUFFLE_VECTORs with appropriate masks.
38 def G_REV32 : AArch64GenericInstruction {
39 let OutOperandList = (outs type0:$dst);
40 let InOperandList = (ins type0:$src);
41 let hasSideEffects = 0;
44 // Pseudo for a rev64 instruction. Produced post-legalization from
45 // G_SHUFFLE_VECTORs with appropriate masks.
46 def G_REV64 : AArch64GenericInstruction {
47 let OutOperandList = (outs type0:$dst);
48 let InOperandList = (ins type0:$src);
49 let hasSideEffects = 0;
52 // Represents an uzp1 instruction. Produced post-legalization from
53 // G_SHUFFLE_VECTORs with appropriate masks.
54 def G_UZP1 : AArch64GenericInstruction {
55 let OutOperandList = (outs type0:$dst);
56 let InOperandList = (ins type0:$v1, type0:$v2);
57 let hasSideEffects = 0;
60 // Represents an uzp2 instruction. Produced post-legalization from
61 // G_SHUFFLE_VECTORs with appropriate masks.
62 def G_UZP2 : AArch64GenericInstruction {
63 let OutOperandList = (outs type0:$dst);
64 let InOperandList = (ins type0:$v1, type0:$v2);
65 let hasSideEffects = 0;
68 // Represents a zip1 instruction. Produced post-legalization from
69 // G_SHUFFLE_VECTORs with appropriate masks.
70 def G_ZIP1 : AArch64GenericInstruction {
71 let OutOperandList = (outs type0:$dst);
72 let InOperandList = (ins type0:$v1, type0:$v2);
73 let hasSideEffects = 0;
76 // Represents a zip2 instruction. Produced post-legalization from
77 // G_SHUFFLE_VECTORs with appropriate masks.
78 def G_ZIP2 : AArch64GenericInstruction {
79 let OutOperandList = (outs type0:$dst);
80 let InOperandList = (ins type0:$v1, type0:$v2);
81 let hasSideEffects = 0;
84 // Represents a dup instruction. Produced post-legalization from
85 // G_SHUFFLE_VECTORs with appropriate masks.
86 def G_DUP: AArch64GenericInstruction {
87 let OutOperandList = (outs type0:$dst);
88 let InOperandList = (ins type1:$lane);
89 let hasSideEffects = 0;
92 // Represents a lane duplicate operation.
93 def G_DUPLANE8 : AArch64GenericInstruction {
94 let OutOperandList = (outs type0:$dst);
95 let InOperandList = (ins type0:$src, type1:$lane);
96 let hasSideEffects = 0;
98 def G_DUPLANE16 : AArch64GenericInstruction {
99 let OutOperandList = (outs type0:$dst);
100 let InOperandList = (ins type0:$src, type1:$lane);
101 let hasSideEffects = 0;
103 def G_DUPLANE32 : AArch64GenericInstruction {
104 let OutOperandList = (outs type0:$dst);
105 let InOperandList = (ins type0:$src, type1:$lane);
106 let hasSideEffects = 0;
108 def G_DUPLANE64 : AArch64GenericInstruction {
109 let OutOperandList = (outs type0:$dst);
110 let InOperandList = (ins type0:$src, type1:$lane);
111 let hasSideEffects = 0;
114 // Represents a trn1 instruction. Produced post-legalization from
115 // G_SHUFFLE_VECTORs with appropriate masks.
116 def G_TRN1 : AArch64GenericInstruction {
117 let OutOperandList = (outs type0:$dst);
118 let InOperandList = (ins type0:$v1, type0:$v2);
119 let hasSideEffects = 0;
122 // Represents a trn2 instruction. Produced post-legalization from
123 // G_SHUFFLE_VECTORs with appropriate masks.
124 def G_TRN2 : AArch64GenericInstruction {
125 let OutOperandList = (outs type0:$dst);
126 let InOperandList = (ins type0:$v1, type0:$v2);
127 let hasSideEffects = 0;
130 // Represents an ext instruction. Produced post-legalization from
131 // G_SHUFFLE_VECTORs with appropriate masks.
132 def G_EXT: AArch64GenericInstruction {
133 let OutOperandList = (outs type0:$dst);
134 let InOperandList = (ins type0:$v1, type0:$v2, untyped_imm_0:$imm);
135 let hasSideEffects = 0;
138 // Represents a vector G_ASHR with an immediate.
139 def G_VASHR : AArch64GenericInstruction {
140 let OutOperandList = (outs type0:$dst);
141 let InOperandList = (ins type0:$src1, untyped_imm_0:$imm);
142 let hasSideEffects = 0;
145 // Represents a vector G_LSHR with an immediate.
146 def G_VLSHR : AArch64GenericInstruction {
147 let OutOperandList = (outs type0:$dst);
148 let InOperandList = (ins type0:$src1, untyped_imm_0:$imm);
149 let hasSideEffects = 0;
152 // Represents an integer to FP conversion on the FPR bank.
153 def G_SITOF : AArch64GenericInstruction {
154 let OutOperandList = (outs type0:$dst);
155 let InOperandList = (ins type0:$src);
156 let hasSideEffects = 0;
158 def G_UITOF : AArch64GenericInstruction {
159 let OutOperandList = (outs type0:$dst);
160 let InOperandList = (ins type0:$src);
161 let hasSideEffects = 0;
164 def G_FCMEQ : AArch64GenericInstruction {
165 let OutOperandList = (outs type0:$dst);
166 let InOperandList = (ins type0:$src1, type1:$src2);
167 let hasSideEffects = 0;
170 def G_FCMGE : AArch64GenericInstruction {
171 let OutOperandList = (outs type0:$dst);
172 let InOperandList = (ins type0:$src1, type1:$src2);
173 let hasSideEffects = 0;
176 def G_FCMGT : AArch64GenericInstruction {
177 let OutOperandList = (outs type0:$dst);
178 let InOperandList = (ins type0:$src1, type1:$src2);
179 let hasSideEffects = 0;
182 def G_FCMEQZ : AArch64GenericInstruction {
183 let OutOperandList = (outs type0:$dst);
184 let InOperandList = (ins type0:$src);
185 let hasSideEffects = 0;
188 def G_FCMGEZ : AArch64GenericInstruction {
189 let OutOperandList = (outs type0:$dst);
190 let InOperandList = (ins type0:$src);
191 let hasSideEffects = 0;
194 def G_FCMGTZ : AArch64GenericInstruction {
195 let OutOperandList = (outs type0:$dst);
196 let InOperandList = (ins type0:$src);
197 let hasSideEffects = 0;
200 def G_FCMLEZ : AArch64GenericInstruction {
201 let OutOperandList = (outs type0:$dst);
202 let InOperandList = (ins type0:$src);
203 let hasSideEffects = 0;
206 def G_FCMLTZ : AArch64GenericInstruction {
207 let OutOperandList = (outs type0:$dst);
208 let InOperandList = (ins type0:$src);
209 let hasSideEffects = 0;
212 def G_AARCH64_PREFETCH : AArch64GenericInstruction {
213 let OutOperandList = (outs);
214 let InOperandList = (ins type0:$imm, ptype0:$src1);
215 let hasSideEffects = 1;
218 def G_UMULL : AArch64GenericInstruction {
219 let OutOperandList = (outs type0:$dst);
220 let InOperandList = (ins type0:$src1, type0:$src2);
221 let hasSideEffects = 0;
224 def G_SMULL : AArch64GenericInstruction {
225 let OutOperandList = (outs type0:$dst);
226 let InOperandList = (ins type0:$src1, type0:$src2);
227 let hasSideEffects = 0;
230 def G_UADDLP : AArch64GenericInstruction {
231 let OutOperandList = (outs type0:$dst);
232 let InOperandList = (ins type0:$src1);
233 let hasSideEffects = 0;
236 def G_SADDLP : AArch64GenericInstruction {
237 let OutOperandList = (outs type0:$dst);
238 let InOperandList = (ins type0:$src1);
239 let hasSideEffects = 0;
242 def G_UADDLV : AArch64GenericInstruction {
243 let OutOperandList = (outs type0:$dst);
244 let InOperandList = (ins type0:$src1);
245 let hasSideEffects = 0;
248 def G_SADDLV : AArch64GenericInstruction {
249 let OutOperandList = (outs type0:$dst);
250 let InOperandList = (ins type0:$src1);
251 let hasSideEffects = 0;
254 def G_UDOT : AArch64GenericInstruction {
255 let OutOperandList = (outs type0:$dst);
256 let InOperandList = (ins type0:$src1, type0:$src2, type0:$src3);
257 let hasSideEffects = 0;
260 def G_SDOT : AArch64GenericInstruction {
261 let OutOperandList = (outs type0:$dst);
262 let InOperandList = (ins type0:$src1, type0:$src2, type0:$src3);
263 let hasSideEffects = 0;
266 // Generic instruction for the BSP pseudo. It is expanded into BSP, which
267 // expands into BSL/BIT/BIF after register allocation.
268 def G_BSP : AArch64GenericInstruction {
269 let OutOperandList = (outs type0:$dst);
270 let InOperandList = (ins type0:$src1, type0:$src2, type0:$src3);
271 let hasSideEffects = 0;
274 def : GINodeEquiv<G_REV16, AArch64rev16>;
275 def : GINodeEquiv<G_REV32, AArch64rev32>;
276 def : GINodeEquiv<G_REV64, AArch64rev64>;
277 def : GINodeEquiv<G_UZP1, AArch64uzp1>;
278 def : GINodeEquiv<G_UZP2, AArch64uzp2>;
279 def : GINodeEquiv<G_ZIP1, AArch64zip1>;
280 def : GINodeEquiv<G_ZIP2, AArch64zip2>;
281 def : GINodeEquiv<G_DUP, AArch64dup>;
282 def : GINodeEquiv<G_DUPLANE8, AArch64duplane8>;
283 def : GINodeEquiv<G_DUPLANE16, AArch64duplane16>;
284 def : GINodeEquiv<G_DUPLANE32, AArch64duplane32>;
285 def : GINodeEquiv<G_DUPLANE64, AArch64duplane64>;
286 def : GINodeEquiv<G_TRN1, AArch64trn1>;
287 def : GINodeEquiv<G_TRN2, AArch64trn2>;
288 def : GINodeEquiv<G_EXT, AArch64ext>;
289 def : GINodeEquiv<G_VASHR, AArch64vashr>;
290 def : GINodeEquiv<G_VLSHR, AArch64vlshr>;
291 def : GINodeEquiv<G_SITOF, AArch64sitof>;
292 def : GINodeEquiv<G_UITOF, AArch64uitof>;
294 def : GINodeEquiv<G_FCMEQ, AArch64fcmeq>;
295 def : GINodeEquiv<G_FCMGE, AArch64fcmge>;
296 def : GINodeEquiv<G_FCMGT, AArch64fcmgt>;
298 def : GINodeEquiv<G_FCMEQZ, AArch64fcmeqz>;
299 def : GINodeEquiv<G_FCMGEZ, AArch64fcmgez>;
300 def : GINodeEquiv<G_FCMGTZ, AArch64fcmgtz>;
301 def : GINodeEquiv<G_FCMLEZ, AArch64fcmlez>;
302 def : GINodeEquiv<G_FCMLTZ, AArch64fcmltz>;
304 def : GINodeEquiv<G_BSP, AArch64bsp>;
306 def : GINodeEquiv<G_UMULL, AArch64umull>;
307 def : GINodeEquiv<G_SMULL, AArch64smull>;
309 def : GINodeEquiv<G_SADDLP, AArch64saddlp_n>;
310 def : GINodeEquiv<G_UADDLP, AArch64uaddlp_n>;
312 def : GINodeEquiv<G_SADDLV, AArch64saddlv>;
313 def : GINodeEquiv<G_UADDLV, AArch64uaddlv>;
315 def : GINodeEquiv<G_UDOT, AArch64udot>;
316 def : GINodeEquiv<G_SDOT, AArch64sdot>;
318 def : GINodeEquiv<G_EXTRACT_VECTOR_ELT, vector_extract>;
320 def : GINodeEquiv<G_AARCH64_PREFETCH, AArch64Prefetch>;
322 // These are patterns that we only use for GlobalISel via the importer.
323 def : Pat<(f32 (fadd (vector_extract (v2f32 FPR64:$Rn), (i64 0)),
324 (vector_extract (v2f32 FPR64:$Rn), (i64 1)))),
325 (f32 (FADDPv2i32p (v2f32 FPR64:$Rn)))>;
327 let Predicates = [HasNEON] in {
328 def : Pat<(v2f64 (sint_to_fp v2i32:$src)),
329 (SCVTFv2f64 (SSHLLv2i32_shift V64:$src, 0))>;
330 def : Pat<(v2f64 (uint_to_fp v2i32:$src)),
331 (UCVTFv2f64 (USHLLv2i32_shift V64:$src, 0))>;
332 def : Pat<(v2f32 (sint_to_fp v2i64:$src)),
333 (FCVTNv2i32 (SCVTFv2f64 V128:$src))>;
334 def : Pat<(v2f32 (uint_to_fp v2i64:$src)),
335 (FCVTNv2i32 (UCVTFv2f64 V128:$src))>;
337 def : Pat<(v2i64 (fp_to_sint v2f32:$src)),
338 (FCVTZSv2f64 (FCVTLv2i32 V64:$src))>;
339 def : Pat<(v2i64 (fp_to_uint v2f32:$src)),
340 (FCVTZUv2f64 (FCVTLv2i32 V64:$src))>;
341 def : Pat<(v2i32 (fp_to_sint v2f64:$src)),
342 (XTNv2i32 (FCVTZSv2f64 V128:$src))>;
343 def : Pat<(v2i32 (fp_to_uint v2f64:$src)),
344 (XTNv2i32 (FCVTZUv2f64 V128:$src))>;
348 let Predicates = [HasNoLSE] in {
349 def : Pat<(atomic_cmp_swap_8 GPR64:$addr, GPR32:$desired, GPR32:$new),
350 (CMP_SWAP_8 GPR64:$addr, GPR32:$desired, GPR32:$new)>;
352 def : Pat<(atomic_cmp_swap_16 GPR64:$addr, GPR32:$desired, GPR32:$new),
353 (CMP_SWAP_16 GPR64:$addr, GPR32:$desired, GPR32:$new)>;
355 def : Pat<(atomic_cmp_swap_32 GPR64:$addr, GPR32:$desired, GPR32:$new),
356 (CMP_SWAP_32 GPR64:$addr, GPR32:$desired, GPR32:$new)>;
358 def : Pat<(atomic_cmp_swap_64 GPR64:$addr, GPR64:$desired, GPR64:$new),
359 (CMP_SWAP_64 GPR64:$addr, GPR64:$desired, GPR64:$new)>;
362 def : Pat<(int_aarch64_stlxp GPR64:$lo, GPR64:$hi, GPR64:$addr),
363 (STLXPX GPR64:$lo, GPR64:$hi, GPR64:$addr)>;
364 def : Pat<(int_aarch64_stxp GPR64:$lo, GPR64:$hi, GPR64:$addr),
365 (STXPX GPR64:$lo, GPR64:$hi, GPR64:$addr)>;
367 let GIIgnoreCopies = 1 in
368 class PatIgnoreCopies<dag pattern, dag result> : Pat<pattern, result>, GISelFlags;
370 multiclass SIMDAcrossLanesSignedIntrinsicBHS<string baseOpc, Intrinsic intOp> {
371 def : PatIgnoreCopies<(i32 (sext (i8 (intOp (v8i8 V64:$Rn))))),
373 (INSERT_SUBREG (v16i8 (IMPLICIT_DEF)),
374 (!cast<Instruction>(!strconcat(baseOpc, "v8i8v")) V64:$Rn), bsub),
376 def : Pat<(i8 (intOp (v8i8 V64:$Rn))),
377 (!cast<Instruction>(!strconcat(baseOpc, "v8i8v")) V64:$Rn)>;
379 def : PatIgnoreCopies<(i32 (sext (i8 (intOp (v16i8 V128:$Rn))))),
381 (INSERT_SUBREG (v16i8 (IMPLICIT_DEF)),
382 (!cast<Instruction>(!strconcat(baseOpc, "v16i8v")) V128:$Rn), bsub),
384 def : Pat<(i8 (intOp (v16i8 V128:$Rn))),
385 (!cast<Instruction>(!strconcat(baseOpc, "v16i8v")) V128:$Rn)>;
387 def : PatIgnoreCopies<(i32 (sext (i16 (intOp (v4i16 V64:$Rn))))),
389 (INSERT_SUBREG (v16i8 (IMPLICIT_DEF)),
390 (!cast<Instruction>(!strconcat(baseOpc, "v4i16v")) V64:$Rn), hsub),
392 def : Pat<(i16 (intOp (v4i16 V64:$Rn))),
393 (!cast<Instruction>(!strconcat(baseOpc, "v4i16v")) V64:$Rn)>;
395 def : PatIgnoreCopies<(i32 (sext (i16 (intOp (v8i16 V128:$Rn))))),
397 (INSERT_SUBREG (v16i8 (IMPLICIT_DEF)),
398 (!cast<Instruction>(!strconcat(baseOpc, "v8i16v")) V128:$Rn), hsub),
400 def : Pat<(i16 (intOp (v8i16 V128:$Rn))),
401 (!cast<Instruction>(!strconcat(baseOpc, "v8i16v")) V128:$Rn)>;
403 def : PatIgnoreCopies<(i32 (intOp (v4i32 V128:$Rn))),
405 (INSERT_SUBREG (v16i8 (IMPLICIT_DEF)),
406 (!cast<Instruction>(!strconcat(baseOpc, "v4i32v")) V128:$Rn), ssub),
410 multiclass SIMDAcrossLanesUnsignedIntrinsicBHS<string baseOpc,
412 def : PatIgnoreCopies<(i32 (zext (i8 (intOp (v8i8 V64:$Rn))))),
415 (INSERT_SUBREG (v16i8 (IMPLICIT_DEF)),
416 (!cast<Instruction>(!strconcat(baseOpc, "v8i8v")) V64:$Rn), bsub),
419 def : Pat<(i8 (intOp (v8i8 V64:$Rn))),
420 (!cast<Instruction>(!strconcat(baseOpc, "v8i8v")) V64:$Rn)>;
422 def : PatIgnoreCopies<(i32 (zext (i8 (intOp (v16i8 V128:$Rn))))),
425 (INSERT_SUBREG (v16i8 (IMPLICIT_DEF)),
426 (!cast<Instruction>(!strconcat(baseOpc, "v16i8v")) V128:$Rn), bsub),
429 def : Pat<(i8 (intOp (v16i8 V128:$Rn))),
430 (!cast<Instruction>(!strconcat(baseOpc, "v16i8v")) V128:$Rn)>;
433 def : PatIgnoreCopies<(i32 (zext (i16 (intOp (v4i16 V64:$Rn))))),
436 (INSERT_SUBREG (v16i8 (IMPLICIT_DEF)),
437 (!cast<Instruction>(!strconcat(baseOpc, "v4i16v")) V64:$Rn), hsub),
440 def : Pat<(i16 (intOp (v4i16 V64:$Rn))),
441 (!cast<Instruction>(!strconcat(baseOpc, "v4i16v")) V64:$Rn)>;
443 def : PatIgnoreCopies<(i32 (zext (i16 (intOp (v8i16 V128:$Rn))))),
446 (INSERT_SUBREG (v16i8 (IMPLICIT_DEF)),
447 (!cast<Instruction>(!strconcat(baseOpc, "v8i16v")) V128:$Rn), hsub),
450 def : Pat<(i16 (intOp (v8i16 V128:$Rn))),
451 (!cast<Instruction>(!strconcat(baseOpc, "v8i16v")) V128:$Rn)>;
453 def : PatIgnoreCopies<(i32 (intOp (v4i32 V128:$Rn))),
455 (INSERT_SUBREG (v16i8 (IMPLICIT_DEF)),
456 (!cast<Instruction>(!strconcat(baseOpc, "v4i32v")) V128:$Rn), ssub),
461 defm : SIMDAcrossLanesSignedIntrinsicBHS<"ADDV", int_aarch64_neon_saddv>;
462 // vaddv_[su]32 is special; -> ADDP Vd.2S,Vn.2S,Vm.2S; return Vd.s[0];Vn==Vm
463 def : Pat<(i32 (int_aarch64_neon_saddv (v2i32 V64:$Rn))),
465 (INSERT_SUBREG (v16i8 (IMPLICIT_DEF)),
466 (ADDPv2i32 V64:$Rn, V64:$Rn), dsub),
469 def : Pat<(i64 (int_aarch64_neon_saddv (v2i64 V128:$Rn))),
471 (INSERT_SUBREG (v2i64 (IMPLICIT_DEF)),
472 (ADDPv2i64p V128:$Rn), dsub),
475 defm : SIMDAcrossLanesUnsignedIntrinsicBHS<"ADDV", int_aarch64_neon_uaddv>;
476 def : Pat<(i32 (int_aarch64_neon_uaddv (v2i32 V64:$Rn))),
478 (INSERT_SUBREG (v16i8 (IMPLICIT_DEF)),
479 (ADDPv2i32 V64:$Rn, V64:$Rn), dsub),
481 def : Pat<(i64 (int_aarch64_neon_uaddv (v2i64 V128:$Rn))),
483 (INSERT_SUBREG (v2i64 (IMPLICIT_DEF)),
484 (ADDPv2i64p V128:$Rn), dsub),
487 defm : SIMDAcrossLanesSignedIntrinsicBHS<"SMAXV", int_aarch64_neon_smaxv>;
488 def : Pat<(i32 (int_aarch64_neon_smaxv (v2i32 V64:$Rn))),
490 (INSERT_SUBREG (v16i8 (IMPLICIT_DEF)),
491 (SMAXPv2i32 V64:$Rn, V64:$Rn), dsub),
494 defm : SIMDAcrossLanesSignedIntrinsicBHS<"SMINV", int_aarch64_neon_sminv>;
495 def : Pat<(i32 (int_aarch64_neon_sminv (v2i32 V64:$Rn))),
497 (INSERT_SUBREG (v16i8 (IMPLICIT_DEF)),
498 (SMINPv2i32 V64:$Rn, V64:$Rn), dsub),
501 defm : SIMDAcrossLanesUnsignedIntrinsicBHS<"UMAXV", int_aarch64_neon_umaxv>;
502 def : Pat<(i32 (int_aarch64_neon_umaxv (v2i32 V64:$Rn))),
504 (INSERT_SUBREG (v16i8 (IMPLICIT_DEF)),
505 (UMAXPv2i32 V64:$Rn, V64:$Rn), dsub),
508 defm : SIMDAcrossLanesUnsignedIntrinsicBHS<"UMINV", int_aarch64_neon_uminv>;
509 def : Pat<(i32 (int_aarch64_neon_uminv (v2i32 V64:$Rn))),
511 (INSERT_SUBREG (v16i8 (IMPLICIT_DEF)),
512 (UMINPv2i32 V64:$Rn, V64:$Rn), dsub),
515 // Match stores from lane 0 to the appropriate subreg's store.
516 multiclass VecStoreLane64_0Pat<ComplexPattern UIAddrMode, SDPatternOperator storeop,
517 ValueType VTy, ValueType STy,
518 SubRegIndex SubRegIdx, Operand IndexType,
520 def : Pat<(storeop (STy (vector_extract (VTy VecListOne64:$Vt), (i64 0))),
521 (UIAddrMode GPR64sp:$Rn, IndexType:$offset)),
522 (STR (EXTRACT_SUBREG VecListOne64:$Vt, SubRegIdx),
523 GPR64sp:$Rn, IndexType:$offset)>;
525 multiclass VecStoreULane64_0Pat<SDPatternOperator StoreOp,
526 ValueType VTy, ValueType STy,
527 SubRegIndex SubRegIdx, Instruction STR> {
528 defm : VecStoreLane64_0Pat<am_unscaled64, StoreOp, VTy, STy, SubRegIdx, simm9, STR>;
531 multiclass VecROStoreLane64_0Pat<ROAddrMode ro, SDPatternOperator storeop,
532 ValueType VecTy, ValueType STy,
533 SubRegIndex SubRegIdx,
534 Instruction STRW, Instruction STRX> {
536 def : Pat<(storeop (STy (vector_extract (VecTy VecListOne64:$Vt), (i64 0))),
537 (ro.Wpat GPR64sp:$Rn, GPR32:$Rm, ro.Wext:$extend)),
538 (STRW (EXTRACT_SUBREG VecListOne64:$Vt, SubRegIdx),
539 GPR64sp:$Rn, GPR32:$Rm, ro.Wext:$extend)>;
541 def : Pat<(storeop (STy (vector_extract (VecTy VecListOne64:$Vt), (i64 0))),
542 (ro.Xpat GPR64sp:$Rn, GPR64:$Rm, ro.Xext:$extend)),
543 (STRX (EXTRACT_SUBREG VecListOne64:$Vt, SubRegIdx),
544 GPR64sp:$Rn, GPR64:$Rm, ro.Xext:$extend)>;
547 let AddedComplexity = 19 in {
548 def : St1Lane128Pat<store, VectorIndexB, v16i8, i8, ST1i8>;
549 def : St1Lane64Pat<store, VectorIndexB, v8i8, i8, ST1i8>;
551 defm : VecStoreLane64_0Pat<am_indexed16, store, v4i16, i16, hsub, uimm12s2, STRHui>;
552 defm : VecStoreLane64_0Pat<am_indexed32, store, v2i32, i32, ssub, uimm12s4, STRSui>;
554 defm : VecStoreULane64_0Pat<store, v4i16, i16, hsub, STURHi>;
555 defm : VecStoreULane64_0Pat<store, v2i32, i32, ssub, STURSi>;
556 defm : VecROStoreLane64_0Pat<ro16, store, v4i16, i16, hsub, STRHroW, STRHroX>;
557 defm : VecROStoreLane64_0Pat<ro32, store, v2i32, i32, ssub, STRSroW, STRSroX>;
560 def : Pat<(v8i8 (AArch64dup (i8 (load (am_indexed8 GPR64sp:$Rn))))),
561 (LD1Rv8b GPR64sp:$Rn)>;
562 def : Pat<(v16i8 (AArch64dup (i8 (load GPR64sp:$Rn)))),
563 (LD1Rv16b GPR64sp:$Rn)>;
564 def : Pat<(v4i16 (AArch64dup (i16 (load GPR64sp:$Rn)))),
565 (LD1Rv4h GPR64sp:$Rn)>;
566 def : Pat<(v8i16 (AArch64dup (i16 (load GPR64sp:$Rn)))),
567 (LD1Rv8h GPR64sp:$Rn)>;
568 def : Pat<(v2i32 (AArch64dup (i32 (load GPR64sp:$Rn)))),
569 (LD1Rv2s GPR64sp:$Rn)>;
570 def : Pat<(v4i32 (AArch64dup (i32 (load GPR64sp:$Rn)))),
571 (LD1Rv4s GPR64sp:$Rn)>;
572 def : Pat<(v2i64 (AArch64dup (i64 (load GPR64sp:$Rn)))),
573 (LD1Rv2d GPR64sp:$Rn)>;
574 def : Pat<(v1i64 (AArch64dup (i64 (load GPR64sp:$Rn)))),
575 (LD1Rv1d GPR64sp:$Rn)>;