blob: 977c7d3f0bbe87fc1391d8a34fb1bc8077429b01 [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
Ahmed Bougachab8886b52015-09-10 01:42:28 +0000251def am_indexed7s8 : ComplexPattern<i64, 2, "SelectAddrModeIndexed7S8", []>;
252def am_indexed7s16 : ComplexPattern<i64, 2, "SelectAddrModeIndexed7S16", []>;
253def am_indexed7s32 : ComplexPattern<i64, 2, "SelectAddrModeIndexed7S32", []>;
254def am_indexed7s64 : ComplexPattern<i64, 2, "SelectAddrModeIndexed7S64", []>;
255def am_indexed7s128 : ComplexPattern<i64, 2, "SelectAddrModeIndexed7S128", []>;
256
Tim Northover3b0846e2014-05-24 12:50:23 +0000257class AsmImmRange<int Low, int High> : AsmOperandClass {
258 let Name = "Imm" # Low # "_" # High;
259 let DiagnosticType = "InvalidImm" # Low # "_" # High;
260}
261
262def Imm1_8Operand : AsmImmRange<1, 8>;
263def Imm1_16Operand : AsmImmRange<1, 16>;
264def Imm1_32Operand : AsmImmRange<1, 32>;
265def Imm1_64Operand : AsmImmRange<1, 64>;
266
267def MovZSymbolG3AsmOperand : AsmOperandClass {
268 let Name = "MovZSymbolG3";
269 let RenderMethod = "addImmOperands";
270}
271
272def movz_symbol_g3 : Operand<i32> {
273 let ParserMatchClass = MovZSymbolG3AsmOperand;
274}
275
276def MovZSymbolG2AsmOperand : AsmOperandClass {
277 let Name = "MovZSymbolG2";
278 let RenderMethod = "addImmOperands";
279}
280
281def movz_symbol_g2 : Operand<i32> {
282 let ParserMatchClass = MovZSymbolG2AsmOperand;
283}
284
285def MovZSymbolG1AsmOperand : AsmOperandClass {
286 let Name = "MovZSymbolG1";
287 let RenderMethod = "addImmOperands";
288}
289
290def movz_symbol_g1 : Operand<i32> {
291 let ParserMatchClass = MovZSymbolG1AsmOperand;
292}
293
294def MovZSymbolG0AsmOperand : AsmOperandClass {
295 let Name = "MovZSymbolG0";
296 let RenderMethod = "addImmOperands";
297}
298
299def movz_symbol_g0 : Operand<i32> {
300 let ParserMatchClass = MovZSymbolG0AsmOperand;
301}
302
303def MovKSymbolG3AsmOperand : AsmOperandClass {
304 let Name = "MovKSymbolG3";
305 let RenderMethod = "addImmOperands";
306}
307
308def movk_symbol_g3 : Operand<i32> {
309 let ParserMatchClass = MovKSymbolG3AsmOperand;
310}
311
312def MovKSymbolG2AsmOperand : AsmOperandClass {
313 let Name = "MovKSymbolG2";
314 let RenderMethod = "addImmOperands";
315}
316
317def movk_symbol_g2 : Operand<i32> {
318 let ParserMatchClass = MovKSymbolG2AsmOperand;
319}
320
321def MovKSymbolG1AsmOperand : AsmOperandClass {
322 let Name = "MovKSymbolG1";
323 let RenderMethod = "addImmOperands";
324}
325
326def movk_symbol_g1 : Operand<i32> {
327 let ParserMatchClass = MovKSymbolG1AsmOperand;
328}
329
330def MovKSymbolG0AsmOperand : AsmOperandClass {
331 let Name = "MovKSymbolG0";
332 let RenderMethod = "addImmOperands";
333}
334
335def movk_symbol_g0 : Operand<i32> {
336 let ParserMatchClass = MovKSymbolG0AsmOperand;
337}
338
339class fixedpoint_i32<ValueType FloatVT>
340 : Operand<FloatVT>,
341 ComplexPattern<FloatVT, 1, "SelectCVTFixedPosOperand<32>", [fpimm, ld]> {
342 let EncoderMethod = "getFixedPointScaleOpValue";
343 let DecoderMethod = "DecodeFixedPointScaleImm32";
344 let ParserMatchClass = Imm1_32Operand;
345}
346
347class fixedpoint_i64<ValueType FloatVT>
348 : Operand<FloatVT>,
349 ComplexPattern<FloatVT, 1, "SelectCVTFixedPosOperand<64>", [fpimm, ld]> {
350 let EncoderMethod = "getFixedPointScaleOpValue";
351 let DecoderMethod = "DecodeFixedPointScaleImm64";
352 let ParserMatchClass = Imm1_64Operand;
353}
354
355def fixedpoint_f32_i32 : fixedpoint_i32<f32>;
356def fixedpoint_f64_i32 : fixedpoint_i32<f64>;
357
358def fixedpoint_f32_i64 : fixedpoint_i64<f32>;
359def fixedpoint_f64_i64 : fixedpoint_i64<f64>;
360
361def vecshiftR8 : Operand<i32>, ImmLeaf<i32, [{
362 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 9);
363}]> {
364 let EncoderMethod = "getVecShiftR8OpValue";
365 let DecoderMethod = "DecodeVecShiftR8Imm";
366 let ParserMatchClass = Imm1_8Operand;
367}
368def vecshiftR16 : Operand<i32>, ImmLeaf<i32, [{
369 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 17);
370}]> {
371 let EncoderMethod = "getVecShiftR16OpValue";
372 let DecoderMethod = "DecodeVecShiftR16Imm";
373 let ParserMatchClass = Imm1_16Operand;
374}
375def vecshiftR16Narrow : Operand<i32>, ImmLeaf<i32, [{
376 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 9);
377}]> {
378 let EncoderMethod = "getVecShiftR16OpValue";
379 let DecoderMethod = "DecodeVecShiftR16ImmNarrow";
380 let ParserMatchClass = Imm1_8Operand;
381}
382def vecshiftR32 : Operand<i32>, ImmLeaf<i32, [{
383 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 33);
384}]> {
385 let EncoderMethod = "getVecShiftR32OpValue";
386 let DecoderMethod = "DecodeVecShiftR32Imm";
387 let ParserMatchClass = Imm1_32Operand;
388}
389def vecshiftR32Narrow : Operand<i32>, ImmLeaf<i32, [{
390 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 17);
391}]> {
392 let EncoderMethod = "getVecShiftR32OpValue";
393 let DecoderMethod = "DecodeVecShiftR32ImmNarrow";
394 let ParserMatchClass = Imm1_16Operand;
395}
396def vecshiftR64 : Operand<i32>, ImmLeaf<i32, [{
397 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 65);
398}]> {
399 let EncoderMethod = "getVecShiftR64OpValue";
400 let DecoderMethod = "DecodeVecShiftR64Imm";
401 let ParserMatchClass = Imm1_64Operand;
402}
403def vecshiftR64Narrow : Operand<i32>, ImmLeaf<i32, [{
404 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 33);
405}]> {
406 let EncoderMethod = "getVecShiftR64OpValue";
407 let DecoderMethod = "DecodeVecShiftR64ImmNarrow";
408 let ParserMatchClass = Imm1_32Operand;
409}
410
Alexandros Lamprineas1bab1912015-10-05 13:42:31 +0000411def Imm0_1Operand : AsmImmRange<0, 1>;
Tim Northover3b0846e2014-05-24 12:50:23 +0000412def Imm0_7Operand : AsmImmRange<0, 7>;
413def Imm0_15Operand : AsmImmRange<0, 15>;
414def Imm0_31Operand : AsmImmRange<0, 31>;
415def Imm0_63Operand : AsmImmRange<0, 63>;
416
417def vecshiftL8 : Operand<i32>, ImmLeaf<i32, [{
418 return (((uint32_t)Imm) < 8);
419}]> {
420 let EncoderMethod = "getVecShiftL8OpValue";
421 let DecoderMethod = "DecodeVecShiftL8Imm";
422 let ParserMatchClass = Imm0_7Operand;
423}
424def vecshiftL16 : Operand<i32>, ImmLeaf<i32, [{
425 return (((uint32_t)Imm) < 16);
426}]> {
427 let EncoderMethod = "getVecShiftL16OpValue";
428 let DecoderMethod = "DecodeVecShiftL16Imm";
429 let ParserMatchClass = Imm0_15Operand;
430}
431def vecshiftL32 : Operand<i32>, ImmLeaf<i32, [{
432 return (((uint32_t)Imm) < 32);
433}]> {
434 let EncoderMethod = "getVecShiftL32OpValue";
435 let DecoderMethod = "DecodeVecShiftL32Imm";
436 let ParserMatchClass = Imm0_31Operand;
437}
438def vecshiftL64 : Operand<i32>, ImmLeaf<i32, [{
439 return (((uint32_t)Imm) < 64);
440}]> {
441 let EncoderMethod = "getVecShiftL64OpValue";
442 let DecoderMethod = "DecodeVecShiftL64Imm";
443 let ParserMatchClass = Imm0_63Operand;
444}
445
446
447// Crazy immediate formats used by 32-bit and 64-bit logical immediate
448// instructions for splatting repeating bit patterns across the immediate.
449def logical_imm32_XFORM : SDNodeXForm<imm, [{
450 uint64_t enc = AArch64_AM::encodeLogicalImmediate(N->getZExtValue(), 32);
Sergey Dmitrouk842a51b2015-04-28 14:05:47 +0000451 return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32);
Tim Northover3b0846e2014-05-24 12:50:23 +0000452}]>;
453def logical_imm64_XFORM : SDNodeXForm<imm, [{
454 uint64_t enc = AArch64_AM::encodeLogicalImmediate(N->getZExtValue(), 64);
Sergey Dmitrouk842a51b2015-04-28 14:05:47 +0000455 return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32);
Tim Northover3b0846e2014-05-24 12:50:23 +0000456}]>;
457
Arnaud A. de Grandmaisonf6432312014-07-10 15:12:26 +0000458let DiagnosticType = "LogicalSecondSource" in {
459 def LogicalImm32Operand : AsmOperandClass {
460 let Name = "LogicalImm32";
461 }
462 def LogicalImm64Operand : AsmOperandClass {
463 let Name = "LogicalImm64";
464 }
465 def LogicalImm32NotOperand : AsmOperandClass {
466 let Name = "LogicalImm32Not";
467 }
468 def LogicalImm64NotOperand : AsmOperandClass {
469 let Name = "LogicalImm64Not";
470 }
Tim Northover3b0846e2014-05-24 12:50:23 +0000471}
472def logical_imm32 : Operand<i32>, PatLeaf<(imm), [{
473 return AArch64_AM::isLogicalImmediate(N->getZExtValue(), 32);
474}], logical_imm32_XFORM> {
475 let PrintMethod = "printLogicalImm32";
476 let ParserMatchClass = LogicalImm32Operand;
477}
478def logical_imm64 : Operand<i64>, PatLeaf<(imm), [{
479 return AArch64_AM::isLogicalImmediate(N->getZExtValue(), 64);
480}], logical_imm64_XFORM> {
481 let PrintMethod = "printLogicalImm64";
482 let ParserMatchClass = LogicalImm64Operand;
483}
Arnaud A. de Grandmaisonf6432312014-07-10 15:12:26 +0000484def logical_imm32_not : Operand<i32> {
485 let ParserMatchClass = LogicalImm32NotOperand;
486}
487def logical_imm64_not : Operand<i64> {
488 let ParserMatchClass = LogicalImm64NotOperand;
489}
Tim Northover3b0846e2014-05-24 12:50:23 +0000490
491// imm0_65535 predicate - True if the immediate is in the range [0,65535].
492def Imm0_65535Operand : AsmImmRange<0, 65535>;
493def imm0_65535 : Operand<i32>, ImmLeaf<i32, [{
494 return ((uint32_t)Imm) < 65536;
495}]> {
496 let ParserMatchClass = Imm0_65535Operand;
497 let PrintMethod = "printHexImm";
498}
499
500// imm0_255 predicate - True if the immediate is in the range [0,255].
501def Imm0_255Operand : AsmOperandClass { let Name = "Imm0_255"; }
502def imm0_255 : Operand<i32>, ImmLeaf<i32, [{
503 return ((uint32_t)Imm) < 256;
504}]> {
505 let ParserMatchClass = Imm0_255Operand;
506 let PrintMethod = "printHexImm";
507}
508
509// imm0_127 predicate - True if the immediate is in the range [0,127]
510def Imm0_127Operand : AsmImmRange<0, 127>;
511def imm0_127 : Operand<i32>, ImmLeaf<i32, [{
512 return ((uint32_t)Imm) < 128;
513}]> {
514 let ParserMatchClass = Imm0_127Operand;
515 let PrintMethod = "printHexImm";
516}
517
518// NOTE: These imm0_N operands have to be of type i64 because i64 is the size
519// for all shift-amounts.
520
521// imm0_63 predicate - True if the immediate is in the range [0,63]
522def imm0_63 : Operand<i64>, ImmLeaf<i64, [{
523 return ((uint64_t)Imm) < 64;
524}]> {
525 let ParserMatchClass = Imm0_63Operand;
526}
527
528// imm0_31 predicate - True if the immediate is in the range [0,31]
529def imm0_31 : Operand<i64>, ImmLeaf<i64, [{
530 return ((uint64_t)Imm) < 32;
531}]> {
532 let ParserMatchClass = Imm0_31Operand;
533}
534
Matthias Braunaf7d7702015-07-16 20:02:37 +0000535// True if the 32-bit immediate is in the range [0,31]
536def imm32_0_31 : Operand<i32>, ImmLeaf<i32, [{
537 return ((uint64_t)Imm) < 32;
538}]> {
539 let ParserMatchClass = Imm0_31Operand;
540}
541
Alexandros Lamprineas1bab1912015-10-05 13:42:31 +0000542// imm0_1 predicate - True if the immediate is in the range [0,1]
543def imm0_1 : Operand<i64>, ImmLeaf<i64, [{
544 return ((uint64_t)Imm) < 2;
545}]> {
546 let ParserMatchClass = Imm0_1Operand;
547}
548
Tim Northover3b0846e2014-05-24 12:50:23 +0000549// imm0_15 predicate - True if the immediate is in the range [0,15]
550def imm0_15 : Operand<i64>, ImmLeaf<i64, [{
551 return ((uint64_t)Imm) < 16;
552}]> {
553 let ParserMatchClass = Imm0_15Operand;
554}
555
556// imm0_7 predicate - True if the immediate is in the range [0,7]
557def imm0_7 : Operand<i64>, ImmLeaf<i64, [{
558 return ((uint64_t)Imm) < 8;
559}]> {
560 let ParserMatchClass = Imm0_7Operand;
561}
562
Yi Kong23550662014-07-17 10:50:20 +0000563// imm32_0_15 predicate - True if the 32-bit immediate is in the range [0,15]
564def imm32_0_15 : Operand<i32>, ImmLeaf<i32, [{
565 return ((uint32_t)Imm) < 16;
Matthias Braunaf7d7702015-07-16 20:02:37 +0000566}]> {
567 let ParserMatchClass = Imm0_15Operand;
568}
Yi Kong23550662014-07-17 10:50:20 +0000569
Tim Northover3b0846e2014-05-24 12:50:23 +0000570// An arithmetic shifter operand:
571// {7-6} - shift type: 00 = lsl, 01 = lsr, 10 = asr
572// {5-0} - imm6
573class arith_shift<ValueType Ty, int width> : Operand<Ty> {
574 let PrintMethod = "printShifter";
575 let ParserMatchClass = !cast<AsmOperandClass>(
576 "ArithmeticShifterOperand" # width);
577}
578
579def arith_shift32 : arith_shift<i32, 32>;
580def arith_shift64 : arith_shift<i64, 64>;
581
582class arith_shifted_reg<ValueType Ty, RegisterClass regclass, int width>
583 : Operand<Ty>,
584 ComplexPattern<Ty, 2, "SelectArithShiftedRegister", []> {
585 let PrintMethod = "printShiftedRegister";
586 let MIOperandInfo = (ops regclass, !cast<Operand>("arith_shift" # width));
587}
588
589def arith_shifted_reg32 : arith_shifted_reg<i32, GPR32, 32>;
590def arith_shifted_reg64 : arith_shifted_reg<i64, GPR64, 64>;
591
592// An arithmetic shifter operand:
593// {7-6} - shift type: 00 = lsl, 01 = lsr, 10 = asr, 11 = ror
594// {5-0} - imm6
595class logical_shift<int width> : Operand<i32> {
596 let PrintMethod = "printShifter";
597 let ParserMatchClass = !cast<AsmOperandClass>(
598 "LogicalShifterOperand" # width);
599}
600
601def logical_shift32 : logical_shift<32>;
602def logical_shift64 : logical_shift<64>;
603
604class logical_shifted_reg<ValueType Ty, RegisterClass regclass, Operand shiftop>
605 : Operand<Ty>,
606 ComplexPattern<Ty, 2, "SelectLogicalShiftedRegister", []> {
607 let PrintMethod = "printShiftedRegister";
608 let MIOperandInfo = (ops regclass, shiftop);
609}
610
611def logical_shifted_reg32 : logical_shifted_reg<i32, GPR32, logical_shift32>;
612def logical_shifted_reg64 : logical_shifted_reg<i64, GPR64, logical_shift64>;
613
614// A logical vector shifter operand:
615// {7-6} - shift type: 00 = lsl
616// {5-0} - imm6: #0, #8, #16, or #24
617def logical_vec_shift : Operand<i32> {
618 let PrintMethod = "printShifter";
619 let EncoderMethod = "getVecShifterOpValue";
620 let ParserMatchClass = LogicalVecShifterOperand;
621}
622
623// A logical vector half-word shifter operand:
624// {7-6} - shift type: 00 = lsl
625// {5-0} - imm6: #0 or #8
626def logical_vec_hw_shift : Operand<i32> {
627 let PrintMethod = "printShifter";
628 let EncoderMethod = "getVecShifterOpValue";
629 let ParserMatchClass = LogicalVecHalfWordShifterOperand;
630}
631
632// A vector move shifter operand:
633// {0} - imm1: #8 or #16
634def move_vec_shift : Operand<i32> {
635 let PrintMethod = "printShifter";
636 let EncoderMethod = "getMoveVecShifterOpValue";
637 let ParserMatchClass = MoveVecShifterOperand;
638}
639
Arnaud A. de Grandmaison650c5202015-07-01 15:05:58 +0000640let DiagnosticType = "AddSubSecondSource" in {
641 def AddSubImmOperand : AsmOperandClass {
642 let Name = "AddSubImm";
643 let ParserMethod = "tryParseAddSubImm";
644 }
645 def AddSubImmNegOperand : AsmOperandClass {
646 let Name = "AddSubImmNeg";
647 let ParserMethod = "tryParseAddSubImm";
648 }
Tim Northover3b0846e2014-05-24 12:50:23 +0000649}
650// An ADD/SUB immediate shifter operand:
651// second operand:
652// {7-6} - shift type: 00 = lsl
653// {5-0} - imm6: #0 or #12
654class addsub_shifted_imm<ValueType Ty>
655 : Operand<Ty>, ComplexPattern<Ty, 2, "SelectArithImmed", [imm]> {
656 let PrintMethod = "printAddSubImm";
657 let EncoderMethod = "getAddSubImmOpValue";
658 let ParserMatchClass = AddSubImmOperand;
659 let MIOperandInfo = (ops i32imm, i32imm);
660}
661
Arnaud A. de Grandmaison650c5202015-07-01 15:05:58 +0000662class addsub_shifted_imm_neg<ValueType Ty>
663 : Operand<Ty> {
664 let EncoderMethod = "getAddSubImmOpValue";
665 let ParserMatchClass = AddSubImmNegOperand;
666 let MIOperandInfo = (ops i32imm, i32imm);
667}
668
Tim Northover3b0846e2014-05-24 12:50:23 +0000669def addsub_shifted_imm32 : addsub_shifted_imm<i32>;
670def addsub_shifted_imm64 : addsub_shifted_imm<i64>;
Arnaud A. de Grandmaison650c5202015-07-01 15:05:58 +0000671def addsub_shifted_imm32_neg : addsub_shifted_imm_neg<i32>;
672def addsub_shifted_imm64_neg : addsub_shifted_imm_neg<i64>;
Tim Northover3b0846e2014-05-24 12:50:23 +0000673
674class neg_addsub_shifted_imm<ValueType Ty>
675 : Operand<Ty>, ComplexPattern<Ty, 2, "SelectNegArithImmed", [imm]> {
676 let PrintMethod = "printAddSubImm";
677 let EncoderMethod = "getAddSubImmOpValue";
678 let ParserMatchClass = AddSubImmOperand;
679 let MIOperandInfo = (ops i32imm, i32imm);
680}
681
682def neg_addsub_shifted_imm32 : neg_addsub_shifted_imm<i32>;
683def neg_addsub_shifted_imm64 : neg_addsub_shifted_imm<i64>;
684
685// An extend operand:
686// {5-3} - extend type
687// {2-0} - imm3
688def arith_extend : Operand<i32> {
689 let PrintMethod = "printArithExtend";
690 let ParserMatchClass = ExtendOperand;
691}
692def arith_extend64 : Operand<i32> {
693 let PrintMethod = "printArithExtend";
694 let ParserMatchClass = ExtendOperand64;
695}
696
697// 'extend' that's a lsl of a 64-bit register.
698def arith_extendlsl64 : Operand<i32> {
699 let PrintMethod = "printArithExtend";
700 let ParserMatchClass = ExtendOperandLSL64;
701}
702
703class arith_extended_reg32<ValueType Ty> : Operand<Ty>,
704 ComplexPattern<Ty, 2, "SelectArithExtendedRegister", []> {
705 let PrintMethod = "printExtendedRegister";
706 let MIOperandInfo = (ops GPR32, arith_extend);
707}
708
709class arith_extended_reg32to64<ValueType Ty> : Operand<Ty>,
710 ComplexPattern<Ty, 2, "SelectArithExtendedRegister", []> {
711 let PrintMethod = "printExtendedRegister";
712 let MIOperandInfo = (ops GPR32, arith_extend64);
713}
714
715// Floating-point immediate.
716def fpimm32 : Operand<f32>,
717 PatLeaf<(f32 fpimm), [{
718 return AArch64_AM::getFP32Imm(N->getValueAPF()) != -1;
719 }], SDNodeXForm<fpimm, [{
720 APFloat InVal = N->getValueAPF();
721 uint32_t enc = AArch64_AM::getFP32Imm(InVal);
Sergey Dmitrouk842a51b2015-04-28 14:05:47 +0000722 return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32);
Tim Northover3b0846e2014-05-24 12:50:23 +0000723 }]>> {
724 let ParserMatchClass = FPImmOperand;
725 let PrintMethod = "printFPImmOperand";
726}
727def fpimm64 : Operand<f64>,
728 PatLeaf<(f64 fpimm), [{
729 return AArch64_AM::getFP64Imm(N->getValueAPF()) != -1;
730 }], SDNodeXForm<fpimm, [{
731 APFloat InVal = N->getValueAPF();
732 uint32_t enc = AArch64_AM::getFP64Imm(InVal);
Sergey Dmitrouk842a51b2015-04-28 14:05:47 +0000733 return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32);
Tim Northover3b0846e2014-05-24 12:50:23 +0000734 }]>> {
735 let ParserMatchClass = FPImmOperand;
736 let PrintMethod = "printFPImmOperand";
737}
738
739def fpimm8 : Operand<i32> {
740 let ParserMatchClass = FPImmOperand;
741 let PrintMethod = "printFPImmOperand";
742}
743
744def fpimm0 : PatLeaf<(fpimm), [{
745 return N->isExactlyValue(+0.0);
746}]>;
747
748// Vector lane operands
749class AsmVectorIndex<string Suffix> : AsmOperandClass {
750 let Name = "VectorIndex" # Suffix;
751 let DiagnosticType = "InvalidIndex" # Suffix;
752}
753def VectorIndex1Operand : AsmVectorIndex<"1">;
754def VectorIndexBOperand : AsmVectorIndex<"B">;
755def VectorIndexHOperand : AsmVectorIndex<"H">;
756def VectorIndexSOperand : AsmVectorIndex<"S">;
757def VectorIndexDOperand : AsmVectorIndex<"D">;
758
759def VectorIndex1 : Operand<i64>, ImmLeaf<i64, [{
760 return ((uint64_t)Imm) == 1;
761}]> {
762 let ParserMatchClass = VectorIndex1Operand;
763 let PrintMethod = "printVectorIndex";
764 let MIOperandInfo = (ops i64imm);
765}
766def VectorIndexB : Operand<i64>, ImmLeaf<i64, [{
767 return ((uint64_t)Imm) < 16;
768}]> {
769 let ParserMatchClass = VectorIndexBOperand;
770 let PrintMethod = "printVectorIndex";
771 let MIOperandInfo = (ops i64imm);
772}
773def VectorIndexH : Operand<i64>, ImmLeaf<i64, [{
774 return ((uint64_t)Imm) < 8;
775}]> {
776 let ParserMatchClass = VectorIndexHOperand;
777 let PrintMethod = "printVectorIndex";
778 let MIOperandInfo = (ops i64imm);
779}
780def VectorIndexS : Operand<i64>, ImmLeaf<i64, [{
781 return ((uint64_t)Imm) < 4;
782}]> {
783 let ParserMatchClass = VectorIndexSOperand;
784 let PrintMethod = "printVectorIndex";
785 let MIOperandInfo = (ops i64imm);
786}
787def VectorIndexD : Operand<i64>, ImmLeaf<i64, [{
788 return ((uint64_t)Imm) < 2;
789}]> {
790 let ParserMatchClass = VectorIndexDOperand;
791 let PrintMethod = "printVectorIndex";
792 let MIOperandInfo = (ops i64imm);
793}
794
795// 8-bit immediate for AdvSIMD where 64-bit values of the form:
796// aaaaaaaa bbbbbbbb cccccccc dddddddd eeeeeeee ffffffff gggggggg hhhhhhhh
797// are encoded as the eight bit value 'abcdefgh'.
798def simdimmtype10 : Operand<i32>,
799 PatLeaf<(f64 fpimm), [{
800 return AArch64_AM::isAdvSIMDModImmType10(N->getValueAPF()
801 .bitcastToAPInt()
802 .getZExtValue());
803 }], SDNodeXForm<fpimm, [{
804 APFloat InVal = N->getValueAPF();
805 uint32_t enc = AArch64_AM::encodeAdvSIMDModImmType10(N->getValueAPF()
806 .bitcastToAPInt()
807 .getZExtValue());
Sergey Dmitrouk842a51b2015-04-28 14:05:47 +0000808 return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32);
Tim Northover3b0846e2014-05-24 12:50:23 +0000809 }]>> {
810 let ParserMatchClass = SIMDImmType10Operand;
811 let PrintMethod = "printSIMDType10Operand";
812}
813
814
815//---
816// System management
817//---
818
819// Base encoding for system instruction operands.
820let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in
Saleem Abdulrasoolf74d48a2014-07-12 21:20:49 +0000821class BaseSystemI<bit L, dag oops, dag iops, string asm, string operands,
822 list<dag> pattern = []>
823 : I<oops, iops, asm, operands, "", pattern> {
Tim Northover3b0846e2014-05-24 12:50:23 +0000824 let Inst{31-22} = 0b1101010100;
825 let Inst{21} = L;
826}
827
828// System instructions which do not have an Rt register.
Saleem Abdulrasoolf74d48a2014-07-12 21:20:49 +0000829class SimpleSystemI<bit L, dag iops, string asm, string operands,
830 list<dag> pattern = []>
831 : BaseSystemI<L, (outs), iops, asm, operands, pattern> {
Tim Northover3b0846e2014-05-24 12:50:23 +0000832 let Inst{4-0} = 0b11111;
833}
834
835// System instructions which have an Rt register.
836class RtSystemI<bit L, dag oops, dag iops, string asm, string operands>
837 : BaseSystemI<L, oops, iops, asm, operands>,
838 Sched<[WriteSys]> {
839 bits<5> Rt;
840 let Inst{4-0} = Rt;
841}
842
843// Hint instructions that take both a CRm and a 3-bit immediate.
Saleem Abdulrasoolf74d48a2014-07-12 21:20:49 +0000844// NOTE: ideally, this would have mayStore = 0, mayLoad = 0, but we cannot
845// model patterns with sufficiently fine granularity
846let mayStore = 1, mayLoad = 1, hasSideEffects = 1 in
847 class HintI<string mnemonic>
Ahmed Bougacha63fae0e2015-09-02 18:52:54 +0000848 : SimpleSystemI<0, (ins imm0_127:$imm), mnemonic#"\t$imm", "",
Saleem Abdulrasoolf74d48a2014-07-12 21:20:49 +0000849 [(int_aarch64_hint imm0_127:$imm)]>,
850 Sched<[WriteHint]> {
851 bits <7> imm;
852 let Inst{20-12} = 0b000110010;
853 let Inst{11-5} = imm;
854 }
Tim Northover3b0846e2014-05-24 12:50:23 +0000855
856// System instructions taking a single literal operand which encodes into
857// CRm. op2 differentiates the opcodes.
858def BarrierAsmOperand : AsmOperandClass {
859 let Name = "Barrier";
860 let ParserMethod = "tryParseBarrierOperand";
861}
862def barrier_op : Operand<i32> {
863 let PrintMethod = "printBarrierOption";
864 let ParserMatchClass = BarrierAsmOperand;
865}
Yi Kong23550662014-07-17 10:50:20 +0000866class CRmSystemI<Operand crmtype, bits<3> opc, string asm,
867 list<dag> pattern = []>
868 : SimpleSystemI<0, (ins crmtype:$CRm), asm, "\t$CRm", pattern>,
Tim Northover3b0846e2014-05-24 12:50:23 +0000869 Sched<[WriteBarrier]> {
870 bits<4> CRm;
871 let Inst{20-12} = 0b000110011;
872 let Inst{11-8} = CRm;
873 let Inst{7-5} = opc;
874}
875
876// MRS/MSR system instructions. These have different operand classes because
877// a different subset of registers can be accessed through each instruction.
878def MRSSystemRegisterOperand : AsmOperandClass {
879 let Name = "MRSSystemRegister";
880 let ParserMethod = "tryParseSysReg";
881 let DiagnosticType = "MRS";
882}
Tom Coxone493f172014-10-01 10:13:59 +0000883// concatenation of op0, op1, CRn, CRm, op2. 16-bit immediate.
Tim Northover3b0846e2014-05-24 12:50:23 +0000884def mrs_sysreg_op : Operand<i32> {
885 let ParserMatchClass = MRSSystemRegisterOperand;
886 let DecoderMethod = "DecodeMRSSystemRegister";
887 let PrintMethod = "printMRSSystemRegister";
888}
889
890def MSRSystemRegisterOperand : AsmOperandClass {
891 let Name = "MSRSystemRegister";
892 let ParserMethod = "tryParseSysReg";
893 let DiagnosticType = "MSR";
894}
895def msr_sysreg_op : Operand<i32> {
896 let ParserMatchClass = MSRSystemRegisterOperand;
897 let DecoderMethod = "DecodeMSRSystemRegister";
898 let PrintMethod = "printMSRSystemRegister";
899}
900
901class MRSI : RtSystemI<1, (outs GPR64:$Rt), (ins mrs_sysreg_op:$systemreg),
902 "mrs", "\t$Rt, $systemreg"> {
Tom Coxone493f172014-10-01 10:13:59 +0000903 bits<16> systemreg;
904 let Inst{20-5} = systemreg;
Tim Northover3b0846e2014-05-24 12:50:23 +0000905}
906
907// FIXME: Some of these def NZCV, others don't. Best way to model that?
908// Explicitly modeling each of the system register as a register class
909// would do it, but feels like overkill at this point.
910class MSRI : RtSystemI<0, (outs), (ins msr_sysreg_op:$systemreg, GPR64:$Rt),
911 "msr", "\t$systemreg, $Rt"> {
Tom Coxone493f172014-10-01 10:13:59 +0000912 bits<16> systemreg;
913 let Inst{20-5} = systemreg;
Tim Northover3b0846e2014-05-24 12:50:23 +0000914}
915
Alexandros Lamprineas1bab1912015-10-05 13:42:31 +0000916def SystemPStateFieldWithImm0_15Operand : AsmOperandClass {
917 let Name = "SystemPStateFieldWithImm0_15";
Tim Northover3b0846e2014-05-24 12:50:23 +0000918 let ParserMethod = "tryParseSysReg";
919}
Alexandros Lamprineas1bab1912015-10-05 13:42:31 +0000920def pstatefield4_op : Operand<i32> {
921 let ParserMatchClass = SystemPStateFieldWithImm0_15Operand;
Tim Northover3b0846e2014-05-24 12:50:23 +0000922 let PrintMethod = "printSystemPStateField";
923}
924
925let Defs = [NZCV] in
Alexandros Lamprineas1bab1912015-10-05 13:42:31 +0000926class MSRpstateImm0_15
927 : SimpleSystemI<0, (ins pstatefield4_op:$pstatefield, imm0_15:$imm),
928 "msr", "\t$pstatefield, $imm">,
Tim Northover3b0846e2014-05-24 12:50:23 +0000929 Sched<[WriteSys]> {
930 bits<6> pstatefield;
931 bits<4> imm;
932 let Inst{20-19} = 0b00;
933 let Inst{18-16} = pstatefield{5-3};
934 let Inst{15-12} = 0b0100;
935 let Inst{11-8} = imm;
936 let Inst{7-5} = pstatefield{2-0};
937
938 let DecoderMethod = "DecodeSystemPStateInstruction";
Petr Pavlu097adfb2015-07-15 08:10:30 +0000939 // MSRpstateI aliases with MSRI. When the MSRpstateI decoder method returns
940 // Fail the decoder should attempt to decode the instruction as MSRI.
941 let hasCompleteDecoder = 0;
Tim Northover3b0846e2014-05-24 12:50:23 +0000942}
943
Alexandros Lamprineas1bab1912015-10-05 13:42:31 +0000944def SystemPStateFieldWithImm0_1Operand : AsmOperandClass {
945 let Name = "SystemPStateFieldWithImm0_1";
946 let ParserMethod = "tryParseSysReg";
947}
948def pstatefield1_op : Operand<i32> {
949 let ParserMatchClass = SystemPStateFieldWithImm0_1Operand;
950 let PrintMethod = "printSystemPStateField";
951}
952
953let Defs = [NZCV] in
954class MSRpstateImm0_1
955 : SimpleSystemI<0, (ins pstatefield1_op:$pstatefield, imm0_1:$imm),
956 "msr", "\t$pstatefield, $imm">,
957 Sched<[WriteSys]> {
958 bits<6> pstatefield;
959 bit imm;
960 let Inst{20-19} = 0b00;
961 let Inst{18-16} = pstatefield{5-3};
962 let Inst{15-9} = 0b0100000;
963 let Inst{8} = imm;
964 let Inst{7-5} = pstatefield{2-0};
965
966 let DecoderMethod = "DecodeSystemPStateInstruction";
967 // MSRpstateI aliases with MSRI. When the MSRpstateI decoder method returns
968 // Fail the decoder should attempt to decode the instruction as MSRI.
969 let hasCompleteDecoder = 0;
970}
971
Tim Northover3b0846e2014-05-24 12:50:23 +0000972// SYS and SYSL generic system instructions.
973def SysCRAsmOperand : AsmOperandClass {
974 let Name = "SysCR";
975 let ParserMethod = "tryParseSysCROperand";
976}
977
978def sys_cr_op : Operand<i32> {
979 let PrintMethod = "printSysCROperand";
980 let ParserMatchClass = SysCRAsmOperand;
981}
982
983class SystemXtI<bit L, string asm>
984 : RtSystemI<L, (outs),
985 (ins imm0_7:$op1, sys_cr_op:$Cn, sys_cr_op:$Cm, imm0_7:$op2, GPR64:$Rt),
986 asm, "\t$op1, $Cn, $Cm, $op2, $Rt"> {
987 bits<3> op1;
988 bits<4> Cn;
989 bits<4> Cm;
990 bits<3> op2;
991 let Inst{20-19} = 0b01;
992 let Inst{18-16} = op1;
993 let Inst{15-12} = Cn;
994 let Inst{11-8} = Cm;
995 let Inst{7-5} = op2;
996}
997
998class SystemLXtI<bit L, string asm>
999 : RtSystemI<L, (outs),
1000 (ins GPR64:$Rt, imm0_7:$op1, sys_cr_op:$Cn, sys_cr_op:$Cm, imm0_7:$op2),
1001 asm, "\t$Rt, $op1, $Cn, $Cm, $op2"> {
1002 bits<3> op1;
1003 bits<4> Cn;
1004 bits<4> Cm;
1005 bits<3> op2;
1006 let Inst{20-19} = 0b01;
1007 let Inst{18-16} = op1;
1008 let Inst{15-12} = Cn;
1009 let Inst{11-8} = Cm;
1010 let Inst{7-5} = op2;
1011}
1012
1013
1014// Branch (register) instructions:
1015//
1016// case opc of
1017// 0001 blr
1018// 0000 br
1019// 0101 dret
1020// 0100 eret
1021// 0010 ret
1022// otherwise UNDEFINED
1023class BaseBranchReg<bits<4> opc, dag oops, dag iops, string asm,
1024 string operands, list<dag> pattern>
1025 : I<oops, iops, asm, operands, "", pattern>, Sched<[WriteBrReg]> {
1026 let Inst{31-25} = 0b1101011;
1027 let Inst{24-21} = opc;
1028 let Inst{20-16} = 0b11111;
1029 let Inst{15-10} = 0b000000;
1030 let Inst{4-0} = 0b00000;
1031}
1032
1033class BranchReg<bits<4> opc, string asm, list<dag> pattern>
1034 : BaseBranchReg<opc, (outs), (ins GPR64:$Rn), asm, "\t$Rn", pattern> {
1035 bits<5> Rn;
1036 let Inst{9-5} = Rn;
1037}
1038
1039let mayLoad = 0, mayStore = 0, hasSideEffects = 1, isReturn = 1 in
1040class SpecialReturn<bits<4> opc, string asm>
1041 : BaseBranchReg<opc, (outs), (ins), asm, "", []> {
1042 let Inst{9-5} = 0b11111;
1043}
1044
1045//---
1046// Conditional branch instruction.
1047//---
1048
1049// Condition code.
1050// 4-bit immediate. Pretty-printed as <cc>
1051def ccode : Operand<i32> {
1052 let PrintMethod = "printCondCode";
1053 let ParserMatchClass = CondCode;
1054}
1055def inv_ccode : Operand<i32> {
Artyom Skrobov6c8682e2014-06-10 13:11:35 +00001056 // AL and NV are invalid in the aliases which use inv_ccode
Tim Northover3b0846e2014-05-24 12:50:23 +00001057 let PrintMethod = "printInverseCondCode";
1058 let ParserMatchClass = CondCode;
Artyom Skrobov6c8682e2014-06-10 13:11:35 +00001059 let MCOperandPredicate = [{
1060 return MCOp.isImm() &&
1061 MCOp.getImm() != AArch64CC::AL &&
1062 MCOp.getImm() != AArch64CC::NV;
1063 }];
Tim Northover3b0846e2014-05-24 12:50:23 +00001064}
1065
1066// Conditional branch target. 19-bit immediate. The low two bits of the target
1067// offset are implied zero and so are not part of the immediate.
1068def PCRelLabel19Operand : AsmOperandClass {
1069 let Name = "PCRelLabel19";
1070 let DiagnosticType = "InvalidLabel";
1071}
1072def am_brcond : Operand<OtherVT> {
1073 let EncoderMethod = "getCondBranchTargetOpValue";
1074 let DecoderMethod = "DecodePCRelLabel19";
1075 let PrintMethod = "printAlignedLabel";
1076 let ParserMatchClass = PCRelLabel19Operand;
1077}
1078
1079class BranchCond : I<(outs), (ins ccode:$cond, am_brcond:$target),
1080 "b", ".$cond\t$target", "",
1081 [(AArch64brcond bb:$target, imm:$cond, NZCV)]>,
1082 Sched<[WriteBr]> {
1083 let isBranch = 1;
1084 let isTerminator = 1;
1085 let Uses = [NZCV];
1086
1087 bits<4> cond;
1088 bits<19> target;
1089 let Inst{31-24} = 0b01010100;
1090 let Inst{23-5} = target;
1091 let Inst{4} = 0;
1092 let Inst{3-0} = cond;
1093}
1094
1095//---
1096// Compare-and-branch instructions.
1097//---
1098class BaseCmpBranch<RegisterClass regtype, bit op, string asm, SDNode node>
1099 : I<(outs), (ins regtype:$Rt, am_brcond:$target),
1100 asm, "\t$Rt, $target", "",
1101 [(node regtype:$Rt, bb:$target)]>,
1102 Sched<[WriteBr]> {
1103 let isBranch = 1;
1104 let isTerminator = 1;
1105
1106 bits<5> Rt;
1107 bits<19> target;
1108 let Inst{30-25} = 0b011010;
1109 let Inst{24} = op;
1110 let Inst{23-5} = target;
1111 let Inst{4-0} = Rt;
1112}
1113
1114multiclass CmpBranch<bit op, string asm, SDNode node> {
1115 def W : BaseCmpBranch<GPR32, op, asm, node> {
1116 let Inst{31} = 0;
1117 }
1118 def X : BaseCmpBranch<GPR64, op, asm, node> {
1119 let Inst{31} = 1;
1120 }
1121}
1122
1123//---
1124// Test-bit-and-branch instructions.
1125//---
1126// Test-and-branch target. 14-bit sign-extended immediate. The low two bits of
1127// the target offset are implied zero and so are not part of the immediate.
1128def BranchTarget14Operand : AsmOperandClass {
1129 let Name = "BranchTarget14";
1130}
1131def am_tbrcond : Operand<OtherVT> {
1132 let EncoderMethod = "getTestBranchTargetOpValue";
1133 let PrintMethod = "printAlignedLabel";
1134 let ParserMatchClass = BranchTarget14Operand;
1135}
1136
1137// AsmOperand classes to emit (or not) special diagnostics
1138def TBZImm0_31Operand : AsmOperandClass {
1139 let Name = "TBZImm0_31";
1140 let PredicateMethod = "isImm0_31";
1141 let RenderMethod = "addImm0_31Operands";
1142}
1143def TBZImm32_63Operand : AsmOperandClass {
1144 let Name = "Imm32_63";
1145 let DiagnosticType = "InvalidImm0_63";
1146}
1147
1148class tbz_imm0_31<AsmOperandClass matcher> : Operand<i64>, ImmLeaf<i64, [{
1149 return (((uint32_t)Imm) < 32);
1150}]> {
1151 let ParserMatchClass = matcher;
1152}
1153
1154def tbz_imm0_31_diag : tbz_imm0_31<Imm0_31Operand>;
1155def tbz_imm0_31_nodiag : tbz_imm0_31<TBZImm0_31Operand>;
1156
1157def tbz_imm32_63 : Operand<i64>, ImmLeaf<i64, [{
1158 return (((uint32_t)Imm) > 31) && (((uint32_t)Imm) < 64);
1159}]> {
1160 let ParserMatchClass = TBZImm32_63Operand;
1161}
1162
1163class BaseTestBranch<RegisterClass regtype, Operand immtype,
1164 bit op, string asm, SDNode node>
1165 : I<(outs), (ins regtype:$Rt, immtype:$bit_off, am_tbrcond:$target),
1166 asm, "\t$Rt, $bit_off, $target", "",
1167 [(node regtype:$Rt, immtype:$bit_off, bb:$target)]>,
1168 Sched<[WriteBr]> {
1169 let isBranch = 1;
1170 let isTerminator = 1;
1171
1172 bits<5> Rt;
1173 bits<6> bit_off;
1174 bits<14> target;
1175
1176 let Inst{30-25} = 0b011011;
1177 let Inst{24} = op;
1178 let Inst{23-19} = bit_off{4-0};
1179 let Inst{18-5} = target;
1180 let Inst{4-0} = Rt;
1181
1182 let DecoderMethod = "DecodeTestAndBranch";
1183}
1184
1185multiclass TestBranch<bit op, string asm, SDNode node> {
1186 def W : BaseTestBranch<GPR32, tbz_imm0_31_diag, op, asm, node> {
1187 let Inst{31} = 0;
1188 }
1189
1190 def X : BaseTestBranch<GPR64, tbz_imm32_63, op, asm, node> {
1191 let Inst{31} = 1;
1192 }
1193
1194 // Alias X-reg with 0-31 imm to W-Reg.
1195 def : InstAlias<asm # "\t$Rd, $imm, $target",
1196 (!cast<Instruction>(NAME#"W") GPR32as64:$Rd,
1197 tbz_imm0_31_nodiag:$imm, am_tbrcond:$target), 0>;
1198 def : Pat<(node GPR64:$Rn, tbz_imm0_31_diag:$imm, bb:$target),
1199 (!cast<Instruction>(NAME#"W") (EXTRACT_SUBREG GPR64:$Rn, sub_32),
1200 tbz_imm0_31_diag:$imm, bb:$target)>;
1201}
1202
1203//---
1204// Unconditional branch (immediate) instructions.
1205//---
1206def BranchTarget26Operand : AsmOperandClass {
1207 let Name = "BranchTarget26";
1208 let DiagnosticType = "InvalidLabel";
1209}
1210def am_b_target : Operand<OtherVT> {
1211 let EncoderMethod = "getBranchTargetOpValue";
1212 let PrintMethod = "printAlignedLabel";
1213 let ParserMatchClass = BranchTarget26Operand;
1214}
1215def am_bl_target : Operand<i64> {
1216 let EncoderMethod = "getBranchTargetOpValue";
1217 let PrintMethod = "printAlignedLabel";
1218 let ParserMatchClass = BranchTarget26Operand;
1219}
1220
1221class BImm<bit op, dag iops, string asm, list<dag> pattern>
1222 : I<(outs), iops, asm, "\t$addr", "", pattern>, Sched<[WriteBr]> {
1223 bits<26> addr;
1224 let Inst{31} = op;
1225 let Inst{30-26} = 0b00101;
1226 let Inst{25-0} = addr;
1227
1228 let DecoderMethod = "DecodeUnconditionalBranch";
1229}
1230
1231class BranchImm<bit op, string asm, list<dag> pattern>
1232 : BImm<op, (ins am_b_target:$addr), asm, pattern>;
1233class CallImm<bit op, string asm, list<dag> pattern>
1234 : BImm<op, (ins am_bl_target:$addr), asm, pattern>;
1235
1236//---
1237// Basic one-operand data processing instructions.
1238//---
1239
1240let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
1241class BaseOneOperandData<bits<3> opc, RegisterClass regtype, string asm,
1242 SDPatternOperator node>
1243 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm, "\t$Rd, $Rn", "",
1244 [(set regtype:$Rd, (node regtype:$Rn))]>,
1245 Sched<[WriteI, ReadI]> {
1246 bits<5> Rd;
1247 bits<5> Rn;
1248
1249 let Inst{30-13} = 0b101101011000000000;
1250 let Inst{12-10} = opc;
1251 let Inst{9-5} = Rn;
1252 let Inst{4-0} = Rd;
1253}
1254
1255let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
1256multiclass OneOperandData<bits<3> opc, string asm,
1257 SDPatternOperator node = null_frag> {
1258 def Wr : BaseOneOperandData<opc, GPR32, asm, node> {
1259 let Inst{31} = 0;
1260 }
1261
1262 def Xr : BaseOneOperandData<opc, GPR64, asm, node> {
1263 let Inst{31} = 1;
1264 }
1265}
1266
1267class OneWRegData<bits<3> opc, string asm, SDPatternOperator node>
1268 : BaseOneOperandData<opc, GPR32, asm, node> {
1269 let Inst{31} = 0;
1270}
1271
1272class OneXRegData<bits<3> opc, string asm, SDPatternOperator node>
1273 : BaseOneOperandData<opc, GPR64, asm, node> {
1274 let Inst{31} = 1;
1275}
1276
1277//---
1278// Basic two-operand data processing instructions.
1279//---
1280class BaseBaseAddSubCarry<bit isSub, RegisterClass regtype, string asm,
1281 list<dag> pattern>
1282 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm),
1283 asm, "\t$Rd, $Rn, $Rm", "", pattern>,
1284 Sched<[WriteI, ReadI, ReadI]> {
1285 let Uses = [NZCV];
1286 bits<5> Rd;
1287 bits<5> Rn;
1288 bits<5> Rm;
1289 let Inst{30} = isSub;
1290 let Inst{28-21} = 0b11010000;
1291 let Inst{20-16} = Rm;
1292 let Inst{15-10} = 0;
1293 let Inst{9-5} = Rn;
1294 let Inst{4-0} = Rd;
1295}
1296
1297class BaseAddSubCarry<bit isSub, RegisterClass regtype, string asm,
1298 SDNode OpNode>
1299 : BaseBaseAddSubCarry<isSub, regtype, asm,
1300 [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm, NZCV))]>;
1301
1302class BaseAddSubCarrySetFlags<bit isSub, RegisterClass regtype, string asm,
1303 SDNode OpNode>
1304 : BaseBaseAddSubCarry<isSub, regtype, asm,
1305 [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm, NZCV)),
1306 (implicit NZCV)]> {
1307 let Defs = [NZCV];
1308}
1309
1310multiclass AddSubCarry<bit isSub, string asm, string asm_setflags,
1311 SDNode OpNode, SDNode OpNode_setflags> {
1312 def Wr : BaseAddSubCarry<isSub, GPR32, asm, OpNode> {
1313 let Inst{31} = 0;
1314 let Inst{29} = 0;
1315 }
1316 def Xr : BaseAddSubCarry<isSub, GPR64, asm, OpNode> {
1317 let Inst{31} = 1;
1318 let Inst{29} = 0;
1319 }
1320
1321 // Sets flags.
1322 def SWr : BaseAddSubCarrySetFlags<isSub, GPR32, asm_setflags,
1323 OpNode_setflags> {
1324 let Inst{31} = 0;
1325 let Inst{29} = 1;
1326 }
1327 def SXr : BaseAddSubCarrySetFlags<isSub, GPR64, asm_setflags,
1328 OpNode_setflags> {
1329 let Inst{31} = 1;
1330 let Inst{29} = 1;
1331 }
1332}
1333
1334class BaseTwoOperand<bits<4> opc, RegisterClass regtype, string asm,
1335 SDPatternOperator OpNode>
1336 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm),
1337 asm, "\t$Rd, $Rn, $Rm", "",
1338 [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm))]> {
1339 bits<5> Rd;
1340 bits<5> Rn;
1341 bits<5> Rm;
1342 let Inst{30-21} = 0b0011010110;
1343 let Inst{20-16} = Rm;
1344 let Inst{15-14} = 0b00;
1345 let Inst{13-10} = opc;
1346 let Inst{9-5} = Rn;
1347 let Inst{4-0} = Rd;
1348}
1349
1350class BaseDiv<bit isSigned, RegisterClass regtype, string asm,
1351 SDPatternOperator OpNode>
1352 : BaseTwoOperand<{0,0,1,?}, regtype, asm, OpNode> {
1353 let Inst{10} = isSigned;
1354}
1355
1356multiclass Div<bit isSigned, string asm, SDPatternOperator OpNode> {
1357 def Wr : BaseDiv<isSigned, GPR32, asm, OpNode>,
1358 Sched<[WriteID32, ReadID, ReadID]> {
1359 let Inst{31} = 0;
1360 }
1361 def Xr : BaseDiv<isSigned, GPR64, asm, OpNode>,
1362 Sched<[WriteID64, ReadID, ReadID]> {
1363 let Inst{31} = 1;
1364 }
1365}
1366
1367class BaseShift<bits<2> shift_type, RegisterClass regtype, string asm,
1368 SDPatternOperator OpNode = null_frag>
1369 : BaseTwoOperand<{1,0,?,?}, regtype, asm, OpNode>,
1370 Sched<[WriteIS, ReadI]> {
1371 let Inst{11-10} = shift_type;
1372}
1373
1374multiclass Shift<bits<2> shift_type, string asm, SDNode OpNode> {
1375 def Wr : BaseShift<shift_type, GPR32, asm> {
1376 let Inst{31} = 0;
1377 }
1378
1379 def Xr : BaseShift<shift_type, GPR64, asm, OpNode> {
1380 let Inst{31} = 1;
1381 }
1382
1383 def : Pat<(i32 (OpNode GPR32:$Rn, i64:$Rm)),
1384 (!cast<Instruction>(NAME # "Wr") GPR32:$Rn,
1385 (EXTRACT_SUBREG i64:$Rm, sub_32))>;
1386
1387 def : Pat<(i32 (OpNode GPR32:$Rn, (i64 (zext GPR32:$Rm)))),
1388 (!cast<Instruction>(NAME # "Wr") GPR32:$Rn, GPR32:$Rm)>;
1389
1390 def : Pat<(i32 (OpNode GPR32:$Rn, (i64 (anyext GPR32:$Rm)))),
1391 (!cast<Instruction>(NAME # "Wr") GPR32:$Rn, GPR32:$Rm)>;
1392
1393 def : Pat<(i32 (OpNode GPR32:$Rn, (i64 (sext GPR32:$Rm)))),
1394 (!cast<Instruction>(NAME # "Wr") GPR32:$Rn, GPR32:$Rm)>;
1395}
1396
1397class ShiftAlias<string asm, Instruction inst, RegisterClass regtype>
Ahmed Bougacha63fae0e2015-09-02 18:52:54 +00001398 : InstAlias<asm#"\t$dst, $src1, $src2",
Tim Northover3b0846e2014-05-24 12:50:23 +00001399 (inst regtype:$dst, regtype:$src1, regtype:$src2), 0>;
1400
1401class BaseMulAccum<bit isSub, bits<3> opc, RegisterClass multype,
1402 RegisterClass addtype, string asm,
1403 list<dag> pattern>
1404 : I<(outs addtype:$Rd), (ins multype:$Rn, multype:$Rm, addtype:$Ra),
1405 asm, "\t$Rd, $Rn, $Rm, $Ra", "", pattern> {
1406 bits<5> Rd;
1407 bits<5> Rn;
1408 bits<5> Rm;
1409 bits<5> Ra;
1410 let Inst{30-24} = 0b0011011;
1411 let Inst{23-21} = opc;
1412 let Inst{20-16} = Rm;
1413 let Inst{15} = isSub;
1414 let Inst{14-10} = Ra;
1415 let Inst{9-5} = Rn;
1416 let Inst{4-0} = Rd;
1417}
1418
1419multiclass MulAccum<bit isSub, string asm, SDNode AccNode> {
Gerolf Hoflehner97c383b2014-08-07 21:40:58 +00001420 // MADD/MSUB generation is decided by MachineCombiner.cpp
Tim Northover3b0846e2014-05-24 12:50:23 +00001421 def Wrrr : BaseMulAccum<isSub, 0b000, GPR32, GPR32, asm,
Gerolf Hoflehner97c383b2014-08-07 21:40:58 +00001422 [/*(set GPR32:$Rd, (AccNode GPR32:$Ra, (mul GPR32:$Rn, GPR32:$Rm)))*/]>,
Chad Rosier3fe0c872014-06-09 01:54:00 +00001423 Sched<[WriteIM32, ReadIM, ReadIM, ReadIMA]> {
Tim Northover3b0846e2014-05-24 12:50:23 +00001424 let Inst{31} = 0;
1425 }
1426
1427 def Xrrr : BaseMulAccum<isSub, 0b000, GPR64, GPR64, asm,
Gerolf Hoflehner97c383b2014-08-07 21:40:58 +00001428 [/*(set GPR64:$Rd, (AccNode GPR64:$Ra, (mul GPR64:$Rn, GPR64:$Rm)))*/]>,
Chad Rosier3fe0c872014-06-09 01:54:00 +00001429 Sched<[WriteIM64, ReadIM, ReadIM, ReadIMA]> {
Tim Northover3b0846e2014-05-24 12:50:23 +00001430 let Inst{31} = 1;
1431 }
1432}
1433
1434class WideMulAccum<bit isSub, bits<3> opc, string asm,
1435 SDNode AccNode, SDNode ExtNode>
1436 : BaseMulAccum<isSub, opc, GPR32, GPR64, asm,
1437 [(set GPR64:$Rd, (AccNode GPR64:$Ra,
1438 (mul (ExtNode GPR32:$Rn), (ExtNode GPR32:$Rm))))]>,
Chad Rosier3fe0c872014-06-09 01:54:00 +00001439 Sched<[WriteIM32, ReadIM, ReadIM, ReadIMA]> {
Tim Northover3b0846e2014-05-24 12:50:23 +00001440 let Inst{31} = 1;
1441}
1442
1443class MulHi<bits<3> opc, string asm, SDNode OpNode>
1444 : I<(outs GPR64:$Rd), (ins GPR64:$Rn, GPR64:$Rm),
1445 asm, "\t$Rd, $Rn, $Rm", "",
1446 [(set GPR64:$Rd, (OpNode GPR64:$Rn, GPR64:$Rm))]>,
1447 Sched<[WriteIM64, ReadIM, ReadIM]> {
1448 bits<5> Rd;
1449 bits<5> Rn;
1450 bits<5> Rm;
1451 let Inst{31-24} = 0b10011011;
1452 let Inst{23-21} = opc;
1453 let Inst{20-16} = Rm;
1454 let Inst{15} = 0;
1455 let Inst{9-5} = Rn;
1456 let Inst{4-0} = Rd;
1457
1458 // The Ra field of SMULH and UMULH is unused: it should be assembled as 31
1459 // (i.e. all bits 1) but is ignored by the processor.
1460 let PostEncoderMethod = "fixMulHigh";
1461}
1462
1463class MulAccumWAlias<string asm, Instruction inst>
Ahmed Bougacha63fae0e2015-09-02 18:52:54 +00001464 : InstAlias<asm#"\t$dst, $src1, $src2",
Tim Northover3b0846e2014-05-24 12:50:23 +00001465 (inst GPR32:$dst, GPR32:$src1, GPR32:$src2, WZR)>;
1466class MulAccumXAlias<string asm, Instruction inst>
Ahmed Bougacha63fae0e2015-09-02 18:52:54 +00001467 : InstAlias<asm#"\t$dst, $src1, $src2",
Tim Northover3b0846e2014-05-24 12:50:23 +00001468 (inst GPR64:$dst, GPR64:$src1, GPR64:$src2, XZR)>;
1469class WideMulAccumAlias<string asm, Instruction inst>
Ahmed Bougacha63fae0e2015-09-02 18:52:54 +00001470 : InstAlias<asm#"\t$dst, $src1, $src2",
Tim Northover3b0846e2014-05-24 12:50:23 +00001471 (inst GPR64:$dst, GPR32:$src1, GPR32:$src2, XZR)>;
1472
1473class BaseCRC32<bit sf, bits<2> sz, bit C, RegisterClass StreamReg,
1474 SDPatternOperator OpNode, string asm>
1475 : I<(outs GPR32:$Rd), (ins GPR32:$Rn, StreamReg:$Rm),
1476 asm, "\t$Rd, $Rn, $Rm", "",
1477 [(set GPR32:$Rd, (OpNode GPR32:$Rn, StreamReg:$Rm))]>,
1478 Sched<[WriteISReg, ReadI, ReadISReg]> {
1479 bits<5> Rd;
1480 bits<5> Rn;
1481 bits<5> Rm;
1482
1483 let Inst{31} = sf;
1484 let Inst{30-21} = 0b0011010110;
1485 let Inst{20-16} = Rm;
1486 let Inst{15-13} = 0b010;
1487 let Inst{12} = C;
1488 let Inst{11-10} = sz;
1489 let Inst{9-5} = Rn;
1490 let Inst{4-0} = Rd;
1491 let Predicates = [HasCRC];
1492}
1493
1494//---
1495// Address generation.
1496//---
1497
1498class ADRI<bit page, string asm, Operand adr, list<dag> pattern>
1499 : I<(outs GPR64:$Xd), (ins adr:$label), asm, "\t$Xd, $label", "",
1500 pattern>,
1501 Sched<[WriteI]> {
1502 bits<5> Xd;
1503 bits<21> label;
1504 let Inst{31} = page;
1505 let Inst{30-29} = label{1-0};
1506 let Inst{28-24} = 0b10000;
1507 let Inst{23-5} = label{20-2};
1508 let Inst{4-0} = Xd;
1509
1510 let DecoderMethod = "DecodeAdrInstruction";
1511}
1512
1513//---
1514// Move immediate.
1515//---
1516
1517def movimm32_imm : Operand<i32> {
1518 let ParserMatchClass = Imm0_65535Operand;
1519 let EncoderMethod = "getMoveWideImmOpValue";
1520 let PrintMethod = "printHexImm";
1521}
1522def movimm32_shift : Operand<i32> {
1523 let PrintMethod = "printShifter";
1524 let ParserMatchClass = MovImm32ShifterOperand;
1525}
1526def movimm64_shift : Operand<i32> {
1527 let PrintMethod = "printShifter";
1528 let ParserMatchClass = MovImm64ShifterOperand;
1529}
1530
1531let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
1532class BaseMoveImmediate<bits<2> opc, RegisterClass regtype, Operand shifter,
1533 string asm>
1534 : I<(outs regtype:$Rd), (ins movimm32_imm:$imm, shifter:$shift),
1535 asm, "\t$Rd, $imm$shift", "", []>,
1536 Sched<[WriteImm]> {
1537 bits<5> Rd;
1538 bits<16> imm;
1539 bits<6> shift;
1540 let Inst{30-29} = opc;
1541 let Inst{28-23} = 0b100101;
1542 let Inst{22-21} = shift{5-4};
1543 let Inst{20-5} = imm;
1544 let Inst{4-0} = Rd;
1545
1546 let DecoderMethod = "DecodeMoveImmInstruction";
1547}
1548
1549multiclass MoveImmediate<bits<2> opc, string asm> {
1550 def Wi : BaseMoveImmediate<opc, GPR32, movimm32_shift, asm> {
1551 let Inst{31} = 0;
1552 }
1553
1554 def Xi : BaseMoveImmediate<opc, GPR64, movimm64_shift, asm> {
1555 let Inst{31} = 1;
1556 }
1557}
1558
1559let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
1560class BaseInsertImmediate<bits<2> opc, RegisterClass regtype, Operand shifter,
1561 string asm>
1562 : I<(outs regtype:$Rd),
1563 (ins regtype:$src, movimm32_imm:$imm, shifter:$shift),
1564 asm, "\t$Rd, $imm$shift", "$src = $Rd", []>,
1565 Sched<[WriteI, ReadI]> {
1566 bits<5> Rd;
1567 bits<16> imm;
1568 bits<6> shift;
1569 let Inst{30-29} = opc;
1570 let Inst{28-23} = 0b100101;
1571 let Inst{22-21} = shift{5-4};
1572 let Inst{20-5} = imm;
1573 let Inst{4-0} = Rd;
1574
1575 let DecoderMethod = "DecodeMoveImmInstruction";
1576}
1577
1578multiclass InsertImmediate<bits<2> opc, string asm> {
1579 def Wi : BaseInsertImmediate<opc, GPR32, movimm32_shift, asm> {
1580 let Inst{31} = 0;
1581 }
1582
1583 def Xi : BaseInsertImmediate<opc, GPR64, movimm64_shift, asm> {
1584 let Inst{31} = 1;
1585 }
1586}
1587
1588//---
1589// Add/Subtract
1590//---
1591
1592class BaseAddSubImm<bit isSub, bit setFlags, RegisterClass dstRegtype,
1593 RegisterClass srcRegtype, addsub_shifted_imm immtype,
1594 string asm, SDPatternOperator OpNode>
1595 : I<(outs dstRegtype:$Rd), (ins srcRegtype:$Rn, immtype:$imm),
1596 asm, "\t$Rd, $Rn, $imm", "",
1597 [(set dstRegtype:$Rd, (OpNode srcRegtype:$Rn, immtype:$imm))]>,
1598 Sched<[WriteI, ReadI]> {
1599 bits<5> Rd;
1600 bits<5> Rn;
1601 bits<14> imm;
1602 let Inst{30} = isSub;
1603 let Inst{29} = setFlags;
1604 let Inst{28-24} = 0b10001;
1605 let Inst{23-22} = imm{13-12}; // '00' => lsl #0, '01' => lsl #12
1606 let Inst{21-10} = imm{11-0};
1607 let Inst{9-5} = Rn;
1608 let Inst{4-0} = Rd;
1609 let DecoderMethod = "DecodeBaseAddSubImm";
1610}
1611
1612class BaseAddSubRegPseudo<RegisterClass regtype,
1613 SDPatternOperator OpNode>
1614 : Pseudo<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm),
1615 [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm))]>,
1616 Sched<[WriteI, ReadI, ReadI]>;
1617
1618class BaseAddSubSReg<bit isSub, bit setFlags, RegisterClass regtype,
1619 arith_shifted_reg shifted_regtype, string asm,
1620 SDPatternOperator OpNode>
1621 : I<(outs regtype:$Rd), (ins regtype:$Rn, shifted_regtype:$Rm),
1622 asm, "\t$Rd, $Rn, $Rm", "",
1623 [(set regtype:$Rd, (OpNode regtype:$Rn, shifted_regtype:$Rm))]>,
1624 Sched<[WriteISReg, ReadI, ReadISReg]> {
1625 // The operands are in order to match the 'addr' MI operands, so we
1626 // don't need an encoder method and by-name matching. Just use the default
1627 // in-order handling. Since we're using by-order, make sure the names
1628 // do not match.
1629 bits<5> dst;
1630 bits<5> src1;
1631 bits<5> src2;
1632 bits<8> shift;
1633 let Inst{30} = isSub;
1634 let Inst{29} = setFlags;
1635 let Inst{28-24} = 0b01011;
1636 let Inst{23-22} = shift{7-6};
1637 let Inst{21} = 0;
1638 let Inst{20-16} = src2;
1639 let Inst{15-10} = shift{5-0};
1640 let Inst{9-5} = src1;
1641 let Inst{4-0} = dst;
1642
1643 let DecoderMethod = "DecodeThreeAddrSRegInstruction";
1644}
1645
1646class BaseAddSubEReg<bit isSub, bit setFlags, RegisterClass dstRegtype,
1647 RegisterClass src1Regtype, Operand src2Regtype,
1648 string asm, SDPatternOperator OpNode>
1649 : I<(outs dstRegtype:$R1),
1650 (ins src1Regtype:$R2, src2Regtype:$R3),
1651 asm, "\t$R1, $R2, $R3", "",
1652 [(set dstRegtype:$R1, (OpNode src1Regtype:$R2, src2Regtype:$R3))]>,
1653 Sched<[WriteIEReg, ReadI, ReadIEReg]> {
1654 bits<5> Rd;
1655 bits<5> Rn;
1656 bits<5> Rm;
1657 bits<6> ext;
1658 let Inst{30} = isSub;
1659 let Inst{29} = setFlags;
1660 let Inst{28-24} = 0b01011;
1661 let Inst{23-21} = 0b001;
1662 let Inst{20-16} = Rm;
1663 let Inst{15-13} = ext{5-3};
1664 let Inst{12-10} = ext{2-0};
1665 let Inst{9-5} = Rn;
1666 let Inst{4-0} = Rd;
1667
1668 let DecoderMethod = "DecodeAddSubERegInstruction";
1669}
1670
1671let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
1672class BaseAddSubEReg64<bit isSub, bit setFlags, RegisterClass dstRegtype,
1673 RegisterClass src1Regtype, RegisterClass src2Regtype,
1674 Operand ext_op, string asm>
1675 : I<(outs dstRegtype:$Rd),
1676 (ins src1Regtype:$Rn, src2Regtype:$Rm, ext_op:$ext),
1677 asm, "\t$Rd, $Rn, $Rm$ext", "", []>,
1678 Sched<[WriteIEReg, ReadI, ReadIEReg]> {
1679 bits<5> Rd;
1680 bits<5> Rn;
1681 bits<5> Rm;
1682 bits<6> ext;
1683 let Inst{30} = isSub;
1684 let Inst{29} = setFlags;
1685 let Inst{28-24} = 0b01011;
1686 let Inst{23-21} = 0b001;
1687 let Inst{20-16} = Rm;
1688 let Inst{15} = ext{5};
1689 let Inst{12-10} = ext{2-0};
1690 let Inst{9-5} = Rn;
1691 let Inst{4-0} = Rd;
1692
1693 let DecoderMethod = "DecodeAddSubERegInstruction";
1694}
1695
1696// Aliases for register+register add/subtract.
1697class AddSubRegAlias<string asm, Instruction inst, RegisterClass dstRegtype,
1698 RegisterClass src1Regtype, RegisterClass src2Regtype,
1699 int shiftExt>
Ahmed Bougacha63fae0e2015-09-02 18:52:54 +00001700 : InstAlias<asm#"\t$dst, $src1, $src2",
Tim Northover3b0846e2014-05-24 12:50:23 +00001701 (inst dstRegtype:$dst, src1Regtype:$src1, src2Regtype:$src2,
1702 shiftExt)>;
1703
Arnaud A. de Grandmaison650c5202015-07-01 15:05:58 +00001704multiclass AddSub<bit isSub, string mnemonic, string alias,
Tim Northover3b0846e2014-05-24 12:50:23 +00001705 SDPatternOperator OpNode = null_frag> {
Jiangning Liucd296372014-07-29 02:09:26 +00001706 let hasSideEffects = 0, isReMaterializable = 1, isAsCheapAsAMove = 1 in {
Tim Northover3b0846e2014-05-24 12:50:23 +00001707 // Add/Subtract immediate
Quentin Colombeta64723c2015-04-02 18:54:23 +00001708 // Increase the weight of the immediate variant to try to match it before
1709 // the extended register variant.
1710 // We used to match the register variant before the immediate when the
1711 // register argument could be implicitly zero-extended.
Quentin Colombet387a0e72015-03-31 00:31:13 +00001712 let AddedComplexity = 6 in
Tim Northover3b0846e2014-05-24 12:50:23 +00001713 def Wri : BaseAddSubImm<isSub, 0, GPR32sp, GPR32sp, addsub_shifted_imm32,
1714 mnemonic, OpNode> {
1715 let Inst{31} = 0;
1716 }
Quentin Colombet387a0e72015-03-31 00:31:13 +00001717 let AddedComplexity = 6 in
Tim Northover3b0846e2014-05-24 12:50:23 +00001718 def Xri : BaseAddSubImm<isSub, 0, GPR64sp, GPR64sp, addsub_shifted_imm64,
1719 mnemonic, OpNode> {
1720 let Inst{31} = 1;
1721 }
1722
1723 // Add/Subtract register - Only used for CodeGen
1724 def Wrr : BaseAddSubRegPseudo<GPR32, OpNode>;
1725 def Xrr : BaseAddSubRegPseudo<GPR64, OpNode>;
1726
1727 // Add/Subtract shifted register
1728 def Wrs : BaseAddSubSReg<isSub, 0, GPR32, arith_shifted_reg32, mnemonic,
1729 OpNode> {
1730 let Inst{31} = 0;
1731 }
1732 def Xrs : BaseAddSubSReg<isSub, 0, GPR64, arith_shifted_reg64, mnemonic,
1733 OpNode> {
1734 let Inst{31} = 1;
1735 }
1736 }
1737
1738 // Add/Subtract extended register
1739 let AddedComplexity = 1, hasSideEffects = 0 in {
1740 def Wrx : BaseAddSubEReg<isSub, 0, GPR32sp, GPR32sp,
1741 arith_extended_reg32<i32>, mnemonic, OpNode> {
1742 let Inst{31} = 0;
1743 }
1744 def Xrx : BaseAddSubEReg<isSub, 0, GPR64sp, GPR64sp,
1745 arith_extended_reg32to64<i64>, mnemonic, OpNode> {
1746 let Inst{31} = 1;
1747 }
1748 }
1749
1750 def Xrx64 : BaseAddSubEReg64<isSub, 0, GPR64sp, GPR64sp, GPR64,
1751 arith_extendlsl64, mnemonic> {
1752 // UXTX and SXTX only.
1753 let Inst{14-13} = 0b11;
1754 let Inst{31} = 1;
1755 }
1756
Arnaud A. de Grandmaison650c5202015-07-01 15:05:58 +00001757 // add Rd, Rb, -imm -> sub Rd, Rn, imm
Ahmed Bougacha63fae0e2015-09-02 18:52:54 +00001758 def : InstAlias<alias#"\t$Rd, $Rn, $imm",
Arnaud A. de Grandmaison650c5202015-07-01 15:05:58 +00001759 (!cast<Instruction>(NAME # "Wri") GPR32sp:$Rd, GPR32sp:$Rn,
1760 addsub_shifted_imm32_neg:$imm), 0>;
Ahmed Bougacha63fae0e2015-09-02 18:52:54 +00001761 def : InstAlias<alias#"\t$Rd, $Rn, $imm",
Arnaud A. de Grandmaison650c5202015-07-01 15:05:58 +00001762 (!cast<Instruction>(NAME # "Xri") GPR64sp:$Rd, GPR64sp:$Rn,
1763 addsub_shifted_imm64_neg:$imm), 0>;
1764
Tim Northover3b0846e2014-05-24 12:50:23 +00001765 // Register/register aliases with no shift when SP is not used.
1766 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrs"),
1767 GPR32, GPR32, GPR32, 0>;
1768 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Xrs"),
1769 GPR64, GPR64, GPR64, 0>;
1770
1771 // Register/register aliases with no shift when either the destination or
1772 // first source register is SP.
1773 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrx"),
1774 GPR32sponly, GPR32sp, GPR32, 16>; // UXTW #0
1775 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrx"),
1776 GPR32sp, GPR32sponly, GPR32, 16>; // UXTW #0
1777 def : AddSubRegAlias<mnemonic,
1778 !cast<Instruction>(NAME#"Xrx64"),
1779 GPR64sponly, GPR64sp, GPR64, 24>; // UXTX #0
1780 def : AddSubRegAlias<mnemonic,
1781 !cast<Instruction>(NAME#"Xrx64"),
1782 GPR64sp, GPR64sponly, GPR64, 24>; // UXTX #0
1783}
1784
Arnaud A. de Grandmaison650c5202015-07-01 15:05:58 +00001785multiclass AddSubS<bit isSub, string mnemonic, SDNode OpNode, string cmp,
1786 string alias, string cmpAlias> {
Tim Northover3b0846e2014-05-24 12:50:23 +00001787 let isCompare = 1, Defs = [NZCV] in {
1788 // Add/Subtract immediate
1789 def Wri : BaseAddSubImm<isSub, 1, GPR32, GPR32sp, addsub_shifted_imm32,
1790 mnemonic, OpNode> {
1791 let Inst{31} = 0;
1792 }
1793 def Xri : BaseAddSubImm<isSub, 1, GPR64, GPR64sp, addsub_shifted_imm64,
1794 mnemonic, OpNode> {
1795 let Inst{31} = 1;
1796 }
1797
1798 // Add/Subtract register
1799 def Wrr : BaseAddSubRegPseudo<GPR32, OpNode>;
1800 def Xrr : BaseAddSubRegPseudo<GPR64, OpNode>;
1801
1802 // Add/Subtract shifted register
1803 def Wrs : BaseAddSubSReg<isSub, 1, GPR32, arith_shifted_reg32, mnemonic,
1804 OpNode> {
1805 let Inst{31} = 0;
1806 }
1807 def Xrs : BaseAddSubSReg<isSub, 1, GPR64, arith_shifted_reg64, mnemonic,
1808 OpNode> {
1809 let Inst{31} = 1;
1810 }
1811
1812 // Add/Subtract extended register
1813 let AddedComplexity = 1 in {
1814 def Wrx : BaseAddSubEReg<isSub, 1, GPR32, GPR32sp,
1815 arith_extended_reg32<i32>, mnemonic, OpNode> {
1816 let Inst{31} = 0;
1817 }
1818 def Xrx : BaseAddSubEReg<isSub, 1, GPR64, GPR64sp,
1819 arith_extended_reg32<i64>, mnemonic, OpNode> {
1820 let Inst{31} = 1;
1821 }
1822 }
1823
1824 def Xrx64 : BaseAddSubEReg64<isSub, 1, GPR64, GPR64sp, GPR64,
1825 arith_extendlsl64, mnemonic> {
1826 // UXTX and SXTX only.
1827 let Inst{14-13} = 0b11;
1828 let Inst{31} = 1;
1829 }
1830 } // Defs = [NZCV]
1831
Arnaud A. de Grandmaison650c5202015-07-01 15:05:58 +00001832 // Support negative immediates, e.g. adds Rd, Rn, -imm -> subs Rd, Rn, imm
Ahmed Bougacha63fae0e2015-09-02 18:52:54 +00001833 def : InstAlias<alias#"\t$Rd, $Rn, $imm",
Arnaud A. de Grandmaison650c5202015-07-01 15:05:58 +00001834 (!cast<Instruction>(NAME # "Wri") GPR32:$Rd, GPR32sp:$Rn,
1835 addsub_shifted_imm32_neg:$imm), 0>;
Ahmed Bougacha63fae0e2015-09-02 18:52:54 +00001836 def : InstAlias<alias#"\t$Rd, $Rn, $imm",
Arnaud A. de Grandmaison650c5202015-07-01 15:05:58 +00001837 (!cast<Instruction>(NAME # "Xri") GPR64:$Rd, GPR64sp:$Rn,
1838 addsub_shifted_imm64_neg:$imm), 0>;
1839
Tim Northover3b0846e2014-05-24 12:50:23 +00001840 // Compare aliases
Ahmed Bougacha63fae0e2015-09-02 18:52:54 +00001841 def : InstAlias<cmp#"\t$src, $imm", (!cast<Instruction>(NAME#"Wri")
Tim Northover3b0846e2014-05-24 12:50:23 +00001842 WZR, GPR32sp:$src, addsub_shifted_imm32:$imm), 5>;
Ahmed Bougacha63fae0e2015-09-02 18:52:54 +00001843 def : InstAlias<cmp#"\t$src, $imm", (!cast<Instruction>(NAME#"Xri")
Tim Northover3b0846e2014-05-24 12:50:23 +00001844 XZR, GPR64sp:$src, addsub_shifted_imm64:$imm), 5>;
Ahmed Bougacha63fae0e2015-09-02 18:52:54 +00001845 def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Wrx")
Tim Northover3b0846e2014-05-24 12:50:23 +00001846 WZR, GPR32sp:$src1, GPR32:$src2, arith_extend:$sh), 4>;
Ahmed Bougacha63fae0e2015-09-02 18:52:54 +00001847 def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Xrx")
Tim Northover3b0846e2014-05-24 12:50:23 +00001848 XZR, GPR64sp:$src1, GPR32:$src2, arith_extend:$sh), 4>;
Ahmed Bougacha63fae0e2015-09-02 18:52:54 +00001849 def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Xrx64")
Tim Northover3b0846e2014-05-24 12:50:23 +00001850 XZR, GPR64sp:$src1, GPR64:$src2, arith_extendlsl64:$sh), 4>;
Ahmed Bougacha63fae0e2015-09-02 18:52:54 +00001851 def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Wrs")
Tim Northover3b0846e2014-05-24 12:50:23 +00001852 WZR, GPR32:$src1, GPR32:$src2, arith_shift32:$sh), 4>;
Ahmed Bougacha63fae0e2015-09-02 18:52:54 +00001853 def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Xrs")
Tim Northover3b0846e2014-05-24 12:50:23 +00001854 XZR, GPR64:$src1, GPR64:$src2, arith_shift64:$sh), 4>;
1855
Arnaud A. de Grandmaison650c5202015-07-01 15:05:58 +00001856 // Support negative immediates, e.g. cmp Rn, -imm -> cmn Rn, imm
Ahmed Bougacha63fae0e2015-09-02 18:52:54 +00001857 def : InstAlias<cmpAlias#"\t$src, $imm", (!cast<Instruction>(NAME#"Wri")
Arnaud A. de Grandmaison650c5202015-07-01 15:05:58 +00001858 WZR, GPR32sp:$src, addsub_shifted_imm32_neg:$imm), 0>;
Ahmed Bougacha63fae0e2015-09-02 18:52:54 +00001859 def : InstAlias<cmpAlias#"\t$src, $imm", (!cast<Instruction>(NAME#"Xri")
Arnaud A. de Grandmaison650c5202015-07-01 15:05:58 +00001860 XZR, GPR64sp:$src, addsub_shifted_imm64_neg:$imm), 0>;
1861
Tim Northover3b0846e2014-05-24 12:50:23 +00001862 // Compare shorthands
Ahmed Bougacha63fae0e2015-09-02 18:52:54 +00001863 def : InstAlias<cmp#"\t$src1, $src2", (!cast<Instruction>(NAME#"Wrs")
Tim Northover3b0846e2014-05-24 12:50:23 +00001864 WZR, GPR32:$src1, GPR32:$src2, 0), 5>;
Ahmed Bougacha63fae0e2015-09-02 18:52:54 +00001865 def : InstAlias<cmp#"\t$src1, $src2", (!cast<Instruction>(NAME#"Xrs")
Tim Northover3b0846e2014-05-24 12:50:23 +00001866 XZR, GPR64:$src1, GPR64:$src2, 0), 5>;
Ahmed Bougacha63fae0e2015-09-02 18:52:54 +00001867 def : InstAlias<cmp#"\t$src1, $src2", (!cast<Instruction>(NAME#"Wrx")
Artyom Skrobov82ae94f2014-06-09 11:10:14 +00001868 WZR, GPR32sponly:$src1, GPR32:$src2, 16), 5>;
Ahmed Bougacha63fae0e2015-09-02 18:52:54 +00001869 def : InstAlias<cmp#"\t$src1, $src2", (!cast<Instruction>(NAME#"Xrx64")
Artyom Skrobov82ae94f2014-06-09 11:10:14 +00001870 XZR, GPR64sponly:$src1, GPR64:$src2, 24), 5>;
Tim Northover3b0846e2014-05-24 12:50:23 +00001871
1872 // Register/register aliases with no shift when SP is not used.
1873 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrs"),
1874 GPR32, GPR32, GPR32, 0>;
1875 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Xrs"),
1876 GPR64, GPR64, GPR64, 0>;
1877
1878 // Register/register aliases with no shift when the first source register
1879 // is SP.
1880 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrx"),
1881 GPR32, GPR32sponly, GPR32, 16>; // UXTW #0
1882 def : AddSubRegAlias<mnemonic,
1883 !cast<Instruction>(NAME#"Xrx64"),
1884 GPR64, GPR64sponly, GPR64, 24>; // UXTX #0
1885}
1886
1887//---
1888// Extract
1889//---
1890def SDTA64EXTR : SDTypeProfile<1, 3, [SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>,
1891 SDTCisPtrTy<3>]>;
1892def AArch64Extr : SDNode<"AArch64ISD::EXTR", SDTA64EXTR>;
1893
1894class BaseExtractImm<RegisterClass regtype, Operand imm_type, string asm,
1895 list<dag> patterns>
1896 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, imm_type:$imm),
1897 asm, "\t$Rd, $Rn, $Rm, $imm", "", patterns>,
1898 Sched<[WriteExtr, ReadExtrHi]> {
1899 bits<5> Rd;
1900 bits<5> Rn;
1901 bits<5> Rm;
1902 bits<6> imm;
1903
1904 let Inst{30-23} = 0b00100111;
1905 let Inst{21} = 0;
1906 let Inst{20-16} = Rm;
1907 let Inst{15-10} = imm;
1908 let Inst{9-5} = Rn;
1909 let Inst{4-0} = Rd;
1910}
1911
1912multiclass ExtractImm<string asm> {
1913 def Wrri : BaseExtractImm<GPR32, imm0_31, asm,
1914 [(set GPR32:$Rd,
1915 (AArch64Extr GPR32:$Rn, GPR32:$Rm, imm0_31:$imm))]> {
1916 let Inst{31} = 0;
1917 let Inst{22} = 0;
1918 // imm<5> must be zero.
1919 let imm{5} = 0;
1920 }
1921 def Xrri : BaseExtractImm<GPR64, imm0_63, asm,
1922 [(set GPR64:$Rd,
1923 (AArch64Extr GPR64:$Rn, GPR64:$Rm, imm0_63:$imm))]> {
1924
1925 let Inst{31} = 1;
1926 let Inst{22} = 1;
1927 }
1928}
1929
1930//---
1931// Bitfield
1932//---
1933
1934let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
1935class BaseBitfieldImm<bits<2> opc,
1936 RegisterClass regtype, Operand imm_type, string asm>
1937 : I<(outs regtype:$Rd), (ins regtype:$Rn, imm_type:$immr, imm_type:$imms),
1938 asm, "\t$Rd, $Rn, $immr, $imms", "", []>,
1939 Sched<[WriteIS, ReadI]> {
1940 bits<5> Rd;
1941 bits<5> Rn;
1942 bits<6> immr;
1943 bits<6> imms;
1944
1945 let Inst{30-29} = opc;
1946 let Inst{28-23} = 0b100110;
1947 let Inst{21-16} = immr;
1948 let Inst{15-10} = imms;
1949 let Inst{9-5} = Rn;
1950 let Inst{4-0} = Rd;
1951}
1952
1953multiclass BitfieldImm<bits<2> opc, string asm> {
1954 def Wri : BaseBitfieldImm<opc, GPR32, imm0_31, asm> {
1955 let Inst{31} = 0;
1956 let Inst{22} = 0;
1957 // imms<5> and immr<5> must be zero, else ReservedValue().
1958 let Inst{21} = 0;
1959 let Inst{15} = 0;
1960 }
1961 def Xri : BaseBitfieldImm<opc, GPR64, imm0_63, asm> {
1962 let Inst{31} = 1;
1963 let Inst{22} = 1;
1964 }
1965}
1966
1967let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
1968class BaseBitfieldImmWith2RegArgs<bits<2> opc,
1969 RegisterClass regtype, Operand imm_type, string asm>
1970 : I<(outs regtype:$Rd), (ins regtype:$src, regtype:$Rn, imm_type:$immr,
1971 imm_type:$imms),
1972 asm, "\t$Rd, $Rn, $immr, $imms", "$src = $Rd", []>,
1973 Sched<[WriteIS, ReadI]> {
1974 bits<5> Rd;
1975 bits<5> Rn;
1976 bits<6> immr;
1977 bits<6> imms;
1978
1979 let Inst{30-29} = opc;
1980 let Inst{28-23} = 0b100110;
1981 let Inst{21-16} = immr;
1982 let Inst{15-10} = imms;
1983 let Inst{9-5} = Rn;
1984 let Inst{4-0} = Rd;
1985}
1986
1987multiclass BitfieldImmWith2RegArgs<bits<2> opc, string asm> {
1988 def Wri : BaseBitfieldImmWith2RegArgs<opc, GPR32, imm0_31, asm> {
1989 let Inst{31} = 0;
1990 let Inst{22} = 0;
1991 // imms<5> and immr<5> must be zero, else ReservedValue().
1992 let Inst{21} = 0;
1993 let Inst{15} = 0;
1994 }
1995 def Xri : BaseBitfieldImmWith2RegArgs<opc, GPR64, imm0_63, asm> {
1996 let Inst{31} = 1;
1997 let Inst{22} = 1;
1998 }
1999}
2000
2001//---
2002// Logical
2003//---
2004
2005// Logical (immediate)
2006class BaseLogicalImm<bits<2> opc, RegisterClass dregtype,
2007 RegisterClass sregtype, Operand imm_type, string asm,
2008 list<dag> pattern>
2009 : I<(outs dregtype:$Rd), (ins sregtype:$Rn, imm_type:$imm),
2010 asm, "\t$Rd, $Rn, $imm", "", pattern>,
2011 Sched<[WriteI, ReadI]> {
2012 bits<5> Rd;
2013 bits<5> Rn;
2014 bits<13> imm;
2015 let Inst{30-29} = opc;
2016 let Inst{28-23} = 0b100100;
2017 let Inst{22} = imm{12};
2018 let Inst{21-16} = imm{11-6};
2019 let Inst{15-10} = imm{5-0};
2020 let Inst{9-5} = Rn;
2021 let Inst{4-0} = Rd;
2022
2023 let DecoderMethod = "DecodeLogicalImmInstruction";
2024}
2025
2026// Logical (shifted register)
2027class BaseLogicalSReg<bits<2> opc, bit N, RegisterClass regtype,
2028 logical_shifted_reg shifted_regtype, string asm,
2029 list<dag> pattern>
2030 : I<(outs regtype:$Rd), (ins regtype:$Rn, shifted_regtype:$Rm),
2031 asm, "\t$Rd, $Rn, $Rm", "", pattern>,
2032 Sched<[WriteISReg, ReadI, ReadISReg]> {
2033 // The operands are in order to match the 'addr' MI operands, so we
2034 // don't need an encoder method and by-name matching. Just use the default
2035 // in-order handling. Since we're using by-order, make sure the names
2036 // do not match.
2037 bits<5> dst;
2038 bits<5> src1;
2039 bits<5> src2;
2040 bits<8> shift;
2041 let Inst{30-29} = opc;
2042 let Inst{28-24} = 0b01010;
2043 let Inst{23-22} = shift{7-6};
2044 let Inst{21} = N;
2045 let Inst{20-16} = src2;
2046 let Inst{15-10} = shift{5-0};
2047 let Inst{9-5} = src1;
2048 let Inst{4-0} = dst;
2049
2050 let DecoderMethod = "DecodeThreeAddrSRegInstruction";
2051}
2052
2053// Aliases for register+register logical instructions.
2054class LogicalRegAlias<string asm, Instruction inst, RegisterClass regtype>
Ahmed Bougacha63fae0e2015-09-02 18:52:54 +00002055 : InstAlias<asm#"\t$dst, $src1, $src2",
Tim Northover3b0846e2014-05-24 12:50:23 +00002056 (inst regtype:$dst, regtype:$src1, regtype:$src2, 0)>;
2057
Arnaud A. de Grandmaisonf6432312014-07-10 15:12:26 +00002058multiclass LogicalImm<bits<2> opc, string mnemonic, SDNode OpNode,
2059 string Alias> {
Jiangning Liucd296372014-07-29 02:09:26 +00002060 let AddedComplexity = 6, isReMaterializable = 1, isAsCheapAsAMove = 1 in
Tim Northover3b0846e2014-05-24 12:50:23 +00002061 def Wri : BaseLogicalImm<opc, GPR32sp, GPR32, logical_imm32, mnemonic,
2062 [(set GPR32sp:$Rd, (OpNode GPR32:$Rn,
2063 logical_imm32:$imm))]> {
2064 let Inst{31} = 0;
2065 let Inst{22} = 0; // 64-bit version has an additional bit of immediate.
2066 }
Jiangning Liucd296372014-07-29 02:09:26 +00002067 let AddedComplexity = 6, isReMaterializable = 1, isAsCheapAsAMove = 1 in
Tim Northover3b0846e2014-05-24 12:50:23 +00002068 def Xri : BaseLogicalImm<opc, GPR64sp, GPR64, logical_imm64, mnemonic,
2069 [(set GPR64sp:$Rd, (OpNode GPR64:$Rn,
2070 logical_imm64:$imm))]> {
2071 let Inst{31} = 1;
2072 }
Arnaud A. de Grandmaisonf6432312014-07-10 15:12:26 +00002073
Ahmed Bougacha63fae0e2015-09-02 18:52:54 +00002074 def : InstAlias<Alias # "\t$Rd, $Rn, $imm",
Arnaud A. de Grandmaisonf6432312014-07-10 15:12:26 +00002075 (!cast<Instruction>(NAME # "Wri") GPR32sp:$Rd, GPR32:$Rn,
2076 logical_imm32_not:$imm), 0>;
Ahmed Bougacha63fae0e2015-09-02 18:52:54 +00002077 def : InstAlias<Alias # "\t$Rd, $Rn, $imm",
Arnaud A. de Grandmaisonf6432312014-07-10 15:12:26 +00002078 (!cast<Instruction>(NAME # "Xri") GPR64sp:$Rd, GPR64:$Rn,
2079 logical_imm64_not:$imm), 0>;
Tim Northover3b0846e2014-05-24 12:50:23 +00002080}
2081
Arnaud A. de Grandmaisonf6432312014-07-10 15:12:26 +00002082multiclass LogicalImmS<bits<2> opc, string mnemonic, SDNode OpNode,
2083 string Alias> {
Tim Northover3b0846e2014-05-24 12:50:23 +00002084 let isCompare = 1, Defs = [NZCV] in {
2085 def Wri : BaseLogicalImm<opc, GPR32, GPR32, logical_imm32, mnemonic,
2086 [(set GPR32:$Rd, (OpNode GPR32:$Rn, logical_imm32:$imm))]> {
2087 let Inst{31} = 0;
2088 let Inst{22} = 0; // 64-bit version has an additional bit of immediate.
2089 }
2090 def Xri : BaseLogicalImm<opc, GPR64, GPR64, logical_imm64, mnemonic,
2091 [(set GPR64:$Rd, (OpNode GPR64:$Rn, logical_imm64:$imm))]> {
2092 let Inst{31} = 1;
2093 }
2094 } // end Defs = [NZCV]
Arnaud A. de Grandmaisonf6432312014-07-10 15:12:26 +00002095
Ahmed Bougacha63fae0e2015-09-02 18:52:54 +00002096 def : InstAlias<Alias # "\t$Rd, $Rn, $imm",
Arnaud A. de Grandmaisonf6432312014-07-10 15:12:26 +00002097 (!cast<Instruction>(NAME # "Wri") GPR32:$Rd, GPR32:$Rn,
2098 logical_imm32_not:$imm), 0>;
Ahmed Bougacha63fae0e2015-09-02 18:52:54 +00002099 def : InstAlias<Alias # "\t$Rd, $Rn, $imm",
Arnaud A. de Grandmaisonf6432312014-07-10 15:12:26 +00002100 (!cast<Instruction>(NAME # "Xri") GPR64:$Rd, GPR64:$Rn,
2101 logical_imm64_not:$imm), 0>;
Tim Northover3b0846e2014-05-24 12:50:23 +00002102}
2103
2104class BaseLogicalRegPseudo<RegisterClass regtype, SDPatternOperator OpNode>
2105 : Pseudo<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm),
2106 [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm))]>,
2107 Sched<[WriteI, ReadI, ReadI]>;
2108
2109// Split from LogicalImm as not all instructions have both.
2110multiclass LogicalReg<bits<2> opc, bit N, string mnemonic,
2111 SDPatternOperator OpNode> {
Jiangning Liucd296372014-07-29 02:09:26 +00002112 let isReMaterializable = 1, isAsCheapAsAMove = 1 in {
Tim Northover3b0846e2014-05-24 12:50:23 +00002113 def Wrr : BaseLogicalRegPseudo<GPR32, OpNode>;
2114 def Xrr : BaseLogicalRegPseudo<GPR64, OpNode>;
Jiangning Liucd296372014-07-29 02:09:26 +00002115 }
Tim Northover3b0846e2014-05-24 12:50:23 +00002116
2117 def Wrs : BaseLogicalSReg<opc, N, GPR32, logical_shifted_reg32, mnemonic,
2118 [(set GPR32:$Rd, (OpNode GPR32:$Rn,
2119 logical_shifted_reg32:$Rm))]> {
2120 let Inst{31} = 0;
2121 }
2122 def Xrs : BaseLogicalSReg<opc, N, GPR64, logical_shifted_reg64, mnemonic,
2123 [(set GPR64:$Rd, (OpNode GPR64:$Rn,
2124 logical_shifted_reg64:$Rm))]> {
2125 let Inst{31} = 1;
2126 }
2127
2128 def : LogicalRegAlias<mnemonic,
2129 !cast<Instruction>(NAME#"Wrs"), GPR32>;
2130 def : LogicalRegAlias<mnemonic,
2131 !cast<Instruction>(NAME#"Xrs"), GPR64>;
2132}
2133
2134// Split from LogicalReg to allow setting NZCV Defs
2135multiclass LogicalRegS<bits<2> opc, bit N, string mnemonic,
2136 SDPatternOperator OpNode = null_frag> {
2137 let Defs = [NZCV], mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
2138 def Wrr : BaseLogicalRegPseudo<GPR32, OpNode>;
2139 def Xrr : BaseLogicalRegPseudo<GPR64, OpNode>;
2140
2141 def Wrs : BaseLogicalSReg<opc, N, GPR32, logical_shifted_reg32, mnemonic,
2142 [(set GPR32:$Rd, (OpNode GPR32:$Rn, logical_shifted_reg32:$Rm))]> {
2143 let Inst{31} = 0;
2144 }
2145 def Xrs : BaseLogicalSReg<opc, N, GPR64, logical_shifted_reg64, mnemonic,
2146 [(set GPR64:$Rd, (OpNode GPR64:$Rn, logical_shifted_reg64:$Rm))]> {
2147 let Inst{31} = 1;
2148 }
2149 } // Defs = [NZCV]
2150
2151 def : LogicalRegAlias<mnemonic,
2152 !cast<Instruction>(NAME#"Wrs"), GPR32>;
2153 def : LogicalRegAlias<mnemonic,
2154 !cast<Instruction>(NAME#"Xrs"), GPR64>;
2155}
2156
2157//---
2158// Conditionally set flags
2159//---
2160
2161let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
Matthias Braunaf7d7702015-07-16 20:02:37 +00002162class BaseCondComparisonImm<bit op, RegisterClass regtype, ImmLeaf immtype,
2163 string mnemonic, SDNode OpNode>
2164 : I<(outs), (ins regtype:$Rn, immtype:$imm, imm32_0_15:$nzcv, ccode:$cond),
2165 mnemonic, "\t$Rn, $imm, $nzcv, $cond", "",
2166 [(set NZCV, (OpNode regtype:$Rn, immtype:$imm, (i32 imm:$nzcv),
2167 (i32 imm:$cond), NZCV))]>,
Tim Northover3b0846e2014-05-24 12:50:23 +00002168 Sched<[WriteI, ReadI]> {
2169 let Uses = [NZCV];
2170 let Defs = [NZCV];
2171
2172 bits<5> Rn;
2173 bits<5> imm;
2174 bits<4> nzcv;
2175 bits<4> cond;
2176
2177 let Inst{30} = op;
2178 let Inst{29-21} = 0b111010010;
2179 let Inst{20-16} = imm;
2180 let Inst{15-12} = cond;
2181 let Inst{11-10} = 0b10;
2182 let Inst{9-5} = Rn;
2183 let Inst{4} = 0b0;
2184 let Inst{3-0} = nzcv;
2185}
2186
Tim Northover3b0846e2014-05-24 12:50:23 +00002187let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
Matthias Braunaf7d7702015-07-16 20:02:37 +00002188class BaseCondComparisonReg<bit op, RegisterClass regtype, string mnemonic,
2189 SDNode OpNode>
2190 : I<(outs), (ins regtype:$Rn, regtype:$Rm, imm32_0_15:$nzcv, ccode:$cond),
2191 mnemonic, "\t$Rn, $Rm, $nzcv, $cond", "",
2192 [(set NZCV, (OpNode regtype:$Rn, regtype:$Rm, (i32 imm:$nzcv),
2193 (i32 imm:$cond), NZCV))]>,
Tim Northover3b0846e2014-05-24 12:50:23 +00002194 Sched<[WriteI, ReadI, ReadI]> {
2195 let Uses = [NZCV];
2196 let Defs = [NZCV];
2197
2198 bits<5> Rn;
2199 bits<5> Rm;
2200 bits<4> nzcv;
2201 bits<4> cond;
2202
2203 let Inst{30} = op;
2204 let Inst{29-21} = 0b111010010;
2205 let Inst{20-16} = Rm;
2206 let Inst{15-12} = cond;
2207 let Inst{11-10} = 0b00;
2208 let Inst{9-5} = Rn;
2209 let Inst{4} = 0b0;
2210 let Inst{3-0} = nzcv;
2211}
2212
Matthias Braunaf7d7702015-07-16 20:02:37 +00002213multiclass CondComparison<bit op, string mnemonic, SDNode OpNode> {
2214 // immediate operand variants
2215 def Wi : BaseCondComparisonImm<op, GPR32, imm32_0_31, mnemonic, OpNode> {
Tim Northover3b0846e2014-05-24 12:50:23 +00002216 let Inst{31} = 0;
2217 }
Matthias Braunaf7d7702015-07-16 20:02:37 +00002218 def Xi : BaseCondComparisonImm<op, GPR64, imm0_31, mnemonic, OpNode> {
2219 let Inst{31} = 1;
2220 }
2221 // register operand variants
2222 def Wr : BaseCondComparisonReg<op, GPR32, mnemonic, OpNode> {
2223 let Inst{31} = 0;
2224 }
2225 def Xr : BaseCondComparisonReg<op, GPR64, mnemonic, OpNode> {
Tim Northover3b0846e2014-05-24 12:50:23 +00002226 let Inst{31} = 1;
2227 }
2228}
2229
2230//---
2231// Conditional select
2232//---
2233
2234class BaseCondSelect<bit op, bits<2> op2, RegisterClass regtype, string asm>
2235 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, ccode:$cond),
2236 asm, "\t$Rd, $Rn, $Rm, $cond", "",
2237 [(set regtype:$Rd,
2238 (AArch64csel regtype:$Rn, regtype:$Rm, (i32 imm:$cond), NZCV))]>,
2239 Sched<[WriteI, ReadI, ReadI]> {
2240 let Uses = [NZCV];
2241
2242 bits<5> Rd;
2243 bits<5> Rn;
2244 bits<5> Rm;
2245 bits<4> cond;
2246
2247 let Inst{30} = op;
2248 let Inst{29-21} = 0b011010100;
2249 let Inst{20-16} = Rm;
2250 let Inst{15-12} = cond;
2251 let Inst{11-10} = op2;
2252 let Inst{9-5} = Rn;
2253 let Inst{4-0} = Rd;
2254}
2255
2256multiclass CondSelect<bit op, bits<2> op2, string asm> {
2257 def Wr : BaseCondSelect<op, op2, GPR32, asm> {
2258 let Inst{31} = 0;
2259 }
2260 def Xr : BaseCondSelect<op, op2, GPR64, asm> {
2261 let Inst{31} = 1;
2262 }
2263}
2264
2265class BaseCondSelectOp<bit op, bits<2> op2, RegisterClass regtype, string asm,
2266 PatFrag frag>
2267 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, ccode:$cond),
2268 asm, "\t$Rd, $Rn, $Rm, $cond", "",
2269 [(set regtype:$Rd,
2270 (AArch64csel regtype:$Rn, (frag regtype:$Rm),
2271 (i32 imm:$cond), NZCV))]>,
2272 Sched<[WriteI, ReadI, ReadI]> {
2273 let Uses = [NZCV];
2274
2275 bits<5> Rd;
2276 bits<5> Rn;
2277 bits<5> Rm;
2278 bits<4> cond;
2279
2280 let Inst{30} = op;
2281 let Inst{29-21} = 0b011010100;
2282 let Inst{20-16} = Rm;
2283 let Inst{15-12} = cond;
2284 let Inst{11-10} = op2;
2285 let Inst{9-5} = Rn;
2286 let Inst{4-0} = Rd;
2287}
2288
2289def inv_cond_XFORM : SDNodeXForm<imm, [{
2290 AArch64CC::CondCode CC = static_cast<AArch64CC::CondCode>(N->getZExtValue());
Sergey Dmitrouk842a51b2015-04-28 14:05:47 +00002291 return CurDAG->getTargetConstant(AArch64CC::getInvertedCondCode(CC), SDLoc(N),
2292 MVT::i32);
Tim Northover3b0846e2014-05-24 12:50:23 +00002293}]>;
2294
2295multiclass CondSelectOp<bit op, bits<2> op2, string asm, PatFrag frag> {
2296 def Wr : BaseCondSelectOp<op, op2, GPR32, asm, frag> {
2297 let Inst{31} = 0;
2298 }
2299 def Xr : BaseCondSelectOp<op, op2, GPR64, asm, frag> {
2300 let Inst{31} = 1;
2301 }
2302
2303 def : Pat<(AArch64csel (frag GPR32:$Rm), GPR32:$Rn, (i32 imm:$cond), NZCV),
2304 (!cast<Instruction>(NAME # Wr) GPR32:$Rn, GPR32:$Rm,
2305 (inv_cond_XFORM imm:$cond))>;
2306
2307 def : Pat<(AArch64csel (frag GPR64:$Rm), GPR64:$Rn, (i32 imm:$cond), NZCV),
2308 (!cast<Instruction>(NAME # Xr) GPR64:$Rn, GPR64:$Rm,
2309 (inv_cond_XFORM imm:$cond))>;
2310}
2311
2312//---
2313// Special Mask Value
2314//---
2315def maski8_or_more : Operand<i32>,
2316 ImmLeaf<i32, [{ return (Imm & 0xff) == 0xff; }]> {
2317}
2318def maski16_or_more : Operand<i32>,
2319 ImmLeaf<i32, [{ return (Imm & 0xffff) == 0xffff; }]> {
2320}
2321
2322
2323//---
2324// Load/store
2325//---
2326
2327// (unsigned immediate)
2328// Indexed for 8-bit registers. offset is in range [0,4095].
2329def am_indexed8 : ComplexPattern<i64, 2, "SelectAddrModeIndexed8", []>;
2330def am_indexed16 : ComplexPattern<i64, 2, "SelectAddrModeIndexed16", []>;
2331def am_indexed32 : ComplexPattern<i64, 2, "SelectAddrModeIndexed32", []>;
2332def am_indexed64 : ComplexPattern<i64, 2, "SelectAddrModeIndexed64", []>;
2333def am_indexed128 : ComplexPattern<i64, 2, "SelectAddrModeIndexed128", []>;
2334
2335class UImm12OffsetOperand<int Scale> : AsmOperandClass {
2336 let Name = "UImm12Offset" # Scale;
2337 let RenderMethod = "addUImm12OffsetOperands<" # Scale # ">";
2338 let PredicateMethod = "isUImm12Offset<" # Scale # ">";
2339 let DiagnosticType = "InvalidMemoryIndexed" # Scale;
2340}
2341
2342def UImm12OffsetScale1Operand : UImm12OffsetOperand<1>;
2343def UImm12OffsetScale2Operand : UImm12OffsetOperand<2>;
2344def UImm12OffsetScale4Operand : UImm12OffsetOperand<4>;
2345def UImm12OffsetScale8Operand : UImm12OffsetOperand<8>;
2346def UImm12OffsetScale16Operand : UImm12OffsetOperand<16>;
2347
2348class uimm12_scaled<int Scale> : Operand<i64> {
2349 let ParserMatchClass
2350 = !cast<AsmOperandClass>("UImm12OffsetScale" # Scale # "Operand");
2351 let EncoderMethod
2352 = "getLdStUImm12OpValue<AArch64::fixup_aarch64_ldst_imm12_scale" # Scale # ">";
2353 let PrintMethod = "printUImm12Offset<" # Scale # ">";
2354}
2355
2356def uimm12s1 : uimm12_scaled<1>;
2357def uimm12s2 : uimm12_scaled<2>;
2358def uimm12s4 : uimm12_scaled<4>;
2359def uimm12s8 : uimm12_scaled<8>;
2360def uimm12s16 : uimm12_scaled<16>;
2361
2362class BaseLoadStoreUI<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops,
2363 string asm, list<dag> pattern>
2364 : I<oops, iops, asm, "\t$Rt, [$Rn, $offset]", "", pattern> {
2365 bits<5> Rt;
2366
2367 bits<5> Rn;
2368 bits<12> offset;
2369
2370 let Inst{31-30} = sz;
2371 let Inst{29-27} = 0b111;
2372 let Inst{26} = V;
2373 let Inst{25-24} = 0b01;
2374 let Inst{23-22} = opc;
2375 let Inst{21-10} = offset;
2376 let Inst{9-5} = Rn;
2377 let Inst{4-0} = Rt;
2378
2379 let DecoderMethod = "DecodeUnsignedLdStInstruction";
2380}
2381
2382multiclass LoadUI<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2383 Operand indextype, string asm, list<dag> pattern> {
2384 let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
2385 def ui : BaseLoadStoreUI<sz, V, opc, (outs regtype:$Rt),
2386 (ins GPR64sp:$Rn, indextype:$offset),
2387 asm, pattern>,
2388 Sched<[WriteLD]>;
2389
Ahmed Bougacha63fae0e2015-09-02 18:52:54 +00002390 def : InstAlias<asm # "\t$Rt, [$Rn]",
Tim Northover3b0846e2014-05-24 12:50:23 +00002391 (!cast<Instruction>(NAME # "ui") regtype:$Rt, GPR64sp:$Rn, 0)>;
2392}
2393
2394multiclass StoreUI<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2395 Operand indextype, string asm, list<dag> pattern> {
2396 let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
2397 def ui : BaseLoadStoreUI<sz, V, opc, (outs),
2398 (ins regtype:$Rt, GPR64sp:$Rn, indextype:$offset),
2399 asm, pattern>,
2400 Sched<[WriteST]>;
2401
Ahmed Bougacha63fae0e2015-09-02 18:52:54 +00002402 def : InstAlias<asm # "\t$Rt, [$Rn]",
Tim Northover3b0846e2014-05-24 12:50:23 +00002403 (!cast<Instruction>(NAME # "ui") regtype:$Rt, GPR64sp:$Rn, 0)>;
2404}
2405
2406def PrefetchOperand : AsmOperandClass {
2407 let Name = "Prefetch";
2408 let ParserMethod = "tryParsePrefetch";
2409}
2410def prfop : Operand<i32> {
2411 let PrintMethod = "printPrefetchOp";
2412 let ParserMatchClass = PrefetchOperand;
2413}
2414
2415let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in
2416class PrefetchUI<bits<2> sz, bit V, bits<2> opc, string asm, list<dag> pat>
2417 : BaseLoadStoreUI<sz, V, opc,
2418 (outs), (ins prfop:$Rt, GPR64sp:$Rn, uimm12s8:$offset),
2419 asm, pat>,
2420 Sched<[WriteLD]>;
2421
2422//---
2423// Load literal
2424//---
2425
2426// Load literal address: 19-bit immediate. The low two bits of the target
2427// offset are implied zero and so are not part of the immediate.
2428def am_ldrlit : Operand<OtherVT> {
2429 let EncoderMethod = "getLoadLiteralOpValue";
2430 let DecoderMethod = "DecodePCRelLabel19";
2431 let PrintMethod = "printAlignedLabel";
2432 let ParserMatchClass = PCRelLabel19Operand;
2433}
2434
2435let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
2436class LoadLiteral<bits<2> opc, bit V, RegisterClass regtype, string asm>
2437 : I<(outs regtype:$Rt), (ins am_ldrlit:$label),
2438 asm, "\t$Rt, $label", "", []>,
2439 Sched<[WriteLD]> {
2440 bits<5> Rt;
2441 bits<19> label;
2442 let Inst{31-30} = opc;
2443 let Inst{29-27} = 0b011;
2444 let Inst{26} = V;
2445 let Inst{25-24} = 0b00;
2446 let Inst{23-5} = label;
2447 let Inst{4-0} = Rt;
2448}
2449
2450let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in
2451class PrefetchLiteral<bits<2> opc, bit V, string asm, list<dag> pat>
2452 : I<(outs), (ins prfop:$Rt, am_ldrlit:$label),
2453 asm, "\t$Rt, $label", "", pat>,
2454 Sched<[WriteLD]> {
2455 bits<5> Rt;
2456 bits<19> label;
2457 let Inst{31-30} = opc;
2458 let Inst{29-27} = 0b011;
2459 let Inst{26} = V;
2460 let Inst{25-24} = 0b00;
2461 let Inst{23-5} = label;
2462 let Inst{4-0} = Rt;
2463}
2464
2465//---
2466// Load/store register offset
2467//---
2468
2469def ro_Xindexed8 : ComplexPattern<i64, 4, "SelectAddrModeXRO<8>", []>;
2470def ro_Xindexed16 : ComplexPattern<i64, 4, "SelectAddrModeXRO<16>", []>;
2471def ro_Xindexed32 : ComplexPattern<i64, 4, "SelectAddrModeXRO<32>", []>;
2472def ro_Xindexed64 : ComplexPattern<i64, 4, "SelectAddrModeXRO<64>", []>;
2473def ro_Xindexed128 : ComplexPattern<i64, 4, "SelectAddrModeXRO<128>", []>;
2474
2475def ro_Windexed8 : ComplexPattern<i64, 4, "SelectAddrModeWRO<8>", []>;
2476def ro_Windexed16 : ComplexPattern<i64, 4, "SelectAddrModeWRO<16>", []>;
2477def ro_Windexed32 : ComplexPattern<i64, 4, "SelectAddrModeWRO<32>", []>;
2478def ro_Windexed64 : ComplexPattern<i64, 4, "SelectAddrModeWRO<64>", []>;
2479def ro_Windexed128 : ComplexPattern<i64, 4, "SelectAddrModeWRO<128>", []>;
2480
2481class MemExtendOperand<string Reg, int Width> : AsmOperandClass {
2482 let Name = "Mem" # Reg # "Extend" # Width;
2483 let PredicateMethod = "isMem" # Reg # "Extend<" # Width # ">";
2484 let RenderMethod = "addMemExtendOperands";
2485 let DiagnosticType = "InvalidMemory" # Reg # "Extend" # Width;
2486}
2487
2488def MemWExtend8Operand : MemExtendOperand<"W", 8> {
2489 // The address "[x0, x1, lsl #0]" actually maps to the variant which performs
2490 // the trivial shift.
2491 let RenderMethod = "addMemExtend8Operands";
2492}
2493def MemWExtend16Operand : MemExtendOperand<"W", 16>;
2494def MemWExtend32Operand : MemExtendOperand<"W", 32>;
2495def MemWExtend64Operand : MemExtendOperand<"W", 64>;
2496def MemWExtend128Operand : MemExtendOperand<"W", 128>;
2497
2498def MemXExtend8Operand : MemExtendOperand<"X", 8> {
2499 // The address "[x0, x1, lsl #0]" actually maps to the variant which performs
2500 // the trivial shift.
2501 let RenderMethod = "addMemExtend8Operands";
2502}
2503def MemXExtend16Operand : MemExtendOperand<"X", 16>;
2504def MemXExtend32Operand : MemExtendOperand<"X", 32>;
2505def MemXExtend64Operand : MemExtendOperand<"X", 64>;
2506def MemXExtend128Operand : MemExtendOperand<"X", 128>;
2507
2508class ro_extend<AsmOperandClass ParserClass, string Reg, int Width>
2509 : Operand<i32> {
2510 let ParserMatchClass = ParserClass;
2511 let PrintMethod = "printMemExtend<'" # Reg # "', " # Width # ">";
2512 let DecoderMethod = "DecodeMemExtend";
2513 let EncoderMethod = "getMemExtendOpValue";
2514 let MIOperandInfo = (ops i32imm:$signed, i32imm:$doshift);
2515}
2516
2517def ro_Wextend8 : ro_extend<MemWExtend8Operand, "w", 8>;
2518def ro_Wextend16 : ro_extend<MemWExtend16Operand, "w", 16>;
2519def ro_Wextend32 : ro_extend<MemWExtend32Operand, "w", 32>;
2520def ro_Wextend64 : ro_extend<MemWExtend64Operand, "w", 64>;
2521def ro_Wextend128 : ro_extend<MemWExtend128Operand, "w", 128>;
2522
2523def ro_Xextend8 : ro_extend<MemXExtend8Operand, "x", 8>;
2524def ro_Xextend16 : ro_extend<MemXExtend16Operand, "x", 16>;
2525def ro_Xextend32 : ro_extend<MemXExtend32Operand, "x", 32>;
2526def ro_Xextend64 : ro_extend<MemXExtend64Operand, "x", 64>;
2527def ro_Xextend128 : ro_extend<MemXExtend128Operand, "x", 128>;
2528
2529class ROAddrMode<ComplexPattern windex, ComplexPattern xindex,
2530 Operand wextend, Operand xextend> {
2531 // CodeGen-level pattern covering the entire addressing mode.
2532 ComplexPattern Wpat = windex;
2533 ComplexPattern Xpat = xindex;
2534
2535 // Asm-level Operand covering the valid "uxtw #3" style syntax.
2536 Operand Wext = wextend;
2537 Operand Xext = xextend;
2538}
2539
2540def ro8 : ROAddrMode<ro_Windexed8, ro_Xindexed8, ro_Wextend8, ro_Xextend8>;
2541def ro16 : ROAddrMode<ro_Windexed16, ro_Xindexed16, ro_Wextend16, ro_Xextend16>;
2542def ro32 : ROAddrMode<ro_Windexed32, ro_Xindexed32, ro_Wextend32, ro_Xextend32>;
2543def ro64 : ROAddrMode<ro_Windexed64, ro_Xindexed64, ro_Wextend64, ro_Xextend64>;
2544def ro128 : ROAddrMode<ro_Windexed128, ro_Xindexed128, ro_Wextend128,
2545 ro_Xextend128>;
2546
2547class LoadStore8RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2548 string asm, dag ins, dag outs, list<dag> pat>
2549 : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> {
2550 bits<5> Rt;
2551 bits<5> Rn;
2552 bits<5> Rm;
2553 bits<2> extend;
2554 let Inst{31-30} = sz;
2555 let Inst{29-27} = 0b111;
2556 let Inst{26} = V;
2557 let Inst{25-24} = 0b00;
2558 let Inst{23-22} = opc;
2559 let Inst{21} = 1;
2560 let Inst{20-16} = Rm;
2561 let Inst{15} = extend{1}; // sign extend Rm?
2562 let Inst{14} = 1;
2563 let Inst{12} = extend{0}; // do shift?
2564 let Inst{11-10} = 0b10;
2565 let Inst{9-5} = Rn;
2566 let Inst{4-0} = Rt;
2567}
2568
2569class ROInstAlias<string asm, RegisterClass regtype, Instruction INST>
Ahmed Bougachacca07712015-09-02 18:38:36 +00002570 : InstAlias<asm # "\t$Rt, [$Rn, $Rm]",
Tim Northover3b0846e2014-05-24 12:50:23 +00002571 (INST regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, 0, 0)>;
2572
2573multiclass Load8RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2574 string asm, ValueType Ty, SDPatternOperator loadop> {
2575 let AddedComplexity = 10 in
2576 def roW : LoadStore8RO<sz, V, opc, regtype, asm,
2577 (outs regtype:$Rt),
2578 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend8:$extend),
2579 [(set (Ty regtype:$Rt),
2580 (loadop (ro_Windexed8 GPR64sp:$Rn, GPR32:$Rm,
2581 ro_Wextend8:$extend)))]>,
2582 Sched<[WriteLDIdx, ReadAdrBase]> {
2583 let Inst{13} = 0b0;
2584 }
2585
2586 let AddedComplexity = 10 in
2587 def roX : LoadStore8RO<sz, V, opc, regtype, asm,
2588 (outs regtype:$Rt),
2589 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend8:$extend),
2590 [(set (Ty regtype:$Rt),
2591 (loadop (ro_Xindexed8 GPR64sp:$Rn, GPR64:$Rm,
2592 ro_Xextend8:$extend)))]>,
2593 Sched<[WriteLDIdx, ReadAdrBase]> {
2594 let Inst{13} = 0b1;
2595 }
2596
2597 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
2598}
2599
2600multiclass Store8RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2601 string asm, ValueType Ty, SDPatternOperator storeop> {
2602 let AddedComplexity = 10 in
2603 def roW : LoadStore8RO<sz, V, opc, regtype, asm, (outs),
2604 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend8:$extend),
2605 [(storeop (Ty regtype:$Rt),
2606 (ro_Windexed8 GPR64sp:$Rn, GPR32:$Rm,
2607 ro_Wextend8:$extend))]>,
2608 Sched<[WriteSTIdx, ReadAdrBase]> {
2609 let Inst{13} = 0b0;
2610 }
2611
2612 let AddedComplexity = 10 in
2613 def roX : LoadStore8RO<sz, V, opc, regtype, asm, (outs),
2614 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend8:$extend),
2615 [(storeop (Ty regtype:$Rt),
2616 (ro_Xindexed8 GPR64sp:$Rn, GPR64:$Rm,
2617 ro_Xextend8:$extend))]>,
2618 Sched<[WriteSTIdx, ReadAdrBase]> {
2619 let Inst{13} = 0b1;
2620 }
2621
2622 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
2623}
2624
2625class LoadStore16RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2626 string asm, dag ins, dag outs, list<dag> pat>
2627 : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> {
2628 bits<5> Rt;
2629 bits<5> Rn;
2630 bits<5> Rm;
2631 bits<2> extend;
2632 let Inst{31-30} = sz;
2633 let Inst{29-27} = 0b111;
2634 let Inst{26} = V;
2635 let Inst{25-24} = 0b00;
2636 let Inst{23-22} = opc;
2637 let Inst{21} = 1;
2638 let Inst{20-16} = Rm;
2639 let Inst{15} = extend{1}; // sign extend Rm?
2640 let Inst{14} = 1;
2641 let Inst{12} = extend{0}; // do shift?
2642 let Inst{11-10} = 0b10;
2643 let Inst{9-5} = Rn;
2644 let Inst{4-0} = Rt;
2645}
2646
2647multiclass Load16RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2648 string asm, ValueType Ty, SDPatternOperator loadop> {
2649 let AddedComplexity = 10 in
2650 def roW : LoadStore16RO<sz, V, opc, regtype, asm, (outs regtype:$Rt),
2651 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend16:$extend),
2652 [(set (Ty regtype:$Rt),
2653 (loadop (ro_Windexed16 GPR64sp:$Rn, GPR32:$Rm,
2654 ro_Wextend16:$extend)))]>,
2655 Sched<[WriteLDIdx, ReadAdrBase]> {
2656 let Inst{13} = 0b0;
2657 }
2658
2659 let AddedComplexity = 10 in
2660 def roX : LoadStore16RO<sz, V, opc, regtype, asm, (outs regtype:$Rt),
2661 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend16:$extend),
2662 [(set (Ty regtype:$Rt),
2663 (loadop (ro_Xindexed16 GPR64sp:$Rn, GPR64:$Rm,
2664 ro_Xextend16:$extend)))]>,
2665 Sched<[WriteLDIdx, ReadAdrBase]> {
2666 let Inst{13} = 0b1;
2667 }
2668
2669 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
2670}
2671
2672multiclass Store16RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2673 string asm, ValueType Ty, SDPatternOperator storeop> {
2674 let AddedComplexity = 10 in
2675 def roW : LoadStore16RO<sz, V, opc, regtype, asm, (outs),
2676 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend16:$extend),
2677 [(storeop (Ty regtype:$Rt),
2678 (ro_Windexed16 GPR64sp:$Rn, GPR32:$Rm,
2679 ro_Wextend16:$extend))]>,
2680 Sched<[WriteSTIdx, ReadAdrBase]> {
2681 let Inst{13} = 0b0;
2682 }
2683
2684 let AddedComplexity = 10 in
2685 def roX : LoadStore16RO<sz, V, opc, regtype, asm, (outs),
2686 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend16:$extend),
2687 [(storeop (Ty regtype:$Rt),
2688 (ro_Xindexed16 GPR64sp:$Rn, GPR64:$Rm,
2689 ro_Xextend16:$extend))]>,
2690 Sched<[WriteSTIdx, ReadAdrBase]> {
2691 let Inst{13} = 0b1;
2692 }
2693
2694 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
2695}
2696
2697class LoadStore32RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2698 string asm, dag ins, dag outs, list<dag> pat>
2699 : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> {
2700 bits<5> Rt;
2701 bits<5> Rn;
2702 bits<5> Rm;
2703 bits<2> extend;
2704 let Inst{31-30} = sz;
2705 let Inst{29-27} = 0b111;
2706 let Inst{26} = V;
2707 let Inst{25-24} = 0b00;
2708 let Inst{23-22} = opc;
2709 let Inst{21} = 1;
2710 let Inst{20-16} = Rm;
2711 let Inst{15} = extend{1}; // sign extend Rm?
2712 let Inst{14} = 1;
2713 let Inst{12} = extend{0}; // do shift?
2714 let Inst{11-10} = 0b10;
2715 let Inst{9-5} = Rn;
2716 let Inst{4-0} = Rt;
2717}
2718
2719multiclass Load32RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2720 string asm, ValueType Ty, SDPatternOperator loadop> {
2721 let AddedComplexity = 10 in
2722 def roW : LoadStore32RO<sz, V, opc, regtype, asm, (outs regtype:$Rt),
2723 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend32:$extend),
2724 [(set (Ty regtype:$Rt),
2725 (loadop (ro_Windexed32 GPR64sp:$Rn, GPR32:$Rm,
2726 ro_Wextend32:$extend)))]>,
2727 Sched<[WriteLDIdx, ReadAdrBase]> {
2728 let Inst{13} = 0b0;
2729 }
2730
2731 let AddedComplexity = 10 in
2732 def roX : LoadStore32RO<sz, V, opc, regtype, asm, (outs regtype:$Rt),
2733 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend32:$extend),
2734 [(set (Ty regtype:$Rt),
2735 (loadop (ro_Xindexed32 GPR64sp:$Rn, GPR64:$Rm,
2736 ro_Xextend32:$extend)))]>,
2737 Sched<[WriteLDIdx, ReadAdrBase]> {
2738 let Inst{13} = 0b1;
2739 }
2740
2741 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
2742}
2743
2744multiclass Store32RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2745 string asm, ValueType Ty, SDPatternOperator storeop> {
2746 let AddedComplexity = 10 in
2747 def roW : LoadStore32RO<sz, V, opc, regtype, asm, (outs),
2748 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend32:$extend),
2749 [(storeop (Ty regtype:$Rt),
2750 (ro_Windexed32 GPR64sp:$Rn, GPR32:$Rm,
2751 ro_Wextend32:$extend))]>,
2752 Sched<[WriteSTIdx, ReadAdrBase]> {
2753 let Inst{13} = 0b0;
2754 }
2755
2756 let AddedComplexity = 10 in
2757 def roX : LoadStore32RO<sz, V, opc, regtype, asm, (outs),
2758 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend32:$extend),
2759 [(storeop (Ty regtype:$Rt),
2760 (ro_Xindexed32 GPR64sp:$Rn, GPR64:$Rm,
2761 ro_Xextend32:$extend))]>,
2762 Sched<[WriteSTIdx, ReadAdrBase]> {
2763 let Inst{13} = 0b1;
2764 }
2765
2766 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
2767}
2768
2769class LoadStore64RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2770 string asm, dag ins, dag outs, list<dag> pat>
2771 : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> {
2772 bits<5> Rt;
2773 bits<5> Rn;
2774 bits<5> Rm;
2775 bits<2> extend;
2776 let Inst{31-30} = sz;
2777 let Inst{29-27} = 0b111;
2778 let Inst{26} = V;
2779 let Inst{25-24} = 0b00;
2780 let Inst{23-22} = opc;
2781 let Inst{21} = 1;
2782 let Inst{20-16} = Rm;
2783 let Inst{15} = extend{1}; // sign extend Rm?
2784 let Inst{14} = 1;
2785 let Inst{12} = extend{0}; // do shift?
2786 let Inst{11-10} = 0b10;
2787 let Inst{9-5} = Rn;
2788 let Inst{4-0} = Rt;
2789}
2790
2791multiclass Load64RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2792 string asm, ValueType Ty, SDPatternOperator loadop> {
2793 let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
2794 def roW : LoadStore64RO<sz, V, opc, regtype, asm, (outs regtype:$Rt),
2795 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend64:$extend),
2796 [(set (Ty regtype:$Rt),
2797 (loadop (ro_Windexed64 GPR64sp:$Rn, GPR32:$Rm,
2798 ro_Wextend64:$extend)))]>,
2799 Sched<[WriteLDIdx, ReadAdrBase]> {
2800 let Inst{13} = 0b0;
2801 }
2802
2803 let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
2804 def roX : LoadStore64RO<sz, V, opc, regtype, asm, (outs regtype:$Rt),
2805 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend64:$extend),
2806 [(set (Ty regtype:$Rt),
2807 (loadop (ro_Xindexed64 GPR64sp:$Rn, GPR64:$Rm,
2808 ro_Xextend64:$extend)))]>,
2809 Sched<[WriteLDIdx, ReadAdrBase]> {
2810 let Inst{13} = 0b1;
2811 }
2812
2813 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
2814}
2815
2816multiclass Store64RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2817 string asm, ValueType Ty, SDPatternOperator storeop> {
2818 let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
2819 def roW : LoadStore64RO<sz, V, opc, regtype, asm, (outs),
2820 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend64:$extend),
2821 [(storeop (Ty regtype:$Rt),
2822 (ro_Windexed64 GPR64sp:$Rn, GPR32:$Rm,
2823 ro_Wextend64:$extend))]>,
2824 Sched<[WriteSTIdx, ReadAdrBase]> {
2825 let Inst{13} = 0b0;
2826 }
2827
2828 let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
2829 def roX : LoadStore64RO<sz, V, opc, regtype, asm, (outs),
2830 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend64:$extend),
2831 [(storeop (Ty regtype:$Rt),
2832 (ro_Xindexed64 GPR64sp:$Rn, GPR64:$Rm,
2833 ro_Xextend64:$extend))]>,
2834 Sched<[WriteSTIdx, ReadAdrBase]> {
2835 let Inst{13} = 0b1;
2836 }
2837
2838 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
2839}
2840
2841class LoadStore128RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2842 string asm, dag ins, dag outs, list<dag> pat>
2843 : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> {
2844 bits<5> Rt;
2845 bits<5> Rn;
2846 bits<5> Rm;
2847 bits<2> extend;
2848 let Inst{31-30} = sz;
2849 let Inst{29-27} = 0b111;
2850 let Inst{26} = V;
2851 let Inst{25-24} = 0b00;
2852 let Inst{23-22} = opc;
2853 let Inst{21} = 1;
2854 let Inst{20-16} = Rm;
2855 let Inst{15} = extend{1}; // sign extend Rm?
2856 let Inst{14} = 1;
2857 let Inst{12} = extend{0}; // do shift?
2858 let Inst{11-10} = 0b10;
2859 let Inst{9-5} = Rn;
2860 let Inst{4-0} = Rt;
2861}
2862
2863multiclass Load128RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2864 string asm, ValueType Ty, SDPatternOperator loadop> {
2865 let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
2866 def roW : LoadStore128RO<sz, V, opc, regtype, asm, (outs regtype:$Rt),
2867 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend128:$extend),
2868 [(set (Ty regtype:$Rt),
2869 (loadop (ro_Windexed128 GPR64sp:$Rn, GPR32:$Rm,
2870 ro_Wextend128:$extend)))]>,
2871 Sched<[WriteLDIdx, ReadAdrBase]> {
2872 let Inst{13} = 0b0;
2873 }
2874
2875 let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
2876 def roX : LoadStore128RO<sz, V, opc, regtype, asm, (outs regtype:$Rt),
2877 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend128:$extend),
2878 [(set (Ty regtype:$Rt),
2879 (loadop (ro_Xindexed128 GPR64sp:$Rn, GPR64:$Rm,
2880 ro_Xextend128:$extend)))]>,
2881 Sched<[WriteLDIdx, ReadAdrBase]> {
2882 let Inst{13} = 0b1;
2883 }
2884
2885 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
2886}
2887
2888multiclass Store128RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2889 string asm, ValueType Ty, SDPatternOperator storeop> {
2890 let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
2891 def roW : LoadStore128RO<sz, V, opc, regtype, asm, (outs),
2892 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend128:$extend),
2893 [(storeop (Ty regtype:$Rt),
2894 (ro_Windexed128 GPR64sp:$Rn, GPR32:$Rm,
2895 ro_Wextend128:$extend))]>,
2896 Sched<[WriteSTIdx, ReadAdrBase]> {
2897 let Inst{13} = 0b0;
2898 }
2899
2900 let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
2901 def roX : LoadStore128RO<sz, V, opc, regtype, asm, (outs),
2902 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend128:$extend),
2903 [(storeop (Ty regtype:$Rt),
2904 (ro_Xindexed128 GPR64sp:$Rn, GPR64:$Rm,
2905 ro_Xextend128:$extend))]>,
2906 Sched<[WriteSTIdx, ReadAdrBase]> {
2907 let Inst{13} = 0b1;
2908 }
2909
2910 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
2911}
2912
2913let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in
2914class BasePrefetchRO<bits<2> sz, bit V, bits<2> opc, dag outs, dag ins,
2915 string asm, list<dag> pat>
2916 : I<outs, ins, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat>,
2917 Sched<[WriteLD]> {
2918 bits<5> Rt;
2919 bits<5> Rn;
2920 bits<5> Rm;
2921 bits<2> extend;
2922 let Inst{31-30} = sz;
2923 let Inst{29-27} = 0b111;
2924 let Inst{26} = V;
2925 let Inst{25-24} = 0b00;
2926 let Inst{23-22} = opc;
2927 let Inst{21} = 1;
2928 let Inst{20-16} = Rm;
2929 let Inst{15} = extend{1}; // sign extend Rm?
2930 let Inst{14} = 1;
2931 let Inst{12} = extend{0}; // do shift?
2932 let Inst{11-10} = 0b10;
2933 let Inst{9-5} = Rn;
2934 let Inst{4-0} = Rt;
2935}
2936
2937multiclass PrefetchRO<bits<2> sz, bit V, bits<2> opc, string asm> {
2938 def roW : BasePrefetchRO<sz, V, opc, (outs),
2939 (ins prfop:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend64:$extend),
2940 asm, [(AArch64Prefetch imm:$Rt,
2941 (ro_Windexed64 GPR64sp:$Rn, GPR32:$Rm,
2942 ro_Wextend64:$extend))]> {
2943 let Inst{13} = 0b0;
2944 }
2945
2946 def roX : BasePrefetchRO<sz, V, opc, (outs),
2947 (ins prfop:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend64:$extend),
2948 asm, [(AArch64Prefetch imm:$Rt,
2949 (ro_Xindexed64 GPR64sp:$Rn, GPR64:$Rm,
2950 ro_Xextend64:$extend))]> {
2951 let Inst{13} = 0b1;
2952 }
2953
2954 def : InstAlias<"prfm $Rt, [$Rn, $Rm]",
2955 (!cast<Instruction>(NAME # "roX") prfop:$Rt,
2956 GPR64sp:$Rn, GPR64:$Rm, 0, 0)>;
2957}
2958
2959//---
2960// Load/store unscaled immediate
2961//---
2962
2963def am_unscaled8 : ComplexPattern<i64, 2, "SelectAddrModeUnscaled8", []>;
2964def am_unscaled16 : ComplexPattern<i64, 2, "SelectAddrModeUnscaled16", []>;
2965def am_unscaled32 : ComplexPattern<i64, 2, "SelectAddrModeUnscaled32", []>;
2966def am_unscaled64 : ComplexPattern<i64, 2, "SelectAddrModeUnscaled64", []>;
2967def am_unscaled128 :ComplexPattern<i64, 2, "SelectAddrModeUnscaled128", []>;
2968
2969class BaseLoadStoreUnscale<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops,
2970 string asm, list<dag> pattern>
2971 : I<oops, iops, asm, "\t$Rt, [$Rn, $offset]", "", pattern> {
2972 bits<5> Rt;
2973 bits<5> Rn;
2974 bits<9> offset;
2975 let Inst{31-30} = sz;
2976 let Inst{29-27} = 0b111;
2977 let Inst{26} = V;
2978 let Inst{25-24} = 0b00;
2979 let Inst{23-22} = opc;
2980 let Inst{21} = 0;
2981 let Inst{20-12} = offset;
2982 let Inst{11-10} = 0b00;
2983 let Inst{9-5} = Rn;
2984 let Inst{4-0} = Rt;
2985
2986 let DecoderMethod = "DecodeSignedLdStInstruction";
2987}
2988
2989multiclass LoadUnscaled<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2990 string asm, list<dag> pattern> {
2991 let AddedComplexity = 1 in // try this before LoadUI
2992 def i : BaseLoadStoreUnscale<sz, V, opc, (outs regtype:$Rt),
2993 (ins GPR64sp:$Rn, simm9:$offset), asm, pattern>,
2994 Sched<[WriteLD]>;
2995
Ahmed Bougachacca07712015-09-02 18:38:36 +00002996 def : InstAlias<asm # "\t$Rt, [$Rn]",
Tim Northover3b0846e2014-05-24 12:50:23 +00002997 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>;
2998}
2999
3000multiclass StoreUnscaled<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
3001 string asm, list<dag> pattern> {
3002 let AddedComplexity = 1 in // try this before StoreUI
3003 def i : BaseLoadStoreUnscale<sz, V, opc, (outs),
3004 (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset),
3005 asm, pattern>,
3006 Sched<[WriteST]>;
3007
Ahmed Bougachacca07712015-09-02 18:38:36 +00003008 def : InstAlias<asm # "\t$Rt, [$Rn]",
Tim Northover3b0846e2014-05-24 12:50:23 +00003009 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>;
3010}
3011
3012multiclass PrefetchUnscaled<bits<2> sz, bit V, bits<2> opc, string asm,
3013 list<dag> pat> {
3014 let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in
3015 def i : BaseLoadStoreUnscale<sz, V, opc, (outs),
3016 (ins prfop:$Rt, GPR64sp:$Rn, simm9:$offset),
3017 asm, pat>,
3018 Sched<[WriteLD]>;
3019
Ahmed Bougachacca07712015-09-02 18:38:36 +00003020 def : InstAlias<asm # "\t$Rt, [$Rn]",
Tim Northover3b0846e2014-05-24 12:50:23 +00003021 (!cast<Instruction>(NAME # "i") prfop:$Rt, GPR64sp:$Rn, 0)>;
3022}
3023
3024//---
3025// Load/store unscaled immediate, unprivileged
3026//---
3027
3028class BaseLoadStoreUnprivileged<bits<2> sz, bit V, bits<2> opc,
3029 dag oops, dag iops, string asm>
3030 : I<oops, iops, asm, "\t$Rt, [$Rn, $offset]", "", []> {
3031 bits<5> Rt;
3032 bits<5> Rn;
3033 bits<9> offset;
3034 let Inst{31-30} = sz;
3035 let Inst{29-27} = 0b111;
3036 let Inst{26} = V;
3037 let Inst{25-24} = 0b00;
3038 let Inst{23-22} = opc;
3039 let Inst{21} = 0;
3040 let Inst{20-12} = offset;
3041 let Inst{11-10} = 0b10;
3042 let Inst{9-5} = Rn;
3043 let Inst{4-0} = Rt;
3044
3045 let DecoderMethod = "DecodeSignedLdStInstruction";
3046}
3047
3048multiclass LoadUnprivileged<bits<2> sz, bit V, bits<2> opc,
3049 RegisterClass regtype, string asm> {
3050 let mayStore = 0, mayLoad = 1, hasSideEffects = 0 in
3051 def i : BaseLoadStoreUnprivileged<sz, V, opc, (outs regtype:$Rt),
3052 (ins GPR64sp:$Rn, simm9:$offset), asm>,
3053 Sched<[WriteLD]>;
3054
Ahmed Bougachacca07712015-09-02 18:38:36 +00003055 def : InstAlias<asm # "\t$Rt, [$Rn]",
Tim Northover3b0846e2014-05-24 12:50:23 +00003056 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>;
3057}
3058
3059multiclass StoreUnprivileged<bits<2> sz, bit V, bits<2> opc,
3060 RegisterClass regtype, string asm> {
3061 let mayStore = 1, mayLoad = 0, hasSideEffects = 0 in
3062 def i : BaseLoadStoreUnprivileged<sz, V, opc, (outs),
3063 (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset),
3064 asm>,
3065 Sched<[WriteST]>;
3066
Ahmed Bougachacca07712015-09-02 18:38:36 +00003067 def : InstAlias<asm # "\t$Rt, [$Rn]",
Tim Northover3b0846e2014-05-24 12:50:23 +00003068 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>;
3069}
3070
3071//---
3072// Load/store pre-indexed
3073//---
3074
3075class BaseLoadStorePreIdx<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops,
3076 string asm, string cstr, list<dag> pat>
3077 : I<oops, iops, asm, "\t$Rt, [$Rn, $offset]!", cstr, pat> {
3078 bits<5> Rt;
3079 bits<5> Rn;
3080 bits<9> offset;
3081 let Inst{31-30} = sz;
3082 let Inst{29-27} = 0b111;
3083 let Inst{26} = V;
3084 let Inst{25-24} = 0;
3085 let Inst{23-22} = opc;
3086 let Inst{21} = 0;
3087 let Inst{20-12} = offset;
3088 let Inst{11-10} = 0b11;
3089 let Inst{9-5} = Rn;
3090 let Inst{4-0} = Rt;
3091
3092 let DecoderMethod = "DecodeSignedLdStInstruction";
3093}
3094
3095let hasSideEffects = 0 in {
3096let mayStore = 0, mayLoad = 1 in
3097class LoadPreIdx<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
3098 string asm>
3099 : BaseLoadStorePreIdx<sz, V, opc,
3100 (outs GPR64sp:$wback, regtype:$Rt),
3101 (ins GPR64sp:$Rn, simm9:$offset), asm,
Quentin Colombetc64c1752014-08-11 21:39:53 +00003102 "$Rn = $wback,@earlyclobber $wback", []>,
Tim Northover3b0846e2014-05-24 12:50:23 +00003103 Sched<[WriteLD, WriteAdr]>;
3104
3105let mayStore = 1, mayLoad = 0 in
3106class StorePreIdx<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
3107 string asm, SDPatternOperator storeop, ValueType Ty>
3108 : BaseLoadStorePreIdx<sz, V, opc,
3109 (outs GPR64sp:$wback),
3110 (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset),
Quentin Colombetc64c1752014-08-11 21:39:53 +00003111 asm, "$Rn = $wback,@earlyclobber $wback",
Tim Northover3b0846e2014-05-24 12:50:23 +00003112 [(set GPR64sp:$wback,
3113 (storeop (Ty regtype:$Rt), GPR64sp:$Rn, simm9:$offset))]>,
3114 Sched<[WriteAdr, WriteST]>;
3115} // hasSideEffects = 0
3116
3117//---
3118// Load/store post-indexed
3119//---
3120
Tim Northover3b0846e2014-05-24 12:50:23 +00003121class BaseLoadStorePostIdx<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops,
3122 string asm, string cstr, list<dag> pat>
3123 : I<oops, iops, asm, "\t$Rt, [$Rn], $offset", cstr, pat> {
3124 bits<5> Rt;
3125 bits<5> Rn;
3126 bits<9> offset;
3127 let Inst{31-30} = sz;
3128 let Inst{29-27} = 0b111;
3129 let Inst{26} = V;
3130 let Inst{25-24} = 0b00;
3131 let Inst{23-22} = opc;
3132 let Inst{21} = 0b0;
3133 let Inst{20-12} = offset;
3134 let Inst{11-10} = 0b01;
3135 let Inst{9-5} = Rn;
3136 let Inst{4-0} = Rt;
3137
3138 let DecoderMethod = "DecodeSignedLdStInstruction";
3139}
3140
3141let hasSideEffects = 0 in {
3142let mayStore = 0, mayLoad = 1 in
3143class LoadPostIdx<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
3144 string asm>
3145 : BaseLoadStorePostIdx<sz, V, opc,
3146 (outs GPR64sp:$wback, regtype:$Rt),
3147 (ins GPR64sp:$Rn, simm9:$offset),
Quentin Colombetc64c1752014-08-11 21:39:53 +00003148 asm, "$Rn = $wback,@earlyclobber $wback", []>,
Tim Northover3b0846e2014-05-24 12:50:23 +00003149 Sched<[WriteLD, WriteI]>;
3150
3151let mayStore = 1, mayLoad = 0 in
3152class StorePostIdx<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
3153 string asm, SDPatternOperator storeop, ValueType Ty>
3154 : BaseLoadStorePostIdx<sz, V, opc,
3155 (outs GPR64sp:$wback),
3156 (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset),
Quentin Colombetc64c1752014-08-11 21:39:53 +00003157 asm, "$Rn = $wback,@earlyclobber $wback",
Tim Northover3b0846e2014-05-24 12:50:23 +00003158 [(set GPR64sp:$wback,
3159 (storeop (Ty regtype:$Rt), GPR64sp:$Rn, simm9:$offset))]>,
3160 Sched<[WriteAdr, WriteST, ReadAdrBase]>;
3161} // hasSideEffects = 0
3162
3163
3164//---
3165// Load/store pair
3166//---
3167
3168// (indexed, offset)
3169
3170class BaseLoadStorePairOffset<bits<2> opc, bit V, bit L, dag oops, dag iops,
3171 string asm>
3172 : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn, $offset]", "", []> {
3173 bits<5> Rt;
3174 bits<5> Rt2;
3175 bits<5> Rn;
3176 bits<7> offset;
3177 let Inst{31-30} = opc;
3178 let Inst{29-27} = 0b101;
3179 let Inst{26} = V;
3180 let Inst{25-23} = 0b010;
3181 let Inst{22} = L;
3182 let Inst{21-15} = offset;
3183 let Inst{14-10} = Rt2;
3184 let Inst{9-5} = Rn;
3185 let Inst{4-0} = Rt;
3186
3187 let DecoderMethod = "DecodePairLdStInstruction";
3188}
3189
3190multiclass LoadPairOffset<bits<2> opc, bit V, RegisterClass regtype,
3191 Operand indextype, string asm> {
3192 let hasSideEffects = 0, mayStore = 0, mayLoad = 1 in
3193 def i : BaseLoadStorePairOffset<opc, V, 1,
3194 (outs regtype:$Rt, regtype:$Rt2),
3195 (ins GPR64sp:$Rn, indextype:$offset), asm>,
3196 Sched<[WriteLD, WriteLDHi]>;
3197
Ahmed Bougachacca07712015-09-02 18:38:36 +00003198 def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]",
Tim Northover3b0846e2014-05-24 12:50:23 +00003199 (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2,
3200 GPR64sp:$Rn, 0)>;
3201}
3202
3203
3204multiclass StorePairOffset<bits<2> opc, bit V, RegisterClass regtype,
3205 Operand indextype, string asm> {
3206 let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in
3207 def i : BaseLoadStorePairOffset<opc, V, 0, (outs),
3208 (ins regtype:$Rt, regtype:$Rt2,
3209 GPR64sp:$Rn, indextype:$offset),
3210 asm>,
3211 Sched<[WriteSTP]>;
3212
Ahmed Bougachacca07712015-09-02 18:38:36 +00003213 def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]",
Tim Northover3b0846e2014-05-24 12:50:23 +00003214 (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2,
3215 GPR64sp:$Rn, 0)>;
3216}
3217
3218// (pre-indexed)
3219class BaseLoadStorePairPreIdx<bits<2> opc, bit V, bit L, dag oops, dag iops,
3220 string asm>
Quentin Colombetc64c1752014-08-11 21:39:53 +00003221 : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn, $offset]!", "$Rn = $wback,@earlyclobber $wback", []> {
Tim Northover3b0846e2014-05-24 12:50:23 +00003222 bits<5> Rt;
3223 bits<5> Rt2;
3224 bits<5> Rn;
3225 bits<7> offset;
3226 let Inst{31-30} = opc;
3227 let Inst{29-27} = 0b101;
3228 let Inst{26} = V;
3229 let Inst{25-23} = 0b011;
3230 let Inst{22} = L;
3231 let Inst{21-15} = offset;
3232 let Inst{14-10} = Rt2;
3233 let Inst{9-5} = Rn;
3234 let Inst{4-0} = Rt;
3235
3236 let DecoderMethod = "DecodePairLdStInstruction";
3237}
3238
3239let hasSideEffects = 0 in {
3240let mayStore = 0, mayLoad = 1 in
3241class LoadPairPreIdx<bits<2> opc, bit V, RegisterClass regtype,
3242 Operand indextype, string asm>
3243 : BaseLoadStorePairPreIdx<opc, V, 1,
3244 (outs GPR64sp:$wback, regtype:$Rt, regtype:$Rt2),
3245 (ins GPR64sp:$Rn, indextype:$offset), asm>,
3246 Sched<[WriteLD, WriteLDHi, WriteAdr]>;
3247
3248let mayStore = 1, mayLoad = 0 in
3249class StorePairPreIdx<bits<2> opc, bit V, RegisterClass regtype,
3250 Operand indextype, string asm>
3251 : BaseLoadStorePairPreIdx<opc, V, 0, (outs GPR64sp:$wback),
3252 (ins regtype:$Rt, regtype:$Rt2,
3253 GPR64sp:$Rn, indextype:$offset),
3254 asm>,
3255 Sched<[WriteAdr, WriteSTP]>;
3256} // hasSideEffects = 0
3257
3258// (post-indexed)
3259
3260class BaseLoadStorePairPostIdx<bits<2> opc, bit V, bit L, dag oops, dag iops,
3261 string asm>
Quentin Colombetc64c1752014-08-11 21:39:53 +00003262 : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn], $offset", "$Rn = $wback,@earlyclobber $wback", []> {
Tim Northover3b0846e2014-05-24 12:50:23 +00003263 bits<5> Rt;
3264 bits<5> Rt2;
3265 bits<5> Rn;
3266 bits<7> offset;
3267 let Inst{31-30} = opc;
3268 let Inst{29-27} = 0b101;
3269 let Inst{26} = V;
3270 let Inst{25-23} = 0b001;
3271 let Inst{22} = L;
3272 let Inst{21-15} = offset;
3273 let Inst{14-10} = Rt2;
3274 let Inst{9-5} = Rn;
3275 let Inst{4-0} = Rt;
3276
3277 let DecoderMethod = "DecodePairLdStInstruction";
3278}
3279
3280let hasSideEffects = 0 in {
3281let mayStore = 0, mayLoad = 1 in
3282class LoadPairPostIdx<bits<2> opc, bit V, RegisterClass regtype,
3283 Operand idxtype, string asm>
3284 : BaseLoadStorePairPostIdx<opc, V, 1,
3285 (outs GPR64sp:$wback, regtype:$Rt, regtype:$Rt2),
3286 (ins GPR64sp:$Rn, idxtype:$offset), asm>,
3287 Sched<[WriteLD, WriteLDHi, WriteAdr]>;
3288
3289let mayStore = 1, mayLoad = 0 in
3290class StorePairPostIdx<bits<2> opc, bit V, RegisterClass regtype,
3291 Operand idxtype, string asm>
Chad Rosier7cd472b2015-09-24 19:21:42 +00003292 : BaseLoadStorePairPostIdx<opc, V, 0, (outs GPR64sp:$wback),
3293 (ins regtype:$Rt, regtype:$Rt2,
Tim Northover3b0846e2014-05-24 12:50:23 +00003294 GPR64sp:$Rn, idxtype:$offset),
3295 asm>,
3296 Sched<[WriteAdr, WriteSTP]>;
3297} // hasSideEffects = 0
3298
3299// (no-allocate)
3300
3301class BaseLoadStorePairNoAlloc<bits<2> opc, bit V, bit L, dag oops, dag iops,
3302 string asm>
3303 : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn, $offset]", "", []> {
3304 bits<5> Rt;
3305 bits<5> Rt2;
3306 bits<5> Rn;
3307 bits<7> offset;
3308 let Inst{31-30} = opc;
3309 let Inst{29-27} = 0b101;
3310 let Inst{26} = V;
3311 let Inst{25-23} = 0b000;
3312 let Inst{22} = L;
3313 let Inst{21-15} = offset;
3314 let Inst{14-10} = Rt2;
3315 let Inst{9-5} = Rn;
3316 let Inst{4-0} = Rt;
3317
3318 let DecoderMethod = "DecodePairLdStInstruction";
3319}
3320
3321multiclass LoadPairNoAlloc<bits<2> opc, bit V, RegisterClass regtype,
3322 Operand indextype, string asm> {
3323 let hasSideEffects = 0, mayStore = 0, mayLoad = 1 in
3324 def i : BaseLoadStorePairNoAlloc<opc, V, 1,
3325 (outs regtype:$Rt, regtype:$Rt2),
3326 (ins GPR64sp:$Rn, indextype:$offset), asm>,
3327 Sched<[WriteLD, WriteLDHi]>;
3328
3329
3330 def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]",
3331 (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2,
3332 GPR64sp:$Rn, 0)>;
3333}
3334
3335multiclass StorePairNoAlloc<bits<2> opc, bit V, RegisterClass regtype,
3336 Operand indextype, string asm> {
3337 let hasSideEffects = 0, mayStore = 1, mayLoad = 0 in
3338 def i : BaseLoadStorePairNoAlloc<opc, V, 0, (outs),
3339 (ins regtype:$Rt, regtype:$Rt2,
3340 GPR64sp:$Rn, indextype:$offset),
3341 asm>,
3342 Sched<[WriteSTP]>;
3343
3344 def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]",
3345 (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2,
3346 GPR64sp:$Rn, 0)>;
3347}
3348
3349//---
3350// Load/store exclusive
3351//---
3352
3353// True exclusive operations write to and/or read from the system's exclusive
3354// monitors, which as far as a compiler is concerned can be modelled as a
3355// random shared memory address. Hence LoadExclusive mayStore.
3356//
3357// Since these instructions have the undefined register bits set to 1 in
3358// their canonical form, we need a post encoder method to set those bits
3359// to 1 when encoding these instructions. We do this using the
3360// fixLoadStoreExclusive function. This function has template parameters:
3361//
3362// fixLoadStoreExclusive<int hasRs, int hasRt2>
3363//
3364// hasRs indicates that the instruction uses the Rs field, so we won't set
3365// it to 1 (and the same for Rt2). We don't need template parameters for
3366// the other register fields since Rt and Rn are always used.
3367//
3368let hasSideEffects = 1, mayLoad = 1, mayStore = 1 in
3369class BaseLoadStoreExclusive<bits<2> sz, bit o2, bit L, bit o1, bit o0,
3370 dag oops, dag iops, string asm, string operands>
3371 : I<oops, iops, asm, operands, "", []> {
3372 let Inst{31-30} = sz;
3373 let Inst{29-24} = 0b001000;
3374 let Inst{23} = o2;
3375 let Inst{22} = L;
3376 let Inst{21} = o1;
3377 let Inst{15} = o0;
3378
3379 let DecoderMethod = "DecodeExclusiveLdStInstruction";
3380}
3381
3382// Neither Rs nor Rt2 operands.
3383class LoadStoreExclusiveSimple<bits<2> sz, bit o2, bit L, bit o1, bit o0,
3384 dag oops, dag iops, string asm, string operands>
3385 : BaseLoadStoreExclusive<sz, o2, L, o1, o0, oops, iops, asm, operands> {
3386 bits<5> Rt;
3387 bits<5> Rn;
Vladimir Sukharevd49cb8f2015-04-16 15:30:43 +00003388 let Inst{20-16} = 0b11111;
3389 let Unpredictable{20-16} = 0b11111;
3390 let Inst{14-10} = 0b11111;
3391 let Unpredictable{14-10} = 0b11111;
Tim Northover3b0846e2014-05-24 12:50:23 +00003392 let Inst{9-5} = Rn;
3393 let Inst{4-0} = Rt;
3394
3395 let PostEncoderMethod = "fixLoadStoreExclusive<0,0>";
3396}
3397
3398// Simple load acquires don't set the exclusive monitor
3399let mayLoad = 1, mayStore = 0 in
3400class LoadAcquire<bits<2> sz, bit o2, bit L, bit o1, bit o0,
3401 RegisterClass regtype, string asm>
3402 : LoadStoreExclusiveSimple<sz, o2, L, o1, o0, (outs regtype:$Rt),
3403 (ins GPR64sp0:$Rn), asm, "\t$Rt, [$Rn]">,
3404 Sched<[WriteLD]>;
3405
3406class LoadExclusive<bits<2> sz, bit o2, bit L, bit o1, bit o0,
3407 RegisterClass regtype, string asm>
3408 : LoadStoreExclusiveSimple<sz, o2, L, o1, o0, (outs regtype:$Rt),
3409 (ins GPR64sp0:$Rn), asm, "\t$Rt, [$Rn]">,
3410 Sched<[WriteLD]>;
3411
3412class LoadExclusivePair<bits<2> sz, bit o2, bit L, bit o1, bit o0,
3413 RegisterClass regtype, string asm>
3414 : BaseLoadStoreExclusive<sz, o2, L, o1, o0,
3415 (outs regtype:$Rt, regtype:$Rt2),
3416 (ins GPR64sp0:$Rn), asm,
3417 "\t$Rt, $Rt2, [$Rn]">,
3418 Sched<[WriteLD, WriteLDHi]> {
3419 bits<5> Rt;
3420 bits<5> Rt2;
3421 bits<5> Rn;
3422 let Inst{14-10} = Rt2;
3423 let Inst{9-5} = Rn;
3424 let Inst{4-0} = Rt;
3425
3426 let PostEncoderMethod = "fixLoadStoreExclusive<0,1>";
3427}
3428
3429// Simple store release operations do not check the exclusive monitor.
3430let mayLoad = 0, mayStore = 1 in
3431class StoreRelease<bits<2> sz, bit o2, bit L, bit o1, bit o0,
3432 RegisterClass regtype, string asm>
3433 : LoadStoreExclusiveSimple<sz, o2, L, o1, o0, (outs),
3434 (ins regtype:$Rt, GPR64sp0:$Rn),
3435 asm, "\t$Rt, [$Rn]">,
3436 Sched<[WriteST]>;
3437
3438let mayLoad = 1, mayStore = 1 in
3439class StoreExclusive<bits<2> sz, bit o2, bit L, bit o1, bit o0,
3440 RegisterClass regtype, string asm>
3441 : BaseLoadStoreExclusive<sz, o2, L, o1, o0, (outs GPR32:$Ws),
3442 (ins regtype:$Rt, GPR64sp0:$Rn),
3443 asm, "\t$Ws, $Rt, [$Rn]">,
3444 Sched<[WriteSTX]> {
3445 bits<5> Ws;
3446 bits<5> Rt;
3447 bits<5> Rn;
3448 let Inst{20-16} = Ws;
3449 let Inst{9-5} = Rn;
3450 let Inst{4-0} = Rt;
3451
3452 let Constraints = "@earlyclobber $Ws";
3453 let PostEncoderMethod = "fixLoadStoreExclusive<1,0>";
3454}
3455
3456class StoreExclusivePair<bits<2> sz, bit o2, bit L, bit o1, bit o0,
3457 RegisterClass regtype, string asm>
3458 : BaseLoadStoreExclusive<sz, o2, L, o1, o0,
3459 (outs GPR32:$Ws),
3460 (ins regtype:$Rt, regtype:$Rt2, GPR64sp0:$Rn),
3461 asm, "\t$Ws, $Rt, $Rt2, [$Rn]">,
3462 Sched<[WriteSTX]> {
3463 bits<5> Ws;
3464 bits<5> Rt;
3465 bits<5> Rt2;
3466 bits<5> Rn;
3467 let Inst{20-16} = Ws;
3468 let Inst{14-10} = Rt2;
3469 let Inst{9-5} = Rn;
3470 let Inst{4-0} = Rt;
3471
3472 let Constraints = "@earlyclobber $Ws";
3473}
3474
3475//---
3476// Exception generation
3477//---
3478
3479let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in
3480class ExceptionGeneration<bits<3> op1, bits<2> ll, string asm>
3481 : I<(outs), (ins imm0_65535:$imm), asm, "\t$imm", "", []>,
3482 Sched<[WriteSys]> {
3483 bits<16> imm;
3484 let Inst{31-24} = 0b11010100;
3485 let Inst{23-21} = op1;
3486 let Inst{20-5} = imm;
3487 let Inst{4-2} = 0b000;
3488 let Inst{1-0} = ll;
3489}
3490
3491let Predicates = [HasFPARMv8] in {
3492
3493//---
3494// Floating point to integer conversion
3495//---
3496
3497class BaseFPToIntegerUnscaled<bits<2> type, bits<2> rmode, bits<3> opcode,
3498 RegisterClass srcType, RegisterClass dstType,
3499 string asm, list<dag> pattern>
3500 : I<(outs dstType:$Rd), (ins srcType:$Rn),
3501 asm, "\t$Rd, $Rn", "", pattern>,
3502 Sched<[WriteFCvt]> {
3503 bits<5> Rd;
3504 bits<5> Rn;
3505 let Inst{30-29} = 0b00;
3506 let Inst{28-24} = 0b11110;
3507 let Inst{23-22} = type;
3508 let Inst{21} = 1;
3509 let Inst{20-19} = rmode;
3510 let Inst{18-16} = opcode;
3511 let Inst{15-10} = 0;
3512 let Inst{9-5} = Rn;
3513 let Inst{4-0} = Rd;
3514}
3515
3516let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
3517class BaseFPToInteger<bits<2> type, bits<2> rmode, bits<3> opcode,
3518 RegisterClass srcType, RegisterClass dstType,
3519 Operand immType, string asm, list<dag> pattern>
3520 : I<(outs dstType:$Rd), (ins srcType:$Rn, immType:$scale),
3521 asm, "\t$Rd, $Rn, $scale", "", pattern>,
3522 Sched<[WriteFCvt]> {
3523 bits<5> Rd;
3524 bits<5> Rn;
3525 bits<6> scale;
3526 let Inst{30-29} = 0b00;
3527 let Inst{28-24} = 0b11110;
3528 let Inst{23-22} = type;
3529 let Inst{21} = 0;
3530 let Inst{20-19} = rmode;
3531 let Inst{18-16} = opcode;
3532 let Inst{15-10} = scale;
3533 let Inst{9-5} = Rn;
3534 let Inst{4-0} = Rd;
3535}
3536
3537multiclass FPToIntegerUnscaled<bits<2> rmode, bits<3> opcode, string asm,
3538 SDPatternOperator OpN> {
3539 // Unscaled single-precision to 32-bit
3540 def UWSr : BaseFPToIntegerUnscaled<0b00, rmode, opcode, FPR32, GPR32, asm,
3541 [(set GPR32:$Rd, (OpN FPR32:$Rn))]> {
3542 let Inst{31} = 0; // 32-bit GPR flag
3543 }
3544
3545 // Unscaled single-precision to 64-bit
3546 def UXSr : BaseFPToIntegerUnscaled<0b00, rmode, opcode, FPR32, GPR64, asm,
3547 [(set GPR64:$Rd, (OpN FPR32:$Rn))]> {
3548 let Inst{31} = 1; // 64-bit GPR flag
3549 }
3550
3551 // Unscaled double-precision to 32-bit
3552 def UWDr : BaseFPToIntegerUnscaled<0b01, rmode, opcode, FPR64, GPR32, asm,
3553 [(set GPR32:$Rd, (OpN (f64 FPR64:$Rn)))]> {
3554 let Inst{31} = 0; // 32-bit GPR flag
3555 }
3556
3557 // Unscaled double-precision to 64-bit
3558 def UXDr : BaseFPToIntegerUnscaled<0b01, rmode, opcode, FPR64, GPR64, asm,
3559 [(set GPR64:$Rd, (OpN (f64 FPR64:$Rn)))]> {
3560 let Inst{31} = 1; // 64-bit GPR flag
3561 }
3562}
3563
3564multiclass FPToIntegerScaled<bits<2> rmode, bits<3> opcode, string asm,
3565 SDPatternOperator OpN> {
3566 // Scaled single-precision to 32-bit
3567 def SWSri : BaseFPToInteger<0b00, rmode, opcode, FPR32, GPR32,
3568 fixedpoint_f32_i32, asm,
3569 [(set GPR32:$Rd, (OpN (fmul FPR32:$Rn,
3570 fixedpoint_f32_i32:$scale)))]> {
3571 let Inst{31} = 0; // 32-bit GPR flag
3572 let scale{5} = 1;
3573 }
3574
3575 // Scaled single-precision to 64-bit
3576 def SXSri : BaseFPToInteger<0b00, rmode, opcode, FPR32, GPR64,
3577 fixedpoint_f32_i64, asm,
3578 [(set GPR64:$Rd, (OpN (fmul FPR32:$Rn,
3579 fixedpoint_f32_i64:$scale)))]> {
3580 let Inst{31} = 1; // 64-bit GPR flag
3581 }
3582
3583 // Scaled double-precision to 32-bit
3584 def SWDri : BaseFPToInteger<0b01, rmode, opcode, FPR64, GPR32,
3585 fixedpoint_f64_i32, asm,
3586 [(set GPR32:$Rd, (OpN (fmul FPR64:$Rn,
3587 fixedpoint_f64_i32:$scale)))]> {
3588 let Inst{31} = 0; // 32-bit GPR flag
3589 let scale{5} = 1;
3590 }
3591
3592 // Scaled double-precision to 64-bit
3593 def SXDri : BaseFPToInteger<0b01, rmode, opcode, FPR64, GPR64,
3594 fixedpoint_f64_i64, asm,
3595 [(set GPR64:$Rd, (OpN (fmul FPR64:$Rn,
3596 fixedpoint_f64_i64:$scale)))]> {
3597 let Inst{31} = 1; // 64-bit GPR flag
3598 }
3599}
3600
3601//---
3602// Integer to floating point conversion
3603//---
3604
3605let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
3606class BaseIntegerToFP<bit isUnsigned,
3607 RegisterClass srcType, RegisterClass dstType,
3608 Operand immType, string asm, list<dag> pattern>
3609 : I<(outs dstType:$Rd), (ins srcType:$Rn, immType:$scale),
3610 asm, "\t$Rd, $Rn, $scale", "", pattern>,
3611 Sched<[WriteFCvt]> {
3612 bits<5> Rd;
3613 bits<5> Rn;
3614 bits<6> scale;
3615 let Inst{30-23} = 0b00111100;
3616 let Inst{21-17} = 0b00001;
3617 let Inst{16} = isUnsigned;
3618 let Inst{15-10} = scale;
3619 let Inst{9-5} = Rn;
3620 let Inst{4-0} = Rd;
3621}
3622
3623class BaseIntegerToFPUnscaled<bit isUnsigned,
3624 RegisterClass srcType, RegisterClass dstType,
3625 ValueType dvt, string asm, SDNode node>
3626 : I<(outs dstType:$Rd), (ins srcType:$Rn),
3627 asm, "\t$Rd, $Rn", "", [(set (dvt dstType:$Rd), (node srcType:$Rn))]>,
3628 Sched<[WriteFCvt]> {
3629 bits<5> Rd;
3630 bits<5> Rn;
3631 bits<6> scale;
3632 let Inst{30-23} = 0b00111100;
3633 let Inst{21-17} = 0b10001;
3634 let Inst{16} = isUnsigned;
3635 let Inst{15-10} = 0b000000;
3636 let Inst{9-5} = Rn;
3637 let Inst{4-0} = Rd;
3638}
3639
3640multiclass IntegerToFP<bit isUnsigned, string asm, SDNode node> {
3641 // Unscaled
3642 def UWSri: BaseIntegerToFPUnscaled<isUnsigned, GPR32, FPR32, f32, asm, node> {
3643 let Inst{31} = 0; // 32-bit GPR flag
3644 let Inst{22} = 0; // 32-bit FPR flag
3645 }
3646
3647 def UWDri: BaseIntegerToFPUnscaled<isUnsigned, GPR32, FPR64, f64, asm, node> {
3648 let Inst{31} = 0; // 32-bit GPR flag
3649 let Inst{22} = 1; // 64-bit FPR flag
3650 }
3651
3652 def UXSri: BaseIntegerToFPUnscaled<isUnsigned, GPR64, FPR32, f32, asm, node> {
3653 let Inst{31} = 1; // 64-bit GPR flag
3654 let Inst{22} = 0; // 32-bit FPR flag
3655 }
3656
3657 def UXDri: BaseIntegerToFPUnscaled<isUnsigned, GPR64, FPR64, f64, asm, node> {
3658 let Inst{31} = 1; // 64-bit GPR flag
3659 let Inst{22} = 1; // 64-bit FPR flag
3660 }
3661
3662 // Scaled
3663 def SWSri: BaseIntegerToFP<isUnsigned, GPR32, FPR32, fixedpoint_f32_i32, asm,
3664 [(set FPR32:$Rd,
3665 (fdiv (node GPR32:$Rn),
3666 fixedpoint_f32_i32:$scale))]> {
3667 let Inst{31} = 0; // 32-bit GPR flag
3668 let Inst{22} = 0; // 32-bit FPR flag
3669 let scale{5} = 1;
3670 }
3671
3672 def SWDri: BaseIntegerToFP<isUnsigned, GPR32, FPR64, fixedpoint_f64_i32, asm,
3673 [(set FPR64:$Rd,
3674 (fdiv (node GPR32:$Rn),
3675 fixedpoint_f64_i32:$scale))]> {
3676 let Inst{31} = 0; // 32-bit GPR flag
3677 let Inst{22} = 1; // 64-bit FPR flag
3678 let scale{5} = 1;
3679 }
3680
3681 def SXSri: BaseIntegerToFP<isUnsigned, GPR64, FPR32, fixedpoint_f32_i64, asm,
3682 [(set FPR32:$Rd,
3683 (fdiv (node GPR64:$Rn),
3684 fixedpoint_f32_i64:$scale))]> {
3685 let Inst{31} = 1; // 64-bit GPR flag
3686 let Inst{22} = 0; // 32-bit FPR flag
3687 }
3688
3689 def SXDri: BaseIntegerToFP<isUnsigned, GPR64, FPR64, fixedpoint_f64_i64, asm,
3690 [(set FPR64:$Rd,
3691 (fdiv (node GPR64:$Rn),
3692 fixedpoint_f64_i64:$scale))]> {
3693 let Inst{31} = 1; // 64-bit GPR flag
3694 let Inst{22} = 1; // 64-bit FPR flag
3695 }
3696}
3697
3698//---
3699// Unscaled integer <-> floating point conversion (i.e. FMOV)
3700//---
3701
3702let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
3703class BaseUnscaledConversion<bits<2> rmode, bits<3> opcode,
3704 RegisterClass srcType, RegisterClass dstType,
3705 string asm>
3706 : I<(outs dstType:$Rd), (ins srcType:$Rn), asm, "\t$Rd, $Rn", "",
3707 // We use COPY_TO_REGCLASS for these bitconvert operations.
3708 // copyPhysReg() expands the resultant COPY instructions after
3709 // regalloc is done. This gives greater freedom for the allocator
3710 // and related passes (coalescing, copy propagation, et. al.) to
3711 // be more effective.
3712 [/*(set (dvt dstType:$Rd), (bitconvert (svt srcType:$Rn)))*/]>,
3713 Sched<[WriteFCopy]> {
3714 bits<5> Rd;
3715 bits<5> Rn;
3716 let Inst{30-23} = 0b00111100;
3717 let Inst{21} = 1;
3718 let Inst{20-19} = rmode;
3719 let Inst{18-16} = opcode;
3720 let Inst{15-10} = 0b000000;
3721 let Inst{9-5} = Rn;
3722 let Inst{4-0} = Rd;
3723}
3724
3725let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
3726class BaseUnscaledConversionToHigh<bits<2> rmode, bits<3> opcode,
3727 RegisterClass srcType, RegisterOperand dstType, string asm,
3728 string kind>
3729 : I<(outs dstType:$Rd), (ins srcType:$Rn, VectorIndex1:$idx), asm,
3730 "{\t$Rd"#kind#"$idx, $Rn|"#kind#"\t$Rd$idx, $Rn}", "", []>,
3731 Sched<[WriteFCopy]> {
3732 bits<5> Rd;
3733 bits<5> Rn;
3734 let Inst{30-23} = 0b00111101;
3735 let Inst{21} = 1;
3736 let Inst{20-19} = rmode;
3737 let Inst{18-16} = opcode;
3738 let Inst{15-10} = 0b000000;
3739 let Inst{9-5} = Rn;
3740 let Inst{4-0} = Rd;
3741
3742 let DecoderMethod = "DecodeFMOVLaneInstruction";
3743}
3744
3745let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
3746class BaseUnscaledConversionFromHigh<bits<2> rmode, bits<3> opcode,
3747 RegisterOperand srcType, RegisterClass dstType, string asm,
3748 string kind>
3749 : I<(outs dstType:$Rd), (ins srcType:$Rn, VectorIndex1:$idx), asm,
3750 "{\t$Rd, $Rn"#kind#"$idx|"#kind#"\t$Rd, $Rn$idx}", "", []>,
3751 Sched<[WriteFCopy]> {
3752 bits<5> Rd;
3753 bits<5> Rn;
3754 let Inst{30-23} = 0b00111101;
3755 let Inst{21} = 1;
3756 let Inst{20-19} = rmode;
3757 let Inst{18-16} = opcode;
3758 let Inst{15-10} = 0b000000;
3759 let Inst{9-5} = Rn;
3760 let Inst{4-0} = Rd;
3761
3762 let DecoderMethod = "DecodeFMOVLaneInstruction";
3763}
3764
3765
3766
3767multiclass UnscaledConversion<string asm> {
3768 def WSr : BaseUnscaledConversion<0b00, 0b111, GPR32, FPR32, asm> {
3769 let Inst{31} = 0; // 32-bit GPR flag
3770 let Inst{22} = 0; // 32-bit FPR flag
3771 }
3772
3773 def XDr : BaseUnscaledConversion<0b00, 0b111, GPR64, FPR64, asm> {
3774 let Inst{31} = 1; // 64-bit GPR flag
3775 let Inst{22} = 1; // 64-bit FPR flag
3776 }
3777
3778 def SWr : BaseUnscaledConversion<0b00, 0b110, FPR32, GPR32, asm> {
3779 let Inst{31} = 0; // 32-bit GPR flag
3780 let Inst{22} = 0; // 32-bit FPR flag
3781 }
3782
3783 def DXr : BaseUnscaledConversion<0b00, 0b110, FPR64, GPR64, asm> {
3784 let Inst{31} = 1; // 64-bit GPR flag
3785 let Inst{22} = 1; // 64-bit FPR flag
3786 }
3787
3788 def XDHighr : BaseUnscaledConversionToHigh<0b01, 0b111, GPR64, V128,
3789 asm, ".d"> {
3790 let Inst{31} = 1;
3791 let Inst{22} = 0;
3792 }
3793
3794 def DXHighr : BaseUnscaledConversionFromHigh<0b01, 0b110, V128, GPR64,
3795 asm, ".d"> {
3796 let Inst{31} = 1;
3797 let Inst{22} = 0;
3798 }
3799}
3800
3801//---
3802// Floating point conversion
3803//---
3804
3805class BaseFPConversion<bits<2> type, bits<2> opcode, RegisterClass dstType,
3806 RegisterClass srcType, string asm, list<dag> pattern>
3807 : I<(outs dstType:$Rd), (ins srcType:$Rn), asm, "\t$Rd, $Rn", "", pattern>,
3808 Sched<[WriteFCvt]> {
3809 bits<5> Rd;
3810 bits<5> Rn;
3811 let Inst{31-24} = 0b00011110;
3812 let Inst{23-22} = type;
3813 let Inst{21-17} = 0b10001;
3814 let Inst{16-15} = opcode;
3815 let Inst{14-10} = 0b10000;
3816 let Inst{9-5} = Rn;
3817 let Inst{4-0} = Rd;
3818}
3819
3820multiclass FPConversion<string asm> {
3821 // Double-precision to Half-precision
3822 def HDr : BaseFPConversion<0b01, 0b11, FPR16, FPR64, asm,
3823 [(set FPR16:$Rd, (fround FPR64:$Rn))]>;
3824
3825 // Double-precision to Single-precision
3826 def SDr : BaseFPConversion<0b01, 0b00, FPR32, FPR64, asm,
3827 [(set FPR32:$Rd, (fround FPR64:$Rn))]>;
3828
3829 // Half-precision to Double-precision
3830 def DHr : BaseFPConversion<0b11, 0b01, FPR64, FPR16, asm,
3831 [(set FPR64:$Rd, (fextend FPR16:$Rn))]>;
3832
3833 // Half-precision to Single-precision
3834 def SHr : BaseFPConversion<0b11, 0b00, FPR32, FPR16, asm,
3835 [(set FPR32:$Rd, (fextend FPR16:$Rn))]>;
3836
3837 // Single-precision to Double-precision
3838 def DSr : BaseFPConversion<0b00, 0b01, FPR64, FPR32, asm,
3839 [(set FPR64:$Rd, (fextend FPR32:$Rn))]>;
3840
3841 // Single-precision to Half-precision
3842 def HSr : BaseFPConversion<0b00, 0b11, FPR16, FPR32, asm,
3843 [(set FPR16:$Rd, (fround FPR32:$Rn))]>;
3844}
3845
3846//---
3847// Single operand floating point data processing
3848//---
3849
3850let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
3851class BaseSingleOperandFPData<bits<4> opcode, RegisterClass regtype,
3852 ValueType vt, string asm, SDPatternOperator node>
3853 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm, "\t$Rd, $Rn", "",
3854 [(set (vt regtype:$Rd), (node (vt regtype:$Rn)))]>,
3855 Sched<[WriteF]> {
3856 bits<5> Rd;
3857 bits<5> Rn;
3858 let Inst{31-23} = 0b000111100;
3859 let Inst{21-19} = 0b100;
3860 let Inst{18-15} = opcode;
3861 let Inst{14-10} = 0b10000;
3862 let Inst{9-5} = Rn;
3863 let Inst{4-0} = Rd;
3864}
3865
3866multiclass SingleOperandFPData<bits<4> opcode, string asm,
3867 SDPatternOperator node = null_frag> {
3868 def Sr : BaseSingleOperandFPData<opcode, FPR32, f32, asm, node> {
3869 let Inst{22} = 0; // 32-bit size flag
3870 }
3871
3872 def Dr : BaseSingleOperandFPData<opcode, FPR64, f64, asm, node> {
3873 let Inst{22} = 1; // 64-bit size flag
3874 }
3875}
3876
3877//---
3878// Two operand floating point data processing
3879//---
3880
3881let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
3882class BaseTwoOperandFPData<bits<4> opcode, RegisterClass regtype,
3883 string asm, list<dag> pat>
3884 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm),
3885 asm, "\t$Rd, $Rn, $Rm", "", pat>,
3886 Sched<[WriteF]> {
3887 bits<5> Rd;
3888 bits<5> Rn;
3889 bits<5> Rm;
3890 let Inst{31-23} = 0b000111100;
3891 let Inst{21} = 1;
3892 let Inst{20-16} = Rm;
3893 let Inst{15-12} = opcode;
3894 let Inst{11-10} = 0b10;
3895 let Inst{9-5} = Rn;
3896 let Inst{4-0} = Rd;
3897}
3898
3899multiclass TwoOperandFPData<bits<4> opcode, string asm,
3900 SDPatternOperator node = null_frag> {
3901 def Srr : BaseTwoOperandFPData<opcode, FPR32, asm,
3902 [(set (f32 FPR32:$Rd),
3903 (node (f32 FPR32:$Rn), (f32 FPR32:$Rm)))]> {
3904 let Inst{22} = 0; // 32-bit size flag
3905 }
3906
3907 def Drr : BaseTwoOperandFPData<opcode, FPR64, asm,
3908 [(set (f64 FPR64:$Rd),
3909 (node (f64 FPR64:$Rn), (f64 FPR64:$Rm)))]> {
3910 let Inst{22} = 1; // 64-bit size flag
3911 }
3912}
3913
3914multiclass TwoOperandFPDataNeg<bits<4> opcode, string asm, SDNode node> {
3915 def Srr : BaseTwoOperandFPData<opcode, FPR32, asm,
3916 [(set FPR32:$Rd, (fneg (node FPR32:$Rn, (f32 FPR32:$Rm))))]> {
3917 let Inst{22} = 0; // 32-bit size flag
3918 }
3919
3920 def Drr : BaseTwoOperandFPData<opcode, FPR64, asm,
3921 [(set FPR64:$Rd, (fneg (node FPR64:$Rn, (f64 FPR64:$Rm))))]> {
3922 let Inst{22} = 1; // 64-bit size flag
3923 }
3924}
3925
3926
3927//---
3928// Three operand floating point data processing
3929//---
3930
3931class BaseThreeOperandFPData<bit isNegated, bit isSub,
3932 RegisterClass regtype, string asm, list<dag> pat>
3933 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, regtype: $Ra),
3934 asm, "\t$Rd, $Rn, $Rm, $Ra", "", pat>,
3935 Sched<[WriteFMul]> {
3936 bits<5> Rd;
3937 bits<5> Rn;
3938 bits<5> Rm;
3939 bits<5> Ra;
3940 let Inst{31-23} = 0b000111110;
3941 let Inst{21} = isNegated;
3942 let Inst{20-16} = Rm;
3943 let Inst{15} = isSub;
3944 let Inst{14-10} = Ra;
3945 let Inst{9-5} = Rn;
3946 let Inst{4-0} = Rd;
3947}
3948
3949multiclass ThreeOperandFPData<bit isNegated, bit isSub,string asm,
3950 SDPatternOperator node> {
3951 def Srrr : BaseThreeOperandFPData<isNegated, isSub, FPR32, asm,
3952 [(set FPR32:$Rd,
3953 (node (f32 FPR32:$Rn), (f32 FPR32:$Rm), (f32 FPR32:$Ra)))]> {
3954 let Inst{22} = 0; // 32-bit size flag
3955 }
3956
3957 def Drrr : BaseThreeOperandFPData<isNegated, isSub, FPR64, asm,
3958 [(set FPR64:$Rd,
3959 (node (f64 FPR64:$Rn), (f64 FPR64:$Rm), (f64 FPR64:$Ra)))]> {
3960 let Inst{22} = 1; // 64-bit size flag
3961 }
3962}
3963
3964//---
3965// Floating point data comparisons
3966//---
3967
3968let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
3969class BaseOneOperandFPComparison<bit signalAllNans,
3970 RegisterClass regtype, string asm,
3971 list<dag> pat>
3972 : I<(outs), (ins regtype:$Rn), asm, "\t$Rn, #0.0", "", pat>,
3973 Sched<[WriteFCmp]> {
3974 bits<5> Rn;
3975 let Inst{31-23} = 0b000111100;
3976 let Inst{21} = 1;
3977
3978 let Inst{15-10} = 0b001000;
3979 let Inst{9-5} = Rn;
3980 let Inst{4} = signalAllNans;
3981 let Inst{3-0} = 0b1000;
3982
3983 // Rm should be 0b00000 canonically, but we need to accept any value.
3984 let PostEncoderMethod = "fixOneOperandFPComparison";
3985}
3986
3987let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
3988class BaseTwoOperandFPComparison<bit signalAllNans, RegisterClass regtype,
3989 string asm, list<dag> pat>
3990 : I<(outs), (ins regtype:$Rn, regtype:$Rm), asm, "\t$Rn, $Rm", "", pat>,
3991 Sched<[WriteFCmp]> {
3992 bits<5> Rm;
3993 bits<5> Rn;
3994 let Inst{31-23} = 0b000111100;
3995 let Inst{21} = 1;
3996 let Inst{20-16} = Rm;
3997 let Inst{15-10} = 0b001000;
3998 let Inst{9-5} = Rn;
3999 let Inst{4} = signalAllNans;
4000 let Inst{3-0} = 0b0000;
4001}
4002
4003multiclass FPComparison<bit signalAllNans, string asm,
4004 SDPatternOperator OpNode = null_frag> {
4005 let Defs = [NZCV] in {
4006 def Srr : BaseTwoOperandFPComparison<signalAllNans, FPR32, asm,
4007 [(OpNode FPR32:$Rn, (f32 FPR32:$Rm)), (implicit NZCV)]> {
4008 let Inst{22} = 0;
4009 }
4010
4011 def Sri : BaseOneOperandFPComparison<signalAllNans, FPR32, asm,
4012 [(OpNode (f32 FPR32:$Rn), fpimm0), (implicit NZCV)]> {
4013 let Inst{22} = 0;
4014 }
4015
4016 def Drr : BaseTwoOperandFPComparison<signalAllNans, FPR64, asm,
4017 [(OpNode FPR64:$Rn, (f64 FPR64:$Rm)), (implicit NZCV)]> {
4018 let Inst{22} = 1;
4019 }
4020
4021 def Dri : BaseOneOperandFPComparison<signalAllNans, FPR64, asm,
4022 [(OpNode (f64 FPR64:$Rn), fpimm0), (implicit NZCV)]> {
4023 let Inst{22} = 1;
4024 }
4025 } // Defs = [NZCV]
4026}
4027
4028//---
4029// Floating point conditional comparisons
4030//---
4031
4032let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
Matthias Braunaf7d7702015-07-16 20:02:37 +00004033class BaseFPCondComparison<bit signalAllNans, RegisterClass regtype,
4034 string mnemonic, list<dag> pat>
4035 : I<(outs), (ins regtype:$Rn, regtype:$Rm, imm32_0_15:$nzcv, ccode:$cond),
4036 mnemonic, "\t$Rn, $Rm, $nzcv, $cond", "", pat>,
Tim Northover3b0846e2014-05-24 12:50:23 +00004037 Sched<[WriteFCmp]> {
Matthias Braunaf7d7702015-07-16 20:02:37 +00004038 let Uses = [NZCV];
4039 let Defs = [NZCV];
4040
Tim Northover3b0846e2014-05-24 12:50:23 +00004041 bits<5> Rn;
4042 bits<5> Rm;
4043 bits<4> nzcv;
4044 bits<4> cond;
4045
4046 let Inst{31-23} = 0b000111100;
4047 let Inst{21} = 1;
4048 let Inst{20-16} = Rm;
4049 let Inst{15-12} = cond;
4050 let Inst{11-10} = 0b01;
4051 let Inst{9-5} = Rn;
4052 let Inst{4} = signalAllNans;
4053 let Inst{3-0} = nzcv;
4054}
4055
Matthias Braunaf7d7702015-07-16 20:02:37 +00004056multiclass FPCondComparison<bit signalAllNans, string mnemonic,
4057 SDPatternOperator OpNode = null_frag> {
4058 def Srr : BaseFPCondComparison<signalAllNans, FPR32, mnemonic,
4059 [(set NZCV, (OpNode (f32 FPR32:$Rn), (f32 FPR32:$Rm), (i32 imm:$nzcv),
4060 (i32 imm:$cond), NZCV))]> {
Tim Northover3b0846e2014-05-24 12:50:23 +00004061 let Inst{22} = 0;
4062 }
Matthias Braunaf7d7702015-07-16 20:02:37 +00004063 def Drr : BaseFPCondComparison<signalAllNans, FPR64, mnemonic,
4064 [(set NZCV, (OpNode (f64 FPR64:$Rn), (f64 FPR64:$Rm), (i32 imm:$nzcv),
4065 (i32 imm:$cond), NZCV))]> {
Tim Northover3b0846e2014-05-24 12:50:23 +00004066 let Inst{22} = 1;
4067 }
Tim Northover3b0846e2014-05-24 12:50:23 +00004068}
4069
4070//---
4071// Floating point conditional select
4072//---
4073
4074class BaseFPCondSelect<RegisterClass regtype, ValueType vt, string asm>
4075 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, ccode:$cond),
4076 asm, "\t$Rd, $Rn, $Rm, $cond", "",
4077 [(set regtype:$Rd,
4078 (AArch64csel (vt regtype:$Rn), regtype:$Rm,
4079 (i32 imm:$cond), NZCV))]>,
4080 Sched<[WriteF]> {
4081 bits<5> Rd;
4082 bits<5> Rn;
4083 bits<5> Rm;
4084 bits<4> cond;
4085
4086 let Inst{31-23} = 0b000111100;
4087 let Inst{21} = 1;
4088 let Inst{20-16} = Rm;
4089 let Inst{15-12} = cond;
4090 let Inst{11-10} = 0b11;
4091 let Inst{9-5} = Rn;
4092 let Inst{4-0} = Rd;
4093}
4094
4095multiclass FPCondSelect<string asm> {
4096 let Uses = [NZCV] in {
4097 def Srrr : BaseFPCondSelect<FPR32, f32, asm> {
4098 let Inst{22} = 0;
4099 }
4100
4101 def Drrr : BaseFPCondSelect<FPR64, f64, asm> {
4102 let Inst{22} = 1;
4103 }
4104 } // Uses = [NZCV]
4105}
4106
4107//---
4108// Floating move immediate
4109//---
4110
4111class BaseFPMoveImmediate<RegisterClass regtype, Operand fpimmtype, string asm>
4112 : I<(outs regtype:$Rd), (ins fpimmtype:$imm), asm, "\t$Rd, $imm", "",
4113 [(set regtype:$Rd, fpimmtype:$imm)]>,
4114 Sched<[WriteFImm]> {
4115 bits<5> Rd;
4116 bits<8> imm;
4117 let Inst{31-23} = 0b000111100;
4118 let Inst{21} = 1;
4119 let Inst{20-13} = imm;
4120 let Inst{12-5} = 0b10000000;
4121 let Inst{4-0} = Rd;
4122}
4123
4124multiclass FPMoveImmediate<string asm> {
4125 def Si : BaseFPMoveImmediate<FPR32, fpimm32, asm> {
4126 let Inst{22} = 0;
4127 }
4128
4129 def Di : BaseFPMoveImmediate<FPR64, fpimm64, asm> {
4130 let Inst{22} = 1;
4131 }
4132}
4133} // end of 'let Predicates = [HasFPARMv8]'
4134
4135//----------------------------------------------------------------------------
4136// AdvSIMD
4137//----------------------------------------------------------------------------
4138
4139let Predicates = [HasNEON] in {
4140
4141//----------------------------------------------------------------------------
4142// AdvSIMD three register vector instructions
4143//----------------------------------------------------------------------------
4144
4145let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
4146class BaseSIMDThreeSameVector<bit Q, bit U, bits<2> size, bits<5> opcode,
4147 RegisterOperand regtype, string asm, string kind,
4148 list<dag> pattern>
4149 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), asm,
4150 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind #
4151 "|" # kind # "\t$Rd, $Rn, $Rm|}", "", pattern>,
4152 Sched<[WriteV]> {
4153 bits<5> Rd;
4154 bits<5> Rn;
4155 bits<5> Rm;
4156 let Inst{31} = 0;
4157 let Inst{30} = Q;
4158 let Inst{29} = U;
4159 let Inst{28-24} = 0b01110;
4160 let Inst{23-22} = size;
4161 let Inst{21} = 1;
4162 let Inst{20-16} = Rm;
4163 let Inst{15-11} = opcode;
4164 let Inst{10} = 1;
4165 let Inst{9-5} = Rn;
4166 let Inst{4-0} = Rd;
4167}
4168
4169let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
4170class BaseSIMDThreeSameVectorTied<bit Q, bit U, bits<2> size, bits<5> opcode,
4171 RegisterOperand regtype, string asm, string kind,
4172 list<dag> pattern>
4173 : I<(outs regtype:$dst), (ins regtype:$Rd, regtype:$Rn, regtype:$Rm), asm,
4174 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind #
4175 "|" # kind # "\t$Rd, $Rn, $Rm}", "$Rd = $dst", pattern>,
4176 Sched<[WriteV]> {
4177 bits<5> Rd;
4178 bits<5> Rn;
4179 bits<5> Rm;
4180 let Inst{31} = 0;
4181 let Inst{30} = Q;
4182 let Inst{29} = U;
4183 let Inst{28-24} = 0b01110;
4184 let Inst{23-22} = size;
4185 let Inst{21} = 1;
4186 let Inst{20-16} = Rm;
4187 let Inst{15-11} = opcode;
4188 let Inst{10} = 1;
4189 let Inst{9-5} = Rn;
4190 let Inst{4-0} = Rd;
4191}
4192
4193// All operand sizes distinguished in the encoding.
4194multiclass SIMDThreeSameVector<bit U, bits<5> opc, string asm,
4195 SDPatternOperator OpNode> {
4196 def v8i8 : BaseSIMDThreeSameVector<0, U, 0b00, opc, V64,
4197 asm, ".8b",
4198 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
4199 def v16i8 : BaseSIMDThreeSameVector<1, U, 0b00, opc, V128,
4200 asm, ".16b",
4201 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn), (v16i8 V128:$Rm)))]>;
4202 def v4i16 : BaseSIMDThreeSameVector<0, U, 0b01, opc, V64,
4203 asm, ".4h",
4204 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>;
4205 def v8i16 : BaseSIMDThreeSameVector<1, U, 0b01, opc, V128,
4206 asm, ".8h",
4207 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>;
4208 def v2i32 : BaseSIMDThreeSameVector<0, U, 0b10, opc, V64,
4209 asm, ".2s",
4210 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>;
4211 def v4i32 : BaseSIMDThreeSameVector<1, U, 0b10, opc, V128,
4212 asm, ".4s",
4213 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>;
4214 def v2i64 : BaseSIMDThreeSameVector<1, U, 0b11, opc, V128,
4215 asm, ".2d",
4216 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn), (v2i64 V128:$Rm)))]>;
4217}
4218
4219// As above, but D sized elements unsupported.
4220multiclass SIMDThreeSameVectorBHS<bit U, bits<5> opc, string asm,
4221 SDPatternOperator OpNode> {
4222 def v8i8 : BaseSIMDThreeSameVector<0, U, 0b00, opc, V64,
4223 asm, ".8b",
4224 [(set V64:$Rd, (v8i8 (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm))))]>;
4225 def v16i8 : BaseSIMDThreeSameVector<1, U, 0b00, opc, V128,
4226 asm, ".16b",
4227 [(set V128:$Rd, (v16i8 (OpNode (v16i8 V128:$Rn), (v16i8 V128:$Rm))))]>;
4228 def v4i16 : BaseSIMDThreeSameVector<0, U, 0b01, opc, V64,
4229 asm, ".4h",
4230 [(set V64:$Rd, (v4i16 (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm))))]>;
4231 def v8i16 : BaseSIMDThreeSameVector<1, U, 0b01, opc, V128,
4232 asm, ".8h",
4233 [(set V128:$Rd, (v8i16 (OpNode (v8i16 V128:$Rn), (v8i16 V128:$Rm))))]>;
4234 def v2i32 : BaseSIMDThreeSameVector<0, U, 0b10, opc, V64,
4235 asm, ".2s",
4236 [(set V64:$Rd, (v2i32 (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm))))]>;
4237 def v4i32 : BaseSIMDThreeSameVector<1, U, 0b10, opc, V128,
4238 asm, ".4s",
4239 [(set V128:$Rd, (v4i32 (OpNode (v4i32 V128:$Rn), (v4i32 V128:$Rm))))]>;
4240}
4241
4242multiclass SIMDThreeSameVectorBHSTied<bit U, bits<5> opc, string asm,
4243 SDPatternOperator OpNode> {
4244 def v8i8 : BaseSIMDThreeSameVectorTied<0, U, 0b00, opc, V64,
4245 asm, ".8b",
4246 [(set (v8i8 V64:$dst),
4247 (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
4248 def v16i8 : BaseSIMDThreeSameVectorTied<1, U, 0b00, opc, V128,
4249 asm, ".16b",
4250 [(set (v16i8 V128:$dst),
4251 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn), (v16i8 V128:$Rm)))]>;
4252 def v4i16 : BaseSIMDThreeSameVectorTied<0, U, 0b01, opc, V64,
4253 asm, ".4h",
4254 [(set (v4i16 V64:$dst),
4255 (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>;
4256 def v8i16 : BaseSIMDThreeSameVectorTied<1, U, 0b01, opc, V128,
4257 asm, ".8h",
4258 [(set (v8i16 V128:$dst),
4259 (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>;
4260 def v2i32 : BaseSIMDThreeSameVectorTied<0, U, 0b10, opc, V64,
4261 asm, ".2s",
4262 [(set (v2i32 V64:$dst),
4263 (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>;
4264 def v4i32 : BaseSIMDThreeSameVectorTied<1, U, 0b10, opc, V128,
4265 asm, ".4s",
4266 [(set (v4i32 V128:$dst),
4267 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>;
4268}
4269
4270// As above, but only B sized elements supported.
4271multiclass SIMDThreeSameVectorB<bit U, bits<5> opc, string asm,
4272 SDPatternOperator OpNode> {
4273 def v8i8 : BaseSIMDThreeSameVector<0, U, 0b00, opc, V64,
4274 asm, ".8b",
4275 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
4276 def v16i8 : BaseSIMDThreeSameVector<1, U, 0b00, opc, V128,
4277 asm, ".16b",
4278 [(set (v16i8 V128:$Rd),
4279 (OpNode (v16i8 V128:$Rn), (v16i8 V128:$Rm)))]>;
4280}
4281
4282// As above, but only S and D sized floating point elements supported.
4283multiclass SIMDThreeSameVectorFP<bit U, bit S, bits<5> opc,
4284 string asm, SDPatternOperator OpNode> {
4285 def v2f32 : BaseSIMDThreeSameVector<0, U, {S,0}, opc, V64,
4286 asm, ".2s",
4287 [(set (v2f32 V64:$Rd), (OpNode (v2f32 V64:$Rn), (v2f32 V64:$Rm)))]>;
4288 def v4f32 : BaseSIMDThreeSameVector<1, U, {S,0}, opc, V128,
4289 asm, ".4s",
4290 [(set (v4f32 V128:$Rd), (OpNode (v4f32 V128:$Rn), (v4f32 V128:$Rm)))]>;
4291 def v2f64 : BaseSIMDThreeSameVector<1, U, {S,1}, opc, V128,
4292 asm, ".2d",
4293 [(set (v2f64 V128:$Rd), (OpNode (v2f64 V128:$Rn), (v2f64 V128:$Rm)))]>;
4294}
4295
4296multiclass SIMDThreeSameVectorFPCmp<bit U, bit S, bits<5> opc,
4297 string asm,
4298 SDPatternOperator OpNode> {
4299 def v2f32 : BaseSIMDThreeSameVector<0, U, {S,0}, opc, V64,
4300 asm, ".2s",
4301 [(set (v2i32 V64:$Rd), (OpNode (v2f32 V64:$Rn), (v2f32 V64:$Rm)))]>;
4302 def v4f32 : BaseSIMDThreeSameVector<1, U, {S,0}, opc, V128,
4303 asm, ".4s",
4304 [(set (v4i32 V128:$Rd), (OpNode (v4f32 V128:$Rn), (v4f32 V128:$Rm)))]>;
4305 def v2f64 : BaseSIMDThreeSameVector<1, U, {S,1}, opc, V128,
4306 asm, ".2d",
4307 [(set (v2i64 V128:$Rd), (OpNode (v2f64 V128:$Rn), (v2f64 V128:$Rm)))]>;
4308}
4309
4310multiclass SIMDThreeSameVectorFPTied<bit U, bit S, bits<5> opc,
4311 string asm, SDPatternOperator OpNode> {
4312 def v2f32 : BaseSIMDThreeSameVectorTied<0, U, {S,0}, opc, V64,
4313 asm, ".2s",
4314 [(set (v2f32 V64:$dst),
4315 (OpNode (v2f32 V64:$Rd), (v2f32 V64:$Rn), (v2f32 V64:$Rm)))]>;
4316 def v4f32 : BaseSIMDThreeSameVectorTied<1, U, {S,0}, opc, V128,
4317 asm, ".4s",
4318 [(set (v4f32 V128:$dst),
4319 (OpNode (v4f32 V128:$Rd), (v4f32 V128:$Rn), (v4f32 V128:$Rm)))]>;
4320 def v2f64 : BaseSIMDThreeSameVectorTied<1, U, {S,1}, opc, V128,
4321 asm, ".2d",
4322 [(set (v2f64 V128:$dst),
4323 (OpNode (v2f64 V128:$Rd), (v2f64 V128:$Rn), (v2f64 V128:$Rm)))]>;
4324}
4325
4326// As above, but D and B sized elements unsupported.
4327multiclass SIMDThreeSameVectorHS<bit U, bits<5> opc, string asm,
4328 SDPatternOperator OpNode> {
4329 def v4i16 : BaseSIMDThreeSameVector<0, U, 0b01, opc, V64,
4330 asm, ".4h",
4331 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>;
4332 def v8i16 : BaseSIMDThreeSameVector<1, U, 0b01, opc, V128,
4333 asm, ".8h",
4334 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>;
4335 def v2i32 : BaseSIMDThreeSameVector<0, U, 0b10, opc, V64,
4336 asm, ".2s",
4337 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>;
4338 def v4i32 : BaseSIMDThreeSameVector<1, U, 0b10, opc, V128,
4339 asm, ".4s",
4340 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>;
4341}
4342
4343// Logical three vector ops share opcode bits, and only use B sized elements.
4344multiclass SIMDLogicalThreeVector<bit U, bits<2> size, string asm,
4345 SDPatternOperator OpNode = null_frag> {
4346 def v8i8 : BaseSIMDThreeSameVector<0, U, size, 0b00011, V64,
4347 asm, ".8b",
4348 [(set (v8i8 V64:$Rd), (OpNode V64:$Rn, V64:$Rm))]>;
4349 def v16i8 : BaseSIMDThreeSameVector<1, U, size, 0b00011, V128,
4350 asm, ".16b",
4351 [(set (v16i8 V128:$Rd), (OpNode V128:$Rn, V128:$Rm))]>;
4352
4353 def : Pat<(v4i16 (OpNode V64:$LHS, V64:$RHS)),
4354 (!cast<Instruction>(NAME#"v8i8") V64:$LHS, V64:$RHS)>;
4355 def : Pat<(v2i32 (OpNode V64:$LHS, V64:$RHS)),
4356 (!cast<Instruction>(NAME#"v8i8") V64:$LHS, V64:$RHS)>;
4357 def : Pat<(v1i64 (OpNode V64:$LHS, V64:$RHS)),
4358 (!cast<Instruction>(NAME#"v8i8") V64:$LHS, V64:$RHS)>;
4359
4360 def : Pat<(v8i16 (OpNode V128:$LHS, V128:$RHS)),
4361 (!cast<Instruction>(NAME#"v16i8") V128:$LHS, V128:$RHS)>;
4362 def : Pat<(v4i32 (OpNode V128:$LHS, V128:$RHS)),
4363 (!cast<Instruction>(NAME#"v16i8") V128:$LHS, V128:$RHS)>;
4364 def : Pat<(v2i64 (OpNode V128:$LHS, V128:$RHS)),
4365 (!cast<Instruction>(NAME#"v16i8") V128:$LHS, V128:$RHS)>;
4366}
4367
4368multiclass SIMDLogicalThreeVectorTied<bit U, bits<2> size,
4369 string asm, SDPatternOperator OpNode> {
4370 def v8i8 : BaseSIMDThreeSameVectorTied<0, U, size, 0b00011, V64,
4371 asm, ".8b",
4372 [(set (v8i8 V64:$dst),
4373 (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
4374 def v16i8 : BaseSIMDThreeSameVectorTied<1, U, size, 0b00011, V128,
4375 asm, ".16b",
4376 [(set (v16i8 V128:$dst),
4377 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn),
4378 (v16i8 V128:$Rm)))]>;
4379
4380 def : Pat<(v4i16 (OpNode (v4i16 V64:$LHS), (v4i16 V64:$MHS),
4381 (v4i16 V64:$RHS))),
4382 (!cast<Instruction>(NAME#"v8i8")
4383 V64:$LHS, V64:$MHS, V64:$RHS)>;
4384 def : Pat<(v2i32 (OpNode (v2i32 V64:$LHS), (v2i32 V64:$MHS),
4385 (v2i32 V64:$RHS))),
4386 (!cast<Instruction>(NAME#"v8i8")
4387 V64:$LHS, V64:$MHS, V64:$RHS)>;
4388 def : Pat<(v1i64 (OpNode (v1i64 V64:$LHS), (v1i64 V64:$MHS),
4389 (v1i64 V64:$RHS))),
4390 (!cast<Instruction>(NAME#"v8i8")
4391 V64:$LHS, V64:$MHS, V64:$RHS)>;
4392
4393 def : Pat<(v8i16 (OpNode (v8i16 V128:$LHS), (v8i16 V128:$MHS),
4394 (v8i16 V128:$RHS))),
4395 (!cast<Instruction>(NAME#"v16i8")
4396 V128:$LHS, V128:$MHS, V128:$RHS)>;
4397 def : Pat<(v4i32 (OpNode (v4i32 V128:$LHS), (v4i32 V128:$MHS),
4398 (v4i32 V128:$RHS))),
4399 (!cast<Instruction>(NAME#"v16i8")
4400 V128:$LHS, V128:$MHS, V128:$RHS)>;
4401 def : Pat<(v2i64 (OpNode (v2i64 V128:$LHS), (v2i64 V128:$MHS),
4402 (v2i64 V128:$RHS))),
4403 (!cast<Instruction>(NAME#"v16i8")
4404 V128:$LHS, V128:$MHS, V128:$RHS)>;
4405}
4406
4407
4408//----------------------------------------------------------------------------
4409// AdvSIMD two register vector instructions.
4410//----------------------------------------------------------------------------
4411
4412let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
4413class BaseSIMDTwoSameVector<bit Q, bit U, bits<2> size, bits<5> opcode,
4414 RegisterOperand regtype, string asm, string dstkind,
4415 string srckind, list<dag> pattern>
4416 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm,
4417 "{\t$Rd" # dstkind # ", $Rn" # srckind #
4418 "|" # dstkind # "\t$Rd, $Rn}", "", pattern>,
4419 Sched<[WriteV]> {
4420 bits<5> Rd;
4421 bits<5> Rn;
4422 let Inst{31} = 0;
4423 let Inst{30} = Q;
4424 let Inst{29} = U;
4425 let Inst{28-24} = 0b01110;
4426 let Inst{23-22} = size;
4427 let Inst{21-17} = 0b10000;
4428 let Inst{16-12} = opcode;
4429 let Inst{11-10} = 0b10;
4430 let Inst{9-5} = Rn;
4431 let Inst{4-0} = Rd;
4432}
4433
4434let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
4435class BaseSIMDTwoSameVectorTied<bit Q, bit U, bits<2> size, bits<5> opcode,
4436 RegisterOperand regtype, string asm, string dstkind,
4437 string srckind, list<dag> pattern>
4438 : I<(outs regtype:$dst), (ins regtype:$Rd, regtype:$Rn), asm,
4439 "{\t$Rd" # dstkind # ", $Rn" # srckind #
4440 "|" # dstkind # "\t$Rd, $Rn}", "$Rd = $dst", pattern>,
4441 Sched<[WriteV]> {
4442 bits<5> Rd;
4443 bits<5> Rn;
4444 let Inst{31} = 0;
4445 let Inst{30} = Q;
4446 let Inst{29} = U;
4447 let Inst{28-24} = 0b01110;
4448 let Inst{23-22} = size;
4449 let Inst{21-17} = 0b10000;
4450 let Inst{16-12} = opcode;
4451 let Inst{11-10} = 0b10;
4452 let Inst{9-5} = Rn;
4453 let Inst{4-0} = Rd;
4454}
4455
4456// Supports B, H, and S element sizes.
4457multiclass SIMDTwoVectorBHS<bit U, bits<5> opc, string asm,
4458 SDPatternOperator OpNode> {
4459 def v8i8 : BaseSIMDTwoSameVector<0, U, 0b00, opc, V64,
4460 asm, ".8b", ".8b",
4461 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>;
4462 def v16i8 : BaseSIMDTwoSameVector<1, U, 0b00, opc, V128,
4463 asm, ".16b", ".16b",
4464 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>;
4465 def v4i16 : BaseSIMDTwoSameVector<0, U, 0b01, opc, V64,
4466 asm, ".4h", ".4h",
4467 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>;
4468 def v8i16 : BaseSIMDTwoSameVector<1, U, 0b01, opc, V128,
4469 asm, ".8h", ".8h",
4470 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>;
4471 def v2i32 : BaseSIMDTwoSameVector<0, U, 0b10, opc, V64,
4472 asm, ".2s", ".2s",
4473 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>;
4474 def v4i32 : BaseSIMDTwoSameVector<1, U, 0b10, opc, V128,
4475 asm, ".4s", ".4s",
4476 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>;
4477}
4478
4479class BaseSIMDVectorLShiftLongBySize<bit Q, bits<2> size,
4480 RegisterOperand regtype, string asm, string dstkind,
4481 string srckind, string amount>
4482 : I<(outs V128:$Rd), (ins regtype:$Rn), asm,
4483 "{\t$Rd" # dstkind # ", $Rn" # srckind # ", #" # amount #
4484 "|" # dstkind # "\t$Rd, $Rn, #" # amount # "}", "", []>,
4485 Sched<[WriteV]> {
4486 bits<5> Rd;
4487 bits<5> Rn;
4488 let Inst{31} = 0;
4489 let Inst{30} = Q;
4490 let Inst{29-24} = 0b101110;
4491 let Inst{23-22} = size;
4492 let Inst{21-10} = 0b100001001110;
4493 let Inst{9-5} = Rn;
4494 let Inst{4-0} = Rd;
4495}
4496
4497multiclass SIMDVectorLShiftLongBySizeBHS {
Craig Topperc50d64b2014-11-26 00:46:26 +00004498 let hasSideEffects = 0 in {
Tim Northover3b0846e2014-05-24 12:50:23 +00004499 def v8i8 : BaseSIMDVectorLShiftLongBySize<0, 0b00, V64,
4500 "shll", ".8h", ".8b", "8">;
4501 def v16i8 : BaseSIMDVectorLShiftLongBySize<1, 0b00, V128,
4502 "shll2", ".8h", ".16b", "8">;
4503 def v4i16 : BaseSIMDVectorLShiftLongBySize<0, 0b01, V64,
4504 "shll", ".4s", ".4h", "16">;
4505 def v8i16 : BaseSIMDVectorLShiftLongBySize<1, 0b01, V128,
4506 "shll2", ".4s", ".8h", "16">;
4507 def v2i32 : BaseSIMDVectorLShiftLongBySize<0, 0b10, V64,
4508 "shll", ".2d", ".2s", "32">;
4509 def v4i32 : BaseSIMDVectorLShiftLongBySize<1, 0b10, V128,
4510 "shll2", ".2d", ".4s", "32">;
4511 }
4512}
4513
4514// Supports all element sizes.
4515multiclass SIMDLongTwoVector<bit U, bits<5> opc, string asm,
4516 SDPatternOperator OpNode> {
4517 def v8i8_v4i16 : BaseSIMDTwoSameVector<0, U, 0b00, opc, V64,
4518 asm, ".4h", ".8b",
4519 [(set (v4i16 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>;
4520 def v16i8_v8i16 : BaseSIMDTwoSameVector<1, U, 0b00, opc, V128,
4521 asm, ".8h", ".16b",
4522 [(set (v8i16 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>;
4523 def v4i16_v2i32 : BaseSIMDTwoSameVector<0, U, 0b01, opc, V64,
4524 asm, ".2s", ".4h",
4525 [(set (v2i32 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>;
4526 def v8i16_v4i32 : BaseSIMDTwoSameVector<1, U, 0b01, opc, V128,
4527 asm, ".4s", ".8h",
4528 [(set (v4i32 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>;
4529 def v2i32_v1i64 : BaseSIMDTwoSameVector<0, U, 0b10, opc, V64,
4530 asm, ".1d", ".2s",
4531 [(set (v1i64 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>;
4532 def v4i32_v2i64 : BaseSIMDTwoSameVector<1, U, 0b10, opc, V128,
4533 asm, ".2d", ".4s",
4534 [(set (v2i64 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>;
4535}
4536
4537multiclass SIMDLongTwoVectorTied<bit U, bits<5> opc, string asm,
4538 SDPatternOperator OpNode> {
4539 def v8i8_v4i16 : BaseSIMDTwoSameVectorTied<0, U, 0b00, opc, V64,
4540 asm, ".4h", ".8b",
4541 [(set (v4i16 V64:$dst), (OpNode (v4i16 V64:$Rd),
4542 (v8i8 V64:$Rn)))]>;
4543 def v16i8_v8i16 : BaseSIMDTwoSameVectorTied<1, U, 0b00, opc, V128,
4544 asm, ".8h", ".16b",
4545 [(set (v8i16 V128:$dst), (OpNode (v8i16 V128:$Rd),
4546 (v16i8 V128:$Rn)))]>;
4547 def v4i16_v2i32 : BaseSIMDTwoSameVectorTied<0, U, 0b01, opc, V64,
4548 asm, ".2s", ".4h",
4549 [(set (v2i32 V64:$dst), (OpNode (v2i32 V64:$Rd),
4550 (v4i16 V64:$Rn)))]>;
4551 def v8i16_v4i32 : BaseSIMDTwoSameVectorTied<1, U, 0b01, opc, V128,
4552 asm, ".4s", ".8h",
4553 [(set (v4i32 V128:$dst), (OpNode (v4i32 V128:$Rd),
4554 (v8i16 V128:$Rn)))]>;
4555 def v2i32_v1i64 : BaseSIMDTwoSameVectorTied<0, U, 0b10, opc, V64,
4556 asm, ".1d", ".2s",
4557 [(set (v1i64 V64:$dst), (OpNode (v1i64 V64:$Rd),
4558 (v2i32 V64:$Rn)))]>;
4559 def v4i32_v2i64 : BaseSIMDTwoSameVectorTied<1, U, 0b10, opc, V128,
4560 asm, ".2d", ".4s",
4561 [(set (v2i64 V128:$dst), (OpNode (v2i64 V128:$Rd),
4562 (v4i32 V128:$Rn)))]>;
4563}
4564
4565// Supports all element sizes, except 1xD.
4566multiclass SIMDTwoVectorBHSDTied<bit U, bits<5> opc, string asm,
4567 SDPatternOperator OpNode> {
4568 def v8i8 : BaseSIMDTwoSameVectorTied<0, U, 0b00, opc, V64,
4569 asm, ".8b", ".8b",
4570 [(set (v8i8 V64:$dst), (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn)))]>;
4571 def v16i8 : BaseSIMDTwoSameVectorTied<1, U, 0b00, opc, V128,
4572 asm, ".16b", ".16b",
4573 [(set (v16i8 V128:$dst), (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn)))]>;
4574 def v4i16 : BaseSIMDTwoSameVectorTied<0, U, 0b01, opc, V64,
4575 asm, ".4h", ".4h",
4576 [(set (v4i16 V64:$dst), (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn)))]>;
4577 def v8i16 : BaseSIMDTwoSameVectorTied<1, U, 0b01, opc, V128,
4578 asm, ".8h", ".8h",
4579 [(set (v8i16 V128:$dst), (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn)))]>;
4580 def v2i32 : BaseSIMDTwoSameVectorTied<0, U, 0b10, opc, V64,
4581 asm, ".2s", ".2s",
4582 [(set (v2i32 V64:$dst), (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn)))]>;
4583 def v4i32 : BaseSIMDTwoSameVectorTied<1, U, 0b10, opc, V128,
4584 asm, ".4s", ".4s",
4585 [(set (v4i32 V128:$dst), (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn)))]>;
4586 def v2i64 : BaseSIMDTwoSameVectorTied<1, U, 0b11, opc, V128,
4587 asm, ".2d", ".2d",
4588 [(set (v2i64 V128:$dst), (OpNode (v2i64 V128:$Rd), (v2i64 V128:$Rn)))]>;
4589}
4590
4591multiclass SIMDTwoVectorBHSD<bit U, bits<5> opc, string asm,
4592 SDPatternOperator OpNode = null_frag> {
4593 def v8i8 : BaseSIMDTwoSameVector<0, U, 0b00, opc, V64,
4594 asm, ".8b", ".8b",
4595 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>;
4596 def v16i8 : BaseSIMDTwoSameVector<1, U, 0b00, opc, V128,
4597 asm, ".16b", ".16b",
4598 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>;
4599 def v4i16 : BaseSIMDTwoSameVector<0, U, 0b01, opc, V64,
4600 asm, ".4h", ".4h",
4601 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>;
4602 def v8i16 : BaseSIMDTwoSameVector<1, U, 0b01, opc, V128,
4603 asm, ".8h", ".8h",
4604 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>;
4605 def v2i32 : BaseSIMDTwoSameVector<0, U, 0b10, opc, V64,
4606 asm, ".2s", ".2s",
4607 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>;
4608 def v4i32 : BaseSIMDTwoSameVector<1, U, 0b10, opc, V128,
4609 asm, ".4s", ".4s",
4610 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>;
4611 def v2i64 : BaseSIMDTwoSameVector<1, U, 0b11, opc, V128,
4612 asm, ".2d", ".2d",
4613 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn)))]>;
4614}
4615
4616
4617// Supports only B element sizes.
4618multiclass SIMDTwoVectorB<bit U, bits<2> size, bits<5> opc, string asm,
4619 SDPatternOperator OpNode> {
4620 def v8i8 : BaseSIMDTwoSameVector<0, U, size, opc, V64,
4621 asm, ".8b", ".8b",
4622 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>;
4623 def v16i8 : BaseSIMDTwoSameVector<1, U, size, opc, V128,
4624 asm, ".16b", ".16b",
4625 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>;
4626
4627}
4628
4629// Supports only B and H element sizes.
4630multiclass SIMDTwoVectorBH<bit U, bits<5> opc, string asm,
4631 SDPatternOperator OpNode> {
4632 def v8i8 : BaseSIMDTwoSameVector<0, U, 0b00, opc, V64,
4633 asm, ".8b", ".8b",
4634 [(set (v8i8 V64:$Rd), (OpNode V64:$Rn))]>;
4635 def v16i8 : BaseSIMDTwoSameVector<1, U, 0b00, opc, V128,
4636 asm, ".16b", ".16b",
4637 [(set (v16i8 V128:$Rd), (OpNode V128:$Rn))]>;
4638 def v4i16 : BaseSIMDTwoSameVector<0, U, 0b01, opc, V64,
4639 asm, ".4h", ".4h",
4640 [(set (v4i16 V64:$Rd), (OpNode V64:$Rn))]>;
4641 def v8i16 : BaseSIMDTwoSameVector<1, U, 0b01, opc, V128,
4642 asm, ".8h", ".8h",
4643 [(set (v8i16 V128:$Rd), (OpNode V128:$Rn))]>;
4644}
4645
4646// Supports only S and D element sizes, uses high bit of the size field
4647// as an extra opcode bit.
4648multiclass SIMDTwoVectorFP<bit U, bit S, bits<5> opc, string asm,
4649 SDPatternOperator OpNode> {
4650 def v2f32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, V64,
4651 asm, ".2s", ".2s",
4652 [(set (v2f32 V64:$Rd), (OpNode (v2f32 V64:$Rn)))]>;
4653 def v4f32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, V128,
4654 asm, ".4s", ".4s",
4655 [(set (v4f32 V128:$Rd), (OpNode (v4f32 V128:$Rn)))]>;
4656 def v2f64 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, V128,
4657 asm, ".2d", ".2d",
4658 [(set (v2f64 V128:$Rd), (OpNode (v2f64 V128:$Rn)))]>;
4659}
4660
4661// Supports only S element size.
4662multiclass SIMDTwoVectorS<bit U, bit S, bits<5> opc, string asm,
4663 SDPatternOperator OpNode> {
4664 def v2i32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, V64,
4665 asm, ".2s", ".2s",
4666 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>;
4667 def v4i32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, V128,
4668 asm, ".4s", ".4s",
4669 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>;
4670}
4671
4672
4673multiclass SIMDTwoVectorFPToInt<bit U, bit S, bits<5> opc, string asm,
4674 SDPatternOperator OpNode> {
4675 def v2f32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, V64,
4676 asm, ".2s", ".2s",
4677 [(set (v2i32 V64:$Rd), (OpNode (v2f32 V64:$Rn)))]>;
4678 def v4f32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, V128,
4679 asm, ".4s", ".4s",
4680 [(set (v4i32 V128:$Rd), (OpNode (v4f32 V128:$Rn)))]>;
4681 def v2f64 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, V128,
4682 asm, ".2d", ".2d",
4683 [(set (v2i64 V128:$Rd), (OpNode (v2f64 V128:$Rn)))]>;
4684}
4685
4686multiclass SIMDTwoVectorIntToFP<bit U, bit S, bits<5> opc, string asm,
4687 SDPatternOperator OpNode> {
4688 def v2f32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, V64,
4689 asm, ".2s", ".2s",
4690 [(set (v2f32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>;
4691 def v4f32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, V128,
4692 asm, ".4s", ".4s",
4693 [(set (v4f32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>;
4694 def v2f64 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, V128,
4695 asm, ".2d", ".2d",
4696 [(set (v2f64 V128:$Rd), (OpNode (v2i64 V128:$Rn)))]>;
4697}
4698
4699
4700class BaseSIMDMixedTwoVector<bit Q, bit U, bits<2> size, bits<5> opcode,
4701 RegisterOperand inreg, RegisterOperand outreg,
4702 string asm, string outkind, string inkind,
4703 list<dag> pattern>
4704 : I<(outs outreg:$Rd), (ins inreg:$Rn), asm,
4705 "{\t$Rd" # outkind # ", $Rn" # inkind #
4706 "|" # outkind # "\t$Rd, $Rn}", "", pattern>,
4707 Sched<[WriteV]> {
4708 bits<5> Rd;
4709 bits<5> Rn;
4710 let Inst{31} = 0;
4711 let Inst{30} = Q;
4712 let Inst{29} = U;
4713 let Inst{28-24} = 0b01110;
4714 let Inst{23-22} = size;
4715 let Inst{21-17} = 0b10000;
4716 let Inst{16-12} = opcode;
4717 let Inst{11-10} = 0b10;
4718 let Inst{9-5} = Rn;
4719 let Inst{4-0} = Rd;
4720}
4721
4722class BaseSIMDMixedTwoVectorTied<bit Q, bit U, bits<2> size, bits<5> opcode,
4723 RegisterOperand inreg, RegisterOperand outreg,
4724 string asm, string outkind, string inkind,
4725 list<dag> pattern>
4726 : I<(outs outreg:$dst), (ins outreg:$Rd, inreg:$Rn), asm,
4727 "{\t$Rd" # outkind # ", $Rn" # inkind #
4728 "|" # outkind # "\t$Rd, $Rn}", "$Rd = $dst", pattern>,
4729 Sched<[WriteV]> {
4730 bits<5> Rd;
4731 bits<5> Rn;
4732 let Inst{31} = 0;
4733 let Inst{30} = Q;
4734 let Inst{29} = U;
4735 let Inst{28-24} = 0b01110;
4736 let Inst{23-22} = size;
4737 let Inst{21-17} = 0b10000;
4738 let Inst{16-12} = opcode;
4739 let Inst{11-10} = 0b10;
4740 let Inst{9-5} = Rn;
4741 let Inst{4-0} = Rd;
4742}
4743
4744multiclass SIMDMixedTwoVector<bit U, bits<5> opc, string asm,
4745 SDPatternOperator OpNode> {
4746 def v8i8 : BaseSIMDMixedTwoVector<0, U, 0b00, opc, V128, V64,
4747 asm, ".8b", ".8h",
4748 [(set (v8i8 V64:$Rd), (OpNode (v8i16 V128:$Rn)))]>;
4749 def v16i8 : BaseSIMDMixedTwoVectorTied<1, U, 0b00, opc, V128, V128,
4750 asm#"2", ".16b", ".8h", []>;
4751 def v4i16 : BaseSIMDMixedTwoVector<0, U, 0b01, opc, V128, V64,
4752 asm, ".4h", ".4s",
4753 [(set (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn)))]>;
4754 def v8i16 : BaseSIMDMixedTwoVectorTied<1, U, 0b01, opc, V128, V128,
4755 asm#"2", ".8h", ".4s", []>;
4756 def v2i32 : BaseSIMDMixedTwoVector<0, U, 0b10, opc, V128, V64,
4757 asm, ".2s", ".2d",
4758 [(set (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn)))]>;
4759 def v4i32 : BaseSIMDMixedTwoVectorTied<1, U, 0b10, opc, V128, V128,
4760 asm#"2", ".4s", ".2d", []>;
4761
4762 def : Pat<(concat_vectors (v8i8 V64:$Rd), (OpNode (v8i16 V128:$Rn))),
4763 (!cast<Instruction>(NAME # "v16i8")
4764 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>;
4765 def : Pat<(concat_vectors (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn))),
4766 (!cast<Instruction>(NAME # "v8i16")
4767 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>;
4768 def : Pat<(concat_vectors (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn))),
4769 (!cast<Instruction>(NAME # "v4i32")
4770 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>;
4771}
4772
4773class BaseSIMDCmpTwoVector<bit Q, bit U, bits<2> size, bits<5> opcode,
4774 RegisterOperand regtype,
4775 string asm, string kind, string zero,
4776 ValueType dty, ValueType sty, SDNode OpNode>
4777 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm,
4778 "{\t$Rd" # kind # ", $Rn" # kind # ", #" # zero #
4779 "|" # kind # "\t$Rd, $Rn, #" # zero # "}", "",
4780 [(set (dty regtype:$Rd), (OpNode (sty regtype:$Rn)))]>,
4781 Sched<[WriteV]> {
4782 bits<5> Rd;
4783 bits<5> Rn;
4784 let Inst{31} = 0;
4785 let Inst{30} = Q;
4786 let Inst{29} = U;
4787 let Inst{28-24} = 0b01110;
4788 let Inst{23-22} = size;
4789 let Inst{21-17} = 0b10000;
4790 let Inst{16-12} = opcode;
4791 let Inst{11-10} = 0b10;
4792 let Inst{9-5} = Rn;
4793 let Inst{4-0} = Rd;
4794}
4795
4796// Comparisons support all element sizes, except 1xD.
4797multiclass SIMDCmpTwoVector<bit U, bits<5> opc, string asm,
4798 SDNode OpNode> {
4799 def v8i8rz : BaseSIMDCmpTwoVector<0, U, 0b00, opc, V64,
4800 asm, ".8b", "0",
4801 v8i8, v8i8, OpNode>;
4802 def v16i8rz : BaseSIMDCmpTwoVector<1, U, 0b00, opc, V128,
4803 asm, ".16b", "0",
4804 v16i8, v16i8, OpNode>;
4805 def v4i16rz : BaseSIMDCmpTwoVector<0, U, 0b01, opc, V64,
4806 asm, ".4h", "0",
4807 v4i16, v4i16, OpNode>;
4808 def v8i16rz : BaseSIMDCmpTwoVector<1, U, 0b01, opc, V128,
4809 asm, ".8h", "0",
4810 v8i16, v8i16, OpNode>;
4811 def v2i32rz : BaseSIMDCmpTwoVector<0, U, 0b10, opc, V64,
4812 asm, ".2s", "0",
4813 v2i32, v2i32, OpNode>;
4814 def v4i32rz : BaseSIMDCmpTwoVector<1, U, 0b10, opc, V128,
4815 asm, ".4s", "0",
4816 v4i32, v4i32, OpNode>;
4817 def v2i64rz : BaseSIMDCmpTwoVector<1, U, 0b11, opc, V128,
4818 asm, ".2d", "0",
4819 v2i64, v2i64, OpNode>;
4820}
4821
4822// FP Comparisons support only S and D element sizes.
4823multiclass SIMDFPCmpTwoVector<bit U, bit S, bits<5> opc,
4824 string asm, SDNode OpNode> {
4825
4826 def v2i32rz : BaseSIMDCmpTwoVector<0, U, {S,0}, opc, V64,
4827 asm, ".2s", "0.0",
4828 v2i32, v2f32, OpNode>;
4829 def v4i32rz : BaseSIMDCmpTwoVector<1, U, {S,0}, opc, V128,
4830 asm, ".4s", "0.0",
4831 v4i32, v4f32, OpNode>;
4832 def v2i64rz : BaseSIMDCmpTwoVector<1, U, {S,1}, opc, V128,
4833 asm, ".2d", "0.0",
4834 v2i64, v2f64, OpNode>;
4835
Ahmed Bougachacca07712015-09-02 18:38:36 +00004836 def : InstAlias<asm # "\t$Vd.2s, $Vn.2s, #0",
Tim Northover3b0846e2014-05-24 12:50:23 +00004837 (!cast<Instruction>(NAME # v2i32rz) V64:$Vd, V64:$Vn), 0>;
Ahmed Bougachacca07712015-09-02 18:38:36 +00004838 def : InstAlias<asm # "\t$Vd.4s, $Vn.4s, #0",
Tim Northover3b0846e2014-05-24 12:50:23 +00004839 (!cast<Instruction>(NAME # v4i32rz) V128:$Vd, V128:$Vn), 0>;
Ahmed Bougachacca07712015-09-02 18:38:36 +00004840 def : InstAlias<asm # "\t$Vd.2d, $Vn.2d, #0",
Tim Northover3b0846e2014-05-24 12:50:23 +00004841 (!cast<Instruction>(NAME # v2i64rz) V128:$Vd, V128:$Vn), 0>;
Ahmed Bougachacca07712015-09-02 18:38:36 +00004842 def : InstAlias<asm # ".2s\t$Vd, $Vn, #0",
Tim Northover3b0846e2014-05-24 12:50:23 +00004843 (!cast<Instruction>(NAME # v2i32rz) V64:$Vd, V64:$Vn), 0>;
Ahmed Bougachacca07712015-09-02 18:38:36 +00004844 def : InstAlias<asm # ".4s\t$Vd, $Vn, #0",
Tim Northover3b0846e2014-05-24 12:50:23 +00004845 (!cast<Instruction>(NAME # v4i32rz) V128:$Vd, V128:$Vn), 0>;
Ahmed Bougachacca07712015-09-02 18:38:36 +00004846 def : InstAlias<asm # ".2d\t$Vd, $Vn, #0",
Tim Northover3b0846e2014-05-24 12:50:23 +00004847 (!cast<Instruction>(NAME # v2i64rz) V128:$Vd, V128:$Vn), 0>;
4848}
4849
4850let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
4851class BaseSIMDFPCvtTwoVector<bit Q, bit U, bits<2> size, bits<5> opcode,
4852 RegisterOperand outtype, RegisterOperand intype,
4853 string asm, string VdTy, string VnTy,
4854 list<dag> pattern>
4855 : I<(outs outtype:$Rd), (ins intype:$Rn), asm,
4856 !strconcat("\t$Rd", VdTy, ", $Rn", VnTy), "", pattern>,
4857 Sched<[WriteV]> {
4858 bits<5> Rd;
4859 bits<5> Rn;
4860 let Inst{31} = 0;
4861 let Inst{30} = Q;
4862 let Inst{29} = U;
4863 let Inst{28-24} = 0b01110;
4864 let Inst{23-22} = size;
4865 let Inst{21-17} = 0b10000;
4866 let Inst{16-12} = opcode;
4867 let Inst{11-10} = 0b10;
4868 let Inst{9-5} = Rn;
4869 let Inst{4-0} = Rd;
4870}
4871
4872class BaseSIMDFPCvtTwoVectorTied<bit Q, bit U, bits<2> size, bits<5> opcode,
4873 RegisterOperand outtype, RegisterOperand intype,
4874 string asm, string VdTy, string VnTy,
4875 list<dag> pattern>
4876 : I<(outs outtype:$dst), (ins outtype:$Rd, intype:$Rn), asm,
4877 !strconcat("\t$Rd", VdTy, ", $Rn", VnTy), "$Rd = $dst", pattern>,
4878 Sched<[WriteV]> {
4879 bits<5> Rd;
4880 bits<5> Rn;
4881 let Inst{31} = 0;
4882 let Inst{30} = Q;
4883 let Inst{29} = U;
4884 let Inst{28-24} = 0b01110;
4885 let Inst{23-22} = size;
4886 let Inst{21-17} = 0b10000;
4887 let Inst{16-12} = opcode;
4888 let Inst{11-10} = 0b10;
4889 let Inst{9-5} = Rn;
4890 let Inst{4-0} = Rd;
4891}
4892
4893multiclass SIMDFPWidenTwoVector<bit U, bit S, bits<5> opc, string asm> {
4894 def v4i16 : BaseSIMDFPCvtTwoVector<0, U, {S,0}, opc, V128, V64,
4895 asm, ".4s", ".4h", []>;
4896 def v8i16 : BaseSIMDFPCvtTwoVector<1, U, {S,0}, opc, V128, V128,
4897 asm#"2", ".4s", ".8h", []>;
4898 def v2i32 : BaseSIMDFPCvtTwoVector<0, U, {S,1}, opc, V128, V64,
4899 asm, ".2d", ".2s", []>;
4900 def v4i32 : BaseSIMDFPCvtTwoVector<1, U, {S,1}, opc, V128, V128,
4901 asm#"2", ".2d", ".4s", []>;
4902}
4903
4904multiclass SIMDFPNarrowTwoVector<bit U, bit S, bits<5> opc, string asm> {
4905 def v4i16 : BaseSIMDFPCvtTwoVector<0, U, {S,0}, opc, V64, V128,
4906 asm, ".4h", ".4s", []>;
4907 def v8i16 : BaseSIMDFPCvtTwoVectorTied<1, U, {S,0}, opc, V128, V128,
4908 asm#"2", ".8h", ".4s", []>;
4909 def v2i32 : BaseSIMDFPCvtTwoVector<0, U, {S,1}, opc, V64, V128,
4910 asm, ".2s", ".2d", []>;
4911 def v4i32 : BaseSIMDFPCvtTwoVectorTied<1, U, {S,1}, opc, V128, V128,
4912 asm#"2", ".4s", ".2d", []>;
4913}
4914
4915multiclass SIMDFPInexactCvtTwoVector<bit U, bit S, bits<5> opc, string asm,
4916 Intrinsic OpNode> {
4917 def v2f32 : BaseSIMDFPCvtTwoVector<0, U, {S,1}, opc, V64, V128,
4918 asm, ".2s", ".2d",
4919 [(set (v2f32 V64:$Rd), (OpNode (v2f64 V128:$Rn)))]>;
4920 def v4f32 : BaseSIMDFPCvtTwoVectorTied<1, U, {S,1}, opc, V128, V128,
4921 asm#"2", ".4s", ".2d", []>;
4922
4923 def : Pat<(concat_vectors (v2f32 V64:$Rd), (OpNode (v2f64 V128:$Rn))),
4924 (!cast<Instruction>(NAME # "v4f32")
4925 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>;
4926}
4927
4928//----------------------------------------------------------------------------
4929// AdvSIMD three register different-size vector instructions.
4930//----------------------------------------------------------------------------
4931
4932let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
4933class BaseSIMDDifferentThreeVector<bit U, bits<3> size, bits<4> opcode,
4934 RegisterOperand outtype, RegisterOperand intype1,
4935 RegisterOperand intype2, string asm,
4936 string outkind, string inkind1, string inkind2,
4937 list<dag> pattern>
4938 : I<(outs outtype:$Rd), (ins intype1:$Rn, intype2:$Rm), asm,
4939 "{\t$Rd" # outkind # ", $Rn" # inkind1 # ", $Rm" # inkind2 #
4940 "|" # outkind # "\t$Rd, $Rn, $Rm}", "", pattern>,
4941 Sched<[WriteV]> {
4942 bits<5> Rd;
4943 bits<5> Rn;
4944 bits<5> Rm;
4945 let Inst{31} = 0;
4946 let Inst{30} = size{0};
4947 let Inst{29} = U;
4948 let Inst{28-24} = 0b01110;
4949 let Inst{23-22} = size{2-1};
4950 let Inst{21} = 1;
4951 let Inst{20-16} = Rm;
4952 let Inst{15-12} = opcode;
4953 let Inst{11-10} = 0b00;
4954 let Inst{9-5} = Rn;
4955 let Inst{4-0} = Rd;
4956}
4957
4958let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
4959class BaseSIMDDifferentThreeVectorTied<bit U, bits<3> size, bits<4> opcode,
4960 RegisterOperand outtype, RegisterOperand intype1,
4961 RegisterOperand intype2, string asm,
4962 string outkind, string inkind1, string inkind2,
4963 list<dag> pattern>
4964 : I<(outs outtype:$dst), (ins outtype:$Rd, intype1:$Rn, intype2:$Rm), asm,
4965 "{\t$Rd" # outkind # ", $Rn" # inkind1 # ", $Rm" # inkind2 #
4966 "|" # outkind # "\t$Rd, $Rn, $Rm}", "$Rd = $dst", pattern>,
4967 Sched<[WriteV]> {
4968 bits<5> Rd;
4969 bits<5> Rn;
4970 bits<5> Rm;
4971 let Inst{31} = 0;
4972 let Inst{30} = size{0};
4973 let Inst{29} = U;
4974 let Inst{28-24} = 0b01110;
4975 let Inst{23-22} = size{2-1};
4976 let Inst{21} = 1;
4977 let Inst{20-16} = Rm;
4978 let Inst{15-12} = opcode;
4979 let Inst{11-10} = 0b00;
4980 let Inst{9-5} = Rn;
4981 let Inst{4-0} = Rd;
4982}
4983
4984// FIXME: TableGen doesn't know how to deal with expanded types that also
4985// change the element count (in this case, placing the results in
4986// the high elements of the result register rather than the low
4987// elements). Until that's fixed, we can't code-gen those.
4988multiclass SIMDNarrowThreeVectorBHS<bit U, bits<4> opc, string asm,
4989 Intrinsic IntOp> {
4990 def v8i16_v8i8 : BaseSIMDDifferentThreeVector<U, 0b000, opc,
4991 V64, V128, V128,
4992 asm, ".8b", ".8h", ".8h",
4993 [(set (v8i8 V64:$Rd), (IntOp (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>;
4994 def v8i16_v16i8 : BaseSIMDDifferentThreeVectorTied<U, 0b001, opc,
4995 V128, V128, V128,
4996 asm#"2", ".16b", ".8h", ".8h",
4997 []>;
4998 def v4i32_v4i16 : BaseSIMDDifferentThreeVector<U, 0b010, opc,
4999 V64, V128, V128,
5000 asm, ".4h", ".4s", ".4s",
5001 [(set (v4i16 V64:$Rd), (IntOp (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>;
5002 def v4i32_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc,
5003 V128, V128, V128,
5004 asm#"2", ".8h", ".4s", ".4s",
5005 []>;
5006 def v2i64_v2i32 : BaseSIMDDifferentThreeVector<U, 0b100, opc,
5007 V64, V128, V128,
5008 asm, ".2s", ".2d", ".2d",
5009 [(set (v2i32 V64:$Rd), (IntOp (v2i64 V128:$Rn), (v2i64 V128:$Rm)))]>;
5010 def v2i64_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc,
5011 V128, V128, V128,
5012 asm#"2", ".4s", ".2d", ".2d",
5013 []>;
5014
5015
5016 // Patterns for the '2' variants involve INSERT_SUBREG, which you can't put in
5017 // a version attached to an instruction.
5018 def : Pat<(concat_vectors (v8i8 V64:$Rd), (IntOp (v8i16 V128:$Rn),
5019 (v8i16 V128:$Rm))),
5020 (!cast<Instruction>(NAME # "v8i16_v16i8")
5021 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub),
5022 V128:$Rn, V128:$Rm)>;
5023 def : Pat<(concat_vectors (v4i16 V64:$Rd), (IntOp (v4i32 V128:$Rn),
5024 (v4i32 V128:$Rm))),
5025 (!cast<Instruction>(NAME # "v4i32_v8i16")
5026 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub),
5027 V128:$Rn, V128:$Rm)>;
5028 def : Pat<(concat_vectors (v2i32 V64:$Rd), (IntOp (v2i64 V128:$Rn),
5029 (v2i64 V128:$Rm))),
5030 (!cast<Instruction>(NAME # "v2i64_v4i32")
5031 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub),
5032 V128:$Rn, V128:$Rm)>;
5033}
5034
5035multiclass SIMDDifferentThreeVectorBD<bit U, bits<4> opc, string asm,
5036 Intrinsic IntOp> {
5037 def v8i8 : BaseSIMDDifferentThreeVector<U, 0b000, opc,
5038 V128, V64, V64,
5039 asm, ".8h", ".8b", ".8b",
5040 [(set (v8i16 V128:$Rd), (IntOp (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
5041 def v16i8 : BaseSIMDDifferentThreeVector<U, 0b001, opc,
5042 V128, V128, V128,
5043 asm#"2", ".8h", ".16b", ".16b", []>;
5044 let Predicates = [HasCrypto] in {
5045 def v1i64 : BaseSIMDDifferentThreeVector<U, 0b110, opc,
5046 V128, V64, V64,
5047 asm, ".1q", ".1d", ".1d", []>;
5048 def v2i64 : BaseSIMDDifferentThreeVector<U, 0b111, opc,
5049 V128, V128, V128,
5050 asm#"2", ".1q", ".2d", ".2d", []>;
5051 }
5052
5053 def : Pat<(v8i16 (IntOp (v8i8 (extract_high_v16i8 V128:$Rn)),
5054 (v8i8 (extract_high_v16i8 V128:$Rm)))),
5055 (!cast<Instruction>(NAME#"v16i8") V128:$Rn, V128:$Rm)>;
5056}
5057
5058multiclass SIMDLongThreeVectorHS<bit U, bits<4> opc, string asm,
5059 SDPatternOperator OpNode> {
5060 def v4i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b010, opc,
5061 V128, V64, V64,
5062 asm, ".4s", ".4h", ".4h",
5063 [(set (v4i32 V128:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>;
5064 def v8i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b011, opc,
5065 V128, V128, V128,
5066 asm#"2", ".4s", ".8h", ".8h",
5067 [(set (v4i32 V128:$Rd), (OpNode (extract_high_v8i16 V128:$Rn),
5068 (extract_high_v8i16 V128:$Rm)))]>;
5069 def v2i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b100, opc,
5070 V128, V64, V64,
5071 asm, ".2d", ".2s", ".2s",
5072 [(set (v2i64 V128:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>;
5073 def v4i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b101, opc,
5074 V128, V128, V128,
5075 asm#"2", ".2d", ".4s", ".4s",
5076 [(set (v2i64 V128:$Rd), (OpNode (extract_high_v4i32 V128:$Rn),
5077 (extract_high_v4i32 V128:$Rm)))]>;
5078}
5079
5080multiclass SIMDLongThreeVectorBHSabdl<bit U, bits<4> opc, string asm,
5081 SDPatternOperator OpNode = null_frag> {
5082 def v8i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b000, opc,
5083 V128, V64, V64,
5084 asm, ".8h", ".8b", ".8b",
5085 [(set (v8i16 V128:$Rd),
5086 (zext (v8i8 (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))))]>;
5087 def v16i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b001, opc,
5088 V128, V128, V128,
5089 asm#"2", ".8h", ".16b", ".16b",
5090 [(set (v8i16 V128:$Rd),
5091 (zext (v8i8 (OpNode (extract_high_v16i8 V128:$Rn),
5092 (extract_high_v16i8 V128:$Rm)))))]>;
5093 def v4i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b010, opc,
5094 V128, V64, V64,
5095 asm, ".4s", ".4h", ".4h",
5096 [(set (v4i32 V128:$Rd),
5097 (zext (v4i16 (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))))]>;
5098 def v8i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b011, opc,
5099 V128, V128, V128,
5100 asm#"2", ".4s", ".8h", ".8h",
5101 [(set (v4i32 V128:$Rd),
5102 (zext (v4i16 (OpNode (extract_high_v8i16 V128:$Rn),
5103 (extract_high_v8i16 V128:$Rm)))))]>;
5104 def v2i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b100, opc,
5105 V128, V64, V64,
5106 asm, ".2d", ".2s", ".2s",
5107 [(set (v2i64 V128:$Rd),
5108 (zext (v2i32 (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))))]>;
5109 def v4i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b101, opc,
5110 V128, V128, V128,
5111 asm#"2", ".2d", ".4s", ".4s",
5112 [(set (v2i64 V128:$Rd),
5113 (zext (v2i32 (OpNode (extract_high_v4i32 V128:$Rn),
5114 (extract_high_v4i32 V128:$Rm)))))]>;
5115}
5116
5117multiclass SIMDLongThreeVectorTiedBHSabal<bit U, bits<4> opc,
5118 string asm,
5119 SDPatternOperator OpNode> {
5120 def v8i8_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b000, opc,
5121 V128, V64, V64,
5122 asm, ".8h", ".8b", ".8b",
5123 [(set (v8i16 V128:$dst),
5124 (add (v8i16 V128:$Rd),
5125 (zext (v8i8 (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm))))))]>;
5126 def v16i8_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b001, opc,
5127 V128, V128, V128,
5128 asm#"2", ".8h", ".16b", ".16b",
5129 [(set (v8i16 V128:$dst),
5130 (add (v8i16 V128:$Rd),
5131 (zext (v8i8 (OpNode (extract_high_v16i8 V128:$Rn),
5132 (extract_high_v16i8 V128:$Rm))))))]>;
5133 def v4i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b010, opc,
5134 V128, V64, V64,
5135 asm, ".4s", ".4h", ".4h",
5136 [(set (v4i32 V128:$dst),
5137 (add (v4i32 V128:$Rd),
5138 (zext (v4i16 (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm))))))]>;
5139 def v8i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc,
5140 V128, V128, V128,
5141 asm#"2", ".4s", ".8h", ".8h",
5142 [(set (v4i32 V128:$dst),
5143 (add (v4i32 V128:$Rd),
5144 (zext (v4i16 (OpNode (extract_high_v8i16 V128:$Rn),
5145 (extract_high_v8i16 V128:$Rm))))))]>;
5146 def v2i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b100, opc,
5147 V128, V64, V64,
5148 asm, ".2d", ".2s", ".2s",
5149 [(set (v2i64 V128:$dst),
5150 (add (v2i64 V128:$Rd),
5151 (zext (v2i32 (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm))))))]>;
5152 def v4i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc,
5153 V128, V128, V128,
5154 asm#"2", ".2d", ".4s", ".4s",
5155 [(set (v2i64 V128:$dst),
5156 (add (v2i64 V128:$Rd),
5157 (zext (v2i32 (OpNode (extract_high_v4i32 V128:$Rn),
5158 (extract_high_v4i32 V128:$Rm))))))]>;
5159}
5160
5161multiclass SIMDLongThreeVectorBHS<bit U, bits<4> opc, string asm,
5162 SDPatternOperator OpNode = null_frag> {
5163 def v8i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b000, opc,
5164 V128, V64, V64,
5165 asm, ".8h", ".8b", ".8b",
5166 [(set (v8i16 V128:$Rd), (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
5167 def v16i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b001, opc,
5168 V128, V128, V128,
5169 asm#"2", ".8h", ".16b", ".16b",
5170 [(set (v8i16 V128:$Rd), (OpNode (extract_high_v16i8 V128:$Rn),
5171 (extract_high_v16i8 V128:$Rm)))]>;
5172 def v4i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b010, opc,
5173 V128, V64, V64,
5174 asm, ".4s", ".4h", ".4h",
5175 [(set (v4i32 V128:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>;
5176 def v8i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b011, opc,
5177 V128, V128, V128,
5178 asm#"2", ".4s", ".8h", ".8h",
5179 [(set (v4i32 V128:$Rd), (OpNode (extract_high_v8i16 V128:$Rn),
5180 (extract_high_v8i16 V128:$Rm)))]>;
5181 def v2i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b100, opc,
5182 V128, V64, V64,
5183 asm, ".2d", ".2s", ".2s",
5184 [(set (v2i64 V128:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>;
5185 def v4i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b101, opc,
5186 V128, V128, V128,
5187 asm#"2", ".2d", ".4s", ".4s",
5188 [(set (v2i64 V128:$Rd), (OpNode (extract_high_v4i32 V128:$Rn),
5189 (extract_high_v4i32 V128:$Rm)))]>;
5190}
5191
5192multiclass SIMDLongThreeVectorTiedBHS<bit U, bits<4> opc,
5193 string asm,
5194 SDPatternOperator OpNode> {
5195 def v8i8_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b000, opc,
5196 V128, V64, V64,
5197 asm, ".8h", ".8b", ".8b",
5198 [(set (v8i16 V128:$dst),
5199 (OpNode (v8i16 V128:$Rd), (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
5200 def v16i8_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b001, opc,
5201 V128, V128, V128,
5202 asm#"2", ".8h", ".16b", ".16b",
5203 [(set (v8i16 V128:$dst),
5204 (OpNode (v8i16 V128:$Rd),
5205 (extract_high_v16i8 V128:$Rn),
5206 (extract_high_v16i8 V128:$Rm)))]>;
5207 def v4i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b010, opc,
5208 V128, V64, V64,
5209 asm, ".4s", ".4h", ".4h",
5210 [(set (v4i32 V128:$dst),
5211 (OpNode (v4i32 V128:$Rd), (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>;
5212 def v8i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc,
5213 V128, V128, V128,
5214 asm#"2", ".4s", ".8h", ".8h",
5215 [(set (v4i32 V128:$dst),
5216 (OpNode (v4i32 V128:$Rd),
5217 (extract_high_v8i16 V128:$Rn),
5218 (extract_high_v8i16 V128:$Rm)))]>;
5219 def v2i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b100, opc,
5220 V128, V64, V64,
5221 asm, ".2d", ".2s", ".2s",
5222 [(set (v2i64 V128:$dst),
5223 (OpNode (v2i64 V128:$Rd), (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>;
5224 def v4i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc,
5225 V128, V128, V128,
5226 asm#"2", ".2d", ".4s", ".4s",
5227 [(set (v2i64 V128:$dst),
5228 (OpNode (v2i64 V128:$Rd),
5229 (extract_high_v4i32 V128:$Rn),
5230 (extract_high_v4i32 V128:$Rm)))]>;
5231}
5232
5233multiclass SIMDLongThreeVectorSQDMLXTiedHS<bit U, bits<4> opc, string asm,
5234 SDPatternOperator Accum> {
5235 def v4i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b010, opc,
5236 V128, V64, V64,
5237 asm, ".4s", ".4h", ".4h",
5238 [(set (v4i32 V128:$dst),
5239 (Accum (v4i32 V128:$Rd),
5240 (v4i32 (int_aarch64_neon_sqdmull (v4i16 V64:$Rn),
5241 (v4i16 V64:$Rm)))))]>;
5242 def v8i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc,
5243 V128, V128, V128,
5244 asm#"2", ".4s", ".8h", ".8h",
5245 [(set (v4i32 V128:$dst),
5246 (Accum (v4i32 V128:$Rd),
5247 (v4i32 (int_aarch64_neon_sqdmull (extract_high_v8i16 V128:$Rn),
5248 (extract_high_v8i16 V128:$Rm)))))]>;
5249 def v2i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b100, opc,
5250 V128, V64, V64,
5251 asm, ".2d", ".2s", ".2s",
5252 [(set (v2i64 V128:$dst),
5253 (Accum (v2i64 V128:$Rd),
5254 (v2i64 (int_aarch64_neon_sqdmull (v2i32 V64:$Rn),
5255 (v2i32 V64:$Rm)))))]>;
5256 def v4i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc,
5257 V128, V128, V128,
5258 asm#"2", ".2d", ".4s", ".4s",
5259 [(set (v2i64 V128:$dst),
5260 (Accum (v2i64 V128:$Rd),
5261 (v2i64 (int_aarch64_neon_sqdmull (extract_high_v4i32 V128:$Rn),
5262 (extract_high_v4i32 V128:$Rm)))))]>;
5263}
5264
5265multiclass SIMDWideThreeVectorBHS<bit U, bits<4> opc, string asm,
5266 SDPatternOperator OpNode> {
5267 def v8i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b000, opc,
5268 V128, V128, V64,
5269 asm, ".8h", ".8h", ".8b",
5270 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (v8i8 V64:$Rm)))]>;
5271 def v16i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b001, opc,
5272 V128, V128, V128,
5273 asm#"2", ".8h", ".8h", ".16b",
5274 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn),
5275 (extract_high_v16i8 V128:$Rm)))]>;
5276 def v4i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b010, opc,
5277 V128, V128, V64,
5278 asm, ".4s", ".4s", ".4h",
5279 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (v4i16 V64:$Rm)))]>;
5280 def v8i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b011, opc,
5281 V128, V128, V128,
5282 asm#"2", ".4s", ".4s", ".8h",
5283 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn),
5284 (extract_high_v8i16 V128:$Rm)))]>;
5285 def v2i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b100, opc,
5286 V128, V128, V64,
5287 asm, ".2d", ".2d", ".2s",
5288 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn), (v2i32 V64:$Rm)))]>;
5289 def v4i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b101, opc,
5290 V128, V128, V128,
5291 asm#"2", ".2d", ".2d", ".4s",
5292 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn),
5293 (extract_high_v4i32 V128:$Rm)))]>;
5294}
5295
5296//----------------------------------------------------------------------------
5297// AdvSIMD bitwise extract from vector
5298//----------------------------------------------------------------------------
5299
5300class BaseSIMDBitwiseExtract<bit size, RegisterOperand regtype, ValueType vty,
5301 string asm, string kind>
5302 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, i32imm:$imm), asm,
5303 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind # ", $imm" #
5304 "|" # kind # "\t$Rd, $Rn, $Rm, $imm}", "",
5305 [(set (vty regtype:$Rd),
5306 (AArch64ext regtype:$Rn, regtype:$Rm, (i32 imm:$imm)))]>,
5307 Sched<[WriteV]> {
5308 bits<5> Rd;
5309 bits<5> Rn;
5310 bits<5> Rm;
5311 bits<4> imm;
5312 let Inst{31} = 0;
5313 let Inst{30} = size;
5314 let Inst{29-21} = 0b101110000;
5315 let Inst{20-16} = Rm;
5316 let Inst{15} = 0;
5317 let Inst{14-11} = imm;
5318 let Inst{10} = 0;
5319 let Inst{9-5} = Rn;
5320 let Inst{4-0} = Rd;
5321}
5322
5323
5324multiclass SIMDBitwiseExtract<string asm> {
5325 def v8i8 : BaseSIMDBitwiseExtract<0, V64, v8i8, asm, ".8b"> {
5326 let imm{3} = 0;
5327 }
5328 def v16i8 : BaseSIMDBitwiseExtract<1, V128, v16i8, asm, ".16b">;
5329}
5330
5331//----------------------------------------------------------------------------
5332// AdvSIMD zip vector
5333//----------------------------------------------------------------------------
5334
5335class BaseSIMDZipVector<bits<3> size, bits<3> opc, RegisterOperand regtype,
5336 string asm, string kind, SDNode OpNode, ValueType valty>
5337 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), asm,
5338 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind #
5339 "|" # kind # "\t$Rd, $Rn, $Rm}", "",
5340 [(set (valty regtype:$Rd), (OpNode regtype:$Rn, regtype:$Rm))]>,
5341 Sched<[WriteV]> {
5342 bits<5> Rd;
5343 bits<5> Rn;
5344 bits<5> Rm;
5345 let Inst{31} = 0;
5346 let Inst{30} = size{0};
5347 let Inst{29-24} = 0b001110;
5348 let Inst{23-22} = size{2-1};
5349 let Inst{21} = 0;
5350 let Inst{20-16} = Rm;
5351 let Inst{15} = 0;
5352 let Inst{14-12} = opc;
5353 let Inst{11-10} = 0b10;
5354 let Inst{9-5} = Rn;
5355 let Inst{4-0} = Rd;
5356}
5357
5358multiclass SIMDZipVector<bits<3>opc, string asm,
5359 SDNode OpNode> {
5360 def v8i8 : BaseSIMDZipVector<0b000, opc, V64,
5361 asm, ".8b", OpNode, v8i8>;
5362 def v16i8 : BaseSIMDZipVector<0b001, opc, V128,
5363 asm, ".16b", OpNode, v16i8>;
5364 def v4i16 : BaseSIMDZipVector<0b010, opc, V64,
5365 asm, ".4h", OpNode, v4i16>;
5366 def v8i16 : BaseSIMDZipVector<0b011, opc, V128,
5367 asm, ".8h", OpNode, v8i16>;
5368 def v2i32 : BaseSIMDZipVector<0b100, opc, V64,
5369 asm, ".2s", OpNode, v2i32>;
5370 def v4i32 : BaseSIMDZipVector<0b101, opc, V128,
5371 asm, ".4s", OpNode, v4i32>;
5372 def v2i64 : BaseSIMDZipVector<0b111, opc, V128,
5373 asm, ".2d", OpNode, v2i64>;
5374
Oliver Stannard89d15422014-08-27 16:16:04 +00005375 def : Pat<(v4f16 (OpNode V64:$Rn, V64:$Rm)),
5376 (!cast<Instruction>(NAME#"v4i16") V64:$Rn, V64:$Rm)>;
5377 def : Pat<(v8f16 (OpNode V128:$Rn, V128:$Rm)),
5378 (!cast<Instruction>(NAME#"v8i16") V128:$Rn, V128:$Rm)>;
Tim Northover3b0846e2014-05-24 12:50:23 +00005379 def : Pat<(v2f32 (OpNode V64:$Rn, V64:$Rm)),
5380 (!cast<Instruction>(NAME#"v2i32") V64:$Rn, V64:$Rm)>;
5381 def : Pat<(v4f32 (OpNode V128:$Rn, V128:$Rm)),
5382 (!cast<Instruction>(NAME#"v4i32") V128:$Rn, V128:$Rm)>;
5383 def : Pat<(v2f64 (OpNode V128:$Rn, V128:$Rm)),
5384 (!cast<Instruction>(NAME#"v2i64") V128:$Rn, V128:$Rm)>;
5385}
5386
5387//----------------------------------------------------------------------------
5388// AdvSIMD three register scalar instructions
5389//----------------------------------------------------------------------------
5390
5391let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
5392class BaseSIMDThreeScalar<bit U, bits<2> size, bits<5> opcode,
5393 RegisterClass regtype, string asm,
5394 list<dag> pattern>
5395 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), asm,
5396 "\t$Rd, $Rn, $Rm", "", pattern>,
5397 Sched<[WriteV]> {
5398 bits<5> Rd;
5399 bits<5> Rn;
5400 bits<5> Rm;
5401 let Inst{31-30} = 0b01;
5402 let Inst{29} = U;
5403 let Inst{28-24} = 0b11110;
5404 let Inst{23-22} = size;
5405 let Inst{21} = 1;
5406 let Inst{20-16} = Rm;
5407 let Inst{15-11} = opcode;
5408 let Inst{10} = 1;
5409 let Inst{9-5} = Rn;
5410 let Inst{4-0} = Rd;
5411}
5412
Vladimir Sukharev297bf0e2015-03-31 13:15:48 +00005413let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
5414class BaseSIMDThreeScalarTied<bit U, bits<2> size, bit R, bits<5> opcode,
5415 dag oops, dag iops, string asm,
5416 list<dag> pattern>
5417 : I<oops, iops, asm, "\t$Rd, $Rn, $Rm", "$Rd = $dst", pattern>,
5418 Sched<[WriteV]> {
5419 bits<5> Rd;
5420 bits<5> Rn;
5421 bits<5> Rm;
5422 let Inst{31-30} = 0b01;
5423 let Inst{29} = U;
5424 let Inst{28-24} = 0b11110;
5425 let Inst{23-22} = size;
5426 let Inst{21} = R;
5427 let Inst{20-16} = Rm;
5428 let Inst{15-11} = opcode;
5429 let Inst{10} = 1;
5430 let Inst{9-5} = Rn;
5431 let Inst{4-0} = Rd;
5432}
5433
Tim Northover3b0846e2014-05-24 12:50:23 +00005434multiclass SIMDThreeScalarD<bit U, bits<5> opc, string asm,
5435 SDPatternOperator OpNode> {
5436 def v1i64 : BaseSIMDThreeScalar<U, 0b11, opc, FPR64, asm,
5437 [(set (v1i64 FPR64:$Rd), (OpNode (v1i64 FPR64:$Rn), (v1i64 FPR64:$Rm)))]>;
5438}
5439
5440multiclass SIMDThreeScalarBHSD<bit U, bits<5> opc, string asm,
5441 SDPatternOperator OpNode> {
5442 def v1i64 : BaseSIMDThreeScalar<U, 0b11, opc, FPR64, asm,
5443 [(set (v1i64 FPR64:$Rd), (OpNode (v1i64 FPR64:$Rn), (v1i64 FPR64:$Rm)))]>;
5444 def v1i32 : BaseSIMDThreeScalar<U, 0b10, opc, FPR32, asm, []>;
5445 def v1i16 : BaseSIMDThreeScalar<U, 0b01, opc, FPR16, asm, []>;
5446 def v1i8 : BaseSIMDThreeScalar<U, 0b00, opc, FPR8 , asm, []>;
5447
5448 def : Pat<(i64 (OpNode (i64 FPR64:$Rn), (i64 FPR64:$Rm))),
5449 (!cast<Instruction>(NAME#"v1i64") FPR64:$Rn, FPR64:$Rm)>;
5450 def : Pat<(i32 (OpNode (i32 FPR32:$Rn), (i32 FPR32:$Rm))),
5451 (!cast<Instruction>(NAME#"v1i32") FPR32:$Rn, FPR32:$Rm)>;
5452}
5453
5454multiclass SIMDThreeScalarHS<bit U, bits<5> opc, string asm,
5455 SDPatternOperator OpNode> {
5456 def v1i32 : BaseSIMDThreeScalar<U, 0b10, opc, FPR32, asm,
5457 [(set FPR32:$Rd, (OpNode FPR32:$Rn, FPR32:$Rm))]>;
5458 def v1i16 : BaseSIMDThreeScalar<U, 0b01, opc, FPR16, asm, []>;
5459}
5460
Vladimir Sukharev297bf0e2015-03-31 13:15:48 +00005461multiclass SIMDThreeScalarHSTied<bit U, bit R, bits<5> opc, string asm,
5462 SDPatternOperator OpNode = null_frag> {
5463 def v1i32: BaseSIMDThreeScalarTied<U, 0b10, R, opc, (outs FPR32:$dst),
5464 (ins FPR32:$Rd, FPR32:$Rn, FPR32:$Rm),
5465 asm, []>;
5466 def v1i16: BaseSIMDThreeScalarTied<U, 0b01, R, opc, (outs FPR16:$dst),
5467 (ins FPR16:$Rd, FPR16:$Rn, FPR16:$Rm),
5468 asm, []>;
5469}
5470
Tim Northover3b0846e2014-05-24 12:50:23 +00005471multiclass SIMDThreeScalarSD<bit U, bit S, bits<5> opc, string asm,
5472 SDPatternOperator OpNode = null_frag> {
5473 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
5474 def #NAME#64 : BaseSIMDThreeScalar<U, {S,1}, opc, FPR64, asm,
5475 [(set (f64 FPR64:$Rd), (OpNode (f64 FPR64:$Rn), (f64 FPR64:$Rm)))]>;
5476 def #NAME#32 : BaseSIMDThreeScalar<U, {S,0}, opc, FPR32, asm,
5477 [(set FPR32:$Rd, (OpNode FPR32:$Rn, FPR32:$Rm))]>;
5478 }
5479
5480 def : Pat<(v1f64 (OpNode (v1f64 FPR64:$Rn), (v1f64 FPR64:$Rm))),
5481 (!cast<Instruction>(NAME # "64") FPR64:$Rn, FPR64:$Rm)>;
5482}
5483
5484multiclass SIMDThreeScalarFPCmp<bit U, bit S, bits<5> opc, string asm,
5485 SDPatternOperator OpNode = null_frag> {
5486 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
5487 def #NAME#64 : BaseSIMDThreeScalar<U, {S,1}, opc, FPR64, asm,
5488 [(set (i64 FPR64:$Rd), (OpNode (f64 FPR64:$Rn), (f64 FPR64:$Rm)))]>;
5489 def #NAME#32 : BaseSIMDThreeScalar<U, {S,0}, opc, FPR32, asm,
5490 [(set (i32 FPR32:$Rd), (OpNode (f32 FPR32:$Rn), (f32 FPR32:$Rm)))]>;
5491 }
5492
5493 def : Pat<(v1i64 (OpNode (v1f64 FPR64:$Rn), (v1f64 FPR64:$Rm))),
5494 (!cast<Instruction>(NAME # "64") FPR64:$Rn, FPR64:$Rm)>;
5495}
5496
5497class BaseSIMDThreeScalarMixed<bit U, bits<2> size, bits<5> opcode,
5498 dag oops, dag iops, string asm, string cstr, list<dag> pat>
5499 : I<oops, iops, asm,
5500 "\t$Rd, $Rn, $Rm", cstr, pat>,
5501 Sched<[WriteV]> {
5502 bits<5> Rd;
5503 bits<5> Rn;
5504 bits<5> Rm;
5505 let Inst{31-30} = 0b01;
5506 let Inst{29} = U;
5507 let Inst{28-24} = 0b11110;
5508 let Inst{23-22} = size;
5509 let Inst{21} = 1;
5510 let Inst{20-16} = Rm;
5511 let Inst{15-11} = opcode;
5512 let Inst{10} = 0;
5513 let Inst{9-5} = Rn;
5514 let Inst{4-0} = Rd;
5515}
5516
5517let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5518multiclass SIMDThreeScalarMixedHS<bit U, bits<5> opc, string asm,
5519 SDPatternOperator OpNode = null_frag> {
5520 def i16 : BaseSIMDThreeScalarMixed<U, 0b01, opc,
5521 (outs FPR32:$Rd),
5522 (ins FPR16:$Rn, FPR16:$Rm), asm, "", []>;
5523 def i32 : BaseSIMDThreeScalarMixed<U, 0b10, opc,
5524 (outs FPR64:$Rd),
5525 (ins FPR32:$Rn, FPR32:$Rm), asm, "",
5526 [(set (i64 FPR64:$Rd), (OpNode (i32 FPR32:$Rn), (i32 FPR32:$Rm)))]>;
5527}
5528
5529let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5530multiclass SIMDThreeScalarMixedTiedHS<bit U, bits<5> opc, string asm,
5531 SDPatternOperator OpNode = null_frag> {
5532 def i16 : BaseSIMDThreeScalarMixed<U, 0b01, opc,
5533 (outs FPR32:$dst),
5534 (ins FPR32:$Rd, FPR16:$Rn, FPR16:$Rm),
5535 asm, "$Rd = $dst", []>;
5536 def i32 : BaseSIMDThreeScalarMixed<U, 0b10, opc,
5537 (outs FPR64:$dst),
5538 (ins FPR64:$Rd, FPR32:$Rn, FPR32:$Rm),
5539 asm, "$Rd = $dst",
5540 [(set (i64 FPR64:$dst),
5541 (OpNode (i64 FPR64:$Rd), (i32 FPR32:$Rn), (i32 FPR32:$Rm)))]>;
5542}
5543
5544//----------------------------------------------------------------------------
5545// AdvSIMD two register scalar instructions
5546//----------------------------------------------------------------------------
5547
5548let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5549class BaseSIMDTwoScalar<bit U, bits<2> size, bits<5> opcode,
5550 RegisterClass regtype, RegisterClass regtype2,
5551 string asm, list<dag> pat>
5552 : I<(outs regtype:$Rd), (ins regtype2:$Rn), asm,
5553 "\t$Rd, $Rn", "", pat>,
5554 Sched<[WriteV]> {
5555 bits<5> Rd;
5556 bits<5> Rn;
5557 let Inst{31-30} = 0b01;
5558 let Inst{29} = U;
5559 let Inst{28-24} = 0b11110;
5560 let Inst{23-22} = size;
5561 let Inst{21-17} = 0b10000;
5562 let Inst{16-12} = opcode;
5563 let Inst{11-10} = 0b10;
5564 let Inst{9-5} = Rn;
5565 let Inst{4-0} = Rd;
5566}
5567
5568let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5569class BaseSIMDTwoScalarTied<bit U, bits<2> size, bits<5> opcode,
5570 RegisterClass regtype, RegisterClass regtype2,
5571 string asm, list<dag> pat>
5572 : I<(outs regtype:$dst), (ins regtype:$Rd, regtype2:$Rn), asm,
5573 "\t$Rd, $Rn", "$Rd = $dst", pat>,
5574 Sched<[WriteV]> {
5575 bits<5> Rd;
5576 bits<5> Rn;
5577 let Inst{31-30} = 0b01;
5578 let Inst{29} = U;
5579 let Inst{28-24} = 0b11110;
5580 let Inst{23-22} = size;
5581 let Inst{21-17} = 0b10000;
5582 let Inst{16-12} = opcode;
5583 let Inst{11-10} = 0b10;
5584 let Inst{9-5} = Rn;
5585 let Inst{4-0} = Rd;
5586}
5587
5588
5589let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5590class BaseSIMDCmpTwoScalar<bit U, bits<2> size, bits<5> opcode,
5591 RegisterClass regtype, string asm, string zero>
5592 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm,
5593 "\t$Rd, $Rn, #" # zero, "", []>,
5594 Sched<[WriteV]> {
5595 bits<5> Rd;
5596 bits<5> Rn;
5597 let Inst{31-30} = 0b01;
5598 let Inst{29} = U;
5599 let Inst{28-24} = 0b11110;
5600 let Inst{23-22} = size;
5601 let Inst{21-17} = 0b10000;
5602 let Inst{16-12} = opcode;
5603 let Inst{11-10} = 0b10;
5604 let Inst{9-5} = Rn;
5605 let Inst{4-0} = Rd;
5606}
5607
5608class SIMDInexactCvtTwoScalar<bits<5> opcode, string asm>
5609 : I<(outs FPR32:$Rd), (ins FPR64:$Rn), asm, "\t$Rd, $Rn", "",
5610 [(set (f32 FPR32:$Rd), (int_aarch64_sisd_fcvtxn (f64 FPR64:$Rn)))]>,
5611 Sched<[WriteV]> {
5612 bits<5> Rd;
5613 bits<5> Rn;
5614 let Inst{31-17} = 0b011111100110000;
5615 let Inst{16-12} = opcode;
5616 let Inst{11-10} = 0b10;
5617 let Inst{9-5} = Rn;
5618 let Inst{4-0} = Rd;
5619}
5620
5621multiclass SIMDCmpTwoScalarD<bit U, bits<5> opc, string asm,
5622 SDPatternOperator OpNode> {
5623 def v1i64rz : BaseSIMDCmpTwoScalar<U, 0b11, opc, FPR64, asm, "0">;
5624
5625 def : Pat<(v1i64 (OpNode FPR64:$Rn)),
5626 (!cast<Instruction>(NAME # v1i64rz) FPR64:$Rn)>;
5627}
5628
Ahmed Bougacha81fda182015-08-04 01:38:08 +00005629multiclass SIMDFPCmpTwoScalar<bit U, bit S, bits<5> opc, string asm,
Tim Northover3b0846e2014-05-24 12:50:23 +00005630 SDPatternOperator OpNode> {
5631 def v1i64rz : BaseSIMDCmpTwoScalar<U, {S,1}, opc, FPR64, asm, "0.0">;
5632 def v1i32rz : BaseSIMDCmpTwoScalar<U, {S,0}, opc, FPR32, asm, "0.0">;
5633
Ahmed Bougachacca07712015-09-02 18:38:36 +00005634 def : InstAlias<asm # "\t$Rd, $Rn, #0",
Tim Northover3b0846e2014-05-24 12:50:23 +00005635 (!cast<Instruction>(NAME # v1i64rz) FPR64:$Rd, FPR64:$Rn), 0>;
Ahmed Bougachacca07712015-09-02 18:38:36 +00005636 def : InstAlias<asm # "\t$Rd, $Rn, #0",
Tim Northover3b0846e2014-05-24 12:50:23 +00005637 (!cast<Instruction>(NAME # v1i32rz) FPR32:$Rd, FPR32:$Rn), 0>;
5638
5639 def : Pat<(v1i64 (OpNode (v1f64 FPR64:$Rn))),
5640 (!cast<Instruction>(NAME # v1i64rz) FPR64:$Rn)>;
5641}
5642
5643multiclass SIMDTwoScalarD<bit U, bits<5> opc, string asm,
5644 SDPatternOperator OpNode = null_frag> {
5645 def v1i64 : BaseSIMDTwoScalar<U, 0b11, opc, FPR64, FPR64, asm,
5646 [(set (v1i64 FPR64:$Rd), (OpNode (v1i64 FPR64:$Rn)))]>;
5647
5648 def : Pat<(i64 (OpNode (i64 FPR64:$Rn))),
5649 (!cast<Instruction>(NAME # "v1i64") FPR64:$Rn)>;
5650}
5651
Ahmed Bougacha81fda182015-08-04 01:38:08 +00005652multiclass SIMDFPTwoScalar<bit U, bit S, bits<5> opc, string asm> {
Tim Northover3b0846e2014-05-24 12:50:23 +00005653 def v1i64 : BaseSIMDTwoScalar<U, {S,1}, opc, FPR64, FPR64, asm,[]>;
5654 def v1i32 : BaseSIMDTwoScalar<U, {S,0}, opc, FPR32, FPR32, asm,[]>;
5655}
5656
5657multiclass SIMDTwoScalarCVTSD<bit U, bit S, bits<5> opc, string asm,
5658 SDPatternOperator OpNode> {
5659 def v1i64 : BaseSIMDTwoScalar<U, {S,1}, opc, FPR64, FPR64, asm,
5660 [(set FPR64:$Rd, (OpNode (f64 FPR64:$Rn)))]>;
5661 def v1i32 : BaseSIMDTwoScalar<U, {S,0}, opc, FPR32, FPR32, asm,
5662 [(set FPR32:$Rd, (OpNode (f32 FPR32:$Rn)))]>;
5663}
5664
5665multiclass SIMDTwoScalarBHSD<bit U, bits<5> opc, string asm,
5666 SDPatternOperator OpNode = null_frag> {
5667 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
5668 def v1i64 : BaseSIMDTwoScalar<U, 0b11, opc, FPR64, FPR64, asm,
5669 [(set (i64 FPR64:$Rd), (OpNode (i64 FPR64:$Rn)))]>;
5670 def v1i32 : BaseSIMDTwoScalar<U, 0b10, opc, FPR32, FPR32, asm,
5671 [(set (i32 FPR32:$Rd), (OpNode (i32 FPR32:$Rn)))]>;
5672 def v1i16 : BaseSIMDTwoScalar<U, 0b01, opc, FPR16, FPR16, asm, []>;
5673 def v1i8 : BaseSIMDTwoScalar<U, 0b00, opc, FPR8 , FPR8 , asm, []>;
5674 }
5675
5676 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rn))),
5677 (!cast<Instruction>(NAME # v1i64) FPR64:$Rn)>;
5678}
5679
5680multiclass SIMDTwoScalarBHSDTied<bit U, bits<5> opc, string asm,
5681 Intrinsic OpNode> {
5682 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
5683 def v1i64 : BaseSIMDTwoScalarTied<U, 0b11, opc, FPR64, FPR64, asm,
5684 [(set (i64 FPR64:$dst), (OpNode (i64 FPR64:$Rd), (i64 FPR64:$Rn)))]>;
5685 def v1i32 : BaseSIMDTwoScalarTied<U, 0b10, opc, FPR32, FPR32, asm,
5686 [(set (i32 FPR32:$dst), (OpNode (i32 FPR32:$Rd), (i32 FPR32:$Rn)))]>;
5687 def v1i16 : BaseSIMDTwoScalarTied<U, 0b01, opc, FPR16, FPR16, asm, []>;
5688 def v1i8 : BaseSIMDTwoScalarTied<U, 0b00, opc, FPR8 , FPR8 , asm, []>;
5689 }
5690
5691 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rd), (v1i64 FPR64:$Rn))),
5692 (!cast<Instruction>(NAME # v1i64) FPR64:$Rd, FPR64:$Rn)>;
5693}
5694
5695
5696
5697let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5698multiclass SIMDTwoScalarMixedBHS<bit U, bits<5> opc, string asm,
5699 SDPatternOperator OpNode = null_frag> {
5700 def v1i32 : BaseSIMDTwoScalar<U, 0b10, opc, FPR32, FPR64, asm,
5701 [(set (i32 FPR32:$Rd), (OpNode (i64 FPR64:$Rn)))]>;
5702 def v1i16 : BaseSIMDTwoScalar<U, 0b01, opc, FPR16, FPR32, asm, []>;
5703 def v1i8 : BaseSIMDTwoScalar<U, 0b00, opc, FPR8 , FPR16, asm, []>;
5704}
5705
5706//----------------------------------------------------------------------------
5707// AdvSIMD scalar pairwise instructions
5708//----------------------------------------------------------------------------
5709
5710let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5711class BaseSIMDPairwiseScalar<bit U, bits<2> size, bits<5> opcode,
5712 RegisterOperand regtype, RegisterOperand vectype,
5713 string asm, string kind>
5714 : I<(outs regtype:$Rd), (ins vectype:$Rn), asm,
5715 "{\t$Rd, $Rn" # kind # "|" # kind # "\t$Rd, $Rn}", "", []>,
5716 Sched<[WriteV]> {
5717 bits<5> Rd;
5718 bits<5> Rn;
5719 let Inst{31-30} = 0b01;
5720 let Inst{29} = U;
5721 let Inst{28-24} = 0b11110;
5722 let Inst{23-22} = size;
5723 let Inst{21-17} = 0b11000;
5724 let Inst{16-12} = opcode;
5725 let Inst{11-10} = 0b10;
5726 let Inst{9-5} = Rn;
5727 let Inst{4-0} = Rd;
5728}
5729
5730multiclass SIMDPairwiseScalarD<bit U, bits<5> opc, string asm> {
5731 def v2i64p : BaseSIMDPairwiseScalar<U, 0b11, opc, FPR64Op, V128,
5732 asm, ".2d">;
5733}
5734
Ahmed Bougacha81fda182015-08-04 01:38:08 +00005735multiclass SIMDFPPairwiseScalar<bit U, bit S, bits<5> opc, string asm> {
Tim Northover3b0846e2014-05-24 12:50:23 +00005736 def v2i32p : BaseSIMDPairwiseScalar<U, {S,0}, opc, FPR32Op, V64,
5737 asm, ".2s">;
5738 def v2i64p : BaseSIMDPairwiseScalar<U, {S,1}, opc, FPR64Op, V128,
5739 asm, ".2d">;
5740}
5741
5742//----------------------------------------------------------------------------
5743// AdvSIMD across lanes instructions
5744//----------------------------------------------------------------------------
5745
5746let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5747class BaseSIMDAcrossLanes<bit Q, bit U, bits<2> size, bits<5> opcode,
5748 RegisterClass regtype, RegisterOperand vectype,
5749 string asm, string kind, list<dag> pattern>
5750 : I<(outs regtype:$Rd), (ins vectype:$Rn), asm,
5751 "{\t$Rd, $Rn" # kind # "|" # kind # "\t$Rd, $Rn}", "", pattern>,
5752 Sched<[WriteV]> {
5753 bits<5> Rd;
5754 bits<5> Rn;
5755 let Inst{31} = 0;
5756 let Inst{30} = Q;
5757 let Inst{29} = U;
5758 let Inst{28-24} = 0b01110;
5759 let Inst{23-22} = size;
5760 let Inst{21-17} = 0b11000;
5761 let Inst{16-12} = opcode;
5762 let Inst{11-10} = 0b10;
5763 let Inst{9-5} = Rn;
5764 let Inst{4-0} = Rd;
5765}
5766
5767multiclass SIMDAcrossLanesBHS<bit U, bits<5> opcode,
5768 string asm> {
5769 def v8i8v : BaseSIMDAcrossLanes<0, U, 0b00, opcode, FPR8, V64,
5770 asm, ".8b", []>;
5771 def v16i8v : BaseSIMDAcrossLanes<1, U, 0b00, opcode, FPR8, V128,
5772 asm, ".16b", []>;
5773 def v4i16v : BaseSIMDAcrossLanes<0, U, 0b01, opcode, FPR16, V64,
5774 asm, ".4h", []>;
5775 def v8i16v : BaseSIMDAcrossLanes<1, U, 0b01, opcode, FPR16, V128,
5776 asm, ".8h", []>;
5777 def v4i32v : BaseSIMDAcrossLanes<1, U, 0b10, opcode, FPR32, V128,
5778 asm, ".4s", []>;
5779}
5780
5781multiclass SIMDAcrossLanesHSD<bit U, bits<5> opcode, string asm> {
5782 def v8i8v : BaseSIMDAcrossLanes<0, U, 0b00, opcode, FPR16, V64,
5783 asm, ".8b", []>;
5784 def v16i8v : BaseSIMDAcrossLanes<1, U, 0b00, opcode, FPR16, V128,
5785 asm, ".16b", []>;
5786 def v4i16v : BaseSIMDAcrossLanes<0, U, 0b01, opcode, FPR32, V64,
5787 asm, ".4h", []>;
5788 def v8i16v : BaseSIMDAcrossLanes<1, U, 0b01, opcode, FPR32, V128,
5789 asm, ".8h", []>;
5790 def v4i32v : BaseSIMDAcrossLanes<1, U, 0b10, opcode, FPR64, V128,
5791 asm, ".4s", []>;
5792}
5793
5794multiclass SIMDAcrossLanesS<bits<5> opcode, bit sz1, string asm,
5795 Intrinsic intOp> {
5796 def v4i32v : BaseSIMDAcrossLanes<1, 1, {sz1, 0}, opcode, FPR32, V128,
5797 asm, ".4s",
5798 [(set FPR32:$Rd, (intOp (v4f32 V128:$Rn)))]>;
5799}
5800
5801//----------------------------------------------------------------------------
5802// AdvSIMD INS/DUP instructions
5803//----------------------------------------------------------------------------
5804
5805// FIXME: There has got to be a better way to factor these. ugh.
5806
5807class BaseSIMDInsDup<bit Q, bit op, dag outs, dag ins, string asm,
5808 string operands, string constraints, list<dag> pattern>
5809 : I<outs, ins, asm, operands, constraints, pattern>,
5810 Sched<[WriteV]> {
5811 bits<5> Rd;
5812 bits<5> Rn;
5813 let Inst{31} = 0;
5814 let Inst{30} = Q;
5815 let Inst{29} = op;
5816 let Inst{28-21} = 0b01110000;
5817 let Inst{15} = 0;
5818 let Inst{10} = 1;
5819 let Inst{9-5} = Rn;
5820 let Inst{4-0} = Rd;
5821}
5822
5823class SIMDDupFromMain<bit Q, bits<5> imm5, string size, ValueType vectype,
5824 RegisterOperand vecreg, RegisterClass regtype>
5825 : BaseSIMDInsDup<Q, 0, (outs vecreg:$Rd), (ins regtype:$Rn), "dup",
5826 "{\t$Rd" # size # ", $Rn" #
5827 "|" # size # "\t$Rd, $Rn}", "",
5828 [(set (vectype vecreg:$Rd), (AArch64dup regtype:$Rn))]> {
5829 let Inst{20-16} = imm5;
5830 let Inst{14-11} = 0b0001;
5831}
5832
5833class SIMDDupFromElement<bit Q, string dstkind, string srckind,
5834 ValueType vectype, ValueType insreg,
5835 RegisterOperand vecreg, Operand idxtype,
5836 ValueType elttype, SDNode OpNode>
5837 : BaseSIMDInsDup<Q, 0, (outs vecreg:$Rd), (ins V128:$Rn, idxtype:$idx), "dup",
5838 "{\t$Rd" # dstkind # ", $Rn" # srckind # "$idx" #
5839 "|" # dstkind # "\t$Rd, $Rn$idx}", "",
5840 [(set (vectype vecreg:$Rd),
5841 (OpNode (insreg V128:$Rn), idxtype:$idx))]> {
5842 let Inst{14-11} = 0b0000;
5843}
5844
5845class SIMDDup64FromElement
5846 : SIMDDupFromElement<1, ".2d", ".d", v2i64, v2i64, V128,
5847 VectorIndexD, i64, AArch64duplane64> {
5848 bits<1> idx;
5849 let Inst{20} = idx;
5850 let Inst{19-16} = 0b1000;
5851}
5852
5853class SIMDDup32FromElement<bit Q, string size, ValueType vectype,
5854 RegisterOperand vecreg>
5855 : SIMDDupFromElement<Q, size, ".s", vectype, v4i32, vecreg,
5856 VectorIndexS, i64, AArch64duplane32> {
5857 bits<2> idx;
5858 let Inst{20-19} = idx;
5859 let Inst{18-16} = 0b100;
5860}
5861
5862class SIMDDup16FromElement<bit Q, string size, ValueType vectype,
5863 RegisterOperand vecreg>
5864 : SIMDDupFromElement<Q, size, ".h", vectype, v8i16, vecreg,
5865 VectorIndexH, i64, AArch64duplane16> {
5866 bits<3> idx;
5867 let Inst{20-18} = idx;
5868 let Inst{17-16} = 0b10;
5869}
5870
5871class SIMDDup8FromElement<bit Q, string size, ValueType vectype,
5872 RegisterOperand vecreg>
5873 : SIMDDupFromElement<Q, size, ".b", vectype, v16i8, vecreg,
5874 VectorIndexB, i64, AArch64duplane8> {
5875 bits<4> idx;
5876 let Inst{20-17} = idx;
5877 let Inst{16} = 1;
5878}
5879
5880class BaseSIMDMov<bit Q, string size, bits<4> imm4, RegisterClass regtype,
5881 Operand idxtype, string asm, list<dag> pattern>
5882 : BaseSIMDInsDup<Q, 0, (outs regtype:$Rd), (ins V128:$Rn, idxtype:$idx), asm,
5883 "{\t$Rd, $Rn" # size # "$idx" #
5884 "|" # size # "\t$Rd, $Rn$idx}", "", pattern> {
5885 let Inst{14-11} = imm4;
5886}
5887
5888class SIMDSMov<bit Q, string size, RegisterClass regtype,
5889 Operand idxtype>
5890 : BaseSIMDMov<Q, size, 0b0101, regtype, idxtype, "smov", []>;
5891class SIMDUMov<bit Q, string size, ValueType vectype, RegisterClass regtype,
5892 Operand idxtype>
5893 : BaseSIMDMov<Q, size, 0b0111, regtype, idxtype, "umov",
5894 [(set regtype:$Rd, (vector_extract (vectype V128:$Rn), idxtype:$idx))]>;
5895
5896class SIMDMovAlias<string asm, string size, Instruction inst,
5897 RegisterClass regtype, Operand idxtype>
5898 : InstAlias<asm#"{\t$dst, $src"#size#"$idx" #
5899 "|" # size # "\t$dst, $src$idx}",
5900 (inst regtype:$dst, V128:$src, idxtype:$idx)>;
5901
5902multiclass SMov {
5903 def vi8to32 : SIMDSMov<0, ".b", GPR32, VectorIndexB> {
5904 bits<4> idx;
5905 let Inst{20-17} = idx;
5906 let Inst{16} = 1;
5907 }
5908 def vi8to64 : SIMDSMov<1, ".b", GPR64, VectorIndexB> {
5909 bits<4> idx;
5910 let Inst{20-17} = idx;
5911 let Inst{16} = 1;
5912 }
5913 def vi16to32 : SIMDSMov<0, ".h", GPR32, VectorIndexH> {
5914 bits<3> idx;
5915 let Inst{20-18} = idx;
5916 let Inst{17-16} = 0b10;
5917 }
5918 def vi16to64 : SIMDSMov<1, ".h", GPR64, VectorIndexH> {
5919 bits<3> idx;
5920 let Inst{20-18} = idx;
5921 let Inst{17-16} = 0b10;
5922 }
5923 def vi32to64 : SIMDSMov<1, ".s", GPR64, VectorIndexS> {
5924 bits<2> idx;
5925 let Inst{20-19} = idx;
5926 let Inst{18-16} = 0b100;
5927 }
5928}
5929
5930multiclass UMov {
5931 def vi8 : SIMDUMov<0, ".b", v16i8, GPR32, VectorIndexB> {
5932 bits<4> idx;
5933 let Inst{20-17} = idx;
5934 let Inst{16} = 1;
5935 }
5936 def vi16 : SIMDUMov<0, ".h", v8i16, GPR32, VectorIndexH> {
5937 bits<3> idx;
5938 let Inst{20-18} = idx;
5939 let Inst{17-16} = 0b10;
5940 }
5941 def vi32 : SIMDUMov<0, ".s", v4i32, GPR32, VectorIndexS> {
5942 bits<2> idx;
5943 let Inst{20-19} = idx;
5944 let Inst{18-16} = 0b100;
5945 }
5946 def vi64 : SIMDUMov<1, ".d", v2i64, GPR64, VectorIndexD> {
5947 bits<1> idx;
5948 let Inst{20} = idx;
5949 let Inst{19-16} = 0b1000;
5950 }
5951 def : SIMDMovAlias<"mov", ".s",
5952 !cast<Instruction>(NAME#"vi32"),
5953 GPR32, VectorIndexS>;
5954 def : SIMDMovAlias<"mov", ".d",
5955 !cast<Instruction>(NAME#"vi64"),
5956 GPR64, VectorIndexD>;
5957}
5958
5959class SIMDInsFromMain<string size, ValueType vectype,
5960 RegisterClass regtype, Operand idxtype>
5961 : BaseSIMDInsDup<1, 0, (outs V128:$dst),
5962 (ins V128:$Rd, idxtype:$idx, regtype:$Rn), "ins",
5963 "{\t$Rd" # size # "$idx, $Rn" #
5964 "|" # size # "\t$Rd$idx, $Rn}",
5965 "$Rd = $dst",
5966 [(set V128:$dst,
5967 (vector_insert (vectype V128:$Rd), regtype:$Rn, idxtype:$idx))]> {
5968 let Inst{14-11} = 0b0011;
5969}
5970
5971class SIMDInsFromElement<string size, ValueType vectype,
5972 ValueType elttype, Operand idxtype>
5973 : BaseSIMDInsDup<1, 1, (outs V128:$dst),
5974 (ins V128:$Rd, idxtype:$idx, V128:$Rn, idxtype:$idx2), "ins",
5975 "{\t$Rd" # size # "$idx, $Rn" # size # "$idx2" #
5976 "|" # size # "\t$Rd$idx, $Rn$idx2}",
5977 "$Rd = $dst",
5978 [(set V128:$dst,
5979 (vector_insert
5980 (vectype V128:$Rd),
5981 (elttype (vector_extract (vectype V128:$Rn), idxtype:$idx2)),
5982 idxtype:$idx))]>;
5983
5984class SIMDInsMainMovAlias<string size, Instruction inst,
5985 RegisterClass regtype, Operand idxtype>
5986 : InstAlias<"mov" # "{\t$dst" # size # "$idx, $src" #
5987 "|" # size #"\t$dst$idx, $src}",
5988 (inst V128:$dst, idxtype:$idx, regtype:$src)>;
5989class SIMDInsElementMovAlias<string size, Instruction inst,
5990 Operand idxtype>
5991 : InstAlias<"mov" # "{\t$dst" # size # "$idx, $src" # size # "$idx2" #
Ahmed Bougachacca07712015-09-02 18:38:36 +00005992 # "|" # size #"\t$dst$idx, $src$idx2}",
Tim Northover3b0846e2014-05-24 12:50:23 +00005993 (inst V128:$dst, idxtype:$idx, V128:$src, idxtype:$idx2)>;
5994
5995
5996multiclass SIMDIns {
5997 def vi8gpr : SIMDInsFromMain<".b", v16i8, GPR32, VectorIndexB> {
5998 bits<4> idx;
5999 let Inst{20-17} = idx;
6000 let Inst{16} = 1;
6001 }
6002 def vi16gpr : SIMDInsFromMain<".h", v8i16, GPR32, VectorIndexH> {
6003 bits<3> idx;
6004 let Inst{20-18} = idx;
6005 let Inst{17-16} = 0b10;
6006 }
6007 def vi32gpr : SIMDInsFromMain<".s", v4i32, GPR32, VectorIndexS> {
6008 bits<2> idx;
6009 let Inst{20-19} = idx;
6010 let Inst{18-16} = 0b100;
6011 }
6012 def vi64gpr : SIMDInsFromMain<".d", v2i64, GPR64, VectorIndexD> {
6013 bits<1> idx;
6014 let Inst{20} = idx;
6015 let Inst{19-16} = 0b1000;
6016 }
6017
6018 def vi8lane : SIMDInsFromElement<".b", v16i8, i32, VectorIndexB> {
6019 bits<4> idx;
6020 bits<4> idx2;
6021 let Inst{20-17} = idx;
6022 let Inst{16} = 1;
6023 let Inst{14-11} = idx2;
6024 }
6025 def vi16lane : SIMDInsFromElement<".h", v8i16, i32, VectorIndexH> {
6026 bits<3> idx;
6027 bits<3> idx2;
6028 let Inst{20-18} = idx;
6029 let Inst{17-16} = 0b10;
6030 let Inst{14-12} = idx2;
Bradley Smithb9136532015-04-14 15:07:26 +00006031 let Inst{11} = {?};
Tim Northover3b0846e2014-05-24 12:50:23 +00006032 }
6033 def vi32lane : SIMDInsFromElement<".s", v4i32, i32, VectorIndexS> {
6034 bits<2> idx;
6035 bits<2> idx2;
6036 let Inst{20-19} = idx;
6037 let Inst{18-16} = 0b100;
6038 let Inst{14-13} = idx2;
Bradley Smithb9136532015-04-14 15:07:26 +00006039 let Inst{12-11} = {?,?};
Tim Northover3b0846e2014-05-24 12:50:23 +00006040 }
6041 def vi64lane : SIMDInsFromElement<".d", v2i64, i64, VectorIndexD> {
6042 bits<1> idx;
6043 bits<1> idx2;
6044 let Inst{20} = idx;
6045 let Inst{19-16} = 0b1000;
6046 let Inst{14} = idx2;
Bradley Smithb9136532015-04-14 15:07:26 +00006047 let Inst{13-11} = {?,?,?};
Tim Northover3b0846e2014-05-24 12:50:23 +00006048 }
6049
6050 // For all forms of the INS instruction, the "mov" mnemonic is the
6051 // preferred alias. Why they didn't just call the instruction "mov" in
6052 // the first place is a very good question indeed...
6053 def : SIMDInsMainMovAlias<".b", !cast<Instruction>(NAME#"vi8gpr"),
6054 GPR32, VectorIndexB>;
6055 def : SIMDInsMainMovAlias<".h", !cast<Instruction>(NAME#"vi16gpr"),
6056 GPR32, VectorIndexH>;
6057 def : SIMDInsMainMovAlias<".s", !cast<Instruction>(NAME#"vi32gpr"),
6058 GPR32, VectorIndexS>;
6059 def : SIMDInsMainMovAlias<".d", !cast<Instruction>(NAME#"vi64gpr"),
6060 GPR64, VectorIndexD>;
6061
6062 def : SIMDInsElementMovAlias<".b", !cast<Instruction>(NAME#"vi8lane"),
6063 VectorIndexB>;
6064 def : SIMDInsElementMovAlias<".h", !cast<Instruction>(NAME#"vi16lane"),
6065 VectorIndexH>;
6066 def : SIMDInsElementMovAlias<".s", !cast<Instruction>(NAME#"vi32lane"),
6067 VectorIndexS>;
6068 def : SIMDInsElementMovAlias<".d", !cast<Instruction>(NAME#"vi64lane"),
6069 VectorIndexD>;
6070}
6071
6072//----------------------------------------------------------------------------
6073// AdvSIMD TBL/TBX
6074//----------------------------------------------------------------------------
6075
6076let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
6077class BaseSIMDTableLookup<bit Q, bits<2> len, bit op, RegisterOperand vectype,
6078 RegisterOperand listtype, string asm, string kind>
6079 : I<(outs vectype:$Vd), (ins listtype:$Vn, vectype:$Vm), asm,
6080 "\t$Vd" # kind # ", $Vn, $Vm" # kind, "", []>,
6081 Sched<[WriteV]> {
6082 bits<5> Vd;
6083 bits<5> Vn;
6084 bits<5> Vm;
6085 let Inst{31} = 0;
6086 let Inst{30} = Q;
6087 let Inst{29-21} = 0b001110000;
6088 let Inst{20-16} = Vm;
6089 let Inst{15} = 0;
6090 let Inst{14-13} = len;
6091 let Inst{12} = op;
6092 let Inst{11-10} = 0b00;
6093 let Inst{9-5} = Vn;
6094 let Inst{4-0} = Vd;
6095}
6096
6097let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
6098class BaseSIMDTableLookupTied<bit Q, bits<2> len, bit op, RegisterOperand vectype,
6099 RegisterOperand listtype, string asm, string kind>
6100 : I<(outs vectype:$dst), (ins vectype:$Vd, listtype:$Vn, vectype:$Vm), asm,
6101 "\t$Vd" # kind # ", $Vn, $Vm" # kind, "$Vd = $dst", []>,
6102 Sched<[WriteV]> {
6103 bits<5> Vd;
6104 bits<5> Vn;
6105 bits<5> Vm;
6106 let Inst{31} = 0;
6107 let Inst{30} = Q;
6108 let Inst{29-21} = 0b001110000;
6109 let Inst{20-16} = Vm;
6110 let Inst{15} = 0;
6111 let Inst{14-13} = len;
6112 let Inst{12} = op;
6113 let Inst{11-10} = 0b00;
6114 let Inst{9-5} = Vn;
6115 let Inst{4-0} = Vd;
6116}
6117
6118class SIMDTableLookupAlias<string asm, Instruction inst,
6119 RegisterOperand vectype, RegisterOperand listtype>
6120 : InstAlias<!strconcat(asm, "\t$dst, $lst, $index"),
6121 (inst vectype:$dst, listtype:$lst, vectype:$index), 0>;
6122
6123multiclass SIMDTableLookup<bit op, string asm> {
6124 def v8i8One : BaseSIMDTableLookup<0, 0b00, op, V64, VecListOne16b,
6125 asm, ".8b">;
6126 def v8i8Two : BaseSIMDTableLookup<0, 0b01, op, V64, VecListTwo16b,
6127 asm, ".8b">;
6128 def v8i8Three : BaseSIMDTableLookup<0, 0b10, op, V64, VecListThree16b,
6129 asm, ".8b">;
6130 def v8i8Four : BaseSIMDTableLookup<0, 0b11, op, V64, VecListFour16b,
6131 asm, ".8b">;
6132 def v16i8One : BaseSIMDTableLookup<1, 0b00, op, V128, VecListOne16b,
6133 asm, ".16b">;
6134 def v16i8Two : BaseSIMDTableLookup<1, 0b01, op, V128, VecListTwo16b,
6135 asm, ".16b">;
6136 def v16i8Three: BaseSIMDTableLookup<1, 0b10, op, V128, VecListThree16b,
6137 asm, ".16b">;
6138 def v16i8Four : BaseSIMDTableLookup<1, 0b11, op, V128, VecListFour16b,
6139 asm, ".16b">;
6140
6141 def : SIMDTableLookupAlias<asm # ".8b",
6142 !cast<Instruction>(NAME#"v8i8One"),
6143 V64, VecListOne128>;
6144 def : SIMDTableLookupAlias<asm # ".8b",
6145 !cast<Instruction>(NAME#"v8i8Two"),
6146 V64, VecListTwo128>;
6147 def : SIMDTableLookupAlias<asm # ".8b",
6148 !cast<Instruction>(NAME#"v8i8Three"),
6149 V64, VecListThree128>;
6150 def : SIMDTableLookupAlias<asm # ".8b",
6151 !cast<Instruction>(NAME#"v8i8Four"),
6152 V64, VecListFour128>;
6153 def : SIMDTableLookupAlias<asm # ".16b",
6154 !cast<Instruction>(NAME#"v16i8One"),
6155 V128, VecListOne128>;
6156 def : SIMDTableLookupAlias<asm # ".16b",
6157 !cast<Instruction>(NAME#"v16i8Two"),
6158 V128, VecListTwo128>;
6159 def : SIMDTableLookupAlias<asm # ".16b",
6160 !cast<Instruction>(NAME#"v16i8Three"),
6161 V128, VecListThree128>;
6162 def : SIMDTableLookupAlias<asm # ".16b",
6163 !cast<Instruction>(NAME#"v16i8Four"),
6164 V128, VecListFour128>;
6165}
6166
6167multiclass SIMDTableLookupTied<bit op, string asm> {
6168 def v8i8One : BaseSIMDTableLookupTied<0, 0b00, op, V64, VecListOne16b,
6169 asm, ".8b">;
6170 def v8i8Two : BaseSIMDTableLookupTied<0, 0b01, op, V64, VecListTwo16b,
6171 asm, ".8b">;
6172 def v8i8Three : BaseSIMDTableLookupTied<0, 0b10, op, V64, VecListThree16b,
6173 asm, ".8b">;
6174 def v8i8Four : BaseSIMDTableLookupTied<0, 0b11, op, V64, VecListFour16b,
6175 asm, ".8b">;
6176 def v16i8One : BaseSIMDTableLookupTied<1, 0b00, op, V128, VecListOne16b,
6177 asm, ".16b">;
6178 def v16i8Two : BaseSIMDTableLookupTied<1, 0b01, op, V128, VecListTwo16b,
6179 asm, ".16b">;
6180 def v16i8Three: BaseSIMDTableLookupTied<1, 0b10, op, V128, VecListThree16b,
6181 asm, ".16b">;
6182 def v16i8Four : BaseSIMDTableLookupTied<1, 0b11, op, V128, VecListFour16b,
6183 asm, ".16b">;
6184
6185 def : SIMDTableLookupAlias<asm # ".8b",
6186 !cast<Instruction>(NAME#"v8i8One"),
6187 V64, VecListOne128>;
6188 def : SIMDTableLookupAlias<asm # ".8b",
6189 !cast<Instruction>(NAME#"v8i8Two"),
6190 V64, VecListTwo128>;
6191 def : SIMDTableLookupAlias<asm # ".8b",
6192 !cast<Instruction>(NAME#"v8i8Three"),
6193 V64, VecListThree128>;
6194 def : SIMDTableLookupAlias<asm # ".8b",
6195 !cast<Instruction>(NAME#"v8i8Four"),
6196 V64, VecListFour128>;
6197 def : SIMDTableLookupAlias<asm # ".16b",
6198 !cast<Instruction>(NAME#"v16i8One"),
6199 V128, VecListOne128>;
6200 def : SIMDTableLookupAlias<asm # ".16b",
6201 !cast<Instruction>(NAME#"v16i8Two"),
6202 V128, VecListTwo128>;
6203 def : SIMDTableLookupAlias<asm # ".16b",
6204 !cast<Instruction>(NAME#"v16i8Three"),
6205 V128, VecListThree128>;
6206 def : SIMDTableLookupAlias<asm # ".16b",
6207 !cast<Instruction>(NAME#"v16i8Four"),
6208 V128, VecListFour128>;
6209}
6210
6211
6212//----------------------------------------------------------------------------
6213// AdvSIMD scalar CPY
6214//----------------------------------------------------------------------------
6215let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
6216class BaseSIMDScalarCPY<RegisterClass regtype, RegisterOperand vectype,
6217 string kind, Operand idxtype>
6218 : I<(outs regtype:$dst), (ins vectype:$src, idxtype:$idx), "mov",
6219 "{\t$dst, $src" # kind # "$idx" #
6220 "|\t$dst, $src$idx}", "", []>,
6221 Sched<[WriteV]> {
6222 bits<5> dst;
6223 bits<5> src;
6224 let Inst{31-21} = 0b01011110000;
6225 let Inst{15-10} = 0b000001;
6226 let Inst{9-5} = src;
6227 let Inst{4-0} = dst;
6228}
6229
6230class SIMDScalarCPYAlias<string asm, string size, Instruction inst,
6231 RegisterClass regtype, RegisterOperand vectype, Operand idxtype>
6232 : InstAlias<asm # "{\t$dst, $src" # size # "$index" #
6233 # "|\t$dst, $src$index}",
6234 (inst regtype:$dst, vectype:$src, idxtype:$index), 0>;
6235
6236
6237multiclass SIMDScalarCPY<string asm> {
6238 def i8 : BaseSIMDScalarCPY<FPR8, V128, ".b", VectorIndexB> {
6239 bits<4> idx;
6240 let Inst{20-17} = idx;
6241 let Inst{16} = 1;
6242 }
6243 def i16 : BaseSIMDScalarCPY<FPR16, V128, ".h", VectorIndexH> {
6244 bits<3> idx;
6245 let Inst{20-18} = idx;
6246 let Inst{17-16} = 0b10;
6247 }
6248 def i32 : BaseSIMDScalarCPY<FPR32, V128, ".s", VectorIndexS> {
6249 bits<2> idx;
6250 let Inst{20-19} = idx;
6251 let Inst{18-16} = 0b100;
6252 }
6253 def i64 : BaseSIMDScalarCPY<FPR64, V128, ".d", VectorIndexD> {
6254 bits<1> idx;
6255 let Inst{20} = idx;
6256 let Inst{19-16} = 0b1000;
6257 }
6258
6259 def : Pat<(v1i64 (scalar_to_vector (i64 (vector_extract (v2i64 V128:$src),
6260 VectorIndexD:$idx)))),
6261 (!cast<Instruction>(NAME # i64) V128:$src, VectorIndexD:$idx)>;
6262
6263 // 'DUP' mnemonic aliases.
6264 def : SIMDScalarCPYAlias<"dup", ".b",
6265 !cast<Instruction>(NAME#"i8"),
6266 FPR8, V128, VectorIndexB>;
6267 def : SIMDScalarCPYAlias<"dup", ".h",
6268 !cast<Instruction>(NAME#"i16"),
6269 FPR16, V128, VectorIndexH>;
6270 def : SIMDScalarCPYAlias<"dup", ".s",
6271 !cast<Instruction>(NAME#"i32"),
6272 FPR32, V128, VectorIndexS>;
6273 def : SIMDScalarCPYAlias<"dup", ".d",
6274 !cast<Instruction>(NAME#"i64"),
6275 FPR64, V128, VectorIndexD>;
6276}
6277
6278//----------------------------------------------------------------------------
6279// AdvSIMD modified immediate instructions
6280//----------------------------------------------------------------------------
6281
6282class BaseSIMDModifiedImm<bit Q, bit op, dag oops, dag iops,
6283 string asm, string op_string,
6284 string cstr, list<dag> pattern>
6285 : I<oops, iops, asm, op_string, cstr, pattern>,
6286 Sched<[WriteV]> {
6287 bits<5> Rd;
6288 bits<8> imm8;
6289 let Inst{31} = 0;
6290 let Inst{30} = Q;
6291 let Inst{29} = op;
6292 let Inst{28-19} = 0b0111100000;
6293 let Inst{18-16} = imm8{7-5};
6294 let Inst{11-10} = 0b01;
6295 let Inst{9-5} = imm8{4-0};
6296 let Inst{4-0} = Rd;
6297}
6298
6299class BaseSIMDModifiedImmVector<bit Q, bit op, RegisterOperand vectype,
6300 Operand immtype, dag opt_shift_iop,
6301 string opt_shift, string asm, string kind,
6302 list<dag> pattern>
6303 : BaseSIMDModifiedImm<Q, op, (outs vectype:$Rd),
6304 !con((ins immtype:$imm8), opt_shift_iop), asm,
6305 "{\t$Rd" # kind # ", $imm8" # opt_shift #
6306 "|" # kind # "\t$Rd, $imm8" # opt_shift # "}",
6307 "", pattern> {
6308 let DecoderMethod = "DecodeModImmInstruction";
6309}
6310
6311class BaseSIMDModifiedImmVectorTied<bit Q, bit op, RegisterOperand vectype,
6312 Operand immtype, dag opt_shift_iop,
6313 string opt_shift, string asm, string kind,
6314 list<dag> pattern>
6315 : BaseSIMDModifiedImm<Q, op, (outs vectype:$dst),
6316 !con((ins vectype:$Rd, immtype:$imm8), opt_shift_iop),
6317 asm, "{\t$Rd" # kind # ", $imm8" # opt_shift #
6318 "|" # kind # "\t$Rd, $imm8" # opt_shift # "}",
6319 "$Rd = $dst", pattern> {
6320 let DecoderMethod = "DecodeModImmTiedInstruction";
6321}
6322
6323class BaseSIMDModifiedImmVectorShift<bit Q, bit op, bits<2> b15_b12,
6324 RegisterOperand vectype, string asm,
6325 string kind, list<dag> pattern>
6326 : BaseSIMDModifiedImmVector<Q, op, vectype, imm0_255,
6327 (ins logical_vec_shift:$shift),
6328 "$shift", asm, kind, pattern> {
6329 bits<2> shift;
6330 let Inst{15} = b15_b12{1};
6331 let Inst{14-13} = shift;
6332 let Inst{12} = b15_b12{0};
6333}
6334
6335class BaseSIMDModifiedImmVectorShiftTied<bit Q, bit op, bits<2> b15_b12,
6336 RegisterOperand vectype, string asm,
6337 string kind, list<dag> pattern>
6338 : BaseSIMDModifiedImmVectorTied<Q, op, vectype, imm0_255,
6339 (ins logical_vec_shift:$shift),
6340 "$shift", asm, kind, pattern> {
6341 bits<2> shift;
6342 let Inst{15} = b15_b12{1};
6343 let Inst{14-13} = shift;
6344 let Inst{12} = b15_b12{0};
6345}
6346
6347
6348class BaseSIMDModifiedImmVectorShiftHalf<bit Q, bit op, bits<2> b15_b12,
6349 RegisterOperand vectype, string asm,
6350 string kind, list<dag> pattern>
6351 : BaseSIMDModifiedImmVector<Q, op, vectype, imm0_255,
6352 (ins logical_vec_hw_shift:$shift),
6353 "$shift", asm, kind, pattern> {
6354 bits<2> shift;
6355 let Inst{15} = b15_b12{1};
6356 let Inst{14} = 0;
6357 let Inst{13} = shift{0};
6358 let Inst{12} = b15_b12{0};
6359}
6360
6361class BaseSIMDModifiedImmVectorShiftHalfTied<bit Q, bit op, bits<2> b15_b12,
6362 RegisterOperand vectype, string asm,
6363 string kind, list<dag> pattern>
6364 : BaseSIMDModifiedImmVectorTied<Q, op, vectype, imm0_255,
6365 (ins logical_vec_hw_shift:$shift),
6366 "$shift", asm, kind, pattern> {
6367 bits<2> shift;
6368 let Inst{15} = b15_b12{1};
6369 let Inst{14} = 0;
6370 let Inst{13} = shift{0};
6371 let Inst{12} = b15_b12{0};
6372}
6373
6374multiclass SIMDModifiedImmVectorShift<bit op, bits<2> hw_cmode, bits<2> w_cmode,
6375 string asm> {
6376 def v4i16 : BaseSIMDModifiedImmVectorShiftHalf<0, op, hw_cmode, V64,
6377 asm, ".4h", []>;
6378 def v8i16 : BaseSIMDModifiedImmVectorShiftHalf<1, op, hw_cmode, V128,
6379 asm, ".8h", []>;
6380
6381 def v2i32 : BaseSIMDModifiedImmVectorShift<0, op, w_cmode, V64,
6382 asm, ".2s", []>;
6383 def v4i32 : BaseSIMDModifiedImmVectorShift<1, op, w_cmode, V128,
6384 asm, ".4s", []>;
6385}
6386
6387multiclass SIMDModifiedImmVectorShiftTied<bit op, bits<2> hw_cmode,
6388 bits<2> w_cmode, string asm,
6389 SDNode OpNode> {
6390 def v4i16 : BaseSIMDModifiedImmVectorShiftHalfTied<0, op, hw_cmode, V64,
6391 asm, ".4h",
6392 [(set (v4i16 V64:$dst), (OpNode V64:$Rd,
6393 imm0_255:$imm8,
6394 (i32 imm:$shift)))]>;
6395 def v8i16 : BaseSIMDModifiedImmVectorShiftHalfTied<1, op, hw_cmode, V128,
6396 asm, ".8h",
6397 [(set (v8i16 V128:$dst), (OpNode V128:$Rd,
6398 imm0_255:$imm8,
6399 (i32 imm:$shift)))]>;
6400
6401 def v2i32 : BaseSIMDModifiedImmVectorShiftTied<0, op, w_cmode, V64,
6402 asm, ".2s",
6403 [(set (v2i32 V64:$dst), (OpNode V64:$Rd,
6404 imm0_255:$imm8,
6405 (i32 imm:$shift)))]>;
6406 def v4i32 : BaseSIMDModifiedImmVectorShiftTied<1, op, w_cmode, V128,
6407 asm, ".4s",
6408 [(set (v4i32 V128:$dst), (OpNode V128:$Rd,
6409 imm0_255:$imm8,
6410 (i32 imm:$shift)))]>;
6411}
6412
6413class SIMDModifiedImmMoveMSL<bit Q, bit op, bits<4> cmode,
6414 RegisterOperand vectype, string asm,
6415 string kind, list<dag> pattern>
6416 : BaseSIMDModifiedImmVector<Q, op, vectype, imm0_255,
6417 (ins move_vec_shift:$shift),
6418 "$shift", asm, kind, pattern> {
6419 bits<1> shift;
6420 let Inst{15-13} = cmode{3-1};
6421 let Inst{12} = shift;
6422}
6423
6424class SIMDModifiedImmVectorNoShift<bit Q, bit op, bits<4> cmode,
6425 RegisterOperand vectype,
6426 Operand imm_type, string asm,
6427 string kind, list<dag> pattern>
6428 : BaseSIMDModifiedImmVector<Q, op, vectype, imm_type, (ins), "",
6429 asm, kind, pattern> {
6430 let Inst{15-12} = cmode;
6431}
6432
6433class SIMDModifiedImmScalarNoShift<bit Q, bit op, bits<4> cmode, string asm,
6434 list<dag> pattern>
6435 : BaseSIMDModifiedImm<Q, op, (outs FPR64:$Rd), (ins simdimmtype10:$imm8), asm,
6436 "\t$Rd, $imm8", "", pattern> {
6437 let Inst{15-12} = cmode;
6438 let DecoderMethod = "DecodeModImmInstruction";
6439}
6440
6441//----------------------------------------------------------------------------
6442// AdvSIMD indexed element
6443//----------------------------------------------------------------------------
6444
6445let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
6446class BaseSIMDIndexed<bit Q, bit U, bit Scalar, bits<2> size, bits<4> opc,
6447 RegisterOperand dst_reg, RegisterOperand lhs_reg,
6448 RegisterOperand rhs_reg, Operand vec_idx, string asm,
6449 string apple_kind, string dst_kind, string lhs_kind,
6450 string rhs_kind, list<dag> pattern>
6451 : I<(outs dst_reg:$Rd), (ins lhs_reg:$Rn, rhs_reg:$Rm, vec_idx:$idx),
6452 asm,
6453 "{\t$Rd" # dst_kind # ", $Rn" # lhs_kind # ", $Rm" # rhs_kind # "$idx" #
6454 "|" # apple_kind # "\t$Rd, $Rn, $Rm$idx}", "", pattern>,
6455 Sched<[WriteV]> {
6456 bits<5> Rd;
6457 bits<5> Rn;
6458 bits<5> Rm;
6459
6460 let Inst{31} = 0;
6461 let Inst{30} = Q;
6462 let Inst{29} = U;
6463 let Inst{28} = Scalar;
6464 let Inst{27-24} = 0b1111;
6465 let Inst{23-22} = size;
6466 // Bit 21 must be set by the derived class.
6467 let Inst{20-16} = Rm;
6468 let Inst{15-12} = opc;
6469 // Bit 11 must be set by the derived class.
6470 let Inst{10} = 0;
6471 let Inst{9-5} = Rn;
6472 let Inst{4-0} = Rd;
6473}
6474
6475let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
6476class BaseSIMDIndexedTied<bit Q, bit U, bit Scalar, bits<2> size, bits<4> opc,
6477 RegisterOperand dst_reg, RegisterOperand lhs_reg,
6478 RegisterOperand rhs_reg, Operand vec_idx, string asm,
6479 string apple_kind, string dst_kind, string lhs_kind,
6480 string rhs_kind, list<dag> pattern>
6481 : I<(outs dst_reg:$dst),
6482 (ins dst_reg:$Rd, lhs_reg:$Rn, rhs_reg:$Rm, vec_idx:$idx), asm,
6483 "{\t$Rd" # dst_kind # ", $Rn" # lhs_kind # ", $Rm" # rhs_kind # "$idx" #
6484 "|" # apple_kind # "\t$Rd, $Rn, $Rm$idx}", "$Rd = $dst", pattern>,
6485 Sched<[WriteV]> {
6486 bits<5> Rd;
6487 bits<5> Rn;
6488 bits<5> Rm;
6489
6490 let Inst{31} = 0;
6491 let Inst{30} = Q;
6492 let Inst{29} = U;
6493 let Inst{28} = Scalar;
6494 let Inst{27-24} = 0b1111;
6495 let Inst{23-22} = size;
6496 // Bit 21 must be set by the derived class.
6497 let Inst{20-16} = Rm;
6498 let Inst{15-12} = opc;
6499 // Bit 11 must be set by the derived class.
6500 let Inst{10} = 0;
6501 let Inst{9-5} = Rn;
6502 let Inst{4-0} = Rd;
6503}
6504
Ahmed Bougacha81fda182015-08-04 01:38:08 +00006505multiclass SIMDFPIndexed<bit U, bits<4> opc, string asm,
6506 SDPatternOperator OpNode> {
Tim Northover3b0846e2014-05-24 12:50:23 +00006507 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc,
6508 V64, V64,
6509 V128, VectorIndexS,
6510 asm, ".2s", ".2s", ".2s", ".s",
6511 [(set (v2f32 V64:$Rd),
6512 (OpNode (v2f32 V64:$Rn),
6513 (v2f32 (AArch64duplane32 (v4f32 V128:$Rm), VectorIndexS:$idx))))]> {
6514 bits<2> idx;
6515 let Inst{11} = idx{1};
6516 let Inst{21} = idx{0};
6517 }
6518
6519 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc,
6520 V128, V128,
6521 V128, VectorIndexS,
6522 asm, ".4s", ".4s", ".4s", ".s",
6523 [(set (v4f32 V128:$Rd),
6524 (OpNode (v4f32 V128:$Rn),
6525 (v4f32 (AArch64duplane32 (v4f32 V128:$Rm), VectorIndexS:$idx))))]> {
6526 bits<2> idx;
6527 let Inst{11} = idx{1};
6528 let Inst{21} = idx{0};
6529 }
6530
6531 def v2i64_indexed : BaseSIMDIndexed<1, U, 0, 0b11, opc,
6532 V128, V128,
6533 V128, VectorIndexD,
6534 asm, ".2d", ".2d", ".2d", ".d",
6535 [(set (v2f64 V128:$Rd),
6536 (OpNode (v2f64 V128:$Rn),
6537 (v2f64 (AArch64duplane64 (v2f64 V128:$Rm), VectorIndexD:$idx))))]> {
6538 bits<1> idx;
6539 let Inst{11} = idx{0};
6540 let Inst{21} = 0;
6541 }
6542
6543 def v1i32_indexed : BaseSIMDIndexed<1, U, 1, 0b10, opc,
6544 FPR32Op, FPR32Op, V128, VectorIndexS,
6545 asm, ".s", "", "", ".s",
6546 [(set (f32 FPR32Op:$Rd),
6547 (OpNode (f32 FPR32Op:$Rn),
6548 (f32 (vector_extract (v4f32 V128:$Rm),
6549 VectorIndexS:$idx))))]> {
6550 bits<2> idx;
6551 let Inst{11} = idx{1};
6552 let Inst{21} = idx{0};
6553 }
6554
6555 def v1i64_indexed : BaseSIMDIndexed<1, U, 1, 0b11, opc,
6556 FPR64Op, FPR64Op, V128, VectorIndexD,
6557 asm, ".d", "", "", ".d",
6558 [(set (f64 FPR64Op:$Rd),
6559 (OpNode (f64 FPR64Op:$Rn),
6560 (f64 (vector_extract (v2f64 V128:$Rm),
6561 VectorIndexD:$idx))))]> {
6562 bits<1> idx;
6563 let Inst{11} = idx{0};
6564 let Inst{21} = 0;
6565 }
6566}
6567
Ahmed Bougacha81fda182015-08-04 01:38:08 +00006568multiclass SIMDFPIndexedTiedPatterns<string INST, SDPatternOperator OpNode> {
Tim Northover3b0846e2014-05-24 12:50:23 +00006569 // 2 variants for the .2s version: DUPLANE from 128-bit and DUP scalar.
6570 def : Pat<(v2f32 (OpNode (v2f32 V64:$Rd), (v2f32 V64:$Rn),
6571 (AArch64duplane32 (v4f32 V128:$Rm),
6572 VectorIndexS:$idx))),
6573 (!cast<Instruction>(INST # v2i32_indexed)
6574 V64:$Rd, V64:$Rn, V128:$Rm, VectorIndexS:$idx)>;
6575 def : Pat<(v2f32 (OpNode (v2f32 V64:$Rd), (v2f32 V64:$Rn),
6576 (AArch64dup (f32 FPR32Op:$Rm)))),
6577 (!cast<Instruction>(INST # "v2i32_indexed") V64:$Rd, V64:$Rn,
6578 (SUBREG_TO_REG (i32 0), FPR32Op:$Rm, ssub), (i64 0))>;
6579
6580
6581 // 2 variants for the .4s version: DUPLANE from 128-bit and DUP scalar.
6582 def : Pat<(v4f32 (OpNode (v4f32 V128:$Rd), (v4f32 V128:$Rn),
6583 (AArch64duplane32 (v4f32 V128:$Rm),
6584 VectorIndexS:$idx))),
6585 (!cast<Instruction>(INST # "v4i32_indexed")
6586 V128:$Rd, V128:$Rn, V128:$Rm, VectorIndexS:$idx)>;
6587 def : Pat<(v4f32 (OpNode (v4f32 V128:$Rd), (v4f32 V128:$Rn),
6588 (AArch64dup (f32 FPR32Op:$Rm)))),
6589 (!cast<Instruction>(INST # "v4i32_indexed") V128:$Rd, V128:$Rn,
6590 (SUBREG_TO_REG (i32 0), FPR32Op:$Rm, ssub), (i64 0))>;
6591
6592 // 2 variants for the .2d version: DUPLANE from 128-bit and DUP scalar.
6593 def : Pat<(v2f64 (OpNode (v2f64 V128:$Rd), (v2f64 V128:$Rn),
6594 (AArch64duplane64 (v2f64 V128:$Rm),
6595 VectorIndexD:$idx))),
6596 (!cast<Instruction>(INST # "v2i64_indexed")
6597 V128:$Rd, V128:$Rn, V128:$Rm, VectorIndexS:$idx)>;
6598 def : Pat<(v2f64 (OpNode (v2f64 V128:$Rd), (v2f64 V128:$Rn),
6599 (AArch64dup (f64 FPR64Op:$Rm)))),
6600 (!cast<Instruction>(INST # "v2i64_indexed") V128:$Rd, V128:$Rn,
6601 (SUBREG_TO_REG (i32 0), FPR64Op:$Rm, dsub), (i64 0))>;
6602
6603 // 2 variants for 32-bit scalar version: extract from .2s or from .4s
6604 def : Pat<(f32 (OpNode (f32 FPR32:$Rd), (f32 FPR32:$Rn),
6605 (vector_extract (v4f32 V128:$Rm), VectorIndexS:$idx))),
6606 (!cast<Instruction>(INST # "v1i32_indexed") FPR32:$Rd, FPR32:$Rn,
6607 V128:$Rm, VectorIndexS:$idx)>;
6608 def : Pat<(f32 (OpNode (f32 FPR32:$Rd), (f32 FPR32:$Rn),
6609 (vector_extract (v2f32 V64:$Rm), VectorIndexS:$idx))),
6610 (!cast<Instruction>(INST # "v1i32_indexed") FPR32:$Rd, FPR32:$Rn,
6611 (SUBREG_TO_REG (i32 0), V64:$Rm, dsub), VectorIndexS:$idx)>;
6612
6613 // 1 variant for 64-bit scalar version: extract from .1d or from .2d
6614 def : Pat<(f64 (OpNode (f64 FPR64:$Rd), (f64 FPR64:$Rn),
6615 (vector_extract (v2f64 V128:$Rm), VectorIndexD:$idx))),
6616 (!cast<Instruction>(INST # "v1i64_indexed") FPR64:$Rd, FPR64:$Rn,
6617 V128:$Rm, VectorIndexD:$idx)>;
6618}
6619
Ahmed Bougacha81fda182015-08-04 01:38:08 +00006620multiclass SIMDFPIndexedTied<bit U, bits<4> opc, string asm> {
Tim Northover3b0846e2014-05-24 12:50:23 +00006621 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc, V64, V64,
6622 V128, VectorIndexS,
6623 asm, ".2s", ".2s", ".2s", ".s", []> {
6624 bits<2> idx;
6625 let Inst{11} = idx{1};
6626 let Inst{21} = idx{0};
6627 }
6628
6629 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc,
6630 V128, V128,
6631 V128, VectorIndexS,
6632 asm, ".4s", ".4s", ".4s", ".s", []> {
6633 bits<2> idx;
6634 let Inst{11} = idx{1};
6635 let Inst{21} = idx{0};
6636 }
6637
6638 def v2i64_indexed : BaseSIMDIndexedTied<1, U, 0, 0b11, opc,
6639 V128, V128,
6640 V128, VectorIndexD,
6641 asm, ".2d", ".2d", ".2d", ".d", []> {
6642 bits<1> idx;
6643 let Inst{11} = idx{0};
6644 let Inst{21} = 0;
6645 }
6646
6647
6648 def v1i32_indexed : BaseSIMDIndexedTied<1, U, 1, 0b10, opc,
6649 FPR32Op, FPR32Op, V128, VectorIndexS,
6650 asm, ".s", "", "", ".s", []> {
6651 bits<2> idx;
6652 let Inst{11} = idx{1};
6653 let Inst{21} = idx{0};
6654 }
6655
6656 def v1i64_indexed : BaseSIMDIndexedTied<1, U, 1, 0b11, opc,
6657 FPR64Op, FPR64Op, V128, VectorIndexD,
6658 asm, ".d", "", "", ".d", []> {
6659 bits<1> idx;
6660 let Inst{11} = idx{0};
6661 let Inst{21} = 0;
6662 }
6663}
6664
6665multiclass SIMDIndexedHS<bit U, bits<4> opc, string asm,
6666 SDPatternOperator OpNode> {
6667 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc, V64, V64,
6668 V128_lo, VectorIndexH,
6669 asm, ".4h", ".4h", ".4h", ".h",
6670 [(set (v4i16 V64:$Rd),
6671 (OpNode (v4i16 V64:$Rn),
6672 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
6673 bits<3> idx;
6674 let Inst{11} = idx{2};
6675 let Inst{21} = idx{1};
6676 let Inst{20} = idx{0};
6677 }
6678
6679 def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc,
6680 V128, V128,
6681 V128_lo, VectorIndexH,
6682 asm, ".8h", ".8h", ".8h", ".h",
6683 [(set (v8i16 V128:$Rd),
6684 (OpNode (v8i16 V128:$Rn),
6685 (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
6686 bits<3> idx;
6687 let Inst{11} = idx{2};
6688 let Inst{21} = idx{1};
6689 let Inst{20} = idx{0};
6690 }
6691
6692 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc,
6693 V64, V64,
6694 V128, VectorIndexS,
6695 asm, ".2s", ".2s", ".2s", ".s",
6696 [(set (v2i32 V64:$Rd),
6697 (OpNode (v2i32 V64:$Rn),
6698 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
6699 bits<2> idx;
6700 let Inst{11} = idx{1};
6701 let Inst{21} = idx{0};
6702 }
6703
6704 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc,
6705 V128, V128,
6706 V128, VectorIndexS,
6707 asm, ".4s", ".4s", ".4s", ".s",
6708 [(set (v4i32 V128:$Rd),
6709 (OpNode (v4i32 V128:$Rn),
6710 (v4i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
6711 bits<2> idx;
6712 let Inst{11} = idx{1};
6713 let Inst{21} = idx{0};
6714 }
6715
6716 def v1i16_indexed : BaseSIMDIndexed<1, U, 1, 0b01, opc,
6717 FPR16Op, FPR16Op, V128_lo, VectorIndexH,
6718 asm, ".h", "", "", ".h", []> {
6719 bits<3> idx;
6720 let Inst{11} = idx{2};
6721 let Inst{21} = idx{1};
6722 let Inst{20} = idx{0};
6723 }
6724
6725 def v1i32_indexed : BaseSIMDIndexed<1, U, 1, 0b10, opc,
6726 FPR32Op, FPR32Op, V128, VectorIndexS,
6727 asm, ".s", "", "", ".s",
6728 [(set (i32 FPR32Op:$Rd),
6729 (OpNode FPR32Op:$Rn,
6730 (i32 (vector_extract (v4i32 V128:$Rm),
6731 VectorIndexS:$idx))))]> {
6732 bits<2> idx;
6733 let Inst{11} = idx{1};
6734 let Inst{21} = idx{0};
6735 }
6736}
6737
6738multiclass SIMDVectorIndexedHS<bit U, bits<4> opc, string asm,
6739 SDPatternOperator OpNode> {
6740 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc,
6741 V64, V64,
6742 V128_lo, VectorIndexH,
6743 asm, ".4h", ".4h", ".4h", ".h",
6744 [(set (v4i16 V64:$Rd),
6745 (OpNode (v4i16 V64:$Rn),
6746 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
6747 bits<3> idx;
6748 let Inst{11} = idx{2};
6749 let Inst{21} = idx{1};
6750 let Inst{20} = idx{0};
6751 }
6752
6753 def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc,
6754 V128, V128,
6755 V128_lo, VectorIndexH,
6756 asm, ".8h", ".8h", ".8h", ".h",
6757 [(set (v8i16 V128:$Rd),
6758 (OpNode (v8i16 V128:$Rn),
6759 (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
6760 bits<3> idx;
6761 let Inst{11} = idx{2};
6762 let Inst{21} = idx{1};
6763 let Inst{20} = idx{0};
6764 }
6765
6766 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc,
6767 V64, V64,
6768 V128, VectorIndexS,
6769 asm, ".2s", ".2s", ".2s", ".s",
6770 [(set (v2i32 V64:$Rd),
6771 (OpNode (v2i32 V64:$Rn),
6772 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
6773 bits<2> idx;
6774 let Inst{11} = idx{1};
6775 let Inst{21} = idx{0};
6776 }
6777
6778 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc,
6779 V128, V128,
6780 V128, VectorIndexS,
6781 asm, ".4s", ".4s", ".4s", ".s",
6782 [(set (v4i32 V128:$Rd),
6783 (OpNode (v4i32 V128:$Rn),
6784 (v4i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
6785 bits<2> idx;
6786 let Inst{11} = idx{1};
6787 let Inst{21} = idx{0};
6788 }
6789}
6790
6791multiclass SIMDVectorIndexedHSTied<bit U, bits<4> opc, string asm,
6792 SDPatternOperator OpNode> {
6793 def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc, V64, V64,
6794 V128_lo, VectorIndexH,
6795 asm, ".4h", ".4h", ".4h", ".h",
6796 [(set (v4i16 V64:$dst),
6797 (OpNode (v4i16 V64:$Rd),(v4i16 V64:$Rn),
6798 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
6799 bits<3> idx;
6800 let Inst{11} = idx{2};
6801 let Inst{21} = idx{1};
6802 let Inst{20} = idx{0};
6803 }
6804
6805 def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc,
6806 V128, V128,
6807 V128_lo, VectorIndexH,
6808 asm, ".8h", ".8h", ".8h", ".h",
6809 [(set (v8i16 V128:$dst),
6810 (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn),
6811 (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
6812 bits<3> idx;
6813 let Inst{11} = idx{2};
6814 let Inst{21} = idx{1};
6815 let Inst{20} = idx{0};
6816 }
6817
6818 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc,
6819 V64, V64,
6820 V128, VectorIndexS,
6821 asm, ".2s", ".2s", ".2s", ".s",
6822 [(set (v2i32 V64:$dst),
6823 (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn),
6824 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
6825 bits<2> idx;
6826 let Inst{11} = idx{1};
6827 let Inst{21} = idx{0};
6828 }
6829
6830 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc,
6831 V128, V128,
6832 V128, VectorIndexS,
6833 asm, ".4s", ".4s", ".4s", ".s",
6834 [(set (v4i32 V128:$dst),
6835 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn),
6836 (v4i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
6837 bits<2> idx;
6838 let Inst{11} = idx{1};
6839 let Inst{21} = idx{0};
6840 }
6841}
6842
6843multiclass SIMDIndexedLongSD<bit U, bits<4> opc, string asm,
6844 SDPatternOperator OpNode> {
6845 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc,
6846 V128, V64,
6847 V128_lo, VectorIndexH,
6848 asm, ".4s", ".4s", ".4h", ".h",
6849 [(set (v4i32 V128:$Rd),
6850 (OpNode (v4i16 V64:$Rn),
6851 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
6852 bits<3> idx;
6853 let Inst{11} = idx{2};
6854 let Inst{21} = idx{1};
6855 let Inst{20} = idx{0};
6856 }
6857
6858 def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc,
6859 V128, V128,
6860 V128_lo, VectorIndexH,
6861 asm#"2", ".4s", ".4s", ".8h", ".h",
6862 [(set (v4i32 V128:$Rd),
6863 (OpNode (extract_high_v8i16 V128:$Rn),
6864 (extract_high_v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm),
6865 VectorIndexH:$idx))))]> {
6866
6867 bits<3> idx;
6868 let Inst{11} = idx{2};
6869 let Inst{21} = idx{1};
6870 let Inst{20} = idx{0};
6871 }
6872
6873 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc,
6874 V128, V64,
6875 V128, VectorIndexS,
6876 asm, ".2d", ".2d", ".2s", ".s",
6877 [(set (v2i64 V128:$Rd),
6878 (OpNode (v2i32 V64:$Rn),
6879 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
6880 bits<2> idx;
6881 let Inst{11} = idx{1};
6882 let Inst{21} = idx{0};
6883 }
6884
6885 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc,
6886 V128, V128,
6887 V128, VectorIndexS,
6888 asm#"2", ".2d", ".2d", ".4s", ".s",
6889 [(set (v2i64 V128:$Rd),
6890 (OpNode (extract_high_v4i32 V128:$Rn),
6891 (extract_high_v4i32 (AArch64duplane32 (v4i32 V128:$Rm),
6892 VectorIndexS:$idx))))]> {
6893 bits<2> idx;
6894 let Inst{11} = idx{1};
6895 let Inst{21} = idx{0};
6896 }
6897
6898 def v1i32_indexed : BaseSIMDIndexed<1, U, 1, 0b01, opc,
6899 FPR32Op, FPR16Op, V128_lo, VectorIndexH,
6900 asm, ".h", "", "", ".h", []> {
6901 bits<3> idx;
6902 let Inst{11} = idx{2};
6903 let Inst{21} = idx{1};
6904 let Inst{20} = idx{0};
6905 }
6906
6907 def v1i64_indexed : BaseSIMDIndexed<1, U, 1, 0b10, opc,
6908 FPR64Op, FPR32Op, V128, VectorIndexS,
6909 asm, ".s", "", "", ".s", []> {
6910 bits<2> idx;
6911 let Inst{11} = idx{1};
6912 let Inst{21} = idx{0};
6913 }
6914}
6915
6916multiclass SIMDIndexedLongSQDMLXSDTied<bit U, bits<4> opc, string asm,
6917 SDPatternOperator Accum> {
6918 def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc,
6919 V128, V64,
6920 V128_lo, VectorIndexH,
6921 asm, ".4s", ".4s", ".4h", ".h",
6922 [(set (v4i32 V128:$dst),
6923 (Accum (v4i32 V128:$Rd),
6924 (v4i32 (int_aarch64_neon_sqdmull
6925 (v4i16 V64:$Rn),
6926 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm),
6927 VectorIndexH:$idx))))))]> {
6928 bits<3> idx;
6929 let Inst{11} = idx{2};
6930 let Inst{21} = idx{1};
6931 let Inst{20} = idx{0};
6932 }
6933
6934 // FIXME: it would be nice to use the scalar (v1i32) instruction here, but an
6935 // intermediate EXTRACT_SUBREG would be untyped.
6936 def : Pat<(i32 (Accum (i32 FPR32Op:$Rd),
6937 (i32 (vector_extract (v4i32
6938 (int_aarch64_neon_sqdmull (v4i16 V64:$Rn),
6939 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm),
6940 VectorIndexH:$idx)))),
6941 (i64 0))))),
6942 (EXTRACT_SUBREG
6943 (!cast<Instruction>(NAME # v4i16_indexed)
6944 (SUBREG_TO_REG (i32 0), FPR32Op:$Rd, ssub), V64:$Rn,
6945 V128_lo:$Rm, VectorIndexH:$idx),
6946 ssub)>;
6947
6948 def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc,
6949 V128, V128,
6950 V128_lo, VectorIndexH,
6951 asm#"2", ".4s", ".4s", ".8h", ".h",
6952 [(set (v4i32 V128:$dst),
6953 (Accum (v4i32 V128:$Rd),
6954 (v4i32 (int_aarch64_neon_sqdmull
6955 (extract_high_v8i16 V128:$Rn),
6956 (extract_high_v8i16
6957 (AArch64duplane16 (v8i16 V128_lo:$Rm),
6958 VectorIndexH:$idx))))))]> {
6959 bits<3> idx;
6960 let Inst{11} = idx{2};
6961 let Inst{21} = idx{1};
6962 let Inst{20} = idx{0};
6963 }
6964
6965 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc,
6966 V128, V64,
6967 V128, VectorIndexS,
6968 asm, ".2d", ".2d", ".2s", ".s",
6969 [(set (v2i64 V128:$dst),
6970 (Accum (v2i64 V128:$Rd),
6971 (v2i64 (int_aarch64_neon_sqdmull
6972 (v2i32 V64:$Rn),
6973 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm),
6974 VectorIndexS:$idx))))))]> {
6975 bits<2> idx;
6976 let Inst{11} = idx{1};
6977 let Inst{21} = idx{0};
6978 }
6979
6980 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc,
6981 V128, V128,
6982 V128, VectorIndexS,
6983 asm#"2", ".2d", ".2d", ".4s", ".s",
6984 [(set (v2i64 V128:$dst),
6985 (Accum (v2i64 V128:$Rd),
6986 (v2i64 (int_aarch64_neon_sqdmull
6987 (extract_high_v4i32 V128:$Rn),
6988 (extract_high_v4i32
6989 (AArch64duplane32 (v4i32 V128:$Rm),
6990 VectorIndexS:$idx))))))]> {
6991 bits<2> idx;
6992 let Inst{11} = idx{1};
6993 let Inst{21} = idx{0};
6994 }
6995
6996 def v1i32_indexed : BaseSIMDIndexedTied<1, U, 1, 0b01, opc,
6997 FPR32Op, FPR16Op, V128_lo, VectorIndexH,
6998 asm, ".h", "", "", ".h", []> {
6999 bits<3> idx;
7000 let Inst{11} = idx{2};
7001 let Inst{21} = idx{1};
7002 let Inst{20} = idx{0};
7003 }
7004
7005
7006 def v1i64_indexed : BaseSIMDIndexedTied<1, U, 1, 0b10, opc,
7007 FPR64Op, FPR32Op, V128, VectorIndexS,
7008 asm, ".s", "", "", ".s",
7009 [(set (i64 FPR64Op:$dst),
7010 (Accum (i64 FPR64Op:$Rd),
7011 (i64 (int_aarch64_neon_sqdmulls_scalar
7012 (i32 FPR32Op:$Rn),
7013 (i32 (vector_extract (v4i32 V128:$Rm),
7014 VectorIndexS:$idx))))))]> {
7015
7016 bits<2> idx;
7017 let Inst{11} = idx{1};
7018 let Inst{21} = idx{0};
7019 }
7020}
7021
7022multiclass SIMDVectorIndexedLongSD<bit U, bits<4> opc, string asm,
7023 SDPatternOperator OpNode> {
7024 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
7025 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc,
7026 V128, V64,
7027 V128_lo, VectorIndexH,
7028 asm, ".4s", ".4s", ".4h", ".h",
7029 [(set (v4i32 V128:$Rd),
7030 (OpNode (v4i16 V64:$Rn),
7031 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
7032 bits<3> idx;
7033 let Inst{11} = idx{2};
7034 let Inst{21} = idx{1};
7035 let Inst{20} = idx{0};
7036 }
7037
7038 def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc,
7039 V128, V128,
7040 V128_lo, VectorIndexH,
7041 asm#"2", ".4s", ".4s", ".8h", ".h",
7042 [(set (v4i32 V128:$Rd),
7043 (OpNode (extract_high_v8i16 V128:$Rn),
7044 (extract_high_v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm),
7045 VectorIndexH:$idx))))]> {
7046
7047 bits<3> idx;
7048 let Inst{11} = idx{2};
7049 let Inst{21} = idx{1};
7050 let Inst{20} = idx{0};
7051 }
7052
7053 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc,
7054 V128, V64,
7055 V128, VectorIndexS,
7056 asm, ".2d", ".2d", ".2s", ".s",
7057 [(set (v2i64 V128:$Rd),
7058 (OpNode (v2i32 V64:$Rn),
7059 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
7060 bits<2> idx;
7061 let Inst{11} = idx{1};
7062 let Inst{21} = idx{0};
7063 }
7064
7065 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc,
7066 V128, V128,
7067 V128, VectorIndexS,
7068 asm#"2", ".2d", ".2d", ".4s", ".s",
7069 [(set (v2i64 V128:$Rd),
7070 (OpNode (extract_high_v4i32 V128:$Rn),
7071 (extract_high_v4i32 (AArch64duplane32 (v4i32 V128:$Rm),
7072 VectorIndexS:$idx))))]> {
7073 bits<2> idx;
7074 let Inst{11} = idx{1};
7075 let Inst{21} = idx{0};
7076 }
7077 }
7078}
7079
7080multiclass SIMDVectorIndexedLongSDTied<bit U, bits<4> opc, string asm,
7081 SDPatternOperator OpNode> {
7082 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
7083 def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc,
7084 V128, V64,
7085 V128_lo, VectorIndexH,
7086 asm, ".4s", ".4s", ".4h", ".h",
7087 [(set (v4i32 V128:$dst),
7088 (OpNode (v4i32 V128:$Rd), (v4i16 V64:$Rn),
7089 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
7090 bits<3> idx;
7091 let Inst{11} = idx{2};
7092 let Inst{21} = idx{1};
7093 let Inst{20} = idx{0};
7094 }
7095
7096 def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc,
7097 V128, V128,
7098 V128_lo, VectorIndexH,
7099 asm#"2", ".4s", ".4s", ".8h", ".h",
7100 [(set (v4i32 V128:$dst),
7101 (OpNode (v4i32 V128:$Rd),
7102 (extract_high_v8i16 V128:$Rn),
7103 (extract_high_v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm),
7104 VectorIndexH:$idx))))]> {
7105 bits<3> idx;
7106 let Inst{11} = idx{2};
7107 let Inst{21} = idx{1};
7108 let Inst{20} = idx{0};
7109 }
7110
7111 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc,
7112 V128, V64,
7113 V128, VectorIndexS,
7114 asm, ".2d", ".2d", ".2s", ".s",
7115 [(set (v2i64 V128:$dst),
7116 (OpNode (v2i64 V128:$Rd), (v2i32 V64:$Rn),
7117 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
7118 bits<2> idx;
7119 let Inst{11} = idx{1};
7120 let Inst{21} = idx{0};
7121 }
7122
7123 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc,
7124 V128, V128,
7125 V128, VectorIndexS,
7126 asm#"2", ".2d", ".2d", ".4s", ".s",
7127 [(set (v2i64 V128:$dst),
7128 (OpNode (v2i64 V128:$Rd),
7129 (extract_high_v4i32 V128:$Rn),
7130 (extract_high_v4i32 (AArch64duplane32 (v4i32 V128:$Rm),
7131 VectorIndexS:$idx))))]> {
7132 bits<2> idx;
7133 let Inst{11} = idx{1};
7134 let Inst{21} = idx{0};
7135 }
7136 }
7137}
7138
7139//----------------------------------------------------------------------------
7140// AdvSIMD scalar shift by immediate
7141//----------------------------------------------------------------------------
7142
7143let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
7144class BaseSIMDScalarShift<bit U, bits<5> opc, bits<7> fixed_imm,
7145 RegisterClass regtype1, RegisterClass regtype2,
7146 Operand immtype, string asm, list<dag> pattern>
7147 : I<(outs regtype1:$Rd), (ins regtype2:$Rn, immtype:$imm),
7148 asm, "\t$Rd, $Rn, $imm", "", pattern>,
7149 Sched<[WriteV]> {
7150 bits<5> Rd;
7151 bits<5> Rn;
7152 bits<7> imm;
7153 let Inst{31-30} = 0b01;
7154 let Inst{29} = U;
7155 let Inst{28-23} = 0b111110;
7156 let Inst{22-16} = fixed_imm;
7157 let Inst{15-11} = opc;
7158 let Inst{10} = 1;
7159 let Inst{9-5} = Rn;
7160 let Inst{4-0} = Rd;
7161}
7162
7163let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
7164class BaseSIMDScalarShiftTied<bit U, bits<5> opc, bits<7> fixed_imm,
7165 RegisterClass regtype1, RegisterClass regtype2,
7166 Operand immtype, string asm, list<dag> pattern>
7167 : I<(outs regtype1:$dst), (ins regtype1:$Rd, regtype2:$Rn, immtype:$imm),
7168 asm, "\t$Rd, $Rn, $imm", "$Rd = $dst", pattern>,
7169 Sched<[WriteV]> {
7170 bits<5> Rd;
7171 bits<5> Rn;
7172 bits<7> imm;
7173 let Inst{31-30} = 0b01;
7174 let Inst{29} = U;
7175 let Inst{28-23} = 0b111110;
7176 let Inst{22-16} = fixed_imm;
7177 let Inst{15-11} = opc;
7178 let Inst{10} = 1;
7179 let Inst{9-5} = Rn;
7180 let Inst{4-0} = Rd;
7181}
7182
7183
7184multiclass SIMDScalarRShiftSD<bit U, bits<5> opc, string asm> {
7185 def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?},
7186 FPR32, FPR32, vecshiftR32, asm, []> {
7187 let Inst{20-16} = imm{4-0};
7188 }
7189
7190 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?},
7191 FPR64, FPR64, vecshiftR64, asm, []> {
7192 let Inst{21-16} = imm{5-0};
7193 }
7194}
7195
7196multiclass SIMDScalarRShiftD<bit U, bits<5> opc, string asm,
7197 SDPatternOperator OpNode> {
7198 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?},
7199 FPR64, FPR64, vecshiftR64, asm,
7200 [(set (i64 FPR64:$Rd),
7201 (OpNode (i64 FPR64:$Rn), (i32 vecshiftR64:$imm)))]> {
7202 let Inst{21-16} = imm{5-0};
7203 }
7204
7205 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rn), (i32 vecshiftR64:$imm))),
7206 (!cast<Instruction>(NAME # "d") FPR64:$Rn, vecshiftR64:$imm)>;
7207}
7208
7209multiclass SIMDScalarRShiftDTied<bit U, bits<5> opc, string asm,
7210 SDPatternOperator OpNode = null_frag> {
7211 def d : BaseSIMDScalarShiftTied<U, opc, {1,?,?,?,?,?,?},
7212 FPR64, FPR64, vecshiftR64, asm,
7213 [(set (i64 FPR64:$dst), (OpNode (i64 FPR64:$Rd), (i64 FPR64:$Rn),
7214 (i32 vecshiftR64:$imm)))]> {
7215 let Inst{21-16} = imm{5-0};
7216 }
7217
7218 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rd), (v1i64 FPR64:$Rn),
7219 (i32 vecshiftR64:$imm))),
7220 (!cast<Instruction>(NAME # "d") FPR64:$Rd, FPR64:$Rn,
7221 vecshiftR64:$imm)>;
7222}
7223
7224multiclass SIMDScalarLShiftD<bit U, bits<5> opc, string asm,
7225 SDPatternOperator OpNode> {
7226 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?},
7227 FPR64, FPR64, vecshiftL64, asm,
7228 [(set (v1i64 FPR64:$Rd),
7229 (OpNode (v1i64 FPR64:$Rn), (i32 vecshiftL64:$imm)))]> {
7230 let Inst{21-16} = imm{5-0};
7231 }
7232}
7233
7234let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
7235multiclass SIMDScalarLShiftDTied<bit U, bits<5> opc, string asm> {
7236 def d : BaseSIMDScalarShiftTied<U, opc, {1,?,?,?,?,?,?},
7237 FPR64, FPR64, vecshiftL64, asm, []> {
7238 let Inst{21-16} = imm{5-0};
7239 }
7240}
7241
7242let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
7243multiclass SIMDScalarRShiftBHS<bit U, bits<5> opc, string asm,
7244 SDPatternOperator OpNode = null_frag> {
7245 def b : BaseSIMDScalarShift<U, opc, {0,0,0,1,?,?,?},
7246 FPR8, FPR16, vecshiftR8, asm, []> {
7247 let Inst{18-16} = imm{2-0};
7248 }
7249
7250 def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?},
7251 FPR16, FPR32, vecshiftR16, asm, []> {
7252 let Inst{19-16} = imm{3-0};
7253 }
7254
7255 def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?},
7256 FPR32, FPR64, vecshiftR32, asm,
7257 [(set (i32 FPR32:$Rd), (OpNode (i64 FPR64:$Rn), vecshiftR32:$imm))]> {
7258 let Inst{20-16} = imm{4-0};
7259 }
7260}
7261
7262multiclass SIMDScalarLShiftBHSD<bit U, bits<5> opc, string asm,
7263 SDPatternOperator OpNode> {
7264 def b : BaseSIMDScalarShift<U, opc, {0,0,0,1,?,?,?},
7265 FPR8, FPR8, vecshiftL8, asm, []> {
7266 let Inst{18-16} = imm{2-0};
7267 }
7268
7269 def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?},
7270 FPR16, FPR16, vecshiftL16, asm, []> {
7271 let Inst{19-16} = imm{3-0};
7272 }
7273
7274 def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?},
7275 FPR32, FPR32, vecshiftL32, asm,
7276 [(set (i32 FPR32:$Rd), (OpNode (i32 FPR32:$Rn), (i32 vecshiftL32:$imm)))]> {
7277 let Inst{20-16} = imm{4-0};
7278 }
7279
7280 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?},
7281 FPR64, FPR64, vecshiftL64, asm,
7282 [(set (i64 FPR64:$Rd), (OpNode (i64 FPR64:$Rn), (i32 vecshiftL64:$imm)))]> {
7283 let Inst{21-16} = imm{5-0};
7284 }
7285
7286 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rn), (i32 vecshiftL64:$imm))),
7287 (!cast<Instruction>(NAME # "d") FPR64:$Rn, vecshiftL64:$imm)>;
7288}
7289
7290multiclass SIMDScalarRShiftBHSD<bit U, bits<5> opc, string asm> {
7291 def b : BaseSIMDScalarShift<U, opc, {0,0,0,1,?,?,?},
7292 FPR8, FPR8, vecshiftR8, asm, []> {
7293 let Inst{18-16} = imm{2-0};
7294 }
7295
7296 def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?},
7297 FPR16, FPR16, vecshiftR16, asm, []> {
7298 let Inst{19-16} = imm{3-0};
7299 }
7300
7301 def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?},
7302 FPR32, FPR32, vecshiftR32, asm, []> {
7303 let Inst{20-16} = imm{4-0};
7304 }
7305
7306 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?},
7307 FPR64, FPR64, vecshiftR64, asm, []> {
7308 let Inst{21-16} = imm{5-0};
7309 }
7310}
7311
7312//----------------------------------------------------------------------------
7313// AdvSIMD vector x indexed element
7314//----------------------------------------------------------------------------
7315
7316let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
7317class BaseSIMDVectorShift<bit Q, bit U, bits<5> opc, bits<7> fixed_imm,
7318 RegisterOperand dst_reg, RegisterOperand src_reg,
7319 Operand immtype,
7320 string asm, string dst_kind, string src_kind,
7321 list<dag> pattern>
7322 : I<(outs dst_reg:$Rd), (ins src_reg:$Rn, immtype:$imm),
7323 asm, "{\t$Rd" # dst_kind # ", $Rn" # src_kind # ", $imm" #
7324 "|" # dst_kind # "\t$Rd, $Rn, $imm}", "", pattern>,
7325 Sched<[WriteV]> {
7326 bits<5> Rd;
7327 bits<5> Rn;
7328 let Inst{31} = 0;
7329 let Inst{30} = Q;
7330 let Inst{29} = U;
7331 let Inst{28-23} = 0b011110;
7332 let Inst{22-16} = fixed_imm;
7333 let Inst{15-11} = opc;
7334 let Inst{10} = 1;
7335 let Inst{9-5} = Rn;
7336 let Inst{4-0} = Rd;
7337}
7338
7339let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
7340class BaseSIMDVectorShiftTied<bit Q, bit U, bits<5> opc, bits<7> fixed_imm,
7341 RegisterOperand vectype1, RegisterOperand vectype2,
7342 Operand immtype,
7343 string asm, string dst_kind, string src_kind,
7344 list<dag> pattern>
7345 : I<(outs vectype1:$dst), (ins vectype1:$Rd, vectype2:$Rn, immtype:$imm),
7346 asm, "{\t$Rd" # dst_kind # ", $Rn" # src_kind # ", $imm" #
7347 "|" # dst_kind # "\t$Rd, $Rn, $imm}", "$Rd = $dst", pattern>,
7348 Sched<[WriteV]> {
7349 bits<5> Rd;
7350 bits<5> Rn;
7351 let Inst{31} = 0;
7352 let Inst{30} = Q;
7353 let Inst{29} = U;
7354 let Inst{28-23} = 0b011110;
7355 let Inst{22-16} = fixed_imm;
7356 let Inst{15-11} = opc;
7357 let Inst{10} = 1;
7358 let Inst{9-5} = Rn;
7359 let Inst{4-0} = Rd;
7360}
7361
7362multiclass SIMDVectorRShiftSD<bit U, bits<5> opc, string asm,
7363 Intrinsic OpNode> {
7364 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?},
7365 V64, V64, vecshiftR32,
7366 asm, ".2s", ".2s",
7367 [(set (v2i32 V64:$Rd), (OpNode (v2f32 V64:$Rn), (i32 imm:$imm)))]> {
7368 bits<5> imm;
7369 let Inst{20-16} = imm;
7370 }
7371
7372 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?},
7373 V128, V128, vecshiftR32,
7374 asm, ".4s", ".4s",
7375 [(set (v4i32 V128:$Rd), (OpNode (v4f32 V128:$Rn), (i32 imm:$imm)))]> {
7376 bits<5> imm;
7377 let Inst{20-16} = imm;
7378 }
7379
7380 def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?},
7381 V128, V128, vecshiftR64,
7382 asm, ".2d", ".2d",
7383 [(set (v2i64 V128:$Rd), (OpNode (v2f64 V128:$Rn), (i32 imm:$imm)))]> {
7384 bits<6> imm;
7385 let Inst{21-16} = imm;
7386 }
7387}
7388
7389multiclass SIMDVectorRShiftSDToFP<bit U, bits<5> opc, string asm,
7390 Intrinsic OpNode> {
7391 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?},
7392 V64, V64, vecshiftR32,
7393 asm, ".2s", ".2s",
7394 [(set (v2f32 V64:$Rd), (OpNode (v2i32 V64:$Rn), (i32 imm:$imm)))]> {
7395 bits<5> imm;
7396 let Inst{20-16} = imm;
7397 }
7398
7399 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?},
7400 V128, V128, vecshiftR32,
7401 asm, ".4s", ".4s",
7402 [(set (v4f32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (i32 imm:$imm)))]> {
7403 bits<5> imm;
7404 let Inst{20-16} = imm;
7405 }
7406
7407 def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?},
7408 V128, V128, vecshiftR64,
7409 asm, ".2d", ".2d",
7410 [(set (v2f64 V128:$Rd), (OpNode (v2i64 V128:$Rn), (i32 imm:$imm)))]> {
7411 bits<6> imm;
7412 let Inst{21-16} = imm;
7413 }
7414}
7415
7416multiclass SIMDVectorRShiftNarrowBHS<bit U, bits<5> opc, string asm,
7417 SDPatternOperator OpNode> {
7418 def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?},
7419 V64, V128, vecshiftR16Narrow,
7420 asm, ".8b", ".8h",
7421 [(set (v8i8 V64:$Rd), (OpNode (v8i16 V128:$Rn), vecshiftR16Narrow:$imm))]> {
7422 bits<3> imm;
7423 let Inst{18-16} = imm;
7424 }
7425
7426 def v16i8_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,0,1,?,?,?},
7427 V128, V128, vecshiftR16Narrow,
7428 asm#"2", ".16b", ".8h", []> {
7429 bits<3> imm;
7430 let Inst{18-16} = imm;
7431 let hasSideEffects = 0;
7432 }
7433
7434 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?},
7435 V64, V128, vecshiftR32Narrow,
7436 asm, ".4h", ".4s",
7437 [(set (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn), vecshiftR32Narrow:$imm))]> {
7438 bits<4> imm;
7439 let Inst{19-16} = imm;
7440 }
7441
7442 def v8i16_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,1,?,?,?,?},
7443 V128, V128, vecshiftR32Narrow,
7444 asm#"2", ".8h", ".4s", []> {
7445 bits<4> imm;
7446 let Inst{19-16} = imm;
7447 let hasSideEffects = 0;
7448 }
7449
7450 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?},
7451 V64, V128, vecshiftR64Narrow,
7452 asm, ".2s", ".2d",
7453 [(set (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn), vecshiftR64Narrow:$imm))]> {
7454 bits<5> imm;
7455 let Inst{20-16} = imm;
7456 }
7457
7458 def v4i32_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,1,?,?,?,?,?},
7459 V128, V128, vecshiftR64Narrow,
7460 asm#"2", ".4s", ".2d", []> {
7461 bits<5> imm;
7462 let Inst{20-16} = imm;
7463 let hasSideEffects = 0;
7464 }
7465
7466 // TableGen doesn't like patters w/ INSERT_SUBREG on the instructions
7467 // themselves, so put them here instead.
7468
7469 // Patterns involving what's effectively an insert high and a normal
7470 // intrinsic, represented by CONCAT_VECTORS.
7471 def : Pat<(concat_vectors (v8i8 V64:$Rd),(OpNode (v8i16 V128:$Rn),
7472 vecshiftR16Narrow:$imm)),
7473 (!cast<Instruction>(NAME # "v16i8_shift")
7474 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub),
7475 V128:$Rn, vecshiftR16Narrow:$imm)>;
7476 def : Pat<(concat_vectors (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn),
7477 vecshiftR32Narrow:$imm)),
7478 (!cast<Instruction>(NAME # "v8i16_shift")
7479 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub),
7480 V128:$Rn, vecshiftR32Narrow:$imm)>;
7481 def : Pat<(concat_vectors (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn),
7482 vecshiftR64Narrow:$imm)),
7483 (!cast<Instruction>(NAME # "v4i32_shift")
7484 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub),
7485 V128:$Rn, vecshiftR64Narrow:$imm)>;
7486}
7487
7488multiclass SIMDVectorLShiftBHSD<bit U, bits<5> opc, string asm,
7489 SDPatternOperator OpNode> {
7490 def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?},
7491 V64, V64, vecshiftL8,
7492 asm, ".8b", ".8b",
7493 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn),
7494 (i32 vecshiftL8:$imm)))]> {
7495 bits<3> imm;
7496 let Inst{18-16} = imm;
7497 }
7498
7499 def v16i8_shift : BaseSIMDVectorShift<1, U, opc, {0,0,0,1,?,?,?},
7500 V128, V128, vecshiftL8,
7501 asm, ".16b", ".16b",
7502 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn),
7503 (i32 vecshiftL8:$imm)))]> {
7504 bits<3> imm;
7505 let Inst{18-16} = imm;
7506 }
7507
7508 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?},
7509 V64, V64, vecshiftL16,
7510 asm, ".4h", ".4h",
7511 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn),
7512 (i32 vecshiftL16:$imm)))]> {
7513 bits<4> imm;
7514 let Inst{19-16} = imm;
7515 }
7516
7517 def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?},
7518 V128, V128, vecshiftL16,
7519 asm, ".8h", ".8h",
7520 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn),
7521 (i32 vecshiftL16:$imm)))]> {
7522 bits<4> imm;
7523 let Inst{19-16} = imm;
7524 }
7525
7526 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?},
7527 V64, V64, vecshiftL32,
7528 asm, ".2s", ".2s",
7529 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn),
7530 (i32 vecshiftL32:$imm)))]> {
7531 bits<5> imm;
7532 let Inst{20-16} = imm;
7533 }
7534
7535 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?},
7536 V128, V128, vecshiftL32,
7537 asm, ".4s", ".4s",
7538 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn),
7539 (i32 vecshiftL32:$imm)))]> {
7540 bits<5> imm;
7541 let Inst{20-16} = imm;
7542 }
7543
7544 def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?},
7545 V128, V128, vecshiftL64,
7546 asm, ".2d", ".2d",
7547 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn),
7548 (i32 vecshiftL64:$imm)))]> {
7549 bits<6> imm;
7550 let Inst{21-16} = imm;
7551 }
7552}
7553
7554multiclass SIMDVectorRShiftBHSD<bit U, bits<5> opc, string asm,
7555 SDPatternOperator OpNode> {
7556 def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?},
7557 V64, V64, vecshiftR8,
7558 asm, ".8b", ".8b",
7559 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn),
7560 (i32 vecshiftR8:$imm)))]> {
7561 bits<3> imm;
7562 let Inst{18-16} = imm;
7563 }
7564
7565 def v16i8_shift : BaseSIMDVectorShift<1, U, opc, {0,0,0,1,?,?,?},
7566 V128, V128, vecshiftR8,
7567 asm, ".16b", ".16b",
7568 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn),
7569 (i32 vecshiftR8:$imm)))]> {
7570 bits<3> imm;
7571 let Inst{18-16} = imm;
7572 }
7573
7574 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?},
7575 V64, V64, vecshiftR16,
7576 asm, ".4h", ".4h",
7577 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn),
7578 (i32 vecshiftR16:$imm)))]> {
7579 bits<4> imm;
7580 let Inst{19-16} = imm;
7581 }
7582
7583 def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?},
7584 V128, V128, vecshiftR16,
7585 asm, ".8h", ".8h",
7586 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn),
7587 (i32 vecshiftR16:$imm)))]> {
7588 bits<4> imm;
7589 let Inst{19-16} = imm;
7590 }
7591
7592 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?},
7593 V64, V64, vecshiftR32,
7594 asm, ".2s", ".2s",
7595 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn),
7596 (i32 vecshiftR32:$imm)))]> {
7597 bits<5> imm;
7598 let Inst{20-16} = imm;
7599 }
7600
7601 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?},
7602 V128, V128, vecshiftR32,
7603 asm, ".4s", ".4s",
7604 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn),
7605 (i32 vecshiftR32:$imm)))]> {
7606 bits<5> imm;
7607 let Inst{20-16} = imm;
7608 }
7609
7610 def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?},
7611 V128, V128, vecshiftR64,
7612 asm, ".2d", ".2d",
7613 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn),
7614 (i32 vecshiftR64:$imm)))]> {
7615 bits<6> imm;
7616 let Inst{21-16} = imm;
7617 }
7618}
7619
7620let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
7621multiclass SIMDVectorRShiftBHSDTied<bit U, bits<5> opc, string asm,
7622 SDPatternOperator OpNode = null_frag> {
7623 def v8i8_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,0,1,?,?,?},
7624 V64, V64, vecshiftR8, asm, ".8b", ".8b",
7625 [(set (v8i8 V64:$dst),
7626 (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn),
7627 (i32 vecshiftR8:$imm)))]> {
7628 bits<3> imm;
7629 let Inst{18-16} = imm;
7630 }
7631
7632 def v16i8_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,0,1,?,?,?},
7633 V128, V128, vecshiftR8, asm, ".16b", ".16b",
7634 [(set (v16i8 V128:$dst),
7635 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn),
7636 (i32 vecshiftR8:$imm)))]> {
7637 bits<3> imm;
7638 let Inst{18-16} = imm;
7639 }
7640
7641 def v4i16_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,1,?,?,?,?},
7642 V64, V64, vecshiftR16, asm, ".4h", ".4h",
7643 [(set (v4i16 V64:$dst),
7644 (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn),
7645 (i32 vecshiftR16:$imm)))]> {
7646 bits<4> imm;
7647 let Inst{19-16} = imm;
7648 }
7649
7650 def v8i16_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,1,?,?,?,?},
7651 V128, V128, vecshiftR16, asm, ".8h", ".8h",
7652 [(set (v8i16 V128:$dst),
7653 (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn),
7654 (i32 vecshiftR16:$imm)))]> {
7655 bits<4> imm;
7656 let Inst{19-16} = imm;
7657 }
7658
7659 def v2i32_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,1,?,?,?,?,?},
7660 V64, V64, vecshiftR32, asm, ".2s", ".2s",
7661 [(set (v2i32 V64:$dst),
7662 (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn),
7663 (i32 vecshiftR32:$imm)))]> {
7664 bits<5> imm;
7665 let Inst{20-16} = imm;
7666 }
7667
7668 def v4i32_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,1,?,?,?,?,?},
7669 V128, V128, vecshiftR32, asm, ".4s", ".4s",
7670 [(set (v4i32 V128:$dst),
7671 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn),
7672 (i32 vecshiftR32:$imm)))]> {
7673 bits<5> imm;
7674 let Inst{20-16} = imm;
7675 }
7676
7677 def v2i64_shift : BaseSIMDVectorShiftTied<1, U, opc, {1,?,?,?,?,?,?},
7678 V128, V128, vecshiftR64,
7679 asm, ".2d", ".2d", [(set (v2i64 V128:$dst),
7680 (OpNode (v2i64 V128:$Rd), (v2i64 V128:$Rn),
7681 (i32 vecshiftR64:$imm)))]> {
7682 bits<6> imm;
7683 let Inst{21-16} = imm;
7684 }
7685}
7686
7687multiclass SIMDVectorLShiftBHSDTied<bit U, bits<5> opc, string asm,
7688 SDPatternOperator OpNode = null_frag> {
7689 def v8i8_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,0,1,?,?,?},
7690 V64, V64, vecshiftL8,
7691 asm, ".8b", ".8b",
7692 [(set (v8i8 V64:$dst),
7693 (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn),
7694 (i32 vecshiftL8:$imm)))]> {
7695 bits<3> imm;
7696 let Inst{18-16} = imm;
7697 }
7698
7699 def v16i8_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,0,1,?,?,?},
7700 V128, V128, vecshiftL8,
7701 asm, ".16b", ".16b",
7702 [(set (v16i8 V128:$dst),
7703 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn),
7704 (i32 vecshiftL8:$imm)))]> {
7705 bits<3> imm;
7706 let Inst{18-16} = imm;
7707 }
7708
7709 def v4i16_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,1,?,?,?,?},
7710 V64, V64, vecshiftL16,
7711 asm, ".4h", ".4h",
7712 [(set (v4i16 V64:$dst),
7713 (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn),
7714 (i32 vecshiftL16:$imm)))]> {
7715 bits<4> imm;
7716 let Inst{19-16} = imm;
7717 }
7718
7719 def v8i16_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,1,?,?,?,?},
7720 V128, V128, vecshiftL16,
7721 asm, ".8h", ".8h",
7722 [(set (v8i16 V128:$dst),
7723 (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn),
7724 (i32 vecshiftL16:$imm)))]> {
7725 bits<4> imm;
7726 let Inst{19-16} = imm;
7727 }
7728
7729 def v2i32_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,1,?,?,?,?,?},
7730 V64, V64, vecshiftL32,
7731 asm, ".2s", ".2s",
7732 [(set (v2i32 V64:$dst),
7733 (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn),
7734 (i32 vecshiftL32:$imm)))]> {
7735 bits<5> imm;
7736 let Inst{20-16} = imm;
7737 }
7738
7739 def v4i32_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,1,?,?,?,?,?},
7740 V128, V128, vecshiftL32,
7741 asm, ".4s", ".4s",
7742 [(set (v4i32 V128:$dst),
7743 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn),
7744 (i32 vecshiftL32:$imm)))]> {
7745 bits<5> imm;
7746 let Inst{20-16} = imm;
7747 }
7748
7749 def v2i64_shift : BaseSIMDVectorShiftTied<1, U, opc, {1,?,?,?,?,?,?},
7750 V128, V128, vecshiftL64,
7751 asm, ".2d", ".2d",
7752 [(set (v2i64 V128:$dst),
7753 (OpNode (v2i64 V128:$Rd), (v2i64 V128:$Rn),
7754 (i32 vecshiftL64:$imm)))]> {
7755 bits<6> imm;
7756 let Inst{21-16} = imm;
7757 }
7758}
7759
7760multiclass SIMDVectorLShiftLongBHSD<bit U, bits<5> opc, string asm,
7761 SDPatternOperator OpNode> {
7762 def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?},
7763 V128, V64, vecshiftL8, asm, ".8h", ".8b",
7764 [(set (v8i16 V128:$Rd), (OpNode (v8i8 V64:$Rn), vecshiftL8:$imm))]> {
7765 bits<3> imm;
7766 let Inst{18-16} = imm;
7767 }
7768
7769 def v16i8_shift : BaseSIMDVectorShift<1, U, opc, {0,0,0,1,?,?,?},
7770 V128, V128, vecshiftL8,
7771 asm#"2", ".8h", ".16b",
7772 [(set (v8i16 V128:$Rd),
7773 (OpNode (extract_high_v16i8 V128:$Rn), vecshiftL8:$imm))]> {
7774 bits<3> imm;
7775 let Inst{18-16} = imm;
7776 }
7777
7778 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?},
7779 V128, V64, vecshiftL16, asm, ".4s", ".4h",
7780 [(set (v4i32 V128:$Rd), (OpNode (v4i16 V64:$Rn), vecshiftL16:$imm))]> {
7781 bits<4> imm;
7782 let Inst{19-16} = imm;
7783 }
7784
7785 def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?},
7786 V128, V128, vecshiftL16,
7787 asm#"2", ".4s", ".8h",
7788 [(set (v4i32 V128:$Rd),
7789 (OpNode (extract_high_v8i16 V128:$Rn), vecshiftL16:$imm))]> {
7790
7791 bits<4> imm;
7792 let Inst{19-16} = imm;
7793 }
7794
7795 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?},
7796 V128, V64, vecshiftL32, asm, ".2d", ".2s",
7797 [(set (v2i64 V128:$Rd), (OpNode (v2i32 V64:$Rn), vecshiftL32:$imm))]> {
7798 bits<5> imm;
7799 let Inst{20-16} = imm;
7800 }
7801
7802 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?},
7803 V128, V128, vecshiftL32,
7804 asm#"2", ".2d", ".4s",
7805 [(set (v2i64 V128:$Rd),
7806 (OpNode (extract_high_v4i32 V128:$Rn), vecshiftL32:$imm))]> {
7807 bits<5> imm;
7808 let Inst{20-16} = imm;
7809 }
7810}
7811
7812
7813//---
7814// Vector load/store
7815//---
7816// SIMD ldX/stX no-index memory references don't allow the optional
7817// ", #0" constant and handle post-indexing explicitly, so we use
7818// a more specialized parse method for them. Otherwise, it's the same as
7819// the general GPR64sp handling.
7820
7821class BaseSIMDLdSt<bit Q, bit L, bits<4> opcode, bits<2> size,
7822 string asm, dag oops, dag iops, list<dag> pattern>
7823 : I<oops, iops, asm, "\t$Vt, [$Rn]", "", pattern> {
7824 bits<5> Vt;
7825 bits<5> Rn;
7826 let Inst{31} = 0;
7827 let Inst{30} = Q;
7828 let Inst{29-23} = 0b0011000;
7829 let Inst{22} = L;
7830 let Inst{21-16} = 0b000000;
7831 let Inst{15-12} = opcode;
7832 let Inst{11-10} = size;
7833 let Inst{9-5} = Rn;
7834 let Inst{4-0} = Vt;
7835}
7836
7837class BaseSIMDLdStPost<bit Q, bit L, bits<4> opcode, bits<2> size,
7838 string asm, dag oops, dag iops>
7839 : I<oops, iops, asm, "\t$Vt, [$Rn], $Xm", "$Rn = $wback", []> {
7840 bits<5> Vt;
7841 bits<5> Rn;
7842 bits<5> Xm;
7843 let Inst{31} = 0;
7844 let Inst{30} = Q;
7845 let Inst{29-23} = 0b0011001;
7846 let Inst{22} = L;
7847 let Inst{21} = 0;
7848 let Inst{20-16} = Xm;
7849 let Inst{15-12} = opcode;
7850 let Inst{11-10} = size;
7851 let Inst{9-5} = Rn;
7852 let Inst{4-0} = Vt;
7853}
7854
7855// The immediate form of AdvSIMD post-indexed addressing is encoded with
7856// register post-index addressing from the zero register.
7857multiclass SIMDLdStAliases<string asm, string layout, string Count,
7858 int Offset, int Size> {
7859 // E.g. "ld1 { v0.8b, v1.8b }, [x1], #16"
7860 // "ld1\t$Vt, [$Rn], #16"
7861 // may get mapped to
7862 // (LD1Twov8b_POST VecListTwo8b:$Vt, GPR64sp:$Rn, XZR)
7863 def : InstAlias<asm # "\t$Vt, [$Rn], #" # Offset,
7864 (!cast<Instruction>(NAME # Count # "v" # layout # "_POST")
7865 GPR64sp:$Rn,
7866 !cast<RegisterOperand>("VecList" # Count # layout):$Vt,
7867 XZR), 1>;
7868
7869 // E.g. "ld1.8b { v0, v1 }, [x1], #16"
7870 // "ld1.8b\t$Vt, [$Rn], #16"
7871 // may get mapped to
7872 // (LD1Twov8b_POST VecListTwo64:$Vt, GPR64sp:$Rn, XZR)
7873 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], #" # Offset,
7874 (!cast<Instruction>(NAME # Count # "v" # layout # "_POST")
7875 GPR64sp:$Rn,
7876 !cast<RegisterOperand>("VecList" # Count # Size):$Vt,
7877 XZR), 0>;
7878
7879 // E.g. "ld1.8b { v0, v1 }, [x1]"
7880 // "ld1\t$Vt, [$Rn]"
7881 // may get mapped to
7882 // (LD1Twov8b VecListTwo64:$Vt, GPR64sp:$Rn)
7883 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn]",
7884 (!cast<Instruction>(NAME # Count # "v" # layout)
7885 !cast<RegisterOperand>("VecList" # Count # Size):$Vt,
7886 GPR64sp:$Rn), 0>;
7887
7888 // E.g. "ld1.8b { v0, v1 }, [x1], x2"
7889 // "ld1\t$Vt, [$Rn], $Xm"
7890 // may get mapped to
7891 // (LD1Twov8b_POST VecListTwo64:$Vt, GPR64sp:$Rn, GPR64pi8:$Xm)
7892 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], $Xm",
7893 (!cast<Instruction>(NAME # Count # "v" # layout # "_POST")
7894 GPR64sp:$Rn,
7895 !cast<RegisterOperand>("VecList" # Count # Size):$Vt,
7896 !cast<RegisterOperand>("GPR64pi" # Offset):$Xm), 0>;
7897}
7898
7899multiclass BaseSIMDLdN<string Count, string asm, string veclist, int Offset128,
7900 int Offset64, bits<4> opcode> {
7901 let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in {
7902 def v16b: BaseSIMDLdSt<1, 1, opcode, 0b00, asm,
7903 (outs !cast<RegisterOperand>(veclist # "16b"):$Vt),
7904 (ins GPR64sp:$Rn), []>;
7905 def v8h : BaseSIMDLdSt<1, 1, opcode, 0b01, asm,
7906 (outs !cast<RegisterOperand>(veclist # "8h"):$Vt),
7907 (ins GPR64sp:$Rn), []>;
7908 def v4s : BaseSIMDLdSt<1, 1, opcode, 0b10, asm,
7909 (outs !cast<RegisterOperand>(veclist # "4s"):$Vt),
7910 (ins GPR64sp:$Rn), []>;
7911 def v2d : BaseSIMDLdSt<1, 1, opcode, 0b11, asm,
7912 (outs !cast<RegisterOperand>(veclist # "2d"):$Vt),
7913 (ins GPR64sp:$Rn), []>;
7914 def v8b : BaseSIMDLdSt<0, 1, opcode, 0b00, asm,
7915 (outs !cast<RegisterOperand>(veclist # "8b"):$Vt),
7916 (ins GPR64sp:$Rn), []>;
7917 def v4h : BaseSIMDLdSt<0, 1, opcode, 0b01, asm,
7918 (outs !cast<RegisterOperand>(veclist # "4h"):$Vt),
7919 (ins GPR64sp:$Rn), []>;
7920 def v2s : BaseSIMDLdSt<0, 1, opcode, 0b10, asm,
7921 (outs !cast<RegisterOperand>(veclist # "2s"):$Vt),
7922 (ins GPR64sp:$Rn), []>;
7923
7924
7925 def v16b_POST: BaseSIMDLdStPost<1, 1, opcode, 0b00, asm,
7926 (outs GPR64sp:$wback,
7927 !cast<RegisterOperand>(veclist # "16b"):$Vt),
7928 (ins GPR64sp:$Rn,
7929 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
7930 def v8h_POST : BaseSIMDLdStPost<1, 1, opcode, 0b01, asm,
7931 (outs GPR64sp:$wback,
7932 !cast<RegisterOperand>(veclist # "8h"):$Vt),
7933 (ins GPR64sp:$Rn,
7934 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
7935 def v4s_POST : BaseSIMDLdStPost<1, 1, opcode, 0b10, asm,
7936 (outs GPR64sp:$wback,
7937 !cast<RegisterOperand>(veclist # "4s"):$Vt),
7938 (ins GPR64sp:$Rn,
7939 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
7940 def v2d_POST : BaseSIMDLdStPost<1, 1, opcode, 0b11, asm,
7941 (outs GPR64sp:$wback,
7942 !cast<RegisterOperand>(veclist # "2d"):$Vt),
7943 (ins GPR64sp:$Rn,
7944 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
7945 def v8b_POST : BaseSIMDLdStPost<0, 1, opcode, 0b00, asm,
7946 (outs GPR64sp:$wback,
7947 !cast<RegisterOperand>(veclist # "8b"):$Vt),
7948 (ins GPR64sp:$Rn,
7949 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
7950 def v4h_POST : BaseSIMDLdStPost<0, 1, opcode, 0b01, asm,
7951 (outs GPR64sp:$wback,
7952 !cast<RegisterOperand>(veclist # "4h"):$Vt),
7953 (ins GPR64sp:$Rn,
7954 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
7955 def v2s_POST : BaseSIMDLdStPost<0, 1, opcode, 0b10, asm,
7956 (outs GPR64sp:$wback,
7957 !cast<RegisterOperand>(veclist # "2s"):$Vt),
7958 (ins GPR64sp:$Rn,
7959 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
7960 }
7961
7962 defm : SIMDLdStAliases<asm, "16b", Count, Offset128, 128>;
7963 defm : SIMDLdStAliases<asm, "8h", Count, Offset128, 128>;
7964 defm : SIMDLdStAliases<asm, "4s", Count, Offset128, 128>;
7965 defm : SIMDLdStAliases<asm, "2d", Count, Offset128, 128>;
7966 defm : SIMDLdStAliases<asm, "8b", Count, Offset64, 64>;
7967 defm : SIMDLdStAliases<asm, "4h", Count, Offset64, 64>;
7968 defm : SIMDLdStAliases<asm, "2s", Count, Offset64, 64>;
7969}
7970
7971// Only ld1/st1 has a v1d version.
7972multiclass BaseSIMDStN<string Count, string asm, string veclist, int Offset128,
7973 int Offset64, bits<4> opcode> {
7974 let hasSideEffects = 0, mayStore = 1, mayLoad = 0 in {
7975 def v16b : BaseSIMDLdSt<1, 0, opcode, 0b00, asm, (outs),
7976 (ins !cast<RegisterOperand>(veclist # "16b"):$Vt,
7977 GPR64sp:$Rn), []>;
7978 def v8h : BaseSIMDLdSt<1, 0, opcode, 0b01, asm, (outs),
7979 (ins !cast<RegisterOperand>(veclist # "8h"):$Vt,
7980 GPR64sp:$Rn), []>;
7981 def v4s : BaseSIMDLdSt<1, 0, opcode, 0b10, asm, (outs),
7982 (ins !cast<RegisterOperand>(veclist # "4s"):$Vt,
7983 GPR64sp:$Rn), []>;
7984 def v2d : BaseSIMDLdSt<1, 0, opcode, 0b11, asm, (outs),
7985 (ins !cast<RegisterOperand>(veclist # "2d"):$Vt,
7986 GPR64sp:$Rn), []>;
7987 def v8b : BaseSIMDLdSt<0, 0, opcode, 0b00, asm, (outs),
7988 (ins !cast<RegisterOperand>(veclist # "8b"):$Vt,
7989 GPR64sp:$Rn), []>;
7990 def v4h : BaseSIMDLdSt<0, 0, opcode, 0b01, asm, (outs),
7991 (ins !cast<RegisterOperand>(veclist # "4h"):$Vt,
7992 GPR64sp:$Rn), []>;
7993 def v2s : BaseSIMDLdSt<0, 0, opcode, 0b10, asm, (outs),
7994 (ins !cast<RegisterOperand>(veclist # "2s"):$Vt,
7995 GPR64sp:$Rn), []>;
7996
7997 def v16b_POST : BaseSIMDLdStPost<1, 0, opcode, 0b00, asm,
7998 (outs GPR64sp:$wback),
7999 (ins !cast<RegisterOperand>(veclist # "16b"):$Vt,
8000 GPR64sp:$Rn,
8001 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
8002 def v8h_POST : BaseSIMDLdStPost<1, 0, opcode, 0b01, asm,
8003 (outs GPR64sp:$wback),
8004 (ins !cast<RegisterOperand>(veclist # "8h"):$Vt,
8005 GPR64sp:$Rn,
8006 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
8007 def v4s_POST : BaseSIMDLdStPost<1, 0, opcode, 0b10, asm,
8008 (outs GPR64sp:$wback),
8009 (ins !cast<RegisterOperand>(veclist # "4s"):$Vt,
8010 GPR64sp:$Rn,
8011 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
8012 def v2d_POST : BaseSIMDLdStPost<1, 0, opcode, 0b11, asm,
8013 (outs GPR64sp:$wback),
8014 (ins !cast<RegisterOperand>(veclist # "2d"):$Vt,
8015 GPR64sp:$Rn,
8016 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
8017 def v8b_POST : BaseSIMDLdStPost<0, 0, opcode, 0b00, asm,
8018 (outs GPR64sp:$wback),
8019 (ins !cast<RegisterOperand>(veclist # "8b"):$Vt,
8020 GPR64sp:$Rn,
8021 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
8022 def v4h_POST : BaseSIMDLdStPost<0, 0, opcode, 0b01, asm,
8023 (outs GPR64sp:$wback),
8024 (ins !cast<RegisterOperand>(veclist # "4h"):$Vt,
8025 GPR64sp:$Rn,
8026 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
8027 def v2s_POST : BaseSIMDLdStPost<0, 0, opcode, 0b10, asm,
8028 (outs GPR64sp:$wback),
8029 (ins !cast<RegisterOperand>(veclist # "2s"):$Vt,
8030 GPR64sp:$Rn,
8031 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
8032 }
8033
8034 defm : SIMDLdStAliases<asm, "16b", Count, Offset128, 128>;
8035 defm : SIMDLdStAliases<asm, "8h", Count, Offset128, 128>;
8036 defm : SIMDLdStAliases<asm, "4s", Count, Offset128, 128>;
8037 defm : SIMDLdStAliases<asm, "2d", Count, Offset128, 128>;
8038 defm : SIMDLdStAliases<asm, "8b", Count, Offset64, 64>;
8039 defm : SIMDLdStAliases<asm, "4h", Count, Offset64, 64>;
8040 defm : SIMDLdStAliases<asm, "2s", Count, Offset64, 64>;
8041}
8042
8043multiclass BaseSIMDLd1<string Count, string asm, string veclist,
8044 int Offset128, int Offset64, bits<4> opcode>
8045 : BaseSIMDLdN<Count, asm, veclist, Offset128, Offset64, opcode> {
8046
8047 // LD1 instructions have extra "1d" variants.
8048 let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in {
8049 def v1d : BaseSIMDLdSt<0, 1, opcode, 0b11, asm,
8050 (outs !cast<RegisterOperand>(veclist # "1d"):$Vt),
8051 (ins GPR64sp:$Rn), []>;
8052
8053 def v1d_POST : BaseSIMDLdStPost<0, 1, opcode, 0b11, asm,
8054 (outs GPR64sp:$wback,
8055 !cast<RegisterOperand>(veclist # "1d"):$Vt),
8056 (ins GPR64sp:$Rn,
8057 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
8058 }
8059
8060 defm : SIMDLdStAliases<asm, "1d", Count, Offset64, 64>;
8061}
8062
8063multiclass BaseSIMDSt1<string Count, string asm, string veclist,
8064 int Offset128, int Offset64, bits<4> opcode>
8065 : BaseSIMDStN<Count, asm, veclist, Offset128, Offset64, opcode> {
8066
8067 // ST1 instructions have extra "1d" variants.
8068 let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in {
8069 def v1d : BaseSIMDLdSt<0, 0, opcode, 0b11, asm, (outs),
8070 (ins !cast<RegisterOperand>(veclist # "1d"):$Vt,
8071 GPR64sp:$Rn), []>;
8072
8073 def v1d_POST : BaseSIMDLdStPost<0, 0, opcode, 0b11, asm,
8074 (outs GPR64sp:$wback),
8075 (ins !cast<RegisterOperand>(veclist # "1d"):$Vt,
8076 GPR64sp:$Rn,
8077 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
8078 }
8079
8080 defm : SIMDLdStAliases<asm, "1d", Count, Offset64, 64>;
8081}
8082
8083multiclass SIMDLd1Multiple<string asm> {
8084 defm One : BaseSIMDLd1<"One", asm, "VecListOne", 16, 8, 0b0111>;
8085 defm Two : BaseSIMDLd1<"Two", asm, "VecListTwo", 32, 16, 0b1010>;
8086 defm Three : BaseSIMDLd1<"Three", asm, "VecListThree", 48, 24, 0b0110>;
8087 defm Four : BaseSIMDLd1<"Four", asm, "VecListFour", 64, 32, 0b0010>;
8088}
8089
8090multiclass SIMDSt1Multiple<string asm> {
8091 defm One : BaseSIMDSt1<"One", asm, "VecListOne", 16, 8, 0b0111>;
8092 defm Two : BaseSIMDSt1<"Two", asm, "VecListTwo", 32, 16, 0b1010>;
8093 defm Three : BaseSIMDSt1<"Three", asm, "VecListThree", 48, 24, 0b0110>;
8094 defm Four : BaseSIMDSt1<"Four", asm, "VecListFour", 64, 32, 0b0010>;
8095}
8096
8097multiclass SIMDLd2Multiple<string asm> {
8098 defm Two : BaseSIMDLdN<"Two", asm, "VecListTwo", 32, 16, 0b1000>;
8099}
8100
8101multiclass SIMDSt2Multiple<string asm> {
8102 defm Two : BaseSIMDStN<"Two", asm, "VecListTwo", 32, 16, 0b1000>;
8103}
8104
8105multiclass SIMDLd3Multiple<string asm> {
8106 defm Three : BaseSIMDLdN<"Three", asm, "VecListThree", 48, 24, 0b0100>;
8107}
8108
8109multiclass SIMDSt3Multiple<string asm> {
8110 defm Three : BaseSIMDStN<"Three", asm, "VecListThree", 48, 24, 0b0100>;
8111}
8112
8113multiclass SIMDLd4Multiple<string asm> {
8114 defm Four : BaseSIMDLdN<"Four", asm, "VecListFour", 64, 32, 0b0000>;
8115}
8116
8117multiclass SIMDSt4Multiple<string asm> {
8118 defm Four : BaseSIMDStN<"Four", asm, "VecListFour", 64, 32, 0b0000>;
8119}
8120
8121//---
8122// AdvSIMD Load/store single-element
8123//---
8124
8125class BaseSIMDLdStSingle<bit L, bit R, bits<3> opcode,
8126 string asm, string operands, string cst,
8127 dag oops, dag iops, list<dag> pattern>
8128 : I<oops, iops, asm, operands, cst, pattern> {
8129 bits<5> Vt;
8130 bits<5> Rn;
8131 let Inst{31} = 0;
8132 let Inst{29-24} = 0b001101;
8133 let Inst{22} = L;
8134 let Inst{21} = R;
8135 let Inst{15-13} = opcode;
8136 let Inst{9-5} = Rn;
8137 let Inst{4-0} = Vt;
8138}
8139
8140class BaseSIMDLdStSingleTied<bit L, bit R, bits<3> opcode,
8141 string asm, string operands, string cst,
8142 dag oops, dag iops, list<dag> pattern>
8143 : I<oops, iops, asm, operands, "$Vt = $dst," # cst, pattern> {
8144 bits<5> Vt;
8145 bits<5> Rn;
8146 let Inst{31} = 0;
8147 let Inst{29-24} = 0b001101;
8148 let Inst{22} = L;
8149 let Inst{21} = R;
8150 let Inst{15-13} = opcode;
8151 let Inst{9-5} = Rn;
8152 let Inst{4-0} = Vt;
8153}
8154
8155
8156let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
8157class BaseSIMDLdR<bit Q, bit R, bits<3> opcode, bit S, bits<2> size, string asm,
8158 Operand listtype>
8159 : BaseSIMDLdStSingle<1, R, opcode, asm, "\t$Vt, [$Rn]", "",
8160 (outs listtype:$Vt), (ins GPR64sp:$Rn),
8161 []> {
8162 let Inst{30} = Q;
8163 let Inst{23} = 0;
8164 let Inst{20-16} = 0b00000;
8165 let Inst{12} = S;
8166 let Inst{11-10} = size;
8167}
8168let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
8169class BaseSIMDLdRPost<bit Q, bit R, bits<3> opcode, bit S, bits<2> size,
8170 string asm, Operand listtype, Operand GPR64pi>
8171 : BaseSIMDLdStSingle<1, R, opcode, asm, "\t$Vt, [$Rn], $Xm",
8172 "$Rn = $wback",
8173 (outs GPR64sp:$wback, listtype:$Vt),
8174 (ins GPR64sp:$Rn, GPR64pi:$Xm), []> {
8175 bits<5> Xm;
8176 let Inst{30} = Q;
8177 let Inst{23} = 1;
8178 let Inst{20-16} = Xm;
8179 let Inst{12} = S;
8180 let Inst{11-10} = size;
8181}
8182
8183multiclass SIMDLdrAliases<string asm, string layout, string Count,
8184 int Offset, int Size> {
8185 // E.g. "ld1r { v0.8b }, [x1], #1"
8186 // "ld1r.8b\t$Vt, [$Rn], #1"
8187 // may get mapped to
8188 // (LD1Rv8b_POST VecListOne8b:$Vt, GPR64sp:$Rn, XZR)
8189 def : InstAlias<asm # "\t$Vt, [$Rn], #" # Offset,
8190 (!cast<Instruction>(NAME # "v" # layout # "_POST")
8191 GPR64sp:$Rn,
8192 !cast<RegisterOperand>("VecList" # Count # layout):$Vt,
8193 XZR), 1>;
8194
8195 // E.g. "ld1r.8b { v0 }, [x1], #1"
8196 // "ld1r.8b\t$Vt, [$Rn], #1"
8197 // may get mapped to
8198 // (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, XZR)
8199 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], #" # Offset,
8200 (!cast<Instruction>(NAME # "v" # layout # "_POST")
8201 GPR64sp:$Rn,
8202 !cast<RegisterOperand>("VecList" # Count # Size):$Vt,
8203 XZR), 0>;
8204
8205 // E.g. "ld1r.8b { v0 }, [x1]"
8206 // "ld1r.8b\t$Vt, [$Rn]"
8207 // may get mapped to
8208 // (LD1Rv8b VecListOne64:$Vt, GPR64sp:$Rn)
8209 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn]",
8210 (!cast<Instruction>(NAME # "v" # layout)
8211 !cast<RegisterOperand>("VecList" # Count # Size):$Vt,
8212 GPR64sp:$Rn), 0>;
8213
8214 // E.g. "ld1r.8b { v0 }, [x1], x2"
8215 // "ld1r.8b\t$Vt, [$Rn], $Xm"
8216 // may get mapped to
8217 // (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, GPR64pi1:$Xm)
8218 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], $Xm",
8219 (!cast<Instruction>(NAME # "v" # layout # "_POST")
8220 GPR64sp:$Rn,
8221 !cast<RegisterOperand>("VecList" # Count # Size):$Vt,
8222 !cast<RegisterOperand>("GPR64pi" # Offset):$Xm), 0>;
8223}
8224
8225multiclass SIMDLdR<bit R, bits<3> opcode, bit S, string asm, string Count,
8226 int Offset1, int Offset2, int Offset4, int Offset8> {
8227 def v8b : BaseSIMDLdR<0, R, opcode, S, 0b00, asm,
8228 !cast<Operand>("VecList" # Count # "8b")>;
8229 def v16b: BaseSIMDLdR<1, R, opcode, S, 0b00, asm,
8230 !cast<Operand>("VecList" # Count #"16b")>;
8231 def v4h : BaseSIMDLdR<0, R, opcode, S, 0b01, asm,
8232 !cast<Operand>("VecList" # Count #"4h")>;
8233 def v8h : BaseSIMDLdR<1, R, opcode, S, 0b01, asm,
8234 !cast<Operand>("VecList" # Count #"8h")>;
8235 def v2s : BaseSIMDLdR<0, R, opcode, S, 0b10, asm,
8236 !cast<Operand>("VecList" # Count #"2s")>;
8237 def v4s : BaseSIMDLdR<1, R, opcode, S, 0b10, asm,
8238 !cast<Operand>("VecList" # Count #"4s")>;
8239 def v1d : BaseSIMDLdR<0, R, opcode, S, 0b11, asm,
8240 !cast<Operand>("VecList" # Count #"1d")>;
8241 def v2d : BaseSIMDLdR<1, R, opcode, S, 0b11, asm,
8242 !cast<Operand>("VecList" # Count #"2d")>;
8243
8244 def v8b_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b00, asm,
8245 !cast<Operand>("VecList" # Count # "8b"),
8246 !cast<Operand>("GPR64pi" # Offset1)>;
8247 def v16b_POST: BaseSIMDLdRPost<1, R, opcode, S, 0b00, asm,
8248 !cast<Operand>("VecList" # Count # "16b"),
8249 !cast<Operand>("GPR64pi" # Offset1)>;
8250 def v4h_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b01, asm,
8251 !cast<Operand>("VecList" # Count # "4h"),
8252 !cast<Operand>("GPR64pi" # Offset2)>;
8253 def v8h_POST : BaseSIMDLdRPost<1, R, opcode, S, 0b01, asm,
8254 !cast<Operand>("VecList" # Count # "8h"),
8255 !cast<Operand>("GPR64pi" # Offset2)>;
8256 def v2s_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b10, asm,
8257 !cast<Operand>("VecList" # Count # "2s"),
8258 !cast<Operand>("GPR64pi" # Offset4)>;
8259 def v4s_POST : BaseSIMDLdRPost<1, R, opcode, S, 0b10, asm,
8260 !cast<Operand>("VecList" # Count # "4s"),
8261 !cast<Operand>("GPR64pi" # Offset4)>;
8262 def v1d_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b11, asm,
8263 !cast<Operand>("VecList" # Count # "1d"),
8264 !cast<Operand>("GPR64pi" # Offset8)>;
8265 def v2d_POST : BaseSIMDLdRPost<1, R, opcode, S, 0b11, asm,
8266 !cast<Operand>("VecList" # Count # "2d"),
8267 !cast<Operand>("GPR64pi" # Offset8)>;
8268
8269 defm : SIMDLdrAliases<asm, "8b", Count, Offset1, 64>;
8270 defm : SIMDLdrAliases<asm, "16b", Count, Offset1, 128>;
8271 defm : SIMDLdrAliases<asm, "4h", Count, Offset2, 64>;
8272 defm : SIMDLdrAliases<asm, "8h", Count, Offset2, 128>;
8273 defm : SIMDLdrAliases<asm, "2s", Count, Offset4, 64>;
8274 defm : SIMDLdrAliases<asm, "4s", Count, Offset4, 128>;
8275 defm : SIMDLdrAliases<asm, "1d", Count, Offset8, 64>;
8276 defm : SIMDLdrAliases<asm, "2d", Count, Offset8, 128>;
8277}
8278
8279class SIMDLdStSingleB<bit L, bit R, bits<3> opcode, string asm,
8280 dag oops, dag iops, list<dag> pattern>
8281 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops,
8282 pattern> {
8283 // idx encoded in Q:S:size fields.
8284 bits<4> idx;
8285 let Inst{30} = idx{3};
8286 let Inst{23} = 0;
8287 let Inst{20-16} = 0b00000;
8288 let Inst{12} = idx{2};
8289 let Inst{11-10} = idx{1-0};
8290}
8291class SIMDLdStSingleBTied<bit L, bit R, bits<3> opcode, string asm,
8292 dag oops, dag iops, list<dag> pattern>
8293 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "",
8294 oops, iops, pattern> {
8295 // idx encoded in Q:S:size fields.
8296 bits<4> idx;
8297 let Inst{30} = idx{3};
8298 let Inst{23} = 0;
8299 let Inst{20-16} = 0b00000;
8300 let Inst{12} = idx{2};
8301 let Inst{11-10} = idx{1-0};
8302}
8303class SIMDLdStSingleBPost<bit L, bit R, bits<3> opcode, string asm,
8304 dag oops, dag iops>
8305 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
8306 "$Rn = $wback", oops, iops, []> {
8307 // idx encoded in Q:S:size fields.
8308 bits<4> idx;
8309 bits<5> Xm;
8310 let Inst{30} = idx{3};
8311 let Inst{23} = 1;
8312 let Inst{20-16} = Xm;
8313 let Inst{12} = idx{2};
8314 let Inst{11-10} = idx{1-0};
8315}
8316class SIMDLdStSingleBTiedPost<bit L, bit R, bits<3> opcode, string asm,
8317 dag oops, dag iops>
8318 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
8319 "$Rn = $wback", oops, iops, []> {
8320 // idx encoded in Q:S:size fields.
8321 bits<4> idx;
8322 bits<5> Xm;
8323 let Inst{30} = idx{3};
8324 let Inst{23} = 1;
8325 let Inst{20-16} = Xm;
8326 let Inst{12} = idx{2};
8327 let Inst{11-10} = idx{1-0};
8328}
8329
8330class SIMDLdStSingleH<bit L, bit R, bits<3> opcode, bit size, string asm,
8331 dag oops, dag iops, list<dag> pattern>
8332 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops,
8333 pattern> {
8334 // idx encoded in Q:S:size<1> fields.
8335 bits<3> idx;
8336 let Inst{30} = idx{2};
8337 let Inst{23} = 0;
8338 let Inst{20-16} = 0b00000;
8339 let Inst{12} = idx{1};
8340 let Inst{11} = idx{0};
8341 let Inst{10} = size;
8342}
8343class SIMDLdStSingleHTied<bit L, bit R, bits<3> opcode, bit size, string asm,
8344 dag oops, dag iops, list<dag> pattern>
8345 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "",
8346 oops, iops, pattern> {
8347 // idx encoded in Q:S:size<1> fields.
8348 bits<3> idx;
8349 let Inst{30} = idx{2};
8350 let Inst{23} = 0;
8351 let Inst{20-16} = 0b00000;
8352 let Inst{12} = idx{1};
8353 let Inst{11} = idx{0};
8354 let Inst{10} = size;
8355}
8356
8357class SIMDLdStSingleHPost<bit L, bit R, bits<3> opcode, bit size, string asm,
8358 dag oops, dag iops>
8359 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
8360 "$Rn = $wback", oops, iops, []> {
8361 // idx encoded in Q:S:size<1> fields.
8362 bits<3> idx;
8363 bits<5> Xm;
8364 let Inst{30} = idx{2};
8365 let Inst{23} = 1;
8366 let Inst{20-16} = Xm;
8367 let Inst{12} = idx{1};
8368 let Inst{11} = idx{0};
8369 let Inst{10} = size;
8370}
8371class SIMDLdStSingleHTiedPost<bit L, bit R, bits<3> opcode, bit size, string asm,
8372 dag oops, dag iops>
8373 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
8374 "$Rn = $wback", oops, iops, []> {
8375 // idx encoded in Q:S:size<1> fields.
8376 bits<3> idx;
8377 bits<5> Xm;
8378 let Inst{30} = idx{2};
8379 let Inst{23} = 1;
8380 let Inst{20-16} = Xm;
8381 let Inst{12} = idx{1};
8382 let Inst{11} = idx{0};
8383 let Inst{10} = size;
8384}
8385class SIMDLdStSingleS<bit L, bit R, bits<3> opcode, bits<2> size, string asm,
8386 dag oops, dag iops, list<dag> pattern>
8387 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops,
8388 pattern> {
8389 // idx encoded in Q:S fields.
8390 bits<2> idx;
8391 let Inst{30} = idx{1};
8392 let Inst{23} = 0;
8393 let Inst{20-16} = 0b00000;
8394 let Inst{12} = idx{0};
8395 let Inst{11-10} = size;
8396}
8397class SIMDLdStSingleSTied<bit L, bit R, bits<3> opcode, bits<2> size, string asm,
8398 dag oops, dag iops, list<dag> pattern>
8399 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "",
8400 oops, iops, pattern> {
8401 // idx encoded in Q:S fields.
8402 bits<2> idx;
8403 let Inst{30} = idx{1};
8404 let Inst{23} = 0;
8405 let Inst{20-16} = 0b00000;
8406 let Inst{12} = idx{0};
8407 let Inst{11-10} = size;
8408}
8409class SIMDLdStSingleSPost<bit L, bit R, bits<3> opcode, bits<2> size,
8410 string asm, dag oops, dag iops>
8411 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
8412 "$Rn = $wback", oops, iops, []> {
8413 // idx encoded in Q:S fields.
8414 bits<2> idx;
8415 bits<5> Xm;
8416 let Inst{30} = idx{1};
8417 let Inst{23} = 1;
8418 let Inst{20-16} = Xm;
8419 let Inst{12} = idx{0};
8420 let Inst{11-10} = size;
8421}
8422class SIMDLdStSingleSTiedPost<bit L, bit R, bits<3> opcode, bits<2> size,
8423 string asm, dag oops, dag iops>
8424 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
8425 "$Rn = $wback", oops, iops, []> {
8426 // idx encoded in Q:S fields.
8427 bits<2> idx;
8428 bits<5> Xm;
8429 let Inst{30} = idx{1};
8430 let Inst{23} = 1;
8431 let Inst{20-16} = Xm;
8432 let Inst{12} = idx{0};
8433 let Inst{11-10} = size;
8434}
8435class SIMDLdStSingleD<bit L, bit R, bits<3> opcode, bits<2> size, string asm,
8436 dag oops, dag iops, list<dag> pattern>
8437 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops,
8438 pattern> {
8439 // idx encoded in Q field.
8440 bits<1> idx;
8441 let Inst{30} = idx;
8442 let Inst{23} = 0;
8443 let Inst{20-16} = 0b00000;
8444 let Inst{12} = 0;
8445 let Inst{11-10} = size;
8446}
8447class SIMDLdStSingleDTied<bit L, bit R, bits<3> opcode, bits<2> size, string asm,
8448 dag oops, dag iops, list<dag> pattern>
8449 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "",
8450 oops, iops, pattern> {
8451 // idx encoded in Q field.
8452 bits<1> idx;
8453 let Inst{30} = idx;
8454 let Inst{23} = 0;
8455 let Inst{20-16} = 0b00000;
8456 let Inst{12} = 0;
8457 let Inst{11-10} = size;
8458}
8459class SIMDLdStSingleDPost<bit L, bit R, bits<3> opcode, bits<2> size,
8460 string asm, dag oops, dag iops>
8461 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
8462 "$Rn = $wback", oops, iops, []> {
8463 // idx encoded in Q field.
8464 bits<1> idx;
8465 bits<5> Xm;
8466 let Inst{30} = idx;
8467 let Inst{23} = 1;
8468 let Inst{20-16} = Xm;
8469 let Inst{12} = 0;
8470 let Inst{11-10} = size;
8471}
8472class SIMDLdStSingleDTiedPost<bit L, bit R, bits<3> opcode, bits<2> size,
8473 string asm, dag oops, dag iops>
8474 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
8475 "$Rn = $wback", oops, iops, []> {
8476 // idx encoded in Q field.
8477 bits<1> idx;
8478 bits<5> Xm;
8479 let Inst{30} = idx;
8480 let Inst{23} = 1;
8481 let Inst{20-16} = Xm;
8482 let Inst{12} = 0;
8483 let Inst{11-10} = size;
8484}
8485
8486let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
8487multiclass SIMDLdSingleBTied<bit R, bits<3> opcode, string asm,
8488 RegisterOperand listtype,
8489 RegisterOperand GPR64pi> {
8490 def i8 : SIMDLdStSingleBTied<1, R, opcode, asm,
8491 (outs listtype:$dst),
8492 (ins listtype:$Vt, VectorIndexB:$idx,
8493 GPR64sp:$Rn), []>;
8494
8495 def i8_POST : SIMDLdStSingleBTiedPost<1, R, opcode, asm,
8496 (outs GPR64sp:$wback, listtype:$dst),
8497 (ins listtype:$Vt, VectorIndexB:$idx,
8498 GPR64sp:$Rn, GPR64pi:$Xm)>;
8499}
8500let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
8501multiclass SIMDLdSingleHTied<bit R, bits<3> opcode, bit size, string asm,
8502 RegisterOperand listtype,
8503 RegisterOperand GPR64pi> {
8504 def i16 : SIMDLdStSingleHTied<1, R, opcode, size, asm,
8505 (outs listtype:$dst),
8506 (ins listtype:$Vt, VectorIndexH:$idx,
8507 GPR64sp:$Rn), []>;
8508
8509 def i16_POST : SIMDLdStSingleHTiedPost<1, R, opcode, size, asm,
8510 (outs GPR64sp:$wback, listtype:$dst),
8511 (ins listtype:$Vt, VectorIndexH:$idx,
8512 GPR64sp:$Rn, GPR64pi:$Xm)>;
8513}
8514let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
8515multiclass SIMDLdSingleSTied<bit R, bits<3> opcode, bits<2> size,string asm,
8516 RegisterOperand listtype,
8517 RegisterOperand GPR64pi> {
8518 def i32 : SIMDLdStSingleSTied<1, R, opcode, size, asm,
8519 (outs listtype:$dst),
8520 (ins listtype:$Vt, VectorIndexS:$idx,
8521 GPR64sp:$Rn), []>;
8522
8523 def i32_POST : SIMDLdStSingleSTiedPost<1, R, opcode, size, asm,
8524 (outs GPR64sp:$wback, listtype:$dst),
8525 (ins listtype:$Vt, VectorIndexS:$idx,
8526 GPR64sp:$Rn, GPR64pi:$Xm)>;
8527}
8528let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
8529multiclass SIMDLdSingleDTied<bit R, bits<3> opcode, bits<2> size, string asm,
8530 RegisterOperand listtype, RegisterOperand GPR64pi> {
8531 def i64 : SIMDLdStSingleDTied<1, R, opcode, size, asm,
8532 (outs listtype:$dst),
8533 (ins listtype:$Vt, VectorIndexD:$idx,
8534 GPR64sp:$Rn), []>;
8535
8536 def i64_POST : SIMDLdStSingleDTiedPost<1, R, opcode, size, asm,
8537 (outs GPR64sp:$wback, listtype:$dst),
8538 (ins listtype:$Vt, VectorIndexD:$idx,
8539 GPR64sp:$Rn, GPR64pi:$Xm)>;
8540}
8541let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
8542multiclass SIMDStSingleB<bit R, bits<3> opcode, string asm,
8543 RegisterOperand listtype, RegisterOperand GPR64pi> {
8544 def i8 : SIMDLdStSingleB<0, R, opcode, asm,
8545 (outs), (ins listtype:$Vt, VectorIndexB:$idx,
8546 GPR64sp:$Rn), []>;
8547
8548 def i8_POST : SIMDLdStSingleBPost<0, R, opcode, asm,
8549 (outs GPR64sp:$wback),
8550 (ins listtype:$Vt, VectorIndexB:$idx,
8551 GPR64sp:$Rn, GPR64pi:$Xm)>;
8552}
8553let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
8554multiclass SIMDStSingleH<bit R, bits<3> opcode, bit size, string asm,
8555 RegisterOperand listtype, RegisterOperand GPR64pi> {
8556 def i16 : SIMDLdStSingleH<0, R, opcode, size, asm,
8557 (outs), (ins listtype:$Vt, VectorIndexH:$idx,
8558 GPR64sp:$Rn), []>;
8559
8560 def i16_POST : SIMDLdStSingleHPost<0, R, opcode, size, asm,
8561 (outs GPR64sp:$wback),
8562 (ins listtype:$Vt, VectorIndexH:$idx,
8563 GPR64sp:$Rn, GPR64pi:$Xm)>;
8564}
8565let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
8566multiclass SIMDStSingleS<bit R, bits<3> opcode, bits<2> size,string asm,
8567 RegisterOperand listtype, RegisterOperand GPR64pi> {
8568 def i32 : SIMDLdStSingleS<0, R, opcode, size, asm,
8569 (outs), (ins listtype:$Vt, VectorIndexS:$idx,
8570 GPR64sp:$Rn), []>;
8571
8572 def i32_POST : SIMDLdStSingleSPost<0, R, opcode, size, asm,
8573 (outs GPR64sp:$wback),
8574 (ins listtype:$Vt, VectorIndexS:$idx,
8575 GPR64sp:$Rn, GPR64pi:$Xm)>;
8576}
8577let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
8578multiclass SIMDStSingleD<bit R, bits<3> opcode, bits<2> size, string asm,
8579 RegisterOperand listtype, RegisterOperand GPR64pi> {
8580 def i64 : SIMDLdStSingleD<0, R, opcode, size, asm,
8581 (outs), (ins listtype:$Vt, VectorIndexD:$idx,
8582 GPR64sp:$Rn), []>;
8583
8584 def i64_POST : SIMDLdStSingleDPost<0, R, opcode, size, asm,
8585 (outs GPR64sp:$wback),
8586 (ins listtype:$Vt, VectorIndexD:$idx,
8587 GPR64sp:$Rn, GPR64pi:$Xm)>;
8588}
8589
8590multiclass SIMDLdStSingleAliases<string asm, string layout, string Type,
8591 string Count, int Offset, Operand idxtype> {
8592 // E.g. "ld1 { v0.8b }[0], [x1], #1"
8593 // "ld1\t$Vt, [$Rn], #1"
8594 // may get mapped to
8595 // (LD1Rv8b_POST VecListOne8b:$Vt, GPR64sp:$Rn, XZR)
8596 def : InstAlias<asm # "\t$Vt$idx, [$Rn], #" # Offset,
8597 (!cast<Instruction>(NAME # Type # "_POST")
8598 GPR64sp:$Rn,
8599 !cast<RegisterOperand>("VecList" # Count # layout):$Vt,
8600 idxtype:$idx, XZR), 1>;
8601
8602 // E.g. "ld1.8b { v0 }[0], [x1], #1"
8603 // "ld1.8b\t$Vt, [$Rn], #1"
8604 // may get mapped to
8605 // (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, XZR)
8606 def : InstAlias<asm # "." # layout # "\t$Vt$idx, [$Rn], #" # Offset,
8607 (!cast<Instruction>(NAME # Type # "_POST")
8608 GPR64sp:$Rn,
8609 !cast<RegisterOperand>("VecList" # Count # "128"):$Vt,
8610 idxtype:$idx, XZR), 0>;
8611
8612 // E.g. "ld1.8b { v0 }[0], [x1]"
8613 // "ld1.8b\t$Vt, [$Rn]"
8614 // may get mapped to
8615 // (LD1Rv8b VecListOne64:$Vt, GPR64sp:$Rn)
8616 def : InstAlias<asm # "." # layout # "\t$Vt$idx, [$Rn]",
8617 (!cast<Instruction>(NAME # Type)
8618 !cast<RegisterOperand>("VecList" # Count # "128"):$Vt,
8619 idxtype:$idx, GPR64sp:$Rn), 0>;
8620
8621 // E.g. "ld1.8b { v0 }[0], [x1], x2"
8622 // "ld1.8b\t$Vt, [$Rn], $Xm"
8623 // may get mapped to
8624 // (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, GPR64pi1:$Xm)
8625 def : InstAlias<asm # "." # layout # "\t$Vt$idx, [$Rn], $Xm",
8626 (!cast<Instruction>(NAME # Type # "_POST")
8627 GPR64sp:$Rn,
8628 !cast<RegisterOperand>("VecList" # Count # "128"):$Vt,
8629 idxtype:$idx,
8630 !cast<RegisterOperand>("GPR64pi" # Offset):$Xm), 0>;
8631}
8632
8633multiclass SIMDLdSt1SingleAliases<string asm> {
8634 defm : SIMDLdStSingleAliases<asm, "b", "i8", "One", 1, VectorIndexB>;
8635 defm : SIMDLdStSingleAliases<asm, "h", "i16", "One", 2, VectorIndexH>;
8636 defm : SIMDLdStSingleAliases<asm, "s", "i32", "One", 4, VectorIndexS>;
8637 defm : SIMDLdStSingleAliases<asm, "d", "i64", "One", 8, VectorIndexD>;
8638}
8639
8640multiclass SIMDLdSt2SingleAliases<string asm> {
8641 defm : SIMDLdStSingleAliases<asm, "b", "i8", "Two", 2, VectorIndexB>;
8642 defm : SIMDLdStSingleAliases<asm, "h", "i16", "Two", 4, VectorIndexH>;
8643 defm : SIMDLdStSingleAliases<asm, "s", "i32", "Two", 8, VectorIndexS>;
8644 defm : SIMDLdStSingleAliases<asm, "d", "i64", "Two", 16, VectorIndexD>;
8645}
8646
8647multiclass SIMDLdSt3SingleAliases<string asm> {
8648 defm : SIMDLdStSingleAliases<asm, "b", "i8", "Three", 3, VectorIndexB>;
8649 defm : SIMDLdStSingleAliases<asm, "h", "i16", "Three", 6, VectorIndexH>;
8650 defm : SIMDLdStSingleAliases<asm, "s", "i32", "Three", 12, VectorIndexS>;
8651 defm : SIMDLdStSingleAliases<asm, "d", "i64", "Three", 24, VectorIndexD>;
8652}
8653
8654multiclass SIMDLdSt4SingleAliases<string asm> {
8655 defm : SIMDLdStSingleAliases<asm, "b", "i8", "Four", 4, VectorIndexB>;
8656 defm : SIMDLdStSingleAliases<asm, "h", "i16", "Four", 8, VectorIndexH>;
8657 defm : SIMDLdStSingleAliases<asm, "s", "i32", "Four", 16, VectorIndexS>;
8658 defm : SIMDLdStSingleAliases<asm, "d", "i64", "Four", 32, VectorIndexD>;
8659}
8660} // end of 'let Predicates = [HasNEON]'
8661
8662//----------------------------------------------------------------------------
Vladimir Sukharev297bf0e2015-03-31 13:15:48 +00008663// AdvSIMD v8.1 Rounding Double Multiply Add/Subtract
8664//----------------------------------------------------------------------------
8665
8666let Predicates = [HasNEON, HasV8_1a] in {
8667
8668class BaseSIMDThreeSameVectorTiedR0<bit Q, bit U, bits<2> size, bits<5> opcode,
8669 RegisterOperand regtype, string asm,
8670 string kind, list<dag> pattern>
8671 : BaseSIMDThreeSameVectorTied<Q, U, size, opcode, regtype, asm, kind,
8672 pattern> {
8673 let Inst{21}=0;
8674}
8675multiclass SIMDThreeSameVectorSQRDMLxHTiedHS<bit U, bits<5> opc, string asm,
8676 SDPatternOperator Accum> {
8677 def v4i16 : BaseSIMDThreeSameVectorTiedR0<0, U, 0b01, opc, V64, asm, ".4h",
8678 [(set (v4i16 V64:$dst),
8679 (Accum (v4i16 V64:$Rd),
8680 (v4i16 (int_aarch64_neon_sqrdmulh (v4i16 V64:$Rn),
8681 (v4i16 V64:$Rm)))))]>;
8682 def v8i16 : BaseSIMDThreeSameVectorTiedR0<1, U, 0b01, opc, V128, asm, ".8h",
8683 [(set (v8i16 V128:$dst),
8684 (Accum (v8i16 V128:$Rd),
8685 (v8i16 (int_aarch64_neon_sqrdmulh (v8i16 V128:$Rn),
8686 (v8i16 V128:$Rm)))))]>;
8687 def v2i32 : BaseSIMDThreeSameVectorTiedR0<0, U, 0b10, opc, V64, asm, ".2s",
8688 [(set (v2i32 V64:$dst),
8689 (Accum (v2i32 V64:$Rd),
8690 (v2i32 (int_aarch64_neon_sqrdmulh (v2i32 V64:$Rn),
8691 (v2i32 V64:$Rm)))))]>;
8692 def v4i32 : BaseSIMDThreeSameVectorTiedR0<1, U, 0b10, opc, V128, asm, ".4s",
8693 [(set (v4i32 V128:$dst),
8694 (Accum (v4i32 V128:$Rd),
8695 (v4i32 (int_aarch64_neon_sqrdmulh (v4i32 V128:$Rn),
8696 (v4i32 V128:$Rm)))))]>;
8697}
8698
8699multiclass SIMDIndexedSQRDMLxHSDTied<bit U, bits<4> opc, string asm,
8700 SDPatternOperator Accum> {
8701 def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc,
8702 V64, V64, V128_lo, VectorIndexH,
8703 asm, ".4h", ".4h", ".4h", ".h",
8704 [(set (v4i16 V64:$dst),
8705 (Accum (v4i16 V64:$Rd),
8706 (v4i16 (int_aarch64_neon_sqrdmulh
8707 (v4i16 V64:$Rn),
8708 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm),
8709 VectorIndexH:$idx))))))]> {
8710 bits<3> idx;
8711 let Inst{11} = idx{2};
8712 let Inst{21} = idx{1};
8713 let Inst{20} = idx{0};
8714 }
8715
8716 def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc,
8717 V128, V128, V128_lo, VectorIndexH,
8718 asm, ".8h", ".8h", ".8h", ".h",
8719 [(set (v8i16 V128:$dst),
8720 (Accum (v8i16 V128:$Rd),
8721 (v8i16 (int_aarch64_neon_sqrdmulh
8722 (v8i16 V128:$Rn),
8723 (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm),
8724 VectorIndexH:$idx))))))]> {
8725 bits<3> idx;
8726 let Inst{11} = idx{2};
8727 let Inst{21} = idx{1};
8728 let Inst{20} = idx{0};
8729 }
8730
8731 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc,
8732 V64, V64, V128, VectorIndexS,
8733 asm, ".2s", ".2s", ".2s", ".s",
8734 [(set (v2i32 V64:$dst),
8735 (Accum (v2i32 V64:$Rd),
8736 (v2i32 (int_aarch64_neon_sqrdmulh
8737 (v2i32 V64:$Rn),
8738 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm),
8739 VectorIndexS:$idx))))))]> {
8740 bits<2> idx;
8741 let Inst{11} = idx{1};
8742 let Inst{21} = idx{0};
8743 }
8744
8745 // FIXME: it would be nice to use the scalar (v1i32) instruction here, but
8746 // an intermediate EXTRACT_SUBREG would be untyped.
8747 // FIXME: direct EXTRACT_SUBREG from v2i32 to i32 is illegal, that's why we
8748 // got it lowered here as (i32 vector_extract (v4i32 insert_subvector(..)))
8749 def : Pat<(i32 (Accum (i32 FPR32Op:$Rd),
8750 (i32 (vector_extract
8751 (v4i32 (insert_subvector
8752 (undef),
8753 (v2i32 (int_aarch64_neon_sqrdmulh
8754 (v2i32 V64:$Rn),
8755 (v2i32 (AArch64duplane32
8756 (v4i32 V128:$Rm),
8757 VectorIndexS:$idx)))),
8758 (i32 0))),
8759 (i64 0))))),
8760 (EXTRACT_SUBREG
8761 (v2i32 (!cast<Instruction>(NAME # v2i32_indexed)
8762 (v2i32 (INSERT_SUBREG (v2i32 (IMPLICIT_DEF)),
8763 FPR32Op:$Rd,
8764 ssub)),
8765 V64:$Rn,
8766 V128:$Rm,
8767 VectorIndexS:$idx)),
8768 ssub)>;
8769
8770 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc,
8771 V128, V128, V128, VectorIndexS,
8772 asm, ".4s", ".4s", ".4s", ".s",
8773 [(set (v4i32 V128:$dst),
8774 (Accum (v4i32 V128:$Rd),
8775 (v4i32 (int_aarch64_neon_sqrdmulh
8776 (v4i32 V128:$Rn),
8777 (v4i32 (AArch64duplane32 (v4i32 V128:$Rm),
8778 VectorIndexS:$idx))))))]> {
8779 bits<2> idx;
8780 let Inst{11} = idx{1};
8781 let Inst{21} = idx{0};
8782 }
8783
8784 // FIXME: it would be nice to use the scalar (v1i32) instruction here, but
8785 // an intermediate EXTRACT_SUBREG would be untyped.
8786 def : Pat<(i32 (Accum (i32 FPR32Op:$Rd),
8787 (i32 (vector_extract
8788 (v4i32 (int_aarch64_neon_sqrdmulh
8789 (v4i32 V128:$Rn),
8790 (v4i32 (AArch64duplane32
8791 (v4i32 V128:$Rm),
8792 VectorIndexS:$idx)))),
8793 (i64 0))))),
8794 (EXTRACT_SUBREG
8795 (v4i32 (!cast<Instruction>(NAME # v4i32_indexed)
8796 (v4i32 (INSERT_SUBREG (v4i32 (IMPLICIT_DEF)),
8797 FPR32Op:$Rd,
8798 ssub)),
8799 V128:$Rn,
8800 V128:$Rm,
8801 VectorIndexS:$idx)),
8802 ssub)>;
8803
8804 def i16_indexed : BaseSIMDIndexedTied<1, U, 1, 0b01, opc,
8805 FPR16Op, FPR16Op, V128_lo,
8806 VectorIndexH, asm, ".h", "", "", ".h",
8807 []> {
8808 bits<3> idx;
8809 let Inst{11} = idx{2};
8810 let Inst{21} = idx{1};
8811 let Inst{20} = idx{0};
8812 }
8813
8814 def i32_indexed : BaseSIMDIndexedTied<1, U, 1, 0b10, opc,
8815 FPR32Op, FPR32Op, V128, VectorIndexS,
8816 asm, ".s", "", "", ".s",
8817 [(set (i32 FPR32Op:$dst),
8818 (Accum (i32 FPR32Op:$Rd),
8819 (i32 (int_aarch64_neon_sqrdmulh
8820 (i32 FPR32Op:$Rn),
8821 (i32 (vector_extract (v4i32 V128:$Rm),
8822 VectorIndexS:$idx))))))]> {
8823 bits<2> idx;
8824 let Inst{11} = idx{1};
8825 let Inst{21} = idx{0};
8826 }
8827}
8828} // let Predicates = [HasNeon, HasV8_1a]
8829
8830//----------------------------------------------------------------------------
Tim Northover3b0846e2014-05-24 12:50:23 +00008831// Crypto extensions
8832//----------------------------------------------------------------------------
8833
8834let Predicates = [HasCrypto] in {
8835let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
8836class AESBase<bits<4> opc, string asm, dag outs, dag ins, string cstr,
8837 list<dag> pat>
8838 : I<outs, ins, asm, "{\t$Rd.16b, $Rn.16b|.16b\t$Rd, $Rn}", cstr, pat>,
8839 Sched<[WriteV]>{
8840 bits<5> Rd;
8841 bits<5> Rn;
8842 let Inst{31-16} = 0b0100111000101000;
8843 let Inst{15-12} = opc;
8844 let Inst{11-10} = 0b10;
8845 let Inst{9-5} = Rn;
8846 let Inst{4-0} = Rd;
8847}
8848
8849class AESInst<bits<4> opc, string asm, Intrinsic OpNode>
8850 : AESBase<opc, asm, (outs V128:$Rd), (ins V128:$Rn), "",
8851 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>;
8852
8853class AESTiedInst<bits<4> opc, string asm, Intrinsic OpNode>
8854 : AESBase<opc, asm, (outs V128:$dst), (ins V128:$Rd, V128:$Rn),
8855 "$Rd = $dst",
8856 [(set (v16i8 V128:$dst),
8857 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn)))]>;
8858
8859let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
8860class SHA3OpTiedInst<bits<3> opc, string asm, string dst_lhs_kind,
8861 dag oops, dag iops, list<dag> pat>
8862 : I<oops, iops, asm,
8863 "{\t$Rd" # dst_lhs_kind # ", $Rn" # dst_lhs_kind # ", $Rm.4s" #
8864 "|.4s\t$Rd, $Rn, $Rm}", "$Rd = $dst", pat>,
8865 Sched<[WriteV]>{
8866 bits<5> Rd;
8867 bits<5> Rn;
8868 bits<5> Rm;
8869 let Inst{31-21} = 0b01011110000;
8870 let Inst{20-16} = Rm;
8871 let Inst{15} = 0;
8872 let Inst{14-12} = opc;
8873 let Inst{11-10} = 0b00;
8874 let Inst{9-5} = Rn;
8875 let Inst{4-0} = Rd;
8876}
8877
8878class SHATiedInstQSV<bits<3> opc, string asm, Intrinsic OpNode>
8879 : SHA3OpTiedInst<opc, asm, "", (outs FPR128:$dst),
8880 (ins FPR128:$Rd, FPR32:$Rn, V128:$Rm),
8881 [(set (v4i32 FPR128:$dst),
8882 (OpNode (v4i32 FPR128:$Rd), (i32 FPR32:$Rn),
8883 (v4i32 V128:$Rm)))]>;
8884
8885class SHATiedInstVVV<bits<3> opc, string asm, Intrinsic OpNode>
8886 : SHA3OpTiedInst<opc, asm, ".4s", (outs V128:$dst),
8887 (ins V128:$Rd, V128:$Rn, V128:$Rm),
8888 [(set (v4i32 V128:$dst),
8889 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn),
8890 (v4i32 V128:$Rm)))]>;
8891
8892class SHATiedInstQQV<bits<3> opc, string asm, Intrinsic OpNode>
8893 : SHA3OpTiedInst<opc, asm, "", (outs FPR128:$dst),
8894 (ins FPR128:$Rd, FPR128:$Rn, V128:$Rm),
8895 [(set (v4i32 FPR128:$dst),
8896 (OpNode (v4i32 FPR128:$Rd), (v4i32 FPR128:$Rn),
8897 (v4i32 V128:$Rm)))]>;
8898
8899let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
8900class SHA2OpInst<bits<4> opc, string asm, string kind,
8901 string cstr, dag oops, dag iops,
8902 list<dag> pat>
8903 : I<oops, iops, asm, "{\t$Rd" # kind # ", $Rn" # kind #
8904 "|" # kind # "\t$Rd, $Rn}", cstr, pat>,
8905 Sched<[WriteV]>{
8906 bits<5> Rd;
8907 bits<5> Rn;
8908 let Inst{31-16} = 0b0101111000101000;
8909 let Inst{15-12} = opc;
8910 let Inst{11-10} = 0b10;
8911 let Inst{9-5} = Rn;
8912 let Inst{4-0} = Rd;
8913}
8914
8915class SHATiedInstVV<bits<4> opc, string asm, Intrinsic OpNode>
8916 : SHA2OpInst<opc, asm, ".4s", "$Rd = $dst", (outs V128:$dst),
8917 (ins V128:$Rd, V128:$Rn),
8918 [(set (v4i32 V128:$dst),
8919 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn)))]>;
8920
8921class SHAInstSS<bits<4> opc, string asm, Intrinsic OpNode>
8922 : SHA2OpInst<opc, asm, "", "", (outs FPR32:$Rd), (ins FPR32:$Rn),
8923 [(set (i32 FPR32:$Rd), (OpNode (i32 FPR32:$Rn)))]>;
8924} // end of 'let Predicates = [HasCrypto]'
8925
Vladimir Sukharev5f6f60d2015-06-02 10:58:41 +00008926//----------------------------------------------------------------------------
8927// v8.1 atomic instructions extension:
8928// * CAS
8929// * CASP
8930// * SWP
8931// * LDOPregister<OP>, and aliases STOPregister<OP>
8932
8933// Instruction encodings:
8934//
8935// 31 30|29 24|23|22|21|20 16|15|14 10|9 5|4 0
8936// CAS SZ |001000|1 |A |1 |Rs |R |11111 |Rn |Rt
8937// CASP 0|SZ|001000|0 |A |1 |Rs |R |11111 |Rn |Rt
8938// SWP SZ |111000|A |R |1 |Rs |1 |OPC|00|Rn |Rt
8939// LD SZ |111000|A |R |1 |Rs |0 |OPC|00|Rn |Rt
8940// ST SZ |111000|A |R |1 |Rs |0 |OPC|00|Rn |11111
8941
8942// Instruction syntax:
8943//
8944// CAS{<order>}[<size>] <Ws>, <Wt>, [<Xn|SP>]
8945// CAS{<order>} <Xs>, <Xt>, [<Xn|SP>]
8946// CASP{<order>} <Ws>, <W(s+1)>, <Wt>, <W(t+1)>, [<Xn|SP>]
8947// CASP{<order>} <Xs>, <X(s+1)>, <Xt>, <X(t+1)>, [<Xn|SP>]
8948// SWP{<order>}[<size>] <Ws>, <Wt>, [<Xn|SP>]
8949// SWP{<order>} <Xs>, <Xt>, [<Xn|SP>]
8950// LD<OP>{<order>}[<size>] <Ws>, <Wt>, [<Xn|SP>]
8951// LD<OP>{<order>} <Xs>, <Xt>, [<Xn|SP>]
8952// ST<OP>{<order>}[<size>] <Ws>, [<Xn|SP>]
8953// ST<OP>{<order>} <Xs>, [<Xn|SP>]
8954
8955let Predicates = [HasV8_1a], mayLoad = 1, mayStore = 1, hasSideEffects = 1 in
8956class BaseCASEncoding<dag oops, dag iops, string asm, string operands,
8957 string cstr, list<dag> pattern>
8958 : I<oops, iops, asm, operands, cstr, pattern> {
8959 bits<2> Sz;
8960 bit NP;
8961 bit Acq;
8962 bit Rel;
8963 bits<5> Rs;
8964 bits<5> Rn;
8965 bits<5> Rt;
8966 let Inst{31-30} = Sz;
8967 let Inst{29-24} = 0b001000;
8968 let Inst{23} = NP;
8969 let Inst{22} = Acq;
8970 let Inst{21} = 0b1;
8971 let Inst{20-16} = Rs;
8972 let Inst{15} = Rel;
8973 let Inst{14-10} = 0b11111;
8974 let Inst{9-5} = Rn;
8975 let Inst{4-0} = Rt;
8976}
8977
8978class BaseCAS<string order, string size, RegisterClass RC>
8979 : BaseCASEncoding<(outs RC:$out),(ins RC:$Rs, RC:$Rt, GPR64sp:$Rn),
8980 "cas" # order # size, "\t$Rs, $Rt, [$Rn]",
8981 "$out = $Rs",[]> {
8982 let NP = 1;
8983}
8984
8985multiclass CompareAndSwap<bits<1> Acq, bits<1> Rel, string order> {
8986 let Sz = 0b00, Acq = Acq, Rel = Rel in def b : BaseCAS<order, "b", GPR32>;
8987 let Sz = 0b01, Acq = Acq, Rel = Rel in def h : BaseCAS<order, "h", GPR32>;
8988 let Sz = 0b10, Acq = Acq, Rel = Rel in def s : BaseCAS<order, "", GPR32>;
8989 let Sz = 0b11, Acq = Acq, Rel = Rel in def d : BaseCAS<order, "", GPR64>;
8990}
8991
8992class BaseCASP<string order, string size, RegisterOperand RC>
8993 : BaseCASEncoding<(outs RC:$out),(ins RC:$Rs, RC:$Rt, GPR64sp:$Rn),
8994 "casp" # order # size, "\t$Rs, $Rt, [$Rn]",
8995 "$out = $Rs",[]> {
8996 let NP = 0;
8997}
8998
8999multiclass CompareAndSwapPair<bits<1> Acq, bits<1> Rel, string order> {
9000 let Sz = 0b00, Acq = Acq, Rel = Rel in
9001 def s : BaseCASP<order, "", WSeqPairClassOperand>;
9002 let Sz = 0b01, Acq = Acq, Rel = Rel in
9003 def d : BaseCASP<order, "", XSeqPairClassOperand>;
9004}
9005
9006let Predicates = [HasV8_1a] in
9007class BaseSWP<string order, string size, RegisterClass RC>
9008 : I<(outs RC:$Rt),(ins RC:$Rs, GPR64sp:$Rn), "swp" # order # size,
9009 "\t$Rs, $Rt, [$Rn]","",[]> {
9010 bits<2> Sz;
9011 bit Acq;
9012 bit Rel;
9013 bits<5> Rs;
9014 bits<3> opc = 0b000;
9015 bits<5> Rn;
9016 bits<5> Rt;
9017 let Inst{31-30} = Sz;
9018 let Inst{29-24} = 0b111000;
9019 let Inst{23} = Acq;
9020 let Inst{22} = Rel;
9021 let Inst{21} = 0b1;
9022 let Inst{20-16} = Rs;
9023 let Inst{15} = 0b1;
9024 let Inst{14-12} = opc;
9025 let Inst{11-10} = 0b00;
9026 let Inst{9-5} = Rn;
9027 let Inst{4-0} = Rt;
9028}
9029
9030multiclass Swap<bits<1> Acq, bits<1> Rel, string order> {
9031 let Sz = 0b00, Acq = Acq, Rel = Rel in def b : BaseSWP<order, "b", GPR32>;
9032 let Sz = 0b01, Acq = Acq, Rel = Rel in def h : BaseSWP<order, "h", GPR32>;
9033 let Sz = 0b10, Acq = Acq, Rel = Rel in def s : BaseSWP<order, "", GPR32>;
9034 let Sz = 0b11, Acq = Acq, Rel = Rel in def d : BaseSWP<order, "", GPR64>;
9035}
9036
9037let Predicates = [HasV8_1a], mayLoad = 1, mayStore = 1, hasSideEffects = 1 in
9038class BaseLDOPregister<string op, string order, string size, RegisterClass RC>
9039 : I<(outs RC:$Rt),(ins RC:$Rs, GPR64sp:$Rn), "ld" # op # order # size,
9040 "\t$Rs, $Rt, [$Rn]","",[]> {
9041 bits<2> Sz;
9042 bit Acq;
9043 bit Rel;
9044 bits<5> Rs;
9045 bits<3> opc;
9046 bits<5> Rn;
9047 bits<5> Rt;
9048 let Inst{31-30} = Sz;
9049 let Inst{29-24} = 0b111000;
9050 let Inst{23} = Acq;
9051 let Inst{22} = Rel;
9052 let Inst{21} = 0b1;
9053 let Inst{20-16} = Rs;
9054 let Inst{15} = 0b0;
9055 let Inst{14-12} = opc;
9056 let Inst{11-10} = 0b00;
9057 let Inst{9-5} = Rn;
9058 let Inst{4-0} = Rt;
9059}
9060
9061multiclass LDOPregister<bits<3> opc, string op, bits<1> Acq, bits<1> Rel,
9062 string order> {
9063 let Sz = 0b00, Acq = Acq, Rel = Rel, opc = opc in
9064 def b : BaseLDOPregister<op, order, "b", GPR32>;
9065 let Sz = 0b01, Acq = Acq, Rel = Rel, opc = opc in
9066 def h : BaseLDOPregister<op, order, "h", GPR32>;
9067 let Sz = 0b10, Acq = Acq, Rel = Rel, opc = opc in
9068 def s : BaseLDOPregister<op, order, "", GPR32>;
9069 let Sz = 0b11, Acq = Acq, Rel = Rel, opc = opc in
9070 def d : BaseLDOPregister<op, order, "", GPR64>;
9071}
9072
9073let Predicates = [HasV8_1a] in
9074class BaseSTOPregister<string asm, RegisterClass OP, Register Reg,
9075 Instruction inst> :
9076 InstAlias<asm # "\t$Rs, [$Rn]", (inst Reg, OP:$Rs, GPR64sp:$Rn)>;
9077
9078multiclass STOPregister<string asm, string instr> {
9079 def : BaseSTOPregister<asm # "lb", GPR32, WZR,
9080 !cast<Instruction>(instr # "Lb")>;
9081 def : BaseSTOPregister<asm # "lh", GPR32, WZR,
9082 !cast<Instruction>(instr # "Lh")>;
9083 def : BaseSTOPregister<asm # "l", GPR32, WZR,
9084 !cast<Instruction>(instr # "Ls")>;
9085 def : BaseSTOPregister<asm # "l", GPR64, XZR,
9086 !cast<Instruction>(instr # "Ld")>;
9087 def : BaseSTOPregister<asm # "b", GPR32, WZR,
9088 !cast<Instruction>(instr # "b")>;
9089 def : BaseSTOPregister<asm # "h", GPR32, WZR,
9090 !cast<Instruction>(instr # "h")>;
9091 def : BaseSTOPregister<asm, GPR32, WZR,
9092 !cast<Instruction>(instr # "s")>;
9093 def : BaseSTOPregister<asm, GPR64, XZR,
9094 !cast<Instruction>(instr # "d")>;
9095}
9096
9097//----------------------------------------------------------------------------
Tim Northover3b0846e2014-05-24 12:50:23 +00009098// Allow the size specifier tokens to be upper case, not just lower.
9099def : TokenAlias<".8B", ".8b">;
9100def : TokenAlias<".4H", ".4h">;
9101def : TokenAlias<".2S", ".2s">;
9102def : TokenAlias<".1D", ".1d">;
9103def : TokenAlias<".16B", ".16b">;
9104def : TokenAlias<".8H", ".8h">;
9105def : TokenAlias<".4S", ".4s">;
9106def : TokenAlias<".2D", ".2d">;
9107def : TokenAlias<".1Q", ".1q">;
9108def : TokenAlias<".B", ".b">;
9109def : TokenAlias<".H", ".h">;
9110def : TokenAlias<".S", ".s">;
9111def : TokenAlias<".D", ".d">;
9112def : TokenAlias<".Q", ".q">;