blob: 123a3654c93d42b2c3a061222b5fe155404301b4 [file] [log] [blame]
Tim Northover3b0846e2014-05-24 12:50:23 +00001//===- AArch64InstrFormats.td - AArch64 Instruction Formats --*- tblgen -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10//===----------------------------------------------------------------------===//
11// Describe AArch64 instructions format here
12//
13
14// Format specifies the encoding used by the instruction. This is part of the
15// ad-hoc solution used to emit machine instruction encodings by our machine
16// code emitter.
17class Format<bits<2> val> {
18 bits<2> Value = val;
19}
20
21def PseudoFrm : Format<0>;
22def NormalFrm : Format<1>; // Do we need any others?
23
24// AArch64 Instruction Format
25class AArch64Inst<Format f, string cstr> : Instruction {
26 field bits<32> Inst; // Instruction encoding.
27 // Mask of bits that cause an encoding to be UNPREDICTABLE.
28 // If a bit is set, then if the corresponding bit in the
29 // target encoding differs from its value in the "Inst" field,
30 // the instruction is UNPREDICTABLE (SoftFail in abstract parlance).
31 field bits<32> Unpredictable = 0;
32 // SoftFail is the generic name for this field, but we alias it so
33 // as to make it more obvious what it means in ARM-land.
34 field bits<32> SoftFail = Unpredictable;
35 let Namespace = "AArch64";
36 Format F = f;
37 bits<2> Form = F.Value;
38 let Pattern = [];
39 let Constraints = cstr;
40}
41
42// Pseudo instructions (don't have encoding information)
43class Pseudo<dag oops, dag iops, list<dag> pattern, string cstr = "">
44 : AArch64Inst<PseudoFrm, cstr> {
45 dag OutOperandList = oops;
46 dag InOperandList = iops;
47 let Pattern = pattern;
48 let isCodeGenOnly = 1;
49}
50
51// Real instructions (have encoding information)
52class EncodedI<string cstr, list<dag> pattern> : AArch64Inst<NormalFrm, cstr> {
53 let Pattern = pattern;
54 let Size = 4;
55}
56
57// Normal instructions
58class I<dag oops, dag iops, string asm, string operands, string cstr,
59 list<dag> pattern>
60 : EncodedI<cstr, pattern> {
61 dag OutOperandList = oops;
62 dag InOperandList = iops;
63 let AsmString = !strconcat(asm, operands);
64}
65
66class TriOpFrag<dag res> : PatFrag<(ops node:$LHS, node:$MHS, node:$RHS), res>;
67class BinOpFrag<dag res> : PatFrag<(ops node:$LHS, node:$RHS), res>;
68class UnOpFrag<dag res> : PatFrag<(ops node:$LHS), res>;
69
70// Helper fragment for an extract of the high portion of a 128-bit vector.
71def extract_high_v16i8 :
72 UnOpFrag<(extract_subvector (v16i8 node:$LHS), (i64 8))>;
73def extract_high_v8i16 :
74 UnOpFrag<(extract_subvector (v8i16 node:$LHS), (i64 4))>;
75def extract_high_v4i32 :
76 UnOpFrag<(extract_subvector (v4i32 node:$LHS), (i64 2))>;
77def extract_high_v2i64 :
78 UnOpFrag<(extract_subvector (v2i64 node:$LHS), (i64 1))>;
79
80//===----------------------------------------------------------------------===//
81// Asm Operand Classes.
82//
83
84// Shifter operand for arithmetic shifted encodings.
85def ShifterOperand : AsmOperandClass {
86 let Name = "Shifter";
87}
88
89// Shifter operand for mov immediate encodings.
90def MovImm32ShifterOperand : AsmOperandClass {
91 let SuperClasses = [ShifterOperand];
92 let Name = "MovImm32Shifter";
93 let RenderMethod = "addShifterOperands";
94 let DiagnosticType = "InvalidMovImm32Shift";
95}
96def MovImm64ShifterOperand : AsmOperandClass {
97 let SuperClasses = [ShifterOperand];
98 let Name = "MovImm64Shifter";
99 let RenderMethod = "addShifterOperands";
100 let DiagnosticType = "InvalidMovImm64Shift";
101}
102
103// Shifter operand for arithmetic register shifted encodings.
104class ArithmeticShifterOperand<int width> : AsmOperandClass {
105 let SuperClasses = [ShifterOperand];
106 let Name = "ArithmeticShifter" # width;
107 let PredicateMethod = "isArithmeticShifter<" # width # ">";
108 let RenderMethod = "addShifterOperands";
109 let DiagnosticType = "AddSubRegShift" # width;
110}
111
112def ArithmeticShifterOperand32 : ArithmeticShifterOperand<32>;
113def ArithmeticShifterOperand64 : ArithmeticShifterOperand<64>;
114
115// Shifter operand for logical register shifted encodings.
116class LogicalShifterOperand<int width> : AsmOperandClass {
117 let SuperClasses = [ShifterOperand];
118 let Name = "LogicalShifter" # width;
119 let PredicateMethod = "isLogicalShifter<" # width # ">";
120 let RenderMethod = "addShifterOperands";
121 let DiagnosticType = "AddSubRegShift" # width;
122}
123
124def LogicalShifterOperand32 : LogicalShifterOperand<32>;
125def LogicalShifterOperand64 : LogicalShifterOperand<64>;
126
127// Shifter operand for logical vector 128/64-bit shifted encodings.
128def LogicalVecShifterOperand : AsmOperandClass {
129 let SuperClasses = [ShifterOperand];
130 let Name = "LogicalVecShifter";
131 let RenderMethod = "addShifterOperands";
132}
133def LogicalVecHalfWordShifterOperand : AsmOperandClass {
134 let SuperClasses = [LogicalVecShifterOperand];
135 let Name = "LogicalVecHalfWordShifter";
136 let RenderMethod = "addShifterOperands";
137}
138
139// The "MSL" shifter on the vector MOVI instruction.
140def MoveVecShifterOperand : AsmOperandClass {
141 let SuperClasses = [ShifterOperand];
142 let Name = "MoveVecShifter";
143 let RenderMethod = "addShifterOperands";
144}
145
146// Extend operand for arithmetic encodings.
147def ExtendOperand : AsmOperandClass {
148 let Name = "Extend";
149 let DiagnosticType = "AddSubRegExtendLarge";
150}
151def ExtendOperand64 : AsmOperandClass {
152 let SuperClasses = [ExtendOperand];
153 let Name = "Extend64";
154 let DiagnosticType = "AddSubRegExtendSmall";
155}
156// 'extend' that's a lsl of a 64-bit register.
157def ExtendOperandLSL64 : AsmOperandClass {
158 let SuperClasses = [ExtendOperand];
159 let Name = "ExtendLSL64";
160 let RenderMethod = "addExtend64Operands";
161 let DiagnosticType = "AddSubRegExtendLarge";
162}
163
164// 8-bit floating-point immediate encodings.
165def FPImmOperand : AsmOperandClass {
166 let Name = "FPImm";
167 let ParserMethod = "tryParseFPImm";
168 let DiagnosticType = "InvalidFPImm";
169}
170
171def CondCode : AsmOperandClass {
172 let Name = "CondCode";
173 let DiagnosticType = "InvalidCondCode";
174}
175
176// A 32-bit register pasrsed as 64-bit
177def GPR32as64Operand : AsmOperandClass {
178 let Name = "GPR32as64";
179}
180def GPR32as64 : RegisterOperand<GPR32> {
181 let ParserMatchClass = GPR32as64Operand;
182}
183
184// 8-bit immediate for AdvSIMD where 64-bit values of the form:
185// aaaaaaaa bbbbbbbb cccccccc dddddddd eeeeeeee ffffffff gggggggg hhhhhhhh
186// are encoded as the eight bit value 'abcdefgh'.
187def SIMDImmType10Operand : AsmOperandClass { let Name = "SIMDImmType10"; }
188
189
190//===----------------------------------------------------------------------===//
191// Operand Definitions.
192//
193
194// ADR[P] instruction labels.
195def AdrpOperand : AsmOperandClass {
196 let Name = "AdrpLabel";
197 let ParserMethod = "tryParseAdrpLabel";
198 let DiagnosticType = "InvalidLabel";
199}
200def adrplabel : Operand<i64> {
201 let EncoderMethod = "getAdrLabelOpValue";
202 let PrintMethod = "printAdrpLabel";
203 let ParserMatchClass = AdrpOperand;
204}
205
206def AdrOperand : AsmOperandClass {
207 let Name = "AdrLabel";
208 let ParserMethod = "tryParseAdrLabel";
209 let DiagnosticType = "InvalidLabel";
210}
211def adrlabel : Operand<i64> {
212 let EncoderMethod = "getAdrLabelOpValue";
213 let ParserMatchClass = AdrOperand;
214}
215
216// simm9 predicate - True if the immediate is in the range [-256, 255].
217def SImm9Operand : AsmOperandClass {
218 let Name = "SImm9";
219 let DiagnosticType = "InvalidMemoryIndexedSImm9";
220}
221def simm9 : Operand<i64>, ImmLeaf<i64, [{ return Imm >= -256 && Imm < 256; }]> {
222 let ParserMatchClass = SImm9Operand;
223}
224
225// simm7sN predicate - True if the immediate is a multiple of N in the range
226// [-64 * N, 63 * N].
227class SImm7Scaled<int Scale> : AsmOperandClass {
228 let Name = "SImm7s" # Scale;
229 let DiagnosticType = "InvalidMemoryIndexed" # Scale # "SImm7";
230}
231
232def SImm7s4Operand : SImm7Scaled<4>;
233def SImm7s8Operand : SImm7Scaled<8>;
234def SImm7s16Operand : SImm7Scaled<16>;
235
236def simm7s4 : Operand<i32> {
237 let ParserMatchClass = SImm7s4Operand;
238 let PrintMethod = "printImmScale<4>";
239}
240
241def simm7s8 : Operand<i32> {
242 let ParserMatchClass = SImm7s8Operand;
243 let PrintMethod = "printImmScale<8>";
244}
245
246def simm7s16 : Operand<i32> {
247 let ParserMatchClass = SImm7s16Operand;
248 let PrintMethod = "printImmScale<16>";
249}
250
251class AsmImmRange<int Low, int High> : AsmOperandClass {
252 let Name = "Imm" # Low # "_" # High;
253 let DiagnosticType = "InvalidImm" # Low # "_" # High;
254}
255
256def Imm1_8Operand : AsmImmRange<1, 8>;
257def Imm1_16Operand : AsmImmRange<1, 16>;
258def Imm1_32Operand : AsmImmRange<1, 32>;
259def Imm1_64Operand : AsmImmRange<1, 64>;
260
261def MovZSymbolG3AsmOperand : AsmOperandClass {
262 let Name = "MovZSymbolG3";
263 let RenderMethod = "addImmOperands";
264}
265
266def movz_symbol_g3 : Operand<i32> {
267 let ParserMatchClass = MovZSymbolG3AsmOperand;
268}
269
270def MovZSymbolG2AsmOperand : AsmOperandClass {
271 let Name = "MovZSymbolG2";
272 let RenderMethod = "addImmOperands";
273}
274
275def movz_symbol_g2 : Operand<i32> {
276 let ParserMatchClass = MovZSymbolG2AsmOperand;
277}
278
279def MovZSymbolG1AsmOperand : AsmOperandClass {
280 let Name = "MovZSymbolG1";
281 let RenderMethod = "addImmOperands";
282}
283
284def movz_symbol_g1 : Operand<i32> {
285 let ParserMatchClass = MovZSymbolG1AsmOperand;
286}
287
288def MovZSymbolG0AsmOperand : AsmOperandClass {
289 let Name = "MovZSymbolG0";
290 let RenderMethod = "addImmOperands";
291}
292
293def movz_symbol_g0 : Operand<i32> {
294 let ParserMatchClass = MovZSymbolG0AsmOperand;
295}
296
297def MovKSymbolG3AsmOperand : AsmOperandClass {
298 let Name = "MovKSymbolG3";
299 let RenderMethod = "addImmOperands";
300}
301
302def movk_symbol_g3 : Operand<i32> {
303 let ParserMatchClass = MovKSymbolG3AsmOperand;
304}
305
306def MovKSymbolG2AsmOperand : AsmOperandClass {
307 let Name = "MovKSymbolG2";
308 let RenderMethod = "addImmOperands";
309}
310
311def movk_symbol_g2 : Operand<i32> {
312 let ParserMatchClass = MovKSymbolG2AsmOperand;
313}
314
315def MovKSymbolG1AsmOperand : AsmOperandClass {
316 let Name = "MovKSymbolG1";
317 let RenderMethod = "addImmOperands";
318}
319
320def movk_symbol_g1 : Operand<i32> {
321 let ParserMatchClass = MovKSymbolG1AsmOperand;
322}
323
324def MovKSymbolG0AsmOperand : AsmOperandClass {
325 let Name = "MovKSymbolG0";
326 let RenderMethod = "addImmOperands";
327}
328
329def movk_symbol_g0 : Operand<i32> {
330 let ParserMatchClass = MovKSymbolG0AsmOperand;
331}
332
333class fixedpoint_i32<ValueType FloatVT>
334 : Operand<FloatVT>,
335 ComplexPattern<FloatVT, 1, "SelectCVTFixedPosOperand<32>", [fpimm, ld]> {
336 let EncoderMethod = "getFixedPointScaleOpValue";
337 let DecoderMethod = "DecodeFixedPointScaleImm32";
338 let ParserMatchClass = Imm1_32Operand;
339}
340
341class fixedpoint_i64<ValueType FloatVT>
342 : Operand<FloatVT>,
343 ComplexPattern<FloatVT, 1, "SelectCVTFixedPosOperand<64>", [fpimm, ld]> {
344 let EncoderMethod = "getFixedPointScaleOpValue";
345 let DecoderMethod = "DecodeFixedPointScaleImm64";
346 let ParserMatchClass = Imm1_64Operand;
347}
348
349def fixedpoint_f32_i32 : fixedpoint_i32<f32>;
350def fixedpoint_f64_i32 : fixedpoint_i32<f64>;
351
352def fixedpoint_f32_i64 : fixedpoint_i64<f32>;
353def fixedpoint_f64_i64 : fixedpoint_i64<f64>;
354
355def vecshiftR8 : Operand<i32>, ImmLeaf<i32, [{
356 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 9);
357}]> {
358 let EncoderMethod = "getVecShiftR8OpValue";
359 let DecoderMethod = "DecodeVecShiftR8Imm";
360 let ParserMatchClass = Imm1_8Operand;
361}
362def vecshiftR16 : Operand<i32>, ImmLeaf<i32, [{
363 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 17);
364}]> {
365 let EncoderMethod = "getVecShiftR16OpValue";
366 let DecoderMethod = "DecodeVecShiftR16Imm";
367 let ParserMatchClass = Imm1_16Operand;
368}
369def vecshiftR16Narrow : Operand<i32>, ImmLeaf<i32, [{
370 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 9);
371}]> {
372 let EncoderMethod = "getVecShiftR16OpValue";
373 let DecoderMethod = "DecodeVecShiftR16ImmNarrow";
374 let ParserMatchClass = Imm1_8Operand;
375}
376def vecshiftR32 : Operand<i32>, ImmLeaf<i32, [{
377 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 33);
378}]> {
379 let EncoderMethod = "getVecShiftR32OpValue";
380 let DecoderMethod = "DecodeVecShiftR32Imm";
381 let ParserMatchClass = Imm1_32Operand;
382}
383def vecshiftR32Narrow : Operand<i32>, ImmLeaf<i32, [{
384 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 17);
385}]> {
386 let EncoderMethod = "getVecShiftR32OpValue";
387 let DecoderMethod = "DecodeVecShiftR32ImmNarrow";
388 let ParserMatchClass = Imm1_16Operand;
389}
390def vecshiftR64 : Operand<i32>, ImmLeaf<i32, [{
391 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 65);
392}]> {
393 let EncoderMethod = "getVecShiftR64OpValue";
394 let DecoderMethod = "DecodeVecShiftR64Imm";
395 let ParserMatchClass = Imm1_64Operand;
396}
397def vecshiftR64Narrow : Operand<i32>, ImmLeaf<i32, [{
398 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 33);
399}]> {
400 let EncoderMethod = "getVecShiftR64OpValue";
401 let DecoderMethod = "DecodeVecShiftR64ImmNarrow";
402 let ParserMatchClass = Imm1_32Operand;
403}
404
405def Imm0_7Operand : AsmImmRange<0, 7>;
406def Imm0_15Operand : AsmImmRange<0, 15>;
407def Imm0_31Operand : AsmImmRange<0, 31>;
408def Imm0_63Operand : AsmImmRange<0, 63>;
409
410def vecshiftL8 : Operand<i32>, ImmLeaf<i32, [{
411 return (((uint32_t)Imm) < 8);
412}]> {
413 let EncoderMethod = "getVecShiftL8OpValue";
414 let DecoderMethod = "DecodeVecShiftL8Imm";
415 let ParserMatchClass = Imm0_7Operand;
416}
417def vecshiftL16 : Operand<i32>, ImmLeaf<i32, [{
418 return (((uint32_t)Imm) < 16);
419}]> {
420 let EncoderMethod = "getVecShiftL16OpValue";
421 let DecoderMethod = "DecodeVecShiftL16Imm";
422 let ParserMatchClass = Imm0_15Operand;
423}
424def vecshiftL32 : Operand<i32>, ImmLeaf<i32, [{
425 return (((uint32_t)Imm) < 32);
426}]> {
427 let EncoderMethod = "getVecShiftL32OpValue";
428 let DecoderMethod = "DecodeVecShiftL32Imm";
429 let ParserMatchClass = Imm0_31Operand;
430}
431def vecshiftL64 : Operand<i32>, ImmLeaf<i32, [{
432 return (((uint32_t)Imm) < 64);
433}]> {
434 let EncoderMethod = "getVecShiftL64OpValue";
435 let DecoderMethod = "DecodeVecShiftL64Imm";
436 let ParserMatchClass = Imm0_63Operand;
437}
438
439
440// Crazy immediate formats used by 32-bit and 64-bit logical immediate
441// instructions for splatting repeating bit patterns across the immediate.
442def logical_imm32_XFORM : SDNodeXForm<imm, [{
443 uint64_t enc = AArch64_AM::encodeLogicalImmediate(N->getZExtValue(), 32);
Sergey Dmitrouk842a51b2015-04-28 14:05:47 +0000444 return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32);
Tim Northover3b0846e2014-05-24 12:50:23 +0000445}]>;
446def logical_imm64_XFORM : SDNodeXForm<imm, [{
447 uint64_t enc = AArch64_AM::encodeLogicalImmediate(N->getZExtValue(), 64);
Sergey Dmitrouk842a51b2015-04-28 14:05:47 +0000448 return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32);
Tim Northover3b0846e2014-05-24 12:50:23 +0000449}]>;
450
Arnaud A. de Grandmaisonf6432312014-07-10 15:12:26 +0000451let DiagnosticType = "LogicalSecondSource" in {
452 def LogicalImm32Operand : AsmOperandClass {
453 let Name = "LogicalImm32";
454 }
455 def LogicalImm64Operand : AsmOperandClass {
456 let Name = "LogicalImm64";
457 }
458 def LogicalImm32NotOperand : AsmOperandClass {
459 let Name = "LogicalImm32Not";
460 }
461 def LogicalImm64NotOperand : AsmOperandClass {
462 let Name = "LogicalImm64Not";
463 }
Tim Northover3b0846e2014-05-24 12:50:23 +0000464}
465def logical_imm32 : Operand<i32>, PatLeaf<(imm), [{
466 return AArch64_AM::isLogicalImmediate(N->getZExtValue(), 32);
467}], logical_imm32_XFORM> {
468 let PrintMethod = "printLogicalImm32";
469 let ParserMatchClass = LogicalImm32Operand;
470}
471def logical_imm64 : Operand<i64>, PatLeaf<(imm), [{
472 return AArch64_AM::isLogicalImmediate(N->getZExtValue(), 64);
473}], logical_imm64_XFORM> {
474 let PrintMethod = "printLogicalImm64";
475 let ParserMatchClass = LogicalImm64Operand;
476}
Arnaud A. de Grandmaisonf6432312014-07-10 15:12:26 +0000477def logical_imm32_not : Operand<i32> {
478 let ParserMatchClass = LogicalImm32NotOperand;
479}
480def logical_imm64_not : Operand<i64> {
481 let ParserMatchClass = LogicalImm64NotOperand;
482}
Tim Northover3b0846e2014-05-24 12:50:23 +0000483
484// imm0_65535 predicate - True if the immediate is in the range [0,65535].
485def Imm0_65535Operand : AsmImmRange<0, 65535>;
486def imm0_65535 : Operand<i32>, ImmLeaf<i32, [{
487 return ((uint32_t)Imm) < 65536;
488}]> {
489 let ParserMatchClass = Imm0_65535Operand;
490 let PrintMethod = "printHexImm";
491}
492
493// imm0_255 predicate - True if the immediate is in the range [0,255].
494def Imm0_255Operand : AsmOperandClass { let Name = "Imm0_255"; }
495def imm0_255 : Operand<i32>, ImmLeaf<i32, [{
496 return ((uint32_t)Imm) < 256;
497}]> {
498 let ParserMatchClass = Imm0_255Operand;
499 let PrintMethod = "printHexImm";
500}
501
502// imm0_127 predicate - True if the immediate is in the range [0,127]
503def Imm0_127Operand : AsmImmRange<0, 127>;
504def imm0_127 : Operand<i32>, ImmLeaf<i32, [{
505 return ((uint32_t)Imm) < 128;
506}]> {
507 let ParserMatchClass = Imm0_127Operand;
508 let PrintMethod = "printHexImm";
509}
510
511// NOTE: These imm0_N operands have to be of type i64 because i64 is the size
512// for all shift-amounts.
513
514// imm0_63 predicate - True if the immediate is in the range [0,63]
515def imm0_63 : Operand<i64>, ImmLeaf<i64, [{
516 return ((uint64_t)Imm) < 64;
517}]> {
518 let ParserMatchClass = Imm0_63Operand;
519}
520
521// imm0_31 predicate - True if the immediate is in the range [0,31]
522def imm0_31 : Operand<i64>, ImmLeaf<i64, [{
523 return ((uint64_t)Imm) < 32;
524}]> {
525 let ParserMatchClass = Imm0_31Operand;
526}
527
Matthias Braunaf7d7702015-07-16 20:02:37 +0000528// True if the 32-bit immediate is in the range [0,31]
529def imm32_0_31 : Operand<i32>, ImmLeaf<i32, [{
530 return ((uint64_t)Imm) < 32;
531}]> {
532 let ParserMatchClass = Imm0_31Operand;
533}
534
Tim Northover3b0846e2014-05-24 12:50:23 +0000535// imm0_15 predicate - True if the immediate is in the range [0,15]
536def imm0_15 : Operand<i64>, ImmLeaf<i64, [{
537 return ((uint64_t)Imm) < 16;
538}]> {
539 let ParserMatchClass = Imm0_15Operand;
540}
541
542// imm0_7 predicate - True if the immediate is in the range [0,7]
543def imm0_7 : Operand<i64>, ImmLeaf<i64, [{
544 return ((uint64_t)Imm) < 8;
545}]> {
546 let ParserMatchClass = Imm0_7Operand;
547}
548
Yi Kong23550662014-07-17 10:50:20 +0000549// imm32_0_15 predicate - True if the 32-bit immediate is in the range [0,15]
550def imm32_0_15 : Operand<i32>, ImmLeaf<i32, [{
551 return ((uint32_t)Imm) < 16;
Matthias Braunaf7d7702015-07-16 20:02:37 +0000552}]> {
553 let ParserMatchClass = Imm0_15Operand;
554}
Yi Kong23550662014-07-17 10:50:20 +0000555
Tim Northover3b0846e2014-05-24 12:50:23 +0000556// An arithmetic shifter operand:
557// {7-6} - shift type: 00 = lsl, 01 = lsr, 10 = asr
558// {5-0} - imm6
559class arith_shift<ValueType Ty, int width> : Operand<Ty> {
560 let PrintMethod = "printShifter";
561 let ParserMatchClass = !cast<AsmOperandClass>(
562 "ArithmeticShifterOperand" # width);
563}
564
565def arith_shift32 : arith_shift<i32, 32>;
566def arith_shift64 : arith_shift<i64, 64>;
567
568class arith_shifted_reg<ValueType Ty, RegisterClass regclass, int width>
569 : Operand<Ty>,
570 ComplexPattern<Ty, 2, "SelectArithShiftedRegister", []> {
571 let PrintMethod = "printShiftedRegister";
572 let MIOperandInfo = (ops regclass, !cast<Operand>("arith_shift" # width));
573}
574
575def arith_shifted_reg32 : arith_shifted_reg<i32, GPR32, 32>;
576def arith_shifted_reg64 : arith_shifted_reg<i64, GPR64, 64>;
577
578// An arithmetic shifter operand:
579// {7-6} - shift type: 00 = lsl, 01 = lsr, 10 = asr, 11 = ror
580// {5-0} - imm6
581class logical_shift<int width> : Operand<i32> {
582 let PrintMethod = "printShifter";
583 let ParserMatchClass = !cast<AsmOperandClass>(
584 "LogicalShifterOperand" # width);
585}
586
587def logical_shift32 : logical_shift<32>;
588def logical_shift64 : logical_shift<64>;
589
590class logical_shifted_reg<ValueType Ty, RegisterClass regclass, Operand shiftop>
591 : Operand<Ty>,
592 ComplexPattern<Ty, 2, "SelectLogicalShiftedRegister", []> {
593 let PrintMethod = "printShiftedRegister";
594 let MIOperandInfo = (ops regclass, shiftop);
595}
596
597def logical_shifted_reg32 : logical_shifted_reg<i32, GPR32, logical_shift32>;
598def logical_shifted_reg64 : logical_shifted_reg<i64, GPR64, logical_shift64>;
599
600// A logical vector shifter operand:
601// {7-6} - shift type: 00 = lsl
602// {5-0} - imm6: #0, #8, #16, or #24
603def logical_vec_shift : Operand<i32> {
604 let PrintMethod = "printShifter";
605 let EncoderMethod = "getVecShifterOpValue";
606 let ParserMatchClass = LogicalVecShifterOperand;
607}
608
609// A logical vector half-word shifter operand:
610// {7-6} - shift type: 00 = lsl
611// {5-0} - imm6: #0 or #8
612def logical_vec_hw_shift : Operand<i32> {
613 let PrintMethod = "printShifter";
614 let EncoderMethod = "getVecShifterOpValue";
615 let ParserMatchClass = LogicalVecHalfWordShifterOperand;
616}
617
618// A vector move shifter operand:
619// {0} - imm1: #8 or #16
620def move_vec_shift : Operand<i32> {
621 let PrintMethod = "printShifter";
622 let EncoderMethod = "getMoveVecShifterOpValue";
623 let ParserMatchClass = MoveVecShifterOperand;
624}
625
Arnaud A. de Grandmaison650c5202015-07-01 15:05:58 +0000626let DiagnosticType = "AddSubSecondSource" in {
627 def AddSubImmOperand : AsmOperandClass {
628 let Name = "AddSubImm";
629 let ParserMethod = "tryParseAddSubImm";
630 }
631 def AddSubImmNegOperand : AsmOperandClass {
632 let Name = "AddSubImmNeg";
633 let ParserMethod = "tryParseAddSubImm";
634 }
Tim Northover3b0846e2014-05-24 12:50:23 +0000635}
636// An ADD/SUB immediate shifter operand:
637// second operand:
638// {7-6} - shift type: 00 = lsl
639// {5-0} - imm6: #0 or #12
640class addsub_shifted_imm<ValueType Ty>
641 : Operand<Ty>, ComplexPattern<Ty, 2, "SelectArithImmed", [imm]> {
642 let PrintMethod = "printAddSubImm";
643 let EncoderMethod = "getAddSubImmOpValue";
644 let ParserMatchClass = AddSubImmOperand;
645 let MIOperandInfo = (ops i32imm, i32imm);
646}
647
Arnaud A. de Grandmaison650c5202015-07-01 15:05:58 +0000648class addsub_shifted_imm_neg<ValueType Ty>
649 : Operand<Ty> {
650 let EncoderMethod = "getAddSubImmOpValue";
651 let ParserMatchClass = AddSubImmNegOperand;
652 let MIOperandInfo = (ops i32imm, i32imm);
653}
654
Tim Northover3b0846e2014-05-24 12:50:23 +0000655def addsub_shifted_imm32 : addsub_shifted_imm<i32>;
656def addsub_shifted_imm64 : addsub_shifted_imm<i64>;
Arnaud A. de Grandmaison650c5202015-07-01 15:05:58 +0000657def addsub_shifted_imm32_neg : addsub_shifted_imm_neg<i32>;
658def addsub_shifted_imm64_neg : addsub_shifted_imm_neg<i64>;
Tim Northover3b0846e2014-05-24 12:50:23 +0000659
660class neg_addsub_shifted_imm<ValueType Ty>
661 : Operand<Ty>, ComplexPattern<Ty, 2, "SelectNegArithImmed", [imm]> {
662 let PrintMethod = "printAddSubImm";
663 let EncoderMethod = "getAddSubImmOpValue";
664 let ParserMatchClass = AddSubImmOperand;
665 let MIOperandInfo = (ops i32imm, i32imm);
666}
667
668def neg_addsub_shifted_imm32 : neg_addsub_shifted_imm<i32>;
669def neg_addsub_shifted_imm64 : neg_addsub_shifted_imm<i64>;
670
671// An extend operand:
672// {5-3} - extend type
673// {2-0} - imm3
674def arith_extend : Operand<i32> {
675 let PrintMethod = "printArithExtend";
676 let ParserMatchClass = ExtendOperand;
677}
678def arith_extend64 : Operand<i32> {
679 let PrintMethod = "printArithExtend";
680 let ParserMatchClass = ExtendOperand64;
681}
682
683// 'extend' that's a lsl of a 64-bit register.
684def arith_extendlsl64 : Operand<i32> {
685 let PrintMethod = "printArithExtend";
686 let ParserMatchClass = ExtendOperandLSL64;
687}
688
689class arith_extended_reg32<ValueType Ty> : Operand<Ty>,
690 ComplexPattern<Ty, 2, "SelectArithExtendedRegister", []> {
691 let PrintMethod = "printExtendedRegister";
692 let MIOperandInfo = (ops GPR32, arith_extend);
693}
694
695class arith_extended_reg32to64<ValueType Ty> : Operand<Ty>,
696 ComplexPattern<Ty, 2, "SelectArithExtendedRegister", []> {
697 let PrintMethod = "printExtendedRegister";
698 let MIOperandInfo = (ops GPR32, arith_extend64);
699}
700
701// Floating-point immediate.
702def fpimm32 : Operand<f32>,
703 PatLeaf<(f32 fpimm), [{
704 return AArch64_AM::getFP32Imm(N->getValueAPF()) != -1;
705 }], SDNodeXForm<fpimm, [{
706 APFloat InVal = N->getValueAPF();
707 uint32_t enc = AArch64_AM::getFP32Imm(InVal);
Sergey Dmitrouk842a51b2015-04-28 14:05:47 +0000708 return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32);
Tim Northover3b0846e2014-05-24 12:50:23 +0000709 }]>> {
710 let ParserMatchClass = FPImmOperand;
711 let PrintMethod = "printFPImmOperand";
712}
713def fpimm64 : Operand<f64>,
714 PatLeaf<(f64 fpimm), [{
715 return AArch64_AM::getFP64Imm(N->getValueAPF()) != -1;
716 }], SDNodeXForm<fpimm, [{
717 APFloat InVal = N->getValueAPF();
718 uint32_t enc = AArch64_AM::getFP64Imm(InVal);
Sergey Dmitrouk842a51b2015-04-28 14:05:47 +0000719 return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32);
Tim Northover3b0846e2014-05-24 12:50:23 +0000720 }]>> {
721 let ParserMatchClass = FPImmOperand;
722 let PrintMethod = "printFPImmOperand";
723}
724
725def fpimm8 : Operand<i32> {
726 let ParserMatchClass = FPImmOperand;
727 let PrintMethod = "printFPImmOperand";
728}
729
730def fpimm0 : PatLeaf<(fpimm), [{
731 return N->isExactlyValue(+0.0);
732}]>;
733
734// Vector lane operands
735class AsmVectorIndex<string Suffix> : AsmOperandClass {
736 let Name = "VectorIndex" # Suffix;
737 let DiagnosticType = "InvalidIndex" # Suffix;
738}
739def VectorIndex1Operand : AsmVectorIndex<"1">;
740def VectorIndexBOperand : AsmVectorIndex<"B">;
741def VectorIndexHOperand : AsmVectorIndex<"H">;
742def VectorIndexSOperand : AsmVectorIndex<"S">;
743def VectorIndexDOperand : AsmVectorIndex<"D">;
744
745def VectorIndex1 : Operand<i64>, ImmLeaf<i64, [{
746 return ((uint64_t)Imm) == 1;
747}]> {
748 let ParserMatchClass = VectorIndex1Operand;
749 let PrintMethod = "printVectorIndex";
750 let MIOperandInfo = (ops i64imm);
751}
752def VectorIndexB : Operand<i64>, ImmLeaf<i64, [{
753 return ((uint64_t)Imm) < 16;
754}]> {
755 let ParserMatchClass = VectorIndexBOperand;
756 let PrintMethod = "printVectorIndex";
757 let MIOperandInfo = (ops i64imm);
758}
759def VectorIndexH : Operand<i64>, ImmLeaf<i64, [{
760 return ((uint64_t)Imm) < 8;
761}]> {
762 let ParserMatchClass = VectorIndexHOperand;
763 let PrintMethod = "printVectorIndex";
764 let MIOperandInfo = (ops i64imm);
765}
766def VectorIndexS : Operand<i64>, ImmLeaf<i64, [{
767 return ((uint64_t)Imm) < 4;
768}]> {
769 let ParserMatchClass = VectorIndexSOperand;
770 let PrintMethod = "printVectorIndex";
771 let MIOperandInfo = (ops i64imm);
772}
773def VectorIndexD : Operand<i64>, ImmLeaf<i64, [{
774 return ((uint64_t)Imm) < 2;
775}]> {
776 let ParserMatchClass = VectorIndexDOperand;
777 let PrintMethod = "printVectorIndex";
778 let MIOperandInfo = (ops i64imm);
779}
780
781// 8-bit immediate for AdvSIMD where 64-bit values of the form:
782// aaaaaaaa bbbbbbbb cccccccc dddddddd eeeeeeee ffffffff gggggggg hhhhhhhh
783// are encoded as the eight bit value 'abcdefgh'.
784def simdimmtype10 : Operand<i32>,
785 PatLeaf<(f64 fpimm), [{
786 return AArch64_AM::isAdvSIMDModImmType10(N->getValueAPF()
787 .bitcastToAPInt()
788 .getZExtValue());
789 }], SDNodeXForm<fpimm, [{
790 APFloat InVal = N->getValueAPF();
791 uint32_t enc = AArch64_AM::encodeAdvSIMDModImmType10(N->getValueAPF()
792 .bitcastToAPInt()
793 .getZExtValue());
Sergey Dmitrouk842a51b2015-04-28 14:05:47 +0000794 return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32);
Tim Northover3b0846e2014-05-24 12:50:23 +0000795 }]>> {
796 let ParserMatchClass = SIMDImmType10Operand;
797 let PrintMethod = "printSIMDType10Operand";
798}
799
800
801//---
802// System management
803//---
804
805// Base encoding for system instruction operands.
806let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in
Saleem Abdulrasoolf74d48a2014-07-12 21:20:49 +0000807class BaseSystemI<bit L, dag oops, dag iops, string asm, string operands,
808 list<dag> pattern = []>
809 : I<oops, iops, asm, operands, "", pattern> {
Tim Northover3b0846e2014-05-24 12:50:23 +0000810 let Inst{31-22} = 0b1101010100;
811 let Inst{21} = L;
812}
813
814// System instructions which do not have an Rt register.
Saleem Abdulrasoolf74d48a2014-07-12 21:20:49 +0000815class SimpleSystemI<bit L, dag iops, string asm, string operands,
816 list<dag> pattern = []>
817 : BaseSystemI<L, (outs), iops, asm, operands, pattern> {
Tim Northover3b0846e2014-05-24 12:50:23 +0000818 let Inst{4-0} = 0b11111;
819}
820
821// System instructions which have an Rt register.
822class RtSystemI<bit L, dag oops, dag iops, string asm, string operands>
823 : BaseSystemI<L, oops, iops, asm, operands>,
824 Sched<[WriteSys]> {
825 bits<5> Rt;
826 let Inst{4-0} = Rt;
827}
828
829// Hint instructions that take both a CRm and a 3-bit immediate.
Saleem Abdulrasoolf74d48a2014-07-12 21:20:49 +0000830// NOTE: ideally, this would have mayStore = 0, mayLoad = 0, but we cannot
831// model patterns with sufficiently fine granularity
832let mayStore = 1, mayLoad = 1, hasSideEffects = 1 in
833 class HintI<string mnemonic>
834 : SimpleSystemI<0, (ins imm0_127:$imm), mnemonic#" $imm", "",
835 [(int_aarch64_hint imm0_127:$imm)]>,
836 Sched<[WriteHint]> {
837 bits <7> imm;
838 let Inst{20-12} = 0b000110010;
839 let Inst{11-5} = imm;
840 }
Tim Northover3b0846e2014-05-24 12:50:23 +0000841
842// System instructions taking a single literal operand which encodes into
843// CRm. op2 differentiates the opcodes.
844def BarrierAsmOperand : AsmOperandClass {
845 let Name = "Barrier";
846 let ParserMethod = "tryParseBarrierOperand";
847}
848def barrier_op : Operand<i32> {
849 let PrintMethod = "printBarrierOption";
850 let ParserMatchClass = BarrierAsmOperand;
851}
Yi Kong23550662014-07-17 10:50:20 +0000852class CRmSystemI<Operand crmtype, bits<3> opc, string asm,
853 list<dag> pattern = []>
854 : SimpleSystemI<0, (ins crmtype:$CRm), asm, "\t$CRm", pattern>,
Tim Northover3b0846e2014-05-24 12:50:23 +0000855 Sched<[WriteBarrier]> {
856 bits<4> CRm;
857 let Inst{20-12} = 0b000110011;
858 let Inst{11-8} = CRm;
859 let Inst{7-5} = opc;
860}
861
862// MRS/MSR system instructions. These have different operand classes because
863// a different subset of registers can be accessed through each instruction.
864def MRSSystemRegisterOperand : AsmOperandClass {
865 let Name = "MRSSystemRegister";
866 let ParserMethod = "tryParseSysReg";
867 let DiagnosticType = "MRS";
868}
Tom Coxone493f172014-10-01 10:13:59 +0000869// concatenation of op0, op1, CRn, CRm, op2. 16-bit immediate.
Tim Northover3b0846e2014-05-24 12:50:23 +0000870def mrs_sysreg_op : Operand<i32> {
871 let ParserMatchClass = MRSSystemRegisterOperand;
872 let DecoderMethod = "DecodeMRSSystemRegister";
873 let PrintMethod = "printMRSSystemRegister";
874}
875
876def MSRSystemRegisterOperand : AsmOperandClass {
877 let Name = "MSRSystemRegister";
878 let ParserMethod = "tryParseSysReg";
879 let DiagnosticType = "MSR";
880}
881def msr_sysreg_op : Operand<i32> {
882 let ParserMatchClass = MSRSystemRegisterOperand;
883 let DecoderMethod = "DecodeMSRSystemRegister";
884 let PrintMethod = "printMSRSystemRegister";
885}
886
887class MRSI : RtSystemI<1, (outs GPR64:$Rt), (ins mrs_sysreg_op:$systemreg),
888 "mrs", "\t$Rt, $systemreg"> {
Tom Coxone493f172014-10-01 10:13:59 +0000889 bits<16> systemreg;
890 let Inst{20-5} = systemreg;
Tim Northover3b0846e2014-05-24 12:50:23 +0000891}
892
893// FIXME: Some of these def NZCV, others don't. Best way to model that?
894// Explicitly modeling each of the system register as a register class
895// would do it, but feels like overkill at this point.
896class MSRI : RtSystemI<0, (outs), (ins msr_sysreg_op:$systemreg, GPR64:$Rt),
897 "msr", "\t$systemreg, $Rt"> {
Tom Coxone493f172014-10-01 10:13:59 +0000898 bits<16> systemreg;
899 let Inst{20-5} = systemreg;
Tim Northover3b0846e2014-05-24 12:50:23 +0000900}
901
902def SystemPStateFieldOperand : AsmOperandClass {
903 let Name = "SystemPStateField";
904 let ParserMethod = "tryParseSysReg";
905}
906def pstatefield_op : Operand<i32> {
907 let ParserMatchClass = SystemPStateFieldOperand;
908 let PrintMethod = "printSystemPStateField";
909}
910
911let Defs = [NZCV] in
912class MSRpstateI
913 : SimpleSystemI<0, (ins pstatefield_op:$pstate_field, imm0_15:$imm),
914 "msr", "\t$pstate_field, $imm">,
915 Sched<[WriteSys]> {
916 bits<6> pstatefield;
917 bits<4> imm;
918 let Inst{20-19} = 0b00;
919 let Inst{18-16} = pstatefield{5-3};
920 let Inst{15-12} = 0b0100;
921 let Inst{11-8} = imm;
922 let Inst{7-5} = pstatefield{2-0};
923
924 let DecoderMethod = "DecodeSystemPStateInstruction";
Petr Pavlu097adfb2015-07-15 08:10:30 +0000925 // MSRpstateI aliases with MSRI. When the MSRpstateI decoder method returns
926 // Fail the decoder should attempt to decode the instruction as MSRI.
927 let hasCompleteDecoder = 0;
Tim Northover3b0846e2014-05-24 12:50:23 +0000928}
929
930// SYS and SYSL generic system instructions.
931def SysCRAsmOperand : AsmOperandClass {
932 let Name = "SysCR";
933 let ParserMethod = "tryParseSysCROperand";
934}
935
936def sys_cr_op : Operand<i32> {
937 let PrintMethod = "printSysCROperand";
938 let ParserMatchClass = SysCRAsmOperand;
939}
940
941class SystemXtI<bit L, string asm>
942 : RtSystemI<L, (outs),
943 (ins imm0_7:$op1, sys_cr_op:$Cn, sys_cr_op:$Cm, imm0_7:$op2, GPR64:$Rt),
944 asm, "\t$op1, $Cn, $Cm, $op2, $Rt"> {
945 bits<3> op1;
946 bits<4> Cn;
947 bits<4> Cm;
948 bits<3> op2;
949 let Inst{20-19} = 0b01;
950 let Inst{18-16} = op1;
951 let Inst{15-12} = Cn;
952 let Inst{11-8} = Cm;
953 let Inst{7-5} = op2;
954}
955
956class SystemLXtI<bit L, string asm>
957 : RtSystemI<L, (outs),
958 (ins GPR64:$Rt, imm0_7:$op1, sys_cr_op:$Cn, sys_cr_op:$Cm, imm0_7:$op2),
959 asm, "\t$Rt, $op1, $Cn, $Cm, $op2"> {
960 bits<3> op1;
961 bits<4> Cn;
962 bits<4> Cm;
963 bits<3> op2;
964 let Inst{20-19} = 0b01;
965 let Inst{18-16} = op1;
966 let Inst{15-12} = Cn;
967 let Inst{11-8} = Cm;
968 let Inst{7-5} = op2;
969}
970
971
972// Branch (register) instructions:
973//
974// case opc of
975// 0001 blr
976// 0000 br
977// 0101 dret
978// 0100 eret
979// 0010 ret
980// otherwise UNDEFINED
981class BaseBranchReg<bits<4> opc, dag oops, dag iops, string asm,
982 string operands, list<dag> pattern>
983 : I<oops, iops, asm, operands, "", pattern>, Sched<[WriteBrReg]> {
984 let Inst{31-25} = 0b1101011;
985 let Inst{24-21} = opc;
986 let Inst{20-16} = 0b11111;
987 let Inst{15-10} = 0b000000;
988 let Inst{4-0} = 0b00000;
989}
990
991class BranchReg<bits<4> opc, string asm, list<dag> pattern>
992 : BaseBranchReg<opc, (outs), (ins GPR64:$Rn), asm, "\t$Rn", pattern> {
993 bits<5> Rn;
994 let Inst{9-5} = Rn;
995}
996
997let mayLoad = 0, mayStore = 0, hasSideEffects = 1, isReturn = 1 in
998class SpecialReturn<bits<4> opc, string asm>
999 : BaseBranchReg<opc, (outs), (ins), asm, "", []> {
1000 let Inst{9-5} = 0b11111;
1001}
1002
1003//---
1004// Conditional branch instruction.
1005//---
1006
1007// Condition code.
1008// 4-bit immediate. Pretty-printed as <cc>
1009def ccode : Operand<i32> {
1010 let PrintMethod = "printCondCode";
1011 let ParserMatchClass = CondCode;
1012}
1013def inv_ccode : Operand<i32> {
Artyom Skrobov6c8682e2014-06-10 13:11:35 +00001014 // AL and NV are invalid in the aliases which use inv_ccode
Tim Northover3b0846e2014-05-24 12:50:23 +00001015 let PrintMethod = "printInverseCondCode";
1016 let ParserMatchClass = CondCode;
Artyom Skrobov6c8682e2014-06-10 13:11:35 +00001017 let MCOperandPredicate = [{
1018 return MCOp.isImm() &&
1019 MCOp.getImm() != AArch64CC::AL &&
1020 MCOp.getImm() != AArch64CC::NV;
1021 }];
Tim Northover3b0846e2014-05-24 12:50:23 +00001022}
1023
1024// Conditional branch target. 19-bit immediate. The low two bits of the target
1025// offset are implied zero and so are not part of the immediate.
1026def PCRelLabel19Operand : AsmOperandClass {
1027 let Name = "PCRelLabel19";
1028 let DiagnosticType = "InvalidLabel";
1029}
1030def am_brcond : Operand<OtherVT> {
1031 let EncoderMethod = "getCondBranchTargetOpValue";
1032 let DecoderMethod = "DecodePCRelLabel19";
1033 let PrintMethod = "printAlignedLabel";
1034 let ParserMatchClass = PCRelLabel19Operand;
1035}
1036
1037class BranchCond : I<(outs), (ins ccode:$cond, am_brcond:$target),
1038 "b", ".$cond\t$target", "",
1039 [(AArch64brcond bb:$target, imm:$cond, NZCV)]>,
1040 Sched<[WriteBr]> {
1041 let isBranch = 1;
1042 let isTerminator = 1;
1043 let Uses = [NZCV];
1044
1045 bits<4> cond;
1046 bits<19> target;
1047 let Inst{31-24} = 0b01010100;
1048 let Inst{23-5} = target;
1049 let Inst{4} = 0;
1050 let Inst{3-0} = cond;
1051}
1052
1053//---
1054// Compare-and-branch instructions.
1055//---
1056class BaseCmpBranch<RegisterClass regtype, bit op, string asm, SDNode node>
1057 : I<(outs), (ins regtype:$Rt, am_brcond:$target),
1058 asm, "\t$Rt, $target", "",
1059 [(node regtype:$Rt, bb:$target)]>,
1060 Sched<[WriteBr]> {
1061 let isBranch = 1;
1062 let isTerminator = 1;
1063
1064 bits<5> Rt;
1065 bits<19> target;
1066 let Inst{30-25} = 0b011010;
1067 let Inst{24} = op;
1068 let Inst{23-5} = target;
1069 let Inst{4-0} = Rt;
1070}
1071
1072multiclass CmpBranch<bit op, string asm, SDNode node> {
1073 def W : BaseCmpBranch<GPR32, op, asm, node> {
1074 let Inst{31} = 0;
1075 }
1076 def X : BaseCmpBranch<GPR64, op, asm, node> {
1077 let Inst{31} = 1;
1078 }
1079}
1080
1081//---
1082// Test-bit-and-branch instructions.
1083//---
1084// Test-and-branch target. 14-bit sign-extended immediate. The low two bits of
1085// the target offset are implied zero and so are not part of the immediate.
1086def BranchTarget14Operand : AsmOperandClass {
1087 let Name = "BranchTarget14";
1088}
1089def am_tbrcond : Operand<OtherVT> {
1090 let EncoderMethod = "getTestBranchTargetOpValue";
1091 let PrintMethod = "printAlignedLabel";
1092 let ParserMatchClass = BranchTarget14Operand;
1093}
1094
1095// AsmOperand classes to emit (or not) special diagnostics
1096def TBZImm0_31Operand : AsmOperandClass {
1097 let Name = "TBZImm0_31";
1098 let PredicateMethod = "isImm0_31";
1099 let RenderMethod = "addImm0_31Operands";
1100}
1101def TBZImm32_63Operand : AsmOperandClass {
1102 let Name = "Imm32_63";
1103 let DiagnosticType = "InvalidImm0_63";
1104}
1105
1106class tbz_imm0_31<AsmOperandClass matcher> : Operand<i64>, ImmLeaf<i64, [{
1107 return (((uint32_t)Imm) < 32);
1108}]> {
1109 let ParserMatchClass = matcher;
1110}
1111
1112def tbz_imm0_31_diag : tbz_imm0_31<Imm0_31Operand>;
1113def tbz_imm0_31_nodiag : tbz_imm0_31<TBZImm0_31Operand>;
1114
1115def tbz_imm32_63 : Operand<i64>, ImmLeaf<i64, [{
1116 return (((uint32_t)Imm) > 31) && (((uint32_t)Imm) < 64);
1117}]> {
1118 let ParserMatchClass = TBZImm32_63Operand;
1119}
1120
1121class BaseTestBranch<RegisterClass regtype, Operand immtype,
1122 bit op, string asm, SDNode node>
1123 : I<(outs), (ins regtype:$Rt, immtype:$bit_off, am_tbrcond:$target),
1124 asm, "\t$Rt, $bit_off, $target", "",
1125 [(node regtype:$Rt, immtype:$bit_off, bb:$target)]>,
1126 Sched<[WriteBr]> {
1127 let isBranch = 1;
1128 let isTerminator = 1;
1129
1130 bits<5> Rt;
1131 bits<6> bit_off;
1132 bits<14> target;
1133
1134 let Inst{30-25} = 0b011011;
1135 let Inst{24} = op;
1136 let Inst{23-19} = bit_off{4-0};
1137 let Inst{18-5} = target;
1138 let Inst{4-0} = Rt;
1139
1140 let DecoderMethod = "DecodeTestAndBranch";
1141}
1142
1143multiclass TestBranch<bit op, string asm, SDNode node> {
1144 def W : BaseTestBranch<GPR32, tbz_imm0_31_diag, op, asm, node> {
1145 let Inst{31} = 0;
1146 }
1147
1148 def X : BaseTestBranch<GPR64, tbz_imm32_63, op, asm, node> {
1149 let Inst{31} = 1;
1150 }
1151
1152 // Alias X-reg with 0-31 imm to W-Reg.
1153 def : InstAlias<asm # "\t$Rd, $imm, $target",
1154 (!cast<Instruction>(NAME#"W") GPR32as64:$Rd,
1155 tbz_imm0_31_nodiag:$imm, am_tbrcond:$target), 0>;
1156 def : Pat<(node GPR64:$Rn, tbz_imm0_31_diag:$imm, bb:$target),
1157 (!cast<Instruction>(NAME#"W") (EXTRACT_SUBREG GPR64:$Rn, sub_32),
1158 tbz_imm0_31_diag:$imm, bb:$target)>;
1159}
1160
1161//---
1162// Unconditional branch (immediate) instructions.
1163//---
1164def BranchTarget26Operand : AsmOperandClass {
1165 let Name = "BranchTarget26";
1166 let DiagnosticType = "InvalidLabel";
1167}
1168def am_b_target : Operand<OtherVT> {
1169 let EncoderMethod = "getBranchTargetOpValue";
1170 let PrintMethod = "printAlignedLabel";
1171 let ParserMatchClass = BranchTarget26Operand;
1172}
1173def am_bl_target : Operand<i64> {
1174 let EncoderMethod = "getBranchTargetOpValue";
1175 let PrintMethod = "printAlignedLabel";
1176 let ParserMatchClass = BranchTarget26Operand;
1177}
1178
1179class BImm<bit op, dag iops, string asm, list<dag> pattern>
1180 : I<(outs), iops, asm, "\t$addr", "", pattern>, Sched<[WriteBr]> {
1181 bits<26> addr;
1182 let Inst{31} = op;
1183 let Inst{30-26} = 0b00101;
1184 let Inst{25-0} = addr;
1185
1186 let DecoderMethod = "DecodeUnconditionalBranch";
1187}
1188
1189class BranchImm<bit op, string asm, list<dag> pattern>
1190 : BImm<op, (ins am_b_target:$addr), asm, pattern>;
1191class CallImm<bit op, string asm, list<dag> pattern>
1192 : BImm<op, (ins am_bl_target:$addr), asm, pattern>;
1193
1194//---
1195// Basic one-operand data processing instructions.
1196//---
1197
1198let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
1199class BaseOneOperandData<bits<3> opc, RegisterClass regtype, string asm,
1200 SDPatternOperator node>
1201 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm, "\t$Rd, $Rn", "",
1202 [(set regtype:$Rd, (node regtype:$Rn))]>,
1203 Sched<[WriteI, ReadI]> {
1204 bits<5> Rd;
1205 bits<5> Rn;
1206
1207 let Inst{30-13} = 0b101101011000000000;
1208 let Inst{12-10} = opc;
1209 let Inst{9-5} = Rn;
1210 let Inst{4-0} = Rd;
1211}
1212
1213let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
1214multiclass OneOperandData<bits<3> opc, string asm,
1215 SDPatternOperator node = null_frag> {
1216 def Wr : BaseOneOperandData<opc, GPR32, asm, node> {
1217 let Inst{31} = 0;
1218 }
1219
1220 def Xr : BaseOneOperandData<opc, GPR64, asm, node> {
1221 let Inst{31} = 1;
1222 }
1223}
1224
1225class OneWRegData<bits<3> opc, string asm, SDPatternOperator node>
1226 : BaseOneOperandData<opc, GPR32, asm, node> {
1227 let Inst{31} = 0;
1228}
1229
1230class OneXRegData<bits<3> opc, string asm, SDPatternOperator node>
1231 : BaseOneOperandData<opc, GPR64, asm, node> {
1232 let Inst{31} = 1;
1233}
1234
1235//---
1236// Basic two-operand data processing instructions.
1237//---
1238class BaseBaseAddSubCarry<bit isSub, RegisterClass regtype, string asm,
1239 list<dag> pattern>
1240 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm),
1241 asm, "\t$Rd, $Rn, $Rm", "", pattern>,
1242 Sched<[WriteI, ReadI, ReadI]> {
1243 let Uses = [NZCV];
1244 bits<5> Rd;
1245 bits<5> Rn;
1246 bits<5> Rm;
1247 let Inst{30} = isSub;
1248 let Inst{28-21} = 0b11010000;
1249 let Inst{20-16} = Rm;
1250 let Inst{15-10} = 0;
1251 let Inst{9-5} = Rn;
1252 let Inst{4-0} = Rd;
1253}
1254
1255class BaseAddSubCarry<bit isSub, RegisterClass regtype, string asm,
1256 SDNode OpNode>
1257 : BaseBaseAddSubCarry<isSub, regtype, asm,
1258 [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm, NZCV))]>;
1259
1260class BaseAddSubCarrySetFlags<bit isSub, RegisterClass regtype, string asm,
1261 SDNode OpNode>
1262 : BaseBaseAddSubCarry<isSub, regtype, asm,
1263 [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm, NZCV)),
1264 (implicit NZCV)]> {
1265 let Defs = [NZCV];
1266}
1267
1268multiclass AddSubCarry<bit isSub, string asm, string asm_setflags,
1269 SDNode OpNode, SDNode OpNode_setflags> {
1270 def Wr : BaseAddSubCarry<isSub, GPR32, asm, OpNode> {
1271 let Inst{31} = 0;
1272 let Inst{29} = 0;
1273 }
1274 def Xr : BaseAddSubCarry<isSub, GPR64, asm, OpNode> {
1275 let Inst{31} = 1;
1276 let Inst{29} = 0;
1277 }
1278
1279 // Sets flags.
1280 def SWr : BaseAddSubCarrySetFlags<isSub, GPR32, asm_setflags,
1281 OpNode_setflags> {
1282 let Inst{31} = 0;
1283 let Inst{29} = 1;
1284 }
1285 def SXr : BaseAddSubCarrySetFlags<isSub, GPR64, asm_setflags,
1286 OpNode_setflags> {
1287 let Inst{31} = 1;
1288 let Inst{29} = 1;
1289 }
1290}
1291
1292class BaseTwoOperand<bits<4> opc, RegisterClass regtype, string asm,
1293 SDPatternOperator OpNode>
1294 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm),
1295 asm, "\t$Rd, $Rn, $Rm", "",
1296 [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm))]> {
1297 bits<5> Rd;
1298 bits<5> Rn;
1299 bits<5> Rm;
1300 let Inst{30-21} = 0b0011010110;
1301 let Inst{20-16} = Rm;
1302 let Inst{15-14} = 0b00;
1303 let Inst{13-10} = opc;
1304 let Inst{9-5} = Rn;
1305 let Inst{4-0} = Rd;
1306}
1307
1308class BaseDiv<bit isSigned, RegisterClass regtype, string asm,
1309 SDPatternOperator OpNode>
1310 : BaseTwoOperand<{0,0,1,?}, regtype, asm, OpNode> {
1311 let Inst{10} = isSigned;
1312}
1313
1314multiclass Div<bit isSigned, string asm, SDPatternOperator OpNode> {
1315 def Wr : BaseDiv<isSigned, GPR32, asm, OpNode>,
1316 Sched<[WriteID32, ReadID, ReadID]> {
1317 let Inst{31} = 0;
1318 }
1319 def Xr : BaseDiv<isSigned, GPR64, asm, OpNode>,
1320 Sched<[WriteID64, ReadID, ReadID]> {
1321 let Inst{31} = 1;
1322 }
1323}
1324
1325class BaseShift<bits<2> shift_type, RegisterClass regtype, string asm,
1326 SDPatternOperator OpNode = null_frag>
1327 : BaseTwoOperand<{1,0,?,?}, regtype, asm, OpNode>,
1328 Sched<[WriteIS, ReadI]> {
1329 let Inst{11-10} = shift_type;
1330}
1331
1332multiclass Shift<bits<2> shift_type, string asm, SDNode OpNode> {
1333 def Wr : BaseShift<shift_type, GPR32, asm> {
1334 let Inst{31} = 0;
1335 }
1336
1337 def Xr : BaseShift<shift_type, GPR64, asm, OpNode> {
1338 let Inst{31} = 1;
1339 }
1340
1341 def : Pat<(i32 (OpNode GPR32:$Rn, i64:$Rm)),
1342 (!cast<Instruction>(NAME # "Wr") GPR32:$Rn,
1343 (EXTRACT_SUBREG i64:$Rm, sub_32))>;
1344
1345 def : Pat<(i32 (OpNode GPR32:$Rn, (i64 (zext GPR32:$Rm)))),
1346 (!cast<Instruction>(NAME # "Wr") GPR32:$Rn, GPR32:$Rm)>;
1347
1348 def : Pat<(i32 (OpNode GPR32:$Rn, (i64 (anyext GPR32:$Rm)))),
1349 (!cast<Instruction>(NAME # "Wr") GPR32:$Rn, GPR32:$Rm)>;
1350
1351 def : Pat<(i32 (OpNode GPR32:$Rn, (i64 (sext GPR32:$Rm)))),
1352 (!cast<Instruction>(NAME # "Wr") GPR32:$Rn, GPR32:$Rm)>;
1353}
1354
1355class ShiftAlias<string asm, Instruction inst, RegisterClass regtype>
1356 : InstAlias<asm#" $dst, $src1, $src2",
1357 (inst regtype:$dst, regtype:$src1, regtype:$src2), 0>;
1358
1359class BaseMulAccum<bit isSub, bits<3> opc, RegisterClass multype,
1360 RegisterClass addtype, string asm,
1361 list<dag> pattern>
1362 : I<(outs addtype:$Rd), (ins multype:$Rn, multype:$Rm, addtype:$Ra),
1363 asm, "\t$Rd, $Rn, $Rm, $Ra", "", pattern> {
1364 bits<5> Rd;
1365 bits<5> Rn;
1366 bits<5> Rm;
1367 bits<5> Ra;
1368 let Inst{30-24} = 0b0011011;
1369 let Inst{23-21} = opc;
1370 let Inst{20-16} = Rm;
1371 let Inst{15} = isSub;
1372 let Inst{14-10} = Ra;
1373 let Inst{9-5} = Rn;
1374 let Inst{4-0} = Rd;
1375}
1376
1377multiclass MulAccum<bit isSub, string asm, SDNode AccNode> {
Gerolf Hoflehner97c383b2014-08-07 21:40:58 +00001378 // MADD/MSUB generation is decided by MachineCombiner.cpp
Tim Northover3b0846e2014-05-24 12:50:23 +00001379 def Wrrr : BaseMulAccum<isSub, 0b000, GPR32, GPR32, asm,
Gerolf Hoflehner97c383b2014-08-07 21:40:58 +00001380 [/*(set GPR32:$Rd, (AccNode GPR32:$Ra, (mul GPR32:$Rn, GPR32:$Rm)))*/]>,
Chad Rosier3fe0c872014-06-09 01:54:00 +00001381 Sched<[WriteIM32, ReadIM, ReadIM, ReadIMA]> {
Tim Northover3b0846e2014-05-24 12:50:23 +00001382 let Inst{31} = 0;
1383 }
1384
1385 def Xrrr : BaseMulAccum<isSub, 0b000, GPR64, GPR64, asm,
Gerolf Hoflehner97c383b2014-08-07 21:40:58 +00001386 [/*(set GPR64:$Rd, (AccNode GPR64:$Ra, (mul GPR64:$Rn, GPR64:$Rm)))*/]>,
Chad Rosier3fe0c872014-06-09 01:54:00 +00001387 Sched<[WriteIM64, ReadIM, ReadIM, ReadIMA]> {
Tim Northover3b0846e2014-05-24 12:50:23 +00001388 let Inst{31} = 1;
1389 }
1390}
1391
1392class WideMulAccum<bit isSub, bits<3> opc, string asm,
1393 SDNode AccNode, SDNode ExtNode>
1394 : BaseMulAccum<isSub, opc, GPR32, GPR64, asm,
1395 [(set GPR64:$Rd, (AccNode GPR64:$Ra,
1396 (mul (ExtNode GPR32:$Rn), (ExtNode GPR32:$Rm))))]>,
Chad Rosier3fe0c872014-06-09 01:54:00 +00001397 Sched<[WriteIM32, ReadIM, ReadIM, ReadIMA]> {
Tim Northover3b0846e2014-05-24 12:50:23 +00001398 let Inst{31} = 1;
1399}
1400
1401class MulHi<bits<3> opc, string asm, SDNode OpNode>
1402 : I<(outs GPR64:$Rd), (ins GPR64:$Rn, GPR64:$Rm),
1403 asm, "\t$Rd, $Rn, $Rm", "",
1404 [(set GPR64:$Rd, (OpNode GPR64:$Rn, GPR64:$Rm))]>,
1405 Sched<[WriteIM64, ReadIM, ReadIM]> {
1406 bits<5> Rd;
1407 bits<5> Rn;
1408 bits<5> Rm;
1409 let Inst{31-24} = 0b10011011;
1410 let Inst{23-21} = opc;
1411 let Inst{20-16} = Rm;
1412 let Inst{15} = 0;
1413 let Inst{9-5} = Rn;
1414 let Inst{4-0} = Rd;
1415
1416 // The Ra field of SMULH and UMULH is unused: it should be assembled as 31
1417 // (i.e. all bits 1) but is ignored by the processor.
1418 let PostEncoderMethod = "fixMulHigh";
1419}
1420
1421class MulAccumWAlias<string asm, Instruction inst>
1422 : InstAlias<asm#" $dst, $src1, $src2",
1423 (inst GPR32:$dst, GPR32:$src1, GPR32:$src2, WZR)>;
1424class MulAccumXAlias<string asm, Instruction inst>
1425 : InstAlias<asm#" $dst, $src1, $src2",
1426 (inst GPR64:$dst, GPR64:$src1, GPR64:$src2, XZR)>;
1427class WideMulAccumAlias<string asm, Instruction inst>
1428 : InstAlias<asm#" $dst, $src1, $src2",
1429 (inst GPR64:$dst, GPR32:$src1, GPR32:$src2, XZR)>;
1430
1431class BaseCRC32<bit sf, bits<2> sz, bit C, RegisterClass StreamReg,
1432 SDPatternOperator OpNode, string asm>
1433 : I<(outs GPR32:$Rd), (ins GPR32:$Rn, StreamReg:$Rm),
1434 asm, "\t$Rd, $Rn, $Rm", "",
1435 [(set GPR32:$Rd, (OpNode GPR32:$Rn, StreamReg:$Rm))]>,
1436 Sched<[WriteISReg, ReadI, ReadISReg]> {
1437 bits<5> Rd;
1438 bits<5> Rn;
1439 bits<5> Rm;
1440
1441 let Inst{31} = sf;
1442 let Inst{30-21} = 0b0011010110;
1443 let Inst{20-16} = Rm;
1444 let Inst{15-13} = 0b010;
1445 let Inst{12} = C;
1446 let Inst{11-10} = sz;
1447 let Inst{9-5} = Rn;
1448 let Inst{4-0} = Rd;
1449 let Predicates = [HasCRC];
1450}
1451
1452//---
1453// Address generation.
1454//---
1455
1456class ADRI<bit page, string asm, Operand adr, list<dag> pattern>
1457 : I<(outs GPR64:$Xd), (ins adr:$label), asm, "\t$Xd, $label", "",
1458 pattern>,
1459 Sched<[WriteI]> {
1460 bits<5> Xd;
1461 bits<21> label;
1462 let Inst{31} = page;
1463 let Inst{30-29} = label{1-0};
1464 let Inst{28-24} = 0b10000;
1465 let Inst{23-5} = label{20-2};
1466 let Inst{4-0} = Xd;
1467
1468 let DecoderMethod = "DecodeAdrInstruction";
1469}
1470
1471//---
1472// Move immediate.
1473//---
1474
1475def movimm32_imm : Operand<i32> {
1476 let ParserMatchClass = Imm0_65535Operand;
1477 let EncoderMethod = "getMoveWideImmOpValue";
1478 let PrintMethod = "printHexImm";
1479}
1480def movimm32_shift : Operand<i32> {
1481 let PrintMethod = "printShifter";
1482 let ParserMatchClass = MovImm32ShifterOperand;
1483}
1484def movimm64_shift : Operand<i32> {
1485 let PrintMethod = "printShifter";
1486 let ParserMatchClass = MovImm64ShifterOperand;
1487}
1488
1489let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
1490class BaseMoveImmediate<bits<2> opc, RegisterClass regtype, Operand shifter,
1491 string asm>
1492 : I<(outs regtype:$Rd), (ins movimm32_imm:$imm, shifter:$shift),
1493 asm, "\t$Rd, $imm$shift", "", []>,
1494 Sched<[WriteImm]> {
1495 bits<5> Rd;
1496 bits<16> imm;
1497 bits<6> shift;
1498 let Inst{30-29} = opc;
1499 let Inst{28-23} = 0b100101;
1500 let Inst{22-21} = shift{5-4};
1501 let Inst{20-5} = imm;
1502 let Inst{4-0} = Rd;
1503
1504 let DecoderMethod = "DecodeMoveImmInstruction";
1505}
1506
1507multiclass MoveImmediate<bits<2> opc, string asm> {
1508 def Wi : BaseMoveImmediate<opc, GPR32, movimm32_shift, asm> {
1509 let Inst{31} = 0;
1510 }
1511
1512 def Xi : BaseMoveImmediate<opc, GPR64, movimm64_shift, asm> {
1513 let Inst{31} = 1;
1514 }
1515}
1516
1517let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
1518class BaseInsertImmediate<bits<2> opc, RegisterClass regtype, Operand shifter,
1519 string asm>
1520 : I<(outs regtype:$Rd),
1521 (ins regtype:$src, movimm32_imm:$imm, shifter:$shift),
1522 asm, "\t$Rd, $imm$shift", "$src = $Rd", []>,
1523 Sched<[WriteI, ReadI]> {
1524 bits<5> Rd;
1525 bits<16> imm;
1526 bits<6> shift;
1527 let Inst{30-29} = opc;
1528 let Inst{28-23} = 0b100101;
1529 let Inst{22-21} = shift{5-4};
1530 let Inst{20-5} = imm;
1531 let Inst{4-0} = Rd;
1532
1533 let DecoderMethod = "DecodeMoveImmInstruction";
1534}
1535
1536multiclass InsertImmediate<bits<2> opc, string asm> {
1537 def Wi : BaseInsertImmediate<opc, GPR32, movimm32_shift, asm> {
1538 let Inst{31} = 0;
1539 }
1540
1541 def Xi : BaseInsertImmediate<opc, GPR64, movimm64_shift, asm> {
1542 let Inst{31} = 1;
1543 }
1544}
1545
1546//---
1547// Add/Subtract
1548//---
1549
1550class BaseAddSubImm<bit isSub, bit setFlags, RegisterClass dstRegtype,
1551 RegisterClass srcRegtype, addsub_shifted_imm immtype,
1552 string asm, SDPatternOperator OpNode>
1553 : I<(outs dstRegtype:$Rd), (ins srcRegtype:$Rn, immtype:$imm),
1554 asm, "\t$Rd, $Rn, $imm", "",
1555 [(set dstRegtype:$Rd, (OpNode srcRegtype:$Rn, immtype:$imm))]>,
1556 Sched<[WriteI, ReadI]> {
1557 bits<5> Rd;
1558 bits<5> Rn;
1559 bits<14> imm;
1560 let Inst{30} = isSub;
1561 let Inst{29} = setFlags;
1562 let Inst{28-24} = 0b10001;
1563 let Inst{23-22} = imm{13-12}; // '00' => lsl #0, '01' => lsl #12
1564 let Inst{21-10} = imm{11-0};
1565 let Inst{9-5} = Rn;
1566 let Inst{4-0} = Rd;
1567 let DecoderMethod = "DecodeBaseAddSubImm";
1568}
1569
1570class BaseAddSubRegPseudo<RegisterClass regtype,
1571 SDPatternOperator OpNode>
1572 : Pseudo<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm),
1573 [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm))]>,
1574 Sched<[WriteI, ReadI, ReadI]>;
1575
1576class BaseAddSubSReg<bit isSub, bit setFlags, RegisterClass regtype,
1577 arith_shifted_reg shifted_regtype, string asm,
1578 SDPatternOperator OpNode>
1579 : I<(outs regtype:$Rd), (ins regtype:$Rn, shifted_regtype:$Rm),
1580 asm, "\t$Rd, $Rn, $Rm", "",
1581 [(set regtype:$Rd, (OpNode regtype:$Rn, shifted_regtype:$Rm))]>,
1582 Sched<[WriteISReg, ReadI, ReadISReg]> {
1583 // The operands are in order to match the 'addr' MI operands, so we
1584 // don't need an encoder method and by-name matching. Just use the default
1585 // in-order handling. Since we're using by-order, make sure the names
1586 // do not match.
1587 bits<5> dst;
1588 bits<5> src1;
1589 bits<5> src2;
1590 bits<8> shift;
1591 let Inst{30} = isSub;
1592 let Inst{29} = setFlags;
1593 let Inst{28-24} = 0b01011;
1594 let Inst{23-22} = shift{7-6};
1595 let Inst{21} = 0;
1596 let Inst{20-16} = src2;
1597 let Inst{15-10} = shift{5-0};
1598 let Inst{9-5} = src1;
1599 let Inst{4-0} = dst;
1600
1601 let DecoderMethod = "DecodeThreeAddrSRegInstruction";
1602}
1603
1604class BaseAddSubEReg<bit isSub, bit setFlags, RegisterClass dstRegtype,
1605 RegisterClass src1Regtype, Operand src2Regtype,
1606 string asm, SDPatternOperator OpNode>
1607 : I<(outs dstRegtype:$R1),
1608 (ins src1Regtype:$R2, src2Regtype:$R3),
1609 asm, "\t$R1, $R2, $R3", "",
1610 [(set dstRegtype:$R1, (OpNode src1Regtype:$R2, src2Regtype:$R3))]>,
1611 Sched<[WriteIEReg, ReadI, ReadIEReg]> {
1612 bits<5> Rd;
1613 bits<5> Rn;
1614 bits<5> Rm;
1615 bits<6> ext;
1616 let Inst{30} = isSub;
1617 let Inst{29} = setFlags;
1618 let Inst{28-24} = 0b01011;
1619 let Inst{23-21} = 0b001;
1620 let Inst{20-16} = Rm;
1621 let Inst{15-13} = ext{5-3};
1622 let Inst{12-10} = ext{2-0};
1623 let Inst{9-5} = Rn;
1624 let Inst{4-0} = Rd;
1625
1626 let DecoderMethod = "DecodeAddSubERegInstruction";
1627}
1628
1629let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
1630class BaseAddSubEReg64<bit isSub, bit setFlags, RegisterClass dstRegtype,
1631 RegisterClass src1Regtype, RegisterClass src2Regtype,
1632 Operand ext_op, string asm>
1633 : I<(outs dstRegtype:$Rd),
1634 (ins src1Regtype:$Rn, src2Regtype:$Rm, ext_op:$ext),
1635 asm, "\t$Rd, $Rn, $Rm$ext", "", []>,
1636 Sched<[WriteIEReg, ReadI, ReadIEReg]> {
1637 bits<5> Rd;
1638 bits<5> Rn;
1639 bits<5> Rm;
1640 bits<6> ext;
1641 let Inst{30} = isSub;
1642 let Inst{29} = setFlags;
1643 let Inst{28-24} = 0b01011;
1644 let Inst{23-21} = 0b001;
1645 let Inst{20-16} = Rm;
1646 let Inst{15} = ext{5};
1647 let Inst{12-10} = ext{2-0};
1648 let Inst{9-5} = Rn;
1649 let Inst{4-0} = Rd;
1650
1651 let DecoderMethod = "DecodeAddSubERegInstruction";
1652}
1653
1654// Aliases for register+register add/subtract.
1655class AddSubRegAlias<string asm, Instruction inst, RegisterClass dstRegtype,
1656 RegisterClass src1Regtype, RegisterClass src2Regtype,
1657 int shiftExt>
1658 : InstAlias<asm#" $dst, $src1, $src2",
1659 (inst dstRegtype:$dst, src1Regtype:$src1, src2Regtype:$src2,
1660 shiftExt)>;
1661
Arnaud A. de Grandmaison650c5202015-07-01 15:05:58 +00001662multiclass AddSub<bit isSub, string mnemonic, string alias,
Tim Northover3b0846e2014-05-24 12:50:23 +00001663 SDPatternOperator OpNode = null_frag> {
Jiangning Liucd296372014-07-29 02:09:26 +00001664 let hasSideEffects = 0, isReMaterializable = 1, isAsCheapAsAMove = 1 in {
Tim Northover3b0846e2014-05-24 12:50:23 +00001665 // Add/Subtract immediate
Quentin Colombeta64723c2015-04-02 18:54:23 +00001666 // Increase the weight of the immediate variant to try to match it before
1667 // the extended register variant.
1668 // We used to match the register variant before the immediate when the
1669 // register argument could be implicitly zero-extended.
Quentin Colombet387a0e72015-03-31 00:31:13 +00001670 let AddedComplexity = 6 in
Tim Northover3b0846e2014-05-24 12:50:23 +00001671 def Wri : BaseAddSubImm<isSub, 0, GPR32sp, GPR32sp, addsub_shifted_imm32,
1672 mnemonic, OpNode> {
1673 let Inst{31} = 0;
1674 }
Quentin Colombet387a0e72015-03-31 00:31:13 +00001675 let AddedComplexity = 6 in
Tim Northover3b0846e2014-05-24 12:50:23 +00001676 def Xri : BaseAddSubImm<isSub, 0, GPR64sp, GPR64sp, addsub_shifted_imm64,
1677 mnemonic, OpNode> {
1678 let Inst{31} = 1;
1679 }
1680
1681 // Add/Subtract register - Only used for CodeGen
1682 def Wrr : BaseAddSubRegPseudo<GPR32, OpNode>;
1683 def Xrr : BaseAddSubRegPseudo<GPR64, OpNode>;
1684
1685 // Add/Subtract shifted register
1686 def Wrs : BaseAddSubSReg<isSub, 0, GPR32, arith_shifted_reg32, mnemonic,
1687 OpNode> {
1688 let Inst{31} = 0;
1689 }
1690 def Xrs : BaseAddSubSReg<isSub, 0, GPR64, arith_shifted_reg64, mnemonic,
1691 OpNode> {
1692 let Inst{31} = 1;
1693 }
1694 }
1695
1696 // Add/Subtract extended register
1697 let AddedComplexity = 1, hasSideEffects = 0 in {
1698 def Wrx : BaseAddSubEReg<isSub, 0, GPR32sp, GPR32sp,
1699 arith_extended_reg32<i32>, mnemonic, OpNode> {
1700 let Inst{31} = 0;
1701 }
1702 def Xrx : BaseAddSubEReg<isSub, 0, GPR64sp, GPR64sp,
1703 arith_extended_reg32to64<i64>, mnemonic, OpNode> {
1704 let Inst{31} = 1;
1705 }
1706 }
1707
1708 def Xrx64 : BaseAddSubEReg64<isSub, 0, GPR64sp, GPR64sp, GPR64,
1709 arith_extendlsl64, mnemonic> {
1710 // UXTX and SXTX only.
1711 let Inst{14-13} = 0b11;
1712 let Inst{31} = 1;
1713 }
1714
Arnaud A. de Grandmaison650c5202015-07-01 15:05:58 +00001715 // add Rd, Rb, -imm -> sub Rd, Rn, imm
1716 def : InstAlias<alias#" $Rd, $Rn, $imm",
1717 (!cast<Instruction>(NAME # "Wri") GPR32sp:$Rd, GPR32sp:$Rn,
1718 addsub_shifted_imm32_neg:$imm), 0>;
1719 def : InstAlias<alias#" $Rd, $Rn, $imm",
1720 (!cast<Instruction>(NAME # "Xri") GPR64sp:$Rd, GPR64sp:$Rn,
1721 addsub_shifted_imm64_neg:$imm), 0>;
1722
Tim Northover3b0846e2014-05-24 12:50:23 +00001723 // Register/register aliases with no shift when SP is not used.
1724 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrs"),
1725 GPR32, GPR32, GPR32, 0>;
1726 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Xrs"),
1727 GPR64, GPR64, GPR64, 0>;
1728
1729 // Register/register aliases with no shift when either the destination or
1730 // first source register is SP.
1731 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrx"),
1732 GPR32sponly, GPR32sp, GPR32, 16>; // UXTW #0
1733 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrx"),
1734 GPR32sp, GPR32sponly, GPR32, 16>; // UXTW #0
1735 def : AddSubRegAlias<mnemonic,
1736 !cast<Instruction>(NAME#"Xrx64"),
1737 GPR64sponly, GPR64sp, GPR64, 24>; // UXTX #0
1738 def : AddSubRegAlias<mnemonic,
1739 !cast<Instruction>(NAME#"Xrx64"),
1740 GPR64sp, GPR64sponly, GPR64, 24>; // UXTX #0
1741}
1742
Arnaud A. de Grandmaison650c5202015-07-01 15:05:58 +00001743multiclass AddSubS<bit isSub, string mnemonic, SDNode OpNode, string cmp,
1744 string alias, string cmpAlias> {
Tim Northover3b0846e2014-05-24 12:50:23 +00001745 let isCompare = 1, Defs = [NZCV] in {
1746 // Add/Subtract immediate
1747 def Wri : BaseAddSubImm<isSub, 1, GPR32, GPR32sp, addsub_shifted_imm32,
1748 mnemonic, OpNode> {
1749 let Inst{31} = 0;
1750 }
1751 def Xri : BaseAddSubImm<isSub, 1, GPR64, GPR64sp, addsub_shifted_imm64,
1752 mnemonic, OpNode> {
1753 let Inst{31} = 1;
1754 }
1755
1756 // Add/Subtract register
1757 def Wrr : BaseAddSubRegPseudo<GPR32, OpNode>;
1758 def Xrr : BaseAddSubRegPseudo<GPR64, OpNode>;
1759
1760 // Add/Subtract shifted register
1761 def Wrs : BaseAddSubSReg<isSub, 1, GPR32, arith_shifted_reg32, mnemonic,
1762 OpNode> {
1763 let Inst{31} = 0;
1764 }
1765 def Xrs : BaseAddSubSReg<isSub, 1, GPR64, arith_shifted_reg64, mnemonic,
1766 OpNode> {
1767 let Inst{31} = 1;
1768 }
1769
1770 // Add/Subtract extended register
1771 let AddedComplexity = 1 in {
1772 def Wrx : BaseAddSubEReg<isSub, 1, GPR32, GPR32sp,
1773 arith_extended_reg32<i32>, mnemonic, OpNode> {
1774 let Inst{31} = 0;
1775 }
1776 def Xrx : BaseAddSubEReg<isSub, 1, GPR64, GPR64sp,
1777 arith_extended_reg32<i64>, mnemonic, OpNode> {
1778 let Inst{31} = 1;
1779 }
1780 }
1781
1782 def Xrx64 : BaseAddSubEReg64<isSub, 1, GPR64, GPR64sp, GPR64,
1783 arith_extendlsl64, mnemonic> {
1784 // UXTX and SXTX only.
1785 let Inst{14-13} = 0b11;
1786 let Inst{31} = 1;
1787 }
1788 } // Defs = [NZCV]
1789
Arnaud A. de Grandmaison650c5202015-07-01 15:05:58 +00001790 // Support negative immediates, e.g. adds Rd, Rn, -imm -> subs Rd, Rn, imm
1791 def : InstAlias<alias#" $Rd, $Rn, $imm",
1792 (!cast<Instruction>(NAME # "Wri") GPR32:$Rd, GPR32sp:$Rn,
1793 addsub_shifted_imm32_neg:$imm), 0>;
1794 def : InstAlias<alias#" $Rd, $Rn, $imm",
1795 (!cast<Instruction>(NAME # "Xri") GPR64:$Rd, GPR64sp:$Rn,
1796 addsub_shifted_imm64_neg:$imm), 0>;
1797
Tim Northover3b0846e2014-05-24 12:50:23 +00001798 // Compare aliases
1799 def : InstAlias<cmp#" $src, $imm", (!cast<Instruction>(NAME#"Wri")
1800 WZR, GPR32sp:$src, addsub_shifted_imm32:$imm), 5>;
1801 def : InstAlias<cmp#" $src, $imm", (!cast<Instruction>(NAME#"Xri")
1802 XZR, GPR64sp:$src, addsub_shifted_imm64:$imm), 5>;
1803 def : InstAlias<cmp#" $src1, $src2$sh", (!cast<Instruction>(NAME#"Wrx")
1804 WZR, GPR32sp:$src1, GPR32:$src2, arith_extend:$sh), 4>;
1805 def : InstAlias<cmp#" $src1, $src2$sh", (!cast<Instruction>(NAME#"Xrx")
1806 XZR, GPR64sp:$src1, GPR32:$src2, arith_extend:$sh), 4>;
1807 def : InstAlias<cmp#" $src1, $src2$sh", (!cast<Instruction>(NAME#"Xrx64")
1808 XZR, GPR64sp:$src1, GPR64:$src2, arith_extendlsl64:$sh), 4>;
1809 def : InstAlias<cmp#" $src1, $src2$sh", (!cast<Instruction>(NAME#"Wrs")
1810 WZR, GPR32:$src1, GPR32:$src2, arith_shift32:$sh), 4>;
1811 def : InstAlias<cmp#" $src1, $src2$sh", (!cast<Instruction>(NAME#"Xrs")
1812 XZR, GPR64:$src1, GPR64:$src2, arith_shift64:$sh), 4>;
1813
Arnaud A. de Grandmaison650c5202015-07-01 15:05:58 +00001814 // Support negative immediates, e.g. cmp Rn, -imm -> cmn Rn, imm
1815 def : InstAlias<cmpAlias#" $src, $imm", (!cast<Instruction>(NAME#"Wri")
1816 WZR, GPR32sp:$src, addsub_shifted_imm32_neg:$imm), 0>;
1817 def : InstAlias<cmpAlias#" $src, $imm", (!cast<Instruction>(NAME#"Xri")
1818 XZR, GPR64sp:$src, addsub_shifted_imm64_neg:$imm), 0>;
1819
Tim Northover3b0846e2014-05-24 12:50:23 +00001820 // Compare shorthands
1821 def : InstAlias<cmp#" $src1, $src2", (!cast<Instruction>(NAME#"Wrs")
1822 WZR, GPR32:$src1, GPR32:$src2, 0), 5>;
1823 def : InstAlias<cmp#" $src1, $src2", (!cast<Instruction>(NAME#"Xrs")
1824 XZR, GPR64:$src1, GPR64:$src2, 0), 5>;
Artyom Skrobov82ae94f2014-06-09 11:10:14 +00001825 def : InstAlias<cmp#" $src1, $src2", (!cast<Instruction>(NAME#"Wrx")
1826 WZR, GPR32sponly:$src1, GPR32:$src2, 16), 5>;
1827 def : InstAlias<cmp#" $src1, $src2", (!cast<Instruction>(NAME#"Xrx64")
1828 XZR, GPR64sponly:$src1, GPR64:$src2, 24), 5>;
Tim Northover3b0846e2014-05-24 12:50:23 +00001829
1830 // Register/register aliases with no shift when SP is not used.
1831 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrs"),
1832 GPR32, GPR32, GPR32, 0>;
1833 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Xrs"),
1834 GPR64, GPR64, GPR64, 0>;
1835
1836 // Register/register aliases with no shift when the first source register
1837 // is SP.
1838 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrx"),
1839 GPR32, GPR32sponly, GPR32, 16>; // UXTW #0
1840 def : AddSubRegAlias<mnemonic,
1841 !cast<Instruction>(NAME#"Xrx64"),
1842 GPR64, GPR64sponly, GPR64, 24>; // UXTX #0
1843}
1844
1845//---
1846// Extract
1847//---
1848def SDTA64EXTR : SDTypeProfile<1, 3, [SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>,
1849 SDTCisPtrTy<3>]>;
1850def AArch64Extr : SDNode<"AArch64ISD::EXTR", SDTA64EXTR>;
1851
1852class BaseExtractImm<RegisterClass regtype, Operand imm_type, string asm,
1853 list<dag> patterns>
1854 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, imm_type:$imm),
1855 asm, "\t$Rd, $Rn, $Rm, $imm", "", patterns>,
1856 Sched<[WriteExtr, ReadExtrHi]> {
1857 bits<5> Rd;
1858 bits<5> Rn;
1859 bits<5> Rm;
1860 bits<6> imm;
1861
1862 let Inst{30-23} = 0b00100111;
1863 let Inst{21} = 0;
1864 let Inst{20-16} = Rm;
1865 let Inst{15-10} = imm;
1866 let Inst{9-5} = Rn;
1867 let Inst{4-0} = Rd;
1868}
1869
1870multiclass ExtractImm<string asm> {
1871 def Wrri : BaseExtractImm<GPR32, imm0_31, asm,
1872 [(set GPR32:$Rd,
1873 (AArch64Extr GPR32:$Rn, GPR32:$Rm, imm0_31:$imm))]> {
1874 let Inst{31} = 0;
1875 let Inst{22} = 0;
1876 // imm<5> must be zero.
1877 let imm{5} = 0;
1878 }
1879 def Xrri : BaseExtractImm<GPR64, imm0_63, asm,
1880 [(set GPR64:$Rd,
1881 (AArch64Extr GPR64:$Rn, GPR64:$Rm, imm0_63:$imm))]> {
1882
1883 let Inst{31} = 1;
1884 let Inst{22} = 1;
1885 }
1886}
1887
1888//---
1889// Bitfield
1890//---
1891
1892let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
1893class BaseBitfieldImm<bits<2> opc,
1894 RegisterClass regtype, Operand imm_type, string asm>
1895 : I<(outs regtype:$Rd), (ins regtype:$Rn, imm_type:$immr, imm_type:$imms),
1896 asm, "\t$Rd, $Rn, $immr, $imms", "", []>,
1897 Sched<[WriteIS, ReadI]> {
1898 bits<5> Rd;
1899 bits<5> Rn;
1900 bits<6> immr;
1901 bits<6> imms;
1902
1903 let Inst{30-29} = opc;
1904 let Inst{28-23} = 0b100110;
1905 let Inst{21-16} = immr;
1906 let Inst{15-10} = imms;
1907 let Inst{9-5} = Rn;
1908 let Inst{4-0} = Rd;
1909}
1910
1911multiclass BitfieldImm<bits<2> opc, string asm> {
1912 def Wri : BaseBitfieldImm<opc, GPR32, imm0_31, asm> {
1913 let Inst{31} = 0;
1914 let Inst{22} = 0;
1915 // imms<5> and immr<5> must be zero, else ReservedValue().
1916 let Inst{21} = 0;
1917 let Inst{15} = 0;
1918 }
1919 def Xri : BaseBitfieldImm<opc, GPR64, imm0_63, asm> {
1920 let Inst{31} = 1;
1921 let Inst{22} = 1;
1922 }
1923}
1924
1925let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
1926class BaseBitfieldImmWith2RegArgs<bits<2> opc,
1927 RegisterClass regtype, Operand imm_type, string asm>
1928 : I<(outs regtype:$Rd), (ins regtype:$src, regtype:$Rn, imm_type:$immr,
1929 imm_type:$imms),
1930 asm, "\t$Rd, $Rn, $immr, $imms", "$src = $Rd", []>,
1931 Sched<[WriteIS, ReadI]> {
1932 bits<5> Rd;
1933 bits<5> Rn;
1934 bits<6> immr;
1935 bits<6> imms;
1936
1937 let Inst{30-29} = opc;
1938 let Inst{28-23} = 0b100110;
1939 let Inst{21-16} = immr;
1940 let Inst{15-10} = imms;
1941 let Inst{9-5} = Rn;
1942 let Inst{4-0} = Rd;
1943}
1944
1945multiclass BitfieldImmWith2RegArgs<bits<2> opc, string asm> {
1946 def Wri : BaseBitfieldImmWith2RegArgs<opc, GPR32, imm0_31, asm> {
1947 let Inst{31} = 0;
1948 let Inst{22} = 0;
1949 // imms<5> and immr<5> must be zero, else ReservedValue().
1950 let Inst{21} = 0;
1951 let Inst{15} = 0;
1952 }
1953 def Xri : BaseBitfieldImmWith2RegArgs<opc, GPR64, imm0_63, asm> {
1954 let Inst{31} = 1;
1955 let Inst{22} = 1;
1956 }
1957}
1958
1959//---
1960// Logical
1961//---
1962
1963// Logical (immediate)
1964class BaseLogicalImm<bits<2> opc, RegisterClass dregtype,
1965 RegisterClass sregtype, Operand imm_type, string asm,
1966 list<dag> pattern>
1967 : I<(outs dregtype:$Rd), (ins sregtype:$Rn, imm_type:$imm),
1968 asm, "\t$Rd, $Rn, $imm", "", pattern>,
1969 Sched<[WriteI, ReadI]> {
1970 bits<5> Rd;
1971 bits<5> Rn;
1972 bits<13> imm;
1973 let Inst{30-29} = opc;
1974 let Inst{28-23} = 0b100100;
1975 let Inst{22} = imm{12};
1976 let Inst{21-16} = imm{11-6};
1977 let Inst{15-10} = imm{5-0};
1978 let Inst{9-5} = Rn;
1979 let Inst{4-0} = Rd;
1980
1981 let DecoderMethod = "DecodeLogicalImmInstruction";
1982}
1983
1984// Logical (shifted register)
1985class BaseLogicalSReg<bits<2> opc, bit N, RegisterClass regtype,
1986 logical_shifted_reg shifted_regtype, string asm,
1987 list<dag> pattern>
1988 : I<(outs regtype:$Rd), (ins regtype:$Rn, shifted_regtype:$Rm),
1989 asm, "\t$Rd, $Rn, $Rm", "", pattern>,
1990 Sched<[WriteISReg, ReadI, ReadISReg]> {
1991 // The operands are in order to match the 'addr' MI operands, so we
1992 // don't need an encoder method and by-name matching. Just use the default
1993 // in-order handling. Since we're using by-order, make sure the names
1994 // do not match.
1995 bits<5> dst;
1996 bits<5> src1;
1997 bits<5> src2;
1998 bits<8> shift;
1999 let Inst{30-29} = opc;
2000 let Inst{28-24} = 0b01010;
2001 let Inst{23-22} = shift{7-6};
2002 let Inst{21} = N;
2003 let Inst{20-16} = src2;
2004 let Inst{15-10} = shift{5-0};
2005 let Inst{9-5} = src1;
2006 let Inst{4-0} = dst;
2007
2008 let DecoderMethod = "DecodeThreeAddrSRegInstruction";
2009}
2010
2011// Aliases for register+register logical instructions.
2012class LogicalRegAlias<string asm, Instruction inst, RegisterClass regtype>
2013 : InstAlias<asm#" $dst, $src1, $src2",
2014 (inst regtype:$dst, regtype:$src1, regtype:$src2, 0)>;
2015
Arnaud A. de Grandmaisonf6432312014-07-10 15:12:26 +00002016multiclass LogicalImm<bits<2> opc, string mnemonic, SDNode OpNode,
2017 string Alias> {
Jiangning Liucd296372014-07-29 02:09:26 +00002018 let AddedComplexity = 6, isReMaterializable = 1, isAsCheapAsAMove = 1 in
Tim Northover3b0846e2014-05-24 12:50:23 +00002019 def Wri : BaseLogicalImm<opc, GPR32sp, GPR32, logical_imm32, mnemonic,
2020 [(set GPR32sp:$Rd, (OpNode GPR32:$Rn,
2021 logical_imm32:$imm))]> {
2022 let Inst{31} = 0;
2023 let Inst{22} = 0; // 64-bit version has an additional bit of immediate.
2024 }
Jiangning Liucd296372014-07-29 02:09:26 +00002025 let AddedComplexity = 6, isReMaterializable = 1, isAsCheapAsAMove = 1 in
Tim Northover3b0846e2014-05-24 12:50:23 +00002026 def Xri : BaseLogicalImm<opc, GPR64sp, GPR64, logical_imm64, mnemonic,
2027 [(set GPR64sp:$Rd, (OpNode GPR64:$Rn,
2028 logical_imm64:$imm))]> {
2029 let Inst{31} = 1;
2030 }
Arnaud A. de Grandmaisonf6432312014-07-10 15:12:26 +00002031
2032 def : InstAlias<Alias # " $Rd, $Rn, $imm",
2033 (!cast<Instruction>(NAME # "Wri") GPR32sp:$Rd, GPR32:$Rn,
2034 logical_imm32_not:$imm), 0>;
2035 def : InstAlias<Alias # " $Rd, $Rn, $imm",
2036 (!cast<Instruction>(NAME # "Xri") GPR64sp:$Rd, GPR64:$Rn,
2037 logical_imm64_not:$imm), 0>;
Tim Northover3b0846e2014-05-24 12:50:23 +00002038}
2039
Arnaud A. de Grandmaisonf6432312014-07-10 15:12:26 +00002040multiclass LogicalImmS<bits<2> opc, string mnemonic, SDNode OpNode,
2041 string Alias> {
Tim Northover3b0846e2014-05-24 12:50:23 +00002042 let isCompare = 1, Defs = [NZCV] in {
2043 def Wri : BaseLogicalImm<opc, GPR32, GPR32, logical_imm32, mnemonic,
2044 [(set GPR32:$Rd, (OpNode GPR32:$Rn, logical_imm32:$imm))]> {
2045 let Inst{31} = 0;
2046 let Inst{22} = 0; // 64-bit version has an additional bit of immediate.
2047 }
2048 def Xri : BaseLogicalImm<opc, GPR64, GPR64, logical_imm64, mnemonic,
2049 [(set GPR64:$Rd, (OpNode GPR64:$Rn, logical_imm64:$imm))]> {
2050 let Inst{31} = 1;
2051 }
2052 } // end Defs = [NZCV]
Arnaud A. de Grandmaisonf6432312014-07-10 15:12:26 +00002053
2054 def : InstAlias<Alias # " $Rd, $Rn, $imm",
2055 (!cast<Instruction>(NAME # "Wri") GPR32:$Rd, GPR32:$Rn,
2056 logical_imm32_not:$imm), 0>;
2057 def : InstAlias<Alias # " $Rd, $Rn, $imm",
2058 (!cast<Instruction>(NAME # "Xri") GPR64:$Rd, GPR64:$Rn,
2059 logical_imm64_not:$imm), 0>;
Tim Northover3b0846e2014-05-24 12:50:23 +00002060}
2061
2062class BaseLogicalRegPseudo<RegisterClass regtype, SDPatternOperator OpNode>
2063 : Pseudo<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm),
2064 [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm))]>,
2065 Sched<[WriteI, ReadI, ReadI]>;
2066
2067// Split from LogicalImm as not all instructions have both.
2068multiclass LogicalReg<bits<2> opc, bit N, string mnemonic,
2069 SDPatternOperator OpNode> {
Jiangning Liucd296372014-07-29 02:09:26 +00002070 let isReMaterializable = 1, isAsCheapAsAMove = 1 in {
Tim Northover3b0846e2014-05-24 12:50:23 +00002071 def Wrr : BaseLogicalRegPseudo<GPR32, OpNode>;
2072 def Xrr : BaseLogicalRegPseudo<GPR64, OpNode>;
Jiangning Liucd296372014-07-29 02:09:26 +00002073 }
Tim Northover3b0846e2014-05-24 12:50:23 +00002074
2075 def Wrs : BaseLogicalSReg<opc, N, GPR32, logical_shifted_reg32, mnemonic,
2076 [(set GPR32:$Rd, (OpNode GPR32:$Rn,
2077 logical_shifted_reg32:$Rm))]> {
2078 let Inst{31} = 0;
2079 }
2080 def Xrs : BaseLogicalSReg<opc, N, GPR64, logical_shifted_reg64, mnemonic,
2081 [(set GPR64:$Rd, (OpNode GPR64:$Rn,
2082 logical_shifted_reg64:$Rm))]> {
2083 let Inst{31} = 1;
2084 }
2085
2086 def : LogicalRegAlias<mnemonic,
2087 !cast<Instruction>(NAME#"Wrs"), GPR32>;
2088 def : LogicalRegAlias<mnemonic,
2089 !cast<Instruction>(NAME#"Xrs"), GPR64>;
2090}
2091
2092// Split from LogicalReg to allow setting NZCV Defs
2093multiclass LogicalRegS<bits<2> opc, bit N, string mnemonic,
2094 SDPatternOperator OpNode = null_frag> {
2095 let Defs = [NZCV], mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
2096 def Wrr : BaseLogicalRegPseudo<GPR32, OpNode>;
2097 def Xrr : BaseLogicalRegPseudo<GPR64, OpNode>;
2098
2099 def Wrs : BaseLogicalSReg<opc, N, GPR32, logical_shifted_reg32, mnemonic,
2100 [(set GPR32:$Rd, (OpNode GPR32:$Rn, logical_shifted_reg32:$Rm))]> {
2101 let Inst{31} = 0;
2102 }
2103 def Xrs : BaseLogicalSReg<opc, N, GPR64, logical_shifted_reg64, mnemonic,
2104 [(set GPR64:$Rd, (OpNode GPR64:$Rn, logical_shifted_reg64:$Rm))]> {
2105 let Inst{31} = 1;
2106 }
2107 } // Defs = [NZCV]
2108
2109 def : LogicalRegAlias<mnemonic,
2110 !cast<Instruction>(NAME#"Wrs"), GPR32>;
2111 def : LogicalRegAlias<mnemonic,
2112 !cast<Instruction>(NAME#"Xrs"), GPR64>;
2113}
2114
2115//---
2116// Conditionally set flags
2117//---
2118
2119let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
Matthias Braunaf7d7702015-07-16 20:02:37 +00002120class BaseCondComparisonImm<bit op, RegisterClass regtype, ImmLeaf immtype,
2121 string mnemonic, SDNode OpNode>
2122 : I<(outs), (ins regtype:$Rn, immtype:$imm, imm32_0_15:$nzcv, ccode:$cond),
2123 mnemonic, "\t$Rn, $imm, $nzcv, $cond", "",
2124 [(set NZCV, (OpNode regtype:$Rn, immtype:$imm, (i32 imm:$nzcv),
2125 (i32 imm:$cond), NZCV))]>,
Tim Northover3b0846e2014-05-24 12:50:23 +00002126 Sched<[WriteI, ReadI]> {
2127 let Uses = [NZCV];
2128 let Defs = [NZCV];
2129
2130 bits<5> Rn;
2131 bits<5> imm;
2132 bits<4> nzcv;
2133 bits<4> cond;
2134
2135 let Inst{30} = op;
2136 let Inst{29-21} = 0b111010010;
2137 let Inst{20-16} = imm;
2138 let Inst{15-12} = cond;
2139 let Inst{11-10} = 0b10;
2140 let Inst{9-5} = Rn;
2141 let Inst{4} = 0b0;
2142 let Inst{3-0} = nzcv;
2143}
2144
Tim Northover3b0846e2014-05-24 12:50:23 +00002145let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
Matthias Braunaf7d7702015-07-16 20:02:37 +00002146class BaseCondComparisonReg<bit op, RegisterClass regtype, string mnemonic,
2147 SDNode OpNode>
2148 : I<(outs), (ins regtype:$Rn, regtype:$Rm, imm32_0_15:$nzcv, ccode:$cond),
2149 mnemonic, "\t$Rn, $Rm, $nzcv, $cond", "",
2150 [(set NZCV, (OpNode regtype:$Rn, regtype:$Rm, (i32 imm:$nzcv),
2151 (i32 imm:$cond), NZCV))]>,
Tim Northover3b0846e2014-05-24 12:50:23 +00002152 Sched<[WriteI, ReadI, ReadI]> {
2153 let Uses = [NZCV];
2154 let Defs = [NZCV];
2155
2156 bits<5> Rn;
2157 bits<5> Rm;
2158 bits<4> nzcv;
2159 bits<4> cond;
2160
2161 let Inst{30} = op;
2162 let Inst{29-21} = 0b111010010;
2163 let Inst{20-16} = Rm;
2164 let Inst{15-12} = cond;
2165 let Inst{11-10} = 0b00;
2166 let Inst{9-5} = Rn;
2167 let Inst{4} = 0b0;
2168 let Inst{3-0} = nzcv;
2169}
2170
Matthias Braunaf7d7702015-07-16 20:02:37 +00002171multiclass CondComparison<bit op, string mnemonic, SDNode OpNode> {
2172 // immediate operand variants
2173 def Wi : BaseCondComparisonImm<op, GPR32, imm32_0_31, mnemonic, OpNode> {
Tim Northover3b0846e2014-05-24 12:50:23 +00002174 let Inst{31} = 0;
2175 }
Matthias Braunaf7d7702015-07-16 20:02:37 +00002176 def Xi : BaseCondComparisonImm<op, GPR64, imm0_31, mnemonic, OpNode> {
2177 let Inst{31} = 1;
2178 }
2179 // register operand variants
2180 def Wr : BaseCondComparisonReg<op, GPR32, mnemonic, OpNode> {
2181 let Inst{31} = 0;
2182 }
2183 def Xr : BaseCondComparisonReg<op, GPR64, mnemonic, OpNode> {
Tim Northover3b0846e2014-05-24 12:50:23 +00002184 let Inst{31} = 1;
2185 }
2186}
2187
2188//---
2189// Conditional select
2190//---
2191
2192class BaseCondSelect<bit op, bits<2> op2, RegisterClass regtype, string asm>
2193 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, ccode:$cond),
2194 asm, "\t$Rd, $Rn, $Rm, $cond", "",
2195 [(set regtype:$Rd,
2196 (AArch64csel regtype:$Rn, regtype:$Rm, (i32 imm:$cond), NZCV))]>,
2197 Sched<[WriteI, ReadI, ReadI]> {
2198 let Uses = [NZCV];
2199
2200 bits<5> Rd;
2201 bits<5> Rn;
2202 bits<5> Rm;
2203 bits<4> cond;
2204
2205 let Inst{30} = op;
2206 let Inst{29-21} = 0b011010100;
2207 let Inst{20-16} = Rm;
2208 let Inst{15-12} = cond;
2209 let Inst{11-10} = op2;
2210 let Inst{9-5} = Rn;
2211 let Inst{4-0} = Rd;
2212}
2213
2214multiclass CondSelect<bit op, bits<2> op2, string asm> {
2215 def Wr : BaseCondSelect<op, op2, GPR32, asm> {
2216 let Inst{31} = 0;
2217 }
2218 def Xr : BaseCondSelect<op, op2, GPR64, asm> {
2219 let Inst{31} = 1;
2220 }
2221}
2222
2223class BaseCondSelectOp<bit op, bits<2> op2, RegisterClass regtype, string asm,
2224 PatFrag frag>
2225 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, ccode:$cond),
2226 asm, "\t$Rd, $Rn, $Rm, $cond", "",
2227 [(set regtype:$Rd,
2228 (AArch64csel regtype:$Rn, (frag regtype:$Rm),
2229 (i32 imm:$cond), NZCV))]>,
2230 Sched<[WriteI, ReadI, ReadI]> {
2231 let Uses = [NZCV];
2232
2233 bits<5> Rd;
2234 bits<5> Rn;
2235 bits<5> Rm;
2236 bits<4> cond;
2237
2238 let Inst{30} = op;
2239 let Inst{29-21} = 0b011010100;
2240 let Inst{20-16} = Rm;
2241 let Inst{15-12} = cond;
2242 let Inst{11-10} = op2;
2243 let Inst{9-5} = Rn;
2244 let Inst{4-0} = Rd;
2245}
2246
2247def inv_cond_XFORM : SDNodeXForm<imm, [{
2248 AArch64CC::CondCode CC = static_cast<AArch64CC::CondCode>(N->getZExtValue());
Sergey Dmitrouk842a51b2015-04-28 14:05:47 +00002249 return CurDAG->getTargetConstant(AArch64CC::getInvertedCondCode(CC), SDLoc(N),
2250 MVT::i32);
Tim Northover3b0846e2014-05-24 12:50:23 +00002251}]>;
2252
2253multiclass CondSelectOp<bit op, bits<2> op2, string asm, PatFrag frag> {
2254 def Wr : BaseCondSelectOp<op, op2, GPR32, asm, frag> {
2255 let Inst{31} = 0;
2256 }
2257 def Xr : BaseCondSelectOp<op, op2, GPR64, asm, frag> {
2258 let Inst{31} = 1;
2259 }
2260
2261 def : Pat<(AArch64csel (frag GPR32:$Rm), GPR32:$Rn, (i32 imm:$cond), NZCV),
2262 (!cast<Instruction>(NAME # Wr) GPR32:$Rn, GPR32:$Rm,
2263 (inv_cond_XFORM imm:$cond))>;
2264
2265 def : Pat<(AArch64csel (frag GPR64:$Rm), GPR64:$Rn, (i32 imm:$cond), NZCV),
2266 (!cast<Instruction>(NAME # Xr) GPR64:$Rn, GPR64:$Rm,
2267 (inv_cond_XFORM imm:$cond))>;
2268}
2269
2270//---
2271// Special Mask Value
2272//---
2273def maski8_or_more : Operand<i32>,
2274 ImmLeaf<i32, [{ return (Imm & 0xff) == 0xff; }]> {
2275}
2276def maski16_or_more : Operand<i32>,
2277 ImmLeaf<i32, [{ return (Imm & 0xffff) == 0xffff; }]> {
2278}
2279
2280
2281//---
2282// Load/store
2283//---
2284
2285// (unsigned immediate)
2286// Indexed for 8-bit registers. offset is in range [0,4095].
2287def am_indexed8 : ComplexPattern<i64, 2, "SelectAddrModeIndexed8", []>;
2288def am_indexed16 : ComplexPattern<i64, 2, "SelectAddrModeIndexed16", []>;
2289def am_indexed32 : ComplexPattern<i64, 2, "SelectAddrModeIndexed32", []>;
2290def am_indexed64 : ComplexPattern<i64, 2, "SelectAddrModeIndexed64", []>;
2291def am_indexed128 : ComplexPattern<i64, 2, "SelectAddrModeIndexed128", []>;
2292
2293class UImm12OffsetOperand<int Scale> : AsmOperandClass {
2294 let Name = "UImm12Offset" # Scale;
2295 let RenderMethod = "addUImm12OffsetOperands<" # Scale # ">";
2296 let PredicateMethod = "isUImm12Offset<" # Scale # ">";
2297 let DiagnosticType = "InvalidMemoryIndexed" # Scale;
2298}
2299
2300def UImm12OffsetScale1Operand : UImm12OffsetOperand<1>;
2301def UImm12OffsetScale2Operand : UImm12OffsetOperand<2>;
2302def UImm12OffsetScale4Operand : UImm12OffsetOperand<4>;
2303def UImm12OffsetScale8Operand : UImm12OffsetOperand<8>;
2304def UImm12OffsetScale16Operand : UImm12OffsetOperand<16>;
2305
2306class uimm12_scaled<int Scale> : Operand<i64> {
2307 let ParserMatchClass
2308 = !cast<AsmOperandClass>("UImm12OffsetScale" # Scale # "Operand");
2309 let EncoderMethod
2310 = "getLdStUImm12OpValue<AArch64::fixup_aarch64_ldst_imm12_scale" # Scale # ">";
2311 let PrintMethod = "printUImm12Offset<" # Scale # ">";
2312}
2313
2314def uimm12s1 : uimm12_scaled<1>;
2315def uimm12s2 : uimm12_scaled<2>;
2316def uimm12s4 : uimm12_scaled<4>;
2317def uimm12s8 : uimm12_scaled<8>;
2318def uimm12s16 : uimm12_scaled<16>;
2319
2320class BaseLoadStoreUI<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops,
2321 string asm, list<dag> pattern>
2322 : I<oops, iops, asm, "\t$Rt, [$Rn, $offset]", "", pattern> {
2323 bits<5> Rt;
2324
2325 bits<5> Rn;
2326 bits<12> offset;
2327
2328 let Inst{31-30} = sz;
2329 let Inst{29-27} = 0b111;
2330 let Inst{26} = V;
2331 let Inst{25-24} = 0b01;
2332 let Inst{23-22} = opc;
2333 let Inst{21-10} = offset;
2334 let Inst{9-5} = Rn;
2335 let Inst{4-0} = Rt;
2336
2337 let DecoderMethod = "DecodeUnsignedLdStInstruction";
2338}
2339
2340multiclass LoadUI<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2341 Operand indextype, string asm, list<dag> pattern> {
2342 let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
2343 def ui : BaseLoadStoreUI<sz, V, opc, (outs regtype:$Rt),
2344 (ins GPR64sp:$Rn, indextype:$offset),
2345 asm, pattern>,
2346 Sched<[WriteLD]>;
2347
2348 def : InstAlias<asm # " $Rt, [$Rn]",
2349 (!cast<Instruction>(NAME # "ui") regtype:$Rt, GPR64sp:$Rn, 0)>;
2350}
2351
2352multiclass StoreUI<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2353 Operand indextype, string asm, list<dag> pattern> {
2354 let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
2355 def ui : BaseLoadStoreUI<sz, V, opc, (outs),
2356 (ins regtype:$Rt, GPR64sp:$Rn, indextype:$offset),
2357 asm, pattern>,
2358 Sched<[WriteST]>;
2359
2360 def : InstAlias<asm # " $Rt, [$Rn]",
2361 (!cast<Instruction>(NAME # "ui") regtype:$Rt, GPR64sp:$Rn, 0)>;
2362}
2363
2364def PrefetchOperand : AsmOperandClass {
2365 let Name = "Prefetch";
2366 let ParserMethod = "tryParsePrefetch";
2367}
2368def prfop : Operand<i32> {
2369 let PrintMethod = "printPrefetchOp";
2370 let ParserMatchClass = PrefetchOperand;
2371}
2372
2373let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in
2374class PrefetchUI<bits<2> sz, bit V, bits<2> opc, string asm, list<dag> pat>
2375 : BaseLoadStoreUI<sz, V, opc,
2376 (outs), (ins prfop:$Rt, GPR64sp:$Rn, uimm12s8:$offset),
2377 asm, pat>,
2378 Sched<[WriteLD]>;
2379
2380//---
2381// Load literal
2382//---
2383
2384// Load literal address: 19-bit immediate. The low two bits of the target
2385// offset are implied zero and so are not part of the immediate.
2386def am_ldrlit : Operand<OtherVT> {
2387 let EncoderMethod = "getLoadLiteralOpValue";
2388 let DecoderMethod = "DecodePCRelLabel19";
2389 let PrintMethod = "printAlignedLabel";
2390 let ParserMatchClass = PCRelLabel19Operand;
2391}
2392
2393let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
2394class LoadLiteral<bits<2> opc, bit V, RegisterClass regtype, string asm>
2395 : I<(outs regtype:$Rt), (ins am_ldrlit:$label),
2396 asm, "\t$Rt, $label", "", []>,
2397 Sched<[WriteLD]> {
2398 bits<5> Rt;
2399 bits<19> label;
2400 let Inst{31-30} = opc;
2401 let Inst{29-27} = 0b011;
2402 let Inst{26} = V;
2403 let Inst{25-24} = 0b00;
2404 let Inst{23-5} = label;
2405 let Inst{4-0} = Rt;
2406}
2407
2408let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in
2409class PrefetchLiteral<bits<2> opc, bit V, string asm, list<dag> pat>
2410 : I<(outs), (ins prfop:$Rt, am_ldrlit:$label),
2411 asm, "\t$Rt, $label", "", pat>,
2412 Sched<[WriteLD]> {
2413 bits<5> Rt;
2414 bits<19> label;
2415 let Inst{31-30} = opc;
2416 let Inst{29-27} = 0b011;
2417 let Inst{26} = V;
2418 let Inst{25-24} = 0b00;
2419 let Inst{23-5} = label;
2420 let Inst{4-0} = Rt;
2421}
2422
2423//---
2424// Load/store register offset
2425//---
2426
2427def ro_Xindexed8 : ComplexPattern<i64, 4, "SelectAddrModeXRO<8>", []>;
2428def ro_Xindexed16 : ComplexPattern<i64, 4, "SelectAddrModeXRO<16>", []>;
2429def ro_Xindexed32 : ComplexPattern<i64, 4, "SelectAddrModeXRO<32>", []>;
2430def ro_Xindexed64 : ComplexPattern<i64, 4, "SelectAddrModeXRO<64>", []>;
2431def ro_Xindexed128 : ComplexPattern<i64, 4, "SelectAddrModeXRO<128>", []>;
2432
2433def ro_Windexed8 : ComplexPattern<i64, 4, "SelectAddrModeWRO<8>", []>;
2434def ro_Windexed16 : ComplexPattern<i64, 4, "SelectAddrModeWRO<16>", []>;
2435def ro_Windexed32 : ComplexPattern<i64, 4, "SelectAddrModeWRO<32>", []>;
2436def ro_Windexed64 : ComplexPattern<i64, 4, "SelectAddrModeWRO<64>", []>;
2437def ro_Windexed128 : ComplexPattern<i64, 4, "SelectAddrModeWRO<128>", []>;
2438
2439class MemExtendOperand<string Reg, int Width> : AsmOperandClass {
2440 let Name = "Mem" # Reg # "Extend" # Width;
2441 let PredicateMethod = "isMem" # Reg # "Extend<" # Width # ">";
2442 let RenderMethod = "addMemExtendOperands";
2443 let DiagnosticType = "InvalidMemory" # Reg # "Extend" # Width;
2444}
2445
2446def MemWExtend8Operand : MemExtendOperand<"W", 8> {
2447 // The address "[x0, x1, lsl #0]" actually maps to the variant which performs
2448 // the trivial shift.
2449 let RenderMethod = "addMemExtend8Operands";
2450}
2451def MemWExtend16Operand : MemExtendOperand<"W", 16>;
2452def MemWExtend32Operand : MemExtendOperand<"W", 32>;
2453def MemWExtend64Operand : MemExtendOperand<"W", 64>;
2454def MemWExtend128Operand : MemExtendOperand<"W", 128>;
2455
2456def MemXExtend8Operand : MemExtendOperand<"X", 8> {
2457 // The address "[x0, x1, lsl #0]" actually maps to the variant which performs
2458 // the trivial shift.
2459 let RenderMethod = "addMemExtend8Operands";
2460}
2461def MemXExtend16Operand : MemExtendOperand<"X", 16>;
2462def MemXExtend32Operand : MemExtendOperand<"X", 32>;
2463def MemXExtend64Operand : MemExtendOperand<"X", 64>;
2464def MemXExtend128Operand : MemExtendOperand<"X", 128>;
2465
2466class ro_extend<AsmOperandClass ParserClass, string Reg, int Width>
2467 : Operand<i32> {
2468 let ParserMatchClass = ParserClass;
2469 let PrintMethod = "printMemExtend<'" # Reg # "', " # Width # ">";
2470 let DecoderMethod = "DecodeMemExtend";
2471 let EncoderMethod = "getMemExtendOpValue";
2472 let MIOperandInfo = (ops i32imm:$signed, i32imm:$doshift);
2473}
2474
2475def ro_Wextend8 : ro_extend<MemWExtend8Operand, "w", 8>;
2476def ro_Wextend16 : ro_extend<MemWExtend16Operand, "w", 16>;
2477def ro_Wextend32 : ro_extend<MemWExtend32Operand, "w", 32>;
2478def ro_Wextend64 : ro_extend<MemWExtend64Operand, "w", 64>;
2479def ro_Wextend128 : ro_extend<MemWExtend128Operand, "w", 128>;
2480
2481def ro_Xextend8 : ro_extend<MemXExtend8Operand, "x", 8>;
2482def ro_Xextend16 : ro_extend<MemXExtend16Operand, "x", 16>;
2483def ro_Xextend32 : ro_extend<MemXExtend32Operand, "x", 32>;
2484def ro_Xextend64 : ro_extend<MemXExtend64Operand, "x", 64>;
2485def ro_Xextend128 : ro_extend<MemXExtend128Operand, "x", 128>;
2486
2487class ROAddrMode<ComplexPattern windex, ComplexPattern xindex,
2488 Operand wextend, Operand xextend> {
2489 // CodeGen-level pattern covering the entire addressing mode.
2490 ComplexPattern Wpat = windex;
2491 ComplexPattern Xpat = xindex;
2492
2493 // Asm-level Operand covering the valid "uxtw #3" style syntax.
2494 Operand Wext = wextend;
2495 Operand Xext = xextend;
2496}
2497
2498def ro8 : ROAddrMode<ro_Windexed8, ro_Xindexed8, ro_Wextend8, ro_Xextend8>;
2499def ro16 : ROAddrMode<ro_Windexed16, ro_Xindexed16, ro_Wextend16, ro_Xextend16>;
2500def ro32 : ROAddrMode<ro_Windexed32, ro_Xindexed32, ro_Wextend32, ro_Xextend32>;
2501def ro64 : ROAddrMode<ro_Windexed64, ro_Xindexed64, ro_Wextend64, ro_Xextend64>;
2502def ro128 : ROAddrMode<ro_Windexed128, ro_Xindexed128, ro_Wextend128,
2503 ro_Xextend128>;
2504
2505class LoadStore8RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2506 string asm, dag ins, dag outs, list<dag> pat>
2507 : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> {
2508 bits<5> Rt;
2509 bits<5> Rn;
2510 bits<5> Rm;
2511 bits<2> extend;
2512 let Inst{31-30} = sz;
2513 let Inst{29-27} = 0b111;
2514 let Inst{26} = V;
2515 let Inst{25-24} = 0b00;
2516 let Inst{23-22} = opc;
2517 let Inst{21} = 1;
2518 let Inst{20-16} = Rm;
2519 let Inst{15} = extend{1}; // sign extend Rm?
2520 let Inst{14} = 1;
2521 let Inst{12} = extend{0}; // do shift?
2522 let Inst{11-10} = 0b10;
2523 let Inst{9-5} = Rn;
2524 let Inst{4-0} = Rt;
2525}
2526
2527class ROInstAlias<string asm, RegisterClass regtype, Instruction INST>
2528 : InstAlias<asm # " $Rt, [$Rn, $Rm]",
2529 (INST regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, 0, 0)>;
2530
2531multiclass Load8RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2532 string asm, ValueType Ty, SDPatternOperator loadop> {
2533 let AddedComplexity = 10 in
2534 def roW : LoadStore8RO<sz, V, opc, regtype, asm,
2535 (outs regtype:$Rt),
2536 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend8:$extend),
2537 [(set (Ty regtype:$Rt),
2538 (loadop (ro_Windexed8 GPR64sp:$Rn, GPR32:$Rm,
2539 ro_Wextend8:$extend)))]>,
2540 Sched<[WriteLDIdx, ReadAdrBase]> {
2541 let Inst{13} = 0b0;
2542 }
2543
2544 let AddedComplexity = 10 in
2545 def roX : LoadStore8RO<sz, V, opc, regtype, asm,
2546 (outs regtype:$Rt),
2547 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend8:$extend),
2548 [(set (Ty regtype:$Rt),
2549 (loadop (ro_Xindexed8 GPR64sp:$Rn, GPR64:$Rm,
2550 ro_Xextend8:$extend)))]>,
2551 Sched<[WriteLDIdx, ReadAdrBase]> {
2552 let Inst{13} = 0b1;
2553 }
2554
2555 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
2556}
2557
2558multiclass Store8RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2559 string asm, ValueType Ty, SDPatternOperator storeop> {
2560 let AddedComplexity = 10 in
2561 def roW : LoadStore8RO<sz, V, opc, regtype, asm, (outs),
2562 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend8:$extend),
2563 [(storeop (Ty regtype:$Rt),
2564 (ro_Windexed8 GPR64sp:$Rn, GPR32:$Rm,
2565 ro_Wextend8:$extend))]>,
2566 Sched<[WriteSTIdx, ReadAdrBase]> {
2567 let Inst{13} = 0b0;
2568 }
2569
2570 let AddedComplexity = 10 in
2571 def roX : LoadStore8RO<sz, V, opc, regtype, asm, (outs),
2572 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend8:$extend),
2573 [(storeop (Ty regtype:$Rt),
2574 (ro_Xindexed8 GPR64sp:$Rn, GPR64:$Rm,
2575 ro_Xextend8:$extend))]>,
2576 Sched<[WriteSTIdx, ReadAdrBase]> {
2577 let Inst{13} = 0b1;
2578 }
2579
2580 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
2581}
2582
2583class LoadStore16RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2584 string asm, dag ins, dag outs, list<dag> pat>
2585 : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> {
2586 bits<5> Rt;
2587 bits<5> Rn;
2588 bits<5> Rm;
2589 bits<2> extend;
2590 let Inst{31-30} = sz;
2591 let Inst{29-27} = 0b111;
2592 let Inst{26} = V;
2593 let Inst{25-24} = 0b00;
2594 let Inst{23-22} = opc;
2595 let Inst{21} = 1;
2596 let Inst{20-16} = Rm;
2597 let Inst{15} = extend{1}; // sign extend Rm?
2598 let Inst{14} = 1;
2599 let Inst{12} = extend{0}; // do shift?
2600 let Inst{11-10} = 0b10;
2601 let Inst{9-5} = Rn;
2602 let Inst{4-0} = Rt;
2603}
2604
2605multiclass Load16RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2606 string asm, ValueType Ty, SDPatternOperator loadop> {
2607 let AddedComplexity = 10 in
2608 def roW : LoadStore16RO<sz, V, opc, regtype, asm, (outs regtype:$Rt),
2609 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend16:$extend),
2610 [(set (Ty regtype:$Rt),
2611 (loadop (ro_Windexed16 GPR64sp:$Rn, GPR32:$Rm,
2612 ro_Wextend16:$extend)))]>,
2613 Sched<[WriteLDIdx, ReadAdrBase]> {
2614 let Inst{13} = 0b0;
2615 }
2616
2617 let AddedComplexity = 10 in
2618 def roX : LoadStore16RO<sz, V, opc, regtype, asm, (outs regtype:$Rt),
2619 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend16:$extend),
2620 [(set (Ty regtype:$Rt),
2621 (loadop (ro_Xindexed16 GPR64sp:$Rn, GPR64:$Rm,
2622 ro_Xextend16:$extend)))]>,
2623 Sched<[WriteLDIdx, ReadAdrBase]> {
2624 let Inst{13} = 0b1;
2625 }
2626
2627 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
2628}
2629
2630multiclass Store16RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2631 string asm, ValueType Ty, SDPatternOperator storeop> {
2632 let AddedComplexity = 10 in
2633 def roW : LoadStore16RO<sz, V, opc, regtype, asm, (outs),
2634 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend16:$extend),
2635 [(storeop (Ty regtype:$Rt),
2636 (ro_Windexed16 GPR64sp:$Rn, GPR32:$Rm,
2637 ro_Wextend16:$extend))]>,
2638 Sched<[WriteSTIdx, ReadAdrBase]> {
2639 let Inst{13} = 0b0;
2640 }
2641
2642 let AddedComplexity = 10 in
2643 def roX : LoadStore16RO<sz, V, opc, regtype, asm, (outs),
2644 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend16:$extend),
2645 [(storeop (Ty regtype:$Rt),
2646 (ro_Xindexed16 GPR64sp:$Rn, GPR64:$Rm,
2647 ro_Xextend16:$extend))]>,
2648 Sched<[WriteSTIdx, ReadAdrBase]> {
2649 let Inst{13} = 0b1;
2650 }
2651
2652 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
2653}
2654
2655class LoadStore32RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2656 string asm, dag ins, dag outs, list<dag> pat>
2657 : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> {
2658 bits<5> Rt;
2659 bits<5> Rn;
2660 bits<5> Rm;
2661 bits<2> extend;
2662 let Inst{31-30} = sz;
2663 let Inst{29-27} = 0b111;
2664 let Inst{26} = V;
2665 let Inst{25-24} = 0b00;
2666 let Inst{23-22} = opc;
2667 let Inst{21} = 1;
2668 let Inst{20-16} = Rm;
2669 let Inst{15} = extend{1}; // sign extend Rm?
2670 let Inst{14} = 1;
2671 let Inst{12} = extend{0}; // do shift?
2672 let Inst{11-10} = 0b10;
2673 let Inst{9-5} = Rn;
2674 let Inst{4-0} = Rt;
2675}
2676
2677multiclass Load32RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2678 string asm, ValueType Ty, SDPatternOperator loadop> {
2679 let AddedComplexity = 10 in
2680 def roW : LoadStore32RO<sz, V, opc, regtype, asm, (outs regtype:$Rt),
2681 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend32:$extend),
2682 [(set (Ty regtype:$Rt),
2683 (loadop (ro_Windexed32 GPR64sp:$Rn, GPR32:$Rm,
2684 ro_Wextend32:$extend)))]>,
2685 Sched<[WriteLDIdx, ReadAdrBase]> {
2686 let Inst{13} = 0b0;
2687 }
2688
2689 let AddedComplexity = 10 in
2690 def roX : LoadStore32RO<sz, V, opc, regtype, asm, (outs regtype:$Rt),
2691 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend32:$extend),
2692 [(set (Ty regtype:$Rt),
2693 (loadop (ro_Xindexed32 GPR64sp:$Rn, GPR64:$Rm,
2694 ro_Xextend32:$extend)))]>,
2695 Sched<[WriteLDIdx, ReadAdrBase]> {
2696 let Inst{13} = 0b1;
2697 }
2698
2699 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
2700}
2701
2702multiclass Store32RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2703 string asm, ValueType Ty, SDPatternOperator storeop> {
2704 let AddedComplexity = 10 in
2705 def roW : LoadStore32RO<sz, V, opc, regtype, asm, (outs),
2706 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend32:$extend),
2707 [(storeop (Ty regtype:$Rt),
2708 (ro_Windexed32 GPR64sp:$Rn, GPR32:$Rm,
2709 ro_Wextend32:$extend))]>,
2710 Sched<[WriteSTIdx, ReadAdrBase]> {
2711 let Inst{13} = 0b0;
2712 }
2713
2714 let AddedComplexity = 10 in
2715 def roX : LoadStore32RO<sz, V, opc, regtype, asm, (outs),
2716 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend32:$extend),
2717 [(storeop (Ty regtype:$Rt),
2718 (ro_Xindexed32 GPR64sp:$Rn, GPR64:$Rm,
2719 ro_Xextend32:$extend))]>,
2720 Sched<[WriteSTIdx, ReadAdrBase]> {
2721 let Inst{13} = 0b1;
2722 }
2723
2724 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
2725}
2726
2727class LoadStore64RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2728 string asm, dag ins, dag outs, list<dag> pat>
2729 : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> {
2730 bits<5> Rt;
2731 bits<5> Rn;
2732 bits<5> Rm;
2733 bits<2> extend;
2734 let Inst{31-30} = sz;
2735 let Inst{29-27} = 0b111;
2736 let Inst{26} = V;
2737 let Inst{25-24} = 0b00;
2738 let Inst{23-22} = opc;
2739 let Inst{21} = 1;
2740 let Inst{20-16} = Rm;
2741 let Inst{15} = extend{1}; // sign extend Rm?
2742 let Inst{14} = 1;
2743 let Inst{12} = extend{0}; // do shift?
2744 let Inst{11-10} = 0b10;
2745 let Inst{9-5} = Rn;
2746 let Inst{4-0} = Rt;
2747}
2748
2749multiclass Load64RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2750 string asm, ValueType Ty, SDPatternOperator loadop> {
2751 let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
2752 def roW : LoadStore64RO<sz, V, opc, regtype, asm, (outs regtype:$Rt),
2753 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend64:$extend),
2754 [(set (Ty regtype:$Rt),
2755 (loadop (ro_Windexed64 GPR64sp:$Rn, GPR32:$Rm,
2756 ro_Wextend64:$extend)))]>,
2757 Sched<[WriteLDIdx, ReadAdrBase]> {
2758 let Inst{13} = 0b0;
2759 }
2760
2761 let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
2762 def roX : LoadStore64RO<sz, V, opc, regtype, asm, (outs regtype:$Rt),
2763 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend64:$extend),
2764 [(set (Ty regtype:$Rt),
2765 (loadop (ro_Xindexed64 GPR64sp:$Rn, GPR64:$Rm,
2766 ro_Xextend64:$extend)))]>,
2767 Sched<[WriteLDIdx, ReadAdrBase]> {
2768 let Inst{13} = 0b1;
2769 }
2770
2771 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
2772}
2773
2774multiclass Store64RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2775 string asm, ValueType Ty, SDPatternOperator storeop> {
2776 let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
2777 def roW : LoadStore64RO<sz, V, opc, regtype, asm, (outs),
2778 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend64:$extend),
2779 [(storeop (Ty regtype:$Rt),
2780 (ro_Windexed64 GPR64sp:$Rn, GPR32:$Rm,
2781 ro_Wextend64:$extend))]>,
2782 Sched<[WriteSTIdx, ReadAdrBase]> {
2783 let Inst{13} = 0b0;
2784 }
2785
2786 let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
2787 def roX : LoadStore64RO<sz, V, opc, regtype, asm, (outs),
2788 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend64:$extend),
2789 [(storeop (Ty regtype:$Rt),
2790 (ro_Xindexed64 GPR64sp:$Rn, GPR64:$Rm,
2791 ro_Xextend64:$extend))]>,
2792 Sched<[WriteSTIdx, ReadAdrBase]> {
2793 let Inst{13} = 0b1;
2794 }
2795
2796 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
2797}
2798
2799class LoadStore128RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2800 string asm, dag ins, dag outs, list<dag> pat>
2801 : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> {
2802 bits<5> Rt;
2803 bits<5> Rn;
2804 bits<5> Rm;
2805 bits<2> extend;
2806 let Inst{31-30} = sz;
2807 let Inst{29-27} = 0b111;
2808 let Inst{26} = V;
2809 let Inst{25-24} = 0b00;
2810 let Inst{23-22} = opc;
2811 let Inst{21} = 1;
2812 let Inst{20-16} = Rm;
2813 let Inst{15} = extend{1}; // sign extend Rm?
2814 let Inst{14} = 1;
2815 let Inst{12} = extend{0}; // do shift?
2816 let Inst{11-10} = 0b10;
2817 let Inst{9-5} = Rn;
2818 let Inst{4-0} = Rt;
2819}
2820
2821multiclass Load128RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2822 string asm, ValueType Ty, SDPatternOperator loadop> {
2823 let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
2824 def roW : LoadStore128RO<sz, V, opc, regtype, asm, (outs regtype:$Rt),
2825 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend128:$extend),
2826 [(set (Ty regtype:$Rt),
2827 (loadop (ro_Windexed128 GPR64sp:$Rn, GPR32:$Rm,
2828 ro_Wextend128:$extend)))]>,
2829 Sched<[WriteLDIdx, ReadAdrBase]> {
2830 let Inst{13} = 0b0;
2831 }
2832
2833 let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
2834 def roX : LoadStore128RO<sz, V, opc, regtype, asm, (outs regtype:$Rt),
2835 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend128:$extend),
2836 [(set (Ty regtype:$Rt),
2837 (loadop (ro_Xindexed128 GPR64sp:$Rn, GPR64:$Rm,
2838 ro_Xextend128:$extend)))]>,
2839 Sched<[WriteLDIdx, ReadAdrBase]> {
2840 let Inst{13} = 0b1;
2841 }
2842
2843 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
2844}
2845
2846multiclass Store128RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2847 string asm, ValueType Ty, SDPatternOperator storeop> {
2848 let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
2849 def roW : LoadStore128RO<sz, V, opc, regtype, asm, (outs),
2850 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend128:$extend),
2851 [(storeop (Ty regtype:$Rt),
2852 (ro_Windexed128 GPR64sp:$Rn, GPR32:$Rm,
2853 ro_Wextend128:$extend))]>,
2854 Sched<[WriteSTIdx, ReadAdrBase]> {
2855 let Inst{13} = 0b0;
2856 }
2857
2858 let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
2859 def roX : LoadStore128RO<sz, V, opc, regtype, asm, (outs),
2860 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend128:$extend),
2861 [(storeop (Ty regtype:$Rt),
2862 (ro_Xindexed128 GPR64sp:$Rn, GPR64:$Rm,
2863 ro_Xextend128:$extend))]>,
2864 Sched<[WriteSTIdx, ReadAdrBase]> {
2865 let Inst{13} = 0b1;
2866 }
2867
2868 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
2869}
2870
2871let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in
2872class BasePrefetchRO<bits<2> sz, bit V, bits<2> opc, dag outs, dag ins,
2873 string asm, list<dag> pat>
2874 : I<outs, ins, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat>,
2875 Sched<[WriteLD]> {
2876 bits<5> Rt;
2877 bits<5> Rn;
2878 bits<5> Rm;
2879 bits<2> extend;
2880 let Inst{31-30} = sz;
2881 let Inst{29-27} = 0b111;
2882 let Inst{26} = V;
2883 let Inst{25-24} = 0b00;
2884 let Inst{23-22} = opc;
2885 let Inst{21} = 1;
2886 let Inst{20-16} = Rm;
2887 let Inst{15} = extend{1}; // sign extend Rm?
2888 let Inst{14} = 1;
2889 let Inst{12} = extend{0}; // do shift?
2890 let Inst{11-10} = 0b10;
2891 let Inst{9-5} = Rn;
2892 let Inst{4-0} = Rt;
2893}
2894
2895multiclass PrefetchRO<bits<2> sz, bit V, bits<2> opc, string asm> {
2896 def roW : BasePrefetchRO<sz, V, opc, (outs),
2897 (ins prfop:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend64:$extend),
2898 asm, [(AArch64Prefetch imm:$Rt,
2899 (ro_Windexed64 GPR64sp:$Rn, GPR32:$Rm,
2900 ro_Wextend64:$extend))]> {
2901 let Inst{13} = 0b0;
2902 }
2903
2904 def roX : BasePrefetchRO<sz, V, opc, (outs),
2905 (ins prfop:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend64:$extend),
2906 asm, [(AArch64Prefetch imm:$Rt,
2907 (ro_Xindexed64 GPR64sp:$Rn, GPR64:$Rm,
2908 ro_Xextend64:$extend))]> {
2909 let Inst{13} = 0b1;
2910 }
2911
2912 def : InstAlias<"prfm $Rt, [$Rn, $Rm]",
2913 (!cast<Instruction>(NAME # "roX") prfop:$Rt,
2914 GPR64sp:$Rn, GPR64:$Rm, 0, 0)>;
2915}
2916
2917//---
2918// Load/store unscaled immediate
2919//---
2920
2921def am_unscaled8 : ComplexPattern<i64, 2, "SelectAddrModeUnscaled8", []>;
2922def am_unscaled16 : ComplexPattern<i64, 2, "SelectAddrModeUnscaled16", []>;
2923def am_unscaled32 : ComplexPattern<i64, 2, "SelectAddrModeUnscaled32", []>;
2924def am_unscaled64 : ComplexPattern<i64, 2, "SelectAddrModeUnscaled64", []>;
2925def am_unscaled128 :ComplexPattern<i64, 2, "SelectAddrModeUnscaled128", []>;
2926
2927class BaseLoadStoreUnscale<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops,
2928 string asm, list<dag> pattern>
2929 : I<oops, iops, asm, "\t$Rt, [$Rn, $offset]", "", pattern> {
2930 bits<5> Rt;
2931 bits<5> Rn;
2932 bits<9> offset;
2933 let Inst{31-30} = sz;
2934 let Inst{29-27} = 0b111;
2935 let Inst{26} = V;
2936 let Inst{25-24} = 0b00;
2937 let Inst{23-22} = opc;
2938 let Inst{21} = 0;
2939 let Inst{20-12} = offset;
2940 let Inst{11-10} = 0b00;
2941 let Inst{9-5} = Rn;
2942 let Inst{4-0} = Rt;
2943
2944 let DecoderMethod = "DecodeSignedLdStInstruction";
2945}
2946
2947multiclass LoadUnscaled<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2948 string asm, list<dag> pattern> {
2949 let AddedComplexity = 1 in // try this before LoadUI
2950 def i : BaseLoadStoreUnscale<sz, V, opc, (outs regtype:$Rt),
2951 (ins GPR64sp:$Rn, simm9:$offset), asm, pattern>,
2952 Sched<[WriteLD]>;
2953
2954 def : InstAlias<asm # " $Rt, [$Rn]",
2955 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>;
2956}
2957
2958multiclass StoreUnscaled<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2959 string asm, list<dag> pattern> {
2960 let AddedComplexity = 1 in // try this before StoreUI
2961 def i : BaseLoadStoreUnscale<sz, V, opc, (outs),
2962 (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset),
2963 asm, pattern>,
2964 Sched<[WriteST]>;
2965
2966 def : InstAlias<asm # " $Rt, [$Rn]",
2967 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>;
2968}
2969
2970multiclass PrefetchUnscaled<bits<2> sz, bit V, bits<2> opc, string asm,
2971 list<dag> pat> {
2972 let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in
2973 def i : BaseLoadStoreUnscale<sz, V, opc, (outs),
2974 (ins prfop:$Rt, GPR64sp:$Rn, simm9:$offset),
2975 asm, pat>,
2976 Sched<[WriteLD]>;
2977
2978 def : InstAlias<asm # " $Rt, [$Rn]",
2979 (!cast<Instruction>(NAME # "i") prfop:$Rt, GPR64sp:$Rn, 0)>;
2980}
2981
2982//---
2983// Load/store unscaled immediate, unprivileged
2984//---
2985
2986class BaseLoadStoreUnprivileged<bits<2> sz, bit V, bits<2> opc,
2987 dag oops, dag iops, string asm>
2988 : I<oops, iops, asm, "\t$Rt, [$Rn, $offset]", "", []> {
2989 bits<5> Rt;
2990 bits<5> Rn;
2991 bits<9> offset;
2992 let Inst{31-30} = sz;
2993 let Inst{29-27} = 0b111;
2994 let Inst{26} = V;
2995 let Inst{25-24} = 0b00;
2996 let Inst{23-22} = opc;
2997 let Inst{21} = 0;
2998 let Inst{20-12} = offset;
2999 let Inst{11-10} = 0b10;
3000 let Inst{9-5} = Rn;
3001 let Inst{4-0} = Rt;
3002
3003 let DecoderMethod = "DecodeSignedLdStInstruction";
3004}
3005
3006multiclass LoadUnprivileged<bits<2> sz, bit V, bits<2> opc,
3007 RegisterClass regtype, string asm> {
3008 let mayStore = 0, mayLoad = 1, hasSideEffects = 0 in
3009 def i : BaseLoadStoreUnprivileged<sz, V, opc, (outs regtype:$Rt),
3010 (ins GPR64sp:$Rn, simm9:$offset), asm>,
3011 Sched<[WriteLD]>;
3012
3013 def : InstAlias<asm # " $Rt, [$Rn]",
3014 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>;
3015}
3016
3017multiclass StoreUnprivileged<bits<2> sz, bit V, bits<2> opc,
3018 RegisterClass regtype, string asm> {
3019 let mayStore = 1, mayLoad = 0, hasSideEffects = 0 in
3020 def i : BaseLoadStoreUnprivileged<sz, V, opc, (outs),
3021 (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset),
3022 asm>,
3023 Sched<[WriteST]>;
3024
3025 def : InstAlias<asm # " $Rt, [$Rn]",
3026 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>;
3027}
3028
3029//---
3030// Load/store pre-indexed
3031//---
3032
3033class BaseLoadStorePreIdx<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops,
3034 string asm, string cstr, list<dag> pat>
3035 : I<oops, iops, asm, "\t$Rt, [$Rn, $offset]!", cstr, pat> {
3036 bits<5> Rt;
3037 bits<5> Rn;
3038 bits<9> offset;
3039 let Inst{31-30} = sz;
3040 let Inst{29-27} = 0b111;
3041 let Inst{26} = V;
3042 let Inst{25-24} = 0;
3043 let Inst{23-22} = opc;
3044 let Inst{21} = 0;
3045 let Inst{20-12} = offset;
3046 let Inst{11-10} = 0b11;
3047 let Inst{9-5} = Rn;
3048 let Inst{4-0} = Rt;
3049
3050 let DecoderMethod = "DecodeSignedLdStInstruction";
3051}
3052
3053let hasSideEffects = 0 in {
3054let mayStore = 0, mayLoad = 1 in
3055class LoadPreIdx<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
3056 string asm>
3057 : BaseLoadStorePreIdx<sz, V, opc,
3058 (outs GPR64sp:$wback, regtype:$Rt),
3059 (ins GPR64sp:$Rn, simm9:$offset), asm,
Quentin Colombetc64c1752014-08-11 21:39:53 +00003060 "$Rn = $wback,@earlyclobber $wback", []>,
Tim Northover3b0846e2014-05-24 12:50:23 +00003061 Sched<[WriteLD, WriteAdr]>;
3062
3063let mayStore = 1, mayLoad = 0 in
3064class StorePreIdx<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
3065 string asm, SDPatternOperator storeop, ValueType Ty>
3066 : BaseLoadStorePreIdx<sz, V, opc,
3067 (outs GPR64sp:$wback),
3068 (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset),
Quentin Colombetc64c1752014-08-11 21:39:53 +00003069 asm, "$Rn = $wback,@earlyclobber $wback",
Tim Northover3b0846e2014-05-24 12:50:23 +00003070 [(set GPR64sp:$wback,
3071 (storeop (Ty regtype:$Rt), GPR64sp:$Rn, simm9:$offset))]>,
3072 Sched<[WriteAdr, WriteST]>;
3073} // hasSideEffects = 0
3074
3075//---
3076// Load/store post-indexed
3077//---
3078
Tim Northover3b0846e2014-05-24 12:50:23 +00003079class BaseLoadStorePostIdx<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops,
3080 string asm, string cstr, list<dag> pat>
3081 : I<oops, iops, asm, "\t$Rt, [$Rn], $offset", cstr, pat> {
3082 bits<5> Rt;
3083 bits<5> Rn;
3084 bits<9> offset;
3085 let Inst{31-30} = sz;
3086 let Inst{29-27} = 0b111;
3087 let Inst{26} = V;
3088 let Inst{25-24} = 0b00;
3089 let Inst{23-22} = opc;
3090 let Inst{21} = 0b0;
3091 let Inst{20-12} = offset;
3092 let Inst{11-10} = 0b01;
3093 let Inst{9-5} = Rn;
3094 let Inst{4-0} = Rt;
3095
3096 let DecoderMethod = "DecodeSignedLdStInstruction";
3097}
3098
3099let hasSideEffects = 0 in {
3100let mayStore = 0, mayLoad = 1 in
3101class LoadPostIdx<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
3102 string asm>
3103 : BaseLoadStorePostIdx<sz, V, opc,
3104 (outs GPR64sp:$wback, regtype:$Rt),
3105 (ins GPR64sp:$Rn, simm9:$offset),
Quentin Colombetc64c1752014-08-11 21:39:53 +00003106 asm, "$Rn = $wback,@earlyclobber $wback", []>,
Tim Northover3b0846e2014-05-24 12:50:23 +00003107 Sched<[WriteLD, WriteI]>;
3108
3109let mayStore = 1, mayLoad = 0 in
3110class StorePostIdx<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
3111 string asm, SDPatternOperator storeop, ValueType Ty>
3112 : BaseLoadStorePostIdx<sz, V, opc,
3113 (outs GPR64sp:$wback),
3114 (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset),
Quentin Colombetc64c1752014-08-11 21:39:53 +00003115 asm, "$Rn = $wback,@earlyclobber $wback",
Tim Northover3b0846e2014-05-24 12:50:23 +00003116 [(set GPR64sp:$wback,
3117 (storeop (Ty regtype:$Rt), GPR64sp:$Rn, simm9:$offset))]>,
3118 Sched<[WriteAdr, WriteST, ReadAdrBase]>;
3119} // hasSideEffects = 0
3120
3121
3122//---
3123// Load/store pair
3124//---
3125
3126// (indexed, offset)
3127
3128class BaseLoadStorePairOffset<bits<2> opc, bit V, bit L, dag oops, dag iops,
3129 string asm>
3130 : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn, $offset]", "", []> {
3131 bits<5> Rt;
3132 bits<5> Rt2;
3133 bits<5> Rn;
3134 bits<7> offset;
3135 let Inst{31-30} = opc;
3136 let Inst{29-27} = 0b101;
3137 let Inst{26} = V;
3138 let Inst{25-23} = 0b010;
3139 let Inst{22} = L;
3140 let Inst{21-15} = offset;
3141 let Inst{14-10} = Rt2;
3142 let Inst{9-5} = Rn;
3143 let Inst{4-0} = Rt;
3144
3145 let DecoderMethod = "DecodePairLdStInstruction";
3146}
3147
3148multiclass LoadPairOffset<bits<2> opc, bit V, RegisterClass regtype,
3149 Operand indextype, string asm> {
3150 let hasSideEffects = 0, mayStore = 0, mayLoad = 1 in
3151 def i : BaseLoadStorePairOffset<opc, V, 1,
3152 (outs regtype:$Rt, regtype:$Rt2),
3153 (ins GPR64sp:$Rn, indextype:$offset), asm>,
3154 Sched<[WriteLD, WriteLDHi]>;
3155
3156 def : InstAlias<asm # " $Rt, $Rt2, [$Rn]",
3157 (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2,
3158 GPR64sp:$Rn, 0)>;
3159}
3160
3161
3162multiclass StorePairOffset<bits<2> opc, bit V, RegisterClass regtype,
3163 Operand indextype, string asm> {
3164 let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in
3165 def i : BaseLoadStorePairOffset<opc, V, 0, (outs),
3166 (ins regtype:$Rt, regtype:$Rt2,
3167 GPR64sp:$Rn, indextype:$offset),
3168 asm>,
3169 Sched<[WriteSTP]>;
3170
3171 def : InstAlias<asm # " $Rt, $Rt2, [$Rn]",
3172 (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2,
3173 GPR64sp:$Rn, 0)>;
3174}
3175
3176// (pre-indexed)
3177class BaseLoadStorePairPreIdx<bits<2> opc, bit V, bit L, dag oops, dag iops,
3178 string asm>
Quentin Colombetc64c1752014-08-11 21:39:53 +00003179 : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn, $offset]!", "$Rn = $wback,@earlyclobber $wback", []> {
Tim Northover3b0846e2014-05-24 12:50:23 +00003180 bits<5> Rt;
3181 bits<5> Rt2;
3182 bits<5> Rn;
3183 bits<7> offset;
3184 let Inst{31-30} = opc;
3185 let Inst{29-27} = 0b101;
3186 let Inst{26} = V;
3187 let Inst{25-23} = 0b011;
3188 let Inst{22} = L;
3189 let Inst{21-15} = offset;
3190 let Inst{14-10} = Rt2;
3191 let Inst{9-5} = Rn;
3192 let Inst{4-0} = Rt;
3193
3194 let DecoderMethod = "DecodePairLdStInstruction";
3195}
3196
3197let hasSideEffects = 0 in {
3198let mayStore = 0, mayLoad = 1 in
3199class LoadPairPreIdx<bits<2> opc, bit V, RegisterClass regtype,
3200 Operand indextype, string asm>
3201 : BaseLoadStorePairPreIdx<opc, V, 1,
3202 (outs GPR64sp:$wback, regtype:$Rt, regtype:$Rt2),
3203 (ins GPR64sp:$Rn, indextype:$offset), asm>,
3204 Sched<[WriteLD, WriteLDHi, WriteAdr]>;
3205
3206let mayStore = 1, mayLoad = 0 in
3207class StorePairPreIdx<bits<2> opc, bit V, RegisterClass regtype,
3208 Operand indextype, string asm>
3209 : BaseLoadStorePairPreIdx<opc, V, 0, (outs GPR64sp:$wback),
3210 (ins regtype:$Rt, regtype:$Rt2,
3211 GPR64sp:$Rn, indextype:$offset),
3212 asm>,
3213 Sched<[WriteAdr, WriteSTP]>;
3214} // hasSideEffects = 0
3215
3216// (post-indexed)
3217
3218class BaseLoadStorePairPostIdx<bits<2> opc, bit V, bit L, dag oops, dag iops,
3219 string asm>
Quentin Colombetc64c1752014-08-11 21:39:53 +00003220 : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn], $offset", "$Rn = $wback,@earlyclobber $wback", []> {
Tim Northover3b0846e2014-05-24 12:50:23 +00003221 bits<5> Rt;
3222 bits<5> Rt2;
3223 bits<5> Rn;
3224 bits<7> offset;
3225 let Inst{31-30} = opc;
3226 let Inst{29-27} = 0b101;
3227 let Inst{26} = V;
3228 let Inst{25-23} = 0b001;
3229 let Inst{22} = L;
3230 let Inst{21-15} = offset;
3231 let Inst{14-10} = Rt2;
3232 let Inst{9-5} = Rn;
3233 let Inst{4-0} = Rt;
3234
3235 let DecoderMethod = "DecodePairLdStInstruction";
3236}
3237
3238let hasSideEffects = 0 in {
3239let mayStore = 0, mayLoad = 1 in
3240class LoadPairPostIdx<bits<2> opc, bit V, RegisterClass regtype,
3241 Operand idxtype, string asm>
3242 : BaseLoadStorePairPostIdx<opc, V, 1,
3243 (outs GPR64sp:$wback, regtype:$Rt, regtype:$Rt2),
3244 (ins GPR64sp:$Rn, idxtype:$offset), asm>,
3245 Sched<[WriteLD, WriteLDHi, WriteAdr]>;
3246
3247let mayStore = 1, mayLoad = 0 in
3248class StorePairPostIdx<bits<2> opc, bit V, RegisterClass regtype,
3249 Operand idxtype, string asm>
3250 : BaseLoadStorePairPostIdx<opc, V, 0, (outs),
3251 (ins GPR64sp:$wback, regtype:$Rt, regtype:$Rt2,
3252 GPR64sp:$Rn, idxtype:$offset),
3253 asm>,
3254 Sched<[WriteAdr, WriteSTP]>;
3255} // hasSideEffects = 0
3256
3257// (no-allocate)
3258
3259class BaseLoadStorePairNoAlloc<bits<2> opc, bit V, bit L, dag oops, dag iops,
3260 string asm>
3261 : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn, $offset]", "", []> {
3262 bits<5> Rt;
3263 bits<5> Rt2;
3264 bits<5> Rn;
3265 bits<7> offset;
3266 let Inst{31-30} = opc;
3267 let Inst{29-27} = 0b101;
3268 let Inst{26} = V;
3269 let Inst{25-23} = 0b000;
3270 let Inst{22} = L;
3271 let Inst{21-15} = offset;
3272 let Inst{14-10} = Rt2;
3273 let Inst{9-5} = Rn;
3274 let Inst{4-0} = Rt;
3275
3276 let DecoderMethod = "DecodePairLdStInstruction";
3277}
3278
3279multiclass LoadPairNoAlloc<bits<2> opc, bit V, RegisterClass regtype,
3280 Operand indextype, string asm> {
3281 let hasSideEffects = 0, mayStore = 0, mayLoad = 1 in
3282 def i : BaseLoadStorePairNoAlloc<opc, V, 1,
3283 (outs regtype:$Rt, regtype:$Rt2),
3284 (ins GPR64sp:$Rn, indextype:$offset), asm>,
3285 Sched<[WriteLD, WriteLDHi]>;
3286
3287
3288 def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]",
3289 (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2,
3290 GPR64sp:$Rn, 0)>;
3291}
3292
3293multiclass StorePairNoAlloc<bits<2> opc, bit V, RegisterClass regtype,
3294 Operand indextype, string asm> {
3295 let hasSideEffects = 0, mayStore = 1, mayLoad = 0 in
3296 def i : BaseLoadStorePairNoAlloc<opc, V, 0, (outs),
3297 (ins regtype:$Rt, regtype:$Rt2,
3298 GPR64sp:$Rn, indextype:$offset),
3299 asm>,
3300 Sched<[WriteSTP]>;
3301
3302 def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]",
3303 (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2,
3304 GPR64sp:$Rn, 0)>;
3305}
3306
3307//---
3308// Load/store exclusive
3309//---
3310
3311// True exclusive operations write to and/or read from the system's exclusive
3312// monitors, which as far as a compiler is concerned can be modelled as a
3313// random shared memory address. Hence LoadExclusive mayStore.
3314//
3315// Since these instructions have the undefined register bits set to 1 in
3316// their canonical form, we need a post encoder method to set those bits
3317// to 1 when encoding these instructions. We do this using the
3318// fixLoadStoreExclusive function. This function has template parameters:
3319//
3320// fixLoadStoreExclusive<int hasRs, int hasRt2>
3321//
3322// hasRs indicates that the instruction uses the Rs field, so we won't set
3323// it to 1 (and the same for Rt2). We don't need template parameters for
3324// the other register fields since Rt and Rn are always used.
3325//
3326let hasSideEffects = 1, mayLoad = 1, mayStore = 1 in
3327class BaseLoadStoreExclusive<bits<2> sz, bit o2, bit L, bit o1, bit o0,
3328 dag oops, dag iops, string asm, string operands>
3329 : I<oops, iops, asm, operands, "", []> {
3330 let Inst{31-30} = sz;
3331 let Inst{29-24} = 0b001000;
3332 let Inst{23} = o2;
3333 let Inst{22} = L;
3334 let Inst{21} = o1;
3335 let Inst{15} = o0;
3336
3337 let DecoderMethod = "DecodeExclusiveLdStInstruction";
3338}
3339
3340// Neither Rs nor Rt2 operands.
3341class LoadStoreExclusiveSimple<bits<2> sz, bit o2, bit L, bit o1, bit o0,
3342 dag oops, dag iops, string asm, string operands>
3343 : BaseLoadStoreExclusive<sz, o2, L, o1, o0, oops, iops, asm, operands> {
3344 bits<5> Rt;
3345 bits<5> Rn;
Vladimir Sukharevd49cb8f2015-04-16 15:30:43 +00003346 let Inst{20-16} = 0b11111;
3347 let Unpredictable{20-16} = 0b11111;
3348 let Inst{14-10} = 0b11111;
3349 let Unpredictable{14-10} = 0b11111;
Tim Northover3b0846e2014-05-24 12:50:23 +00003350 let Inst{9-5} = Rn;
3351 let Inst{4-0} = Rt;
3352
3353 let PostEncoderMethod = "fixLoadStoreExclusive<0,0>";
3354}
3355
3356// Simple load acquires don't set the exclusive monitor
3357let mayLoad = 1, mayStore = 0 in
3358class LoadAcquire<bits<2> sz, bit o2, bit L, bit o1, bit o0,
3359 RegisterClass regtype, string asm>
3360 : LoadStoreExclusiveSimple<sz, o2, L, o1, o0, (outs regtype:$Rt),
3361 (ins GPR64sp0:$Rn), asm, "\t$Rt, [$Rn]">,
3362 Sched<[WriteLD]>;
3363
3364class LoadExclusive<bits<2> sz, bit o2, bit L, bit o1, bit o0,
3365 RegisterClass regtype, string asm>
3366 : LoadStoreExclusiveSimple<sz, o2, L, o1, o0, (outs regtype:$Rt),
3367 (ins GPR64sp0:$Rn), asm, "\t$Rt, [$Rn]">,
3368 Sched<[WriteLD]>;
3369
3370class LoadExclusivePair<bits<2> sz, bit o2, bit L, bit o1, bit o0,
3371 RegisterClass regtype, string asm>
3372 : BaseLoadStoreExclusive<sz, o2, L, o1, o0,
3373 (outs regtype:$Rt, regtype:$Rt2),
3374 (ins GPR64sp0:$Rn), asm,
3375 "\t$Rt, $Rt2, [$Rn]">,
3376 Sched<[WriteLD, WriteLDHi]> {
3377 bits<5> Rt;
3378 bits<5> Rt2;
3379 bits<5> Rn;
3380 let Inst{14-10} = Rt2;
3381 let Inst{9-5} = Rn;
3382 let Inst{4-0} = Rt;
3383
3384 let PostEncoderMethod = "fixLoadStoreExclusive<0,1>";
3385}
3386
3387// Simple store release operations do not check the exclusive monitor.
3388let mayLoad = 0, mayStore = 1 in
3389class StoreRelease<bits<2> sz, bit o2, bit L, bit o1, bit o0,
3390 RegisterClass regtype, string asm>
3391 : LoadStoreExclusiveSimple<sz, o2, L, o1, o0, (outs),
3392 (ins regtype:$Rt, GPR64sp0:$Rn),
3393 asm, "\t$Rt, [$Rn]">,
3394 Sched<[WriteST]>;
3395
3396let mayLoad = 1, mayStore = 1 in
3397class StoreExclusive<bits<2> sz, bit o2, bit L, bit o1, bit o0,
3398 RegisterClass regtype, string asm>
3399 : BaseLoadStoreExclusive<sz, o2, L, o1, o0, (outs GPR32:$Ws),
3400 (ins regtype:$Rt, GPR64sp0:$Rn),
3401 asm, "\t$Ws, $Rt, [$Rn]">,
3402 Sched<[WriteSTX]> {
3403 bits<5> Ws;
3404 bits<5> Rt;
3405 bits<5> Rn;
3406 let Inst{20-16} = Ws;
3407 let Inst{9-5} = Rn;
3408 let Inst{4-0} = Rt;
3409
3410 let Constraints = "@earlyclobber $Ws";
3411 let PostEncoderMethod = "fixLoadStoreExclusive<1,0>";
3412}
3413
3414class StoreExclusivePair<bits<2> sz, bit o2, bit L, bit o1, bit o0,
3415 RegisterClass regtype, string asm>
3416 : BaseLoadStoreExclusive<sz, o2, L, o1, o0,
3417 (outs GPR32:$Ws),
3418 (ins regtype:$Rt, regtype:$Rt2, GPR64sp0:$Rn),
3419 asm, "\t$Ws, $Rt, $Rt2, [$Rn]">,
3420 Sched<[WriteSTX]> {
3421 bits<5> Ws;
3422 bits<5> Rt;
3423 bits<5> Rt2;
3424 bits<5> Rn;
3425 let Inst{20-16} = Ws;
3426 let Inst{14-10} = Rt2;
3427 let Inst{9-5} = Rn;
3428 let Inst{4-0} = Rt;
3429
3430 let Constraints = "@earlyclobber $Ws";
3431}
3432
3433//---
3434// Exception generation
3435//---
3436
3437let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in
3438class ExceptionGeneration<bits<3> op1, bits<2> ll, string asm>
3439 : I<(outs), (ins imm0_65535:$imm), asm, "\t$imm", "", []>,
3440 Sched<[WriteSys]> {
3441 bits<16> imm;
3442 let Inst{31-24} = 0b11010100;
3443 let Inst{23-21} = op1;
3444 let Inst{20-5} = imm;
3445 let Inst{4-2} = 0b000;
3446 let Inst{1-0} = ll;
3447}
3448
3449let Predicates = [HasFPARMv8] in {
3450
3451//---
3452// Floating point to integer conversion
3453//---
3454
3455class BaseFPToIntegerUnscaled<bits<2> type, bits<2> rmode, bits<3> opcode,
3456 RegisterClass srcType, RegisterClass dstType,
3457 string asm, list<dag> pattern>
3458 : I<(outs dstType:$Rd), (ins srcType:$Rn),
3459 asm, "\t$Rd, $Rn", "", pattern>,
3460 Sched<[WriteFCvt]> {
3461 bits<5> Rd;
3462 bits<5> Rn;
3463 let Inst{30-29} = 0b00;
3464 let Inst{28-24} = 0b11110;
3465 let Inst{23-22} = type;
3466 let Inst{21} = 1;
3467 let Inst{20-19} = rmode;
3468 let Inst{18-16} = opcode;
3469 let Inst{15-10} = 0;
3470 let Inst{9-5} = Rn;
3471 let Inst{4-0} = Rd;
3472}
3473
3474let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
3475class BaseFPToInteger<bits<2> type, bits<2> rmode, bits<3> opcode,
3476 RegisterClass srcType, RegisterClass dstType,
3477 Operand immType, string asm, list<dag> pattern>
3478 : I<(outs dstType:$Rd), (ins srcType:$Rn, immType:$scale),
3479 asm, "\t$Rd, $Rn, $scale", "", pattern>,
3480 Sched<[WriteFCvt]> {
3481 bits<5> Rd;
3482 bits<5> Rn;
3483 bits<6> scale;
3484 let Inst{30-29} = 0b00;
3485 let Inst{28-24} = 0b11110;
3486 let Inst{23-22} = type;
3487 let Inst{21} = 0;
3488 let Inst{20-19} = rmode;
3489 let Inst{18-16} = opcode;
3490 let Inst{15-10} = scale;
3491 let Inst{9-5} = Rn;
3492 let Inst{4-0} = Rd;
3493}
3494
3495multiclass FPToIntegerUnscaled<bits<2> rmode, bits<3> opcode, string asm,
3496 SDPatternOperator OpN> {
3497 // Unscaled single-precision to 32-bit
3498 def UWSr : BaseFPToIntegerUnscaled<0b00, rmode, opcode, FPR32, GPR32, asm,
3499 [(set GPR32:$Rd, (OpN FPR32:$Rn))]> {
3500 let Inst{31} = 0; // 32-bit GPR flag
3501 }
3502
3503 // Unscaled single-precision to 64-bit
3504 def UXSr : BaseFPToIntegerUnscaled<0b00, rmode, opcode, FPR32, GPR64, asm,
3505 [(set GPR64:$Rd, (OpN FPR32:$Rn))]> {
3506 let Inst{31} = 1; // 64-bit GPR flag
3507 }
3508
3509 // Unscaled double-precision to 32-bit
3510 def UWDr : BaseFPToIntegerUnscaled<0b01, rmode, opcode, FPR64, GPR32, asm,
3511 [(set GPR32:$Rd, (OpN (f64 FPR64:$Rn)))]> {
3512 let Inst{31} = 0; // 32-bit GPR flag
3513 }
3514
3515 // Unscaled double-precision to 64-bit
3516 def UXDr : BaseFPToIntegerUnscaled<0b01, rmode, opcode, FPR64, GPR64, asm,
3517 [(set GPR64:$Rd, (OpN (f64 FPR64:$Rn)))]> {
3518 let Inst{31} = 1; // 64-bit GPR flag
3519 }
3520}
3521
3522multiclass FPToIntegerScaled<bits<2> rmode, bits<3> opcode, string asm,
3523 SDPatternOperator OpN> {
3524 // Scaled single-precision to 32-bit
3525 def SWSri : BaseFPToInteger<0b00, rmode, opcode, FPR32, GPR32,
3526 fixedpoint_f32_i32, asm,
3527 [(set GPR32:$Rd, (OpN (fmul FPR32:$Rn,
3528 fixedpoint_f32_i32:$scale)))]> {
3529 let Inst{31} = 0; // 32-bit GPR flag
3530 let scale{5} = 1;
3531 }
3532
3533 // Scaled single-precision to 64-bit
3534 def SXSri : BaseFPToInteger<0b00, rmode, opcode, FPR32, GPR64,
3535 fixedpoint_f32_i64, asm,
3536 [(set GPR64:$Rd, (OpN (fmul FPR32:$Rn,
3537 fixedpoint_f32_i64:$scale)))]> {
3538 let Inst{31} = 1; // 64-bit GPR flag
3539 }
3540
3541 // Scaled double-precision to 32-bit
3542 def SWDri : BaseFPToInteger<0b01, rmode, opcode, FPR64, GPR32,
3543 fixedpoint_f64_i32, asm,
3544 [(set GPR32:$Rd, (OpN (fmul FPR64:$Rn,
3545 fixedpoint_f64_i32:$scale)))]> {
3546 let Inst{31} = 0; // 32-bit GPR flag
3547 let scale{5} = 1;
3548 }
3549
3550 // Scaled double-precision to 64-bit
3551 def SXDri : BaseFPToInteger<0b01, rmode, opcode, FPR64, GPR64,
3552 fixedpoint_f64_i64, asm,
3553 [(set GPR64:$Rd, (OpN (fmul FPR64:$Rn,
3554 fixedpoint_f64_i64:$scale)))]> {
3555 let Inst{31} = 1; // 64-bit GPR flag
3556 }
3557}
3558
3559//---
3560// Integer to floating point conversion
3561//---
3562
3563let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
3564class BaseIntegerToFP<bit isUnsigned,
3565 RegisterClass srcType, RegisterClass dstType,
3566 Operand immType, string asm, list<dag> pattern>
3567 : I<(outs dstType:$Rd), (ins srcType:$Rn, immType:$scale),
3568 asm, "\t$Rd, $Rn, $scale", "", pattern>,
3569 Sched<[WriteFCvt]> {
3570 bits<5> Rd;
3571 bits<5> Rn;
3572 bits<6> scale;
3573 let Inst{30-23} = 0b00111100;
3574 let Inst{21-17} = 0b00001;
3575 let Inst{16} = isUnsigned;
3576 let Inst{15-10} = scale;
3577 let Inst{9-5} = Rn;
3578 let Inst{4-0} = Rd;
3579}
3580
3581class BaseIntegerToFPUnscaled<bit isUnsigned,
3582 RegisterClass srcType, RegisterClass dstType,
3583 ValueType dvt, string asm, SDNode node>
3584 : I<(outs dstType:$Rd), (ins srcType:$Rn),
3585 asm, "\t$Rd, $Rn", "", [(set (dvt dstType:$Rd), (node srcType:$Rn))]>,
3586 Sched<[WriteFCvt]> {
3587 bits<5> Rd;
3588 bits<5> Rn;
3589 bits<6> scale;
3590 let Inst{30-23} = 0b00111100;
3591 let Inst{21-17} = 0b10001;
3592 let Inst{16} = isUnsigned;
3593 let Inst{15-10} = 0b000000;
3594 let Inst{9-5} = Rn;
3595 let Inst{4-0} = Rd;
3596}
3597
3598multiclass IntegerToFP<bit isUnsigned, string asm, SDNode node> {
3599 // Unscaled
3600 def UWSri: BaseIntegerToFPUnscaled<isUnsigned, GPR32, FPR32, f32, asm, node> {
3601 let Inst{31} = 0; // 32-bit GPR flag
3602 let Inst{22} = 0; // 32-bit FPR flag
3603 }
3604
3605 def UWDri: BaseIntegerToFPUnscaled<isUnsigned, GPR32, FPR64, f64, asm, node> {
3606 let Inst{31} = 0; // 32-bit GPR flag
3607 let Inst{22} = 1; // 64-bit FPR flag
3608 }
3609
3610 def UXSri: BaseIntegerToFPUnscaled<isUnsigned, GPR64, FPR32, f32, asm, node> {
3611 let Inst{31} = 1; // 64-bit GPR flag
3612 let Inst{22} = 0; // 32-bit FPR flag
3613 }
3614
3615 def UXDri: BaseIntegerToFPUnscaled<isUnsigned, GPR64, FPR64, f64, asm, node> {
3616 let Inst{31} = 1; // 64-bit GPR flag
3617 let Inst{22} = 1; // 64-bit FPR flag
3618 }
3619
3620 // Scaled
3621 def SWSri: BaseIntegerToFP<isUnsigned, GPR32, FPR32, fixedpoint_f32_i32, asm,
3622 [(set FPR32:$Rd,
3623 (fdiv (node GPR32:$Rn),
3624 fixedpoint_f32_i32:$scale))]> {
3625 let Inst{31} = 0; // 32-bit GPR flag
3626 let Inst{22} = 0; // 32-bit FPR flag
3627 let scale{5} = 1;
3628 }
3629
3630 def SWDri: BaseIntegerToFP<isUnsigned, GPR32, FPR64, fixedpoint_f64_i32, asm,
3631 [(set FPR64:$Rd,
3632 (fdiv (node GPR32:$Rn),
3633 fixedpoint_f64_i32:$scale))]> {
3634 let Inst{31} = 0; // 32-bit GPR flag
3635 let Inst{22} = 1; // 64-bit FPR flag
3636 let scale{5} = 1;
3637 }
3638
3639 def SXSri: BaseIntegerToFP<isUnsigned, GPR64, FPR32, fixedpoint_f32_i64, asm,
3640 [(set FPR32:$Rd,
3641 (fdiv (node GPR64:$Rn),
3642 fixedpoint_f32_i64:$scale))]> {
3643 let Inst{31} = 1; // 64-bit GPR flag
3644 let Inst{22} = 0; // 32-bit FPR flag
3645 }
3646
3647 def SXDri: BaseIntegerToFP<isUnsigned, GPR64, FPR64, fixedpoint_f64_i64, asm,
3648 [(set FPR64:$Rd,
3649 (fdiv (node GPR64:$Rn),
3650 fixedpoint_f64_i64:$scale))]> {
3651 let Inst{31} = 1; // 64-bit GPR flag
3652 let Inst{22} = 1; // 64-bit FPR flag
3653 }
3654}
3655
3656//---
3657// Unscaled integer <-> floating point conversion (i.e. FMOV)
3658//---
3659
3660let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
3661class BaseUnscaledConversion<bits<2> rmode, bits<3> opcode,
3662 RegisterClass srcType, RegisterClass dstType,
3663 string asm>
3664 : I<(outs dstType:$Rd), (ins srcType:$Rn), asm, "\t$Rd, $Rn", "",
3665 // We use COPY_TO_REGCLASS for these bitconvert operations.
3666 // copyPhysReg() expands the resultant COPY instructions after
3667 // regalloc is done. This gives greater freedom for the allocator
3668 // and related passes (coalescing, copy propagation, et. al.) to
3669 // be more effective.
3670 [/*(set (dvt dstType:$Rd), (bitconvert (svt srcType:$Rn)))*/]>,
3671 Sched<[WriteFCopy]> {
3672 bits<5> Rd;
3673 bits<5> Rn;
3674 let Inst{30-23} = 0b00111100;
3675 let Inst{21} = 1;
3676 let Inst{20-19} = rmode;
3677 let Inst{18-16} = opcode;
3678 let Inst{15-10} = 0b000000;
3679 let Inst{9-5} = Rn;
3680 let Inst{4-0} = Rd;
3681}
3682
3683let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
3684class BaseUnscaledConversionToHigh<bits<2> rmode, bits<3> opcode,
3685 RegisterClass srcType, RegisterOperand dstType, string asm,
3686 string kind>
3687 : I<(outs dstType:$Rd), (ins srcType:$Rn, VectorIndex1:$idx), asm,
3688 "{\t$Rd"#kind#"$idx, $Rn|"#kind#"\t$Rd$idx, $Rn}", "", []>,
3689 Sched<[WriteFCopy]> {
3690 bits<5> Rd;
3691 bits<5> Rn;
3692 let Inst{30-23} = 0b00111101;
3693 let Inst{21} = 1;
3694 let Inst{20-19} = rmode;
3695 let Inst{18-16} = opcode;
3696 let Inst{15-10} = 0b000000;
3697 let Inst{9-5} = Rn;
3698 let Inst{4-0} = Rd;
3699
3700 let DecoderMethod = "DecodeFMOVLaneInstruction";
3701}
3702
3703let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
3704class BaseUnscaledConversionFromHigh<bits<2> rmode, bits<3> opcode,
3705 RegisterOperand srcType, RegisterClass dstType, string asm,
3706 string kind>
3707 : I<(outs dstType:$Rd), (ins srcType:$Rn, VectorIndex1:$idx), asm,
3708 "{\t$Rd, $Rn"#kind#"$idx|"#kind#"\t$Rd, $Rn$idx}", "", []>,
3709 Sched<[WriteFCopy]> {
3710 bits<5> Rd;
3711 bits<5> Rn;
3712 let Inst{30-23} = 0b00111101;
3713 let Inst{21} = 1;
3714 let Inst{20-19} = rmode;
3715 let Inst{18-16} = opcode;
3716 let Inst{15-10} = 0b000000;
3717 let Inst{9-5} = Rn;
3718 let Inst{4-0} = Rd;
3719
3720 let DecoderMethod = "DecodeFMOVLaneInstruction";
3721}
3722
3723
3724
3725multiclass UnscaledConversion<string asm> {
3726 def WSr : BaseUnscaledConversion<0b00, 0b111, GPR32, FPR32, asm> {
3727 let Inst{31} = 0; // 32-bit GPR flag
3728 let Inst{22} = 0; // 32-bit FPR flag
3729 }
3730
3731 def XDr : BaseUnscaledConversion<0b00, 0b111, GPR64, FPR64, asm> {
3732 let Inst{31} = 1; // 64-bit GPR flag
3733 let Inst{22} = 1; // 64-bit FPR flag
3734 }
3735
3736 def SWr : BaseUnscaledConversion<0b00, 0b110, FPR32, GPR32, asm> {
3737 let Inst{31} = 0; // 32-bit GPR flag
3738 let Inst{22} = 0; // 32-bit FPR flag
3739 }
3740
3741 def DXr : BaseUnscaledConversion<0b00, 0b110, FPR64, GPR64, asm> {
3742 let Inst{31} = 1; // 64-bit GPR flag
3743 let Inst{22} = 1; // 64-bit FPR flag
3744 }
3745
3746 def XDHighr : BaseUnscaledConversionToHigh<0b01, 0b111, GPR64, V128,
3747 asm, ".d"> {
3748 let Inst{31} = 1;
3749 let Inst{22} = 0;
3750 }
3751
3752 def DXHighr : BaseUnscaledConversionFromHigh<0b01, 0b110, V128, GPR64,
3753 asm, ".d"> {
3754 let Inst{31} = 1;
3755 let Inst{22} = 0;
3756 }
3757}
3758
3759//---
3760// Floating point conversion
3761//---
3762
3763class BaseFPConversion<bits<2> type, bits<2> opcode, RegisterClass dstType,
3764 RegisterClass srcType, string asm, list<dag> pattern>
3765 : I<(outs dstType:$Rd), (ins srcType:$Rn), asm, "\t$Rd, $Rn", "", pattern>,
3766 Sched<[WriteFCvt]> {
3767 bits<5> Rd;
3768 bits<5> Rn;
3769 let Inst{31-24} = 0b00011110;
3770 let Inst{23-22} = type;
3771 let Inst{21-17} = 0b10001;
3772 let Inst{16-15} = opcode;
3773 let Inst{14-10} = 0b10000;
3774 let Inst{9-5} = Rn;
3775 let Inst{4-0} = Rd;
3776}
3777
3778multiclass FPConversion<string asm> {
3779 // Double-precision to Half-precision
3780 def HDr : BaseFPConversion<0b01, 0b11, FPR16, FPR64, asm,
3781 [(set FPR16:$Rd, (fround FPR64:$Rn))]>;
3782
3783 // Double-precision to Single-precision
3784 def SDr : BaseFPConversion<0b01, 0b00, FPR32, FPR64, asm,
3785 [(set FPR32:$Rd, (fround FPR64:$Rn))]>;
3786
3787 // Half-precision to Double-precision
3788 def DHr : BaseFPConversion<0b11, 0b01, FPR64, FPR16, asm,
3789 [(set FPR64:$Rd, (fextend FPR16:$Rn))]>;
3790
3791 // Half-precision to Single-precision
3792 def SHr : BaseFPConversion<0b11, 0b00, FPR32, FPR16, asm,
3793 [(set FPR32:$Rd, (fextend FPR16:$Rn))]>;
3794
3795 // Single-precision to Double-precision
3796 def DSr : BaseFPConversion<0b00, 0b01, FPR64, FPR32, asm,
3797 [(set FPR64:$Rd, (fextend FPR32:$Rn))]>;
3798
3799 // Single-precision to Half-precision
3800 def HSr : BaseFPConversion<0b00, 0b11, FPR16, FPR32, asm,
3801 [(set FPR16:$Rd, (fround FPR32:$Rn))]>;
3802}
3803
3804//---
3805// Single operand floating point data processing
3806//---
3807
3808let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
3809class BaseSingleOperandFPData<bits<4> opcode, RegisterClass regtype,
3810 ValueType vt, string asm, SDPatternOperator node>
3811 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm, "\t$Rd, $Rn", "",
3812 [(set (vt regtype:$Rd), (node (vt regtype:$Rn)))]>,
3813 Sched<[WriteF]> {
3814 bits<5> Rd;
3815 bits<5> Rn;
3816 let Inst{31-23} = 0b000111100;
3817 let Inst{21-19} = 0b100;
3818 let Inst{18-15} = opcode;
3819 let Inst{14-10} = 0b10000;
3820 let Inst{9-5} = Rn;
3821 let Inst{4-0} = Rd;
3822}
3823
3824multiclass SingleOperandFPData<bits<4> opcode, string asm,
3825 SDPatternOperator node = null_frag> {
3826 def Sr : BaseSingleOperandFPData<opcode, FPR32, f32, asm, node> {
3827 let Inst{22} = 0; // 32-bit size flag
3828 }
3829
3830 def Dr : BaseSingleOperandFPData<opcode, FPR64, f64, asm, node> {
3831 let Inst{22} = 1; // 64-bit size flag
3832 }
3833}
3834
3835//---
3836// Two operand floating point data processing
3837//---
3838
3839let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
3840class BaseTwoOperandFPData<bits<4> opcode, RegisterClass regtype,
3841 string asm, list<dag> pat>
3842 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm),
3843 asm, "\t$Rd, $Rn, $Rm", "", pat>,
3844 Sched<[WriteF]> {
3845 bits<5> Rd;
3846 bits<5> Rn;
3847 bits<5> Rm;
3848 let Inst{31-23} = 0b000111100;
3849 let Inst{21} = 1;
3850 let Inst{20-16} = Rm;
3851 let Inst{15-12} = opcode;
3852 let Inst{11-10} = 0b10;
3853 let Inst{9-5} = Rn;
3854 let Inst{4-0} = Rd;
3855}
3856
3857multiclass TwoOperandFPData<bits<4> opcode, string asm,
3858 SDPatternOperator node = null_frag> {
3859 def Srr : BaseTwoOperandFPData<opcode, FPR32, asm,
3860 [(set (f32 FPR32:$Rd),
3861 (node (f32 FPR32:$Rn), (f32 FPR32:$Rm)))]> {
3862 let Inst{22} = 0; // 32-bit size flag
3863 }
3864
3865 def Drr : BaseTwoOperandFPData<opcode, FPR64, asm,
3866 [(set (f64 FPR64:$Rd),
3867 (node (f64 FPR64:$Rn), (f64 FPR64:$Rm)))]> {
3868 let Inst{22} = 1; // 64-bit size flag
3869 }
3870}
3871
3872multiclass TwoOperandFPDataNeg<bits<4> opcode, string asm, SDNode node> {
3873 def Srr : BaseTwoOperandFPData<opcode, FPR32, asm,
3874 [(set FPR32:$Rd, (fneg (node FPR32:$Rn, (f32 FPR32:$Rm))))]> {
3875 let Inst{22} = 0; // 32-bit size flag
3876 }
3877
3878 def Drr : BaseTwoOperandFPData<opcode, FPR64, asm,
3879 [(set FPR64:$Rd, (fneg (node FPR64:$Rn, (f64 FPR64:$Rm))))]> {
3880 let Inst{22} = 1; // 64-bit size flag
3881 }
3882}
3883
3884
3885//---
3886// Three operand floating point data processing
3887//---
3888
3889class BaseThreeOperandFPData<bit isNegated, bit isSub,
3890 RegisterClass regtype, string asm, list<dag> pat>
3891 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, regtype: $Ra),
3892 asm, "\t$Rd, $Rn, $Rm, $Ra", "", pat>,
3893 Sched<[WriteFMul]> {
3894 bits<5> Rd;
3895 bits<5> Rn;
3896 bits<5> Rm;
3897 bits<5> Ra;
3898 let Inst{31-23} = 0b000111110;
3899 let Inst{21} = isNegated;
3900 let Inst{20-16} = Rm;
3901 let Inst{15} = isSub;
3902 let Inst{14-10} = Ra;
3903 let Inst{9-5} = Rn;
3904 let Inst{4-0} = Rd;
3905}
3906
3907multiclass ThreeOperandFPData<bit isNegated, bit isSub,string asm,
3908 SDPatternOperator node> {
3909 def Srrr : BaseThreeOperandFPData<isNegated, isSub, FPR32, asm,
3910 [(set FPR32:$Rd,
3911 (node (f32 FPR32:$Rn), (f32 FPR32:$Rm), (f32 FPR32:$Ra)))]> {
3912 let Inst{22} = 0; // 32-bit size flag
3913 }
3914
3915 def Drrr : BaseThreeOperandFPData<isNegated, isSub, FPR64, asm,
3916 [(set FPR64:$Rd,
3917 (node (f64 FPR64:$Rn), (f64 FPR64:$Rm), (f64 FPR64:$Ra)))]> {
3918 let Inst{22} = 1; // 64-bit size flag
3919 }
3920}
3921
3922//---
3923// Floating point data comparisons
3924//---
3925
3926let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
3927class BaseOneOperandFPComparison<bit signalAllNans,
3928 RegisterClass regtype, string asm,
3929 list<dag> pat>
3930 : I<(outs), (ins regtype:$Rn), asm, "\t$Rn, #0.0", "", pat>,
3931 Sched<[WriteFCmp]> {
3932 bits<5> Rn;
3933 let Inst{31-23} = 0b000111100;
3934 let Inst{21} = 1;
3935
3936 let Inst{15-10} = 0b001000;
3937 let Inst{9-5} = Rn;
3938 let Inst{4} = signalAllNans;
3939 let Inst{3-0} = 0b1000;
3940
3941 // Rm should be 0b00000 canonically, but we need to accept any value.
3942 let PostEncoderMethod = "fixOneOperandFPComparison";
3943}
3944
3945let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
3946class BaseTwoOperandFPComparison<bit signalAllNans, RegisterClass regtype,
3947 string asm, list<dag> pat>
3948 : I<(outs), (ins regtype:$Rn, regtype:$Rm), asm, "\t$Rn, $Rm", "", pat>,
3949 Sched<[WriteFCmp]> {
3950 bits<5> Rm;
3951 bits<5> Rn;
3952 let Inst{31-23} = 0b000111100;
3953 let Inst{21} = 1;
3954 let Inst{20-16} = Rm;
3955 let Inst{15-10} = 0b001000;
3956 let Inst{9-5} = Rn;
3957 let Inst{4} = signalAllNans;
3958 let Inst{3-0} = 0b0000;
3959}
3960
3961multiclass FPComparison<bit signalAllNans, string asm,
3962 SDPatternOperator OpNode = null_frag> {
3963 let Defs = [NZCV] in {
3964 def Srr : BaseTwoOperandFPComparison<signalAllNans, FPR32, asm,
3965 [(OpNode FPR32:$Rn, (f32 FPR32:$Rm)), (implicit NZCV)]> {
3966 let Inst{22} = 0;
3967 }
3968
3969 def Sri : BaseOneOperandFPComparison<signalAllNans, FPR32, asm,
3970 [(OpNode (f32 FPR32:$Rn), fpimm0), (implicit NZCV)]> {
3971 let Inst{22} = 0;
3972 }
3973
3974 def Drr : BaseTwoOperandFPComparison<signalAllNans, FPR64, asm,
3975 [(OpNode FPR64:$Rn, (f64 FPR64:$Rm)), (implicit NZCV)]> {
3976 let Inst{22} = 1;
3977 }
3978
3979 def Dri : BaseOneOperandFPComparison<signalAllNans, FPR64, asm,
3980 [(OpNode (f64 FPR64:$Rn), fpimm0), (implicit NZCV)]> {
3981 let Inst{22} = 1;
3982 }
3983 } // Defs = [NZCV]
3984}
3985
3986//---
3987// Floating point conditional comparisons
3988//---
3989
3990let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
Matthias Braunaf7d7702015-07-16 20:02:37 +00003991class BaseFPCondComparison<bit signalAllNans, RegisterClass regtype,
3992 string mnemonic, list<dag> pat>
3993 : I<(outs), (ins regtype:$Rn, regtype:$Rm, imm32_0_15:$nzcv, ccode:$cond),
3994 mnemonic, "\t$Rn, $Rm, $nzcv, $cond", "", pat>,
Tim Northover3b0846e2014-05-24 12:50:23 +00003995 Sched<[WriteFCmp]> {
Matthias Braunaf7d7702015-07-16 20:02:37 +00003996 let Uses = [NZCV];
3997 let Defs = [NZCV];
3998
Tim Northover3b0846e2014-05-24 12:50:23 +00003999 bits<5> Rn;
4000 bits<5> Rm;
4001 bits<4> nzcv;
4002 bits<4> cond;
4003
4004 let Inst{31-23} = 0b000111100;
4005 let Inst{21} = 1;
4006 let Inst{20-16} = Rm;
4007 let Inst{15-12} = cond;
4008 let Inst{11-10} = 0b01;
4009 let Inst{9-5} = Rn;
4010 let Inst{4} = signalAllNans;
4011 let Inst{3-0} = nzcv;
4012}
4013
Matthias Braunaf7d7702015-07-16 20:02:37 +00004014multiclass FPCondComparison<bit signalAllNans, string mnemonic,
4015 SDPatternOperator OpNode = null_frag> {
4016 def Srr : BaseFPCondComparison<signalAllNans, FPR32, mnemonic,
4017 [(set NZCV, (OpNode (f32 FPR32:$Rn), (f32 FPR32:$Rm), (i32 imm:$nzcv),
4018 (i32 imm:$cond), NZCV))]> {
Tim Northover3b0846e2014-05-24 12:50:23 +00004019 let Inst{22} = 0;
4020 }
Matthias Braunaf7d7702015-07-16 20:02:37 +00004021 def Drr : BaseFPCondComparison<signalAllNans, FPR64, mnemonic,
4022 [(set NZCV, (OpNode (f64 FPR64:$Rn), (f64 FPR64:$Rm), (i32 imm:$nzcv),
4023 (i32 imm:$cond), NZCV))]> {
Tim Northover3b0846e2014-05-24 12:50:23 +00004024 let Inst{22} = 1;
4025 }
Tim Northover3b0846e2014-05-24 12:50:23 +00004026}
4027
4028//---
4029// Floating point conditional select
4030//---
4031
4032class BaseFPCondSelect<RegisterClass regtype, ValueType vt, string asm>
4033 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, ccode:$cond),
4034 asm, "\t$Rd, $Rn, $Rm, $cond", "",
4035 [(set regtype:$Rd,
4036 (AArch64csel (vt regtype:$Rn), regtype:$Rm,
4037 (i32 imm:$cond), NZCV))]>,
4038 Sched<[WriteF]> {
4039 bits<5> Rd;
4040 bits<5> Rn;
4041 bits<5> Rm;
4042 bits<4> cond;
4043
4044 let Inst{31-23} = 0b000111100;
4045 let Inst{21} = 1;
4046 let Inst{20-16} = Rm;
4047 let Inst{15-12} = cond;
4048 let Inst{11-10} = 0b11;
4049 let Inst{9-5} = Rn;
4050 let Inst{4-0} = Rd;
4051}
4052
4053multiclass FPCondSelect<string asm> {
4054 let Uses = [NZCV] in {
4055 def Srrr : BaseFPCondSelect<FPR32, f32, asm> {
4056 let Inst{22} = 0;
4057 }
4058
4059 def Drrr : BaseFPCondSelect<FPR64, f64, asm> {
4060 let Inst{22} = 1;
4061 }
4062 } // Uses = [NZCV]
4063}
4064
4065//---
4066// Floating move immediate
4067//---
4068
4069class BaseFPMoveImmediate<RegisterClass regtype, Operand fpimmtype, string asm>
4070 : I<(outs regtype:$Rd), (ins fpimmtype:$imm), asm, "\t$Rd, $imm", "",
4071 [(set regtype:$Rd, fpimmtype:$imm)]>,
4072 Sched<[WriteFImm]> {
4073 bits<5> Rd;
4074 bits<8> imm;
4075 let Inst{31-23} = 0b000111100;
4076 let Inst{21} = 1;
4077 let Inst{20-13} = imm;
4078 let Inst{12-5} = 0b10000000;
4079 let Inst{4-0} = Rd;
4080}
4081
4082multiclass FPMoveImmediate<string asm> {
4083 def Si : BaseFPMoveImmediate<FPR32, fpimm32, asm> {
4084 let Inst{22} = 0;
4085 }
4086
4087 def Di : BaseFPMoveImmediate<FPR64, fpimm64, asm> {
4088 let Inst{22} = 1;
4089 }
4090}
4091} // end of 'let Predicates = [HasFPARMv8]'
4092
4093//----------------------------------------------------------------------------
4094// AdvSIMD
4095//----------------------------------------------------------------------------
4096
4097let Predicates = [HasNEON] in {
4098
4099//----------------------------------------------------------------------------
4100// AdvSIMD three register vector instructions
4101//----------------------------------------------------------------------------
4102
4103let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
4104class BaseSIMDThreeSameVector<bit Q, bit U, bits<2> size, bits<5> opcode,
4105 RegisterOperand regtype, string asm, string kind,
4106 list<dag> pattern>
4107 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), asm,
4108 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind #
4109 "|" # kind # "\t$Rd, $Rn, $Rm|}", "", pattern>,
4110 Sched<[WriteV]> {
4111 bits<5> Rd;
4112 bits<5> Rn;
4113 bits<5> Rm;
4114 let Inst{31} = 0;
4115 let Inst{30} = Q;
4116 let Inst{29} = U;
4117 let Inst{28-24} = 0b01110;
4118 let Inst{23-22} = size;
4119 let Inst{21} = 1;
4120 let Inst{20-16} = Rm;
4121 let Inst{15-11} = opcode;
4122 let Inst{10} = 1;
4123 let Inst{9-5} = Rn;
4124 let Inst{4-0} = Rd;
4125}
4126
4127let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
4128class BaseSIMDThreeSameVectorTied<bit Q, bit U, bits<2> size, bits<5> opcode,
4129 RegisterOperand regtype, string asm, string kind,
4130 list<dag> pattern>
4131 : I<(outs regtype:$dst), (ins regtype:$Rd, regtype:$Rn, regtype:$Rm), asm,
4132 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind #
4133 "|" # kind # "\t$Rd, $Rn, $Rm}", "$Rd = $dst", pattern>,
4134 Sched<[WriteV]> {
4135 bits<5> Rd;
4136 bits<5> Rn;
4137 bits<5> Rm;
4138 let Inst{31} = 0;
4139 let Inst{30} = Q;
4140 let Inst{29} = U;
4141 let Inst{28-24} = 0b01110;
4142 let Inst{23-22} = size;
4143 let Inst{21} = 1;
4144 let Inst{20-16} = Rm;
4145 let Inst{15-11} = opcode;
4146 let Inst{10} = 1;
4147 let Inst{9-5} = Rn;
4148 let Inst{4-0} = Rd;
4149}
4150
4151// All operand sizes distinguished in the encoding.
4152multiclass SIMDThreeSameVector<bit U, bits<5> opc, string asm,
4153 SDPatternOperator OpNode> {
4154 def v8i8 : BaseSIMDThreeSameVector<0, U, 0b00, opc, V64,
4155 asm, ".8b",
4156 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
4157 def v16i8 : BaseSIMDThreeSameVector<1, U, 0b00, opc, V128,
4158 asm, ".16b",
4159 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn), (v16i8 V128:$Rm)))]>;
4160 def v4i16 : BaseSIMDThreeSameVector<0, U, 0b01, opc, V64,
4161 asm, ".4h",
4162 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>;
4163 def v8i16 : BaseSIMDThreeSameVector<1, U, 0b01, opc, V128,
4164 asm, ".8h",
4165 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>;
4166 def v2i32 : BaseSIMDThreeSameVector<0, U, 0b10, opc, V64,
4167 asm, ".2s",
4168 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>;
4169 def v4i32 : BaseSIMDThreeSameVector<1, U, 0b10, opc, V128,
4170 asm, ".4s",
4171 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>;
4172 def v2i64 : BaseSIMDThreeSameVector<1, U, 0b11, opc, V128,
4173 asm, ".2d",
4174 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn), (v2i64 V128:$Rm)))]>;
4175}
4176
4177// As above, but D sized elements unsupported.
4178multiclass SIMDThreeSameVectorBHS<bit U, bits<5> opc, string asm,
4179 SDPatternOperator OpNode> {
4180 def v8i8 : BaseSIMDThreeSameVector<0, U, 0b00, opc, V64,
4181 asm, ".8b",
4182 [(set V64:$Rd, (v8i8 (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm))))]>;
4183 def v16i8 : BaseSIMDThreeSameVector<1, U, 0b00, opc, V128,
4184 asm, ".16b",
4185 [(set V128:$Rd, (v16i8 (OpNode (v16i8 V128:$Rn), (v16i8 V128:$Rm))))]>;
4186 def v4i16 : BaseSIMDThreeSameVector<0, U, 0b01, opc, V64,
4187 asm, ".4h",
4188 [(set V64:$Rd, (v4i16 (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm))))]>;
4189 def v8i16 : BaseSIMDThreeSameVector<1, U, 0b01, opc, V128,
4190 asm, ".8h",
4191 [(set V128:$Rd, (v8i16 (OpNode (v8i16 V128:$Rn), (v8i16 V128:$Rm))))]>;
4192 def v2i32 : BaseSIMDThreeSameVector<0, U, 0b10, opc, V64,
4193 asm, ".2s",
4194 [(set V64:$Rd, (v2i32 (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm))))]>;
4195 def v4i32 : BaseSIMDThreeSameVector<1, U, 0b10, opc, V128,
4196 asm, ".4s",
4197 [(set V128:$Rd, (v4i32 (OpNode (v4i32 V128:$Rn), (v4i32 V128:$Rm))))]>;
4198}
4199
4200multiclass SIMDThreeSameVectorBHSTied<bit U, bits<5> opc, string asm,
4201 SDPatternOperator OpNode> {
4202 def v8i8 : BaseSIMDThreeSameVectorTied<0, U, 0b00, opc, V64,
4203 asm, ".8b",
4204 [(set (v8i8 V64:$dst),
4205 (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
4206 def v16i8 : BaseSIMDThreeSameVectorTied<1, U, 0b00, opc, V128,
4207 asm, ".16b",
4208 [(set (v16i8 V128:$dst),
4209 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn), (v16i8 V128:$Rm)))]>;
4210 def v4i16 : BaseSIMDThreeSameVectorTied<0, U, 0b01, opc, V64,
4211 asm, ".4h",
4212 [(set (v4i16 V64:$dst),
4213 (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>;
4214 def v8i16 : BaseSIMDThreeSameVectorTied<1, U, 0b01, opc, V128,
4215 asm, ".8h",
4216 [(set (v8i16 V128:$dst),
4217 (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>;
4218 def v2i32 : BaseSIMDThreeSameVectorTied<0, U, 0b10, opc, V64,
4219 asm, ".2s",
4220 [(set (v2i32 V64:$dst),
4221 (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>;
4222 def v4i32 : BaseSIMDThreeSameVectorTied<1, U, 0b10, opc, V128,
4223 asm, ".4s",
4224 [(set (v4i32 V128:$dst),
4225 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>;
4226}
4227
4228// As above, but only B sized elements supported.
4229multiclass SIMDThreeSameVectorB<bit U, bits<5> opc, string asm,
4230 SDPatternOperator OpNode> {
4231 def v8i8 : BaseSIMDThreeSameVector<0, U, 0b00, opc, V64,
4232 asm, ".8b",
4233 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
4234 def v16i8 : BaseSIMDThreeSameVector<1, U, 0b00, opc, V128,
4235 asm, ".16b",
4236 [(set (v16i8 V128:$Rd),
4237 (OpNode (v16i8 V128:$Rn), (v16i8 V128:$Rm)))]>;
4238}
4239
4240// As above, but only S and D sized floating point elements supported.
4241multiclass SIMDThreeSameVectorFP<bit U, bit S, bits<5> opc,
4242 string asm, SDPatternOperator OpNode> {
4243 def v2f32 : BaseSIMDThreeSameVector<0, U, {S,0}, opc, V64,
4244 asm, ".2s",
4245 [(set (v2f32 V64:$Rd), (OpNode (v2f32 V64:$Rn), (v2f32 V64:$Rm)))]>;
4246 def v4f32 : BaseSIMDThreeSameVector<1, U, {S,0}, opc, V128,
4247 asm, ".4s",
4248 [(set (v4f32 V128:$Rd), (OpNode (v4f32 V128:$Rn), (v4f32 V128:$Rm)))]>;
4249 def v2f64 : BaseSIMDThreeSameVector<1, U, {S,1}, opc, V128,
4250 asm, ".2d",
4251 [(set (v2f64 V128:$Rd), (OpNode (v2f64 V128:$Rn), (v2f64 V128:$Rm)))]>;
4252}
4253
4254multiclass SIMDThreeSameVectorFPCmp<bit U, bit S, bits<5> opc,
4255 string asm,
4256 SDPatternOperator OpNode> {
4257 def v2f32 : BaseSIMDThreeSameVector<0, U, {S,0}, opc, V64,
4258 asm, ".2s",
4259 [(set (v2i32 V64:$Rd), (OpNode (v2f32 V64:$Rn), (v2f32 V64:$Rm)))]>;
4260 def v4f32 : BaseSIMDThreeSameVector<1, U, {S,0}, opc, V128,
4261 asm, ".4s",
4262 [(set (v4i32 V128:$Rd), (OpNode (v4f32 V128:$Rn), (v4f32 V128:$Rm)))]>;
4263 def v2f64 : BaseSIMDThreeSameVector<1, U, {S,1}, opc, V128,
4264 asm, ".2d",
4265 [(set (v2i64 V128:$Rd), (OpNode (v2f64 V128:$Rn), (v2f64 V128:$Rm)))]>;
4266}
4267
4268multiclass SIMDThreeSameVectorFPTied<bit U, bit S, bits<5> opc,
4269 string asm, SDPatternOperator OpNode> {
4270 def v2f32 : BaseSIMDThreeSameVectorTied<0, U, {S,0}, opc, V64,
4271 asm, ".2s",
4272 [(set (v2f32 V64:$dst),
4273 (OpNode (v2f32 V64:$Rd), (v2f32 V64:$Rn), (v2f32 V64:$Rm)))]>;
4274 def v4f32 : BaseSIMDThreeSameVectorTied<1, U, {S,0}, opc, V128,
4275 asm, ".4s",
4276 [(set (v4f32 V128:$dst),
4277 (OpNode (v4f32 V128:$Rd), (v4f32 V128:$Rn), (v4f32 V128:$Rm)))]>;
4278 def v2f64 : BaseSIMDThreeSameVectorTied<1, U, {S,1}, opc, V128,
4279 asm, ".2d",
4280 [(set (v2f64 V128:$dst),
4281 (OpNode (v2f64 V128:$Rd), (v2f64 V128:$Rn), (v2f64 V128:$Rm)))]>;
4282}
4283
4284// As above, but D and B sized elements unsupported.
4285multiclass SIMDThreeSameVectorHS<bit U, bits<5> opc, string asm,
4286 SDPatternOperator OpNode> {
4287 def v4i16 : BaseSIMDThreeSameVector<0, U, 0b01, opc, V64,
4288 asm, ".4h",
4289 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>;
4290 def v8i16 : BaseSIMDThreeSameVector<1, U, 0b01, opc, V128,
4291 asm, ".8h",
4292 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>;
4293 def v2i32 : BaseSIMDThreeSameVector<0, U, 0b10, opc, V64,
4294 asm, ".2s",
4295 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>;
4296 def v4i32 : BaseSIMDThreeSameVector<1, U, 0b10, opc, V128,
4297 asm, ".4s",
4298 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>;
4299}
4300
4301// Logical three vector ops share opcode bits, and only use B sized elements.
4302multiclass SIMDLogicalThreeVector<bit U, bits<2> size, string asm,
4303 SDPatternOperator OpNode = null_frag> {
4304 def v8i8 : BaseSIMDThreeSameVector<0, U, size, 0b00011, V64,
4305 asm, ".8b",
4306 [(set (v8i8 V64:$Rd), (OpNode V64:$Rn, V64:$Rm))]>;
4307 def v16i8 : BaseSIMDThreeSameVector<1, U, size, 0b00011, V128,
4308 asm, ".16b",
4309 [(set (v16i8 V128:$Rd), (OpNode V128:$Rn, V128:$Rm))]>;
4310
4311 def : Pat<(v4i16 (OpNode V64:$LHS, V64:$RHS)),
4312 (!cast<Instruction>(NAME#"v8i8") V64:$LHS, V64:$RHS)>;
4313 def : Pat<(v2i32 (OpNode V64:$LHS, V64:$RHS)),
4314 (!cast<Instruction>(NAME#"v8i8") V64:$LHS, V64:$RHS)>;
4315 def : Pat<(v1i64 (OpNode V64:$LHS, V64:$RHS)),
4316 (!cast<Instruction>(NAME#"v8i8") V64:$LHS, V64:$RHS)>;
4317
4318 def : Pat<(v8i16 (OpNode V128:$LHS, V128:$RHS)),
4319 (!cast<Instruction>(NAME#"v16i8") V128:$LHS, V128:$RHS)>;
4320 def : Pat<(v4i32 (OpNode V128:$LHS, V128:$RHS)),
4321 (!cast<Instruction>(NAME#"v16i8") V128:$LHS, V128:$RHS)>;
4322 def : Pat<(v2i64 (OpNode V128:$LHS, V128:$RHS)),
4323 (!cast<Instruction>(NAME#"v16i8") V128:$LHS, V128:$RHS)>;
4324}
4325
4326multiclass SIMDLogicalThreeVectorTied<bit U, bits<2> size,
4327 string asm, SDPatternOperator OpNode> {
4328 def v8i8 : BaseSIMDThreeSameVectorTied<0, U, size, 0b00011, V64,
4329 asm, ".8b",
4330 [(set (v8i8 V64:$dst),
4331 (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
4332 def v16i8 : BaseSIMDThreeSameVectorTied<1, U, size, 0b00011, V128,
4333 asm, ".16b",
4334 [(set (v16i8 V128:$dst),
4335 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn),
4336 (v16i8 V128:$Rm)))]>;
4337
4338 def : Pat<(v4i16 (OpNode (v4i16 V64:$LHS), (v4i16 V64:$MHS),
4339 (v4i16 V64:$RHS))),
4340 (!cast<Instruction>(NAME#"v8i8")
4341 V64:$LHS, V64:$MHS, V64:$RHS)>;
4342 def : Pat<(v2i32 (OpNode (v2i32 V64:$LHS), (v2i32 V64:$MHS),
4343 (v2i32 V64:$RHS))),
4344 (!cast<Instruction>(NAME#"v8i8")
4345 V64:$LHS, V64:$MHS, V64:$RHS)>;
4346 def : Pat<(v1i64 (OpNode (v1i64 V64:$LHS), (v1i64 V64:$MHS),
4347 (v1i64 V64:$RHS))),
4348 (!cast<Instruction>(NAME#"v8i8")
4349 V64:$LHS, V64:$MHS, V64:$RHS)>;
4350
4351 def : Pat<(v8i16 (OpNode (v8i16 V128:$LHS), (v8i16 V128:$MHS),
4352 (v8i16 V128:$RHS))),
4353 (!cast<Instruction>(NAME#"v16i8")
4354 V128:$LHS, V128:$MHS, V128:$RHS)>;
4355 def : Pat<(v4i32 (OpNode (v4i32 V128:$LHS), (v4i32 V128:$MHS),
4356 (v4i32 V128:$RHS))),
4357 (!cast<Instruction>(NAME#"v16i8")
4358 V128:$LHS, V128:$MHS, V128:$RHS)>;
4359 def : Pat<(v2i64 (OpNode (v2i64 V128:$LHS), (v2i64 V128:$MHS),
4360 (v2i64 V128:$RHS))),
4361 (!cast<Instruction>(NAME#"v16i8")
4362 V128:$LHS, V128:$MHS, V128:$RHS)>;
4363}
4364
4365
4366//----------------------------------------------------------------------------
4367// AdvSIMD two register vector instructions.
4368//----------------------------------------------------------------------------
4369
4370let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
4371class BaseSIMDTwoSameVector<bit Q, bit U, bits<2> size, bits<5> opcode,
4372 RegisterOperand regtype, string asm, string dstkind,
4373 string srckind, list<dag> pattern>
4374 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm,
4375 "{\t$Rd" # dstkind # ", $Rn" # srckind #
4376 "|" # dstkind # "\t$Rd, $Rn}", "", pattern>,
4377 Sched<[WriteV]> {
4378 bits<5> Rd;
4379 bits<5> Rn;
4380 let Inst{31} = 0;
4381 let Inst{30} = Q;
4382 let Inst{29} = U;
4383 let Inst{28-24} = 0b01110;
4384 let Inst{23-22} = size;
4385 let Inst{21-17} = 0b10000;
4386 let Inst{16-12} = opcode;
4387 let Inst{11-10} = 0b10;
4388 let Inst{9-5} = Rn;
4389 let Inst{4-0} = Rd;
4390}
4391
4392let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
4393class BaseSIMDTwoSameVectorTied<bit Q, bit U, bits<2> size, bits<5> opcode,
4394 RegisterOperand regtype, string asm, string dstkind,
4395 string srckind, list<dag> pattern>
4396 : I<(outs regtype:$dst), (ins regtype:$Rd, regtype:$Rn), asm,
4397 "{\t$Rd" # dstkind # ", $Rn" # srckind #
4398 "|" # dstkind # "\t$Rd, $Rn}", "$Rd = $dst", pattern>,
4399 Sched<[WriteV]> {
4400 bits<5> Rd;
4401 bits<5> Rn;
4402 let Inst{31} = 0;
4403 let Inst{30} = Q;
4404 let Inst{29} = U;
4405 let Inst{28-24} = 0b01110;
4406 let Inst{23-22} = size;
4407 let Inst{21-17} = 0b10000;
4408 let Inst{16-12} = opcode;
4409 let Inst{11-10} = 0b10;
4410 let Inst{9-5} = Rn;
4411 let Inst{4-0} = Rd;
4412}
4413
4414// Supports B, H, and S element sizes.
4415multiclass SIMDTwoVectorBHS<bit U, bits<5> opc, string asm,
4416 SDPatternOperator OpNode> {
4417 def v8i8 : BaseSIMDTwoSameVector<0, U, 0b00, opc, V64,
4418 asm, ".8b", ".8b",
4419 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>;
4420 def v16i8 : BaseSIMDTwoSameVector<1, U, 0b00, opc, V128,
4421 asm, ".16b", ".16b",
4422 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>;
4423 def v4i16 : BaseSIMDTwoSameVector<0, U, 0b01, opc, V64,
4424 asm, ".4h", ".4h",
4425 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>;
4426 def v8i16 : BaseSIMDTwoSameVector<1, U, 0b01, opc, V128,
4427 asm, ".8h", ".8h",
4428 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>;
4429 def v2i32 : BaseSIMDTwoSameVector<0, U, 0b10, opc, V64,
4430 asm, ".2s", ".2s",
4431 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>;
4432 def v4i32 : BaseSIMDTwoSameVector<1, U, 0b10, opc, V128,
4433 asm, ".4s", ".4s",
4434 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>;
4435}
4436
4437class BaseSIMDVectorLShiftLongBySize<bit Q, bits<2> size,
4438 RegisterOperand regtype, string asm, string dstkind,
4439 string srckind, string amount>
4440 : I<(outs V128:$Rd), (ins regtype:$Rn), asm,
4441 "{\t$Rd" # dstkind # ", $Rn" # srckind # ", #" # amount #
4442 "|" # dstkind # "\t$Rd, $Rn, #" # amount # "}", "", []>,
4443 Sched<[WriteV]> {
4444 bits<5> Rd;
4445 bits<5> Rn;
4446 let Inst{31} = 0;
4447 let Inst{30} = Q;
4448 let Inst{29-24} = 0b101110;
4449 let Inst{23-22} = size;
4450 let Inst{21-10} = 0b100001001110;
4451 let Inst{9-5} = Rn;
4452 let Inst{4-0} = Rd;
4453}
4454
4455multiclass SIMDVectorLShiftLongBySizeBHS {
Craig Topperc50d64b2014-11-26 00:46:26 +00004456 let hasSideEffects = 0 in {
Tim Northover3b0846e2014-05-24 12:50:23 +00004457 def v8i8 : BaseSIMDVectorLShiftLongBySize<0, 0b00, V64,
4458 "shll", ".8h", ".8b", "8">;
4459 def v16i8 : BaseSIMDVectorLShiftLongBySize<1, 0b00, V128,
4460 "shll2", ".8h", ".16b", "8">;
4461 def v4i16 : BaseSIMDVectorLShiftLongBySize<0, 0b01, V64,
4462 "shll", ".4s", ".4h", "16">;
4463 def v8i16 : BaseSIMDVectorLShiftLongBySize<1, 0b01, V128,
4464 "shll2", ".4s", ".8h", "16">;
4465 def v2i32 : BaseSIMDVectorLShiftLongBySize<0, 0b10, V64,
4466 "shll", ".2d", ".2s", "32">;
4467 def v4i32 : BaseSIMDVectorLShiftLongBySize<1, 0b10, V128,
4468 "shll2", ".2d", ".4s", "32">;
4469 }
4470}
4471
4472// Supports all element sizes.
4473multiclass SIMDLongTwoVector<bit U, bits<5> opc, string asm,
4474 SDPatternOperator OpNode> {
4475 def v8i8_v4i16 : BaseSIMDTwoSameVector<0, U, 0b00, opc, V64,
4476 asm, ".4h", ".8b",
4477 [(set (v4i16 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>;
4478 def v16i8_v8i16 : BaseSIMDTwoSameVector<1, U, 0b00, opc, V128,
4479 asm, ".8h", ".16b",
4480 [(set (v8i16 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>;
4481 def v4i16_v2i32 : BaseSIMDTwoSameVector<0, U, 0b01, opc, V64,
4482 asm, ".2s", ".4h",
4483 [(set (v2i32 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>;
4484 def v8i16_v4i32 : BaseSIMDTwoSameVector<1, U, 0b01, opc, V128,
4485 asm, ".4s", ".8h",
4486 [(set (v4i32 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>;
4487 def v2i32_v1i64 : BaseSIMDTwoSameVector<0, U, 0b10, opc, V64,
4488 asm, ".1d", ".2s",
4489 [(set (v1i64 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>;
4490 def v4i32_v2i64 : BaseSIMDTwoSameVector<1, U, 0b10, opc, V128,
4491 asm, ".2d", ".4s",
4492 [(set (v2i64 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>;
4493}
4494
4495multiclass SIMDLongTwoVectorTied<bit U, bits<5> opc, string asm,
4496 SDPatternOperator OpNode> {
4497 def v8i8_v4i16 : BaseSIMDTwoSameVectorTied<0, U, 0b00, opc, V64,
4498 asm, ".4h", ".8b",
4499 [(set (v4i16 V64:$dst), (OpNode (v4i16 V64:$Rd),
4500 (v8i8 V64:$Rn)))]>;
4501 def v16i8_v8i16 : BaseSIMDTwoSameVectorTied<1, U, 0b00, opc, V128,
4502 asm, ".8h", ".16b",
4503 [(set (v8i16 V128:$dst), (OpNode (v8i16 V128:$Rd),
4504 (v16i8 V128:$Rn)))]>;
4505 def v4i16_v2i32 : BaseSIMDTwoSameVectorTied<0, U, 0b01, opc, V64,
4506 asm, ".2s", ".4h",
4507 [(set (v2i32 V64:$dst), (OpNode (v2i32 V64:$Rd),
4508 (v4i16 V64:$Rn)))]>;
4509 def v8i16_v4i32 : BaseSIMDTwoSameVectorTied<1, U, 0b01, opc, V128,
4510 asm, ".4s", ".8h",
4511 [(set (v4i32 V128:$dst), (OpNode (v4i32 V128:$Rd),
4512 (v8i16 V128:$Rn)))]>;
4513 def v2i32_v1i64 : BaseSIMDTwoSameVectorTied<0, U, 0b10, opc, V64,
4514 asm, ".1d", ".2s",
4515 [(set (v1i64 V64:$dst), (OpNode (v1i64 V64:$Rd),
4516 (v2i32 V64:$Rn)))]>;
4517 def v4i32_v2i64 : BaseSIMDTwoSameVectorTied<1, U, 0b10, opc, V128,
4518 asm, ".2d", ".4s",
4519 [(set (v2i64 V128:$dst), (OpNode (v2i64 V128:$Rd),
4520 (v4i32 V128:$Rn)))]>;
4521}
4522
4523// Supports all element sizes, except 1xD.
4524multiclass SIMDTwoVectorBHSDTied<bit U, bits<5> opc, string asm,
4525 SDPatternOperator OpNode> {
4526 def v8i8 : BaseSIMDTwoSameVectorTied<0, U, 0b00, opc, V64,
4527 asm, ".8b", ".8b",
4528 [(set (v8i8 V64:$dst), (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn)))]>;
4529 def v16i8 : BaseSIMDTwoSameVectorTied<1, U, 0b00, opc, V128,
4530 asm, ".16b", ".16b",
4531 [(set (v16i8 V128:$dst), (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn)))]>;
4532 def v4i16 : BaseSIMDTwoSameVectorTied<0, U, 0b01, opc, V64,
4533 asm, ".4h", ".4h",
4534 [(set (v4i16 V64:$dst), (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn)))]>;
4535 def v8i16 : BaseSIMDTwoSameVectorTied<1, U, 0b01, opc, V128,
4536 asm, ".8h", ".8h",
4537 [(set (v8i16 V128:$dst), (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn)))]>;
4538 def v2i32 : BaseSIMDTwoSameVectorTied<0, U, 0b10, opc, V64,
4539 asm, ".2s", ".2s",
4540 [(set (v2i32 V64:$dst), (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn)))]>;
4541 def v4i32 : BaseSIMDTwoSameVectorTied<1, U, 0b10, opc, V128,
4542 asm, ".4s", ".4s",
4543 [(set (v4i32 V128:$dst), (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn)))]>;
4544 def v2i64 : BaseSIMDTwoSameVectorTied<1, U, 0b11, opc, V128,
4545 asm, ".2d", ".2d",
4546 [(set (v2i64 V128:$dst), (OpNode (v2i64 V128:$Rd), (v2i64 V128:$Rn)))]>;
4547}
4548
4549multiclass SIMDTwoVectorBHSD<bit U, bits<5> opc, string asm,
4550 SDPatternOperator OpNode = null_frag> {
4551 def v8i8 : BaseSIMDTwoSameVector<0, U, 0b00, opc, V64,
4552 asm, ".8b", ".8b",
4553 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>;
4554 def v16i8 : BaseSIMDTwoSameVector<1, U, 0b00, opc, V128,
4555 asm, ".16b", ".16b",
4556 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>;
4557 def v4i16 : BaseSIMDTwoSameVector<0, U, 0b01, opc, V64,
4558 asm, ".4h", ".4h",
4559 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>;
4560 def v8i16 : BaseSIMDTwoSameVector<1, U, 0b01, opc, V128,
4561 asm, ".8h", ".8h",
4562 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>;
4563 def v2i32 : BaseSIMDTwoSameVector<0, U, 0b10, opc, V64,
4564 asm, ".2s", ".2s",
4565 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>;
4566 def v4i32 : BaseSIMDTwoSameVector<1, U, 0b10, opc, V128,
4567 asm, ".4s", ".4s",
4568 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>;
4569 def v2i64 : BaseSIMDTwoSameVector<1, U, 0b11, opc, V128,
4570 asm, ".2d", ".2d",
4571 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn)))]>;
4572}
4573
4574
4575// Supports only B element sizes.
4576multiclass SIMDTwoVectorB<bit U, bits<2> size, bits<5> opc, string asm,
4577 SDPatternOperator OpNode> {
4578 def v8i8 : BaseSIMDTwoSameVector<0, U, size, opc, V64,
4579 asm, ".8b", ".8b",
4580 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>;
4581 def v16i8 : BaseSIMDTwoSameVector<1, U, size, opc, V128,
4582 asm, ".16b", ".16b",
4583 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>;
4584
4585}
4586
4587// Supports only B and H element sizes.
4588multiclass SIMDTwoVectorBH<bit U, bits<5> opc, string asm,
4589 SDPatternOperator OpNode> {
4590 def v8i8 : BaseSIMDTwoSameVector<0, U, 0b00, opc, V64,
4591 asm, ".8b", ".8b",
4592 [(set (v8i8 V64:$Rd), (OpNode V64:$Rn))]>;
4593 def v16i8 : BaseSIMDTwoSameVector<1, U, 0b00, opc, V128,
4594 asm, ".16b", ".16b",
4595 [(set (v16i8 V128:$Rd), (OpNode V128:$Rn))]>;
4596 def v4i16 : BaseSIMDTwoSameVector<0, U, 0b01, opc, V64,
4597 asm, ".4h", ".4h",
4598 [(set (v4i16 V64:$Rd), (OpNode V64:$Rn))]>;
4599 def v8i16 : BaseSIMDTwoSameVector<1, U, 0b01, opc, V128,
4600 asm, ".8h", ".8h",
4601 [(set (v8i16 V128:$Rd), (OpNode V128:$Rn))]>;
4602}
4603
4604// Supports only S and D element sizes, uses high bit of the size field
4605// as an extra opcode bit.
4606multiclass SIMDTwoVectorFP<bit U, bit S, bits<5> opc, string asm,
4607 SDPatternOperator OpNode> {
4608 def v2f32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, V64,
4609 asm, ".2s", ".2s",
4610 [(set (v2f32 V64:$Rd), (OpNode (v2f32 V64:$Rn)))]>;
4611 def v4f32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, V128,
4612 asm, ".4s", ".4s",
4613 [(set (v4f32 V128:$Rd), (OpNode (v4f32 V128:$Rn)))]>;
4614 def v2f64 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, V128,
4615 asm, ".2d", ".2d",
4616 [(set (v2f64 V128:$Rd), (OpNode (v2f64 V128:$Rn)))]>;
4617}
4618
4619// Supports only S element size.
4620multiclass SIMDTwoVectorS<bit U, bit S, bits<5> opc, string asm,
4621 SDPatternOperator OpNode> {
4622 def v2i32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, V64,
4623 asm, ".2s", ".2s",
4624 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>;
4625 def v4i32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, V128,
4626 asm, ".4s", ".4s",
4627 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>;
4628}
4629
4630
4631multiclass SIMDTwoVectorFPToInt<bit U, bit S, bits<5> opc, string asm,
4632 SDPatternOperator OpNode> {
4633 def v2f32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, V64,
4634 asm, ".2s", ".2s",
4635 [(set (v2i32 V64:$Rd), (OpNode (v2f32 V64:$Rn)))]>;
4636 def v4f32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, V128,
4637 asm, ".4s", ".4s",
4638 [(set (v4i32 V128:$Rd), (OpNode (v4f32 V128:$Rn)))]>;
4639 def v2f64 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, V128,
4640 asm, ".2d", ".2d",
4641 [(set (v2i64 V128:$Rd), (OpNode (v2f64 V128:$Rn)))]>;
4642}
4643
4644multiclass SIMDTwoVectorIntToFP<bit U, bit S, bits<5> opc, string asm,
4645 SDPatternOperator OpNode> {
4646 def v2f32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, V64,
4647 asm, ".2s", ".2s",
4648 [(set (v2f32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>;
4649 def v4f32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, V128,
4650 asm, ".4s", ".4s",
4651 [(set (v4f32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>;
4652 def v2f64 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, V128,
4653 asm, ".2d", ".2d",
4654 [(set (v2f64 V128:$Rd), (OpNode (v2i64 V128:$Rn)))]>;
4655}
4656
4657
4658class BaseSIMDMixedTwoVector<bit Q, bit U, bits<2> size, bits<5> opcode,
4659 RegisterOperand inreg, RegisterOperand outreg,
4660 string asm, string outkind, string inkind,
4661 list<dag> pattern>
4662 : I<(outs outreg:$Rd), (ins inreg:$Rn), asm,
4663 "{\t$Rd" # outkind # ", $Rn" # inkind #
4664 "|" # outkind # "\t$Rd, $Rn}", "", pattern>,
4665 Sched<[WriteV]> {
4666 bits<5> Rd;
4667 bits<5> Rn;
4668 let Inst{31} = 0;
4669 let Inst{30} = Q;
4670 let Inst{29} = U;
4671 let Inst{28-24} = 0b01110;
4672 let Inst{23-22} = size;
4673 let Inst{21-17} = 0b10000;
4674 let Inst{16-12} = opcode;
4675 let Inst{11-10} = 0b10;
4676 let Inst{9-5} = Rn;
4677 let Inst{4-0} = Rd;
4678}
4679
4680class BaseSIMDMixedTwoVectorTied<bit Q, bit U, bits<2> size, bits<5> opcode,
4681 RegisterOperand inreg, RegisterOperand outreg,
4682 string asm, string outkind, string inkind,
4683 list<dag> pattern>
4684 : I<(outs outreg:$dst), (ins outreg:$Rd, inreg:$Rn), asm,
4685 "{\t$Rd" # outkind # ", $Rn" # inkind #
4686 "|" # outkind # "\t$Rd, $Rn}", "$Rd = $dst", pattern>,
4687 Sched<[WriteV]> {
4688 bits<5> Rd;
4689 bits<5> Rn;
4690 let Inst{31} = 0;
4691 let Inst{30} = Q;
4692 let Inst{29} = U;
4693 let Inst{28-24} = 0b01110;
4694 let Inst{23-22} = size;
4695 let Inst{21-17} = 0b10000;
4696 let Inst{16-12} = opcode;
4697 let Inst{11-10} = 0b10;
4698 let Inst{9-5} = Rn;
4699 let Inst{4-0} = Rd;
4700}
4701
4702multiclass SIMDMixedTwoVector<bit U, bits<5> opc, string asm,
4703 SDPatternOperator OpNode> {
4704 def v8i8 : BaseSIMDMixedTwoVector<0, U, 0b00, opc, V128, V64,
4705 asm, ".8b", ".8h",
4706 [(set (v8i8 V64:$Rd), (OpNode (v8i16 V128:$Rn)))]>;
4707 def v16i8 : BaseSIMDMixedTwoVectorTied<1, U, 0b00, opc, V128, V128,
4708 asm#"2", ".16b", ".8h", []>;
4709 def v4i16 : BaseSIMDMixedTwoVector<0, U, 0b01, opc, V128, V64,
4710 asm, ".4h", ".4s",
4711 [(set (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn)))]>;
4712 def v8i16 : BaseSIMDMixedTwoVectorTied<1, U, 0b01, opc, V128, V128,
4713 asm#"2", ".8h", ".4s", []>;
4714 def v2i32 : BaseSIMDMixedTwoVector<0, U, 0b10, opc, V128, V64,
4715 asm, ".2s", ".2d",
4716 [(set (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn)))]>;
4717 def v4i32 : BaseSIMDMixedTwoVectorTied<1, U, 0b10, opc, V128, V128,
4718 asm#"2", ".4s", ".2d", []>;
4719
4720 def : Pat<(concat_vectors (v8i8 V64:$Rd), (OpNode (v8i16 V128:$Rn))),
4721 (!cast<Instruction>(NAME # "v16i8")
4722 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>;
4723 def : Pat<(concat_vectors (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn))),
4724 (!cast<Instruction>(NAME # "v8i16")
4725 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>;
4726 def : Pat<(concat_vectors (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn))),
4727 (!cast<Instruction>(NAME # "v4i32")
4728 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>;
4729}
4730
4731class BaseSIMDCmpTwoVector<bit Q, bit U, bits<2> size, bits<5> opcode,
4732 RegisterOperand regtype,
4733 string asm, string kind, string zero,
4734 ValueType dty, ValueType sty, SDNode OpNode>
4735 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm,
4736 "{\t$Rd" # kind # ", $Rn" # kind # ", #" # zero #
4737 "|" # kind # "\t$Rd, $Rn, #" # zero # "}", "",
4738 [(set (dty regtype:$Rd), (OpNode (sty regtype:$Rn)))]>,
4739 Sched<[WriteV]> {
4740 bits<5> Rd;
4741 bits<5> Rn;
4742 let Inst{31} = 0;
4743 let Inst{30} = Q;
4744 let Inst{29} = U;
4745 let Inst{28-24} = 0b01110;
4746 let Inst{23-22} = size;
4747 let Inst{21-17} = 0b10000;
4748 let Inst{16-12} = opcode;
4749 let Inst{11-10} = 0b10;
4750 let Inst{9-5} = Rn;
4751 let Inst{4-0} = Rd;
4752}
4753
4754// Comparisons support all element sizes, except 1xD.
4755multiclass SIMDCmpTwoVector<bit U, bits<5> opc, string asm,
4756 SDNode OpNode> {
4757 def v8i8rz : BaseSIMDCmpTwoVector<0, U, 0b00, opc, V64,
4758 asm, ".8b", "0",
4759 v8i8, v8i8, OpNode>;
4760 def v16i8rz : BaseSIMDCmpTwoVector<1, U, 0b00, opc, V128,
4761 asm, ".16b", "0",
4762 v16i8, v16i8, OpNode>;
4763 def v4i16rz : BaseSIMDCmpTwoVector<0, U, 0b01, opc, V64,
4764 asm, ".4h", "0",
4765 v4i16, v4i16, OpNode>;
4766 def v8i16rz : BaseSIMDCmpTwoVector<1, U, 0b01, opc, V128,
4767 asm, ".8h", "0",
4768 v8i16, v8i16, OpNode>;
4769 def v2i32rz : BaseSIMDCmpTwoVector<0, U, 0b10, opc, V64,
4770 asm, ".2s", "0",
4771 v2i32, v2i32, OpNode>;
4772 def v4i32rz : BaseSIMDCmpTwoVector<1, U, 0b10, opc, V128,
4773 asm, ".4s", "0",
4774 v4i32, v4i32, OpNode>;
4775 def v2i64rz : BaseSIMDCmpTwoVector<1, U, 0b11, opc, V128,
4776 asm, ".2d", "0",
4777 v2i64, v2i64, OpNode>;
4778}
4779
4780// FP Comparisons support only S and D element sizes.
4781multiclass SIMDFPCmpTwoVector<bit U, bit S, bits<5> opc,
4782 string asm, SDNode OpNode> {
4783
4784 def v2i32rz : BaseSIMDCmpTwoVector<0, U, {S,0}, opc, V64,
4785 asm, ".2s", "0.0",
4786 v2i32, v2f32, OpNode>;
4787 def v4i32rz : BaseSIMDCmpTwoVector<1, U, {S,0}, opc, V128,
4788 asm, ".4s", "0.0",
4789 v4i32, v4f32, OpNode>;
4790 def v2i64rz : BaseSIMDCmpTwoVector<1, U, {S,1}, opc, V128,
4791 asm, ".2d", "0.0",
4792 v2i64, v2f64, OpNode>;
4793
4794 def : InstAlias<asm # " $Vd.2s, $Vn.2s, #0",
4795 (!cast<Instruction>(NAME # v2i32rz) V64:$Vd, V64:$Vn), 0>;
4796 def : InstAlias<asm # " $Vd.4s, $Vn.4s, #0",
4797 (!cast<Instruction>(NAME # v4i32rz) V128:$Vd, V128:$Vn), 0>;
4798 def : InstAlias<asm # " $Vd.2d, $Vn.2d, #0",
4799 (!cast<Instruction>(NAME # v2i64rz) V128:$Vd, V128:$Vn), 0>;
4800 def : InstAlias<asm # ".2s $Vd, $Vn, #0",
4801 (!cast<Instruction>(NAME # v2i32rz) V64:$Vd, V64:$Vn), 0>;
4802 def : InstAlias<asm # ".4s $Vd, $Vn, #0",
4803 (!cast<Instruction>(NAME # v4i32rz) V128:$Vd, V128:$Vn), 0>;
4804 def : InstAlias<asm # ".2d $Vd, $Vn, #0",
4805 (!cast<Instruction>(NAME # v2i64rz) V128:$Vd, V128:$Vn), 0>;
4806}
4807
4808let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
4809class BaseSIMDFPCvtTwoVector<bit Q, bit U, bits<2> size, bits<5> opcode,
4810 RegisterOperand outtype, RegisterOperand intype,
4811 string asm, string VdTy, string VnTy,
4812 list<dag> pattern>
4813 : I<(outs outtype:$Rd), (ins intype:$Rn), asm,
4814 !strconcat("\t$Rd", VdTy, ", $Rn", VnTy), "", pattern>,
4815 Sched<[WriteV]> {
4816 bits<5> Rd;
4817 bits<5> Rn;
4818 let Inst{31} = 0;
4819 let Inst{30} = Q;
4820 let Inst{29} = U;
4821 let Inst{28-24} = 0b01110;
4822 let Inst{23-22} = size;
4823 let Inst{21-17} = 0b10000;
4824 let Inst{16-12} = opcode;
4825 let Inst{11-10} = 0b10;
4826 let Inst{9-5} = Rn;
4827 let Inst{4-0} = Rd;
4828}
4829
4830class BaseSIMDFPCvtTwoVectorTied<bit Q, bit U, bits<2> size, bits<5> opcode,
4831 RegisterOperand outtype, RegisterOperand intype,
4832 string asm, string VdTy, string VnTy,
4833 list<dag> pattern>
4834 : I<(outs outtype:$dst), (ins outtype:$Rd, intype:$Rn), asm,
4835 !strconcat("\t$Rd", VdTy, ", $Rn", VnTy), "$Rd = $dst", pattern>,
4836 Sched<[WriteV]> {
4837 bits<5> Rd;
4838 bits<5> Rn;
4839 let Inst{31} = 0;
4840 let Inst{30} = Q;
4841 let Inst{29} = U;
4842 let Inst{28-24} = 0b01110;
4843 let Inst{23-22} = size;
4844 let Inst{21-17} = 0b10000;
4845 let Inst{16-12} = opcode;
4846 let Inst{11-10} = 0b10;
4847 let Inst{9-5} = Rn;
4848 let Inst{4-0} = Rd;
4849}
4850
4851multiclass SIMDFPWidenTwoVector<bit U, bit S, bits<5> opc, string asm> {
4852 def v4i16 : BaseSIMDFPCvtTwoVector<0, U, {S,0}, opc, V128, V64,
4853 asm, ".4s", ".4h", []>;
4854 def v8i16 : BaseSIMDFPCvtTwoVector<1, U, {S,0}, opc, V128, V128,
4855 asm#"2", ".4s", ".8h", []>;
4856 def v2i32 : BaseSIMDFPCvtTwoVector<0, U, {S,1}, opc, V128, V64,
4857 asm, ".2d", ".2s", []>;
4858 def v4i32 : BaseSIMDFPCvtTwoVector<1, U, {S,1}, opc, V128, V128,
4859 asm#"2", ".2d", ".4s", []>;
4860}
4861
4862multiclass SIMDFPNarrowTwoVector<bit U, bit S, bits<5> opc, string asm> {
4863 def v4i16 : BaseSIMDFPCvtTwoVector<0, U, {S,0}, opc, V64, V128,
4864 asm, ".4h", ".4s", []>;
4865 def v8i16 : BaseSIMDFPCvtTwoVectorTied<1, U, {S,0}, opc, V128, V128,
4866 asm#"2", ".8h", ".4s", []>;
4867 def v2i32 : BaseSIMDFPCvtTwoVector<0, U, {S,1}, opc, V64, V128,
4868 asm, ".2s", ".2d", []>;
4869 def v4i32 : BaseSIMDFPCvtTwoVectorTied<1, U, {S,1}, opc, V128, V128,
4870 asm#"2", ".4s", ".2d", []>;
4871}
4872
4873multiclass SIMDFPInexactCvtTwoVector<bit U, bit S, bits<5> opc, string asm,
4874 Intrinsic OpNode> {
4875 def v2f32 : BaseSIMDFPCvtTwoVector<0, U, {S,1}, opc, V64, V128,
4876 asm, ".2s", ".2d",
4877 [(set (v2f32 V64:$Rd), (OpNode (v2f64 V128:$Rn)))]>;
4878 def v4f32 : BaseSIMDFPCvtTwoVectorTied<1, U, {S,1}, opc, V128, V128,
4879 asm#"2", ".4s", ".2d", []>;
4880
4881 def : Pat<(concat_vectors (v2f32 V64:$Rd), (OpNode (v2f64 V128:$Rn))),
4882 (!cast<Instruction>(NAME # "v4f32")
4883 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>;
4884}
4885
4886//----------------------------------------------------------------------------
4887// AdvSIMD three register different-size vector instructions.
4888//----------------------------------------------------------------------------
4889
4890let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
4891class BaseSIMDDifferentThreeVector<bit U, bits<3> size, bits<4> opcode,
4892 RegisterOperand outtype, RegisterOperand intype1,
4893 RegisterOperand intype2, string asm,
4894 string outkind, string inkind1, string inkind2,
4895 list<dag> pattern>
4896 : I<(outs outtype:$Rd), (ins intype1:$Rn, intype2:$Rm), asm,
4897 "{\t$Rd" # outkind # ", $Rn" # inkind1 # ", $Rm" # inkind2 #
4898 "|" # outkind # "\t$Rd, $Rn, $Rm}", "", pattern>,
4899 Sched<[WriteV]> {
4900 bits<5> Rd;
4901 bits<5> Rn;
4902 bits<5> Rm;
4903 let Inst{31} = 0;
4904 let Inst{30} = size{0};
4905 let Inst{29} = U;
4906 let Inst{28-24} = 0b01110;
4907 let Inst{23-22} = size{2-1};
4908 let Inst{21} = 1;
4909 let Inst{20-16} = Rm;
4910 let Inst{15-12} = opcode;
4911 let Inst{11-10} = 0b00;
4912 let Inst{9-5} = Rn;
4913 let Inst{4-0} = Rd;
4914}
4915
4916let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
4917class BaseSIMDDifferentThreeVectorTied<bit U, bits<3> size, bits<4> opcode,
4918 RegisterOperand outtype, RegisterOperand intype1,
4919 RegisterOperand intype2, string asm,
4920 string outkind, string inkind1, string inkind2,
4921 list<dag> pattern>
4922 : I<(outs outtype:$dst), (ins outtype:$Rd, intype1:$Rn, intype2:$Rm), asm,
4923 "{\t$Rd" # outkind # ", $Rn" # inkind1 # ", $Rm" # inkind2 #
4924 "|" # outkind # "\t$Rd, $Rn, $Rm}", "$Rd = $dst", pattern>,
4925 Sched<[WriteV]> {
4926 bits<5> Rd;
4927 bits<5> Rn;
4928 bits<5> Rm;
4929 let Inst{31} = 0;
4930 let Inst{30} = size{0};
4931 let Inst{29} = U;
4932 let Inst{28-24} = 0b01110;
4933 let Inst{23-22} = size{2-1};
4934 let Inst{21} = 1;
4935 let Inst{20-16} = Rm;
4936 let Inst{15-12} = opcode;
4937 let Inst{11-10} = 0b00;
4938 let Inst{9-5} = Rn;
4939 let Inst{4-0} = Rd;
4940}
4941
4942// FIXME: TableGen doesn't know how to deal with expanded types that also
4943// change the element count (in this case, placing the results in
4944// the high elements of the result register rather than the low
4945// elements). Until that's fixed, we can't code-gen those.
4946multiclass SIMDNarrowThreeVectorBHS<bit U, bits<4> opc, string asm,
4947 Intrinsic IntOp> {
4948 def v8i16_v8i8 : BaseSIMDDifferentThreeVector<U, 0b000, opc,
4949 V64, V128, V128,
4950 asm, ".8b", ".8h", ".8h",
4951 [(set (v8i8 V64:$Rd), (IntOp (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>;
4952 def v8i16_v16i8 : BaseSIMDDifferentThreeVectorTied<U, 0b001, opc,
4953 V128, V128, V128,
4954 asm#"2", ".16b", ".8h", ".8h",
4955 []>;
4956 def v4i32_v4i16 : BaseSIMDDifferentThreeVector<U, 0b010, opc,
4957 V64, V128, V128,
4958 asm, ".4h", ".4s", ".4s",
4959 [(set (v4i16 V64:$Rd), (IntOp (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>;
4960 def v4i32_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc,
4961 V128, V128, V128,
4962 asm#"2", ".8h", ".4s", ".4s",
4963 []>;
4964 def v2i64_v2i32 : BaseSIMDDifferentThreeVector<U, 0b100, opc,
4965 V64, V128, V128,
4966 asm, ".2s", ".2d", ".2d",
4967 [(set (v2i32 V64:$Rd), (IntOp (v2i64 V128:$Rn), (v2i64 V128:$Rm)))]>;
4968 def v2i64_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc,
4969 V128, V128, V128,
4970 asm#"2", ".4s", ".2d", ".2d",
4971 []>;
4972
4973
4974 // Patterns for the '2' variants involve INSERT_SUBREG, which you can't put in
4975 // a version attached to an instruction.
4976 def : Pat<(concat_vectors (v8i8 V64:$Rd), (IntOp (v8i16 V128:$Rn),
4977 (v8i16 V128:$Rm))),
4978 (!cast<Instruction>(NAME # "v8i16_v16i8")
4979 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub),
4980 V128:$Rn, V128:$Rm)>;
4981 def : Pat<(concat_vectors (v4i16 V64:$Rd), (IntOp (v4i32 V128:$Rn),
4982 (v4i32 V128:$Rm))),
4983 (!cast<Instruction>(NAME # "v4i32_v8i16")
4984 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub),
4985 V128:$Rn, V128:$Rm)>;
4986 def : Pat<(concat_vectors (v2i32 V64:$Rd), (IntOp (v2i64 V128:$Rn),
4987 (v2i64 V128:$Rm))),
4988 (!cast<Instruction>(NAME # "v2i64_v4i32")
4989 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub),
4990 V128:$Rn, V128:$Rm)>;
4991}
4992
4993multiclass SIMDDifferentThreeVectorBD<bit U, bits<4> opc, string asm,
4994 Intrinsic IntOp> {
4995 def v8i8 : BaseSIMDDifferentThreeVector<U, 0b000, opc,
4996 V128, V64, V64,
4997 asm, ".8h", ".8b", ".8b",
4998 [(set (v8i16 V128:$Rd), (IntOp (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
4999 def v16i8 : BaseSIMDDifferentThreeVector<U, 0b001, opc,
5000 V128, V128, V128,
5001 asm#"2", ".8h", ".16b", ".16b", []>;
5002 let Predicates = [HasCrypto] in {
5003 def v1i64 : BaseSIMDDifferentThreeVector<U, 0b110, opc,
5004 V128, V64, V64,
5005 asm, ".1q", ".1d", ".1d", []>;
5006 def v2i64 : BaseSIMDDifferentThreeVector<U, 0b111, opc,
5007 V128, V128, V128,
5008 asm#"2", ".1q", ".2d", ".2d", []>;
5009 }
5010
5011 def : Pat<(v8i16 (IntOp (v8i8 (extract_high_v16i8 V128:$Rn)),
5012 (v8i8 (extract_high_v16i8 V128:$Rm)))),
5013 (!cast<Instruction>(NAME#"v16i8") V128:$Rn, V128:$Rm)>;
5014}
5015
5016multiclass SIMDLongThreeVectorHS<bit U, bits<4> opc, string asm,
5017 SDPatternOperator OpNode> {
5018 def v4i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b010, opc,
5019 V128, V64, V64,
5020 asm, ".4s", ".4h", ".4h",
5021 [(set (v4i32 V128:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>;
5022 def v8i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b011, opc,
5023 V128, V128, V128,
5024 asm#"2", ".4s", ".8h", ".8h",
5025 [(set (v4i32 V128:$Rd), (OpNode (extract_high_v8i16 V128:$Rn),
5026 (extract_high_v8i16 V128:$Rm)))]>;
5027 def v2i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b100, opc,
5028 V128, V64, V64,
5029 asm, ".2d", ".2s", ".2s",
5030 [(set (v2i64 V128:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>;
5031 def v4i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b101, opc,
5032 V128, V128, V128,
5033 asm#"2", ".2d", ".4s", ".4s",
5034 [(set (v2i64 V128:$Rd), (OpNode (extract_high_v4i32 V128:$Rn),
5035 (extract_high_v4i32 V128:$Rm)))]>;
5036}
5037
5038multiclass SIMDLongThreeVectorBHSabdl<bit U, bits<4> opc, string asm,
5039 SDPatternOperator OpNode = null_frag> {
5040 def v8i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b000, opc,
5041 V128, V64, V64,
5042 asm, ".8h", ".8b", ".8b",
5043 [(set (v8i16 V128:$Rd),
5044 (zext (v8i8 (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))))]>;
5045 def v16i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b001, opc,
5046 V128, V128, V128,
5047 asm#"2", ".8h", ".16b", ".16b",
5048 [(set (v8i16 V128:$Rd),
5049 (zext (v8i8 (OpNode (extract_high_v16i8 V128:$Rn),
5050 (extract_high_v16i8 V128:$Rm)))))]>;
5051 def v4i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b010, opc,
5052 V128, V64, V64,
5053 asm, ".4s", ".4h", ".4h",
5054 [(set (v4i32 V128:$Rd),
5055 (zext (v4i16 (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))))]>;
5056 def v8i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b011, opc,
5057 V128, V128, V128,
5058 asm#"2", ".4s", ".8h", ".8h",
5059 [(set (v4i32 V128:$Rd),
5060 (zext (v4i16 (OpNode (extract_high_v8i16 V128:$Rn),
5061 (extract_high_v8i16 V128:$Rm)))))]>;
5062 def v2i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b100, opc,
5063 V128, V64, V64,
5064 asm, ".2d", ".2s", ".2s",
5065 [(set (v2i64 V128:$Rd),
5066 (zext (v2i32 (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))))]>;
5067 def v4i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b101, opc,
5068 V128, V128, V128,
5069 asm#"2", ".2d", ".4s", ".4s",
5070 [(set (v2i64 V128:$Rd),
5071 (zext (v2i32 (OpNode (extract_high_v4i32 V128:$Rn),
5072 (extract_high_v4i32 V128:$Rm)))))]>;
5073}
5074
5075multiclass SIMDLongThreeVectorTiedBHSabal<bit U, bits<4> opc,
5076 string asm,
5077 SDPatternOperator OpNode> {
5078 def v8i8_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b000, opc,
5079 V128, V64, V64,
5080 asm, ".8h", ".8b", ".8b",
5081 [(set (v8i16 V128:$dst),
5082 (add (v8i16 V128:$Rd),
5083 (zext (v8i8 (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm))))))]>;
5084 def v16i8_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b001, opc,
5085 V128, V128, V128,
5086 asm#"2", ".8h", ".16b", ".16b",
5087 [(set (v8i16 V128:$dst),
5088 (add (v8i16 V128:$Rd),
5089 (zext (v8i8 (OpNode (extract_high_v16i8 V128:$Rn),
5090 (extract_high_v16i8 V128:$Rm))))))]>;
5091 def v4i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b010, opc,
5092 V128, V64, V64,
5093 asm, ".4s", ".4h", ".4h",
5094 [(set (v4i32 V128:$dst),
5095 (add (v4i32 V128:$Rd),
5096 (zext (v4i16 (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm))))))]>;
5097 def v8i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc,
5098 V128, V128, V128,
5099 asm#"2", ".4s", ".8h", ".8h",
5100 [(set (v4i32 V128:$dst),
5101 (add (v4i32 V128:$Rd),
5102 (zext (v4i16 (OpNode (extract_high_v8i16 V128:$Rn),
5103 (extract_high_v8i16 V128:$Rm))))))]>;
5104 def v2i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b100, opc,
5105 V128, V64, V64,
5106 asm, ".2d", ".2s", ".2s",
5107 [(set (v2i64 V128:$dst),
5108 (add (v2i64 V128:$Rd),
5109 (zext (v2i32 (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm))))))]>;
5110 def v4i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc,
5111 V128, V128, V128,
5112 asm#"2", ".2d", ".4s", ".4s",
5113 [(set (v2i64 V128:$dst),
5114 (add (v2i64 V128:$Rd),
5115 (zext (v2i32 (OpNode (extract_high_v4i32 V128:$Rn),
5116 (extract_high_v4i32 V128:$Rm))))))]>;
5117}
5118
5119multiclass SIMDLongThreeVectorBHS<bit U, bits<4> opc, string asm,
5120 SDPatternOperator OpNode = null_frag> {
5121 def v8i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b000, opc,
5122 V128, V64, V64,
5123 asm, ".8h", ".8b", ".8b",
5124 [(set (v8i16 V128:$Rd), (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
5125 def v16i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b001, opc,
5126 V128, V128, V128,
5127 asm#"2", ".8h", ".16b", ".16b",
5128 [(set (v8i16 V128:$Rd), (OpNode (extract_high_v16i8 V128:$Rn),
5129 (extract_high_v16i8 V128:$Rm)))]>;
5130 def v4i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b010, opc,
5131 V128, V64, V64,
5132 asm, ".4s", ".4h", ".4h",
5133 [(set (v4i32 V128:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>;
5134 def v8i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b011, opc,
5135 V128, V128, V128,
5136 asm#"2", ".4s", ".8h", ".8h",
5137 [(set (v4i32 V128:$Rd), (OpNode (extract_high_v8i16 V128:$Rn),
5138 (extract_high_v8i16 V128:$Rm)))]>;
5139 def v2i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b100, opc,
5140 V128, V64, V64,
5141 asm, ".2d", ".2s", ".2s",
5142 [(set (v2i64 V128:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>;
5143 def v4i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b101, opc,
5144 V128, V128, V128,
5145 asm#"2", ".2d", ".4s", ".4s",
5146 [(set (v2i64 V128:$Rd), (OpNode (extract_high_v4i32 V128:$Rn),
5147 (extract_high_v4i32 V128:$Rm)))]>;
5148}
5149
5150multiclass SIMDLongThreeVectorTiedBHS<bit U, bits<4> opc,
5151 string asm,
5152 SDPatternOperator OpNode> {
5153 def v8i8_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b000, opc,
5154 V128, V64, V64,
5155 asm, ".8h", ".8b", ".8b",
5156 [(set (v8i16 V128:$dst),
5157 (OpNode (v8i16 V128:$Rd), (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
5158 def v16i8_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b001, opc,
5159 V128, V128, V128,
5160 asm#"2", ".8h", ".16b", ".16b",
5161 [(set (v8i16 V128:$dst),
5162 (OpNode (v8i16 V128:$Rd),
5163 (extract_high_v16i8 V128:$Rn),
5164 (extract_high_v16i8 V128:$Rm)))]>;
5165 def v4i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b010, opc,
5166 V128, V64, V64,
5167 asm, ".4s", ".4h", ".4h",
5168 [(set (v4i32 V128:$dst),
5169 (OpNode (v4i32 V128:$Rd), (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>;
5170 def v8i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc,
5171 V128, V128, V128,
5172 asm#"2", ".4s", ".8h", ".8h",
5173 [(set (v4i32 V128:$dst),
5174 (OpNode (v4i32 V128:$Rd),
5175 (extract_high_v8i16 V128:$Rn),
5176 (extract_high_v8i16 V128:$Rm)))]>;
5177 def v2i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b100, opc,
5178 V128, V64, V64,
5179 asm, ".2d", ".2s", ".2s",
5180 [(set (v2i64 V128:$dst),
5181 (OpNode (v2i64 V128:$Rd), (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>;
5182 def v4i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc,
5183 V128, V128, V128,
5184 asm#"2", ".2d", ".4s", ".4s",
5185 [(set (v2i64 V128:$dst),
5186 (OpNode (v2i64 V128:$Rd),
5187 (extract_high_v4i32 V128:$Rn),
5188 (extract_high_v4i32 V128:$Rm)))]>;
5189}
5190
5191multiclass SIMDLongThreeVectorSQDMLXTiedHS<bit U, bits<4> opc, string asm,
5192 SDPatternOperator Accum> {
5193 def v4i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b010, opc,
5194 V128, V64, V64,
5195 asm, ".4s", ".4h", ".4h",
5196 [(set (v4i32 V128:$dst),
5197 (Accum (v4i32 V128:$Rd),
5198 (v4i32 (int_aarch64_neon_sqdmull (v4i16 V64:$Rn),
5199 (v4i16 V64:$Rm)))))]>;
5200 def v8i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc,
5201 V128, V128, V128,
5202 asm#"2", ".4s", ".8h", ".8h",
5203 [(set (v4i32 V128:$dst),
5204 (Accum (v4i32 V128:$Rd),
5205 (v4i32 (int_aarch64_neon_sqdmull (extract_high_v8i16 V128:$Rn),
5206 (extract_high_v8i16 V128:$Rm)))))]>;
5207 def v2i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b100, opc,
5208 V128, V64, V64,
5209 asm, ".2d", ".2s", ".2s",
5210 [(set (v2i64 V128:$dst),
5211 (Accum (v2i64 V128:$Rd),
5212 (v2i64 (int_aarch64_neon_sqdmull (v2i32 V64:$Rn),
5213 (v2i32 V64:$Rm)))))]>;
5214 def v4i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc,
5215 V128, V128, V128,
5216 asm#"2", ".2d", ".4s", ".4s",
5217 [(set (v2i64 V128:$dst),
5218 (Accum (v2i64 V128:$Rd),
5219 (v2i64 (int_aarch64_neon_sqdmull (extract_high_v4i32 V128:$Rn),
5220 (extract_high_v4i32 V128:$Rm)))))]>;
5221}
5222
5223multiclass SIMDWideThreeVectorBHS<bit U, bits<4> opc, string asm,
5224 SDPatternOperator OpNode> {
5225 def v8i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b000, opc,
5226 V128, V128, V64,
5227 asm, ".8h", ".8h", ".8b",
5228 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (v8i8 V64:$Rm)))]>;
5229 def v16i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b001, opc,
5230 V128, V128, V128,
5231 asm#"2", ".8h", ".8h", ".16b",
5232 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn),
5233 (extract_high_v16i8 V128:$Rm)))]>;
5234 def v4i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b010, opc,
5235 V128, V128, V64,
5236 asm, ".4s", ".4s", ".4h",
5237 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (v4i16 V64:$Rm)))]>;
5238 def v8i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b011, opc,
5239 V128, V128, V128,
5240 asm#"2", ".4s", ".4s", ".8h",
5241 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn),
5242 (extract_high_v8i16 V128:$Rm)))]>;
5243 def v2i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b100, opc,
5244 V128, V128, V64,
5245 asm, ".2d", ".2d", ".2s",
5246 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn), (v2i32 V64:$Rm)))]>;
5247 def v4i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b101, opc,
5248 V128, V128, V128,
5249 asm#"2", ".2d", ".2d", ".4s",
5250 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn),
5251 (extract_high_v4i32 V128:$Rm)))]>;
5252}
5253
5254//----------------------------------------------------------------------------
5255// AdvSIMD bitwise extract from vector
5256//----------------------------------------------------------------------------
5257
5258class BaseSIMDBitwiseExtract<bit size, RegisterOperand regtype, ValueType vty,
5259 string asm, string kind>
5260 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, i32imm:$imm), asm,
5261 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind # ", $imm" #
5262 "|" # kind # "\t$Rd, $Rn, $Rm, $imm}", "",
5263 [(set (vty regtype:$Rd),
5264 (AArch64ext regtype:$Rn, regtype:$Rm, (i32 imm:$imm)))]>,
5265 Sched<[WriteV]> {
5266 bits<5> Rd;
5267 bits<5> Rn;
5268 bits<5> Rm;
5269 bits<4> imm;
5270 let Inst{31} = 0;
5271 let Inst{30} = size;
5272 let Inst{29-21} = 0b101110000;
5273 let Inst{20-16} = Rm;
5274 let Inst{15} = 0;
5275 let Inst{14-11} = imm;
5276 let Inst{10} = 0;
5277 let Inst{9-5} = Rn;
5278 let Inst{4-0} = Rd;
5279}
5280
5281
5282multiclass SIMDBitwiseExtract<string asm> {
5283 def v8i8 : BaseSIMDBitwiseExtract<0, V64, v8i8, asm, ".8b"> {
5284 let imm{3} = 0;
5285 }
5286 def v16i8 : BaseSIMDBitwiseExtract<1, V128, v16i8, asm, ".16b">;
5287}
5288
5289//----------------------------------------------------------------------------
5290// AdvSIMD zip vector
5291//----------------------------------------------------------------------------
5292
5293class BaseSIMDZipVector<bits<3> size, bits<3> opc, RegisterOperand regtype,
5294 string asm, string kind, SDNode OpNode, ValueType valty>
5295 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), asm,
5296 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind #
5297 "|" # kind # "\t$Rd, $Rn, $Rm}", "",
5298 [(set (valty regtype:$Rd), (OpNode regtype:$Rn, regtype:$Rm))]>,
5299 Sched<[WriteV]> {
5300 bits<5> Rd;
5301 bits<5> Rn;
5302 bits<5> Rm;
5303 let Inst{31} = 0;
5304 let Inst{30} = size{0};
5305 let Inst{29-24} = 0b001110;
5306 let Inst{23-22} = size{2-1};
5307 let Inst{21} = 0;
5308 let Inst{20-16} = Rm;
5309 let Inst{15} = 0;
5310 let Inst{14-12} = opc;
5311 let Inst{11-10} = 0b10;
5312 let Inst{9-5} = Rn;
5313 let Inst{4-0} = Rd;
5314}
5315
5316multiclass SIMDZipVector<bits<3>opc, string asm,
5317 SDNode OpNode> {
5318 def v8i8 : BaseSIMDZipVector<0b000, opc, V64,
5319 asm, ".8b", OpNode, v8i8>;
5320 def v16i8 : BaseSIMDZipVector<0b001, opc, V128,
5321 asm, ".16b", OpNode, v16i8>;
5322 def v4i16 : BaseSIMDZipVector<0b010, opc, V64,
5323 asm, ".4h", OpNode, v4i16>;
5324 def v8i16 : BaseSIMDZipVector<0b011, opc, V128,
5325 asm, ".8h", OpNode, v8i16>;
5326 def v2i32 : BaseSIMDZipVector<0b100, opc, V64,
5327 asm, ".2s", OpNode, v2i32>;
5328 def v4i32 : BaseSIMDZipVector<0b101, opc, V128,
5329 asm, ".4s", OpNode, v4i32>;
5330 def v2i64 : BaseSIMDZipVector<0b111, opc, V128,
5331 asm, ".2d", OpNode, v2i64>;
5332
Oliver Stannard89d15422014-08-27 16:16:04 +00005333 def : Pat<(v4f16 (OpNode V64:$Rn, V64:$Rm)),
5334 (!cast<Instruction>(NAME#"v4i16") V64:$Rn, V64:$Rm)>;
5335 def : Pat<(v8f16 (OpNode V128:$Rn, V128:$Rm)),
5336 (!cast<Instruction>(NAME#"v8i16") V128:$Rn, V128:$Rm)>;
Tim Northover3b0846e2014-05-24 12:50:23 +00005337 def : Pat<(v2f32 (OpNode V64:$Rn, V64:$Rm)),
5338 (!cast<Instruction>(NAME#"v2i32") V64:$Rn, V64:$Rm)>;
5339 def : Pat<(v4f32 (OpNode V128:$Rn, V128:$Rm)),
5340 (!cast<Instruction>(NAME#"v4i32") V128:$Rn, V128:$Rm)>;
5341 def : Pat<(v2f64 (OpNode V128:$Rn, V128:$Rm)),
5342 (!cast<Instruction>(NAME#"v2i64") V128:$Rn, V128:$Rm)>;
5343}
5344
5345//----------------------------------------------------------------------------
5346// AdvSIMD three register scalar instructions
5347//----------------------------------------------------------------------------
5348
5349let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
5350class BaseSIMDThreeScalar<bit U, bits<2> size, bits<5> opcode,
5351 RegisterClass regtype, string asm,
5352 list<dag> pattern>
5353 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), asm,
5354 "\t$Rd, $Rn, $Rm", "", pattern>,
5355 Sched<[WriteV]> {
5356 bits<5> Rd;
5357 bits<5> Rn;
5358 bits<5> Rm;
5359 let Inst{31-30} = 0b01;
5360 let Inst{29} = U;
5361 let Inst{28-24} = 0b11110;
5362 let Inst{23-22} = size;
5363 let Inst{21} = 1;
5364 let Inst{20-16} = Rm;
5365 let Inst{15-11} = opcode;
5366 let Inst{10} = 1;
5367 let Inst{9-5} = Rn;
5368 let Inst{4-0} = Rd;
5369}
5370
Vladimir Sukharev297bf0e2015-03-31 13:15:48 +00005371let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
5372class BaseSIMDThreeScalarTied<bit U, bits<2> size, bit R, bits<5> opcode,
5373 dag oops, dag iops, string asm,
5374 list<dag> pattern>
5375 : I<oops, iops, asm, "\t$Rd, $Rn, $Rm", "$Rd = $dst", pattern>,
5376 Sched<[WriteV]> {
5377 bits<5> Rd;
5378 bits<5> Rn;
5379 bits<5> Rm;
5380 let Inst{31-30} = 0b01;
5381 let Inst{29} = U;
5382 let Inst{28-24} = 0b11110;
5383 let Inst{23-22} = size;
5384 let Inst{21} = R;
5385 let Inst{20-16} = Rm;
5386 let Inst{15-11} = opcode;
5387 let Inst{10} = 1;
5388 let Inst{9-5} = Rn;
5389 let Inst{4-0} = Rd;
5390}
5391
Tim Northover3b0846e2014-05-24 12:50:23 +00005392multiclass SIMDThreeScalarD<bit U, bits<5> opc, string asm,
5393 SDPatternOperator OpNode> {
5394 def v1i64 : BaseSIMDThreeScalar<U, 0b11, opc, FPR64, asm,
5395 [(set (v1i64 FPR64:$Rd), (OpNode (v1i64 FPR64:$Rn), (v1i64 FPR64:$Rm)))]>;
5396}
5397
5398multiclass SIMDThreeScalarBHSD<bit U, bits<5> opc, string asm,
5399 SDPatternOperator OpNode> {
5400 def v1i64 : BaseSIMDThreeScalar<U, 0b11, opc, FPR64, asm,
5401 [(set (v1i64 FPR64:$Rd), (OpNode (v1i64 FPR64:$Rn), (v1i64 FPR64:$Rm)))]>;
5402 def v1i32 : BaseSIMDThreeScalar<U, 0b10, opc, FPR32, asm, []>;
5403 def v1i16 : BaseSIMDThreeScalar<U, 0b01, opc, FPR16, asm, []>;
5404 def v1i8 : BaseSIMDThreeScalar<U, 0b00, opc, FPR8 , asm, []>;
5405
5406 def : Pat<(i64 (OpNode (i64 FPR64:$Rn), (i64 FPR64:$Rm))),
5407 (!cast<Instruction>(NAME#"v1i64") FPR64:$Rn, FPR64:$Rm)>;
5408 def : Pat<(i32 (OpNode (i32 FPR32:$Rn), (i32 FPR32:$Rm))),
5409 (!cast<Instruction>(NAME#"v1i32") FPR32:$Rn, FPR32:$Rm)>;
5410}
5411
5412multiclass SIMDThreeScalarHS<bit U, bits<5> opc, string asm,
5413 SDPatternOperator OpNode> {
5414 def v1i32 : BaseSIMDThreeScalar<U, 0b10, opc, FPR32, asm,
5415 [(set FPR32:$Rd, (OpNode FPR32:$Rn, FPR32:$Rm))]>;
5416 def v1i16 : BaseSIMDThreeScalar<U, 0b01, opc, FPR16, asm, []>;
5417}
5418
Vladimir Sukharev297bf0e2015-03-31 13:15:48 +00005419multiclass SIMDThreeScalarHSTied<bit U, bit R, bits<5> opc, string asm,
5420 SDPatternOperator OpNode = null_frag> {
5421 def v1i32: BaseSIMDThreeScalarTied<U, 0b10, R, opc, (outs FPR32:$dst),
5422 (ins FPR32:$Rd, FPR32:$Rn, FPR32:$Rm),
5423 asm, []>;
5424 def v1i16: BaseSIMDThreeScalarTied<U, 0b01, R, opc, (outs FPR16:$dst),
5425 (ins FPR16:$Rd, FPR16:$Rn, FPR16:$Rm),
5426 asm, []>;
5427}
5428
Tim Northover3b0846e2014-05-24 12:50:23 +00005429multiclass SIMDThreeScalarSD<bit U, bit S, bits<5> opc, string asm,
5430 SDPatternOperator OpNode = null_frag> {
5431 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
5432 def #NAME#64 : BaseSIMDThreeScalar<U, {S,1}, opc, FPR64, asm,
5433 [(set (f64 FPR64:$Rd), (OpNode (f64 FPR64:$Rn), (f64 FPR64:$Rm)))]>;
5434 def #NAME#32 : BaseSIMDThreeScalar<U, {S,0}, opc, FPR32, asm,
5435 [(set FPR32:$Rd, (OpNode FPR32:$Rn, FPR32:$Rm))]>;
5436 }
5437
5438 def : Pat<(v1f64 (OpNode (v1f64 FPR64:$Rn), (v1f64 FPR64:$Rm))),
5439 (!cast<Instruction>(NAME # "64") FPR64:$Rn, FPR64:$Rm)>;
5440}
5441
5442multiclass SIMDThreeScalarFPCmp<bit U, bit S, bits<5> opc, string asm,
5443 SDPatternOperator OpNode = null_frag> {
5444 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
5445 def #NAME#64 : BaseSIMDThreeScalar<U, {S,1}, opc, FPR64, asm,
5446 [(set (i64 FPR64:$Rd), (OpNode (f64 FPR64:$Rn), (f64 FPR64:$Rm)))]>;
5447 def #NAME#32 : BaseSIMDThreeScalar<U, {S,0}, opc, FPR32, asm,
5448 [(set (i32 FPR32:$Rd), (OpNode (f32 FPR32:$Rn), (f32 FPR32:$Rm)))]>;
5449 }
5450
5451 def : Pat<(v1i64 (OpNode (v1f64 FPR64:$Rn), (v1f64 FPR64:$Rm))),
5452 (!cast<Instruction>(NAME # "64") FPR64:$Rn, FPR64:$Rm)>;
5453}
5454
5455class BaseSIMDThreeScalarMixed<bit U, bits<2> size, bits<5> opcode,
5456 dag oops, dag iops, string asm, string cstr, list<dag> pat>
5457 : I<oops, iops, asm,
5458 "\t$Rd, $Rn, $Rm", cstr, pat>,
5459 Sched<[WriteV]> {
5460 bits<5> Rd;
5461 bits<5> Rn;
5462 bits<5> Rm;
5463 let Inst{31-30} = 0b01;
5464 let Inst{29} = U;
5465 let Inst{28-24} = 0b11110;
5466 let Inst{23-22} = size;
5467 let Inst{21} = 1;
5468 let Inst{20-16} = Rm;
5469 let Inst{15-11} = opcode;
5470 let Inst{10} = 0;
5471 let Inst{9-5} = Rn;
5472 let Inst{4-0} = Rd;
5473}
5474
5475let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5476multiclass SIMDThreeScalarMixedHS<bit U, bits<5> opc, string asm,
5477 SDPatternOperator OpNode = null_frag> {
5478 def i16 : BaseSIMDThreeScalarMixed<U, 0b01, opc,
5479 (outs FPR32:$Rd),
5480 (ins FPR16:$Rn, FPR16:$Rm), asm, "", []>;
5481 def i32 : BaseSIMDThreeScalarMixed<U, 0b10, opc,
5482 (outs FPR64:$Rd),
5483 (ins FPR32:$Rn, FPR32:$Rm), asm, "",
5484 [(set (i64 FPR64:$Rd), (OpNode (i32 FPR32:$Rn), (i32 FPR32:$Rm)))]>;
5485}
5486
5487let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5488multiclass SIMDThreeScalarMixedTiedHS<bit U, bits<5> opc, string asm,
5489 SDPatternOperator OpNode = null_frag> {
5490 def i16 : BaseSIMDThreeScalarMixed<U, 0b01, opc,
5491 (outs FPR32:$dst),
5492 (ins FPR32:$Rd, FPR16:$Rn, FPR16:$Rm),
5493 asm, "$Rd = $dst", []>;
5494 def i32 : BaseSIMDThreeScalarMixed<U, 0b10, opc,
5495 (outs FPR64:$dst),
5496 (ins FPR64:$Rd, FPR32:$Rn, FPR32:$Rm),
5497 asm, "$Rd = $dst",
5498 [(set (i64 FPR64:$dst),
5499 (OpNode (i64 FPR64:$Rd), (i32 FPR32:$Rn), (i32 FPR32:$Rm)))]>;
5500}
5501
5502//----------------------------------------------------------------------------
5503// AdvSIMD two register scalar instructions
5504//----------------------------------------------------------------------------
5505
5506let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5507class BaseSIMDTwoScalar<bit U, bits<2> size, bits<5> opcode,
5508 RegisterClass regtype, RegisterClass regtype2,
5509 string asm, list<dag> pat>
5510 : I<(outs regtype:$Rd), (ins regtype2:$Rn), asm,
5511 "\t$Rd, $Rn", "", pat>,
5512 Sched<[WriteV]> {
5513 bits<5> Rd;
5514 bits<5> Rn;
5515 let Inst{31-30} = 0b01;
5516 let Inst{29} = U;
5517 let Inst{28-24} = 0b11110;
5518 let Inst{23-22} = size;
5519 let Inst{21-17} = 0b10000;
5520 let Inst{16-12} = opcode;
5521 let Inst{11-10} = 0b10;
5522 let Inst{9-5} = Rn;
5523 let Inst{4-0} = Rd;
5524}
5525
5526let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5527class BaseSIMDTwoScalarTied<bit U, bits<2> size, bits<5> opcode,
5528 RegisterClass regtype, RegisterClass regtype2,
5529 string asm, list<dag> pat>
5530 : I<(outs regtype:$dst), (ins regtype:$Rd, regtype2:$Rn), asm,
5531 "\t$Rd, $Rn", "$Rd = $dst", pat>,
5532 Sched<[WriteV]> {
5533 bits<5> Rd;
5534 bits<5> Rn;
5535 let Inst{31-30} = 0b01;
5536 let Inst{29} = U;
5537 let Inst{28-24} = 0b11110;
5538 let Inst{23-22} = size;
5539 let Inst{21-17} = 0b10000;
5540 let Inst{16-12} = opcode;
5541 let Inst{11-10} = 0b10;
5542 let Inst{9-5} = Rn;
5543 let Inst{4-0} = Rd;
5544}
5545
5546
5547let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5548class BaseSIMDCmpTwoScalar<bit U, bits<2> size, bits<5> opcode,
5549 RegisterClass regtype, string asm, string zero>
5550 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm,
5551 "\t$Rd, $Rn, #" # zero, "", []>,
5552 Sched<[WriteV]> {
5553 bits<5> Rd;
5554 bits<5> Rn;
5555 let Inst{31-30} = 0b01;
5556 let Inst{29} = U;
5557 let Inst{28-24} = 0b11110;
5558 let Inst{23-22} = size;
5559 let Inst{21-17} = 0b10000;
5560 let Inst{16-12} = opcode;
5561 let Inst{11-10} = 0b10;
5562 let Inst{9-5} = Rn;
5563 let Inst{4-0} = Rd;
5564}
5565
5566class SIMDInexactCvtTwoScalar<bits<5> opcode, string asm>
5567 : I<(outs FPR32:$Rd), (ins FPR64:$Rn), asm, "\t$Rd, $Rn", "",
5568 [(set (f32 FPR32:$Rd), (int_aarch64_sisd_fcvtxn (f64 FPR64:$Rn)))]>,
5569 Sched<[WriteV]> {
5570 bits<5> Rd;
5571 bits<5> Rn;
5572 let Inst{31-17} = 0b011111100110000;
5573 let Inst{16-12} = opcode;
5574 let Inst{11-10} = 0b10;
5575 let Inst{9-5} = Rn;
5576 let Inst{4-0} = Rd;
5577}
5578
5579multiclass SIMDCmpTwoScalarD<bit U, bits<5> opc, string asm,
5580 SDPatternOperator OpNode> {
5581 def v1i64rz : BaseSIMDCmpTwoScalar<U, 0b11, opc, FPR64, asm, "0">;
5582
5583 def : Pat<(v1i64 (OpNode FPR64:$Rn)),
5584 (!cast<Instruction>(NAME # v1i64rz) FPR64:$Rn)>;
5585}
5586
5587multiclass SIMDCmpTwoScalarSD<bit U, bit S, bits<5> opc, string asm,
5588 SDPatternOperator OpNode> {
5589 def v1i64rz : BaseSIMDCmpTwoScalar<U, {S,1}, opc, FPR64, asm, "0.0">;
5590 def v1i32rz : BaseSIMDCmpTwoScalar<U, {S,0}, opc, FPR32, asm, "0.0">;
5591
5592 def : InstAlias<asm # " $Rd, $Rn, #0",
5593 (!cast<Instruction>(NAME # v1i64rz) FPR64:$Rd, FPR64:$Rn), 0>;
5594 def : InstAlias<asm # " $Rd, $Rn, #0",
5595 (!cast<Instruction>(NAME # v1i32rz) FPR32:$Rd, FPR32:$Rn), 0>;
5596
5597 def : Pat<(v1i64 (OpNode (v1f64 FPR64:$Rn))),
5598 (!cast<Instruction>(NAME # v1i64rz) FPR64:$Rn)>;
5599}
5600
5601multiclass SIMDTwoScalarD<bit U, bits<5> opc, string asm,
5602 SDPatternOperator OpNode = null_frag> {
5603 def v1i64 : BaseSIMDTwoScalar<U, 0b11, opc, FPR64, FPR64, asm,
5604 [(set (v1i64 FPR64:$Rd), (OpNode (v1i64 FPR64:$Rn)))]>;
5605
5606 def : Pat<(i64 (OpNode (i64 FPR64:$Rn))),
5607 (!cast<Instruction>(NAME # "v1i64") FPR64:$Rn)>;
5608}
5609
5610multiclass SIMDTwoScalarSD<bit U, bit S, bits<5> opc, string asm> {
5611 def v1i64 : BaseSIMDTwoScalar<U, {S,1}, opc, FPR64, FPR64, asm,[]>;
5612 def v1i32 : BaseSIMDTwoScalar<U, {S,0}, opc, FPR32, FPR32, asm,[]>;
5613}
5614
5615multiclass SIMDTwoScalarCVTSD<bit U, bit S, bits<5> opc, string asm,
5616 SDPatternOperator OpNode> {
5617 def v1i64 : BaseSIMDTwoScalar<U, {S,1}, opc, FPR64, FPR64, asm,
5618 [(set FPR64:$Rd, (OpNode (f64 FPR64:$Rn)))]>;
5619 def v1i32 : BaseSIMDTwoScalar<U, {S,0}, opc, FPR32, FPR32, asm,
5620 [(set FPR32:$Rd, (OpNode (f32 FPR32:$Rn)))]>;
5621}
5622
5623multiclass SIMDTwoScalarBHSD<bit U, bits<5> opc, string asm,
5624 SDPatternOperator OpNode = null_frag> {
5625 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
5626 def v1i64 : BaseSIMDTwoScalar<U, 0b11, opc, FPR64, FPR64, asm,
5627 [(set (i64 FPR64:$Rd), (OpNode (i64 FPR64:$Rn)))]>;
5628 def v1i32 : BaseSIMDTwoScalar<U, 0b10, opc, FPR32, FPR32, asm,
5629 [(set (i32 FPR32:$Rd), (OpNode (i32 FPR32:$Rn)))]>;
5630 def v1i16 : BaseSIMDTwoScalar<U, 0b01, opc, FPR16, FPR16, asm, []>;
5631 def v1i8 : BaseSIMDTwoScalar<U, 0b00, opc, FPR8 , FPR8 , asm, []>;
5632 }
5633
5634 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rn))),
5635 (!cast<Instruction>(NAME # v1i64) FPR64:$Rn)>;
5636}
5637
5638multiclass SIMDTwoScalarBHSDTied<bit U, bits<5> opc, string asm,
5639 Intrinsic OpNode> {
5640 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
5641 def v1i64 : BaseSIMDTwoScalarTied<U, 0b11, opc, FPR64, FPR64, asm,
5642 [(set (i64 FPR64:$dst), (OpNode (i64 FPR64:$Rd), (i64 FPR64:$Rn)))]>;
5643 def v1i32 : BaseSIMDTwoScalarTied<U, 0b10, opc, FPR32, FPR32, asm,
5644 [(set (i32 FPR32:$dst), (OpNode (i32 FPR32:$Rd), (i32 FPR32:$Rn)))]>;
5645 def v1i16 : BaseSIMDTwoScalarTied<U, 0b01, opc, FPR16, FPR16, asm, []>;
5646 def v1i8 : BaseSIMDTwoScalarTied<U, 0b00, opc, FPR8 , FPR8 , asm, []>;
5647 }
5648
5649 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rd), (v1i64 FPR64:$Rn))),
5650 (!cast<Instruction>(NAME # v1i64) FPR64:$Rd, FPR64:$Rn)>;
5651}
5652
5653
5654
5655let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5656multiclass SIMDTwoScalarMixedBHS<bit U, bits<5> opc, string asm,
5657 SDPatternOperator OpNode = null_frag> {
5658 def v1i32 : BaseSIMDTwoScalar<U, 0b10, opc, FPR32, FPR64, asm,
5659 [(set (i32 FPR32:$Rd), (OpNode (i64 FPR64:$Rn)))]>;
5660 def v1i16 : BaseSIMDTwoScalar<U, 0b01, opc, FPR16, FPR32, asm, []>;
5661 def v1i8 : BaseSIMDTwoScalar<U, 0b00, opc, FPR8 , FPR16, asm, []>;
5662}
5663
5664//----------------------------------------------------------------------------
5665// AdvSIMD scalar pairwise instructions
5666//----------------------------------------------------------------------------
5667
5668let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5669class BaseSIMDPairwiseScalar<bit U, bits<2> size, bits<5> opcode,
5670 RegisterOperand regtype, RegisterOperand vectype,
5671 string asm, string kind>
5672 : I<(outs regtype:$Rd), (ins vectype:$Rn), asm,
5673 "{\t$Rd, $Rn" # kind # "|" # kind # "\t$Rd, $Rn}", "", []>,
5674 Sched<[WriteV]> {
5675 bits<5> Rd;
5676 bits<5> Rn;
5677 let Inst{31-30} = 0b01;
5678 let Inst{29} = U;
5679 let Inst{28-24} = 0b11110;
5680 let Inst{23-22} = size;
5681 let Inst{21-17} = 0b11000;
5682 let Inst{16-12} = opcode;
5683 let Inst{11-10} = 0b10;
5684 let Inst{9-5} = Rn;
5685 let Inst{4-0} = Rd;
5686}
5687
5688multiclass SIMDPairwiseScalarD<bit U, bits<5> opc, string asm> {
5689 def v2i64p : BaseSIMDPairwiseScalar<U, 0b11, opc, FPR64Op, V128,
5690 asm, ".2d">;
5691}
5692
5693multiclass SIMDPairwiseScalarSD<bit U, bit S, bits<5> opc, string asm> {
5694 def v2i32p : BaseSIMDPairwiseScalar<U, {S,0}, opc, FPR32Op, V64,
5695 asm, ".2s">;
5696 def v2i64p : BaseSIMDPairwiseScalar<U, {S,1}, opc, FPR64Op, V128,
5697 asm, ".2d">;
5698}
5699
5700//----------------------------------------------------------------------------
5701// AdvSIMD across lanes instructions
5702//----------------------------------------------------------------------------
5703
5704let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5705class BaseSIMDAcrossLanes<bit Q, bit U, bits<2> size, bits<5> opcode,
5706 RegisterClass regtype, RegisterOperand vectype,
5707 string asm, string kind, list<dag> pattern>
5708 : I<(outs regtype:$Rd), (ins vectype:$Rn), asm,
5709 "{\t$Rd, $Rn" # kind # "|" # kind # "\t$Rd, $Rn}", "", pattern>,
5710 Sched<[WriteV]> {
5711 bits<5> Rd;
5712 bits<5> Rn;
5713 let Inst{31} = 0;
5714 let Inst{30} = Q;
5715 let Inst{29} = U;
5716 let Inst{28-24} = 0b01110;
5717 let Inst{23-22} = size;
5718 let Inst{21-17} = 0b11000;
5719 let Inst{16-12} = opcode;
5720 let Inst{11-10} = 0b10;
5721 let Inst{9-5} = Rn;
5722 let Inst{4-0} = Rd;
5723}
5724
5725multiclass SIMDAcrossLanesBHS<bit U, bits<5> opcode,
5726 string asm> {
5727 def v8i8v : BaseSIMDAcrossLanes<0, U, 0b00, opcode, FPR8, V64,
5728 asm, ".8b", []>;
5729 def v16i8v : BaseSIMDAcrossLanes<1, U, 0b00, opcode, FPR8, V128,
5730 asm, ".16b", []>;
5731 def v4i16v : BaseSIMDAcrossLanes<0, U, 0b01, opcode, FPR16, V64,
5732 asm, ".4h", []>;
5733 def v8i16v : BaseSIMDAcrossLanes<1, U, 0b01, opcode, FPR16, V128,
5734 asm, ".8h", []>;
5735 def v4i32v : BaseSIMDAcrossLanes<1, U, 0b10, opcode, FPR32, V128,
5736 asm, ".4s", []>;
5737}
5738
5739multiclass SIMDAcrossLanesHSD<bit U, bits<5> opcode, string asm> {
5740 def v8i8v : BaseSIMDAcrossLanes<0, U, 0b00, opcode, FPR16, V64,
5741 asm, ".8b", []>;
5742 def v16i8v : BaseSIMDAcrossLanes<1, U, 0b00, opcode, FPR16, V128,
5743 asm, ".16b", []>;
5744 def v4i16v : BaseSIMDAcrossLanes<0, U, 0b01, opcode, FPR32, V64,
5745 asm, ".4h", []>;
5746 def v8i16v : BaseSIMDAcrossLanes<1, U, 0b01, opcode, FPR32, V128,
5747 asm, ".8h", []>;
5748 def v4i32v : BaseSIMDAcrossLanes<1, U, 0b10, opcode, FPR64, V128,
5749 asm, ".4s", []>;
5750}
5751
5752multiclass SIMDAcrossLanesS<bits<5> opcode, bit sz1, string asm,
5753 Intrinsic intOp> {
5754 def v4i32v : BaseSIMDAcrossLanes<1, 1, {sz1, 0}, opcode, FPR32, V128,
5755 asm, ".4s",
5756 [(set FPR32:$Rd, (intOp (v4f32 V128:$Rn)))]>;
5757}
5758
5759//----------------------------------------------------------------------------
5760// AdvSIMD INS/DUP instructions
5761//----------------------------------------------------------------------------
5762
5763// FIXME: There has got to be a better way to factor these. ugh.
5764
5765class BaseSIMDInsDup<bit Q, bit op, dag outs, dag ins, string asm,
5766 string operands, string constraints, list<dag> pattern>
5767 : I<outs, ins, asm, operands, constraints, pattern>,
5768 Sched<[WriteV]> {
5769 bits<5> Rd;
5770 bits<5> Rn;
5771 let Inst{31} = 0;
5772 let Inst{30} = Q;
5773 let Inst{29} = op;
5774 let Inst{28-21} = 0b01110000;
5775 let Inst{15} = 0;
5776 let Inst{10} = 1;
5777 let Inst{9-5} = Rn;
5778 let Inst{4-0} = Rd;
5779}
5780
5781class SIMDDupFromMain<bit Q, bits<5> imm5, string size, ValueType vectype,
5782 RegisterOperand vecreg, RegisterClass regtype>
5783 : BaseSIMDInsDup<Q, 0, (outs vecreg:$Rd), (ins regtype:$Rn), "dup",
5784 "{\t$Rd" # size # ", $Rn" #
5785 "|" # size # "\t$Rd, $Rn}", "",
5786 [(set (vectype vecreg:$Rd), (AArch64dup regtype:$Rn))]> {
5787 let Inst{20-16} = imm5;
5788 let Inst{14-11} = 0b0001;
5789}
5790
5791class SIMDDupFromElement<bit Q, string dstkind, string srckind,
5792 ValueType vectype, ValueType insreg,
5793 RegisterOperand vecreg, Operand idxtype,
5794 ValueType elttype, SDNode OpNode>
5795 : BaseSIMDInsDup<Q, 0, (outs vecreg:$Rd), (ins V128:$Rn, idxtype:$idx), "dup",
5796 "{\t$Rd" # dstkind # ", $Rn" # srckind # "$idx" #
5797 "|" # dstkind # "\t$Rd, $Rn$idx}", "",
5798 [(set (vectype vecreg:$Rd),
5799 (OpNode (insreg V128:$Rn), idxtype:$idx))]> {
5800 let Inst{14-11} = 0b0000;
5801}
5802
5803class SIMDDup64FromElement
5804 : SIMDDupFromElement<1, ".2d", ".d", v2i64, v2i64, V128,
5805 VectorIndexD, i64, AArch64duplane64> {
5806 bits<1> idx;
5807 let Inst{20} = idx;
5808 let Inst{19-16} = 0b1000;
5809}
5810
5811class SIMDDup32FromElement<bit Q, string size, ValueType vectype,
5812 RegisterOperand vecreg>
5813 : SIMDDupFromElement<Q, size, ".s", vectype, v4i32, vecreg,
5814 VectorIndexS, i64, AArch64duplane32> {
5815 bits<2> idx;
5816 let Inst{20-19} = idx;
5817 let Inst{18-16} = 0b100;
5818}
5819
5820class SIMDDup16FromElement<bit Q, string size, ValueType vectype,
5821 RegisterOperand vecreg>
5822 : SIMDDupFromElement<Q, size, ".h", vectype, v8i16, vecreg,
5823 VectorIndexH, i64, AArch64duplane16> {
5824 bits<3> idx;
5825 let Inst{20-18} = idx;
5826 let Inst{17-16} = 0b10;
5827}
5828
5829class SIMDDup8FromElement<bit Q, string size, ValueType vectype,
5830 RegisterOperand vecreg>
5831 : SIMDDupFromElement<Q, size, ".b", vectype, v16i8, vecreg,
5832 VectorIndexB, i64, AArch64duplane8> {
5833 bits<4> idx;
5834 let Inst{20-17} = idx;
5835 let Inst{16} = 1;
5836}
5837
5838class BaseSIMDMov<bit Q, string size, bits<4> imm4, RegisterClass regtype,
5839 Operand idxtype, string asm, list<dag> pattern>
5840 : BaseSIMDInsDup<Q, 0, (outs regtype:$Rd), (ins V128:$Rn, idxtype:$idx), asm,
5841 "{\t$Rd, $Rn" # size # "$idx" #
5842 "|" # size # "\t$Rd, $Rn$idx}", "", pattern> {
5843 let Inst{14-11} = imm4;
5844}
5845
5846class SIMDSMov<bit Q, string size, RegisterClass regtype,
5847 Operand idxtype>
5848 : BaseSIMDMov<Q, size, 0b0101, regtype, idxtype, "smov", []>;
5849class SIMDUMov<bit Q, string size, ValueType vectype, RegisterClass regtype,
5850 Operand idxtype>
5851 : BaseSIMDMov<Q, size, 0b0111, regtype, idxtype, "umov",
5852 [(set regtype:$Rd, (vector_extract (vectype V128:$Rn), idxtype:$idx))]>;
5853
5854class SIMDMovAlias<string asm, string size, Instruction inst,
5855 RegisterClass regtype, Operand idxtype>
5856 : InstAlias<asm#"{\t$dst, $src"#size#"$idx" #
5857 "|" # size # "\t$dst, $src$idx}",
5858 (inst regtype:$dst, V128:$src, idxtype:$idx)>;
5859
5860multiclass SMov {
5861 def vi8to32 : SIMDSMov<0, ".b", GPR32, VectorIndexB> {
5862 bits<4> idx;
5863 let Inst{20-17} = idx;
5864 let Inst{16} = 1;
5865 }
5866 def vi8to64 : SIMDSMov<1, ".b", GPR64, VectorIndexB> {
5867 bits<4> idx;
5868 let Inst{20-17} = idx;
5869 let Inst{16} = 1;
5870 }
5871 def vi16to32 : SIMDSMov<0, ".h", GPR32, VectorIndexH> {
5872 bits<3> idx;
5873 let Inst{20-18} = idx;
5874 let Inst{17-16} = 0b10;
5875 }
5876 def vi16to64 : SIMDSMov<1, ".h", GPR64, VectorIndexH> {
5877 bits<3> idx;
5878 let Inst{20-18} = idx;
5879 let Inst{17-16} = 0b10;
5880 }
5881 def vi32to64 : SIMDSMov<1, ".s", GPR64, VectorIndexS> {
5882 bits<2> idx;
5883 let Inst{20-19} = idx;
5884 let Inst{18-16} = 0b100;
5885 }
5886}
5887
5888multiclass UMov {
5889 def vi8 : SIMDUMov<0, ".b", v16i8, GPR32, VectorIndexB> {
5890 bits<4> idx;
5891 let Inst{20-17} = idx;
5892 let Inst{16} = 1;
5893 }
5894 def vi16 : SIMDUMov<0, ".h", v8i16, GPR32, VectorIndexH> {
5895 bits<3> idx;
5896 let Inst{20-18} = idx;
5897 let Inst{17-16} = 0b10;
5898 }
5899 def vi32 : SIMDUMov<0, ".s", v4i32, GPR32, VectorIndexS> {
5900 bits<2> idx;
5901 let Inst{20-19} = idx;
5902 let Inst{18-16} = 0b100;
5903 }
5904 def vi64 : SIMDUMov<1, ".d", v2i64, GPR64, VectorIndexD> {
5905 bits<1> idx;
5906 let Inst{20} = idx;
5907 let Inst{19-16} = 0b1000;
5908 }
5909 def : SIMDMovAlias<"mov", ".s",
5910 !cast<Instruction>(NAME#"vi32"),
5911 GPR32, VectorIndexS>;
5912 def : SIMDMovAlias<"mov", ".d",
5913 !cast<Instruction>(NAME#"vi64"),
5914 GPR64, VectorIndexD>;
5915}
5916
5917class SIMDInsFromMain<string size, ValueType vectype,
5918 RegisterClass regtype, Operand idxtype>
5919 : BaseSIMDInsDup<1, 0, (outs V128:$dst),
5920 (ins V128:$Rd, idxtype:$idx, regtype:$Rn), "ins",
5921 "{\t$Rd" # size # "$idx, $Rn" #
5922 "|" # size # "\t$Rd$idx, $Rn}",
5923 "$Rd = $dst",
5924 [(set V128:$dst,
5925 (vector_insert (vectype V128:$Rd), regtype:$Rn, idxtype:$idx))]> {
5926 let Inst{14-11} = 0b0011;
5927}
5928
5929class SIMDInsFromElement<string size, ValueType vectype,
5930 ValueType elttype, Operand idxtype>
5931 : BaseSIMDInsDup<1, 1, (outs V128:$dst),
5932 (ins V128:$Rd, idxtype:$idx, V128:$Rn, idxtype:$idx2), "ins",
5933 "{\t$Rd" # size # "$idx, $Rn" # size # "$idx2" #
5934 "|" # size # "\t$Rd$idx, $Rn$idx2}",
5935 "$Rd = $dst",
5936 [(set V128:$dst,
5937 (vector_insert
5938 (vectype V128:$Rd),
5939 (elttype (vector_extract (vectype V128:$Rn), idxtype:$idx2)),
5940 idxtype:$idx))]>;
5941
5942class SIMDInsMainMovAlias<string size, Instruction inst,
5943 RegisterClass regtype, Operand idxtype>
5944 : InstAlias<"mov" # "{\t$dst" # size # "$idx, $src" #
5945 "|" # size #"\t$dst$idx, $src}",
5946 (inst V128:$dst, idxtype:$idx, regtype:$src)>;
5947class SIMDInsElementMovAlias<string size, Instruction inst,
5948 Operand idxtype>
5949 : InstAlias<"mov" # "{\t$dst" # size # "$idx, $src" # size # "$idx2" #
5950 # "|" # size #" $dst$idx, $src$idx2}",
5951 (inst V128:$dst, idxtype:$idx, V128:$src, idxtype:$idx2)>;
5952
5953
5954multiclass SIMDIns {
5955 def vi8gpr : SIMDInsFromMain<".b", v16i8, GPR32, VectorIndexB> {
5956 bits<4> idx;
5957 let Inst{20-17} = idx;
5958 let Inst{16} = 1;
5959 }
5960 def vi16gpr : SIMDInsFromMain<".h", v8i16, GPR32, VectorIndexH> {
5961 bits<3> idx;
5962 let Inst{20-18} = idx;
5963 let Inst{17-16} = 0b10;
5964 }
5965 def vi32gpr : SIMDInsFromMain<".s", v4i32, GPR32, VectorIndexS> {
5966 bits<2> idx;
5967 let Inst{20-19} = idx;
5968 let Inst{18-16} = 0b100;
5969 }
5970 def vi64gpr : SIMDInsFromMain<".d", v2i64, GPR64, VectorIndexD> {
5971 bits<1> idx;
5972 let Inst{20} = idx;
5973 let Inst{19-16} = 0b1000;
5974 }
5975
5976 def vi8lane : SIMDInsFromElement<".b", v16i8, i32, VectorIndexB> {
5977 bits<4> idx;
5978 bits<4> idx2;
5979 let Inst{20-17} = idx;
5980 let Inst{16} = 1;
5981 let Inst{14-11} = idx2;
5982 }
5983 def vi16lane : SIMDInsFromElement<".h", v8i16, i32, VectorIndexH> {
5984 bits<3> idx;
5985 bits<3> idx2;
5986 let Inst{20-18} = idx;
5987 let Inst{17-16} = 0b10;
5988 let Inst{14-12} = idx2;
Bradley Smithb9136532015-04-14 15:07:26 +00005989 let Inst{11} = {?};
Tim Northover3b0846e2014-05-24 12:50:23 +00005990 }
5991 def vi32lane : SIMDInsFromElement<".s", v4i32, i32, VectorIndexS> {
5992 bits<2> idx;
5993 bits<2> idx2;
5994 let Inst{20-19} = idx;
5995 let Inst{18-16} = 0b100;
5996 let Inst{14-13} = idx2;
Bradley Smithb9136532015-04-14 15:07:26 +00005997 let Inst{12-11} = {?,?};
Tim Northover3b0846e2014-05-24 12:50:23 +00005998 }
5999 def vi64lane : SIMDInsFromElement<".d", v2i64, i64, VectorIndexD> {
6000 bits<1> idx;
6001 bits<1> idx2;
6002 let Inst{20} = idx;
6003 let Inst{19-16} = 0b1000;
6004 let Inst{14} = idx2;
Bradley Smithb9136532015-04-14 15:07:26 +00006005 let Inst{13-11} = {?,?,?};
Tim Northover3b0846e2014-05-24 12:50:23 +00006006 }
6007
6008 // For all forms of the INS instruction, the "mov" mnemonic is the
6009 // preferred alias. Why they didn't just call the instruction "mov" in
6010 // the first place is a very good question indeed...
6011 def : SIMDInsMainMovAlias<".b", !cast<Instruction>(NAME#"vi8gpr"),
6012 GPR32, VectorIndexB>;
6013 def : SIMDInsMainMovAlias<".h", !cast<Instruction>(NAME#"vi16gpr"),
6014 GPR32, VectorIndexH>;
6015 def : SIMDInsMainMovAlias<".s", !cast<Instruction>(NAME#"vi32gpr"),
6016 GPR32, VectorIndexS>;
6017 def : SIMDInsMainMovAlias<".d", !cast<Instruction>(NAME#"vi64gpr"),
6018 GPR64, VectorIndexD>;
6019
6020 def : SIMDInsElementMovAlias<".b", !cast<Instruction>(NAME#"vi8lane"),
6021 VectorIndexB>;
6022 def : SIMDInsElementMovAlias<".h", !cast<Instruction>(NAME#"vi16lane"),
6023 VectorIndexH>;
6024 def : SIMDInsElementMovAlias<".s", !cast<Instruction>(NAME#"vi32lane"),
6025 VectorIndexS>;
6026 def : SIMDInsElementMovAlias<".d", !cast<Instruction>(NAME#"vi64lane"),
6027 VectorIndexD>;
6028}
6029
6030//----------------------------------------------------------------------------
6031// AdvSIMD TBL/TBX
6032//----------------------------------------------------------------------------
6033
6034let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
6035class BaseSIMDTableLookup<bit Q, bits<2> len, bit op, RegisterOperand vectype,
6036 RegisterOperand listtype, string asm, string kind>
6037 : I<(outs vectype:$Vd), (ins listtype:$Vn, vectype:$Vm), asm,
6038 "\t$Vd" # kind # ", $Vn, $Vm" # kind, "", []>,
6039 Sched<[WriteV]> {
6040 bits<5> Vd;
6041 bits<5> Vn;
6042 bits<5> Vm;
6043 let Inst{31} = 0;
6044 let Inst{30} = Q;
6045 let Inst{29-21} = 0b001110000;
6046 let Inst{20-16} = Vm;
6047 let Inst{15} = 0;
6048 let Inst{14-13} = len;
6049 let Inst{12} = op;
6050 let Inst{11-10} = 0b00;
6051 let Inst{9-5} = Vn;
6052 let Inst{4-0} = Vd;
6053}
6054
6055let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
6056class BaseSIMDTableLookupTied<bit Q, bits<2> len, bit op, RegisterOperand vectype,
6057 RegisterOperand listtype, string asm, string kind>
6058 : I<(outs vectype:$dst), (ins vectype:$Vd, listtype:$Vn, vectype:$Vm), asm,
6059 "\t$Vd" # kind # ", $Vn, $Vm" # kind, "$Vd = $dst", []>,
6060 Sched<[WriteV]> {
6061 bits<5> Vd;
6062 bits<5> Vn;
6063 bits<5> Vm;
6064 let Inst{31} = 0;
6065 let Inst{30} = Q;
6066 let Inst{29-21} = 0b001110000;
6067 let Inst{20-16} = Vm;
6068 let Inst{15} = 0;
6069 let Inst{14-13} = len;
6070 let Inst{12} = op;
6071 let Inst{11-10} = 0b00;
6072 let Inst{9-5} = Vn;
6073 let Inst{4-0} = Vd;
6074}
6075
6076class SIMDTableLookupAlias<string asm, Instruction inst,
6077 RegisterOperand vectype, RegisterOperand listtype>
6078 : InstAlias<!strconcat(asm, "\t$dst, $lst, $index"),
6079 (inst vectype:$dst, listtype:$lst, vectype:$index), 0>;
6080
6081multiclass SIMDTableLookup<bit op, string asm> {
6082 def v8i8One : BaseSIMDTableLookup<0, 0b00, op, V64, VecListOne16b,
6083 asm, ".8b">;
6084 def v8i8Two : BaseSIMDTableLookup<0, 0b01, op, V64, VecListTwo16b,
6085 asm, ".8b">;
6086 def v8i8Three : BaseSIMDTableLookup<0, 0b10, op, V64, VecListThree16b,
6087 asm, ".8b">;
6088 def v8i8Four : BaseSIMDTableLookup<0, 0b11, op, V64, VecListFour16b,
6089 asm, ".8b">;
6090 def v16i8One : BaseSIMDTableLookup<1, 0b00, op, V128, VecListOne16b,
6091 asm, ".16b">;
6092 def v16i8Two : BaseSIMDTableLookup<1, 0b01, op, V128, VecListTwo16b,
6093 asm, ".16b">;
6094 def v16i8Three: BaseSIMDTableLookup<1, 0b10, op, V128, VecListThree16b,
6095 asm, ".16b">;
6096 def v16i8Four : BaseSIMDTableLookup<1, 0b11, op, V128, VecListFour16b,
6097 asm, ".16b">;
6098
6099 def : SIMDTableLookupAlias<asm # ".8b",
6100 !cast<Instruction>(NAME#"v8i8One"),
6101 V64, VecListOne128>;
6102 def : SIMDTableLookupAlias<asm # ".8b",
6103 !cast<Instruction>(NAME#"v8i8Two"),
6104 V64, VecListTwo128>;
6105 def : SIMDTableLookupAlias<asm # ".8b",
6106 !cast<Instruction>(NAME#"v8i8Three"),
6107 V64, VecListThree128>;
6108 def : SIMDTableLookupAlias<asm # ".8b",
6109 !cast<Instruction>(NAME#"v8i8Four"),
6110 V64, VecListFour128>;
6111 def : SIMDTableLookupAlias<asm # ".16b",
6112 !cast<Instruction>(NAME#"v16i8One"),
6113 V128, VecListOne128>;
6114 def : SIMDTableLookupAlias<asm # ".16b",
6115 !cast<Instruction>(NAME#"v16i8Two"),
6116 V128, VecListTwo128>;
6117 def : SIMDTableLookupAlias<asm # ".16b",
6118 !cast<Instruction>(NAME#"v16i8Three"),
6119 V128, VecListThree128>;
6120 def : SIMDTableLookupAlias<asm # ".16b",
6121 !cast<Instruction>(NAME#"v16i8Four"),
6122 V128, VecListFour128>;
6123}
6124
6125multiclass SIMDTableLookupTied<bit op, string asm> {
6126 def v8i8One : BaseSIMDTableLookupTied<0, 0b00, op, V64, VecListOne16b,
6127 asm, ".8b">;
6128 def v8i8Two : BaseSIMDTableLookupTied<0, 0b01, op, V64, VecListTwo16b,
6129 asm, ".8b">;
6130 def v8i8Three : BaseSIMDTableLookupTied<0, 0b10, op, V64, VecListThree16b,
6131 asm, ".8b">;
6132 def v8i8Four : BaseSIMDTableLookupTied<0, 0b11, op, V64, VecListFour16b,
6133 asm, ".8b">;
6134 def v16i8One : BaseSIMDTableLookupTied<1, 0b00, op, V128, VecListOne16b,
6135 asm, ".16b">;
6136 def v16i8Two : BaseSIMDTableLookupTied<1, 0b01, op, V128, VecListTwo16b,
6137 asm, ".16b">;
6138 def v16i8Three: BaseSIMDTableLookupTied<1, 0b10, op, V128, VecListThree16b,
6139 asm, ".16b">;
6140 def v16i8Four : BaseSIMDTableLookupTied<1, 0b11, op, V128, VecListFour16b,
6141 asm, ".16b">;
6142
6143 def : SIMDTableLookupAlias<asm # ".8b",
6144 !cast<Instruction>(NAME#"v8i8One"),
6145 V64, VecListOne128>;
6146 def : SIMDTableLookupAlias<asm # ".8b",
6147 !cast<Instruction>(NAME#"v8i8Two"),
6148 V64, VecListTwo128>;
6149 def : SIMDTableLookupAlias<asm # ".8b",
6150 !cast<Instruction>(NAME#"v8i8Three"),
6151 V64, VecListThree128>;
6152 def : SIMDTableLookupAlias<asm # ".8b",
6153 !cast<Instruction>(NAME#"v8i8Four"),
6154 V64, VecListFour128>;
6155 def : SIMDTableLookupAlias<asm # ".16b",
6156 !cast<Instruction>(NAME#"v16i8One"),
6157 V128, VecListOne128>;
6158 def : SIMDTableLookupAlias<asm # ".16b",
6159 !cast<Instruction>(NAME#"v16i8Two"),
6160 V128, VecListTwo128>;
6161 def : SIMDTableLookupAlias<asm # ".16b",
6162 !cast<Instruction>(NAME#"v16i8Three"),
6163 V128, VecListThree128>;
6164 def : SIMDTableLookupAlias<asm # ".16b",
6165 !cast<Instruction>(NAME#"v16i8Four"),
6166 V128, VecListFour128>;
6167}
6168
6169
6170//----------------------------------------------------------------------------
6171// AdvSIMD scalar CPY
6172//----------------------------------------------------------------------------
6173let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
6174class BaseSIMDScalarCPY<RegisterClass regtype, RegisterOperand vectype,
6175 string kind, Operand idxtype>
6176 : I<(outs regtype:$dst), (ins vectype:$src, idxtype:$idx), "mov",
6177 "{\t$dst, $src" # kind # "$idx" #
6178 "|\t$dst, $src$idx}", "", []>,
6179 Sched<[WriteV]> {
6180 bits<5> dst;
6181 bits<5> src;
6182 let Inst{31-21} = 0b01011110000;
6183 let Inst{15-10} = 0b000001;
6184 let Inst{9-5} = src;
6185 let Inst{4-0} = dst;
6186}
6187
6188class SIMDScalarCPYAlias<string asm, string size, Instruction inst,
6189 RegisterClass regtype, RegisterOperand vectype, Operand idxtype>
6190 : InstAlias<asm # "{\t$dst, $src" # size # "$index" #
6191 # "|\t$dst, $src$index}",
6192 (inst regtype:$dst, vectype:$src, idxtype:$index), 0>;
6193
6194
6195multiclass SIMDScalarCPY<string asm> {
6196 def i8 : BaseSIMDScalarCPY<FPR8, V128, ".b", VectorIndexB> {
6197 bits<4> idx;
6198 let Inst{20-17} = idx;
6199 let Inst{16} = 1;
6200 }
6201 def i16 : BaseSIMDScalarCPY<FPR16, V128, ".h", VectorIndexH> {
6202 bits<3> idx;
6203 let Inst{20-18} = idx;
6204 let Inst{17-16} = 0b10;
6205 }
6206 def i32 : BaseSIMDScalarCPY<FPR32, V128, ".s", VectorIndexS> {
6207 bits<2> idx;
6208 let Inst{20-19} = idx;
6209 let Inst{18-16} = 0b100;
6210 }
6211 def i64 : BaseSIMDScalarCPY<FPR64, V128, ".d", VectorIndexD> {
6212 bits<1> idx;
6213 let Inst{20} = idx;
6214 let Inst{19-16} = 0b1000;
6215 }
6216
6217 def : Pat<(v1i64 (scalar_to_vector (i64 (vector_extract (v2i64 V128:$src),
6218 VectorIndexD:$idx)))),
6219 (!cast<Instruction>(NAME # i64) V128:$src, VectorIndexD:$idx)>;
6220
6221 // 'DUP' mnemonic aliases.
6222 def : SIMDScalarCPYAlias<"dup", ".b",
6223 !cast<Instruction>(NAME#"i8"),
6224 FPR8, V128, VectorIndexB>;
6225 def : SIMDScalarCPYAlias<"dup", ".h",
6226 !cast<Instruction>(NAME#"i16"),
6227 FPR16, V128, VectorIndexH>;
6228 def : SIMDScalarCPYAlias<"dup", ".s",
6229 !cast<Instruction>(NAME#"i32"),
6230 FPR32, V128, VectorIndexS>;
6231 def : SIMDScalarCPYAlias<"dup", ".d",
6232 !cast<Instruction>(NAME#"i64"),
6233 FPR64, V128, VectorIndexD>;
6234}
6235
6236//----------------------------------------------------------------------------
6237// AdvSIMD modified immediate instructions
6238//----------------------------------------------------------------------------
6239
6240class BaseSIMDModifiedImm<bit Q, bit op, dag oops, dag iops,
6241 string asm, string op_string,
6242 string cstr, list<dag> pattern>
6243 : I<oops, iops, asm, op_string, cstr, pattern>,
6244 Sched<[WriteV]> {
6245 bits<5> Rd;
6246 bits<8> imm8;
6247 let Inst{31} = 0;
6248 let Inst{30} = Q;
6249 let Inst{29} = op;
6250 let Inst{28-19} = 0b0111100000;
6251 let Inst{18-16} = imm8{7-5};
6252 let Inst{11-10} = 0b01;
6253 let Inst{9-5} = imm8{4-0};
6254 let Inst{4-0} = Rd;
6255}
6256
6257class BaseSIMDModifiedImmVector<bit Q, bit op, RegisterOperand vectype,
6258 Operand immtype, dag opt_shift_iop,
6259 string opt_shift, string asm, string kind,
6260 list<dag> pattern>
6261 : BaseSIMDModifiedImm<Q, op, (outs vectype:$Rd),
6262 !con((ins immtype:$imm8), opt_shift_iop), asm,
6263 "{\t$Rd" # kind # ", $imm8" # opt_shift #
6264 "|" # kind # "\t$Rd, $imm8" # opt_shift # "}",
6265 "", pattern> {
6266 let DecoderMethod = "DecodeModImmInstruction";
6267}
6268
6269class BaseSIMDModifiedImmVectorTied<bit Q, bit op, RegisterOperand vectype,
6270 Operand immtype, dag opt_shift_iop,
6271 string opt_shift, string asm, string kind,
6272 list<dag> pattern>
6273 : BaseSIMDModifiedImm<Q, op, (outs vectype:$dst),
6274 !con((ins vectype:$Rd, immtype:$imm8), opt_shift_iop),
6275 asm, "{\t$Rd" # kind # ", $imm8" # opt_shift #
6276 "|" # kind # "\t$Rd, $imm8" # opt_shift # "}",
6277 "$Rd = $dst", pattern> {
6278 let DecoderMethod = "DecodeModImmTiedInstruction";
6279}
6280
6281class BaseSIMDModifiedImmVectorShift<bit Q, bit op, bits<2> b15_b12,
6282 RegisterOperand vectype, string asm,
6283 string kind, list<dag> pattern>
6284 : BaseSIMDModifiedImmVector<Q, op, vectype, imm0_255,
6285 (ins logical_vec_shift:$shift),
6286 "$shift", asm, kind, pattern> {
6287 bits<2> shift;
6288 let Inst{15} = b15_b12{1};
6289 let Inst{14-13} = shift;
6290 let Inst{12} = b15_b12{0};
6291}
6292
6293class BaseSIMDModifiedImmVectorShiftTied<bit Q, bit op, bits<2> b15_b12,
6294 RegisterOperand vectype, string asm,
6295 string kind, list<dag> pattern>
6296 : BaseSIMDModifiedImmVectorTied<Q, op, vectype, imm0_255,
6297 (ins logical_vec_shift:$shift),
6298 "$shift", asm, kind, pattern> {
6299 bits<2> shift;
6300 let Inst{15} = b15_b12{1};
6301 let Inst{14-13} = shift;
6302 let Inst{12} = b15_b12{0};
6303}
6304
6305
6306class BaseSIMDModifiedImmVectorShiftHalf<bit Q, bit op, bits<2> b15_b12,
6307 RegisterOperand vectype, string asm,
6308 string kind, list<dag> pattern>
6309 : BaseSIMDModifiedImmVector<Q, op, vectype, imm0_255,
6310 (ins logical_vec_hw_shift:$shift),
6311 "$shift", asm, kind, pattern> {
6312 bits<2> shift;
6313 let Inst{15} = b15_b12{1};
6314 let Inst{14} = 0;
6315 let Inst{13} = shift{0};
6316 let Inst{12} = b15_b12{0};
6317}
6318
6319class BaseSIMDModifiedImmVectorShiftHalfTied<bit Q, bit op, bits<2> b15_b12,
6320 RegisterOperand vectype, string asm,
6321 string kind, list<dag> pattern>
6322 : BaseSIMDModifiedImmVectorTied<Q, op, vectype, imm0_255,
6323 (ins logical_vec_hw_shift:$shift),
6324 "$shift", asm, kind, pattern> {
6325 bits<2> shift;
6326 let Inst{15} = b15_b12{1};
6327 let Inst{14} = 0;
6328 let Inst{13} = shift{0};
6329 let Inst{12} = b15_b12{0};
6330}
6331
6332multiclass SIMDModifiedImmVectorShift<bit op, bits<2> hw_cmode, bits<2> w_cmode,
6333 string asm> {
6334 def v4i16 : BaseSIMDModifiedImmVectorShiftHalf<0, op, hw_cmode, V64,
6335 asm, ".4h", []>;
6336 def v8i16 : BaseSIMDModifiedImmVectorShiftHalf<1, op, hw_cmode, V128,
6337 asm, ".8h", []>;
6338
6339 def v2i32 : BaseSIMDModifiedImmVectorShift<0, op, w_cmode, V64,
6340 asm, ".2s", []>;
6341 def v4i32 : BaseSIMDModifiedImmVectorShift<1, op, w_cmode, V128,
6342 asm, ".4s", []>;
6343}
6344
6345multiclass SIMDModifiedImmVectorShiftTied<bit op, bits<2> hw_cmode,
6346 bits<2> w_cmode, string asm,
6347 SDNode OpNode> {
6348 def v4i16 : BaseSIMDModifiedImmVectorShiftHalfTied<0, op, hw_cmode, V64,
6349 asm, ".4h",
6350 [(set (v4i16 V64:$dst), (OpNode V64:$Rd,
6351 imm0_255:$imm8,
6352 (i32 imm:$shift)))]>;
6353 def v8i16 : BaseSIMDModifiedImmVectorShiftHalfTied<1, op, hw_cmode, V128,
6354 asm, ".8h",
6355 [(set (v8i16 V128:$dst), (OpNode V128:$Rd,
6356 imm0_255:$imm8,
6357 (i32 imm:$shift)))]>;
6358
6359 def v2i32 : BaseSIMDModifiedImmVectorShiftTied<0, op, w_cmode, V64,
6360 asm, ".2s",
6361 [(set (v2i32 V64:$dst), (OpNode V64:$Rd,
6362 imm0_255:$imm8,
6363 (i32 imm:$shift)))]>;
6364 def v4i32 : BaseSIMDModifiedImmVectorShiftTied<1, op, w_cmode, V128,
6365 asm, ".4s",
6366 [(set (v4i32 V128:$dst), (OpNode V128:$Rd,
6367 imm0_255:$imm8,
6368 (i32 imm:$shift)))]>;
6369}
6370
6371class SIMDModifiedImmMoveMSL<bit Q, bit op, bits<4> cmode,
6372 RegisterOperand vectype, string asm,
6373 string kind, list<dag> pattern>
6374 : BaseSIMDModifiedImmVector<Q, op, vectype, imm0_255,
6375 (ins move_vec_shift:$shift),
6376 "$shift", asm, kind, pattern> {
6377 bits<1> shift;
6378 let Inst{15-13} = cmode{3-1};
6379 let Inst{12} = shift;
6380}
6381
6382class SIMDModifiedImmVectorNoShift<bit Q, bit op, bits<4> cmode,
6383 RegisterOperand vectype,
6384 Operand imm_type, string asm,
6385 string kind, list<dag> pattern>
6386 : BaseSIMDModifiedImmVector<Q, op, vectype, imm_type, (ins), "",
6387 asm, kind, pattern> {
6388 let Inst{15-12} = cmode;
6389}
6390
6391class SIMDModifiedImmScalarNoShift<bit Q, bit op, bits<4> cmode, string asm,
6392 list<dag> pattern>
6393 : BaseSIMDModifiedImm<Q, op, (outs FPR64:$Rd), (ins simdimmtype10:$imm8), asm,
6394 "\t$Rd, $imm8", "", pattern> {
6395 let Inst{15-12} = cmode;
6396 let DecoderMethod = "DecodeModImmInstruction";
6397}
6398
6399//----------------------------------------------------------------------------
6400// AdvSIMD indexed element
6401//----------------------------------------------------------------------------
6402
6403let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
6404class BaseSIMDIndexed<bit Q, bit U, bit Scalar, bits<2> size, bits<4> opc,
6405 RegisterOperand dst_reg, RegisterOperand lhs_reg,
6406 RegisterOperand rhs_reg, Operand vec_idx, string asm,
6407 string apple_kind, string dst_kind, string lhs_kind,
6408 string rhs_kind, list<dag> pattern>
6409 : I<(outs dst_reg:$Rd), (ins lhs_reg:$Rn, rhs_reg:$Rm, vec_idx:$idx),
6410 asm,
6411 "{\t$Rd" # dst_kind # ", $Rn" # lhs_kind # ", $Rm" # rhs_kind # "$idx" #
6412 "|" # apple_kind # "\t$Rd, $Rn, $Rm$idx}", "", pattern>,
6413 Sched<[WriteV]> {
6414 bits<5> Rd;
6415 bits<5> Rn;
6416 bits<5> Rm;
6417
6418 let Inst{31} = 0;
6419 let Inst{30} = Q;
6420 let Inst{29} = U;
6421 let Inst{28} = Scalar;
6422 let Inst{27-24} = 0b1111;
6423 let Inst{23-22} = size;
6424 // Bit 21 must be set by the derived class.
6425 let Inst{20-16} = Rm;
6426 let Inst{15-12} = opc;
6427 // Bit 11 must be set by the derived class.
6428 let Inst{10} = 0;
6429 let Inst{9-5} = Rn;
6430 let Inst{4-0} = Rd;
6431}
6432
6433let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
6434class BaseSIMDIndexedTied<bit Q, bit U, bit Scalar, bits<2> size, bits<4> opc,
6435 RegisterOperand dst_reg, RegisterOperand lhs_reg,
6436 RegisterOperand rhs_reg, Operand vec_idx, string asm,
6437 string apple_kind, string dst_kind, string lhs_kind,
6438 string rhs_kind, list<dag> pattern>
6439 : I<(outs dst_reg:$dst),
6440 (ins dst_reg:$Rd, lhs_reg:$Rn, rhs_reg:$Rm, vec_idx:$idx), asm,
6441 "{\t$Rd" # dst_kind # ", $Rn" # lhs_kind # ", $Rm" # rhs_kind # "$idx" #
6442 "|" # apple_kind # "\t$Rd, $Rn, $Rm$idx}", "$Rd = $dst", pattern>,
6443 Sched<[WriteV]> {
6444 bits<5> Rd;
6445 bits<5> Rn;
6446 bits<5> Rm;
6447
6448 let Inst{31} = 0;
6449 let Inst{30} = Q;
6450 let Inst{29} = U;
6451 let Inst{28} = Scalar;
6452 let Inst{27-24} = 0b1111;
6453 let Inst{23-22} = size;
6454 // Bit 21 must be set by the derived class.
6455 let Inst{20-16} = Rm;
6456 let Inst{15-12} = opc;
6457 // Bit 11 must be set by the derived class.
6458 let Inst{10} = 0;
6459 let Inst{9-5} = Rn;
6460 let Inst{4-0} = Rd;
6461}
6462
6463multiclass SIMDFPIndexedSD<bit U, bits<4> opc, string asm,
6464 SDPatternOperator OpNode> {
6465 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc,
6466 V64, V64,
6467 V128, VectorIndexS,
6468 asm, ".2s", ".2s", ".2s", ".s",
6469 [(set (v2f32 V64:$Rd),
6470 (OpNode (v2f32 V64:$Rn),
6471 (v2f32 (AArch64duplane32 (v4f32 V128:$Rm), VectorIndexS:$idx))))]> {
6472 bits<2> idx;
6473 let Inst{11} = idx{1};
6474 let Inst{21} = idx{0};
6475 }
6476
6477 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc,
6478 V128, V128,
6479 V128, VectorIndexS,
6480 asm, ".4s", ".4s", ".4s", ".s",
6481 [(set (v4f32 V128:$Rd),
6482 (OpNode (v4f32 V128:$Rn),
6483 (v4f32 (AArch64duplane32 (v4f32 V128:$Rm), VectorIndexS:$idx))))]> {
6484 bits<2> idx;
6485 let Inst{11} = idx{1};
6486 let Inst{21} = idx{0};
6487 }
6488
6489 def v2i64_indexed : BaseSIMDIndexed<1, U, 0, 0b11, opc,
6490 V128, V128,
6491 V128, VectorIndexD,
6492 asm, ".2d", ".2d", ".2d", ".d",
6493 [(set (v2f64 V128:$Rd),
6494 (OpNode (v2f64 V128:$Rn),
6495 (v2f64 (AArch64duplane64 (v2f64 V128:$Rm), VectorIndexD:$idx))))]> {
6496 bits<1> idx;
6497 let Inst{11} = idx{0};
6498 let Inst{21} = 0;
6499 }
6500
6501 def v1i32_indexed : BaseSIMDIndexed<1, U, 1, 0b10, opc,
6502 FPR32Op, FPR32Op, V128, VectorIndexS,
6503 asm, ".s", "", "", ".s",
6504 [(set (f32 FPR32Op:$Rd),
6505 (OpNode (f32 FPR32Op:$Rn),
6506 (f32 (vector_extract (v4f32 V128:$Rm),
6507 VectorIndexS:$idx))))]> {
6508 bits<2> idx;
6509 let Inst{11} = idx{1};
6510 let Inst{21} = idx{0};
6511 }
6512
6513 def v1i64_indexed : BaseSIMDIndexed<1, U, 1, 0b11, opc,
6514 FPR64Op, FPR64Op, V128, VectorIndexD,
6515 asm, ".d", "", "", ".d",
6516 [(set (f64 FPR64Op:$Rd),
6517 (OpNode (f64 FPR64Op:$Rn),
6518 (f64 (vector_extract (v2f64 V128:$Rm),
6519 VectorIndexD:$idx))))]> {
6520 bits<1> idx;
6521 let Inst{11} = idx{0};
6522 let Inst{21} = 0;
6523 }
6524}
6525
6526multiclass SIMDFPIndexedSDTiedPatterns<string INST, SDPatternOperator OpNode> {
6527 // 2 variants for the .2s version: DUPLANE from 128-bit and DUP scalar.
6528 def : Pat<(v2f32 (OpNode (v2f32 V64:$Rd), (v2f32 V64:$Rn),
6529 (AArch64duplane32 (v4f32 V128:$Rm),
6530 VectorIndexS:$idx))),
6531 (!cast<Instruction>(INST # v2i32_indexed)
6532 V64:$Rd, V64:$Rn, V128:$Rm, VectorIndexS:$idx)>;
6533 def : Pat<(v2f32 (OpNode (v2f32 V64:$Rd), (v2f32 V64:$Rn),
6534 (AArch64dup (f32 FPR32Op:$Rm)))),
6535 (!cast<Instruction>(INST # "v2i32_indexed") V64:$Rd, V64:$Rn,
6536 (SUBREG_TO_REG (i32 0), FPR32Op:$Rm, ssub), (i64 0))>;
6537
6538
6539 // 2 variants for the .4s version: DUPLANE from 128-bit and DUP scalar.
6540 def : Pat<(v4f32 (OpNode (v4f32 V128:$Rd), (v4f32 V128:$Rn),
6541 (AArch64duplane32 (v4f32 V128:$Rm),
6542 VectorIndexS:$idx))),
6543 (!cast<Instruction>(INST # "v4i32_indexed")
6544 V128:$Rd, V128:$Rn, V128:$Rm, VectorIndexS:$idx)>;
6545 def : Pat<(v4f32 (OpNode (v4f32 V128:$Rd), (v4f32 V128:$Rn),
6546 (AArch64dup (f32 FPR32Op:$Rm)))),
6547 (!cast<Instruction>(INST # "v4i32_indexed") V128:$Rd, V128:$Rn,
6548 (SUBREG_TO_REG (i32 0), FPR32Op:$Rm, ssub), (i64 0))>;
6549
6550 // 2 variants for the .2d version: DUPLANE from 128-bit and DUP scalar.
6551 def : Pat<(v2f64 (OpNode (v2f64 V128:$Rd), (v2f64 V128:$Rn),
6552 (AArch64duplane64 (v2f64 V128:$Rm),
6553 VectorIndexD:$idx))),
6554 (!cast<Instruction>(INST # "v2i64_indexed")
6555 V128:$Rd, V128:$Rn, V128:$Rm, VectorIndexS:$idx)>;
6556 def : Pat<(v2f64 (OpNode (v2f64 V128:$Rd), (v2f64 V128:$Rn),
6557 (AArch64dup (f64 FPR64Op:$Rm)))),
6558 (!cast<Instruction>(INST # "v2i64_indexed") V128:$Rd, V128:$Rn,
6559 (SUBREG_TO_REG (i32 0), FPR64Op:$Rm, dsub), (i64 0))>;
6560
6561 // 2 variants for 32-bit scalar version: extract from .2s or from .4s
6562 def : Pat<(f32 (OpNode (f32 FPR32:$Rd), (f32 FPR32:$Rn),
6563 (vector_extract (v4f32 V128:$Rm), VectorIndexS:$idx))),
6564 (!cast<Instruction>(INST # "v1i32_indexed") FPR32:$Rd, FPR32:$Rn,
6565 V128:$Rm, VectorIndexS:$idx)>;
6566 def : Pat<(f32 (OpNode (f32 FPR32:$Rd), (f32 FPR32:$Rn),
6567 (vector_extract (v2f32 V64:$Rm), VectorIndexS:$idx))),
6568 (!cast<Instruction>(INST # "v1i32_indexed") FPR32:$Rd, FPR32:$Rn,
6569 (SUBREG_TO_REG (i32 0), V64:$Rm, dsub), VectorIndexS:$idx)>;
6570
6571 // 1 variant for 64-bit scalar version: extract from .1d or from .2d
6572 def : Pat<(f64 (OpNode (f64 FPR64:$Rd), (f64 FPR64:$Rn),
6573 (vector_extract (v2f64 V128:$Rm), VectorIndexD:$idx))),
6574 (!cast<Instruction>(INST # "v1i64_indexed") FPR64:$Rd, FPR64:$Rn,
6575 V128:$Rm, VectorIndexD:$idx)>;
6576}
6577
6578multiclass SIMDFPIndexedSDTied<bit U, bits<4> opc, string asm> {
6579 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc, V64, V64,
6580 V128, VectorIndexS,
6581 asm, ".2s", ".2s", ".2s", ".s", []> {
6582 bits<2> idx;
6583 let Inst{11} = idx{1};
6584 let Inst{21} = idx{0};
6585 }
6586
6587 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc,
6588 V128, V128,
6589 V128, VectorIndexS,
6590 asm, ".4s", ".4s", ".4s", ".s", []> {
6591 bits<2> idx;
6592 let Inst{11} = idx{1};
6593 let Inst{21} = idx{0};
6594 }
6595
6596 def v2i64_indexed : BaseSIMDIndexedTied<1, U, 0, 0b11, opc,
6597 V128, V128,
6598 V128, VectorIndexD,
6599 asm, ".2d", ".2d", ".2d", ".d", []> {
6600 bits<1> idx;
6601 let Inst{11} = idx{0};
6602 let Inst{21} = 0;
6603 }
6604
6605
6606 def v1i32_indexed : BaseSIMDIndexedTied<1, U, 1, 0b10, opc,
6607 FPR32Op, FPR32Op, V128, VectorIndexS,
6608 asm, ".s", "", "", ".s", []> {
6609 bits<2> idx;
6610 let Inst{11} = idx{1};
6611 let Inst{21} = idx{0};
6612 }
6613
6614 def v1i64_indexed : BaseSIMDIndexedTied<1, U, 1, 0b11, opc,
6615 FPR64Op, FPR64Op, V128, VectorIndexD,
6616 asm, ".d", "", "", ".d", []> {
6617 bits<1> idx;
6618 let Inst{11} = idx{0};
6619 let Inst{21} = 0;
6620 }
6621}
6622
6623multiclass SIMDIndexedHS<bit U, bits<4> opc, string asm,
6624 SDPatternOperator OpNode> {
6625 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc, V64, V64,
6626 V128_lo, VectorIndexH,
6627 asm, ".4h", ".4h", ".4h", ".h",
6628 [(set (v4i16 V64:$Rd),
6629 (OpNode (v4i16 V64:$Rn),
6630 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
6631 bits<3> idx;
6632 let Inst{11} = idx{2};
6633 let Inst{21} = idx{1};
6634 let Inst{20} = idx{0};
6635 }
6636
6637 def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc,
6638 V128, V128,
6639 V128_lo, VectorIndexH,
6640 asm, ".8h", ".8h", ".8h", ".h",
6641 [(set (v8i16 V128:$Rd),
6642 (OpNode (v8i16 V128:$Rn),
6643 (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
6644 bits<3> idx;
6645 let Inst{11} = idx{2};
6646 let Inst{21} = idx{1};
6647 let Inst{20} = idx{0};
6648 }
6649
6650 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc,
6651 V64, V64,
6652 V128, VectorIndexS,
6653 asm, ".2s", ".2s", ".2s", ".s",
6654 [(set (v2i32 V64:$Rd),
6655 (OpNode (v2i32 V64:$Rn),
6656 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
6657 bits<2> idx;
6658 let Inst{11} = idx{1};
6659 let Inst{21} = idx{0};
6660 }
6661
6662 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc,
6663 V128, V128,
6664 V128, VectorIndexS,
6665 asm, ".4s", ".4s", ".4s", ".s",
6666 [(set (v4i32 V128:$Rd),
6667 (OpNode (v4i32 V128:$Rn),
6668 (v4i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
6669 bits<2> idx;
6670 let Inst{11} = idx{1};
6671 let Inst{21} = idx{0};
6672 }
6673
6674 def v1i16_indexed : BaseSIMDIndexed<1, U, 1, 0b01, opc,
6675 FPR16Op, FPR16Op, V128_lo, VectorIndexH,
6676 asm, ".h", "", "", ".h", []> {
6677 bits<3> idx;
6678 let Inst{11} = idx{2};
6679 let Inst{21} = idx{1};
6680 let Inst{20} = idx{0};
6681 }
6682
6683 def v1i32_indexed : BaseSIMDIndexed<1, U, 1, 0b10, opc,
6684 FPR32Op, FPR32Op, V128, VectorIndexS,
6685 asm, ".s", "", "", ".s",
6686 [(set (i32 FPR32Op:$Rd),
6687 (OpNode FPR32Op:$Rn,
6688 (i32 (vector_extract (v4i32 V128:$Rm),
6689 VectorIndexS:$idx))))]> {
6690 bits<2> idx;
6691 let Inst{11} = idx{1};
6692 let Inst{21} = idx{0};
6693 }
6694}
6695
6696multiclass SIMDVectorIndexedHS<bit U, bits<4> opc, string asm,
6697 SDPatternOperator OpNode> {
6698 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc,
6699 V64, V64,
6700 V128_lo, VectorIndexH,
6701 asm, ".4h", ".4h", ".4h", ".h",
6702 [(set (v4i16 V64:$Rd),
6703 (OpNode (v4i16 V64:$Rn),
6704 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
6705 bits<3> idx;
6706 let Inst{11} = idx{2};
6707 let Inst{21} = idx{1};
6708 let Inst{20} = idx{0};
6709 }
6710
6711 def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc,
6712 V128, V128,
6713 V128_lo, VectorIndexH,
6714 asm, ".8h", ".8h", ".8h", ".h",
6715 [(set (v8i16 V128:$Rd),
6716 (OpNode (v8i16 V128:$Rn),
6717 (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
6718 bits<3> idx;
6719 let Inst{11} = idx{2};
6720 let Inst{21} = idx{1};
6721 let Inst{20} = idx{0};
6722 }
6723
6724 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc,
6725 V64, V64,
6726 V128, VectorIndexS,
6727 asm, ".2s", ".2s", ".2s", ".s",
6728 [(set (v2i32 V64:$Rd),
6729 (OpNode (v2i32 V64:$Rn),
6730 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
6731 bits<2> idx;
6732 let Inst{11} = idx{1};
6733 let Inst{21} = idx{0};
6734 }
6735
6736 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc,
6737 V128, V128,
6738 V128, VectorIndexS,
6739 asm, ".4s", ".4s", ".4s", ".s",
6740 [(set (v4i32 V128:$Rd),
6741 (OpNode (v4i32 V128:$Rn),
6742 (v4i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
6743 bits<2> idx;
6744 let Inst{11} = idx{1};
6745 let Inst{21} = idx{0};
6746 }
6747}
6748
6749multiclass SIMDVectorIndexedHSTied<bit U, bits<4> opc, string asm,
6750 SDPatternOperator OpNode> {
6751 def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc, V64, V64,
6752 V128_lo, VectorIndexH,
6753 asm, ".4h", ".4h", ".4h", ".h",
6754 [(set (v4i16 V64:$dst),
6755 (OpNode (v4i16 V64:$Rd),(v4i16 V64:$Rn),
6756 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
6757 bits<3> idx;
6758 let Inst{11} = idx{2};
6759 let Inst{21} = idx{1};
6760 let Inst{20} = idx{0};
6761 }
6762
6763 def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc,
6764 V128, V128,
6765 V128_lo, VectorIndexH,
6766 asm, ".8h", ".8h", ".8h", ".h",
6767 [(set (v8i16 V128:$dst),
6768 (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn),
6769 (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
6770 bits<3> idx;
6771 let Inst{11} = idx{2};
6772 let Inst{21} = idx{1};
6773 let Inst{20} = idx{0};
6774 }
6775
6776 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc,
6777 V64, V64,
6778 V128, VectorIndexS,
6779 asm, ".2s", ".2s", ".2s", ".s",
6780 [(set (v2i32 V64:$dst),
6781 (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn),
6782 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
6783 bits<2> idx;
6784 let Inst{11} = idx{1};
6785 let Inst{21} = idx{0};
6786 }
6787
6788 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc,
6789 V128, V128,
6790 V128, VectorIndexS,
6791 asm, ".4s", ".4s", ".4s", ".s",
6792 [(set (v4i32 V128:$dst),
6793 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn),
6794 (v4i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
6795 bits<2> idx;
6796 let Inst{11} = idx{1};
6797 let Inst{21} = idx{0};
6798 }
6799}
6800
6801multiclass SIMDIndexedLongSD<bit U, bits<4> opc, string asm,
6802 SDPatternOperator OpNode> {
6803 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc,
6804 V128, V64,
6805 V128_lo, VectorIndexH,
6806 asm, ".4s", ".4s", ".4h", ".h",
6807 [(set (v4i32 V128:$Rd),
6808 (OpNode (v4i16 V64:$Rn),
6809 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
6810 bits<3> idx;
6811 let Inst{11} = idx{2};
6812 let Inst{21} = idx{1};
6813 let Inst{20} = idx{0};
6814 }
6815
6816 def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc,
6817 V128, V128,
6818 V128_lo, VectorIndexH,
6819 asm#"2", ".4s", ".4s", ".8h", ".h",
6820 [(set (v4i32 V128:$Rd),
6821 (OpNode (extract_high_v8i16 V128:$Rn),
6822 (extract_high_v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm),
6823 VectorIndexH:$idx))))]> {
6824
6825 bits<3> idx;
6826 let Inst{11} = idx{2};
6827 let Inst{21} = idx{1};
6828 let Inst{20} = idx{0};
6829 }
6830
6831 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc,
6832 V128, V64,
6833 V128, VectorIndexS,
6834 asm, ".2d", ".2d", ".2s", ".s",
6835 [(set (v2i64 V128:$Rd),
6836 (OpNode (v2i32 V64:$Rn),
6837 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
6838 bits<2> idx;
6839 let Inst{11} = idx{1};
6840 let Inst{21} = idx{0};
6841 }
6842
6843 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc,
6844 V128, V128,
6845 V128, VectorIndexS,
6846 asm#"2", ".2d", ".2d", ".4s", ".s",
6847 [(set (v2i64 V128:$Rd),
6848 (OpNode (extract_high_v4i32 V128:$Rn),
6849 (extract_high_v4i32 (AArch64duplane32 (v4i32 V128:$Rm),
6850 VectorIndexS:$idx))))]> {
6851 bits<2> idx;
6852 let Inst{11} = idx{1};
6853 let Inst{21} = idx{0};
6854 }
6855
6856 def v1i32_indexed : BaseSIMDIndexed<1, U, 1, 0b01, opc,
6857 FPR32Op, FPR16Op, V128_lo, VectorIndexH,
6858 asm, ".h", "", "", ".h", []> {
6859 bits<3> idx;
6860 let Inst{11} = idx{2};
6861 let Inst{21} = idx{1};
6862 let Inst{20} = idx{0};
6863 }
6864
6865 def v1i64_indexed : BaseSIMDIndexed<1, U, 1, 0b10, opc,
6866 FPR64Op, FPR32Op, V128, VectorIndexS,
6867 asm, ".s", "", "", ".s", []> {
6868 bits<2> idx;
6869 let Inst{11} = idx{1};
6870 let Inst{21} = idx{0};
6871 }
6872}
6873
6874multiclass SIMDIndexedLongSQDMLXSDTied<bit U, bits<4> opc, string asm,
6875 SDPatternOperator Accum> {
6876 def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc,
6877 V128, V64,
6878 V128_lo, VectorIndexH,
6879 asm, ".4s", ".4s", ".4h", ".h",
6880 [(set (v4i32 V128:$dst),
6881 (Accum (v4i32 V128:$Rd),
6882 (v4i32 (int_aarch64_neon_sqdmull
6883 (v4i16 V64:$Rn),
6884 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm),
6885 VectorIndexH:$idx))))))]> {
6886 bits<3> idx;
6887 let Inst{11} = idx{2};
6888 let Inst{21} = idx{1};
6889 let Inst{20} = idx{0};
6890 }
6891
6892 // FIXME: it would be nice to use the scalar (v1i32) instruction here, but an
6893 // intermediate EXTRACT_SUBREG would be untyped.
6894 def : Pat<(i32 (Accum (i32 FPR32Op:$Rd),
6895 (i32 (vector_extract (v4i32
6896 (int_aarch64_neon_sqdmull (v4i16 V64:$Rn),
6897 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm),
6898 VectorIndexH:$idx)))),
6899 (i64 0))))),
6900 (EXTRACT_SUBREG
6901 (!cast<Instruction>(NAME # v4i16_indexed)
6902 (SUBREG_TO_REG (i32 0), FPR32Op:$Rd, ssub), V64:$Rn,
6903 V128_lo:$Rm, VectorIndexH:$idx),
6904 ssub)>;
6905
6906 def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc,
6907 V128, V128,
6908 V128_lo, VectorIndexH,
6909 asm#"2", ".4s", ".4s", ".8h", ".h",
6910 [(set (v4i32 V128:$dst),
6911 (Accum (v4i32 V128:$Rd),
6912 (v4i32 (int_aarch64_neon_sqdmull
6913 (extract_high_v8i16 V128:$Rn),
6914 (extract_high_v8i16
6915 (AArch64duplane16 (v8i16 V128_lo:$Rm),
6916 VectorIndexH:$idx))))))]> {
6917 bits<3> idx;
6918 let Inst{11} = idx{2};
6919 let Inst{21} = idx{1};
6920 let Inst{20} = idx{0};
6921 }
6922
6923 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc,
6924 V128, V64,
6925 V128, VectorIndexS,
6926 asm, ".2d", ".2d", ".2s", ".s",
6927 [(set (v2i64 V128:$dst),
6928 (Accum (v2i64 V128:$Rd),
6929 (v2i64 (int_aarch64_neon_sqdmull
6930 (v2i32 V64:$Rn),
6931 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm),
6932 VectorIndexS:$idx))))))]> {
6933 bits<2> idx;
6934 let Inst{11} = idx{1};
6935 let Inst{21} = idx{0};
6936 }
6937
6938 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc,
6939 V128, V128,
6940 V128, VectorIndexS,
6941 asm#"2", ".2d", ".2d", ".4s", ".s",
6942 [(set (v2i64 V128:$dst),
6943 (Accum (v2i64 V128:$Rd),
6944 (v2i64 (int_aarch64_neon_sqdmull
6945 (extract_high_v4i32 V128:$Rn),
6946 (extract_high_v4i32
6947 (AArch64duplane32 (v4i32 V128:$Rm),
6948 VectorIndexS:$idx))))))]> {
6949 bits<2> idx;
6950 let Inst{11} = idx{1};
6951 let Inst{21} = idx{0};
6952 }
6953
6954 def v1i32_indexed : BaseSIMDIndexedTied<1, U, 1, 0b01, opc,
6955 FPR32Op, FPR16Op, V128_lo, VectorIndexH,
6956 asm, ".h", "", "", ".h", []> {
6957 bits<3> idx;
6958 let Inst{11} = idx{2};
6959 let Inst{21} = idx{1};
6960 let Inst{20} = idx{0};
6961 }
6962
6963
6964 def v1i64_indexed : BaseSIMDIndexedTied<1, U, 1, 0b10, opc,
6965 FPR64Op, FPR32Op, V128, VectorIndexS,
6966 asm, ".s", "", "", ".s",
6967 [(set (i64 FPR64Op:$dst),
6968 (Accum (i64 FPR64Op:$Rd),
6969 (i64 (int_aarch64_neon_sqdmulls_scalar
6970 (i32 FPR32Op:$Rn),
6971 (i32 (vector_extract (v4i32 V128:$Rm),
6972 VectorIndexS:$idx))))))]> {
6973
6974 bits<2> idx;
6975 let Inst{11} = idx{1};
6976 let Inst{21} = idx{0};
6977 }
6978}
6979
6980multiclass SIMDVectorIndexedLongSD<bit U, bits<4> opc, string asm,
6981 SDPatternOperator OpNode> {
6982 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
6983 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc,
6984 V128, V64,
6985 V128_lo, VectorIndexH,
6986 asm, ".4s", ".4s", ".4h", ".h",
6987 [(set (v4i32 V128:$Rd),
6988 (OpNode (v4i16 V64:$Rn),
6989 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
6990 bits<3> idx;
6991 let Inst{11} = idx{2};
6992 let Inst{21} = idx{1};
6993 let Inst{20} = idx{0};
6994 }
6995
6996 def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc,
6997 V128, V128,
6998 V128_lo, VectorIndexH,
6999 asm#"2", ".4s", ".4s", ".8h", ".h",
7000 [(set (v4i32 V128:$Rd),
7001 (OpNode (extract_high_v8i16 V128:$Rn),
7002 (extract_high_v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm),
7003 VectorIndexH:$idx))))]> {
7004
7005 bits<3> idx;
7006 let Inst{11} = idx{2};
7007 let Inst{21} = idx{1};
7008 let Inst{20} = idx{0};
7009 }
7010
7011 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc,
7012 V128, V64,
7013 V128, VectorIndexS,
7014 asm, ".2d", ".2d", ".2s", ".s",
7015 [(set (v2i64 V128:$Rd),
7016 (OpNode (v2i32 V64:$Rn),
7017 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
7018 bits<2> idx;
7019 let Inst{11} = idx{1};
7020 let Inst{21} = idx{0};
7021 }
7022
7023 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc,
7024 V128, V128,
7025 V128, VectorIndexS,
7026 asm#"2", ".2d", ".2d", ".4s", ".s",
7027 [(set (v2i64 V128:$Rd),
7028 (OpNode (extract_high_v4i32 V128:$Rn),
7029 (extract_high_v4i32 (AArch64duplane32 (v4i32 V128:$Rm),
7030 VectorIndexS:$idx))))]> {
7031 bits<2> idx;
7032 let Inst{11} = idx{1};
7033 let Inst{21} = idx{0};
7034 }
7035 }
7036}
7037
7038multiclass SIMDVectorIndexedLongSDTied<bit U, bits<4> opc, string asm,
7039 SDPatternOperator OpNode> {
7040 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
7041 def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc,
7042 V128, V64,
7043 V128_lo, VectorIndexH,
7044 asm, ".4s", ".4s", ".4h", ".h",
7045 [(set (v4i32 V128:$dst),
7046 (OpNode (v4i32 V128:$Rd), (v4i16 V64:$Rn),
7047 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
7048 bits<3> idx;
7049 let Inst{11} = idx{2};
7050 let Inst{21} = idx{1};
7051 let Inst{20} = idx{0};
7052 }
7053
7054 def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc,
7055 V128, V128,
7056 V128_lo, VectorIndexH,
7057 asm#"2", ".4s", ".4s", ".8h", ".h",
7058 [(set (v4i32 V128:$dst),
7059 (OpNode (v4i32 V128:$Rd),
7060 (extract_high_v8i16 V128:$Rn),
7061 (extract_high_v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm),
7062 VectorIndexH:$idx))))]> {
7063 bits<3> idx;
7064 let Inst{11} = idx{2};
7065 let Inst{21} = idx{1};
7066 let Inst{20} = idx{0};
7067 }
7068
7069 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc,
7070 V128, V64,
7071 V128, VectorIndexS,
7072 asm, ".2d", ".2d", ".2s", ".s",
7073 [(set (v2i64 V128:$dst),
7074 (OpNode (v2i64 V128:$Rd), (v2i32 V64:$Rn),
7075 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
7076 bits<2> idx;
7077 let Inst{11} = idx{1};
7078 let Inst{21} = idx{0};
7079 }
7080
7081 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc,
7082 V128, V128,
7083 V128, VectorIndexS,
7084 asm#"2", ".2d", ".2d", ".4s", ".s",
7085 [(set (v2i64 V128:$dst),
7086 (OpNode (v2i64 V128:$Rd),
7087 (extract_high_v4i32 V128:$Rn),
7088 (extract_high_v4i32 (AArch64duplane32 (v4i32 V128:$Rm),
7089 VectorIndexS:$idx))))]> {
7090 bits<2> idx;
7091 let Inst{11} = idx{1};
7092 let Inst{21} = idx{0};
7093 }
7094 }
7095}
7096
7097//----------------------------------------------------------------------------
7098// AdvSIMD scalar shift by immediate
7099//----------------------------------------------------------------------------
7100
7101let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
7102class BaseSIMDScalarShift<bit U, bits<5> opc, bits<7> fixed_imm,
7103 RegisterClass regtype1, RegisterClass regtype2,
7104 Operand immtype, string asm, list<dag> pattern>
7105 : I<(outs regtype1:$Rd), (ins regtype2:$Rn, immtype:$imm),
7106 asm, "\t$Rd, $Rn, $imm", "", pattern>,
7107 Sched<[WriteV]> {
7108 bits<5> Rd;
7109 bits<5> Rn;
7110 bits<7> imm;
7111 let Inst{31-30} = 0b01;
7112 let Inst{29} = U;
7113 let Inst{28-23} = 0b111110;
7114 let Inst{22-16} = fixed_imm;
7115 let Inst{15-11} = opc;
7116 let Inst{10} = 1;
7117 let Inst{9-5} = Rn;
7118 let Inst{4-0} = Rd;
7119}
7120
7121let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
7122class BaseSIMDScalarShiftTied<bit U, bits<5> opc, bits<7> fixed_imm,
7123 RegisterClass regtype1, RegisterClass regtype2,
7124 Operand immtype, string asm, list<dag> pattern>
7125 : I<(outs regtype1:$dst), (ins regtype1:$Rd, regtype2:$Rn, immtype:$imm),
7126 asm, "\t$Rd, $Rn, $imm", "$Rd = $dst", pattern>,
7127 Sched<[WriteV]> {
7128 bits<5> Rd;
7129 bits<5> Rn;
7130 bits<7> imm;
7131 let Inst{31-30} = 0b01;
7132 let Inst{29} = U;
7133 let Inst{28-23} = 0b111110;
7134 let Inst{22-16} = fixed_imm;
7135 let Inst{15-11} = opc;
7136 let Inst{10} = 1;
7137 let Inst{9-5} = Rn;
7138 let Inst{4-0} = Rd;
7139}
7140
7141
7142multiclass SIMDScalarRShiftSD<bit U, bits<5> opc, string asm> {
7143 def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?},
7144 FPR32, FPR32, vecshiftR32, asm, []> {
7145 let Inst{20-16} = imm{4-0};
7146 }
7147
7148 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?},
7149 FPR64, FPR64, vecshiftR64, asm, []> {
7150 let Inst{21-16} = imm{5-0};
7151 }
7152}
7153
7154multiclass SIMDScalarRShiftD<bit U, bits<5> opc, string asm,
7155 SDPatternOperator OpNode> {
7156 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?},
7157 FPR64, FPR64, vecshiftR64, asm,
7158 [(set (i64 FPR64:$Rd),
7159 (OpNode (i64 FPR64:$Rn), (i32 vecshiftR64:$imm)))]> {
7160 let Inst{21-16} = imm{5-0};
7161 }
7162
7163 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rn), (i32 vecshiftR64:$imm))),
7164 (!cast<Instruction>(NAME # "d") FPR64:$Rn, vecshiftR64:$imm)>;
7165}
7166
7167multiclass SIMDScalarRShiftDTied<bit U, bits<5> opc, string asm,
7168 SDPatternOperator OpNode = null_frag> {
7169 def d : BaseSIMDScalarShiftTied<U, opc, {1,?,?,?,?,?,?},
7170 FPR64, FPR64, vecshiftR64, asm,
7171 [(set (i64 FPR64:$dst), (OpNode (i64 FPR64:$Rd), (i64 FPR64:$Rn),
7172 (i32 vecshiftR64:$imm)))]> {
7173 let Inst{21-16} = imm{5-0};
7174 }
7175
7176 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rd), (v1i64 FPR64:$Rn),
7177 (i32 vecshiftR64:$imm))),
7178 (!cast<Instruction>(NAME # "d") FPR64:$Rd, FPR64:$Rn,
7179 vecshiftR64:$imm)>;
7180}
7181
7182multiclass SIMDScalarLShiftD<bit U, bits<5> opc, string asm,
7183 SDPatternOperator OpNode> {
7184 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?},
7185 FPR64, FPR64, vecshiftL64, asm,
7186 [(set (v1i64 FPR64:$Rd),
7187 (OpNode (v1i64 FPR64:$Rn), (i32 vecshiftL64:$imm)))]> {
7188 let Inst{21-16} = imm{5-0};
7189 }
7190}
7191
7192let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
7193multiclass SIMDScalarLShiftDTied<bit U, bits<5> opc, string asm> {
7194 def d : BaseSIMDScalarShiftTied<U, opc, {1,?,?,?,?,?,?},
7195 FPR64, FPR64, vecshiftL64, asm, []> {
7196 let Inst{21-16} = imm{5-0};
7197 }
7198}
7199
7200let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
7201multiclass SIMDScalarRShiftBHS<bit U, bits<5> opc, string asm,
7202 SDPatternOperator OpNode = null_frag> {
7203 def b : BaseSIMDScalarShift<U, opc, {0,0,0,1,?,?,?},
7204 FPR8, FPR16, vecshiftR8, asm, []> {
7205 let Inst{18-16} = imm{2-0};
7206 }
7207
7208 def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?},
7209 FPR16, FPR32, vecshiftR16, asm, []> {
7210 let Inst{19-16} = imm{3-0};
7211 }
7212
7213 def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?},
7214 FPR32, FPR64, vecshiftR32, asm,
7215 [(set (i32 FPR32:$Rd), (OpNode (i64 FPR64:$Rn), vecshiftR32:$imm))]> {
7216 let Inst{20-16} = imm{4-0};
7217 }
7218}
7219
7220multiclass SIMDScalarLShiftBHSD<bit U, bits<5> opc, string asm,
7221 SDPatternOperator OpNode> {
7222 def b : BaseSIMDScalarShift<U, opc, {0,0,0,1,?,?,?},
7223 FPR8, FPR8, vecshiftL8, asm, []> {
7224 let Inst{18-16} = imm{2-0};
7225 }
7226
7227 def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?},
7228 FPR16, FPR16, vecshiftL16, asm, []> {
7229 let Inst{19-16} = imm{3-0};
7230 }
7231
7232 def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?},
7233 FPR32, FPR32, vecshiftL32, asm,
7234 [(set (i32 FPR32:$Rd), (OpNode (i32 FPR32:$Rn), (i32 vecshiftL32:$imm)))]> {
7235 let Inst{20-16} = imm{4-0};
7236 }
7237
7238 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?},
7239 FPR64, FPR64, vecshiftL64, asm,
7240 [(set (i64 FPR64:$Rd), (OpNode (i64 FPR64:$Rn), (i32 vecshiftL64:$imm)))]> {
7241 let Inst{21-16} = imm{5-0};
7242 }
7243
7244 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rn), (i32 vecshiftL64:$imm))),
7245 (!cast<Instruction>(NAME # "d") FPR64:$Rn, vecshiftL64:$imm)>;
7246}
7247
7248multiclass SIMDScalarRShiftBHSD<bit U, bits<5> opc, string asm> {
7249 def b : BaseSIMDScalarShift<U, opc, {0,0,0,1,?,?,?},
7250 FPR8, FPR8, vecshiftR8, asm, []> {
7251 let Inst{18-16} = imm{2-0};
7252 }
7253
7254 def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?},
7255 FPR16, FPR16, vecshiftR16, asm, []> {
7256 let Inst{19-16} = imm{3-0};
7257 }
7258
7259 def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?},
7260 FPR32, FPR32, vecshiftR32, asm, []> {
7261 let Inst{20-16} = imm{4-0};
7262 }
7263
7264 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?},
7265 FPR64, FPR64, vecshiftR64, asm, []> {
7266 let Inst{21-16} = imm{5-0};
7267 }
7268}
7269
7270//----------------------------------------------------------------------------
7271// AdvSIMD vector x indexed element
7272//----------------------------------------------------------------------------
7273
7274let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
7275class BaseSIMDVectorShift<bit Q, bit U, bits<5> opc, bits<7> fixed_imm,
7276 RegisterOperand dst_reg, RegisterOperand src_reg,
7277 Operand immtype,
7278 string asm, string dst_kind, string src_kind,
7279 list<dag> pattern>
7280 : I<(outs dst_reg:$Rd), (ins src_reg:$Rn, immtype:$imm),
7281 asm, "{\t$Rd" # dst_kind # ", $Rn" # src_kind # ", $imm" #
7282 "|" # dst_kind # "\t$Rd, $Rn, $imm}", "", pattern>,
7283 Sched<[WriteV]> {
7284 bits<5> Rd;
7285 bits<5> Rn;
7286 let Inst{31} = 0;
7287 let Inst{30} = Q;
7288 let Inst{29} = U;
7289 let Inst{28-23} = 0b011110;
7290 let Inst{22-16} = fixed_imm;
7291 let Inst{15-11} = opc;
7292 let Inst{10} = 1;
7293 let Inst{9-5} = Rn;
7294 let Inst{4-0} = Rd;
7295}
7296
7297let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
7298class BaseSIMDVectorShiftTied<bit Q, bit U, bits<5> opc, bits<7> fixed_imm,
7299 RegisterOperand vectype1, RegisterOperand vectype2,
7300 Operand immtype,
7301 string asm, string dst_kind, string src_kind,
7302 list<dag> pattern>
7303 : I<(outs vectype1:$dst), (ins vectype1:$Rd, vectype2:$Rn, immtype:$imm),
7304 asm, "{\t$Rd" # dst_kind # ", $Rn" # src_kind # ", $imm" #
7305 "|" # dst_kind # "\t$Rd, $Rn, $imm}", "$Rd = $dst", pattern>,
7306 Sched<[WriteV]> {
7307 bits<5> Rd;
7308 bits<5> Rn;
7309 let Inst{31} = 0;
7310 let Inst{30} = Q;
7311 let Inst{29} = U;
7312 let Inst{28-23} = 0b011110;
7313 let Inst{22-16} = fixed_imm;
7314 let Inst{15-11} = opc;
7315 let Inst{10} = 1;
7316 let Inst{9-5} = Rn;
7317 let Inst{4-0} = Rd;
7318}
7319
7320multiclass SIMDVectorRShiftSD<bit U, bits<5> opc, string asm,
7321 Intrinsic OpNode> {
7322 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?},
7323 V64, V64, vecshiftR32,
7324 asm, ".2s", ".2s",
7325 [(set (v2i32 V64:$Rd), (OpNode (v2f32 V64:$Rn), (i32 imm:$imm)))]> {
7326 bits<5> imm;
7327 let Inst{20-16} = imm;
7328 }
7329
7330 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?},
7331 V128, V128, vecshiftR32,
7332 asm, ".4s", ".4s",
7333 [(set (v4i32 V128:$Rd), (OpNode (v4f32 V128:$Rn), (i32 imm:$imm)))]> {
7334 bits<5> imm;
7335 let Inst{20-16} = imm;
7336 }
7337
7338 def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?},
7339 V128, V128, vecshiftR64,
7340 asm, ".2d", ".2d",
7341 [(set (v2i64 V128:$Rd), (OpNode (v2f64 V128:$Rn), (i32 imm:$imm)))]> {
7342 bits<6> imm;
7343 let Inst{21-16} = imm;
7344 }
7345}
7346
7347multiclass SIMDVectorRShiftSDToFP<bit U, bits<5> opc, string asm,
7348 Intrinsic OpNode> {
7349 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?},
7350 V64, V64, vecshiftR32,
7351 asm, ".2s", ".2s",
7352 [(set (v2f32 V64:$Rd), (OpNode (v2i32 V64:$Rn), (i32 imm:$imm)))]> {
7353 bits<5> imm;
7354 let Inst{20-16} = imm;
7355 }
7356
7357 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?},
7358 V128, V128, vecshiftR32,
7359 asm, ".4s", ".4s",
7360 [(set (v4f32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (i32 imm:$imm)))]> {
7361 bits<5> imm;
7362 let Inst{20-16} = imm;
7363 }
7364
7365 def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?},
7366 V128, V128, vecshiftR64,
7367 asm, ".2d", ".2d",
7368 [(set (v2f64 V128:$Rd), (OpNode (v2i64 V128:$Rn), (i32 imm:$imm)))]> {
7369 bits<6> imm;
7370 let Inst{21-16} = imm;
7371 }
7372}
7373
7374multiclass SIMDVectorRShiftNarrowBHS<bit U, bits<5> opc, string asm,
7375 SDPatternOperator OpNode> {
7376 def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?},
7377 V64, V128, vecshiftR16Narrow,
7378 asm, ".8b", ".8h",
7379 [(set (v8i8 V64:$Rd), (OpNode (v8i16 V128:$Rn), vecshiftR16Narrow:$imm))]> {
7380 bits<3> imm;
7381 let Inst{18-16} = imm;
7382 }
7383
7384 def v16i8_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,0,1,?,?,?},
7385 V128, V128, vecshiftR16Narrow,
7386 asm#"2", ".16b", ".8h", []> {
7387 bits<3> imm;
7388 let Inst{18-16} = imm;
7389 let hasSideEffects = 0;
7390 }
7391
7392 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?},
7393 V64, V128, vecshiftR32Narrow,
7394 asm, ".4h", ".4s",
7395 [(set (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn), vecshiftR32Narrow:$imm))]> {
7396 bits<4> imm;
7397 let Inst{19-16} = imm;
7398 }
7399
7400 def v8i16_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,1,?,?,?,?},
7401 V128, V128, vecshiftR32Narrow,
7402 asm#"2", ".8h", ".4s", []> {
7403 bits<4> imm;
7404 let Inst{19-16} = imm;
7405 let hasSideEffects = 0;
7406 }
7407
7408 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?},
7409 V64, V128, vecshiftR64Narrow,
7410 asm, ".2s", ".2d",
7411 [(set (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn), vecshiftR64Narrow:$imm))]> {
7412 bits<5> imm;
7413 let Inst{20-16} = imm;
7414 }
7415
7416 def v4i32_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,1,?,?,?,?,?},
7417 V128, V128, vecshiftR64Narrow,
7418 asm#"2", ".4s", ".2d", []> {
7419 bits<5> imm;
7420 let Inst{20-16} = imm;
7421 let hasSideEffects = 0;
7422 }
7423
7424 // TableGen doesn't like patters w/ INSERT_SUBREG on the instructions
7425 // themselves, so put them here instead.
7426
7427 // Patterns involving what's effectively an insert high and a normal
7428 // intrinsic, represented by CONCAT_VECTORS.
7429 def : Pat<(concat_vectors (v8i8 V64:$Rd),(OpNode (v8i16 V128:$Rn),
7430 vecshiftR16Narrow:$imm)),
7431 (!cast<Instruction>(NAME # "v16i8_shift")
7432 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub),
7433 V128:$Rn, vecshiftR16Narrow:$imm)>;
7434 def : Pat<(concat_vectors (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn),
7435 vecshiftR32Narrow:$imm)),
7436 (!cast<Instruction>(NAME # "v8i16_shift")
7437 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub),
7438 V128:$Rn, vecshiftR32Narrow:$imm)>;
7439 def : Pat<(concat_vectors (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn),
7440 vecshiftR64Narrow:$imm)),
7441 (!cast<Instruction>(NAME # "v4i32_shift")
7442 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub),
7443 V128:$Rn, vecshiftR64Narrow:$imm)>;
7444}
7445
7446multiclass SIMDVectorLShiftBHSD<bit U, bits<5> opc, string asm,
7447 SDPatternOperator OpNode> {
7448 def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?},
7449 V64, V64, vecshiftL8,
7450 asm, ".8b", ".8b",
7451 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn),
7452 (i32 vecshiftL8:$imm)))]> {
7453 bits<3> imm;
7454 let Inst{18-16} = imm;
7455 }
7456
7457 def v16i8_shift : BaseSIMDVectorShift<1, U, opc, {0,0,0,1,?,?,?},
7458 V128, V128, vecshiftL8,
7459 asm, ".16b", ".16b",
7460 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn),
7461 (i32 vecshiftL8:$imm)))]> {
7462 bits<3> imm;
7463 let Inst{18-16} = imm;
7464 }
7465
7466 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?},
7467 V64, V64, vecshiftL16,
7468 asm, ".4h", ".4h",
7469 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn),
7470 (i32 vecshiftL16:$imm)))]> {
7471 bits<4> imm;
7472 let Inst{19-16} = imm;
7473 }
7474
7475 def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?},
7476 V128, V128, vecshiftL16,
7477 asm, ".8h", ".8h",
7478 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn),
7479 (i32 vecshiftL16:$imm)))]> {
7480 bits<4> imm;
7481 let Inst{19-16} = imm;
7482 }
7483
7484 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?},
7485 V64, V64, vecshiftL32,
7486 asm, ".2s", ".2s",
7487 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn),
7488 (i32 vecshiftL32:$imm)))]> {
7489 bits<5> imm;
7490 let Inst{20-16} = imm;
7491 }
7492
7493 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?},
7494 V128, V128, vecshiftL32,
7495 asm, ".4s", ".4s",
7496 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn),
7497 (i32 vecshiftL32:$imm)))]> {
7498 bits<5> imm;
7499 let Inst{20-16} = imm;
7500 }
7501
7502 def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?},
7503 V128, V128, vecshiftL64,
7504 asm, ".2d", ".2d",
7505 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn),
7506 (i32 vecshiftL64:$imm)))]> {
7507 bits<6> imm;
7508 let Inst{21-16} = imm;
7509 }
7510}
7511
7512multiclass SIMDVectorRShiftBHSD<bit U, bits<5> opc, string asm,
7513 SDPatternOperator OpNode> {
7514 def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?},
7515 V64, V64, vecshiftR8,
7516 asm, ".8b", ".8b",
7517 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn),
7518 (i32 vecshiftR8:$imm)))]> {
7519 bits<3> imm;
7520 let Inst{18-16} = imm;
7521 }
7522
7523 def v16i8_shift : BaseSIMDVectorShift<1, U, opc, {0,0,0,1,?,?,?},
7524 V128, V128, vecshiftR8,
7525 asm, ".16b", ".16b",
7526 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn),
7527 (i32 vecshiftR8:$imm)))]> {
7528 bits<3> imm;
7529 let Inst{18-16} = imm;
7530 }
7531
7532 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?},
7533 V64, V64, vecshiftR16,
7534 asm, ".4h", ".4h",
7535 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn),
7536 (i32 vecshiftR16:$imm)))]> {
7537 bits<4> imm;
7538 let Inst{19-16} = imm;
7539 }
7540
7541 def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?},
7542 V128, V128, vecshiftR16,
7543 asm, ".8h", ".8h",
7544 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn),
7545 (i32 vecshiftR16:$imm)))]> {
7546 bits<4> imm;
7547 let Inst{19-16} = imm;
7548 }
7549
7550 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?},
7551 V64, V64, vecshiftR32,
7552 asm, ".2s", ".2s",
7553 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn),
7554 (i32 vecshiftR32:$imm)))]> {
7555 bits<5> imm;
7556 let Inst{20-16} = imm;
7557 }
7558
7559 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?},
7560 V128, V128, vecshiftR32,
7561 asm, ".4s", ".4s",
7562 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn),
7563 (i32 vecshiftR32:$imm)))]> {
7564 bits<5> imm;
7565 let Inst{20-16} = imm;
7566 }
7567
7568 def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?},
7569 V128, V128, vecshiftR64,
7570 asm, ".2d", ".2d",
7571 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn),
7572 (i32 vecshiftR64:$imm)))]> {
7573 bits<6> imm;
7574 let Inst{21-16} = imm;
7575 }
7576}
7577
7578let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
7579multiclass SIMDVectorRShiftBHSDTied<bit U, bits<5> opc, string asm,
7580 SDPatternOperator OpNode = null_frag> {
7581 def v8i8_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,0,1,?,?,?},
7582 V64, V64, vecshiftR8, asm, ".8b", ".8b",
7583 [(set (v8i8 V64:$dst),
7584 (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn),
7585 (i32 vecshiftR8:$imm)))]> {
7586 bits<3> imm;
7587 let Inst{18-16} = imm;
7588 }
7589
7590 def v16i8_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,0,1,?,?,?},
7591 V128, V128, vecshiftR8, asm, ".16b", ".16b",
7592 [(set (v16i8 V128:$dst),
7593 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn),
7594 (i32 vecshiftR8:$imm)))]> {
7595 bits<3> imm;
7596 let Inst{18-16} = imm;
7597 }
7598
7599 def v4i16_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,1,?,?,?,?},
7600 V64, V64, vecshiftR16, asm, ".4h", ".4h",
7601 [(set (v4i16 V64:$dst),
7602 (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn),
7603 (i32 vecshiftR16:$imm)))]> {
7604 bits<4> imm;
7605 let Inst{19-16} = imm;
7606 }
7607
7608 def v8i16_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,1,?,?,?,?},
7609 V128, V128, vecshiftR16, asm, ".8h", ".8h",
7610 [(set (v8i16 V128:$dst),
7611 (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn),
7612 (i32 vecshiftR16:$imm)))]> {
7613 bits<4> imm;
7614 let Inst{19-16} = imm;
7615 }
7616
7617 def v2i32_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,1,?,?,?,?,?},
7618 V64, V64, vecshiftR32, asm, ".2s", ".2s",
7619 [(set (v2i32 V64:$dst),
7620 (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn),
7621 (i32 vecshiftR32:$imm)))]> {
7622 bits<5> imm;
7623 let Inst{20-16} = imm;
7624 }
7625
7626 def v4i32_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,1,?,?,?,?,?},
7627 V128, V128, vecshiftR32, asm, ".4s", ".4s",
7628 [(set (v4i32 V128:$dst),
7629 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn),
7630 (i32 vecshiftR32:$imm)))]> {
7631 bits<5> imm;
7632 let Inst{20-16} = imm;
7633 }
7634
7635 def v2i64_shift : BaseSIMDVectorShiftTied<1, U, opc, {1,?,?,?,?,?,?},
7636 V128, V128, vecshiftR64,
7637 asm, ".2d", ".2d", [(set (v2i64 V128:$dst),
7638 (OpNode (v2i64 V128:$Rd), (v2i64 V128:$Rn),
7639 (i32 vecshiftR64:$imm)))]> {
7640 bits<6> imm;
7641 let Inst{21-16} = imm;
7642 }
7643}
7644
7645multiclass SIMDVectorLShiftBHSDTied<bit U, bits<5> opc, string asm,
7646 SDPatternOperator OpNode = null_frag> {
7647 def v8i8_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,0,1,?,?,?},
7648 V64, V64, vecshiftL8,
7649 asm, ".8b", ".8b",
7650 [(set (v8i8 V64:$dst),
7651 (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn),
7652 (i32 vecshiftL8:$imm)))]> {
7653 bits<3> imm;
7654 let Inst{18-16} = imm;
7655 }
7656
7657 def v16i8_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,0,1,?,?,?},
7658 V128, V128, vecshiftL8,
7659 asm, ".16b", ".16b",
7660 [(set (v16i8 V128:$dst),
7661 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn),
7662 (i32 vecshiftL8:$imm)))]> {
7663 bits<3> imm;
7664 let Inst{18-16} = imm;
7665 }
7666
7667 def v4i16_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,1,?,?,?,?},
7668 V64, V64, vecshiftL16,
7669 asm, ".4h", ".4h",
7670 [(set (v4i16 V64:$dst),
7671 (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn),
7672 (i32 vecshiftL16:$imm)))]> {
7673 bits<4> imm;
7674 let Inst{19-16} = imm;
7675 }
7676
7677 def v8i16_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,1,?,?,?,?},
7678 V128, V128, vecshiftL16,
7679 asm, ".8h", ".8h",
7680 [(set (v8i16 V128:$dst),
7681 (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn),
7682 (i32 vecshiftL16:$imm)))]> {
7683 bits<4> imm;
7684 let Inst{19-16} = imm;
7685 }
7686
7687 def v2i32_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,1,?,?,?,?,?},
7688 V64, V64, vecshiftL32,
7689 asm, ".2s", ".2s",
7690 [(set (v2i32 V64:$dst),
7691 (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn),
7692 (i32 vecshiftL32:$imm)))]> {
7693 bits<5> imm;
7694 let Inst{20-16} = imm;
7695 }
7696
7697 def v4i32_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,1,?,?,?,?,?},
7698 V128, V128, vecshiftL32,
7699 asm, ".4s", ".4s",
7700 [(set (v4i32 V128:$dst),
7701 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn),
7702 (i32 vecshiftL32:$imm)))]> {
7703 bits<5> imm;
7704 let Inst{20-16} = imm;
7705 }
7706
7707 def v2i64_shift : BaseSIMDVectorShiftTied<1, U, opc, {1,?,?,?,?,?,?},
7708 V128, V128, vecshiftL64,
7709 asm, ".2d", ".2d",
7710 [(set (v2i64 V128:$dst),
7711 (OpNode (v2i64 V128:$Rd), (v2i64 V128:$Rn),
7712 (i32 vecshiftL64:$imm)))]> {
7713 bits<6> imm;
7714 let Inst{21-16} = imm;
7715 }
7716}
7717
7718multiclass SIMDVectorLShiftLongBHSD<bit U, bits<5> opc, string asm,
7719 SDPatternOperator OpNode> {
7720 def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?},
7721 V128, V64, vecshiftL8, asm, ".8h", ".8b",
7722 [(set (v8i16 V128:$Rd), (OpNode (v8i8 V64:$Rn), vecshiftL8:$imm))]> {
7723 bits<3> imm;
7724 let Inst{18-16} = imm;
7725 }
7726
7727 def v16i8_shift : BaseSIMDVectorShift<1, U, opc, {0,0,0,1,?,?,?},
7728 V128, V128, vecshiftL8,
7729 asm#"2", ".8h", ".16b",
7730 [(set (v8i16 V128:$Rd),
7731 (OpNode (extract_high_v16i8 V128:$Rn), vecshiftL8:$imm))]> {
7732 bits<3> imm;
7733 let Inst{18-16} = imm;
7734 }
7735
7736 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?},
7737 V128, V64, vecshiftL16, asm, ".4s", ".4h",
7738 [(set (v4i32 V128:$Rd), (OpNode (v4i16 V64:$Rn), vecshiftL16:$imm))]> {
7739 bits<4> imm;
7740 let Inst{19-16} = imm;
7741 }
7742
7743 def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?},
7744 V128, V128, vecshiftL16,
7745 asm#"2", ".4s", ".8h",
7746 [(set (v4i32 V128:$Rd),
7747 (OpNode (extract_high_v8i16 V128:$Rn), vecshiftL16:$imm))]> {
7748
7749 bits<4> imm;
7750 let Inst{19-16} = imm;
7751 }
7752
7753 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?},
7754 V128, V64, vecshiftL32, asm, ".2d", ".2s",
7755 [(set (v2i64 V128:$Rd), (OpNode (v2i32 V64:$Rn), vecshiftL32:$imm))]> {
7756 bits<5> imm;
7757 let Inst{20-16} = imm;
7758 }
7759
7760 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?},
7761 V128, V128, vecshiftL32,
7762 asm#"2", ".2d", ".4s",
7763 [(set (v2i64 V128:$Rd),
7764 (OpNode (extract_high_v4i32 V128:$Rn), vecshiftL32:$imm))]> {
7765 bits<5> imm;
7766 let Inst{20-16} = imm;
7767 }
7768}
7769
7770
7771//---
7772// Vector load/store
7773//---
7774// SIMD ldX/stX no-index memory references don't allow the optional
7775// ", #0" constant and handle post-indexing explicitly, so we use
7776// a more specialized parse method for them. Otherwise, it's the same as
7777// the general GPR64sp handling.
7778
7779class BaseSIMDLdSt<bit Q, bit L, bits<4> opcode, bits<2> size,
7780 string asm, dag oops, dag iops, list<dag> pattern>
7781 : I<oops, iops, asm, "\t$Vt, [$Rn]", "", pattern> {
7782 bits<5> Vt;
7783 bits<5> Rn;
7784 let Inst{31} = 0;
7785 let Inst{30} = Q;
7786 let Inst{29-23} = 0b0011000;
7787 let Inst{22} = L;
7788 let Inst{21-16} = 0b000000;
7789 let Inst{15-12} = opcode;
7790 let Inst{11-10} = size;
7791 let Inst{9-5} = Rn;
7792 let Inst{4-0} = Vt;
7793}
7794
7795class BaseSIMDLdStPost<bit Q, bit L, bits<4> opcode, bits<2> size,
7796 string asm, dag oops, dag iops>
7797 : I<oops, iops, asm, "\t$Vt, [$Rn], $Xm", "$Rn = $wback", []> {
7798 bits<5> Vt;
7799 bits<5> Rn;
7800 bits<5> Xm;
7801 let Inst{31} = 0;
7802 let Inst{30} = Q;
7803 let Inst{29-23} = 0b0011001;
7804 let Inst{22} = L;
7805 let Inst{21} = 0;
7806 let Inst{20-16} = Xm;
7807 let Inst{15-12} = opcode;
7808 let Inst{11-10} = size;
7809 let Inst{9-5} = Rn;
7810 let Inst{4-0} = Vt;
7811}
7812
7813// The immediate form of AdvSIMD post-indexed addressing is encoded with
7814// register post-index addressing from the zero register.
7815multiclass SIMDLdStAliases<string asm, string layout, string Count,
7816 int Offset, int Size> {
7817 // E.g. "ld1 { v0.8b, v1.8b }, [x1], #16"
7818 // "ld1\t$Vt, [$Rn], #16"
7819 // may get mapped to
7820 // (LD1Twov8b_POST VecListTwo8b:$Vt, GPR64sp:$Rn, XZR)
7821 def : InstAlias<asm # "\t$Vt, [$Rn], #" # Offset,
7822 (!cast<Instruction>(NAME # Count # "v" # layout # "_POST")
7823 GPR64sp:$Rn,
7824 !cast<RegisterOperand>("VecList" # Count # layout):$Vt,
7825 XZR), 1>;
7826
7827 // E.g. "ld1.8b { v0, v1 }, [x1], #16"
7828 // "ld1.8b\t$Vt, [$Rn], #16"
7829 // may get mapped to
7830 // (LD1Twov8b_POST VecListTwo64:$Vt, GPR64sp:$Rn, XZR)
7831 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], #" # Offset,
7832 (!cast<Instruction>(NAME # Count # "v" # layout # "_POST")
7833 GPR64sp:$Rn,
7834 !cast<RegisterOperand>("VecList" # Count # Size):$Vt,
7835 XZR), 0>;
7836
7837 // E.g. "ld1.8b { v0, v1 }, [x1]"
7838 // "ld1\t$Vt, [$Rn]"
7839 // may get mapped to
7840 // (LD1Twov8b VecListTwo64:$Vt, GPR64sp:$Rn)
7841 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn]",
7842 (!cast<Instruction>(NAME # Count # "v" # layout)
7843 !cast<RegisterOperand>("VecList" # Count # Size):$Vt,
7844 GPR64sp:$Rn), 0>;
7845
7846 // E.g. "ld1.8b { v0, v1 }, [x1], x2"
7847 // "ld1\t$Vt, [$Rn], $Xm"
7848 // may get mapped to
7849 // (LD1Twov8b_POST VecListTwo64:$Vt, GPR64sp:$Rn, GPR64pi8:$Xm)
7850 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], $Xm",
7851 (!cast<Instruction>(NAME # Count # "v" # layout # "_POST")
7852 GPR64sp:$Rn,
7853 !cast<RegisterOperand>("VecList" # Count # Size):$Vt,
7854 !cast<RegisterOperand>("GPR64pi" # Offset):$Xm), 0>;
7855}
7856
7857multiclass BaseSIMDLdN<string Count, string asm, string veclist, int Offset128,
7858 int Offset64, bits<4> opcode> {
7859 let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in {
7860 def v16b: BaseSIMDLdSt<1, 1, opcode, 0b00, asm,
7861 (outs !cast<RegisterOperand>(veclist # "16b"):$Vt),
7862 (ins GPR64sp:$Rn), []>;
7863 def v8h : BaseSIMDLdSt<1, 1, opcode, 0b01, asm,
7864 (outs !cast<RegisterOperand>(veclist # "8h"):$Vt),
7865 (ins GPR64sp:$Rn), []>;
7866 def v4s : BaseSIMDLdSt<1, 1, opcode, 0b10, asm,
7867 (outs !cast<RegisterOperand>(veclist # "4s"):$Vt),
7868 (ins GPR64sp:$Rn), []>;
7869 def v2d : BaseSIMDLdSt<1, 1, opcode, 0b11, asm,
7870 (outs !cast<RegisterOperand>(veclist # "2d"):$Vt),
7871 (ins GPR64sp:$Rn), []>;
7872 def v8b : BaseSIMDLdSt<0, 1, opcode, 0b00, asm,
7873 (outs !cast<RegisterOperand>(veclist # "8b"):$Vt),
7874 (ins GPR64sp:$Rn), []>;
7875 def v4h : BaseSIMDLdSt<0, 1, opcode, 0b01, asm,
7876 (outs !cast<RegisterOperand>(veclist # "4h"):$Vt),
7877 (ins GPR64sp:$Rn), []>;
7878 def v2s : BaseSIMDLdSt<0, 1, opcode, 0b10, asm,
7879 (outs !cast<RegisterOperand>(veclist # "2s"):$Vt),
7880 (ins GPR64sp:$Rn), []>;
7881
7882
7883 def v16b_POST: BaseSIMDLdStPost<1, 1, opcode, 0b00, asm,
7884 (outs GPR64sp:$wback,
7885 !cast<RegisterOperand>(veclist # "16b"):$Vt),
7886 (ins GPR64sp:$Rn,
7887 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
7888 def v8h_POST : BaseSIMDLdStPost<1, 1, opcode, 0b01, asm,
7889 (outs GPR64sp:$wback,
7890 !cast<RegisterOperand>(veclist # "8h"):$Vt),
7891 (ins GPR64sp:$Rn,
7892 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
7893 def v4s_POST : BaseSIMDLdStPost<1, 1, opcode, 0b10, asm,
7894 (outs GPR64sp:$wback,
7895 !cast<RegisterOperand>(veclist # "4s"):$Vt),
7896 (ins GPR64sp:$Rn,
7897 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
7898 def v2d_POST : BaseSIMDLdStPost<1, 1, opcode, 0b11, asm,
7899 (outs GPR64sp:$wback,
7900 !cast<RegisterOperand>(veclist # "2d"):$Vt),
7901 (ins GPR64sp:$Rn,
7902 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
7903 def v8b_POST : BaseSIMDLdStPost<0, 1, opcode, 0b00, asm,
7904 (outs GPR64sp:$wback,
7905 !cast<RegisterOperand>(veclist # "8b"):$Vt),
7906 (ins GPR64sp:$Rn,
7907 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
7908 def v4h_POST : BaseSIMDLdStPost<0, 1, opcode, 0b01, asm,
7909 (outs GPR64sp:$wback,
7910 !cast<RegisterOperand>(veclist # "4h"):$Vt),
7911 (ins GPR64sp:$Rn,
7912 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
7913 def v2s_POST : BaseSIMDLdStPost<0, 1, opcode, 0b10, asm,
7914 (outs GPR64sp:$wback,
7915 !cast<RegisterOperand>(veclist # "2s"):$Vt),
7916 (ins GPR64sp:$Rn,
7917 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
7918 }
7919
7920 defm : SIMDLdStAliases<asm, "16b", Count, Offset128, 128>;
7921 defm : SIMDLdStAliases<asm, "8h", Count, Offset128, 128>;
7922 defm : SIMDLdStAliases<asm, "4s", Count, Offset128, 128>;
7923 defm : SIMDLdStAliases<asm, "2d", Count, Offset128, 128>;
7924 defm : SIMDLdStAliases<asm, "8b", Count, Offset64, 64>;
7925 defm : SIMDLdStAliases<asm, "4h", Count, Offset64, 64>;
7926 defm : SIMDLdStAliases<asm, "2s", Count, Offset64, 64>;
7927}
7928
7929// Only ld1/st1 has a v1d version.
7930multiclass BaseSIMDStN<string Count, string asm, string veclist, int Offset128,
7931 int Offset64, bits<4> opcode> {
7932 let hasSideEffects = 0, mayStore = 1, mayLoad = 0 in {
7933 def v16b : BaseSIMDLdSt<1, 0, opcode, 0b00, asm, (outs),
7934 (ins !cast<RegisterOperand>(veclist # "16b"):$Vt,
7935 GPR64sp:$Rn), []>;
7936 def v8h : BaseSIMDLdSt<1, 0, opcode, 0b01, asm, (outs),
7937 (ins !cast<RegisterOperand>(veclist # "8h"):$Vt,
7938 GPR64sp:$Rn), []>;
7939 def v4s : BaseSIMDLdSt<1, 0, opcode, 0b10, asm, (outs),
7940 (ins !cast<RegisterOperand>(veclist # "4s"):$Vt,
7941 GPR64sp:$Rn), []>;
7942 def v2d : BaseSIMDLdSt<1, 0, opcode, 0b11, asm, (outs),
7943 (ins !cast<RegisterOperand>(veclist # "2d"):$Vt,
7944 GPR64sp:$Rn), []>;
7945 def v8b : BaseSIMDLdSt<0, 0, opcode, 0b00, asm, (outs),
7946 (ins !cast<RegisterOperand>(veclist # "8b"):$Vt,
7947 GPR64sp:$Rn), []>;
7948 def v4h : BaseSIMDLdSt<0, 0, opcode, 0b01, asm, (outs),
7949 (ins !cast<RegisterOperand>(veclist # "4h"):$Vt,
7950 GPR64sp:$Rn), []>;
7951 def v2s : BaseSIMDLdSt<0, 0, opcode, 0b10, asm, (outs),
7952 (ins !cast<RegisterOperand>(veclist # "2s"):$Vt,
7953 GPR64sp:$Rn), []>;
7954
7955 def v16b_POST : BaseSIMDLdStPost<1, 0, opcode, 0b00, asm,
7956 (outs GPR64sp:$wback),
7957 (ins !cast<RegisterOperand>(veclist # "16b"):$Vt,
7958 GPR64sp:$Rn,
7959 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
7960 def v8h_POST : BaseSIMDLdStPost<1, 0, opcode, 0b01, asm,
7961 (outs GPR64sp:$wback),
7962 (ins !cast<RegisterOperand>(veclist # "8h"):$Vt,
7963 GPR64sp:$Rn,
7964 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
7965 def v4s_POST : BaseSIMDLdStPost<1, 0, opcode, 0b10, asm,
7966 (outs GPR64sp:$wback),
7967 (ins !cast<RegisterOperand>(veclist # "4s"):$Vt,
7968 GPR64sp:$Rn,
7969 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
7970 def v2d_POST : BaseSIMDLdStPost<1, 0, opcode, 0b11, asm,
7971 (outs GPR64sp:$wback),
7972 (ins !cast<RegisterOperand>(veclist # "2d"):$Vt,
7973 GPR64sp:$Rn,
7974 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
7975 def v8b_POST : BaseSIMDLdStPost<0, 0, opcode, 0b00, asm,
7976 (outs GPR64sp:$wback),
7977 (ins !cast<RegisterOperand>(veclist # "8b"):$Vt,
7978 GPR64sp:$Rn,
7979 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
7980 def v4h_POST : BaseSIMDLdStPost<0, 0, opcode, 0b01, asm,
7981 (outs GPR64sp:$wback),
7982 (ins !cast<RegisterOperand>(veclist # "4h"):$Vt,
7983 GPR64sp:$Rn,
7984 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
7985 def v2s_POST : BaseSIMDLdStPost<0, 0, opcode, 0b10, asm,
7986 (outs GPR64sp:$wback),
7987 (ins !cast<RegisterOperand>(veclist # "2s"):$Vt,
7988 GPR64sp:$Rn,
7989 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
7990 }
7991
7992 defm : SIMDLdStAliases<asm, "16b", Count, Offset128, 128>;
7993 defm : SIMDLdStAliases<asm, "8h", Count, Offset128, 128>;
7994 defm : SIMDLdStAliases<asm, "4s", Count, Offset128, 128>;
7995 defm : SIMDLdStAliases<asm, "2d", Count, Offset128, 128>;
7996 defm : SIMDLdStAliases<asm, "8b", Count, Offset64, 64>;
7997 defm : SIMDLdStAliases<asm, "4h", Count, Offset64, 64>;
7998 defm : SIMDLdStAliases<asm, "2s", Count, Offset64, 64>;
7999}
8000
8001multiclass BaseSIMDLd1<string Count, string asm, string veclist,
8002 int Offset128, int Offset64, bits<4> opcode>
8003 : BaseSIMDLdN<Count, asm, veclist, Offset128, Offset64, opcode> {
8004
8005 // LD1 instructions have extra "1d" variants.
8006 let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in {
8007 def v1d : BaseSIMDLdSt<0, 1, opcode, 0b11, asm,
8008 (outs !cast<RegisterOperand>(veclist # "1d"):$Vt),
8009 (ins GPR64sp:$Rn), []>;
8010
8011 def v1d_POST : BaseSIMDLdStPost<0, 1, opcode, 0b11, asm,
8012 (outs GPR64sp:$wback,
8013 !cast<RegisterOperand>(veclist # "1d"):$Vt),
8014 (ins GPR64sp:$Rn,
8015 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
8016 }
8017
8018 defm : SIMDLdStAliases<asm, "1d", Count, Offset64, 64>;
8019}
8020
8021multiclass BaseSIMDSt1<string Count, string asm, string veclist,
8022 int Offset128, int Offset64, bits<4> opcode>
8023 : BaseSIMDStN<Count, asm, veclist, Offset128, Offset64, opcode> {
8024
8025 // ST1 instructions have extra "1d" variants.
8026 let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in {
8027 def v1d : BaseSIMDLdSt<0, 0, opcode, 0b11, asm, (outs),
8028 (ins !cast<RegisterOperand>(veclist # "1d"):$Vt,
8029 GPR64sp:$Rn), []>;
8030
8031 def v1d_POST : BaseSIMDLdStPost<0, 0, opcode, 0b11, asm,
8032 (outs GPR64sp:$wback),
8033 (ins !cast<RegisterOperand>(veclist # "1d"):$Vt,
8034 GPR64sp:$Rn,
8035 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
8036 }
8037
8038 defm : SIMDLdStAliases<asm, "1d", Count, Offset64, 64>;
8039}
8040
8041multiclass SIMDLd1Multiple<string asm> {
8042 defm One : BaseSIMDLd1<"One", asm, "VecListOne", 16, 8, 0b0111>;
8043 defm Two : BaseSIMDLd1<"Two", asm, "VecListTwo", 32, 16, 0b1010>;
8044 defm Three : BaseSIMDLd1<"Three", asm, "VecListThree", 48, 24, 0b0110>;
8045 defm Four : BaseSIMDLd1<"Four", asm, "VecListFour", 64, 32, 0b0010>;
8046}
8047
8048multiclass SIMDSt1Multiple<string asm> {
8049 defm One : BaseSIMDSt1<"One", asm, "VecListOne", 16, 8, 0b0111>;
8050 defm Two : BaseSIMDSt1<"Two", asm, "VecListTwo", 32, 16, 0b1010>;
8051 defm Three : BaseSIMDSt1<"Three", asm, "VecListThree", 48, 24, 0b0110>;
8052 defm Four : BaseSIMDSt1<"Four", asm, "VecListFour", 64, 32, 0b0010>;
8053}
8054
8055multiclass SIMDLd2Multiple<string asm> {
8056 defm Two : BaseSIMDLdN<"Two", asm, "VecListTwo", 32, 16, 0b1000>;
8057}
8058
8059multiclass SIMDSt2Multiple<string asm> {
8060 defm Two : BaseSIMDStN<"Two", asm, "VecListTwo", 32, 16, 0b1000>;
8061}
8062
8063multiclass SIMDLd3Multiple<string asm> {
8064 defm Three : BaseSIMDLdN<"Three", asm, "VecListThree", 48, 24, 0b0100>;
8065}
8066
8067multiclass SIMDSt3Multiple<string asm> {
8068 defm Three : BaseSIMDStN<"Three", asm, "VecListThree", 48, 24, 0b0100>;
8069}
8070
8071multiclass SIMDLd4Multiple<string asm> {
8072 defm Four : BaseSIMDLdN<"Four", asm, "VecListFour", 64, 32, 0b0000>;
8073}
8074
8075multiclass SIMDSt4Multiple<string asm> {
8076 defm Four : BaseSIMDStN<"Four", asm, "VecListFour", 64, 32, 0b0000>;
8077}
8078
8079//---
8080// AdvSIMD Load/store single-element
8081//---
8082
8083class BaseSIMDLdStSingle<bit L, bit R, bits<3> opcode,
8084 string asm, string operands, string cst,
8085 dag oops, dag iops, list<dag> pattern>
8086 : I<oops, iops, asm, operands, cst, pattern> {
8087 bits<5> Vt;
8088 bits<5> Rn;
8089 let Inst{31} = 0;
8090 let Inst{29-24} = 0b001101;
8091 let Inst{22} = L;
8092 let Inst{21} = R;
8093 let Inst{15-13} = opcode;
8094 let Inst{9-5} = Rn;
8095 let Inst{4-0} = Vt;
8096}
8097
8098class BaseSIMDLdStSingleTied<bit L, bit R, bits<3> opcode,
8099 string asm, string operands, string cst,
8100 dag oops, dag iops, list<dag> pattern>
8101 : I<oops, iops, asm, operands, "$Vt = $dst," # cst, pattern> {
8102 bits<5> Vt;
8103 bits<5> Rn;
8104 let Inst{31} = 0;
8105 let Inst{29-24} = 0b001101;
8106 let Inst{22} = L;
8107 let Inst{21} = R;
8108 let Inst{15-13} = opcode;
8109 let Inst{9-5} = Rn;
8110 let Inst{4-0} = Vt;
8111}
8112
8113
8114let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
8115class BaseSIMDLdR<bit Q, bit R, bits<3> opcode, bit S, bits<2> size, string asm,
8116 Operand listtype>
8117 : BaseSIMDLdStSingle<1, R, opcode, asm, "\t$Vt, [$Rn]", "",
8118 (outs listtype:$Vt), (ins GPR64sp:$Rn),
8119 []> {
8120 let Inst{30} = Q;
8121 let Inst{23} = 0;
8122 let Inst{20-16} = 0b00000;
8123 let Inst{12} = S;
8124 let Inst{11-10} = size;
8125}
8126let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
8127class BaseSIMDLdRPost<bit Q, bit R, bits<3> opcode, bit S, bits<2> size,
8128 string asm, Operand listtype, Operand GPR64pi>
8129 : BaseSIMDLdStSingle<1, R, opcode, asm, "\t$Vt, [$Rn], $Xm",
8130 "$Rn = $wback",
8131 (outs GPR64sp:$wback, listtype:$Vt),
8132 (ins GPR64sp:$Rn, GPR64pi:$Xm), []> {
8133 bits<5> Xm;
8134 let Inst{30} = Q;
8135 let Inst{23} = 1;
8136 let Inst{20-16} = Xm;
8137 let Inst{12} = S;
8138 let Inst{11-10} = size;
8139}
8140
8141multiclass SIMDLdrAliases<string asm, string layout, string Count,
8142 int Offset, int Size> {
8143 // E.g. "ld1r { v0.8b }, [x1], #1"
8144 // "ld1r.8b\t$Vt, [$Rn], #1"
8145 // may get mapped to
8146 // (LD1Rv8b_POST VecListOne8b:$Vt, GPR64sp:$Rn, XZR)
8147 def : InstAlias<asm # "\t$Vt, [$Rn], #" # Offset,
8148 (!cast<Instruction>(NAME # "v" # layout # "_POST")
8149 GPR64sp:$Rn,
8150 !cast<RegisterOperand>("VecList" # Count # layout):$Vt,
8151 XZR), 1>;
8152
8153 // E.g. "ld1r.8b { v0 }, [x1], #1"
8154 // "ld1r.8b\t$Vt, [$Rn], #1"
8155 // may get mapped to
8156 // (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, XZR)
8157 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], #" # Offset,
8158 (!cast<Instruction>(NAME # "v" # layout # "_POST")
8159 GPR64sp:$Rn,
8160 !cast<RegisterOperand>("VecList" # Count # Size):$Vt,
8161 XZR), 0>;
8162
8163 // E.g. "ld1r.8b { v0 }, [x1]"
8164 // "ld1r.8b\t$Vt, [$Rn]"
8165 // may get mapped to
8166 // (LD1Rv8b VecListOne64:$Vt, GPR64sp:$Rn)
8167 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn]",
8168 (!cast<Instruction>(NAME # "v" # layout)
8169 !cast<RegisterOperand>("VecList" # Count # Size):$Vt,
8170 GPR64sp:$Rn), 0>;
8171
8172 // E.g. "ld1r.8b { v0 }, [x1], x2"
8173 // "ld1r.8b\t$Vt, [$Rn], $Xm"
8174 // may get mapped to
8175 // (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, GPR64pi1:$Xm)
8176 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], $Xm",
8177 (!cast<Instruction>(NAME # "v" # layout # "_POST")
8178 GPR64sp:$Rn,
8179 !cast<RegisterOperand>("VecList" # Count # Size):$Vt,
8180 !cast<RegisterOperand>("GPR64pi" # Offset):$Xm), 0>;
8181}
8182
8183multiclass SIMDLdR<bit R, bits<3> opcode, bit S, string asm, string Count,
8184 int Offset1, int Offset2, int Offset4, int Offset8> {
8185 def v8b : BaseSIMDLdR<0, R, opcode, S, 0b00, asm,
8186 !cast<Operand>("VecList" # Count # "8b")>;
8187 def v16b: BaseSIMDLdR<1, R, opcode, S, 0b00, asm,
8188 !cast<Operand>("VecList" # Count #"16b")>;
8189 def v4h : BaseSIMDLdR<0, R, opcode, S, 0b01, asm,
8190 !cast<Operand>("VecList" # Count #"4h")>;
8191 def v8h : BaseSIMDLdR<1, R, opcode, S, 0b01, asm,
8192 !cast<Operand>("VecList" # Count #"8h")>;
8193 def v2s : BaseSIMDLdR<0, R, opcode, S, 0b10, asm,
8194 !cast<Operand>("VecList" # Count #"2s")>;
8195 def v4s : BaseSIMDLdR<1, R, opcode, S, 0b10, asm,
8196 !cast<Operand>("VecList" # Count #"4s")>;
8197 def v1d : BaseSIMDLdR<0, R, opcode, S, 0b11, asm,
8198 !cast<Operand>("VecList" # Count #"1d")>;
8199 def v2d : BaseSIMDLdR<1, R, opcode, S, 0b11, asm,
8200 !cast<Operand>("VecList" # Count #"2d")>;
8201
8202 def v8b_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b00, asm,
8203 !cast<Operand>("VecList" # Count # "8b"),
8204 !cast<Operand>("GPR64pi" # Offset1)>;
8205 def v16b_POST: BaseSIMDLdRPost<1, R, opcode, S, 0b00, asm,
8206 !cast<Operand>("VecList" # Count # "16b"),
8207 !cast<Operand>("GPR64pi" # Offset1)>;
8208 def v4h_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b01, asm,
8209 !cast<Operand>("VecList" # Count # "4h"),
8210 !cast<Operand>("GPR64pi" # Offset2)>;
8211 def v8h_POST : BaseSIMDLdRPost<1, R, opcode, S, 0b01, asm,
8212 !cast<Operand>("VecList" # Count # "8h"),
8213 !cast<Operand>("GPR64pi" # Offset2)>;
8214 def v2s_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b10, asm,
8215 !cast<Operand>("VecList" # Count # "2s"),
8216 !cast<Operand>("GPR64pi" # Offset4)>;
8217 def v4s_POST : BaseSIMDLdRPost<1, R, opcode, S, 0b10, asm,
8218 !cast<Operand>("VecList" # Count # "4s"),
8219 !cast<Operand>("GPR64pi" # Offset4)>;
8220 def v1d_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b11, asm,
8221 !cast<Operand>("VecList" # Count # "1d"),
8222 !cast<Operand>("GPR64pi" # Offset8)>;
8223 def v2d_POST : BaseSIMDLdRPost<1, R, opcode, S, 0b11, asm,
8224 !cast<Operand>("VecList" # Count # "2d"),
8225 !cast<Operand>("GPR64pi" # Offset8)>;
8226
8227 defm : SIMDLdrAliases<asm, "8b", Count, Offset1, 64>;
8228 defm : SIMDLdrAliases<asm, "16b", Count, Offset1, 128>;
8229 defm : SIMDLdrAliases<asm, "4h", Count, Offset2, 64>;
8230 defm : SIMDLdrAliases<asm, "8h", Count, Offset2, 128>;
8231 defm : SIMDLdrAliases<asm, "2s", Count, Offset4, 64>;
8232 defm : SIMDLdrAliases<asm, "4s", Count, Offset4, 128>;
8233 defm : SIMDLdrAliases<asm, "1d", Count, Offset8, 64>;
8234 defm : SIMDLdrAliases<asm, "2d", Count, Offset8, 128>;
8235}
8236
8237class SIMDLdStSingleB<bit L, bit R, bits<3> opcode, string asm,
8238 dag oops, dag iops, list<dag> pattern>
8239 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops,
8240 pattern> {
8241 // idx encoded in Q:S:size fields.
8242 bits<4> idx;
8243 let Inst{30} = idx{3};
8244 let Inst{23} = 0;
8245 let Inst{20-16} = 0b00000;
8246 let Inst{12} = idx{2};
8247 let Inst{11-10} = idx{1-0};
8248}
8249class SIMDLdStSingleBTied<bit L, bit R, bits<3> opcode, string asm,
8250 dag oops, dag iops, list<dag> pattern>
8251 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "",
8252 oops, iops, pattern> {
8253 // idx encoded in Q:S:size fields.
8254 bits<4> idx;
8255 let Inst{30} = idx{3};
8256 let Inst{23} = 0;
8257 let Inst{20-16} = 0b00000;
8258 let Inst{12} = idx{2};
8259 let Inst{11-10} = idx{1-0};
8260}
8261class SIMDLdStSingleBPost<bit L, bit R, bits<3> opcode, string asm,
8262 dag oops, dag iops>
8263 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
8264 "$Rn = $wback", oops, iops, []> {
8265 // idx encoded in Q:S:size fields.
8266 bits<4> idx;
8267 bits<5> Xm;
8268 let Inst{30} = idx{3};
8269 let Inst{23} = 1;
8270 let Inst{20-16} = Xm;
8271 let Inst{12} = idx{2};
8272 let Inst{11-10} = idx{1-0};
8273}
8274class SIMDLdStSingleBTiedPost<bit L, bit R, bits<3> opcode, string asm,
8275 dag oops, dag iops>
8276 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
8277 "$Rn = $wback", oops, iops, []> {
8278 // idx encoded in Q:S:size fields.
8279 bits<4> idx;
8280 bits<5> Xm;
8281 let Inst{30} = idx{3};
8282 let Inst{23} = 1;
8283 let Inst{20-16} = Xm;
8284 let Inst{12} = idx{2};
8285 let Inst{11-10} = idx{1-0};
8286}
8287
8288class SIMDLdStSingleH<bit L, bit R, bits<3> opcode, bit size, string asm,
8289 dag oops, dag iops, list<dag> pattern>
8290 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops,
8291 pattern> {
8292 // idx encoded in Q:S:size<1> fields.
8293 bits<3> idx;
8294 let Inst{30} = idx{2};
8295 let Inst{23} = 0;
8296 let Inst{20-16} = 0b00000;
8297 let Inst{12} = idx{1};
8298 let Inst{11} = idx{0};
8299 let Inst{10} = size;
8300}
8301class SIMDLdStSingleHTied<bit L, bit R, bits<3> opcode, bit size, string asm,
8302 dag oops, dag iops, list<dag> pattern>
8303 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "",
8304 oops, iops, pattern> {
8305 // idx encoded in Q:S:size<1> fields.
8306 bits<3> idx;
8307 let Inst{30} = idx{2};
8308 let Inst{23} = 0;
8309 let Inst{20-16} = 0b00000;
8310 let Inst{12} = idx{1};
8311 let Inst{11} = idx{0};
8312 let Inst{10} = size;
8313}
8314
8315class SIMDLdStSingleHPost<bit L, bit R, bits<3> opcode, bit size, string asm,
8316 dag oops, dag iops>
8317 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
8318 "$Rn = $wback", oops, iops, []> {
8319 // idx encoded in Q:S:size<1> fields.
8320 bits<3> idx;
8321 bits<5> Xm;
8322 let Inst{30} = idx{2};
8323 let Inst{23} = 1;
8324 let Inst{20-16} = Xm;
8325 let Inst{12} = idx{1};
8326 let Inst{11} = idx{0};
8327 let Inst{10} = size;
8328}
8329class SIMDLdStSingleHTiedPost<bit L, bit R, bits<3> opcode, bit size, string asm,
8330 dag oops, dag iops>
8331 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
8332 "$Rn = $wback", oops, iops, []> {
8333 // idx encoded in Q:S:size<1> fields.
8334 bits<3> idx;
8335 bits<5> Xm;
8336 let Inst{30} = idx{2};
8337 let Inst{23} = 1;
8338 let Inst{20-16} = Xm;
8339 let Inst{12} = idx{1};
8340 let Inst{11} = idx{0};
8341 let Inst{10} = size;
8342}
8343class SIMDLdStSingleS<bit L, bit R, bits<3> opcode, bits<2> size, string asm,
8344 dag oops, dag iops, list<dag> pattern>
8345 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops,
8346 pattern> {
8347 // idx encoded in Q:S fields.
8348 bits<2> idx;
8349 let Inst{30} = idx{1};
8350 let Inst{23} = 0;
8351 let Inst{20-16} = 0b00000;
8352 let Inst{12} = idx{0};
8353 let Inst{11-10} = size;
8354}
8355class SIMDLdStSingleSTied<bit L, bit R, bits<3> opcode, bits<2> size, string asm,
8356 dag oops, dag iops, list<dag> pattern>
8357 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "",
8358 oops, iops, pattern> {
8359 // idx encoded in Q:S fields.
8360 bits<2> idx;
8361 let Inst{30} = idx{1};
8362 let Inst{23} = 0;
8363 let Inst{20-16} = 0b00000;
8364 let Inst{12} = idx{0};
8365 let Inst{11-10} = size;
8366}
8367class SIMDLdStSingleSPost<bit L, bit R, bits<3> opcode, bits<2> size,
8368 string asm, dag oops, dag iops>
8369 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
8370 "$Rn = $wback", oops, iops, []> {
8371 // idx encoded in Q:S fields.
8372 bits<2> idx;
8373 bits<5> Xm;
8374 let Inst{30} = idx{1};
8375 let Inst{23} = 1;
8376 let Inst{20-16} = Xm;
8377 let Inst{12} = idx{0};
8378 let Inst{11-10} = size;
8379}
8380class SIMDLdStSingleSTiedPost<bit L, bit R, bits<3> opcode, bits<2> size,
8381 string asm, dag oops, dag iops>
8382 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
8383 "$Rn = $wback", oops, iops, []> {
8384 // idx encoded in Q:S fields.
8385 bits<2> idx;
8386 bits<5> Xm;
8387 let Inst{30} = idx{1};
8388 let Inst{23} = 1;
8389 let Inst{20-16} = Xm;
8390 let Inst{12} = idx{0};
8391 let Inst{11-10} = size;
8392}
8393class SIMDLdStSingleD<bit L, bit R, bits<3> opcode, bits<2> size, string asm,
8394 dag oops, dag iops, list<dag> pattern>
8395 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops,
8396 pattern> {
8397 // idx encoded in Q field.
8398 bits<1> idx;
8399 let Inst{30} = idx;
8400 let Inst{23} = 0;
8401 let Inst{20-16} = 0b00000;
8402 let Inst{12} = 0;
8403 let Inst{11-10} = size;
8404}
8405class SIMDLdStSingleDTied<bit L, bit R, bits<3> opcode, bits<2> size, string asm,
8406 dag oops, dag iops, list<dag> pattern>
8407 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "",
8408 oops, iops, pattern> {
8409 // idx encoded in Q field.
8410 bits<1> idx;
8411 let Inst{30} = idx;
8412 let Inst{23} = 0;
8413 let Inst{20-16} = 0b00000;
8414 let Inst{12} = 0;
8415 let Inst{11-10} = size;
8416}
8417class SIMDLdStSingleDPost<bit L, bit R, bits<3> opcode, bits<2> size,
8418 string asm, dag oops, dag iops>
8419 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
8420 "$Rn = $wback", oops, iops, []> {
8421 // idx encoded in Q field.
8422 bits<1> idx;
8423 bits<5> Xm;
8424 let Inst{30} = idx;
8425 let Inst{23} = 1;
8426 let Inst{20-16} = Xm;
8427 let Inst{12} = 0;
8428 let Inst{11-10} = size;
8429}
8430class SIMDLdStSingleDTiedPost<bit L, bit R, bits<3> opcode, bits<2> size,
8431 string asm, dag oops, dag iops>
8432 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
8433 "$Rn = $wback", oops, iops, []> {
8434 // idx encoded in Q field.
8435 bits<1> idx;
8436 bits<5> Xm;
8437 let Inst{30} = idx;
8438 let Inst{23} = 1;
8439 let Inst{20-16} = Xm;
8440 let Inst{12} = 0;
8441 let Inst{11-10} = size;
8442}
8443
8444let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
8445multiclass SIMDLdSingleBTied<bit R, bits<3> opcode, string asm,
8446 RegisterOperand listtype,
8447 RegisterOperand GPR64pi> {
8448 def i8 : SIMDLdStSingleBTied<1, R, opcode, asm,
8449 (outs listtype:$dst),
8450 (ins listtype:$Vt, VectorIndexB:$idx,
8451 GPR64sp:$Rn), []>;
8452
8453 def i8_POST : SIMDLdStSingleBTiedPost<1, R, opcode, asm,
8454 (outs GPR64sp:$wback, listtype:$dst),
8455 (ins listtype:$Vt, VectorIndexB:$idx,
8456 GPR64sp:$Rn, GPR64pi:$Xm)>;
8457}
8458let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
8459multiclass SIMDLdSingleHTied<bit R, bits<3> opcode, bit size, string asm,
8460 RegisterOperand listtype,
8461 RegisterOperand GPR64pi> {
8462 def i16 : SIMDLdStSingleHTied<1, R, opcode, size, asm,
8463 (outs listtype:$dst),
8464 (ins listtype:$Vt, VectorIndexH:$idx,
8465 GPR64sp:$Rn), []>;
8466
8467 def i16_POST : SIMDLdStSingleHTiedPost<1, R, opcode, size, asm,
8468 (outs GPR64sp:$wback, listtype:$dst),
8469 (ins listtype:$Vt, VectorIndexH:$idx,
8470 GPR64sp:$Rn, GPR64pi:$Xm)>;
8471}
8472let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
8473multiclass SIMDLdSingleSTied<bit R, bits<3> opcode, bits<2> size,string asm,
8474 RegisterOperand listtype,
8475 RegisterOperand GPR64pi> {
8476 def i32 : SIMDLdStSingleSTied<1, R, opcode, size, asm,
8477 (outs listtype:$dst),
8478 (ins listtype:$Vt, VectorIndexS:$idx,
8479 GPR64sp:$Rn), []>;
8480
8481 def i32_POST : SIMDLdStSingleSTiedPost<1, R, opcode, size, asm,
8482 (outs GPR64sp:$wback, listtype:$dst),
8483 (ins listtype:$Vt, VectorIndexS:$idx,
8484 GPR64sp:$Rn, GPR64pi:$Xm)>;
8485}
8486let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
8487multiclass SIMDLdSingleDTied<bit R, bits<3> opcode, bits<2> size, string asm,
8488 RegisterOperand listtype, RegisterOperand GPR64pi> {
8489 def i64 : SIMDLdStSingleDTied<1, R, opcode, size, asm,
8490 (outs listtype:$dst),
8491 (ins listtype:$Vt, VectorIndexD:$idx,
8492 GPR64sp:$Rn), []>;
8493
8494 def i64_POST : SIMDLdStSingleDTiedPost<1, R, opcode, size, asm,
8495 (outs GPR64sp:$wback, listtype:$dst),
8496 (ins listtype:$Vt, VectorIndexD:$idx,
8497 GPR64sp:$Rn, GPR64pi:$Xm)>;
8498}
8499let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
8500multiclass SIMDStSingleB<bit R, bits<3> opcode, string asm,
8501 RegisterOperand listtype, RegisterOperand GPR64pi> {
8502 def i8 : SIMDLdStSingleB<0, R, opcode, asm,
8503 (outs), (ins listtype:$Vt, VectorIndexB:$idx,
8504 GPR64sp:$Rn), []>;
8505
8506 def i8_POST : SIMDLdStSingleBPost<0, R, opcode, asm,
8507 (outs GPR64sp:$wback),
8508 (ins listtype:$Vt, VectorIndexB:$idx,
8509 GPR64sp:$Rn, GPR64pi:$Xm)>;
8510}
8511let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
8512multiclass SIMDStSingleH<bit R, bits<3> opcode, bit size, string asm,
8513 RegisterOperand listtype, RegisterOperand GPR64pi> {
8514 def i16 : SIMDLdStSingleH<0, R, opcode, size, asm,
8515 (outs), (ins listtype:$Vt, VectorIndexH:$idx,
8516 GPR64sp:$Rn), []>;
8517
8518 def i16_POST : SIMDLdStSingleHPost<0, R, opcode, size, asm,
8519 (outs GPR64sp:$wback),
8520 (ins listtype:$Vt, VectorIndexH:$idx,
8521 GPR64sp:$Rn, GPR64pi:$Xm)>;
8522}
8523let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
8524multiclass SIMDStSingleS<bit R, bits<3> opcode, bits<2> size,string asm,
8525 RegisterOperand listtype, RegisterOperand GPR64pi> {
8526 def i32 : SIMDLdStSingleS<0, R, opcode, size, asm,
8527 (outs), (ins listtype:$Vt, VectorIndexS:$idx,
8528 GPR64sp:$Rn), []>;
8529
8530 def i32_POST : SIMDLdStSingleSPost<0, R, opcode, size, asm,
8531 (outs GPR64sp:$wback),
8532 (ins listtype:$Vt, VectorIndexS:$idx,
8533 GPR64sp:$Rn, GPR64pi:$Xm)>;
8534}
8535let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
8536multiclass SIMDStSingleD<bit R, bits<3> opcode, bits<2> size, string asm,
8537 RegisterOperand listtype, RegisterOperand GPR64pi> {
8538 def i64 : SIMDLdStSingleD<0, R, opcode, size, asm,
8539 (outs), (ins listtype:$Vt, VectorIndexD:$idx,
8540 GPR64sp:$Rn), []>;
8541
8542 def i64_POST : SIMDLdStSingleDPost<0, R, opcode, size, asm,
8543 (outs GPR64sp:$wback),
8544 (ins listtype:$Vt, VectorIndexD:$idx,
8545 GPR64sp:$Rn, GPR64pi:$Xm)>;
8546}
8547
8548multiclass SIMDLdStSingleAliases<string asm, string layout, string Type,
8549 string Count, int Offset, Operand idxtype> {
8550 // E.g. "ld1 { v0.8b }[0], [x1], #1"
8551 // "ld1\t$Vt, [$Rn], #1"
8552 // may get mapped to
8553 // (LD1Rv8b_POST VecListOne8b:$Vt, GPR64sp:$Rn, XZR)
8554 def : InstAlias<asm # "\t$Vt$idx, [$Rn], #" # Offset,
8555 (!cast<Instruction>(NAME # Type # "_POST")
8556 GPR64sp:$Rn,
8557 !cast<RegisterOperand>("VecList" # Count # layout):$Vt,
8558 idxtype:$idx, XZR), 1>;
8559
8560 // E.g. "ld1.8b { v0 }[0], [x1], #1"
8561 // "ld1.8b\t$Vt, [$Rn], #1"
8562 // may get mapped to
8563 // (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, XZR)
8564 def : InstAlias<asm # "." # layout # "\t$Vt$idx, [$Rn], #" # Offset,
8565 (!cast<Instruction>(NAME # Type # "_POST")
8566 GPR64sp:$Rn,
8567 !cast<RegisterOperand>("VecList" # Count # "128"):$Vt,
8568 idxtype:$idx, XZR), 0>;
8569
8570 // E.g. "ld1.8b { v0 }[0], [x1]"
8571 // "ld1.8b\t$Vt, [$Rn]"
8572 // may get mapped to
8573 // (LD1Rv8b VecListOne64:$Vt, GPR64sp:$Rn)
8574 def : InstAlias<asm # "." # layout # "\t$Vt$idx, [$Rn]",
8575 (!cast<Instruction>(NAME # Type)
8576 !cast<RegisterOperand>("VecList" # Count # "128"):$Vt,
8577 idxtype:$idx, GPR64sp:$Rn), 0>;
8578
8579 // E.g. "ld1.8b { v0 }[0], [x1], x2"
8580 // "ld1.8b\t$Vt, [$Rn], $Xm"
8581 // may get mapped to
8582 // (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, GPR64pi1:$Xm)
8583 def : InstAlias<asm # "." # layout # "\t$Vt$idx, [$Rn], $Xm",
8584 (!cast<Instruction>(NAME # Type # "_POST")
8585 GPR64sp:$Rn,
8586 !cast<RegisterOperand>("VecList" # Count # "128"):$Vt,
8587 idxtype:$idx,
8588 !cast<RegisterOperand>("GPR64pi" # Offset):$Xm), 0>;
8589}
8590
8591multiclass SIMDLdSt1SingleAliases<string asm> {
8592 defm : SIMDLdStSingleAliases<asm, "b", "i8", "One", 1, VectorIndexB>;
8593 defm : SIMDLdStSingleAliases<asm, "h", "i16", "One", 2, VectorIndexH>;
8594 defm : SIMDLdStSingleAliases<asm, "s", "i32", "One", 4, VectorIndexS>;
8595 defm : SIMDLdStSingleAliases<asm, "d", "i64", "One", 8, VectorIndexD>;
8596}
8597
8598multiclass SIMDLdSt2SingleAliases<string asm> {
8599 defm : SIMDLdStSingleAliases<asm, "b", "i8", "Two", 2, VectorIndexB>;
8600 defm : SIMDLdStSingleAliases<asm, "h", "i16", "Two", 4, VectorIndexH>;
8601 defm : SIMDLdStSingleAliases<asm, "s", "i32", "Two", 8, VectorIndexS>;
8602 defm : SIMDLdStSingleAliases<asm, "d", "i64", "Two", 16, VectorIndexD>;
8603}
8604
8605multiclass SIMDLdSt3SingleAliases<string asm> {
8606 defm : SIMDLdStSingleAliases<asm, "b", "i8", "Three", 3, VectorIndexB>;
8607 defm : SIMDLdStSingleAliases<asm, "h", "i16", "Three", 6, VectorIndexH>;
8608 defm : SIMDLdStSingleAliases<asm, "s", "i32", "Three", 12, VectorIndexS>;
8609 defm : SIMDLdStSingleAliases<asm, "d", "i64", "Three", 24, VectorIndexD>;
8610}
8611
8612multiclass SIMDLdSt4SingleAliases<string asm> {
8613 defm : SIMDLdStSingleAliases<asm, "b", "i8", "Four", 4, VectorIndexB>;
8614 defm : SIMDLdStSingleAliases<asm, "h", "i16", "Four", 8, VectorIndexH>;
8615 defm : SIMDLdStSingleAliases<asm, "s", "i32", "Four", 16, VectorIndexS>;
8616 defm : SIMDLdStSingleAliases<asm, "d", "i64", "Four", 32, VectorIndexD>;
8617}
8618} // end of 'let Predicates = [HasNEON]'
8619
8620//----------------------------------------------------------------------------
Vladimir Sukharev297bf0e2015-03-31 13:15:48 +00008621// AdvSIMD v8.1 Rounding Double Multiply Add/Subtract
8622//----------------------------------------------------------------------------
8623
8624let Predicates = [HasNEON, HasV8_1a] in {
8625
8626class BaseSIMDThreeSameVectorTiedR0<bit Q, bit U, bits<2> size, bits<5> opcode,
8627 RegisterOperand regtype, string asm,
8628 string kind, list<dag> pattern>
8629 : BaseSIMDThreeSameVectorTied<Q, U, size, opcode, regtype, asm, kind,
8630 pattern> {
8631 let Inst{21}=0;
8632}
8633multiclass SIMDThreeSameVectorSQRDMLxHTiedHS<bit U, bits<5> opc, string asm,
8634 SDPatternOperator Accum> {
8635 def v4i16 : BaseSIMDThreeSameVectorTiedR0<0, U, 0b01, opc, V64, asm, ".4h",
8636 [(set (v4i16 V64:$dst),
8637 (Accum (v4i16 V64:$Rd),
8638 (v4i16 (int_aarch64_neon_sqrdmulh (v4i16 V64:$Rn),
8639 (v4i16 V64:$Rm)))))]>;
8640 def v8i16 : BaseSIMDThreeSameVectorTiedR0<1, U, 0b01, opc, V128, asm, ".8h",
8641 [(set (v8i16 V128:$dst),
8642 (Accum (v8i16 V128:$Rd),
8643 (v8i16 (int_aarch64_neon_sqrdmulh (v8i16 V128:$Rn),
8644 (v8i16 V128:$Rm)))))]>;
8645 def v2i32 : BaseSIMDThreeSameVectorTiedR0<0, U, 0b10, opc, V64, asm, ".2s",
8646 [(set (v2i32 V64:$dst),
8647 (Accum (v2i32 V64:$Rd),
8648 (v2i32 (int_aarch64_neon_sqrdmulh (v2i32 V64:$Rn),
8649 (v2i32 V64:$Rm)))))]>;
8650 def v4i32 : BaseSIMDThreeSameVectorTiedR0<1, U, 0b10, opc, V128, asm, ".4s",
8651 [(set (v4i32 V128:$dst),
8652 (Accum (v4i32 V128:$Rd),
8653 (v4i32 (int_aarch64_neon_sqrdmulh (v4i32 V128:$Rn),
8654 (v4i32 V128:$Rm)))))]>;
8655}
8656
8657multiclass SIMDIndexedSQRDMLxHSDTied<bit U, bits<4> opc, string asm,
8658 SDPatternOperator Accum> {
8659 def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc,
8660 V64, V64, V128_lo, VectorIndexH,
8661 asm, ".4h", ".4h", ".4h", ".h",
8662 [(set (v4i16 V64:$dst),
8663 (Accum (v4i16 V64:$Rd),
8664 (v4i16 (int_aarch64_neon_sqrdmulh
8665 (v4i16 V64:$Rn),
8666 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm),
8667 VectorIndexH:$idx))))))]> {
8668 bits<3> idx;
8669 let Inst{11} = idx{2};
8670 let Inst{21} = idx{1};
8671 let Inst{20} = idx{0};
8672 }
8673
8674 def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc,
8675 V128, V128, V128_lo, VectorIndexH,
8676 asm, ".8h", ".8h", ".8h", ".h",
8677 [(set (v8i16 V128:$dst),
8678 (Accum (v8i16 V128:$Rd),
8679 (v8i16 (int_aarch64_neon_sqrdmulh
8680 (v8i16 V128:$Rn),
8681 (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm),
8682 VectorIndexH:$idx))))))]> {
8683 bits<3> idx;
8684 let Inst{11} = idx{2};
8685 let Inst{21} = idx{1};
8686 let Inst{20} = idx{0};
8687 }
8688
8689 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc,
8690 V64, V64, V128, VectorIndexS,
8691 asm, ".2s", ".2s", ".2s", ".s",
8692 [(set (v2i32 V64:$dst),
8693 (Accum (v2i32 V64:$Rd),
8694 (v2i32 (int_aarch64_neon_sqrdmulh
8695 (v2i32 V64:$Rn),
8696 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm),
8697 VectorIndexS:$idx))))))]> {
8698 bits<2> idx;
8699 let Inst{11} = idx{1};
8700 let Inst{21} = idx{0};
8701 }
8702
8703 // FIXME: it would be nice to use the scalar (v1i32) instruction here, but
8704 // an intermediate EXTRACT_SUBREG would be untyped.
8705 // FIXME: direct EXTRACT_SUBREG from v2i32 to i32 is illegal, that's why we
8706 // got it lowered here as (i32 vector_extract (v4i32 insert_subvector(..)))
8707 def : Pat<(i32 (Accum (i32 FPR32Op:$Rd),
8708 (i32 (vector_extract
8709 (v4i32 (insert_subvector
8710 (undef),
8711 (v2i32 (int_aarch64_neon_sqrdmulh
8712 (v2i32 V64:$Rn),
8713 (v2i32 (AArch64duplane32
8714 (v4i32 V128:$Rm),
8715 VectorIndexS:$idx)))),
8716 (i32 0))),
8717 (i64 0))))),
8718 (EXTRACT_SUBREG
8719 (v2i32 (!cast<Instruction>(NAME # v2i32_indexed)
8720 (v2i32 (INSERT_SUBREG (v2i32 (IMPLICIT_DEF)),
8721 FPR32Op:$Rd,
8722 ssub)),
8723 V64:$Rn,
8724 V128:$Rm,
8725 VectorIndexS:$idx)),
8726 ssub)>;
8727
8728 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc,
8729 V128, V128, V128, VectorIndexS,
8730 asm, ".4s", ".4s", ".4s", ".s",
8731 [(set (v4i32 V128:$dst),
8732 (Accum (v4i32 V128:$Rd),
8733 (v4i32 (int_aarch64_neon_sqrdmulh
8734 (v4i32 V128:$Rn),
8735 (v4i32 (AArch64duplane32 (v4i32 V128:$Rm),
8736 VectorIndexS:$idx))))))]> {
8737 bits<2> idx;
8738 let Inst{11} = idx{1};
8739 let Inst{21} = idx{0};
8740 }
8741
8742 // FIXME: it would be nice to use the scalar (v1i32) instruction here, but
8743 // an intermediate EXTRACT_SUBREG would be untyped.
8744 def : Pat<(i32 (Accum (i32 FPR32Op:$Rd),
8745 (i32 (vector_extract
8746 (v4i32 (int_aarch64_neon_sqrdmulh
8747 (v4i32 V128:$Rn),
8748 (v4i32 (AArch64duplane32
8749 (v4i32 V128:$Rm),
8750 VectorIndexS:$idx)))),
8751 (i64 0))))),
8752 (EXTRACT_SUBREG
8753 (v4i32 (!cast<Instruction>(NAME # v4i32_indexed)
8754 (v4i32 (INSERT_SUBREG (v4i32 (IMPLICIT_DEF)),
8755 FPR32Op:$Rd,
8756 ssub)),
8757 V128:$Rn,
8758 V128:$Rm,
8759 VectorIndexS:$idx)),
8760 ssub)>;
8761
8762 def i16_indexed : BaseSIMDIndexedTied<1, U, 1, 0b01, opc,
8763 FPR16Op, FPR16Op, V128_lo,
8764 VectorIndexH, asm, ".h", "", "", ".h",
8765 []> {
8766 bits<3> idx;
8767 let Inst{11} = idx{2};
8768 let Inst{21} = idx{1};
8769 let Inst{20} = idx{0};
8770 }
8771
8772 def i32_indexed : BaseSIMDIndexedTied<1, U, 1, 0b10, opc,
8773 FPR32Op, FPR32Op, V128, VectorIndexS,
8774 asm, ".s", "", "", ".s",
8775 [(set (i32 FPR32Op:$dst),
8776 (Accum (i32 FPR32Op:$Rd),
8777 (i32 (int_aarch64_neon_sqrdmulh
8778 (i32 FPR32Op:$Rn),
8779 (i32 (vector_extract (v4i32 V128:$Rm),
8780 VectorIndexS:$idx))))))]> {
8781 bits<2> idx;
8782 let Inst{11} = idx{1};
8783 let Inst{21} = idx{0};
8784 }
8785}
8786} // let Predicates = [HasNeon, HasV8_1a]
8787
8788//----------------------------------------------------------------------------
Tim Northover3b0846e2014-05-24 12:50:23 +00008789// Crypto extensions
8790//----------------------------------------------------------------------------
8791
8792let Predicates = [HasCrypto] in {
8793let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
8794class AESBase<bits<4> opc, string asm, dag outs, dag ins, string cstr,
8795 list<dag> pat>
8796 : I<outs, ins, asm, "{\t$Rd.16b, $Rn.16b|.16b\t$Rd, $Rn}", cstr, pat>,
8797 Sched<[WriteV]>{
8798 bits<5> Rd;
8799 bits<5> Rn;
8800 let Inst{31-16} = 0b0100111000101000;
8801 let Inst{15-12} = opc;
8802 let Inst{11-10} = 0b10;
8803 let Inst{9-5} = Rn;
8804 let Inst{4-0} = Rd;
8805}
8806
8807class AESInst<bits<4> opc, string asm, Intrinsic OpNode>
8808 : AESBase<opc, asm, (outs V128:$Rd), (ins V128:$Rn), "",
8809 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>;
8810
8811class AESTiedInst<bits<4> opc, string asm, Intrinsic OpNode>
8812 : AESBase<opc, asm, (outs V128:$dst), (ins V128:$Rd, V128:$Rn),
8813 "$Rd = $dst",
8814 [(set (v16i8 V128:$dst),
8815 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn)))]>;
8816
8817let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
8818class SHA3OpTiedInst<bits<3> opc, string asm, string dst_lhs_kind,
8819 dag oops, dag iops, list<dag> pat>
8820 : I<oops, iops, asm,
8821 "{\t$Rd" # dst_lhs_kind # ", $Rn" # dst_lhs_kind # ", $Rm.4s" #
8822 "|.4s\t$Rd, $Rn, $Rm}", "$Rd = $dst", pat>,
8823 Sched<[WriteV]>{
8824 bits<5> Rd;
8825 bits<5> Rn;
8826 bits<5> Rm;
8827 let Inst{31-21} = 0b01011110000;
8828 let Inst{20-16} = Rm;
8829 let Inst{15} = 0;
8830 let Inst{14-12} = opc;
8831 let Inst{11-10} = 0b00;
8832 let Inst{9-5} = Rn;
8833 let Inst{4-0} = Rd;
8834}
8835
8836class SHATiedInstQSV<bits<3> opc, string asm, Intrinsic OpNode>
8837 : SHA3OpTiedInst<opc, asm, "", (outs FPR128:$dst),
8838 (ins FPR128:$Rd, FPR32:$Rn, V128:$Rm),
8839 [(set (v4i32 FPR128:$dst),
8840 (OpNode (v4i32 FPR128:$Rd), (i32 FPR32:$Rn),
8841 (v4i32 V128:$Rm)))]>;
8842
8843class SHATiedInstVVV<bits<3> opc, string asm, Intrinsic OpNode>
8844 : SHA3OpTiedInst<opc, asm, ".4s", (outs V128:$dst),
8845 (ins V128:$Rd, V128:$Rn, V128:$Rm),
8846 [(set (v4i32 V128:$dst),
8847 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn),
8848 (v4i32 V128:$Rm)))]>;
8849
8850class SHATiedInstQQV<bits<3> opc, string asm, Intrinsic OpNode>
8851 : SHA3OpTiedInst<opc, asm, "", (outs FPR128:$dst),
8852 (ins FPR128:$Rd, FPR128:$Rn, V128:$Rm),
8853 [(set (v4i32 FPR128:$dst),
8854 (OpNode (v4i32 FPR128:$Rd), (v4i32 FPR128:$Rn),
8855 (v4i32 V128:$Rm)))]>;
8856
8857let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
8858class SHA2OpInst<bits<4> opc, string asm, string kind,
8859 string cstr, dag oops, dag iops,
8860 list<dag> pat>
8861 : I<oops, iops, asm, "{\t$Rd" # kind # ", $Rn" # kind #
8862 "|" # kind # "\t$Rd, $Rn}", cstr, pat>,
8863 Sched<[WriteV]>{
8864 bits<5> Rd;
8865 bits<5> Rn;
8866 let Inst{31-16} = 0b0101111000101000;
8867 let Inst{15-12} = opc;
8868 let Inst{11-10} = 0b10;
8869 let Inst{9-5} = Rn;
8870 let Inst{4-0} = Rd;
8871}
8872
8873class SHATiedInstVV<bits<4> opc, string asm, Intrinsic OpNode>
8874 : SHA2OpInst<opc, asm, ".4s", "$Rd = $dst", (outs V128:$dst),
8875 (ins V128:$Rd, V128:$Rn),
8876 [(set (v4i32 V128:$dst),
8877 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn)))]>;
8878
8879class SHAInstSS<bits<4> opc, string asm, Intrinsic OpNode>
8880 : SHA2OpInst<opc, asm, "", "", (outs FPR32:$Rd), (ins FPR32:$Rn),
8881 [(set (i32 FPR32:$Rd), (OpNode (i32 FPR32:$Rn)))]>;
8882} // end of 'let Predicates = [HasCrypto]'
8883
Vladimir Sukharev5f6f60d2015-06-02 10:58:41 +00008884//----------------------------------------------------------------------------
8885// v8.1 atomic instructions extension:
8886// * CAS
8887// * CASP
8888// * SWP
8889// * LDOPregister<OP>, and aliases STOPregister<OP>
8890
8891// Instruction encodings:
8892//
8893// 31 30|29 24|23|22|21|20 16|15|14 10|9 5|4 0
8894// CAS SZ |001000|1 |A |1 |Rs |R |11111 |Rn |Rt
8895// CASP 0|SZ|001000|0 |A |1 |Rs |R |11111 |Rn |Rt
8896// SWP SZ |111000|A |R |1 |Rs |1 |OPC|00|Rn |Rt
8897// LD SZ |111000|A |R |1 |Rs |0 |OPC|00|Rn |Rt
8898// ST SZ |111000|A |R |1 |Rs |0 |OPC|00|Rn |11111
8899
8900// Instruction syntax:
8901//
8902// CAS{<order>}[<size>] <Ws>, <Wt>, [<Xn|SP>]
8903// CAS{<order>} <Xs>, <Xt>, [<Xn|SP>]
8904// CASP{<order>} <Ws>, <W(s+1)>, <Wt>, <W(t+1)>, [<Xn|SP>]
8905// CASP{<order>} <Xs>, <X(s+1)>, <Xt>, <X(t+1)>, [<Xn|SP>]
8906// SWP{<order>}[<size>] <Ws>, <Wt>, [<Xn|SP>]
8907// SWP{<order>} <Xs>, <Xt>, [<Xn|SP>]
8908// LD<OP>{<order>}[<size>] <Ws>, <Wt>, [<Xn|SP>]
8909// LD<OP>{<order>} <Xs>, <Xt>, [<Xn|SP>]
8910// ST<OP>{<order>}[<size>] <Ws>, [<Xn|SP>]
8911// ST<OP>{<order>} <Xs>, [<Xn|SP>]
8912
8913let Predicates = [HasV8_1a], mayLoad = 1, mayStore = 1, hasSideEffects = 1 in
8914class BaseCASEncoding<dag oops, dag iops, string asm, string operands,
8915 string cstr, list<dag> pattern>
8916 : I<oops, iops, asm, operands, cstr, pattern> {
8917 bits<2> Sz;
8918 bit NP;
8919 bit Acq;
8920 bit Rel;
8921 bits<5> Rs;
8922 bits<5> Rn;
8923 bits<5> Rt;
8924 let Inst{31-30} = Sz;
8925 let Inst{29-24} = 0b001000;
8926 let Inst{23} = NP;
8927 let Inst{22} = Acq;
8928 let Inst{21} = 0b1;
8929 let Inst{20-16} = Rs;
8930 let Inst{15} = Rel;
8931 let Inst{14-10} = 0b11111;
8932 let Inst{9-5} = Rn;
8933 let Inst{4-0} = Rt;
8934}
8935
8936class BaseCAS<string order, string size, RegisterClass RC>
8937 : BaseCASEncoding<(outs RC:$out),(ins RC:$Rs, RC:$Rt, GPR64sp:$Rn),
8938 "cas" # order # size, "\t$Rs, $Rt, [$Rn]",
8939 "$out = $Rs",[]> {
8940 let NP = 1;
8941}
8942
8943multiclass CompareAndSwap<bits<1> Acq, bits<1> Rel, string order> {
8944 let Sz = 0b00, Acq = Acq, Rel = Rel in def b : BaseCAS<order, "b", GPR32>;
8945 let Sz = 0b01, Acq = Acq, Rel = Rel in def h : BaseCAS<order, "h", GPR32>;
8946 let Sz = 0b10, Acq = Acq, Rel = Rel in def s : BaseCAS<order, "", GPR32>;
8947 let Sz = 0b11, Acq = Acq, Rel = Rel in def d : BaseCAS<order, "", GPR64>;
8948}
8949
8950class BaseCASP<string order, string size, RegisterOperand RC>
8951 : BaseCASEncoding<(outs RC:$out),(ins RC:$Rs, RC:$Rt, GPR64sp:$Rn),
8952 "casp" # order # size, "\t$Rs, $Rt, [$Rn]",
8953 "$out = $Rs",[]> {
8954 let NP = 0;
8955}
8956
8957multiclass CompareAndSwapPair<bits<1> Acq, bits<1> Rel, string order> {
8958 let Sz = 0b00, Acq = Acq, Rel = Rel in
8959 def s : BaseCASP<order, "", WSeqPairClassOperand>;
8960 let Sz = 0b01, Acq = Acq, Rel = Rel in
8961 def d : BaseCASP<order, "", XSeqPairClassOperand>;
8962}
8963
8964let Predicates = [HasV8_1a] in
8965class BaseSWP<string order, string size, RegisterClass RC>
8966 : I<(outs RC:$Rt),(ins RC:$Rs, GPR64sp:$Rn), "swp" # order # size,
8967 "\t$Rs, $Rt, [$Rn]","",[]> {
8968 bits<2> Sz;
8969 bit Acq;
8970 bit Rel;
8971 bits<5> Rs;
8972 bits<3> opc = 0b000;
8973 bits<5> Rn;
8974 bits<5> Rt;
8975 let Inst{31-30} = Sz;
8976 let Inst{29-24} = 0b111000;
8977 let Inst{23} = Acq;
8978 let Inst{22} = Rel;
8979 let Inst{21} = 0b1;
8980 let Inst{20-16} = Rs;
8981 let Inst{15} = 0b1;
8982 let Inst{14-12} = opc;
8983 let Inst{11-10} = 0b00;
8984 let Inst{9-5} = Rn;
8985 let Inst{4-0} = Rt;
8986}
8987
8988multiclass Swap<bits<1> Acq, bits<1> Rel, string order> {
8989 let Sz = 0b00, Acq = Acq, Rel = Rel in def b : BaseSWP<order, "b", GPR32>;
8990 let Sz = 0b01, Acq = Acq, Rel = Rel in def h : BaseSWP<order, "h", GPR32>;
8991 let Sz = 0b10, Acq = Acq, Rel = Rel in def s : BaseSWP<order, "", GPR32>;
8992 let Sz = 0b11, Acq = Acq, Rel = Rel in def d : BaseSWP<order, "", GPR64>;
8993}
8994
8995let Predicates = [HasV8_1a], mayLoad = 1, mayStore = 1, hasSideEffects = 1 in
8996class BaseLDOPregister<string op, string order, string size, RegisterClass RC>
8997 : I<(outs RC:$Rt),(ins RC:$Rs, GPR64sp:$Rn), "ld" # op # order # size,
8998 "\t$Rs, $Rt, [$Rn]","",[]> {
8999 bits<2> Sz;
9000 bit Acq;
9001 bit Rel;
9002 bits<5> Rs;
9003 bits<3> opc;
9004 bits<5> Rn;
9005 bits<5> Rt;
9006 let Inst{31-30} = Sz;
9007 let Inst{29-24} = 0b111000;
9008 let Inst{23} = Acq;
9009 let Inst{22} = Rel;
9010 let Inst{21} = 0b1;
9011 let Inst{20-16} = Rs;
9012 let Inst{15} = 0b0;
9013 let Inst{14-12} = opc;
9014 let Inst{11-10} = 0b00;
9015 let Inst{9-5} = Rn;
9016 let Inst{4-0} = Rt;
9017}
9018
9019multiclass LDOPregister<bits<3> opc, string op, bits<1> Acq, bits<1> Rel,
9020 string order> {
9021 let Sz = 0b00, Acq = Acq, Rel = Rel, opc = opc in
9022 def b : BaseLDOPregister<op, order, "b", GPR32>;
9023 let Sz = 0b01, Acq = Acq, Rel = Rel, opc = opc in
9024 def h : BaseLDOPregister<op, order, "h", GPR32>;
9025 let Sz = 0b10, Acq = Acq, Rel = Rel, opc = opc in
9026 def s : BaseLDOPregister<op, order, "", GPR32>;
9027 let Sz = 0b11, Acq = Acq, Rel = Rel, opc = opc in
9028 def d : BaseLDOPregister<op, order, "", GPR64>;
9029}
9030
9031let Predicates = [HasV8_1a] in
9032class BaseSTOPregister<string asm, RegisterClass OP, Register Reg,
9033 Instruction inst> :
9034 InstAlias<asm # "\t$Rs, [$Rn]", (inst Reg, OP:$Rs, GPR64sp:$Rn)>;
9035
9036multiclass STOPregister<string asm, string instr> {
9037 def : BaseSTOPregister<asm # "lb", GPR32, WZR,
9038 !cast<Instruction>(instr # "Lb")>;
9039 def : BaseSTOPregister<asm # "lh", GPR32, WZR,
9040 !cast<Instruction>(instr # "Lh")>;
9041 def : BaseSTOPregister<asm # "l", GPR32, WZR,
9042 !cast<Instruction>(instr # "Ls")>;
9043 def : BaseSTOPregister<asm # "l", GPR64, XZR,
9044 !cast<Instruction>(instr # "Ld")>;
9045 def : BaseSTOPregister<asm # "b", GPR32, WZR,
9046 !cast<Instruction>(instr # "b")>;
9047 def : BaseSTOPregister<asm # "h", GPR32, WZR,
9048 !cast<Instruction>(instr # "h")>;
9049 def : BaseSTOPregister<asm, GPR32, WZR,
9050 !cast<Instruction>(instr # "s")>;
9051 def : BaseSTOPregister<asm, GPR64, XZR,
9052 !cast<Instruction>(instr # "d")>;
9053}
9054
9055//----------------------------------------------------------------------------
Tim Northover3b0846e2014-05-24 12:50:23 +00009056// Allow the size specifier tokens to be upper case, not just lower.
9057def : TokenAlias<".8B", ".8b">;
9058def : TokenAlias<".4H", ".4h">;
9059def : TokenAlias<".2S", ".2s">;
9060def : TokenAlias<".1D", ".1d">;
9061def : TokenAlias<".16B", ".16b">;
9062def : TokenAlias<".8H", ".8h">;
9063def : TokenAlias<".4S", ".4s">;
9064def : TokenAlias<".2D", ".2d">;
9065def : TokenAlias<".1Q", ".1q">;
9066def : TokenAlias<".B", ".b">;
9067def : TokenAlias<".H", ".h">;
9068def : TokenAlias<".S", ".s">;
9069def : TokenAlias<".D", ".d">;
9070def : TokenAlias<".Q", ".q">;