blob: 752a153c0574e020c3a1c7d23b506a3c8771cc98 [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
Oliver Stannardb25914e2015-11-27 13:04:48 +0000355def fixedpoint_f16_i32 : fixedpoint_i32<f16>;
Tim Northover3b0846e2014-05-24 12:50:23 +0000356def fixedpoint_f32_i32 : fixedpoint_i32<f32>;
357def fixedpoint_f64_i32 : fixedpoint_i32<f64>;
358
Oliver Stannardb25914e2015-11-27 13:04:48 +0000359def fixedpoint_f16_i64 : fixedpoint_i64<f16>;
Tim Northover3b0846e2014-05-24 12:50:23 +0000360def fixedpoint_f32_i64 : fixedpoint_i64<f32>;
361def fixedpoint_f64_i64 : fixedpoint_i64<f64>;
362
363def vecshiftR8 : Operand<i32>, ImmLeaf<i32, [{
364 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 9);
365}]> {
366 let EncoderMethod = "getVecShiftR8OpValue";
367 let DecoderMethod = "DecodeVecShiftR8Imm";
368 let ParserMatchClass = Imm1_8Operand;
369}
370def vecshiftR16 : Operand<i32>, ImmLeaf<i32, [{
371 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 17);
372}]> {
373 let EncoderMethod = "getVecShiftR16OpValue";
374 let DecoderMethod = "DecodeVecShiftR16Imm";
375 let ParserMatchClass = Imm1_16Operand;
376}
377def vecshiftR16Narrow : Operand<i32>, ImmLeaf<i32, [{
378 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 9);
379}]> {
380 let EncoderMethod = "getVecShiftR16OpValue";
381 let DecoderMethod = "DecodeVecShiftR16ImmNarrow";
382 let ParserMatchClass = Imm1_8Operand;
383}
384def vecshiftR32 : Operand<i32>, ImmLeaf<i32, [{
385 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 33);
386}]> {
387 let EncoderMethod = "getVecShiftR32OpValue";
388 let DecoderMethod = "DecodeVecShiftR32Imm";
389 let ParserMatchClass = Imm1_32Operand;
390}
391def vecshiftR32Narrow : Operand<i32>, ImmLeaf<i32, [{
392 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 17);
393}]> {
394 let EncoderMethod = "getVecShiftR32OpValue";
395 let DecoderMethod = "DecodeVecShiftR32ImmNarrow";
396 let ParserMatchClass = Imm1_16Operand;
397}
398def vecshiftR64 : Operand<i32>, ImmLeaf<i32, [{
399 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 65);
400}]> {
401 let EncoderMethod = "getVecShiftR64OpValue";
402 let DecoderMethod = "DecodeVecShiftR64Imm";
403 let ParserMatchClass = Imm1_64Operand;
404}
405def vecshiftR64Narrow : Operand<i32>, ImmLeaf<i32, [{
406 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 33);
407}]> {
408 let EncoderMethod = "getVecShiftR64OpValue";
409 let DecoderMethod = "DecodeVecShiftR64ImmNarrow";
410 let ParserMatchClass = Imm1_32Operand;
411}
412
Alexandros Lamprineas1bab1912015-10-05 13:42:31 +0000413def Imm0_1Operand : AsmImmRange<0, 1>;
Tim Northover3b0846e2014-05-24 12:50:23 +0000414def Imm0_7Operand : AsmImmRange<0, 7>;
415def Imm0_15Operand : AsmImmRange<0, 15>;
416def Imm0_31Operand : AsmImmRange<0, 31>;
417def Imm0_63Operand : AsmImmRange<0, 63>;
418
419def vecshiftL8 : Operand<i32>, ImmLeaf<i32, [{
420 return (((uint32_t)Imm) < 8);
421}]> {
422 let EncoderMethod = "getVecShiftL8OpValue";
423 let DecoderMethod = "DecodeVecShiftL8Imm";
424 let ParserMatchClass = Imm0_7Operand;
425}
426def vecshiftL16 : Operand<i32>, ImmLeaf<i32, [{
427 return (((uint32_t)Imm) < 16);
428}]> {
429 let EncoderMethod = "getVecShiftL16OpValue";
430 let DecoderMethod = "DecodeVecShiftL16Imm";
431 let ParserMatchClass = Imm0_15Operand;
432}
433def vecshiftL32 : Operand<i32>, ImmLeaf<i32, [{
434 return (((uint32_t)Imm) < 32);
435}]> {
436 let EncoderMethod = "getVecShiftL32OpValue";
437 let DecoderMethod = "DecodeVecShiftL32Imm";
438 let ParserMatchClass = Imm0_31Operand;
439}
440def vecshiftL64 : Operand<i32>, ImmLeaf<i32, [{
441 return (((uint32_t)Imm) < 64);
442}]> {
443 let EncoderMethod = "getVecShiftL64OpValue";
444 let DecoderMethod = "DecodeVecShiftL64Imm";
445 let ParserMatchClass = Imm0_63Operand;
446}
447
448
449// Crazy immediate formats used by 32-bit and 64-bit logical immediate
450// instructions for splatting repeating bit patterns across the immediate.
451def logical_imm32_XFORM : SDNodeXForm<imm, [{
452 uint64_t enc = AArch64_AM::encodeLogicalImmediate(N->getZExtValue(), 32);
Sergey Dmitrouk842a51b2015-04-28 14:05:47 +0000453 return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32);
Tim Northover3b0846e2014-05-24 12:50:23 +0000454}]>;
455def logical_imm64_XFORM : SDNodeXForm<imm, [{
456 uint64_t enc = AArch64_AM::encodeLogicalImmediate(N->getZExtValue(), 64);
Sergey Dmitrouk842a51b2015-04-28 14:05:47 +0000457 return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32);
Tim Northover3b0846e2014-05-24 12:50:23 +0000458}]>;
459
Arnaud A. de Grandmaisonf6432312014-07-10 15:12:26 +0000460let DiagnosticType = "LogicalSecondSource" in {
461 def LogicalImm32Operand : AsmOperandClass {
462 let Name = "LogicalImm32";
463 }
464 def LogicalImm64Operand : AsmOperandClass {
465 let Name = "LogicalImm64";
466 }
467 def LogicalImm32NotOperand : AsmOperandClass {
468 let Name = "LogicalImm32Not";
469 }
470 def LogicalImm64NotOperand : AsmOperandClass {
471 let Name = "LogicalImm64Not";
472 }
Tim Northover3b0846e2014-05-24 12:50:23 +0000473}
474def logical_imm32 : Operand<i32>, PatLeaf<(imm), [{
475 return AArch64_AM::isLogicalImmediate(N->getZExtValue(), 32);
476}], logical_imm32_XFORM> {
477 let PrintMethod = "printLogicalImm32";
478 let ParserMatchClass = LogicalImm32Operand;
479}
480def logical_imm64 : Operand<i64>, PatLeaf<(imm), [{
481 return AArch64_AM::isLogicalImmediate(N->getZExtValue(), 64);
482}], logical_imm64_XFORM> {
483 let PrintMethod = "printLogicalImm64";
484 let ParserMatchClass = LogicalImm64Operand;
485}
Arnaud A. de Grandmaisonf6432312014-07-10 15:12:26 +0000486def logical_imm32_not : Operand<i32> {
487 let ParserMatchClass = LogicalImm32NotOperand;
488}
489def logical_imm64_not : Operand<i64> {
490 let ParserMatchClass = LogicalImm64NotOperand;
491}
Tim Northover3b0846e2014-05-24 12:50:23 +0000492
493// imm0_65535 predicate - True if the immediate is in the range [0,65535].
494def Imm0_65535Operand : AsmImmRange<0, 65535>;
495def imm0_65535 : Operand<i32>, ImmLeaf<i32, [{
496 return ((uint32_t)Imm) < 65536;
497}]> {
498 let ParserMatchClass = Imm0_65535Operand;
499 let PrintMethod = "printHexImm";
500}
501
502// imm0_255 predicate - True if the immediate is in the range [0,255].
503def Imm0_255Operand : AsmOperandClass { let Name = "Imm0_255"; }
504def imm0_255 : Operand<i32>, ImmLeaf<i32, [{
505 return ((uint32_t)Imm) < 256;
506}]> {
507 let ParserMatchClass = Imm0_255Operand;
508 let PrintMethod = "printHexImm";
509}
510
511// imm0_127 predicate - True if the immediate is in the range [0,127]
512def Imm0_127Operand : AsmImmRange<0, 127>;
513def imm0_127 : Operand<i32>, ImmLeaf<i32, [{
514 return ((uint32_t)Imm) < 128;
515}]> {
516 let ParserMatchClass = Imm0_127Operand;
517 let PrintMethod = "printHexImm";
518}
519
520// NOTE: These imm0_N operands have to be of type i64 because i64 is the size
521// for all shift-amounts.
522
523// imm0_63 predicate - True if the immediate is in the range [0,63]
524def imm0_63 : Operand<i64>, ImmLeaf<i64, [{
525 return ((uint64_t)Imm) < 64;
526}]> {
527 let ParserMatchClass = Imm0_63Operand;
528}
529
530// imm0_31 predicate - True if the immediate is in the range [0,31]
531def imm0_31 : Operand<i64>, ImmLeaf<i64, [{
532 return ((uint64_t)Imm) < 32;
533}]> {
534 let ParserMatchClass = Imm0_31Operand;
535}
536
Matthias Braunaf7d7702015-07-16 20:02:37 +0000537// True if the 32-bit immediate is in the range [0,31]
538def imm32_0_31 : Operand<i32>, ImmLeaf<i32, [{
539 return ((uint64_t)Imm) < 32;
540}]> {
541 let ParserMatchClass = Imm0_31Operand;
542}
543
Alexandros Lamprineas1bab1912015-10-05 13:42:31 +0000544// imm0_1 predicate - True if the immediate is in the range [0,1]
545def imm0_1 : Operand<i64>, ImmLeaf<i64, [{
546 return ((uint64_t)Imm) < 2;
547}]> {
548 let ParserMatchClass = Imm0_1Operand;
549}
550
Tim Northover3b0846e2014-05-24 12:50:23 +0000551// imm0_15 predicate - True if the immediate is in the range [0,15]
552def imm0_15 : Operand<i64>, ImmLeaf<i64, [{
553 return ((uint64_t)Imm) < 16;
554}]> {
555 let ParserMatchClass = Imm0_15Operand;
556}
557
558// imm0_7 predicate - True if the immediate is in the range [0,7]
559def imm0_7 : Operand<i64>, ImmLeaf<i64, [{
560 return ((uint64_t)Imm) < 8;
561}]> {
562 let ParserMatchClass = Imm0_7Operand;
563}
564
Yi Kong23550662014-07-17 10:50:20 +0000565// imm32_0_15 predicate - True if the 32-bit immediate is in the range [0,15]
566def imm32_0_15 : Operand<i32>, ImmLeaf<i32, [{
567 return ((uint32_t)Imm) < 16;
Matthias Braunaf7d7702015-07-16 20:02:37 +0000568}]> {
569 let ParserMatchClass = Imm0_15Operand;
570}
Yi Kong23550662014-07-17 10:50:20 +0000571
Tim Northover3b0846e2014-05-24 12:50:23 +0000572// An arithmetic shifter operand:
573// {7-6} - shift type: 00 = lsl, 01 = lsr, 10 = asr
574// {5-0} - imm6
575class arith_shift<ValueType Ty, int width> : Operand<Ty> {
576 let PrintMethod = "printShifter";
577 let ParserMatchClass = !cast<AsmOperandClass>(
578 "ArithmeticShifterOperand" # width);
579}
580
581def arith_shift32 : arith_shift<i32, 32>;
582def arith_shift64 : arith_shift<i64, 64>;
583
584class arith_shifted_reg<ValueType Ty, RegisterClass regclass, int width>
585 : Operand<Ty>,
586 ComplexPattern<Ty, 2, "SelectArithShiftedRegister", []> {
587 let PrintMethod = "printShiftedRegister";
588 let MIOperandInfo = (ops regclass, !cast<Operand>("arith_shift" # width));
589}
590
591def arith_shifted_reg32 : arith_shifted_reg<i32, GPR32, 32>;
592def arith_shifted_reg64 : arith_shifted_reg<i64, GPR64, 64>;
593
594// An arithmetic shifter operand:
595// {7-6} - shift type: 00 = lsl, 01 = lsr, 10 = asr, 11 = ror
596// {5-0} - imm6
597class logical_shift<int width> : Operand<i32> {
598 let PrintMethod = "printShifter";
599 let ParserMatchClass = !cast<AsmOperandClass>(
600 "LogicalShifterOperand" # width);
601}
602
603def logical_shift32 : logical_shift<32>;
604def logical_shift64 : logical_shift<64>;
605
606class logical_shifted_reg<ValueType Ty, RegisterClass regclass, Operand shiftop>
607 : Operand<Ty>,
608 ComplexPattern<Ty, 2, "SelectLogicalShiftedRegister", []> {
609 let PrintMethod = "printShiftedRegister";
610 let MIOperandInfo = (ops regclass, shiftop);
611}
612
613def logical_shifted_reg32 : logical_shifted_reg<i32, GPR32, logical_shift32>;
614def logical_shifted_reg64 : logical_shifted_reg<i64, GPR64, logical_shift64>;
615
616// A logical vector shifter operand:
617// {7-6} - shift type: 00 = lsl
618// {5-0} - imm6: #0, #8, #16, or #24
619def logical_vec_shift : Operand<i32> {
620 let PrintMethod = "printShifter";
621 let EncoderMethod = "getVecShifterOpValue";
622 let ParserMatchClass = LogicalVecShifterOperand;
623}
624
625// A logical vector half-word shifter operand:
626// {7-6} - shift type: 00 = lsl
627// {5-0} - imm6: #0 or #8
628def logical_vec_hw_shift : Operand<i32> {
629 let PrintMethod = "printShifter";
630 let EncoderMethod = "getVecShifterOpValue";
631 let ParserMatchClass = LogicalVecHalfWordShifterOperand;
632}
633
634// A vector move shifter operand:
635// {0} - imm1: #8 or #16
636def move_vec_shift : Operand<i32> {
637 let PrintMethod = "printShifter";
638 let EncoderMethod = "getMoveVecShifterOpValue";
639 let ParserMatchClass = MoveVecShifterOperand;
640}
641
Arnaud A. de Grandmaison650c5202015-07-01 15:05:58 +0000642let DiagnosticType = "AddSubSecondSource" in {
643 def AddSubImmOperand : AsmOperandClass {
644 let Name = "AddSubImm";
645 let ParserMethod = "tryParseAddSubImm";
646 }
647 def AddSubImmNegOperand : AsmOperandClass {
648 let Name = "AddSubImmNeg";
649 let ParserMethod = "tryParseAddSubImm";
650 }
Tim Northover3b0846e2014-05-24 12:50:23 +0000651}
652// An ADD/SUB immediate shifter operand:
653// second operand:
654// {7-6} - shift type: 00 = lsl
655// {5-0} - imm6: #0 or #12
656class addsub_shifted_imm<ValueType Ty>
657 : Operand<Ty>, ComplexPattern<Ty, 2, "SelectArithImmed", [imm]> {
658 let PrintMethod = "printAddSubImm";
659 let EncoderMethod = "getAddSubImmOpValue";
660 let ParserMatchClass = AddSubImmOperand;
661 let MIOperandInfo = (ops i32imm, i32imm);
662}
663
Arnaud A. de Grandmaison650c5202015-07-01 15:05:58 +0000664class addsub_shifted_imm_neg<ValueType Ty>
665 : Operand<Ty> {
666 let EncoderMethod = "getAddSubImmOpValue";
667 let ParserMatchClass = AddSubImmNegOperand;
668 let MIOperandInfo = (ops i32imm, i32imm);
669}
670
Tim Northover3b0846e2014-05-24 12:50:23 +0000671def addsub_shifted_imm32 : addsub_shifted_imm<i32>;
672def addsub_shifted_imm64 : addsub_shifted_imm<i64>;
Arnaud A. de Grandmaison650c5202015-07-01 15:05:58 +0000673def addsub_shifted_imm32_neg : addsub_shifted_imm_neg<i32>;
674def addsub_shifted_imm64_neg : addsub_shifted_imm_neg<i64>;
Tim Northover3b0846e2014-05-24 12:50:23 +0000675
676class neg_addsub_shifted_imm<ValueType Ty>
677 : Operand<Ty>, ComplexPattern<Ty, 2, "SelectNegArithImmed", [imm]> {
678 let PrintMethod = "printAddSubImm";
679 let EncoderMethod = "getAddSubImmOpValue";
680 let ParserMatchClass = AddSubImmOperand;
681 let MIOperandInfo = (ops i32imm, i32imm);
682}
683
684def neg_addsub_shifted_imm32 : neg_addsub_shifted_imm<i32>;
685def neg_addsub_shifted_imm64 : neg_addsub_shifted_imm<i64>;
686
687// An extend operand:
688// {5-3} - extend type
689// {2-0} - imm3
690def arith_extend : Operand<i32> {
691 let PrintMethod = "printArithExtend";
692 let ParserMatchClass = ExtendOperand;
693}
694def arith_extend64 : Operand<i32> {
695 let PrintMethod = "printArithExtend";
696 let ParserMatchClass = ExtendOperand64;
697}
698
699// 'extend' that's a lsl of a 64-bit register.
700def arith_extendlsl64 : Operand<i32> {
701 let PrintMethod = "printArithExtend";
702 let ParserMatchClass = ExtendOperandLSL64;
703}
704
705class arith_extended_reg32<ValueType Ty> : Operand<Ty>,
706 ComplexPattern<Ty, 2, "SelectArithExtendedRegister", []> {
707 let PrintMethod = "printExtendedRegister";
708 let MIOperandInfo = (ops GPR32, arith_extend);
709}
710
711class arith_extended_reg32to64<ValueType Ty> : Operand<Ty>,
712 ComplexPattern<Ty, 2, "SelectArithExtendedRegister", []> {
713 let PrintMethod = "printExtendedRegister";
714 let MIOperandInfo = (ops GPR32, arith_extend64);
715}
716
717// Floating-point immediate.
Oliver Stannardb25914e2015-11-27 13:04:48 +0000718def fpimm16 : Operand<f16>,
719 PatLeaf<(f16 fpimm), [{
720 return AArch64_AM::getFP16Imm(N->getValueAPF()) != -1;
721 }], SDNodeXForm<fpimm, [{
722 APFloat InVal = N->getValueAPF();
723 uint32_t enc = AArch64_AM::getFP16Imm(InVal);
724 return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32);
725 }]>> {
726 let ParserMatchClass = FPImmOperand;
727 let PrintMethod = "printFPImmOperand";
728}
Tim Northover3b0846e2014-05-24 12:50:23 +0000729def fpimm32 : Operand<f32>,
730 PatLeaf<(f32 fpimm), [{
731 return AArch64_AM::getFP32Imm(N->getValueAPF()) != -1;
732 }], SDNodeXForm<fpimm, [{
733 APFloat InVal = N->getValueAPF();
734 uint32_t enc = AArch64_AM::getFP32Imm(InVal);
Sergey Dmitrouk842a51b2015-04-28 14:05:47 +0000735 return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32);
Tim Northover3b0846e2014-05-24 12:50:23 +0000736 }]>> {
737 let ParserMatchClass = FPImmOperand;
738 let PrintMethod = "printFPImmOperand";
739}
740def fpimm64 : Operand<f64>,
741 PatLeaf<(f64 fpimm), [{
742 return AArch64_AM::getFP64Imm(N->getValueAPF()) != -1;
743 }], SDNodeXForm<fpimm, [{
744 APFloat InVal = N->getValueAPF();
745 uint32_t enc = AArch64_AM::getFP64Imm(InVal);
Sergey Dmitrouk842a51b2015-04-28 14:05:47 +0000746 return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32);
Tim Northover3b0846e2014-05-24 12:50:23 +0000747 }]>> {
748 let ParserMatchClass = FPImmOperand;
749 let PrintMethod = "printFPImmOperand";
750}
751
752def fpimm8 : Operand<i32> {
753 let ParserMatchClass = FPImmOperand;
754 let PrintMethod = "printFPImmOperand";
755}
756
757def fpimm0 : PatLeaf<(fpimm), [{
758 return N->isExactlyValue(+0.0);
759}]>;
760
761// Vector lane operands
762class AsmVectorIndex<string Suffix> : AsmOperandClass {
763 let Name = "VectorIndex" # Suffix;
764 let DiagnosticType = "InvalidIndex" # Suffix;
765}
766def VectorIndex1Operand : AsmVectorIndex<"1">;
767def VectorIndexBOperand : AsmVectorIndex<"B">;
768def VectorIndexHOperand : AsmVectorIndex<"H">;
769def VectorIndexSOperand : AsmVectorIndex<"S">;
770def VectorIndexDOperand : AsmVectorIndex<"D">;
771
772def VectorIndex1 : Operand<i64>, ImmLeaf<i64, [{
773 return ((uint64_t)Imm) == 1;
774}]> {
775 let ParserMatchClass = VectorIndex1Operand;
776 let PrintMethod = "printVectorIndex";
777 let MIOperandInfo = (ops i64imm);
778}
779def VectorIndexB : Operand<i64>, ImmLeaf<i64, [{
780 return ((uint64_t)Imm) < 16;
781}]> {
782 let ParserMatchClass = VectorIndexBOperand;
783 let PrintMethod = "printVectorIndex";
784 let MIOperandInfo = (ops i64imm);
785}
786def VectorIndexH : Operand<i64>, ImmLeaf<i64, [{
787 return ((uint64_t)Imm) < 8;
788}]> {
789 let ParserMatchClass = VectorIndexHOperand;
790 let PrintMethod = "printVectorIndex";
791 let MIOperandInfo = (ops i64imm);
792}
793def VectorIndexS : Operand<i64>, ImmLeaf<i64, [{
794 return ((uint64_t)Imm) < 4;
795}]> {
796 let ParserMatchClass = VectorIndexSOperand;
797 let PrintMethod = "printVectorIndex";
798 let MIOperandInfo = (ops i64imm);
799}
800def VectorIndexD : Operand<i64>, ImmLeaf<i64, [{
801 return ((uint64_t)Imm) < 2;
802}]> {
803 let ParserMatchClass = VectorIndexDOperand;
804 let PrintMethod = "printVectorIndex";
805 let MIOperandInfo = (ops i64imm);
806}
807
808// 8-bit immediate for AdvSIMD where 64-bit values of the form:
809// aaaaaaaa bbbbbbbb cccccccc dddddddd eeeeeeee ffffffff gggggggg hhhhhhhh
810// are encoded as the eight bit value 'abcdefgh'.
811def simdimmtype10 : Operand<i32>,
812 PatLeaf<(f64 fpimm), [{
813 return AArch64_AM::isAdvSIMDModImmType10(N->getValueAPF()
814 .bitcastToAPInt()
815 .getZExtValue());
816 }], SDNodeXForm<fpimm, [{
817 APFloat InVal = N->getValueAPF();
818 uint32_t enc = AArch64_AM::encodeAdvSIMDModImmType10(N->getValueAPF()
819 .bitcastToAPInt()
820 .getZExtValue());
Sergey Dmitrouk842a51b2015-04-28 14:05:47 +0000821 return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32);
Tim Northover3b0846e2014-05-24 12:50:23 +0000822 }]>> {
823 let ParserMatchClass = SIMDImmType10Operand;
824 let PrintMethod = "printSIMDType10Operand";
825}
826
827
828//---
829// System management
830//---
831
832// Base encoding for system instruction operands.
833let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in
Saleem Abdulrasoolf74d48a2014-07-12 21:20:49 +0000834class BaseSystemI<bit L, dag oops, dag iops, string asm, string operands,
835 list<dag> pattern = []>
836 : I<oops, iops, asm, operands, "", pattern> {
Tim Northover3b0846e2014-05-24 12:50:23 +0000837 let Inst{31-22} = 0b1101010100;
838 let Inst{21} = L;
839}
840
841// System instructions which do not have an Rt register.
Saleem Abdulrasoolf74d48a2014-07-12 21:20:49 +0000842class SimpleSystemI<bit L, dag iops, string asm, string operands,
843 list<dag> pattern = []>
844 : BaseSystemI<L, (outs), iops, asm, operands, pattern> {
Tim Northover3b0846e2014-05-24 12:50:23 +0000845 let Inst{4-0} = 0b11111;
846}
847
848// System instructions which have an Rt register.
849class RtSystemI<bit L, dag oops, dag iops, string asm, string operands>
850 : BaseSystemI<L, oops, iops, asm, operands>,
851 Sched<[WriteSys]> {
852 bits<5> Rt;
853 let Inst{4-0} = Rt;
854}
855
856// Hint instructions that take both a CRm and a 3-bit immediate.
Saleem Abdulrasoolf74d48a2014-07-12 21:20:49 +0000857// NOTE: ideally, this would have mayStore = 0, mayLoad = 0, but we cannot
858// model patterns with sufficiently fine granularity
859let mayStore = 1, mayLoad = 1, hasSideEffects = 1 in
860 class HintI<string mnemonic>
Ahmed Bougacha63fae0e2015-09-02 18:52:54 +0000861 : SimpleSystemI<0, (ins imm0_127:$imm), mnemonic#"\t$imm", "",
Saleem Abdulrasoolf74d48a2014-07-12 21:20:49 +0000862 [(int_aarch64_hint imm0_127:$imm)]>,
863 Sched<[WriteHint]> {
864 bits <7> imm;
865 let Inst{20-12} = 0b000110010;
866 let Inst{11-5} = imm;
867 }
Tim Northover3b0846e2014-05-24 12:50:23 +0000868
869// System instructions taking a single literal operand which encodes into
870// CRm. op2 differentiates the opcodes.
871def BarrierAsmOperand : AsmOperandClass {
872 let Name = "Barrier";
873 let ParserMethod = "tryParseBarrierOperand";
874}
875def barrier_op : Operand<i32> {
876 let PrintMethod = "printBarrierOption";
877 let ParserMatchClass = BarrierAsmOperand;
878}
Yi Kong23550662014-07-17 10:50:20 +0000879class CRmSystemI<Operand crmtype, bits<3> opc, string asm,
880 list<dag> pattern = []>
881 : SimpleSystemI<0, (ins crmtype:$CRm), asm, "\t$CRm", pattern>,
Tim Northover3b0846e2014-05-24 12:50:23 +0000882 Sched<[WriteBarrier]> {
883 bits<4> CRm;
884 let Inst{20-12} = 0b000110011;
885 let Inst{11-8} = CRm;
886 let Inst{7-5} = opc;
887}
888
889// MRS/MSR system instructions. These have different operand classes because
890// a different subset of registers can be accessed through each instruction.
891def MRSSystemRegisterOperand : AsmOperandClass {
892 let Name = "MRSSystemRegister";
893 let ParserMethod = "tryParseSysReg";
894 let DiagnosticType = "MRS";
895}
Tom Coxone493f172014-10-01 10:13:59 +0000896// concatenation of op0, op1, CRn, CRm, op2. 16-bit immediate.
Tim Northover3b0846e2014-05-24 12:50:23 +0000897def mrs_sysreg_op : Operand<i32> {
898 let ParserMatchClass = MRSSystemRegisterOperand;
899 let DecoderMethod = "DecodeMRSSystemRegister";
900 let PrintMethod = "printMRSSystemRegister";
901}
902
903def MSRSystemRegisterOperand : AsmOperandClass {
904 let Name = "MSRSystemRegister";
905 let ParserMethod = "tryParseSysReg";
906 let DiagnosticType = "MSR";
907}
908def msr_sysreg_op : Operand<i32> {
909 let ParserMatchClass = MSRSystemRegisterOperand;
910 let DecoderMethod = "DecodeMSRSystemRegister";
911 let PrintMethod = "printMSRSystemRegister";
912}
913
914class MRSI : RtSystemI<1, (outs GPR64:$Rt), (ins mrs_sysreg_op:$systemreg),
915 "mrs", "\t$Rt, $systemreg"> {
Tom Coxone493f172014-10-01 10:13:59 +0000916 bits<16> systemreg;
917 let Inst{20-5} = systemreg;
Tim Northover3b0846e2014-05-24 12:50:23 +0000918}
919
920// FIXME: Some of these def NZCV, others don't. Best way to model that?
921// Explicitly modeling each of the system register as a register class
922// would do it, but feels like overkill at this point.
923class MSRI : RtSystemI<0, (outs), (ins msr_sysreg_op:$systemreg, GPR64:$Rt),
924 "msr", "\t$systemreg, $Rt"> {
Tom Coxone493f172014-10-01 10:13:59 +0000925 bits<16> systemreg;
926 let Inst{20-5} = systemreg;
Tim Northover3b0846e2014-05-24 12:50:23 +0000927}
928
Alexandros Lamprineas1bab1912015-10-05 13:42:31 +0000929def SystemPStateFieldWithImm0_15Operand : AsmOperandClass {
930 let Name = "SystemPStateFieldWithImm0_15";
Tim Northover3b0846e2014-05-24 12:50:23 +0000931 let ParserMethod = "tryParseSysReg";
932}
Alexandros Lamprineas1bab1912015-10-05 13:42:31 +0000933def pstatefield4_op : Operand<i32> {
934 let ParserMatchClass = SystemPStateFieldWithImm0_15Operand;
Tim Northover3b0846e2014-05-24 12:50:23 +0000935 let PrintMethod = "printSystemPStateField";
936}
937
938let Defs = [NZCV] in
Alexandros Lamprineas1bab1912015-10-05 13:42:31 +0000939class MSRpstateImm0_15
940 : SimpleSystemI<0, (ins pstatefield4_op:$pstatefield, imm0_15:$imm),
941 "msr", "\t$pstatefield, $imm">,
Tim Northover3b0846e2014-05-24 12:50:23 +0000942 Sched<[WriteSys]> {
943 bits<6> pstatefield;
944 bits<4> imm;
945 let Inst{20-19} = 0b00;
946 let Inst{18-16} = pstatefield{5-3};
947 let Inst{15-12} = 0b0100;
948 let Inst{11-8} = imm;
949 let Inst{7-5} = pstatefield{2-0};
950
951 let DecoderMethod = "DecodeSystemPStateInstruction";
Petr Pavlu097adfb2015-07-15 08:10:30 +0000952 // MSRpstateI aliases with MSRI. When the MSRpstateI decoder method returns
953 // Fail the decoder should attempt to decode the instruction as MSRI.
954 let hasCompleteDecoder = 0;
Tim Northover3b0846e2014-05-24 12:50:23 +0000955}
956
Alexandros Lamprineas1bab1912015-10-05 13:42:31 +0000957def SystemPStateFieldWithImm0_1Operand : AsmOperandClass {
958 let Name = "SystemPStateFieldWithImm0_1";
959 let ParserMethod = "tryParseSysReg";
960}
961def pstatefield1_op : Operand<i32> {
962 let ParserMatchClass = SystemPStateFieldWithImm0_1Operand;
963 let PrintMethod = "printSystemPStateField";
964}
965
966let Defs = [NZCV] in
967class MSRpstateImm0_1
968 : SimpleSystemI<0, (ins pstatefield1_op:$pstatefield, imm0_1:$imm),
969 "msr", "\t$pstatefield, $imm">,
970 Sched<[WriteSys]> {
971 bits<6> pstatefield;
972 bit imm;
973 let Inst{20-19} = 0b00;
974 let Inst{18-16} = pstatefield{5-3};
975 let Inst{15-9} = 0b0100000;
976 let Inst{8} = imm;
977 let Inst{7-5} = pstatefield{2-0};
978
979 let DecoderMethod = "DecodeSystemPStateInstruction";
980 // MSRpstateI aliases with MSRI. When the MSRpstateI decoder method returns
981 // Fail the decoder should attempt to decode the instruction as MSRI.
982 let hasCompleteDecoder = 0;
983}
984
Tim Northover3b0846e2014-05-24 12:50:23 +0000985// SYS and SYSL generic system instructions.
986def SysCRAsmOperand : AsmOperandClass {
987 let Name = "SysCR";
988 let ParserMethod = "tryParseSysCROperand";
989}
990
991def sys_cr_op : Operand<i32> {
992 let PrintMethod = "printSysCROperand";
993 let ParserMatchClass = SysCRAsmOperand;
994}
995
996class SystemXtI<bit L, string asm>
997 : RtSystemI<L, (outs),
998 (ins imm0_7:$op1, sys_cr_op:$Cn, sys_cr_op:$Cm, imm0_7:$op2, GPR64:$Rt),
999 asm, "\t$op1, $Cn, $Cm, $op2, $Rt"> {
1000 bits<3> op1;
1001 bits<4> Cn;
1002 bits<4> Cm;
1003 bits<3> op2;
1004 let Inst{20-19} = 0b01;
1005 let Inst{18-16} = op1;
1006 let Inst{15-12} = Cn;
1007 let Inst{11-8} = Cm;
1008 let Inst{7-5} = op2;
1009}
1010
1011class SystemLXtI<bit L, string asm>
1012 : RtSystemI<L, (outs),
1013 (ins GPR64:$Rt, imm0_7:$op1, sys_cr_op:$Cn, sys_cr_op:$Cm, imm0_7:$op2),
1014 asm, "\t$Rt, $op1, $Cn, $Cm, $op2"> {
1015 bits<3> op1;
1016 bits<4> Cn;
1017 bits<4> Cm;
1018 bits<3> op2;
1019 let Inst{20-19} = 0b01;
1020 let Inst{18-16} = op1;
1021 let Inst{15-12} = Cn;
1022 let Inst{11-8} = Cm;
1023 let Inst{7-5} = op2;
1024}
1025
1026
1027// Branch (register) instructions:
1028//
1029// case opc of
1030// 0001 blr
1031// 0000 br
1032// 0101 dret
1033// 0100 eret
1034// 0010 ret
1035// otherwise UNDEFINED
1036class BaseBranchReg<bits<4> opc, dag oops, dag iops, string asm,
1037 string operands, list<dag> pattern>
1038 : I<oops, iops, asm, operands, "", pattern>, Sched<[WriteBrReg]> {
1039 let Inst{31-25} = 0b1101011;
1040 let Inst{24-21} = opc;
1041 let Inst{20-16} = 0b11111;
1042 let Inst{15-10} = 0b000000;
1043 let Inst{4-0} = 0b00000;
1044}
1045
1046class BranchReg<bits<4> opc, string asm, list<dag> pattern>
1047 : BaseBranchReg<opc, (outs), (ins GPR64:$Rn), asm, "\t$Rn", pattern> {
1048 bits<5> Rn;
1049 let Inst{9-5} = Rn;
1050}
1051
1052let mayLoad = 0, mayStore = 0, hasSideEffects = 1, isReturn = 1 in
1053class SpecialReturn<bits<4> opc, string asm>
1054 : BaseBranchReg<opc, (outs), (ins), asm, "", []> {
1055 let Inst{9-5} = 0b11111;
1056}
1057
1058//---
1059// Conditional branch instruction.
1060//---
1061
1062// Condition code.
1063// 4-bit immediate. Pretty-printed as <cc>
1064def ccode : Operand<i32> {
1065 let PrintMethod = "printCondCode";
1066 let ParserMatchClass = CondCode;
1067}
1068def inv_ccode : Operand<i32> {
Artyom Skrobov6c8682e2014-06-10 13:11:35 +00001069 // AL and NV are invalid in the aliases which use inv_ccode
Tim Northover3b0846e2014-05-24 12:50:23 +00001070 let PrintMethod = "printInverseCondCode";
1071 let ParserMatchClass = CondCode;
Artyom Skrobov6c8682e2014-06-10 13:11:35 +00001072 let MCOperandPredicate = [{
1073 return MCOp.isImm() &&
1074 MCOp.getImm() != AArch64CC::AL &&
1075 MCOp.getImm() != AArch64CC::NV;
1076 }];
Tim Northover3b0846e2014-05-24 12:50:23 +00001077}
1078
1079// Conditional branch target. 19-bit immediate. The low two bits of the target
1080// offset are implied zero and so are not part of the immediate.
1081def PCRelLabel19Operand : AsmOperandClass {
1082 let Name = "PCRelLabel19";
1083 let DiagnosticType = "InvalidLabel";
1084}
1085def am_brcond : Operand<OtherVT> {
1086 let EncoderMethod = "getCondBranchTargetOpValue";
1087 let DecoderMethod = "DecodePCRelLabel19";
1088 let PrintMethod = "printAlignedLabel";
1089 let ParserMatchClass = PCRelLabel19Operand;
1090}
1091
1092class BranchCond : I<(outs), (ins ccode:$cond, am_brcond:$target),
1093 "b", ".$cond\t$target", "",
1094 [(AArch64brcond bb:$target, imm:$cond, NZCV)]>,
1095 Sched<[WriteBr]> {
1096 let isBranch = 1;
1097 let isTerminator = 1;
1098 let Uses = [NZCV];
1099
1100 bits<4> cond;
1101 bits<19> target;
1102 let Inst{31-24} = 0b01010100;
1103 let Inst{23-5} = target;
1104 let Inst{4} = 0;
1105 let Inst{3-0} = cond;
1106}
1107
1108//---
1109// Compare-and-branch instructions.
1110//---
1111class BaseCmpBranch<RegisterClass regtype, bit op, string asm, SDNode node>
1112 : I<(outs), (ins regtype:$Rt, am_brcond:$target),
1113 asm, "\t$Rt, $target", "",
1114 [(node regtype:$Rt, bb:$target)]>,
1115 Sched<[WriteBr]> {
1116 let isBranch = 1;
1117 let isTerminator = 1;
1118
1119 bits<5> Rt;
1120 bits<19> target;
1121 let Inst{30-25} = 0b011010;
1122 let Inst{24} = op;
1123 let Inst{23-5} = target;
1124 let Inst{4-0} = Rt;
1125}
1126
1127multiclass CmpBranch<bit op, string asm, SDNode node> {
1128 def W : BaseCmpBranch<GPR32, op, asm, node> {
1129 let Inst{31} = 0;
1130 }
1131 def X : BaseCmpBranch<GPR64, op, asm, node> {
1132 let Inst{31} = 1;
1133 }
1134}
1135
1136//---
1137// Test-bit-and-branch instructions.
1138//---
1139// Test-and-branch target. 14-bit sign-extended immediate. The low two bits of
1140// the target offset are implied zero and so are not part of the immediate.
1141def BranchTarget14Operand : AsmOperandClass {
1142 let Name = "BranchTarget14";
1143}
1144def am_tbrcond : Operand<OtherVT> {
1145 let EncoderMethod = "getTestBranchTargetOpValue";
1146 let PrintMethod = "printAlignedLabel";
1147 let ParserMatchClass = BranchTarget14Operand;
1148}
1149
1150// AsmOperand classes to emit (or not) special diagnostics
1151def TBZImm0_31Operand : AsmOperandClass {
1152 let Name = "TBZImm0_31";
1153 let PredicateMethod = "isImm0_31";
1154 let RenderMethod = "addImm0_31Operands";
1155}
1156def TBZImm32_63Operand : AsmOperandClass {
1157 let Name = "Imm32_63";
1158 let DiagnosticType = "InvalidImm0_63";
1159}
1160
1161class tbz_imm0_31<AsmOperandClass matcher> : Operand<i64>, ImmLeaf<i64, [{
1162 return (((uint32_t)Imm) < 32);
1163}]> {
1164 let ParserMatchClass = matcher;
1165}
1166
1167def tbz_imm0_31_diag : tbz_imm0_31<Imm0_31Operand>;
1168def tbz_imm0_31_nodiag : tbz_imm0_31<TBZImm0_31Operand>;
1169
1170def tbz_imm32_63 : Operand<i64>, ImmLeaf<i64, [{
1171 return (((uint32_t)Imm) > 31) && (((uint32_t)Imm) < 64);
1172}]> {
1173 let ParserMatchClass = TBZImm32_63Operand;
1174}
1175
1176class BaseTestBranch<RegisterClass regtype, Operand immtype,
1177 bit op, string asm, SDNode node>
1178 : I<(outs), (ins regtype:$Rt, immtype:$bit_off, am_tbrcond:$target),
1179 asm, "\t$Rt, $bit_off, $target", "",
1180 [(node regtype:$Rt, immtype:$bit_off, bb:$target)]>,
1181 Sched<[WriteBr]> {
1182 let isBranch = 1;
1183 let isTerminator = 1;
1184
1185 bits<5> Rt;
1186 bits<6> bit_off;
1187 bits<14> target;
1188
1189 let Inst{30-25} = 0b011011;
1190 let Inst{24} = op;
1191 let Inst{23-19} = bit_off{4-0};
1192 let Inst{18-5} = target;
1193 let Inst{4-0} = Rt;
1194
1195 let DecoderMethod = "DecodeTestAndBranch";
1196}
1197
1198multiclass TestBranch<bit op, string asm, SDNode node> {
1199 def W : BaseTestBranch<GPR32, tbz_imm0_31_diag, op, asm, node> {
1200 let Inst{31} = 0;
1201 }
1202
1203 def X : BaseTestBranch<GPR64, tbz_imm32_63, op, asm, node> {
1204 let Inst{31} = 1;
1205 }
1206
1207 // Alias X-reg with 0-31 imm to W-Reg.
1208 def : InstAlias<asm # "\t$Rd, $imm, $target",
1209 (!cast<Instruction>(NAME#"W") GPR32as64:$Rd,
1210 tbz_imm0_31_nodiag:$imm, am_tbrcond:$target), 0>;
1211 def : Pat<(node GPR64:$Rn, tbz_imm0_31_diag:$imm, bb:$target),
1212 (!cast<Instruction>(NAME#"W") (EXTRACT_SUBREG GPR64:$Rn, sub_32),
1213 tbz_imm0_31_diag:$imm, bb:$target)>;
1214}
1215
1216//---
1217// Unconditional branch (immediate) instructions.
1218//---
1219def BranchTarget26Operand : AsmOperandClass {
1220 let Name = "BranchTarget26";
1221 let DiagnosticType = "InvalidLabel";
1222}
1223def am_b_target : Operand<OtherVT> {
1224 let EncoderMethod = "getBranchTargetOpValue";
1225 let PrintMethod = "printAlignedLabel";
1226 let ParserMatchClass = BranchTarget26Operand;
1227}
1228def am_bl_target : Operand<i64> {
1229 let EncoderMethod = "getBranchTargetOpValue";
1230 let PrintMethod = "printAlignedLabel";
1231 let ParserMatchClass = BranchTarget26Operand;
1232}
1233
1234class BImm<bit op, dag iops, string asm, list<dag> pattern>
1235 : I<(outs), iops, asm, "\t$addr", "", pattern>, Sched<[WriteBr]> {
1236 bits<26> addr;
1237 let Inst{31} = op;
1238 let Inst{30-26} = 0b00101;
1239 let Inst{25-0} = addr;
1240
1241 let DecoderMethod = "DecodeUnconditionalBranch";
1242}
1243
1244class BranchImm<bit op, string asm, list<dag> pattern>
1245 : BImm<op, (ins am_b_target:$addr), asm, pattern>;
1246class CallImm<bit op, string asm, list<dag> pattern>
1247 : BImm<op, (ins am_bl_target:$addr), asm, pattern>;
1248
1249//---
1250// Basic one-operand data processing instructions.
1251//---
1252
1253let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
1254class BaseOneOperandData<bits<3> opc, RegisterClass regtype, string asm,
1255 SDPatternOperator node>
1256 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm, "\t$Rd, $Rn", "",
1257 [(set regtype:$Rd, (node regtype:$Rn))]>,
1258 Sched<[WriteI, ReadI]> {
1259 bits<5> Rd;
1260 bits<5> Rn;
1261
1262 let Inst{30-13} = 0b101101011000000000;
1263 let Inst{12-10} = opc;
1264 let Inst{9-5} = Rn;
1265 let Inst{4-0} = Rd;
1266}
1267
1268let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
1269multiclass OneOperandData<bits<3> opc, string asm,
1270 SDPatternOperator node = null_frag> {
1271 def Wr : BaseOneOperandData<opc, GPR32, asm, node> {
1272 let Inst{31} = 0;
1273 }
1274
1275 def Xr : BaseOneOperandData<opc, GPR64, asm, node> {
1276 let Inst{31} = 1;
1277 }
1278}
1279
1280class OneWRegData<bits<3> opc, string asm, SDPatternOperator node>
1281 : BaseOneOperandData<opc, GPR32, asm, node> {
1282 let Inst{31} = 0;
1283}
1284
1285class OneXRegData<bits<3> opc, string asm, SDPatternOperator node>
1286 : BaseOneOperandData<opc, GPR64, asm, node> {
1287 let Inst{31} = 1;
1288}
1289
1290//---
1291// Basic two-operand data processing instructions.
1292//---
1293class BaseBaseAddSubCarry<bit isSub, RegisterClass regtype, string asm,
1294 list<dag> pattern>
1295 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm),
1296 asm, "\t$Rd, $Rn, $Rm", "", pattern>,
1297 Sched<[WriteI, ReadI, ReadI]> {
1298 let Uses = [NZCV];
1299 bits<5> Rd;
1300 bits<5> Rn;
1301 bits<5> Rm;
1302 let Inst{30} = isSub;
1303 let Inst{28-21} = 0b11010000;
1304 let Inst{20-16} = Rm;
1305 let Inst{15-10} = 0;
1306 let Inst{9-5} = Rn;
1307 let Inst{4-0} = Rd;
1308}
1309
1310class BaseAddSubCarry<bit isSub, RegisterClass regtype, string asm,
1311 SDNode OpNode>
1312 : BaseBaseAddSubCarry<isSub, regtype, asm,
1313 [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm, NZCV))]>;
1314
1315class BaseAddSubCarrySetFlags<bit isSub, RegisterClass regtype, string asm,
1316 SDNode OpNode>
1317 : BaseBaseAddSubCarry<isSub, regtype, asm,
1318 [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm, NZCV)),
1319 (implicit NZCV)]> {
1320 let Defs = [NZCV];
1321}
1322
1323multiclass AddSubCarry<bit isSub, string asm, string asm_setflags,
1324 SDNode OpNode, SDNode OpNode_setflags> {
1325 def Wr : BaseAddSubCarry<isSub, GPR32, asm, OpNode> {
1326 let Inst{31} = 0;
1327 let Inst{29} = 0;
1328 }
1329 def Xr : BaseAddSubCarry<isSub, GPR64, asm, OpNode> {
1330 let Inst{31} = 1;
1331 let Inst{29} = 0;
1332 }
1333
1334 // Sets flags.
1335 def SWr : BaseAddSubCarrySetFlags<isSub, GPR32, asm_setflags,
1336 OpNode_setflags> {
1337 let Inst{31} = 0;
1338 let Inst{29} = 1;
1339 }
1340 def SXr : BaseAddSubCarrySetFlags<isSub, GPR64, asm_setflags,
1341 OpNode_setflags> {
1342 let Inst{31} = 1;
1343 let Inst{29} = 1;
1344 }
1345}
1346
1347class BaseTwoOperand<bits<4> opc, RegisterClass regtype, string asm,
1348 SDPatternOperator OpNode>
1349 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm),
1350 asm, "\t$Rd, $Rn, $Rm", "",
1351 [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm))]> {
1352 bits<5> Rd;
1353 bits<5> Rn;
1354 bits<5> Rm;
1355 let Inst{30-21} = 0b0011010110;
1356 let Inst{20-16} = Rm;
1357 let Inst{15-14} = 0b00;
1358 let Inst{13-10} = opc;
1359 let Inst{9-5} = Rn;
1360 let Inst{4-0} = Rd;
1361}
1362
1363class BaseDiv<bit isSigned, RegisterClass regtype, string asm,
1364 SDPatternOperator OpNode>
1365 : BaseTwoOperand<{0,0,1,?}, regtype, asm, OpNode> {
1366 let Inst{10} = isSigned;
1367}
1368
1369multiclass Div<bit isSigned, string asm, SDPatternOperator OpNode> {
1370 def Wr : BaseDiv<isSigned, GPR32, asm, OpNode>,
1371 Sched<[WriteID32, ReadID, ReadID]> {
1372 let Inst{31} = 0;
1373 }
1374 def Xr : BaseDiv<isSigned, GPR64, asm, OpNode>,
1375 Sched<[WriteID64, ReadID, ReadID]> {
1376 let Inst{31} = 1;
1377 }
1378}
1379
1380class BaseShift<bits<2> shift_type, RegisterClass regtype, string asm,
1381 SDPatternOperator OpNode = null_frag>
1382 : BaseTwoOperand<{1,0,?,?}, regtype, asm, OpNode>,
1383 Sched<[WriteIS, ReadI]> {
1384 let Inst{11-10} = shift_type;
1385}
1386
1387multiclass Shift<bits<2> shift_type, string asm, SDNode OpNode> {
1388 def Wr : BaseShift<shift_type, GPR32, asm> {
1389 let Inst{31} = 0;
1390 }
1391
1392 def Xr : BaseShift<shift_type, GPR64, asm, OpNode> {
1393 let Inst{31} = 1;
1394 }
1395
1396 def : Pat<(i32 (OpNode GPR32:$Rn, i64:$Rm)),
1397 (!cast<Instruction>(NAME # "Wr") GPR32:$Rn,
1398 (EXTRACT_SUBREG i64:$Rm, sub_32))>;
1399
1400 def : Pat<(i32 (OpNode GPR32:$Rn, (i64 (zext GPR32:$Rm)))),
1401 (!cast<Instruction>(NAME # "Wr") GPR32:$Rn, GPR32:$Rm)>;
1402
1403 def : Pat<(i32 (OpNode GPR32:$Rn, (i64 (anyext GPR32:$Rm)))),
1404 (!cast<Instruction>(NAME # "Wr") GPR32:$Rn, GPR32:$Rm)>;
1405
1406 def : Pat<(i32 (OpNode GPR32:$Rn, (i64 (sext GPR32:$Rm)))),
1407 (!cast<Instruction>(NAME # "Wr") GPR32:$Rn, GPR32:$Rm)>;
1408}
1409
1410class ShiftAlias<string asm, Instruction inst, RegisterClass regtype>
Ahmed Bougacha63fae0e2015-09-02 18:52:54 +00001411 : InstAlias<asm#"\t$dst, $src1, $src2",
Tim Northover3b0846e2014-05-24 12:50:23 +00001412 (inst regtype:$dst, regtype:$src1, regtype:$src2), 0>;
1413
1414class BaseMulAccum<bit isSub, bits<3> opc, RegisterClass multype,
1415 RegisterClass addtype, string asm,
1416 list<dag> pattern>
1417 : I<(outs addtype:$Rd), (ins multype:$Rn, multype:$Rm, addtype:$Ra),
1418 asm, "\t$Rd, $Rn, $Rm, $Ra", "", pattern> {
1419 bits<5> Rd;
1420 bits<5> Rn;
1421 bits<5> Rm;
1422 bits<5> Ra;
1423 let Inst{30-24} = 0b0011011;
1424 let Inst{23-21} = opc;
1425 let Inst{20-16} = Rm;
1426 let Inst{15} = isSub;
1427 let Inst{14-10} = Ra;
1428 let Inst{9-5} = Rn;
1429 let Inst{4-0} = Rd;
1430}
1431
1432multiclass MulAccum<bit isSub, string asm, SDNode AccNode> {
Gerolf Hoflehner97c383b2014-08-07 21:40:58 +00001433 // MADD/MSUB generation is decided by MachineCombiner.cpp
Tim Northover3b0846e2014-05-24 12:50:23 +00001434 def Wrrr : BaseMulAccum<isSub, 0b000, GPR32, GPR32, asm,
Gerolf Hoflehner97c383b2014-08-07 21:40:58 +00001435 [/*(set GPR32:$Rd, (AccNode GPR32:$Ra, (mul GPR32:$Rn, GPR32:$Rm)))*/]>,
Chad Rosier3fe0c872014-06-09 01:54:00 +00001436 Sched<[WriteIM32, ReadIM, ReadIM, ReadIMA]> {
Tim Northover3b0846e2014-05-24 12:50:23 +00001437 let Inst{31} = 0;
1438 }
1439
1440 def Xrrr : BaseMulAccum<isSub, 0b000, GPR64, GPR64, asm,
Gerolf Hoflehner97c383b2014-08-07 21:40:58 +00001441 [/*(set GPR64:$Rd, (AccNode GPR64:$Ra, (mul GPR64:$Rn, GPR64:$Rm)))*/]>,
Chad Rosier3fe0c872014-06-09 01:54:00 +00001442 Sched<[WriteIM64, ReadIM, ReadIM, ReadIMA]> {
Tim Northover3b0846e2014-05-24 12:50:23 +00001443 let Inst{31} = 1;
1444 }
1445}
1446
1447class WideMulAccum<bit isSub, bits<3> opc, string asm,
1448 SDNode AccNode, SDNode ExtNode>
1449 : BaseMulAccum<isSub, opc, GPR32, GPR64, asm,
1450 [(set GPR64:$Rd, (AccNode GPR64:$Ra,
1451 (mul (ExtNode GPR32:$Rn), (ExtNode GPR32:$Rm))))]>,
Chad Rosier3fe0c872014-06-09 01:54:00 +00001452 Sched<[WriteIM32, ReadIM, ReadIM, ReadIMA]> {
Tim Northover3b0846e2014-05-24 12:50:23 +00001453 let Inst{31} = 1;
1454}
1455
1456class MulHi<bits<3> opc, string asm, SDNode OpNode>
1457 : I<(outs GPR64:$Rd), (ins GPR64:$Rn, GPR64:$Rm),
1458 asm, "\t$Rd, $Rn, $Rm", "",
1459 [(set GPR64:$Rd, (OpNode GPR64:$Rn, GPR64:$Rm))]>,
1460 Sched<[WriteIM64, ReadIM, ReadIM]> {
1461 bits<5> Rd;
1462 bits<5> Rn;
1463 bits<5> Rm;
1464 let Inst{31-24} = 0b10011011;
1465 let Inst{23-21} = opc;
1466 let Inst{20-16} = Rm;
1467 let Inst{15} = 0;
1468 let Inst{9-5} = Rn;
1469 let Inst{4-0} = Rd;
1470
1471 // The Ra field of SMULH and UMULH is unused: it should be assembled as 31
1472 // (i.e. all bits 1) but is ignored by the processor.
1473 let PostEncoderMethod = "fixMulHigh";
1474}
1475
1476class MulAccumWAlias<string asm, Instruction inst>
Ahmed Bougacha63fae0e2015-09-02 18:52:54 +00001477 : InstAlias<asm#"\t$dst, $src1, $src2",
Tim Northover3b0846e2014-05-24 12:50:23 +00001478 (inst GPR32:$dst, GPR32:$src1, GPR32:$src2, WZR)>;
1479class MulAccumXAlias<string asm, Instruction inst>
Ahmed Bougacha63fae0e2015-09-02 18:52:54 +00001480 : InstAlias<asm#"\t$dst, $src1, $src2",
Tim Northover3b0846e2014-05-24 12:50:23 +00001481 (inst GPR64:$dst, GPR64:$src1, GPR64:$src2, XZR)>;
1482class WideMulAccumAlias<string asm, Instruction inst>
Ahmed Bougacha63fae0e2015-09-02 18:52:54 +00001483 : InstAlias<asm#"\t$dst, $src1, $src2",
Tim Northover3b0846e2014-05-24 12:50:23 +00001484 (inst GPR64:$dst, GPR32:$src1, GPR32:$src2, XZR)>;
1485
1486class BaseCRC32<bit sf, bits<2> sz, bit C, RegisterClass StreamReg,
1487 SDPatternOperator OpNode, string asm>
1488 : I<(outs GPR32:$Rd), (ins GPR32:$Rn, StreamReg:$Rm),
1489 asm, "\t$Rd, $Rn, $Rm", "",
1490 [(set GPR32:$Rd, (OpNode GPR32:$Rn, StreamReg:$Rm))]>,
1491 Sched<[WriteISReg, ReadI, ReadISReg]> {
1492 bits<5> Rd;
1493 bits<5> Rn;
1494 bits<5> Rm;
1495
1496 let Inst{31} = sf;
1497 let Inst{30-21} = 0b0011010110;
1498 let Inst{20-16} = Rm;
1499 let Inst{15-13} = 0b010;
1500 let Inst{12} = C;
1501 let Inst{11-10} = sz;
1502 let Inst{9-5} = Rn;
1503 let Inst{4-0} = Rd;
1504 let Predicates = [HasCRC];
1505}
1506
1507//---
1508// Address generation.
1509//---
1510
1511class ADRI<bit page, string asm, Operand adr, list<dag> pattern>
1512 : I<(outs GPR64:$Xd), (ins adr:$label), asm, "\t$Xd, $label", "",
1513 pattern>,
1514 Sched<[WriteI]> {
1515 bits<5> Xd;
1516 bits<21> label;
1517 let Inst{31} = page;
1518 let Inst{30-29} = label{1-0};
1519 let Inst{28-24} = 0b10000;
1520 let Inst{23-5} = label{20-2};
1521 let Inst{4-0} = Xd;
1522
1523 let DecoderMethod = "DecodeAdrInstruction";
1524}
1525
1526//---
1527// Move immediate.
1528//---
1529
1530def movimm32_imm : Operand<i32> {
1531 let ParserMatchClass = Imm0_65535Operand;
1532 let EncoderMethod = "getMoveWideImmOpValue";
1533 let PrintMethod = "printHexImm";
1534}
1535def movimm32_shift : Operand<i32> {
1536 let PrintMethod = "printShifter";
1537 let ParserMatchClass = MovImm32ShifterOperand;
1538}
1539def movimm64_shift : Operand<i32> {
1540 let PrintMethod = "printShifter";
1541 let ParserMatchClass = MovImm64ShifterOperand;
1542}
1543
1544let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
1545class BaseMoveImmediate<bits<2> opc, RegisterClass regtype, Operand shifter,
1546 string asm>
1547 : I<(outs regtype:$Rd), (ins movimm32_imm:$imm, shifter:$shift),
1548 asm, "\t$Rd, $imm$shift", "", []>,
1549 Sched<[WriteImm]> {
1550 bits<5> Rd;
1551 bits<16> imm;
1552 bits<6> shift;
1553 let Inst{30-29} = opc;
1554 let Inst{28-23} = 0b100101;
1555 let Inst{22-21} = shift{5-4};
1556 let Inst{20-5} = imm;
1557 let Inst{4-0} = Rd;
1558
1559 let DecoderMethod = "DecodeMoveImmInstruction";
1560}
1561
1562multiclass MoveImmediate<bits<2> opc, string asm> {
1563 def Wi : BaseMoveImmediate<opc, GPR32, movimm32_shift, asm> {
1564 let Inst{31} = 0;
1565 }
1566
1567 def Xi : BaseMoveImmediate<opc, GPR64, movimm64_shift, asm> {
1568 let Inst{31} = 1;
1569 }
1570}
1571
1572let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
1573class BaseInsertImmediate<bits<2> opc, RegisterClass regtype, Operand shifter,
1574 string asm>
1575 : I<(outs regtype:$Rd),
1576 (ins regtype:$src, movimm32_imm:$imm, shifter:$shift),
1577 asm, "\t$Rd, $imm$shift", "$src = $Rd", []>,
1578 Sched<[WriteI, ReadI]> {
1579 bits<5> Rd;
1580 bits<16> imm;
1581 bits<6> shift;
1582 let Inst{30-29} = opc;
1583 let Inst{28-23} = 0b100101;
1584 let Inst{22-21} = shift{5-4};
1585 let Inst{20-5} = imm;
1586 let Inst{4-0} = Rd;
1587
1588 let DecoderMethod = "DecodeMoveImmInstruction";
1589}
1590
1591multiclass InsertImmediate<bits<2> opc, string asm> {
1592 def Wi : BaseInsertImmediate<opc, GPR32, movimm32_shift, asm> {
1593 let Inst{31} = 0;
1594 }
1595
1596 def Xi : BaseInsertImmediate<opc, GPR64, movimm64_shift, asm> {
1597 let Inst{31} = 1;
1598 }
1599}
1600
1601//---
1602// Add/Subtract
1603//---
1604
1605class BaseAddSubImm<bit isSub, bit setFlags, RegisterClass dstRegtype,
1606 RegisterClass srcRegtype, addsub_shifted_imm immtype,
1607 string asm, SDPatternOperator OpNode>
1608 : I<(outs dstRegtype:$Rd), (ins srcRegtype:$Rn, immtype:$imm),
1609 asm, "\t$Rd, $Rn, $imm", "",
1610 [(set dstRegtype:$Rd, (OpNode srcRegtype:$Rn, immtype:$imm))]>,
1611 Sched<[WriteI, ReadI]> {
1612 bits<5> Rd;
1613 bits<5> Rn;
1614 bits<14> imm;
1615 let Inst{30} = isSub;
1616 let Inst{29} = setFlags;
1617 let Inst{28-24} = 0b10001;
1618 let Inst{23-22} = imm{13-12}; // '00' => lsl #0, '01' => lsl #12
1619 let Inst{21-10} = imm{11-0};
1620 let Inst{9-5} = Rn;
1621 let Inst{4-0} = Rd;
1622 let DecoderMethod = "DecodeBaseAddSubImm";
1623}
1624
1625class BaseAddSubRegPseudo<RegisterClass regtype,
1626 SDPatternOperator OpNode>
1627 : Pseudo<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm),
1628 [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm))]>,
1629 Sched<[WriteI, ReadI, ReadI]>;
1630
1631class BaseAddSubSReg<bit isSub, bit setFlags, RegisterClass regtype,
1632 arith_shifted_reg shifted_regtype, string asm,
1633 SDPatternOperator OpNode>
1634 : I<(outs regtype:$Rd), (ins regtype:$Rn, shifted_regtype:$Rm),
1635 asm, "\t$Rd, $Rn, $Rm", "",
1636 [(set regtype:$Rd, (OpNode regtype:$Rn, shifted_regtype:$Rm))]>,
1637 Sched<[WriteISReg, ReadI, ReadISReg]> {
1638 // The operands are in order to match the 'addr' MI operands, so we
1639 // don't need an encoder method and by-name matching. Just use the default
1640 // in-order handling. Since we're using by-order, make sure the names
1641 // do not match.
1642 bits<5> dst;
1643 bits<5> src1;
1644 bits<5> src2;
1645 bits<8> shift;
1646 let Inst{30} = isSub;
1647 let Inst{29} = setFlags;
1648 let Inst{28-24} = 0b01011;
1649 let Inst{23-22} = shift{7-6};
1650 let Inst{21} = 0;
1651 let Inst{20-16} = src2;
1652 let Inst{15-10} = shift{5-0};
1653 let Inst{9-5} = src1;
1654 let Inst{4-0} = dst;
1655
1656 let DecoderMethod = "DecodeThreeAddrSRegInstruction";
1657}
1658
1659class BaseAddSubEReg<bit isSub, bit setFlags, RegisterClass dstRegtype,
1660 RegisterClass src1Regtype, Operand src2Regtype,
1661 string asm, SDPatternOperator OpNode>
1662 : I<(outs dstRegtype:$R1),
1663 (ins src1Regtype:$R2, src2Regtype:$R3),
1664 asm, "\t$R1, $R2, $R3", "",
1665 [(set dstRegtype:$R1, (OpNode src1Regtype:$R2, src2Regtype:$R3))]>,
1666 Sched<[WriteIEReg, ReadI, ReadIEReg]> {
1667 bits<5> Rd;
1668 bits<5> Rn;
1669 bits<5> Rm;
1670 bits<6> ext;
1671 let Inst{30} = isSub;
1672 let Inst{29} = setFlags;
1673 let Inst{28-24} = 0b01011;
1674 let Inst{23-21} = 0b001;
1675 let Inst{20-16} = Rm;
1676 let Inst{15-13} = ext{5-3};
1677 let Inst{12-10} = ext{2-0};
1678 let Inst{9-5} = Rn;
1679 let Inst{4-0} = Rd;
1680
1681 let DecoderMethod = "DecodeAddSubERegInstruction";
1682}
1683
1684let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
1685class BaseAddSubEReg64<bit isSub, bit setFlags, RegisterClass dstRegtype,
1686 RegisterClass src1Regtype, RegisterClass src2Regtype,
1687 Operand ext_op, string asm>
1688 : I<(outs dstRegtype:$Rd),
1689 (ins src1Regtype:$Rn, src2Regtype:$Rm, ext_op:$ext),
1690 asm, "\t$Rd, $Rn, $Rm$ext", "", []>,
1691 Sched<[WriteIEReg, ReadI, ReadIEReg]> {
1692 bits<5> Rd;
1693 bits<5> Rn;
1694 bits<5> Rm;
1695 bits<6> ext;
1696 let Inst{30} = isSub;
1697 let Inst{29} = setFlags;
1698 let Inst{28-24} = 0b01011;
1699 let Inst{23-21} = 0b001;
1700 let Inst{20-16} = Rm;
1701 let Inst{15} = ext{5};
1702 let Inst{12-10} = ext{2-0};
1703 let Inst{9-5} = Rn;
1704 let Inst{4-0} = Rd;
1705
1706 let DecoderMethod = "DecodeAddSubERegInstruction";
1707}
1708
1709// Aliases for register+register add/subtract.
1710class AddSubRegAlias<string asm, Instruction inst, RegisterClass dstRegtype,
1711 RegisterClass src1Regtype, RegisterClass src2Regtype,
1712 int shiftExt>
Ahmed Bougacha63fae0e2015-09-02 18:52:54 +00001713 : InstAlias<asm#"\t$dst, $src1, $src2",
Tim Northover3b0846e2014-05-24 12:50:23 +00001714 (inst dstRegtype:$dst, src1Regtype:$src1, src2Regtype:$src2,
1715 shiftExt)>;
1716
Arnaud A. de Grandmaison650c5202015-07-01 15:05:58 +00001717multiclass AddSub<bit isSub, string mnemonic, string alias,
Tim Northover3b0846e2014-05-24 12:50:23 +00001718 SDPatternOperator OpNode = null_frag> {
Jiangning Liucd296372014-07-29 02:09:26 +00001719 let hasSideEffects = 0, isReMaterializable = 1, isAsCheapAsAMove = 1 in {
Tim Northover3b0846e2014-05-24 12:50:23 +00001720 // Add/Subtract immediate
Quentin Colombeta64723c2015-04-02 18:54:23 +00001721 // Increase the weight of the immediate variant to try to match it before
1722 // the extended register variant.
1723 // We used to match the register variant before the immediate when the
1724 // register argument could be implicitly zero-extended.
Quentin Colombet387a0e72015-03-31 00:31:13 +00001725 let AddedComplexity = 6 in
Tim Northover3b0846e2014-05-24 12:50:23 +00001726 def Wri : BaseAddSubImm<isSub, 0, GPR32sp, GPR32sp, addsub_shifted_imm32,
1727 mnemonic, OpNode> {
1728 let Inst{31} = 0;
1729 }
Quentin Colombet387a0e72015-03-31 00:31:13 +00001730 let AddedComplexity = 6 in
Tim Northover3b0846e2014-05-24 12:50:23 +00001731 def Xri : BaseAddSubImm<isSub, 0, GPR64sp, GPR64sp, addsub_shifted_imm64,
1732 mnemonic, OpNode> {
1733 let Inst{31} = 1;
1734 }
1735
1736 // Add/Subtract register - Only used for CodeGen
1737 def Wrr : BaseAddSubRegPseudo<GPR32, OpNode>;
1738 def Xrr : BaseAddSubRegPseudo<GPR64, OpNode>;
1739
1740 // Add/Subtract shifted register
1741 def Wrs : BaseAddSubSReg<isSub, 0, GPR32, arith_shifted_reg32, mnemonic,
1742 OpNode> {
1743 let Inst{31} = 0;
1744 }
1745 def Xrs : BaseAddSubSReg<isSub, 0, GPR64, arith_shifted_reg64, mnemonic,
1746 OpNode> {
1747 let Inst{31} = 1;
1748 }
1749 }
1750
1751 // Add/Subtract extended register
1752 let AddedComplexity = 1, hasSideEffects = 0 in {
1753 def Wrx : BaseAddSubEReg<isSub, 0, GPR32sp, GPR32sp,
1754 arith_extended_reg32<i32>, mnemonic, OpNode> {
1755 let Inst{31} = 0;
1756 }
1757 def Xrx : BaseAddSubEReg<isSub, 0, GPR64sp, GPR64sp,
1758 arith_extended_reg32to64<i64>, mnemonic, OpNode> {
1759 let Inst{31} = 1;
1760 }
1761 }
1762
1763 def Xrx64 : BaseAddSubEReg64<isSub, 0, GPR64sp, GPR64sp, GPR64,
1764 arith_extendlsl64, mnemonic> {
1765 // UXTX and SXTX only.
1766 let Inst{14-13} = 0b11;
1767 let Inst{31} = 1;
1768 }
1769
Arnaud A. de Grandmaison650c5202015-07-01 15:05:58 +00001770 // add Rd, Rb, -imm -> sub Rd, Rn, imm
Ahmed Bougacha63fae0e2015-09-02 18:52:54 +00001771 def : InstAlias<alias#"\t$Rd, $Rn, $imm",
Arnaud A. de Grandmaison650c5202015-07-01 15:05:58 +00001772 (!cast<Instruction>(NAME # "Wri") GPR32sp:$Rd, GPR32sp:$Rn,
1773 addsub_shifted_imm32_neg:$imm), 0>;
Ahmed Bougacha63fae0e2015-09-02 18:52:54 +00001774 def : InstAlias<alias#"\t$Rd, $Rn, $imm",
Arnaud A. de Grandmaison650c5202015-07-01 15:05:58 +00001775 (!cast<Instruction>(NAME # "Xri") GPR64sp:$Rd, GPR64sp:$Rn,
1776 addsub_shifted_imm64_neg:$imm), 0>;
1777
Tim Northover3b0846e2014-05-24 12:50:23 +00001778 // Register/register aliases with no shift when SP is not used.
1779 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrs"),
1780 GPR32, GPR32, GPR32, 0>;
1781 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Xrs"),
1782 GPR64, GPR64, GPR64, 0>;
1783
1784 // Register/register aliases with no shift when either the destination or
1785 // first source register is SP.
1786 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrx"),
1787 GPR32sponly, GPR32sp, GPR32, 16>; // UXTW #0
1788 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrx"),
1789 GPR32sp, GPR32sponly, GPR32, 16>; // UXTW #0
1790 def : AddSubRegAlias<mnemonic,
1791 !cast<Instruction>(NAME#"Xrx64"),
1792 GPR64sponly, GPR64sp, GPR64, 24>; // UXTX #0
1793 def : AddSubRegAlias<mnemonic,
1794 !cast<Instruction>(NAME#"Xrx64"),
1795 GPR64sp, GPR64sponly, GPR64, 24>; // UXTX #0
1796}
1797
Arnaud A. de Grandmaison650c5202015-07-01 15:05:58 +00001798multiclass AddSubS<bit isSub, string mnemonic, SDNode OpNode, string cmp,
1799 string alias, string cmpAlias> {
Tim Northover3b0846e2014-05-24 12:50:23 +00001800 let isCompare = 1, Defs = [NZCV] in {
1801 // Add/Subtract immediate
1802 def Wri : BaseAddSubImm<isSub, 1, GPR32, GPR32sp, addsub_shifted_imm32,
1803 mnemonic, OpNode> {
1804 let Inst{31} = 0;
1805 }
1806 def Xri : BaseAddSubImm<isSub, 1, GPR64, GPR64sp, addsub_shifted_imm64,
1807 mnemonic, OpNode> {
1808 let Inst{31} = 1;
1809 }
1810
1811 // Add/Subtract register
1812 def Wrr : BaseAddSubRegPseudo<GPR32, OpNode>;
1813 def Xrr : BaseAddSubRegPseudo<GPR64, OpNode>;
1814
1815 // Add/Subtract shifted register
1816 def Wrs : BaseAddSubSReg<isSub, 1, GPR32, arith_shifted_reg32, mnemonic,
1817 OpNode> {
1818 let Inst{31} = 0;
1819 }
1820 def Xrs : BaseAddSubSReg<isSub, 1, GPR64, arith_shifted_reg64, mnemonic,
1821 OpNode> {
1822 let Inst{31} = 1;
1823 }
1824
1825 // Add/Subtract extended register
1826 let AddedComplexity = 1 in {
1827 def Wrx : BaseAddSubEReg<isSub, 1, GPR32, GPR32sp,
1828 arith_extended_reg32<i32>, mnemonic, OpNode> {
1829 let Inst{31} = 0;
1830 }
1831 def Xrx : BaseAddSubEReg<isSub, 1, GPR64, GPR64sp,
1832 arith_extended_reg32<i64>, mnemonic, OpNode> {
1833 let Inst{31} = 1;
1834 }
1835 }
1836
1837 def Xrx64 : BaseAddSubEReg64<isSub, 1, GPR64, GPR64sp, GPR64,
1838 arith_extendlsl64, mnemonic> {
1839 // UXTX and SXTX only.
1840 let Inst{14-13} = 0b11;
1841 let Inst{31} = 1;
1842 }
1843 } // Defs = [NZCV]
1844
Arnaud A. de Grandmaison650c5202015-07-01 15:05:58 +00001845 // Support negative immediates, e.g. adds Rd, Rn, -imm -> subs Rd, Rn, imm
Ahmed Bougacha63fae0e2015-09-02 18:52:54 +00001846 def : InstAlias<alias#"\t$Rd, $Rn, $imm",
Arnaud A. de Grandmaison650c5202015-07-01 15:05:58 +00001847 (!cast<Instruction>(NAME # "Wri") GPR32:$Rd, GPR32sp:$Rn,
1848 addsub_shifted_imm32_neg:$imm), 0>;
Ahmed Bougacha63fae0e2015-09-02 18:52:54 +00001849 def : InstAlias<alias#"\t$Rd, $Rn, $imm",
Arnaud A. de Grandmaison650c5202015-07-01 15:05:58 +00001850 (!cast<Instruction>(NAME # "Xri") GPR64:$Rd, GPR64sp:$Rn,
1851 addsub_shifted_imm64_neg:$imm), 0>;
1852
Tim Northover3b0846e2014-05-24 12:50:23 +00001853 // Compare aliases
Ahmed Bougacha63fae0e2015-09-02 18:52:54 +00001854 def : InstAlias<cmp#"\t$src, $imm", (!cast<Instruction>(NAME#"Wri")
Tim Northover3b0846e2014-05-24 12:50:23 +00001855 WZR, GPR32sp:$src, addsub_shifted_imm32:$imm), 5>;
Ahmed Bougacha63fae0e2015-09-02 18:52:54 +00001856 def : InstAlias<cmp#"\t$src, $imm", (!cast<Instruction>(NAME#"Xri")
Tim Northover3b0846e2014-05-24 12:50:23 +00001857 XZR, GPR64sp:$src, addsub_shifted_imm64:$imm), 5>;
Ahmed Bougacha63fae0e2015-09-02 18:52:54 +00001858 def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Wrx")
Tim Northover3b0846e2014-05-24 12:50:23 +00001859 WZR, GPR32sp:$src1, GPR32:$src2, arith_extend:$sh), 4>;
Ahmed Bougacha63fae0e2015-09-02 18:52:54 +00001860 def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Xrx")
Tim Northover3b0846e2014-05-24 12:50:23 +00001861 XZR, GPR64sp:$src1, GPR32:$src2, arith_extend:$sh), 4>;
Ahmed Bougacha63fae0e2015-09-02 18:52:54 +00001862 def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Xrx64")
Tim Northover3b0846e2014-05-24 12:50:23 +00001863 XZR, GPR64sp:$src1, GPR64:$src2, arith_extendlsl64:$sh), 4>;
Ahmed Bougacha63fae0e2015-09-02 18:52:54 +00001864 def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Wrs")
Tim Northover3b0846e2014-05-24 12:50:23 +00001865 WZR, GPR32:$src1, GPR32:$src2, arith_shift32:$sh), 4>;
Ahmed Bougacha63fae0e2015-09-02 18:52:54 +00001866 def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Xrs")
Tim Northover3b0846e2014-05-24 12:50:23 +00001867 XZR, GPR64:$src1, GPR64:$src2, arith_shift64:$sh), 4>;
1868
Arnaud A. de Grandmaison650c5202015-07-01 15:05:58 +00001869 // Support negative immediates, e.g. cmp Rn, -imm -> cmn Rn, imm
Ahmed Bougacha63fae0e2015-09-02 18:52:54 +00001870 def : InstAlias<cmpAlias#"\t$src, $imm", (!cast<Instruction>(NAME#"Wri")
Arnaud A. de Grandmaison650c5202015-07-01 15:05:58 +00001871 WZR, GPR32sp:$src, addsub_shifted_imm32_neg:$imm), 0>;
Ahmed Bougacha63fae0e2015-09-02 18:52:54 +00001872 def : InstAlias<cmpAlias#"\t$src, $imm", (!cast<Instruction>(NAME#"Xri")
Arnaud A. de Grandmaison650c5202015-07-01 15:05:58 +00001873 XZR, GPR64sp:$src, addsub_shifted_imm64_neg:$imm), 0>;
1874
Tim Northover3b0846e2014-05-24 12:50:23 +00001875 // Compare shorthands
Ahmed Bougacha63fae0e2015-09-02 18:52:54 +00001876 def : InstAlias<cmp#"\t$src1, $src2", (!cast<Instruction>(NAME#"Wrs")
Tim Northover3b0846e2014-05-24 12:50:23 +00001877 WZR, GPR32:$src1, GPR32:$src2, 0), 5>;
Ahmed Bougacha63fae0e2015-09-02 18:52:54 +00001878 def : InstAlias<cmp#"\t$src1, $src2", (!cast<Instruction>(NAME#"Xrs")
Tim Northover3b0846e2014-05-24 12:50:23 +00001879 XZR, GPR64:$src1, GPR64:$src2, 0), 5>;
Ahmed Bougacha63fae0e2015-09-02 18:52:54 +00001880 def : InstAlias<cmp#"\t$src1, $src2", (!cast<Instruction>(NAME#"Wrx")
Artyom Skrobov82ae94f2014-06-09 11:10:14 +00001881 WZR, GPR32sponly:$src1, GPR32:$src2, 16), 5>;
Ahmed Bougacha63fae0e2015-09-02 18:52:54 +00001882 def : InstAlias<cmp#"\t$src1, $src2", (!cast<Instruction>(NAME#"Xrx64")
Artyom Skrobov82ae94f2014-06-09 11:10:14 +00001883 XZR, GPR64sponly:$src1, GPR64:$src2, 24), 5>;
Tim Northover3b0846e2014-05-24 12:50:23 +00001884
1885 // Register/register aliases with no shift when SP is not used.
1886 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrs"),
1887 GPR32, GPR32, GPR32, 0>;
1888 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Xrs"),
1889 GPR64, GPR64, GPR64, 0>;
1890
1891 // Register/register aliases with no shift when the first source register
1892 // is SP.
1893 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrx"),
1894 GPR32, GPR32sponly, GPR32, 16>; // UXTW #0
1895 def : AddSubRegAlias<mnemonic,
1896 !cast<Instruction>(NAME#"Xrx64"),
1897 GPR64, GPR64sponly, GPR64, 24>; // UXTX #0
1898}
1899
1900//---
1901// Extract
1902//---
1903def SDTA64EXTR : SDTypeProfile<1, 3, [SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>,
1904 SDTCisPtrTy<3>]>;
1905def AArch64Extr : SDNode<"AArch64ISD::EXTR", SDTA64EXTR>;
1906
1907class BaseExtractImm<RegisterClass regtype, Operand imm_type, string asm,
1908 list<dag> patterns>
1909 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, imm_type:$imm),
1910 asm, "\t$Rd, $Rn, $Rm, $imm", "", patterns>,
1911 Sched<[WriteExtr, ReadExtrHi]> {
1912 bits<5> Rd;
1913 bits<5> Rn;
1914 bits<5> Rm;
1915 bits<6> imm;
1916
1917 let Inst{30-23} = 0b00100111;
1918 let Inst{21} = 0;
1919 let Inst{20-16} = Rm;
1920 let Inst{15-10} = imm;
1921 let Inst{9-5} = Rn;
1922 let Inst{4-0} = Rd;
1923}
1924
1925multiclass ExtractImm<string asm> {
1926 def Wrri : BaseExtractImm<GPR32, imm0_31, asm,
1927 [(set GPR32:$Rd,
1928 (AArch64Extr GPR32:$Rn, GPR32:$Rm, imm0_31:$imm))]> {
1929 let Inst{31} = 0;
1930 let Inst{22} = 0;
1931 // imm<5> must be zero.
1932 let imm{5} = 0;
1933 }
1934 def Xrri : BaseExtractImm<GPR64, imm0_63, asm,
1935 [(set GPR64:$Rd,
1936 (AArch64Extr GPR64:$Rn, GPR64:$Rm, imm0_63:$imm))]> {
1937
1938 let Inst{31} = 1;
1939 let Inst{22} = 1;
1940 }
1941}
1942
1943//---
1944// Bitfield
1945//---
1946
1947let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
1948class BaseBitfieldImm<bits<2> opc,
1949 RegisterClass regtype, Operand imm_type, string asm>
1950 : I<(outs regtype:$Rd), (ins regtype:$Rn, imm_type:$immr, imm_type:$imms),
1951 asm, "\t$Rd, $Rn, $immr, $imms", "", []>,
1952 Sched<[WriteIS, ReadI]> {
1953 bits<5> Rd;
1954 bits<5> Rn;
1955 bits<6> immr;
1956 bits<6> imms;
1957
1958 let Inst{30-29} = opc;
1959 let Inst{28-23} = 0b100110;
1960 let Inst{21-16} = immr;
1961 let Inst{15-10} = imms;
1962 let Inst{9-5} = Rn;
1963 let Inst{4-0} = Rd;
1964}
1965
1966multiclass BitfieldImm<bits<2> opc, string asm> {
1967 def Wri : BaseBitfieldImm<opc, GPR32, imm0_31, asm> {
1968 let Inst{31} = 0;
1969 let Inst{22} = 0;
1970 // imms<5> and immr<5> must be zero, else ReservedValue().
1971 let Inst{21} = 0;
1972 let Inst{15} = 0;
1973 }
1974 def Xri : BaseBitfieldImm<opc, GPR64, imm0_63, asm> {
1975 let Inst{31} = 1;
1976 let Inst{22} = 1;
1977 }
1978}
1979
1980let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
1981class BaseBitfieldImmWith2RegArgs<bits<2> opc,
1982 RegisterClass regtype, Operand imm_type, string asm>
1983 : I<(outs regtype:$Rd), (ins regtype:$src, regtype:$Rn, imm_type:$immr,
1984 imm_type:$imms),
1985 asm, "\t$Rd, $Rn, $immr, $imms", "$src = $Rd", []>,
1986 Sched<[WriteIS, ReadI]> {
1987 bits<5> Rd;
1988 bits<5> Rn;
1989 bits<6> immr;
1990 bits<6> imms;
1991
1992 let Inst{30-29} = opc;
1993 let Inst{28-23} = 0b100110;
1994 let Inst{21-16} = immr;
1995 let Inst{15-10} = imms;
1996 let Inst{9-5} = Rn;
1997 let Inst{4-0} = Rd;
1998}
1999
2000multiclass BitfieldImmWith2RegArgs<bits<2> opc, string asm> {
2001 def Wri : BaseBitfieldImmWith2RegArgs<opc, GPR32, imm0_31, asm> {
2002 let Inst{31} = 0;
2003 let Inst{22} = 0;
2004 // imms<5> and immr<5> must be zero, else ReservedValue().
2005 let Inst{21} = 0;
2006 let Inst{15} = 0;
2007 }
2008 def Xri : BaseBitfieldImmWith2RegArgs<opc, GPR64, imm0_63, asm> {
2009 let Inst{31} = 1;
2010 let Inst{22} = 1;
2011 }
2012}
2013
2014//---
2015// Logical
2016//---
2017
2018// Logical (immediate)
2019class BaseLogicalImm<bits<2> opc, RegisterClass dregtype,
2020 RegisterClass sregtype, Operand imm_type, string asm,
2021 list<dag> pattern>
2022 : I<(outs dregtype:$Rd), (ins sregtype:$Rn, imm_type:$imm),
2023 asm, "\t$Rd, $Rn, $imm", "", pattern>,
2024 Sched<[WriteI, ReadI]> {
2025 bits<5> Rd;
2026 bits<5> Rn;
2027 bits<13> imm;
2028 let Inst{30-29} = opc;
2029 let Inst{28-23} = 0b100100;
2030 let Inst{22} = imm{12};
2031 let Inst{21-16} = imm{11-6};
2032 let Inst{15-10} = imm{5-0};
2033 let Inst{9-5} = Rn;
2034 let Inst{4-0} = Rd;
2035
2036 let DecoderMethod = "DecodeLogicalImmInstruction";
2037}
2038
2039// Logical (shifted register)
2040class BaseLogicalSReg<bits<2> opc, bit N, RegisterClass regtype,
2041 logical_shifted_reg shifted_regtype, string asm,
2042 list<dag> pattern>
2043 : I<(outs regtype:$Rd), (ins regtype:$Rn, shifted_regtype:$Rm),
2044 asm, "\t$Rd, $Rn, $Rm", "", pattern>,
2045 Sched<[WriteISReg, ReadI, ReadISReg]> {
2046 // The operands are in order to match the 'addr' MI operands, so we
2047 // don't need an encoder method and by-name matching. Just use the default
2048 // in-order handling. Since we're using by-order, make sure the names
2049 // do not match.
2050 bits<5> dst;
2051 bits<5> src1;
2052 bits<5> src2;
2053 bits<8> shift;
2054 let Inst{30-29} = opc;
2055 let Inst{28-24} = 0b01010;
2056 let Inst{23-22} = shift{7-6};
2057 let Inst{21} = N;
2058 let Inst{20-16} = src2;
2059 let Inst{15-10} = shift{5-0};
2060 let Inst{9-5} = src1;
2061 let Inst{4-0} = dst;
2062
2063 let DecoderMethod = "DecodeThreeAddrSRegInstruction";
2064}
2065
2066// Aliases for register+register logical instructions.
2067class LogicalRegAlias<string asm, Instruction inst, RegisterClass regtype>
Ahmed Bougacha63fae0e2015-09-02 18:52:54 +00002068 : InstAlias<asm#"\t$dst, $src1, $src2",
Tim Northover3b0846e2014-05-24 12:50:23 +00002069 (inst regtype:$dst, regtype:$src1, regtype:$src2, 0)>;
2070
Arnaud A. de Grandmaisonf6432312014-07-10 15:12:26 +00002071multiclass LogicalImm<bits<2> opc, string mnemonic, SDNode OpNode,
2072 string Alias> {
Jiangning Liucd296372014-07-29 02:09:26 +00002073 let AddedComplexity = 6, isReMaterializable = 1, isAsCheapAsAMove = 1 in
Tim Northover3b0846e2014-05-24 12:50:23 +00002074 def Wri : BaseLogicalImm<opc, GPR32sp, GPR32, logical_imm32, mnemonic,
2075 [(set GPR32sp:$Rd, (OpNode GPR32:$Rn,
2076 logical_imm32:$imm))]> {
2077 let Inst{31} = 0;
2078 let Inst{22} = 0; // 64-bit version has an additional bit of immediate.
2079 }
Jiangning Liucd296372014-07-29 02:09:26 +00002080 let AddedComplexity = 6, isReMaterializable = 1, isAsCheapAsAMove = 1 in
Tim Northover3b0846e2014-05-24 12:50:23 +00002081 def Xri : BaseLogicalImm<opc, GPR64sp, GPR64, logical_imm64, mnemonic,
2082 [(set GPR64sp:$Rd, (OpNode GPR64:$Rn,
2083 logical_imm64:$imm))]> {
2084 let Inst{31} = 1;
2085 }
Arnaud A. de Grandmaisonf6432312014-07-10 15:12:26 +00002086
Ahmed Bougacha63fae0e2015-09-02 18:52:54 +00002087 def : InstAlias<Alias # "\t$Rd, $Rn, $imm",
Arnaud A. de Grandmaisonf6432312014-07-10 15:12:26 +00002088 (!cast<Instruction>(NAME # "Wri") GPR32sp:$Rd, GPR32:$Rn,
2089 logical_imm32_not:$imm), 0>;
Ahmed Bougacha63fae0e2015-09-02 18:52:54 +00002090 def : InstAlias<Alias # "\t$Rd, $Rn, $imm",
Arnaud A. de Grandmaisonf6432312014-07-10 15:12:26 +00002091 (!cast<Instruction>(NAME # "Xri") GPR64sp:$Rd, GPR64:$Rn,
2092 logical_imm64_not:$imm), 0>;
Tim Northover3b0846e2014-05-24 12:50:23 +00002093}
2094
Arnaud A. de Grandmaisonf6432312014-07-10 15:12:26 +00002095multiclass LogicalImmS<bits<2> opc, string mnemonic, SDNode OpNode,
2096 string Alias> {
Tim Northover3b0846e2014-05-24 12:50:23 +00002097 let isCompare = 1, Defs = [NZCV] in {
2098 def Wri : BaseLogicalImm<opc, GPR32, GPR32, logical_imm32, mnemonic,
2099 [(set GPR32:$Rd, (OpNode GPR32:$Rn, logical_imm32:$imm))]> {
2100 let Inst{31} = 0;
2101 let Inst{22} = 0; // 64-bit version has an additional bit of immediate.
2102 }
2103 def Xri : BaseLogicalImm<opc, GPR64, GPR64, logical_imm64, mnemonic,
2104 [(set GPR64:$Rd, (OpNode GPR64:$Rn, logical_imm64:$imm))]> {
2105 let Inst{31} = 1;
2106 }
2107 } // end Defs = [NZCV]
Arnaud A. de Grandmaisonf6432312014-07-10 15:12:26 +00002108
Ahmed Bougacha63fae0e2015-09-02 18:52:54 +00002109 def : InstAlias<Alias # "\t$Rd, $Rn, $imm",
Arnaud A. de Grandmaisonf6432312014-07-10 15:12:26 +00002110 (!cast<Instruction>(NAME # "Wri") GPR32:$Rd, GPR32:$Rn,
2111 logical_imm32_not:$imm), 0>;
Ahmed Bougacha63fae0e2015-09-02 18:52:54 +00002112 def : InstAlias<Alias # "\t$Rd, $Rn, $imm",
Arnaud A. de Grandmaisonf6432312014-07-10 15:12:26 +00002113 (!cast<Instruction>(NAME # "Xri") GPR64:$Rd, GPR64:$Rn,
2114 logical_imm64_not:$imm), 0>;
Tim Northover3b0846e2014-05-24 12:50:23 +00002115}
2116
2117class BaseLogicalRegPseudo<RegisterClass regtype, SDPatternOperator OpNode>
2118 : Pseudo<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm),
2119 [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm))]>,
2120 Sched<[WriteI, ReadI, ReadI]>;
2121
2122// Split from LogicalImm as not all instructions have both.
2123multiclass LogicalReg<bits<2> opc, bit N, string mnemonic,
2124 SDPatternOperator OpNode> {
Jiangning Liucd296372014-07-29 02:09:26 +00002125 let isReMaterializable = 1, isAsCheapAsAMove = 1 in {
Tim Northover3b0846e2014-05-24 12:50:23 +00002126 def Wrr : BaseLogicalRegPseudo<GPR32, OpNode>;
2127 def Xrr : BaseLogicalRegPseudo<GPR64, OpNode>;
Jiangning Liucd296372014-07-29 02:09:26 +00002128 }
Tim Northover3b0846e2014-05-24 12:50:23 +00002129
2130 def Wrs : BaseLogicalSReg<opc, N, GPR32, logical_shifted_reg32, mnemonic,
2131 [(set GPR32:$Rd, (OpNode GPR32:$Rn,
2132 logical_shifted_reg32:$Rm))]> {
2133 let Inst{31} = 0;
2134 }
2135 def Xrs : BaseLogicalSReg<opc, N, GPR64, logical_shifted_reg64, mnemonic,
2136 [(set GPR64:$Rd, (OpNode GPR64:$Rn,
2137 logical_shifted_reg64:$Rm))]> {
2138 let Inst{31} = 1;
2139 }
2140
2141 def : LogicalRegAlias<mnemonic,
2142 !cast<Instruction>(NAME#"Wrs"), GPR32>;
2143 def : LogicalRegAlias<mnemonic,
2144 !cast<Instruction>(NAME#"Xrs"), GPR64>;
2145}
2146
2147// Split from LogicalReg to allow setting NZCV Defs
2148multiclass LogicalRegS<bits<2> opc, bit N, string mnemonic,
2149 SDPatternOperator OpNode = null_frag> {
2150 let Defs = [NZCV], mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
2151 def Wrr : BaseLogicalRegPseudo<GPR32, OpNode>;
2152 def Xrr : BaseLogicalRegPseudo<GPR64, OpNode>;
2153
2154 def Wrs : BaseLogicalSReg<opc, N, GPR32, logical_shifted_reg32, mnemonic,
2155 [(set GPR32:$Rd, (OpNode GPR32:$Rn, logical_shifted_reg32:$Rm))]> {
2156 let Inst{31} = 0;
2157 }
2158 def Xrs : BaseLogicalSReg<opc, N, GPR64, logical_shifted_reg64, mnemonic,
2159 [(set GPR64:$Rd, (OpNode GPR64:$Rn, logical_shifted_reg64:$Rm))]> {
2160 let Inst{31} = 1;
2161 }
2162 } // Defs = [NZCV]
2163
2164 def : LogicalRegAlias<mnemonic,
2165 !cast<Instruction>(NAME#"Wrs"), GPR32>;
2166 def : LogicalRegAlias<mnemonic,
2167 !cast<Instruction>(NAME#"Xrs"), GPR64>;
2168}
2169
2170//---
2171// Conditionally set flags
2172//---
2173
2174let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
Matthias Braunaf7d7702015-07-16 20:02:37 +00002175class BaseCondComparisonImm<bit op, RegisterClass regtype, ImmLeaf immtype,
2176 string mnemonic, SDNode OpNode>
2177 : I<(outs), (ins regtype:$Rn, immtype:$imm, imm32_0_15:$nzcv, ccode:$cond),
2178 mnemonic, "\t$Rn, $imm, $nzcv, $cond", "",
2179 [(set NZCV, (OpNode regtype:$Rn, immtype:$imm, (i32 imm:$nzcv),
2180 (i32 imm:$cond), NZCV))]>,
Tim Northover3b0846e2014-05-24 12:50:23 +00002181 Sched<[WriteI, ReadI]> {
2182 let Uses = [NZCV];
2183 let Defs = [NZCV];
2184
2185 bits<5> Rn;
2186 bits<5> imm;
2187 bits<4> nzcv;
2188 bits<4> cond;
2189
2190 let Inst{30} = op;
2191 let Inst{29-21} = 0b111010010;
2192 let Inst{20-16} = imm;
2193 let Inst{15-12} = cond;
2194 let Inst{11-10} = 0b10;
2195 let Inst{9-5} = Rn;
2196 let Inst{4} = 0b0;
2197 let Inst{3-0} = nzcv;
2198}
2199
Tim Northover3b0846e2014-05-24 12:50:23 +00002200let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
Matthias Braunaf7d7702015-07-16 20:02:37 +00002201class BaseCondComparisonReg<bit op, RegisterClass regtype, string mnemonic,
2202 SDNode OpNode>
2203 : I<(outs), (ins regtype:$Rn, regtype:$Rm, imm32_0_15:$nzcv, ccode:$cond),
2204 mnemonic, "\t$Rn, $Rm, $nzcv, $cond", "",
2205 [(set NZCV, (OpNode regtype:$Rn, regtype:$Rm, (i32 imm:$nzcv),
2206 (i32 imm:$cond), NZCV))]>,
Tim Northover3b0846e2014-05-24 12:50:23 +00002207 Sched<[WriteI, ReadI, ReadI]> {
2208 let Uses = [NZCV];
2209 let Defs = [NZCV];
2210
2211 bits<5> Rn;
2212 bits<5> Rm;
2213 bits<4> nzcv;
2214 bits<4> cond;
2215
2216 let Inst{30} = op;
2217 let Inst{29-21} = 0b111010010;
2218 let Inst{20-16} = Rm;
2219 let Inst{15-12} = cond;
2220 let Inst{11-10} = 0b00;
2221 let Inst{9-5} = Rn;
2222 let Inst{4} = 0b0;
2223 let Inst{3-0} = nzcv;
2224}
2225
Matthias Braunaf7d7702015-07-16 20:02:37 +00002226multiclass CondComparison<bit op, string mnemonic, SDNode OpNode> {
2227 // immediate operand variants
2228 def Wi : BaseCondComparisonImm<op, GPR32, imm32_0_31, mnemonic, OpNode> {
Tim Northover3b0846e2014-05-24 12:50:23 +00002229 let Inst{31} = 0;
2230 }
Matthias Braunaf7d7702015-07-16 20:02:37 +00002231 def Xi : BaseCondComparisonImm<op, GPR64, imm0_31, mnemonic, OpNode> {
2232 let Inst{31} = 1;
2233 }
2234 // register operand variants
2235 def Wr : BaseCondComparisonReg<op, GPR32, mnemonic, OpNode> {
2236 let Inst{31} = 0;
2237 }
2238 def Xr : BaseCondComparisonReg<op, GPR64, mnemonic, OpNode> {
Tim Northover3b0846e2014-05-24 12:50:23 +00002239 let Inst{31} = 1;
2240 }
2241}
2242
2243//---
2244// Conditional select
2245//---
2246
2247class BaseCondSelect<bit op, bits<2> op2, RegisterClass regtype, string asm>
2248 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, ccode:$cond),
2249 asm, "\t$Rd, $Rn, $Rm, $cond", "",
2250 [(set regtype:$Rd,
2251 (AArch64csel regtype:$Rn, regtype:$Rm, (i32 imm:$cond), NZCV))]>,
2252 Sched<[WriteI, ReadI, ReadI]> {
2253 let Uses = [NZCV];
2254
2255 bits<5> Rd;
2256 bits<5> Rn;
2257 bits<5> Rm;
2258 bits<4> cond;
2259
2260 let Inst{30} = op;
2261 let Inst{29-21} = 0b011010100;
2262 let Inst{20-16} = Rm;
2263 let Inst{15-12} = cond;
2264 let Inst{11-10} = op2;
2265 let Inst{9-5} = Rn;
2266 let Inst{4-0} = Rd;
2267}
2268
2269multiclass CondSelect<bit op, bits<2> op2, string asm> {
2270 def Wr : BaseCondSelect<op, op2, GPR32, asm> {
2271 let Inst{31} = 0;
2272 }
2273 def Xr : BaseCondSelect<op, op2, GPR64, asm> {
2274 let Inst{31} = 1;
2275 }
2276}
2277
2278class BaseCondSelectOp<bit op, bits<2> op2, RegisterClass regtype, string asm,
2279 PatFrag frag>
2280 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, ccode:$cond),
2281 asm, "\t$Rd, $Rn, $Rm, $cond", "",
2282 [(set regtype:$Rd,
2283 (AArch64csel regtype:$Rn, (frag regtype:$Rm),
2284 (i32 imm:$cond), NZCV))]>,
2285 Sched<[WriteI, ReadI, ReadI]> {
2286 let Uses = [NZCV];
2287
2288 bits<5> Rd;
2289 bits<5> Rn;
2290 bits<5> Rm;
2291 bits<4> cond;
2292
2293 let Inst{30} = op;
2294 let Inst{29-21} = 0b011010100;
2295 let Inst{20-16} = Rm;
2296 let Inst{15-12} = cond;
2297 let Inst{11-10} = op2;
2298 let Inst{9-5} = Rn;
2299 let Inst{4-0} = Rd;
2300}
2301
2302def inv_cond_XFORM : SDNodeXForm<imm, [{
2303 AArch64CC::CondCode CC = static_cast<AArch64CC::CondCode>(N->getZExtValue());
Sergey Dmitrouk842a51b2015-04-28 14:05:47 +00002304 return CurDAG->getTargetConstant(AArch64CC::getInvertedCondCode(CC), SDLoc(N),
2305 MVT::i32);
Tim Northover3b0846e2014-05-24 12:50:23 +00002306}]>;
2307
2308multiclass CondSelectOp<bit op, bits<2> op2, string asm, PatFrag frag> {
2309 def Wr : BaseCondSelectOp<op, op2, GPR32, asm, frag> {
2310 let Inst{31} = 0;
2311 }
2312 def Xr : BaseCondSelectOp<op, op2, GPR64, asm, frag> {
2313 let Inst{31} = 1;
2314 }
2315
2316 def : Pat<(AArch64csel (frag GPR32:$Rm), GPR32:$Rn, (i32 imm:$cond), NZCV),
2317 (!cast<Instruction>(NAME # Wr) GPR32:$Rn, GPR32:$Rm,
2318 (inv_cond_XFORM imm:$cond))>;
2319
2320 def : Pat<(AArch64csel (frag GPR64:$Rm), GPR64:$Rn, (i32 imm:$cond), NZCV),
2321 (!cast<Instruction>(NAME # Xr) GPR64:$Rn, GPR64:$Rm,
2322 (inv_cond_XFORM imm:$cond))>;
2323}
2324
2325//---
2326// Special Mask Value
2327//---
2328def maski8_or_more : Operand<i32>,
2329 ImmLeaf<i32, [{ return (Imm & 0xff) == 0xff; }]> {
2330}
2331def maski16_or_more : Operand<i32>,
2332 ImmLeaf<i32, [{ return (Imm & 0xffff) == 0xffff; }]> {
2333}
2334
2335
2336//---
2337// Load/store
2338//---
2339
2340// (unsigned immediate)
2341// Indexed for 8-bit registers. offset is in range [0,4095].
2342def am_indexed8 : ComplexPattern<i64, 2, "SelectAddrModeIndexed8", []>;
2343def am_indexed16 : ComplexPattern<i64, 2, "SelectAddrModeIndexed16", []>;
2344def am_indexed32 : ComplexPattern<i64, 2, "SelectAddrModeIndexed32", []>;
2345def am_indexed64 : ComplexPattern<i64, 2, "SelectAddrModeIndexed64", []>;
2346def am_indexed128 : ComplexPattern<i64, 2, "SelectAddrModeIndexed128", []>;
2347
2348class UImm12OffsetOperand<int Scale> : AsmOperandClass {
2349 let Name = "UImm12Offset" # Scale;
2350 let RenderMethod = "addUImm12OffsetOperands<" # Scale # ">";
2351 let PredicateMethod = "isUImm12Offset<" # Scale # ">";
2352 let DiagnosticType = "InvalidMemoryIndexed" # Scale;
2353}
2354
2355def UImm12OffsetScale1Operand : UImm12OffsetOperand<1>;
2356def UImm12OffsetScale2Operand : UImm12OffsetOperand<2>;
2357def UImm12OffsetScale4Operand : UImm12OffsetOperand<4>;
2358def UImm12OffsetScale8Operand : UImm12OffsetOperand<8>;
2359def UImm12OffsetScale16Operand : UImm12OffsetOperand<16>;
2360
2361class uimm12_scaled<int Scale> : Operand<i64> {
2362 let ParserMatchClass
2363 = !cast<AsmOperandClass>("UImm12OffsetScale" # Scale # "Operand");
2364 let EncoderMethod
2365 = "getLdStUImm12OpValue<AArch64::fixup_aarch64_ldst_imm12_scale" # Scale # ">";
2366 let PrintMethod = "printUImm12Offset<" # Scale # ">";
2367}
2368
2369def uimm12s1 : uimm12_scaled<1>;
2370def uimm12s2 : uimm12_scaled<2>;
2371def uimm12s4 : uimm12_scaled<4>;
2372def uimm12s8 : uimm12_scaled<8>;
2373def uimm12s16 : uimm12_scaled<16>;
2374
2375class BaseLoadStoreUI<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops,
2376 string asm, list<dag> pattern>
2377 : I<oops, iops, asm, "\t$Rt, [$Rn, $offset]", "", pattern> {
2378 bits<5> Rt;
2379
2380 bits<5> Rn;
2381 bits<12> offset;
2382
2383 let Inst{31-30} = sz;
2384 let Inst{29-27} = 0b111;
2385 let Inst{26} = V;
2386 let Inst{25-24} = 0b01;
2387 let Inst{23-22} = opc;
2388 let Inst{21-10} = offset;
2389 let Inst{9-5} = Rn;
2390 let Inst{4-0} = Rt;
2391
2392 let DecoderMethod = "DecodeUnsignedLdStInstruction";
2393}
2394
2395multiclass LoadUI<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2396 Operand indextype, string asm, list<dag> pattern> {
2397 let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
2398 def ui : BaseLoadStoreUI<sz, V, opc, (outs regtype:$Rt),
2399 (ins GPR64sp:$Rn, indextype:$offset),
2400 asm, pattern>,
2401 Sched<[WriteLD]>;
2402
Ahmed Bougacha63fae0e2015-09-02 18:52:54 +00002403 def : InstAlias<asm # "\t$Rt, [$Rn]",
Tim Northover3b0846e2014-05-24 12:50:23 +00002404 (!cast<Instruction>(NAME # "ui") regtype:$Rt, GPR64sp:$Rn, 0)>;
2405}
2406
2407multiclass StoreUI<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2408 Operand indextype, string asm, list<dag> pattern> {
2409 let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
2410 def ui : BaseLoadStoreUI<sz, V, opc, (outs),
2411 (ins regtype:$Rt, GPR64sp:$Rn, indextype:$offset),
2412 asm, pattern>,
2413 Sched<[WriteST]>;
2414
Ahmed Bougacha63fae0e2015-09-02 18:52:54 +00002415 def : InstAlias<asm # "\t$Rt, [$Rn]",
Tim Northover3b0846e2014-05-24 12:50:23 +00002416 (!cast<Instruction>(NAME # "ui") regtype:$Rt, GPR64sp:$Rn, 0)>;
2417}
2418
2419def PrefetchOperand : AsmOperandClass {
2420 let Name = "Prefetch";
2421 let ParserMethod = "tryParsePrefetch";
2422}
2423def prfop : Operand<i32> {
2424 let PrintMethod = "printPrefetchOp";
2425 let ParserMatchClass = PrefetchOperand;
2426}
2427
2428let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in
2429class PrefetchUI<bits<2> sz, bit V, bits<2> opc, string asm, list<dag> pat>
2430 : BaseLoadStoreUI<sz, V, opc,
2431 (outs), (ins prfop:$Rt, GPR64sp:$Rn, uimm12s8:$offset),
2432 asm, pat>,
2433 Sched<[WriteLD]>;
2434
2435//---
2436// Load literal
2437//---
2438
2439// Load literal address: 19-bit immediate. The low two bits of the target
2440// offset are implied zero and so are not part of the immediate.
2441def am_ldrlit : Operand<OtherVT> {
2442 let EncoderMethod = "getLoadLiteralOpValue";
2443 let DecoderMethod = "DecodePCRelLabel19";
2444 let PrintMethod = "printAlignedLabel";
2445 let ParserMatchClass = PCRelLabel19Operand;
2446}
2447
2448let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
2449class LoadLiteral<bits<2> opc, bit V, RegisterClass regtype, string asm>
2450 : I<(outs regtype:$Rt), (ins am_ldrlit:$label),
2451 asm, "\t$Rt, $label", "", []>,
2452 Sched<[WriteLD]> {
2453 bits<5> Rt;
2454 bits<19> label;
2455 let Inst{31-30} = opc;
2456 let Inst{29-27} = 0b011;
2457 let Inst{26} = V;
2458 let Inst{25-24} = 0b00;
2459 let Inst{23-5} = label;
2460 let Inst{4-0} = Rt;
2461}
2462
2463let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in
2464class PrefetchLiteral<bits<2> opc, bit V, string asm, list<dag> pat>
2465 : I<(outs), (ins prfop:$Rt, am_ldrlit:$label),
2466 asm, "\t$Rt, $label", "", pat>,
2467 Sched<[WriteLD]> {
2468 bits<5> Rt;
2469 bits<19> label;
2470 let Inst{31-30} = opc;
2471 let Inst{29-27} = 0b011;
2472 let Inst{26} = V;
2473 let Inst{25-24} = 0b00;
2474 let Inst{23-5} = label;
2475 let Inst{4-0} = Rt;
2476}
2477
2478//---
2479// Load/store register offset
2480//---
2481
2482def ro_Xindexed8 : ComplexPattern<i64, 4, "SelectAddrModeXRO<8>", []>;
2483def ro_Xindexed16 : ComplexPattern<i64, 4, "SelectAddrModeXRO<16>", []>;
2484def ro_Xindexed32 : ComplexPattern<i64, 4, "SelectAddrModeXRO<32>", []>;
2485def ro_Xindexed64 : ComplexPattern<i64, 4, "SelectAddrModeXRO<64>", []>;
2486def ro_Xindexed128 : ComplexPattern<i64, 4, "SelectAddrModeXRO<128>", []>;
2487
2488def ro_Windexed8 : ComplexPattern<i64, 4, "SelectAddrModeWRO<8>", []>;
2489def ro_Windexed16 : ComplexPattern<i64, 4, "SelectAddrModeWRO<16>", []>;
2490def ro_Windexed32 : ComplexPattern<i64, 4, "SelectAddrModeWRO<32>", []>;
2491def ro_Windexed64 : ComplexPattern<i64, 4, "SelectAddrModeWRO<64>", []>;
2492def ro_Windexed128 : ComplexPattern<i64, 4, "SelectAddrModeWRO<128>", []>;
2493
2494class MemExtendOperand<string Reg, int Width> : AsmOperandClass {
2495 let Name = "Mem" # Reg # "Extend" # Width;
2496 let PredicateMethod = "isMem" # Reg # "Extend<" # Width # ">";
2497 let RenderMethod = "addMemExtendOperands";
2498 let DiagnosticType = "InvalidMemory" # Reg # "Extend" # Width;
2499}
2500
2501def MemWExtend8Operand : MemExtendOperand<"W", 8> {
2502 // The address "[x0, x1, lsl #0]" actually maps to the variant which performs
2503 // the trivial shift.
2504 let RenderMethod = "addMemExtend8Operands";
2505}
2506def MemWExtend16Operand : MemExtendOperand<"W", 16>;
2507def MemWExtend32Operand : MemExtendOperand<"W", 32>;
2508def MemWExtend64Operand : MemExtendOperand<"W", 64>;
2509def MemWExtend128Operand : MemExtendOperand<"W", 128>;
2510
2511def MemXExtend8Operand : MemExtendOperand<"X", 8> {
2512 // The address "[x0, x1, lsl #0]" actually maps to the variant which performs
2513 // the trivial shift.
2514 let RenderMethod = "addMemExtend8Operands";
2515}
2516def MemXExtend16Operand : MemExtendOperand<"X", 16>;
2517def MemXExtend32Operand : MemExtendOperand<"X", 32>;
2518def MemXExtend64Operand : MemExtendOperand<"X", 64>;
2519def MemXExtend128Operand : MemExtendOperand<"X", 128>;
2520
2521class ro_extend<AsmOperandClass ParserClass, string Reg, int Width>
2522 : Operand<i32> {
2523 let ParserMatchClass = ParserClass;
2524 let PrintMethod = "printMemExtend<'" # Reg # "', " # Width # ">";
2525 let DecoderMethod = "DecodeMemExtend";
2526 let EncoderMethod = "getMemExtendOpValue";
2527 let MIOperandInfo = (ops i32imm:$signed, i32imm:$doshift);
2528}
2529
2530def ro_Wextend8 : ro_extend<MemWExtend8Operand, "w", 8>;
2531def ro_Wextend16 : ro_extend<MemWExtend16Operand, "w", 16>;
2532def ro_Wextend32 : ro_extend<MemWExtend32Operand, "w", 32>;
2533def ro_Wextend64 : ro_extend<MemWExtend64Operand, "w", 64>;
2534def ro_Wextend128 : ro_extend<MemWExtend128Operand, "w", 128>;
2535
2536def ro_Xextend8 : ro_extend<MemXExtend8Operand, "x", 8>;
2537def ro_Xextend16 : ro_extend<MemXExtend16Operand, "x", 16>;
2538def ro_Xextend32 : ro_extend<MemXExtend32Operand, "x", 32>;
2539def ro_Xextend64 : ro_extend<MemXExtend64Operand, "x", 64>;
2540def ro_Xextend128 : ro_extend<MemXExtend128Operand, "x", 128>;
2541
2542class ROAddrMode<ComplexPattern windex, ComplexPattern xindex,
2543 Operand wextend, Operand xextend> {
2544 // CodeGen-level pattern covering the entire addressing mode.
2545 ComplexPattern Wpat = windex;
2546 ComplexPattern Xpat = xindex;
2547
2548 // Asm-level Operand covering the valid "uxtw #3" style syntax.
2549 Operand Wext = wextend;
2550 Operand Xext = xextend;
2551}
2552
2553def ro8 : ROAddrMode<ro_Windexed8, ro_Xindexed8, ro_Wextend8, ro_Xextend8>;
2554def ro16 : ROAddrMode<ro_Windexed16, ro_Xindexed16, ro_Wextend16, ro_Xextend16>;
2555def ro32 : ROAddrMode<ro_Windexed32, ro_Xindexed32, ro_Wextend32, ro_Xextend32>;
2556def ro64 : ROAddrMode<ro_Windexed64, ro_Xindexed64, ro_Wextend64, ro_Xextend64>;
2557def ro128 : ROAddrMode<ro_Windexed128, ro_Xindexed128, ro_Wextend128,
2558 ro_Xextend128>;
2559
2560class LoadStore8RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2561 string asm, dag ins, dag outs, list<dag> pat>
2562 : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> {
2563 bits<5> Rt;
2564 bits<5> Rn;
2565 bits<5> Rm;
2566 bits<2> extend;
2567 let Inst{31-30} = sz;
2568 let Inst{29-27} = 0b111;
2569 let Inst{26} = V;
2570 let Inst{25-24} = 0b00;
2571 let Inst{23-22} = opc;
2572 let Inst{21} = 1;
2573 let Inst{20-16} = Rm;
2574 let Inst{15} = extend{1}; // sign extend Rm?
2575 let Inst{14} = 1;
2576 let Inst{12} = extend{0}; // do shift?
2577 let Inst{11-10} = 0b10;
2578 let Inst{9-5} = Rn;
2579 let Inst{4-0} = Rt;
2580}
2581
2582class ROInstAlias<string asm, RegisterClass regtype, Instruction INST>
Ahmed Bougachacca07712015-09-02 18:38:36 +00002583 : InstAlias<asm # "\t$Rt, [$Rn, $Rm]",
Tim Northover3b0846e2014-05-24 12:50:23 +00002584 (INST regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, 0, 0)>;
2585
2586multiclass Load8RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2587 string asm, ValueType Ty, SDPatternOperator loadop> {
2588 let AddedComplexity = 10 in
2589 def roW : LoadStore8RO<sz, V, opc, regtype, asm,
2590 (outs regtype:$Rt),
2591 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend8:$extend),
2592 [(set (Ty regtype:$Rt),
2593 (loadop (ro_Windexed8 GPR64sp:$Rn, GPR32:$Rm,
2594 ro_Wextend8:$extend)))]>,
2595 Sched<[WriteLDIdx, ReadAdrBase]> {
2596 let Inst{13} = 0b0;
2597 }
2598
2599 let AddedComplexity = 10 in
2600 def roX : LoadStore8RO<sz, V, opc, regtype, asm,
2601 (outs regtype:$Rt),
2602 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend8:$extend),
2603 [(set (Ty regtype:$Rt),
2604 (loadop (ro_Xindexed8 GPR64sp:$Rn, GPR64:$Rm,
2605 ro_Xextend8:$extend)))]>,
2606 Sched<[WriteLDIdx, ReadAdrBase]> {
2607 let Inst{13} = 0b1;
2608 }
2609
2610 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
2611}
2612
2613multiclass Store8RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2614 string asm, ValueType Ty, SDPatternOperator storeop> {
2615 let AddedComplexity = 10 in
2616 def roW : LoadStore8RO<sz, V, opc, regtype, asm, (outs),
2617 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend8:$extend),
2618 [(storeop (Ty regtype:$Rt),
2619 (ro_Windexed8 GPR64sp:$Rn, GPR32:$Rm,
2620 ro_Wextend8:$extend))]>,
2621 Sched<[WriteSTIdx, ReadAdrBase]> {
2622 let Inst{13} = 0b0;
2623 }
2624
2625 let AddedComplexity = 10 in
2626 def roX : LoadStore8RO<sz, V, opc, regtype, asm, (outs),
2627 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend8:$extend),
2628 [(storeop (Ty regtype:$Rt),
2629 (ro_Xindexed8 GPR64sp:$Rn, GPR64:$Rm,
2630 ro_Xextend8:$extend))]>,
2631 Sched<[WriteSTIdx, ReadAdrBase]> {
2632 let Inst{13} = 0b1;
2633 }
2634
2635 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
2636}
2637
2638class LoadStore16RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2639 string asm, dag ins, dag outs, list<dag> pat>
2640 : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> {
2641 bits<5> Rt;
2642 bits<5> Rn;
2643 bits<5> Rm;
2644 bits<2> extend;
2645 let Inst{31-30} = sz;
2646 let Inst{29-27} = 0b111;
2647 let Inst{26} = V;
2648 let Inst{25-24} = 0b00;
2649 let Inst{23-22} = opc;
2650 let Inst{21} = 1;
2651 let Inst{20-16} = Rm;
2652 let Inst{15} = extend{1}; // sign extend Rm?
2653 let Inst{14} = 1;
2654 let Inst{12} = extend{0}; // do shift?
2655 let Inst{11-10} = 0b10;
2656 let Inst{9-5} = Rn;
2657 let Inst{4-0} = Rt;
2658}
2659
2660multiclass Load16RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2661 string asm, ValueType Ty, SDPatternOperator loadop> {
2662 let AddedComplexity = 10 in
2663 def roW : LoadStore16RO<sz, V, opc, regtype, asm, (outs regtype:$Rt),
2664 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend16:$extend),
2665 [(set (Ty regtype:$Rt),
2666 (loadop (ro_Windexed16 GPR64sp:$Rn, GPR32:$Rm,
2667 ro_Wextend16:$extend)))]>,
2668 Sched<[WriteLDIdx, ReadAdrBase]> {
2669 let Inst{13} = 0b0;
2670 }
2671
2672 let AddedComplexity = 10 in
2673 def roX : LoadStore16RO<sz, V, opc, regtype, asm, (outs regtype:$Rt),
2674 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend16:$extend),
2675 [(set (Ty regtype:$Rt),
2676 (loadop (ro_Xindexed16 GPR64sp:$Rn, GPR64:$Rm,
2677 ro_Xextend16:$extend)))]>,
2678 Sched<[WriteLDIdx, ReadAdrBase]> {
2679 let Inst{13} = 0b1;
2680 }
2681
2682 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
2683}
2684
2685multiclass Store16RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2686 string asm, ValueType Ty, SDPatternOperator storeop> {
2687 let AddedComplexity = 10 in
2688 def roW : LoadStore16RO<sz, V, opc, regtype, asm, (outs),
2689 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend16:$extend),
2690 [(storeop (Ty regtype:$Rt),
2691 (ro_Windexed16 GPR64sp:$Rn, GPR32:$Rm,
2692 ro_Wextend16:$extend))]>,
2693 Sched<[WriteSTIdx, ReadAdrBase]> {
2694 let Inst{13} = 0b0;
2695 }
2696
2697 let AddedComplexity = 10 in
2698 def roX : LoadStore16RO<sz, V, opc, regtype, asm, (outs),
2699 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend16:$extend),
2700 [(storeop (Ty regtype:$Rt),
2701 (ro_Xindexed16 GPR64sp:$Rn, GPR64:$Rm,
2702 ro_Xextend16:$extend))]>,
2703 Sched<[WriteSTIdx, ReadAdrBase]> {
2704 let Inst{13} = 0b1;
2705 }
2706
2707 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
2708}
2709
2710class LoadStore32RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2711 string asm, dag ins, dag outs, list<dag> pat>
2712 : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> {
2713 bits<5> Rt;
2714 bits<5> Rn;
2715 bits<5> Rm;
2716 bits<2> extend;
2717 let Inst{31-30} = sz;
2718 let Inst{29-27} = 0b111;
2719 let Inst{26} = V;
2720 let Inst{25-24} = 0b00;
2721 let Inst{23-22} = opc;
2722 let Inst{21} = 1;
2723 let Inst{20-16} = Rm;
2724 let Inst{15} = extend{1}; // sign extend Rm?
2725 let Inst{14} = 1;
2726 let Inst{12} = extend{0}; // do shift?
2727 let Inst{11-10} = 0b10;
2728 let Inst{9-5} = Rn;
2729 let Inst{4-0} = Rt;
2730}
2731
2732multiclass Load32RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2733 string asm, ValueType Ty, SDPatternOperator loadop> {
2734 let AddedComplexity = 10 in
2735 def roW : LoadStore32RO<sz, V, opc, regtype, asm, (outs regtype:$Rt),
2736 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend32:$extend),
2737 [(set (Ty regtype:$Rt),
2738 (loadop (ro_Windexed32 GPR64sp:$Rn, GPR32:$Rm,
2739 ro_Wextend32:$extend)))]>,
2740 Sched<[WriteLDIdx, ReadAdrBase]> {
2741 let Inst{13} = 0b0;
2742 }
2743
2744 let AddedComplexity = 10 in
2745 def roX : LoadStore32RO<sz, V, opc, regtype, asm, (outs regtype:$Rt),
2746 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend32:$extend),
2747 [(set (Ty regtype:$Rt),
2748 (loadop (ro_Xindexed32 GPR64sp:$Rn, GPR64:$Rm,
2749 ro_Xextend32:$extend)))]>,
2750 Sched<[WriteLDIdx, ReadAdrBase]> {
2751 let Inst{13} = 0b1;
2752 }
2753
2754 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
2755}
2756
2757multiclass Store32RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2758 string asm, ValueType Ty, SDPatternOperator storeop> {
2759 let AddedComplexity = 10 in
2760 def roW : LoadStore32RO<sz, V, opc, regtype, asm, (outs),
2761 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend32:$extend),
2762 [(storeop (Ty regtype:$Rt),
2763 (ro_Windexed32 GPR64sp:$Rn, GPR32:$Rm,
2764 ro_Wextend32:$extend))]>,
2765 Sched<[WriteSTIdx, ReadAdrBase]> {
2766 let Inst{13} = 0b0;
2767 }
2768
2769 let AddedComplexity = 10 in
2770 def roX : LoadStore32RO<sz, V, opc, regtype, asm, (outs),
2771 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend32:$extend),
2772 [(storeop (Ty regtype:$Rt),
2773 (ro_Xindexed32 GPR64sp:$Rn, GPR64:$Rm,
2774 ro_Xextend32:$extend))]>,
2775 Sched<[WriteSTIdx, ReadAdrBase]> {
2776 let Inst{13} = 0b1;
2777 }
2778
2779 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
2780}
2781
2782class LoadStore64RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2783 string asm, dag ins, dag outs, list<dag> pat>
2784 : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> {
2785 bits<5> Rt;
2786 bits<5> Rn;
2787 bits<5> Rm;
2788 bits<2> extend;
2789 let Inst{31-30} = sz;
2790 let Inst{29-27} = 0b111;
2791 let Inst{26} = V;
2792 let Inst{25-24} = 0b00;
2793 let Inst{23-22} = opc;
2794 let Inst{21} = 1;
2795 let Inst{20-16} = Rm;
2796 let Inst{15} = extend{1}; // sign extend Rm?
2797 let Inst{14} = 1;
2798 let Inst{12} = extend{0}; // do shift?
2799 let Inst{11-10} = 0b10;
2800 let Inst{9-5} = Rn;
2801 let Inst{4-0} = Rt;
2802}
2803
2804multiclass Load64RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2805 string asm, ValueType Ty, SDPatternOperator loadop> {
2806 let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
2807 def roW : LoadStore64RO<sz, V, opc, regtype, asm, (outs regtype:$Rt),
2808 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend64:$extend),
2809 [(set (Ty regtype:$Rt),
2810 (loadop (ro_Windexed64 GPR64sp:$Rn, GPR32:$Rm,
2811 ro_Wextend64:$extend)))]>,
2812 Sched<[WriteLDIdx, ReadAdrBase]> {
2813 let Inst{13} = 0b0;
2814 }
2815
2816 let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
2817 def roX : LoadStore64RO<sz, V, opc, regtype, asm, (outs regtype:$Rt),
2818 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend64:$extend),
2819 [(set (Ty regtype:$Rt),
2820 (loadop (ro_Xindexed64 GPR64sp:$Rn, GPR64:$Rm,
2821 ro_Xextend64:$extend)))]>,
2822 Sched<[WriteLDIdx, ReadAdrBase]> {
2823 let Inst{13} = 0b1;
2824 }
2825
2826 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
2827}
2828
2829multiclass Store64RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2830 string asm, ValueType Ty, SDPatternOperator storeop> {
2831 let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
2832 def roW : LoadStore64RO<sz, V, opc, regtype, asm, (outs),
2833 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend64:$extend),
2834 [(storeop (Ty regtype:$Rt),
2835 (ro_Windexed64 GPR64sp:$Rn, GPR32:$Rm,
2836 ro_Wextend64:$extend))]>,
2837 Sched<[WriteSTIdx, ReadAdrBase]> {
2838 let Inst{13} = 0b0;
2839 }
2840
2841 let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
2842 def roX : LoadStore64RO<sz, V, opc, regtype, asm, (outs),
2843 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend64:$extend),
2844 [(storeop (Ty regtype:$Rt),
2845 (ro_Xindexed64 GPR64sp:$Rn, GPR64:$Rm,
2846 ro_Xextend64:$extend))]>,
2847 Sched<[WriteSTIdx, ReadAdrBase]> {
2848 let Inst{13} = 0b1;
2849 }
2850
2851 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
2852}
2853
2854class LoadStore128RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2855 string asm, dag ins, dag outs, list<dag> pat>
2856 : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> {
2857 bits<5> Rt;
2858 bits<5> Rn;
2859 bits<5> Rm;
2860 bits<2> extend;
2861 let Inst{31-30} = sz;
2862 let Inst{29-27} = 0b111;
2863 let Inst{26} = V;
2864 let Inst{25-24} = 0b00;
2865 let Inst{23-22} = opc;
2866 let Inst{21} = 1;
2867 let Inst{20-16} = Rm;
2868 let Inst{15} = extend{1}; // sign extend Rm?
2869 let Inst{14} = 1;
2870 let Inst{12} = extend{0}; // do shift?
2871 let Inst{11-10} = 0b10;
2872 let Inst{9-5} = Rn;
2873 let Inst{4-0} = Rt;
2874}
2875
2876multiclass Load128RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2877 string asm, ValueType Ty, SDPatternOperator loadop> {
2878 let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
2879 def roW : LoadStore128RO<sz, V, opc, regtype, asm, (outs regtype:$Rt),
2880 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend128:$extend),
2881 [(set (Ty regtype:$Rt),
2882 (loadop (ro_Windexed128 GPR64sp:$Rn, GPR32:$Rm,
2883 ro_Wextend128:$extend)))]>,
2884 Sched<[WriteLDIdx, ReadAdrBase]> {
2885 let Inst{13} = 0b0;
2886 }
2887
2888 let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
2889 def roX : LoadStore128RO<sz, V, opc, regtype, asm, (outs regtype:$Rt),
2890 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend128:$extend),
2891 [(set (Ty regtype:$Rt),
2892 (loadop (ro_Xindexed128 GPR64sp:$Rn, GPR64:$Rm,
2893 ro_Xextend128:$extend)))]>,
2894 Sched<[WriteLDIdx, ReadAdrBase]> {
2895 let Inst{13} = 0b1;
2896 }
2897
2898 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
2899}
2900
2901multiclass Store128RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2902 string asm, ValueType Ty, SDPatternOperator storeop> {
2903 let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
2904 def roW : LoadStore128RO<sz, V, opc, regtype, asm, (outs),
2905 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend128:$extend),
2906 [(storeop (Ty regtype:$Rt),
2907 (ro_Windexed128 GPR64sp:$Rn, GPR32:$Rm,
2908 ro_Wextend128:$extend))]>,
2909 Sched<[WriteSTIdx, ReadAdrBase]> {
2910 let Inst{13} = 0b0;
2911 }
2912
2913 let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
2914 def roX : LoadStore128RO<sz, V, opc, regtype, asm, (outs),
2915 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend128:$extend),
2916 [(storeop (Ty regtype:$Rt),
2917 (ro_Xindexed128 GPR64sp:$Rn, GPR64:$Rm,
2918 ro_Xextend128:$extend))]>,
2919 Sched<[WriteSTIdx, ReadAdrBase]> {
2920 let Inst{13} = 0b1;
2921 }
2922
2923 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
2924}
2925
2926let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in
2927class BasePrefetchRO<bits<2> sz, bit V, bits<2> opc, dag outs, dag ins,
2928 string asm, list<dag> pat>
2929 : I<outs, ins, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat>,
2930 Sched<[WriteLD]> {
2931 bits<5> Rt;
2932 bits<5> Rn;
2933 bits<5> Rm;
2934 bits<2> extend;
2935 let Inst{31-30} = sz;
2936 let Inst{29-27} = 0b111;
2937 let Inst{26} = V;
2938 let Inst{25-24} = 0b00;
2939 let Inst{23-22} = opc;
2940 let Inst{21} = 1;
2941 let Inst{20-16} = Rm;
2942 let Inst{15} = extend{1}; // sign extend Rm?
2943 let Inst{14} = 1;
2944 let Inst{12} = extend{0}; // do shift?
2945 let Inst{11-10} = 0b10;
2946 let Inst{9-5} = Rn;
2947 let Inst{4-0} = Rt;
2948}
2949
2950multiclass PrefetchRO<bits<2> sz, bit V, bits<2> opc, string asm> {
2951 def roW : BasePrefetchRO<sz, V, opc, (outs),
2952 (ins prfop:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend64:$extend),
2953 asm, [(AArch64Prefetch imm:$Rt,
2954 (ro_Windexed64 GPR64sp:$Rn, GPR32:$Rm,
2955 ro_Wextend64:$extend))]> {
2956 let Inst{13} = 0b0;
2957 }
2958
2959 def roX : BasePrefetchRO<sz, V, opc, (outs),
2960 (ins prfop:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend64:$extend),
2961 asm, [(AArch64Prefetch imm:$Rt,
2962 (ro_Xindexed64 GPR64sp:$Rn, GPR64:$Rm,
2963 ro_Xextend64:$extend))]> {
2964 let Inst{13} = 0b1;
2965 }
2966
2967 def : InstAlias<"prfm $Rt, [$Rn, $Rm]",
2968 (!cast<Instruction>(NAME # "roX") prfop:$Rt,
2969 GPR64sp:$Rn, GPR64:$Rm, 0, 0)>;
2970}
2971
2972//---
2973// Load/store unscaled immediate
2974//---
2975
2976def am_unscaled8 : ComplexPattern<i64, 2, "SelectAddrModeUnscaled8", []>;
2977def am_unscaled16 : ComplexPattern<i64, 2, "SelectAddrModeUnscaled16", []>;
2978def am_unscaled32 : ComplexPattern<i64, 2, "SelectAddrModeUnscaled32", []>;
2979def am_unscaled64 : ComplexPattern<i64, 2, "SelectAddrModeUnscaled64", []>;
2980def am_unscaled128 :ComplexPattern<i64, 2, "SelectAddrModeUnscaled128", []>;
2981
2982class BaseLoadStoreUnscale<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops,
2983 string asm, list<dag> pattern>
2984 : I<oops, iops, asm, "\t$Rt, [$Rn, $offset]", "", pattern> {
2985 bits<5> Rt;
2986 bits<5> Rn;
2987 bits<9> offset;
2988 let Inst{31-30} = sz;
2989 let Inst{29-27} = 0b111;
2990 let Inst{26} = V;
2991 let Inst{25-24} = 0b00;
2992 let Inst{23-22} = opc;
2993 let Inst{21} = 0;
2994 let Inst{20-12} = offset;
2995 let Inst{11-10} = 0b00;
2996 let Inst{9-5} = Rn;
2997 let Inst{4-0} = Rt;
2998
2999 let DecoderMethod = "DecodeSignedLdStInstruction";
3000}
3001
3002multiclass LoadUnscaled<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
3003 string asm, list<dag> pattern> {
3004 let AddedComplexity = 1 in // try this before LoadUI
3005 def i : BaseLoadStoreUnscale<sz, V, opc, (outs regtype:$Rt),
3006 (ins GPR64sp:$Rn, simm9:$offset), asm, pattern>,
3007 Sched<[WriteLD]>;
3008
Ahmed Bougachacca07712015-09-02 18:38:36 +00003009 def : InstAlias<asm # "\t$Rt, [$Rn]",
Tim Northover3b0846e2014-05-24 12:50:23 +00003010 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>;
3011}
3012
3013multiclass StoreUnscaled<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
3014 string asm, list<dag> pattern> {
3015 let AddedComplexity = 1 in // try this before StoreUI
3016 def i : BaseLoadStoreUnscale<sz, V, opc, (outs),
3017 (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset),
3018 asm, pattern>,
3019 Sched<[WriteST]>;
3020
Ahmed Bougachacca07712015-09-02 18:38:36 +00003021 def : InstAlias<asm # "\t$Rt, [$Rn]",
Tim Northover3b0846e2014-05-24 12:50:23 +00003022 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>;
3023}
3024
3025multiclass PrefetchUnscaled<bits<2> sz, bit V, bits<2> opc, string asm,
3026 list<dag> pat> {
3027 let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in
3028 def i : BaseLoadStoreUnscale<sz, V, opc, (outs),
3029 (ins prfop:$Rt, GPR64sp:$Rn, simm9:$offset),
3030 asm, pat>,
3031 Sched<[WriteLD]>;
3032
Ahmed Bougachacca07712015-09-02 18:38:36 +00003033 def : InstAlias<asm # "\t$Rt, [$Rn]",
Tim Northover3b0846e2014-05-24 12:50:23 +00003034 (!cast<Instruction>(NAME # "i") prfop:$Rt, GPR64sp:$Rn, 0)>;
3035}
3036
3037//---
3038// Load/store unscaled immediate, unprivileged
3039//---
3040
3041class BaseLoadStoreUnprivileged<bits<2> sz, bit V, bits<2> opc,
3042 dag oops, dag iops, string asm>
3043 : I<oops, iops, asm, "\t$Rt, [$Rn, $offset]", "", []> {
3044 bits<5> Rt;
3045 bits<5> Rn;
3046 bits<9> offset;
3047 let Inst{31-30} = sz;
3048 let Inst{29-27} = 0b111;
3049 let Inst{26} = V;
3050 let Inst{25-24} = 0b00;
3051 let Inst{23-22} = opc;
3052 let Inst{21} = 0;
3053 let Inst{20-12} = offset;
3054 let Inst{11-10} = 0b10;
3055 let Inst{9-5} = Rn;
3056 let Inst{4-0} = Rt;
3057
3058 let DecoderMethod = "DecodeSignedLdStInstruction";
3059}
3060
3061multiclass LoadUnprivileged<bits<2> sz, bit V, bits<2> opc,
3062 RegisterClass regtype, string asm> {
3063 let mayStore = 0, mayLoad = 1, hasSideEffects = 0 in
3064 def i : BaseLoadStoreUnprivileged<sz, V, opc, (outs regtype:$Rt),
3065 (ins GPR64sp:$Rn, simm9:$offset), asm>,
3066 Sched<[WriteLD]>;
3067
Ahmed Bougachacca07712015-09-02 18:38:36 +00003068 def : InstAlias<asm # "\t$Rt, [$Rn]",
Tim Northover3b0846e2014-05-24 12:50:23 +00003069 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>;
3070}
3071
3072multiclass StoreUnprivileged<bits<2> sz, bit V, bits<2> opc,
3073 RegisterClass regtype, string asm> {
3074 let mayStore = 1, mayLoad = 0, hasSideEffects = 0 in
3075 def i : BaseLoadStoreUnprivileged<sz, V, opc, (outs),
3076 (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset),
3077 asm>,
3078 Sched<[WriteST]>;
3079
Ahmed Bougachacca07712015-09-02 18:38:36 +00003080 def : InstAlias<asm # "\t$Rt, [$Rn]",
Tim Northover3b0846e2014-05-24 12:50:23 +00003081 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>;
3082}
3083
3084//---
3085// Load/store pre-indexed
3086//---
3087
3088class BaseLoadStorePreIdx<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops,
3089 string asm, string cstr, list<dag> pat>
3090 : I<oops, iops, asm, "\t$Rt, [$Rn, $offset]!", cstr, pat> {
3091 bits<5> Rt;
3092 bits<5> Rn;
3093 bits<9> offset;
3094 let Inst{31-30} = sz;
3095 let Inst{29-27} = 0b111;
3096 let Inst{26} = V;
3097 let Inst{25-24} = 0;
3098 let Inst{23-22} = opc;
3099 let Inst{21} = 0;
3100 let Inst{20-12} = offset;
3101 let Inst{11-10} = 0b11;
3102 let Inst{9-5} = Rn;
3103 let Inst{4-0} = Rt;
3104
3105 let DecoderMethod = "DecodeSignedLdStInstruction";
3106}
3107
3108let hasSideEffects = 0 in {
3109let mayStore = 0, mayLoad = 1 in
3110class LoadPreIdx<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
3111 string asm>
3112 : BaseLoadStorePreIdx<sz, V, opc,
3113 (outs GPR64sp:$wback, regtype:$Rt),
3114 (ins GPR64sp:$Rn, simm9:$offset), asm,
Quentin Colombetc64c1752014-08-11 21:39:53 +00003115 "$Rn = $wback,@earlyclobber $wback", []>,
Tim Northover3b0846e2014-05-24 12:50:23 +00003116 Sched<[WriteLD, WriteAdr]>;
3117
3118let mayStore = 1, mayLoad = 0 in
3119class StorePreIdx<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
3120 string asm, SDPatternOperator storeop, ValueType Ty>
3121 : BaseLoadStorePreIdx<sz, V, opc,
3122 (outs GPR64sp:$wback),
3123 (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset),
Quentin Colombetc64c1752014-08-11 21:39:53 +00003124 asm, "$Rn = $wback,@earlyclobber $wback",
Tim Northover3b0846e2014-05-24 12:50:23 +00003125 [(set GPR64sp:$wback,
3126 (storeop (Ty regtype:$Rt), GPR64sp:$Rn, simm9:$offset))]>,
3127 Sched<[WriteAdr, WriteST]>;
3128} // hasSideEffects = 0
3129
3130//---
3131// Load/store post-indexed
3132//---
3133
Tim Northover3b0846e2014-05-24 12:50:23 +00003134class BaseLoadStorePostIdx<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops,
3135 string asm, string cstr, list<dag> pat>
3136 : I<oops, iops, asm, "\t$Rt, [$Rn], $offset", cstr, pat> {
3137 bits<5> Rt;
3138 bits<5> Rn;
3139 bits<9> offset;
3140 let Inst{31-30} = sz;
3141 let Inst{29-27} = 0b111;
3142 let Inst{26} = V;
3143 let Inst{25-24} = 0b00;
3144 let Inst{23-22} = opc;
3145 let Inst{21} = 0b0;
3146 let Inst{20-12} = offset;
3147 let Inst{11-10} = 0b01;
3148 let Inst{9-5} = Rn;
3149 let Inst{4-0} = Rt;
3150
3151 let DecoderMethod = "DecodeSignedLdStInstruction";
3152}
3153
3154let hasSideEffects = 0 in {
3155let mayStore = 0, mayLoad = 1 in
3156class LoadPostIdx<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
3157 string asm>
3158 : BaseLoadStorePostIdx<sz, V, opc,
3159 (outs GPR64sp:$wback, regtype:$Rt),
3160 (ins GPR64sp:$Rn, simm9:$offset),
Quentin Colombetc64c1752014-08-11 21:39:53 +00003161 asm, "$Rn = $wback,@earlyclobber $wback", []>,
Tim Northover3b0846e2014-05-24 12:50:23 +00003162 Sched<[WriteLD, WriteI]>;
3163
3164let mayStore = 1, mayLoad = 0 in
3165class StorePostIdx<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
3166 string asm, SDPatternOperator storeop, ValueType Ty>
3167 : BaseLoadStorePostIdx<sz, V, opc,
3168 (outs GPR64sp:$wback),
3169 (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset),
Quentin Colombetc64c1752014-08-11 21:39:53 +00003170 asm, "$Rn = $wback,@earlyclobber $wback",
Tim Northover3b0846e2014-05-24 12:50:23 +00003171 [(set GPR64sp:$wback,
3172 (storeop (Ty regtype:$Rt), GPR64sp:$Rn, simm9:$offset))]>,
3173 Sched<[WriteAdr, WriteST, ReadAdrBase]>;
3174} // hasSideEffects = 0
3175
3176
3177//---
3178// Load/store pair
3179//---
3180
3181// (indexed, offset)
3182
3183class BaseLoadStorePairOffset<bits<2> opc, bit V, bit L, dag oops, dag iops,
3184 string asm>
3185 : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn, $offset]", "", []> {
3186 bits<5> Rt;
3187 bits<5> Rt2;
3188 bits<5> Rn;
3189 bits<7> offset;
3190 let Inst{31-30} = opc;
3191 let Inst{29-27} = 0b101;
3192 let Inst{26} = V;
3193 let Inst{25-23} = 0b010;
3194 let Inst{22} = L;
3195 let Inst{21-15} = offset;
3196 let Inst{14-10} = Rt2;
3197 let Inst{9-5} = Rn;
3198 let Inst{4-0} = Rt;
3199
3200 let DecoderMethod = "DecodePairLdStInstruction";
3201}
3202
3203multiclass LoadPairOffset<bits<2> opc, bit V, RegisterClass regtype,
3204 Operand indextype, string asm> {
3205 let hasSideEffects = 0, mayStore = 0, mayLoad = 1 in
3206 def i : BaseLoadStorePairOffset<opc, V, 1,
3207 (outs regtype:$Rt, regtype:$Rt2),
3208 (ins GPR64sp:$Rn, indextype:$offset), asm>,
3209 Sched<[WriteLD, WriteLDHi]>;
3210
Ahmed Bougachacca07712015-09-02 18:38:36 +00003211 def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]",
Tim Northover3b0846e2014-05-24 12:50:23 +00003212 (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2,
3213 GPR64sp:$Rn, 0)>;
3214}
3215
3216
3217multiclass StorePairOffset<bits<2> opc, bit V, RegisterClass regtype,
3218 Operand indextype, string asm> {
3219 let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in
3220 def i : BaseLoadStorePairOffset<opc, V, 0, (outs),
3221 (ins regtype:$Rt, regtype:$Rt2,
3222 GPR64sp:$Rn, indextype:$offset),
3223 asm>,
3224 Sched<[WriteSTP]>;
3225
Ahmed Bougachacca07712015-09-02 18:38:36 +00003226 def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]",
Tim Northover3b0846e2014-05-24 12:50:23 +00003227 (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2,
3228 GPR64sp:$Rn, 0)>;
3229}
3230
3231// (pre-indexed)
3232class BaseLoadStorePairPreIdx<bits<2> opc, bit V, bit L, dag oops, dag iops,
3233 string asm>
Quentin Colombetc64c1752014-08-11 21:39:53 +00003234 : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn, $offset]!", "$Rn = $wback,@earlyclobber $wback", []> {
Tim Northover3b0846e2014-05-24 12:50:23 +00003235 bits<5> Rt;
3236 bits<5> Rt2;
3237 bits<5> Rn;
3238 bits<7> offset;
3239 let Inst{31-30} = opc;
3240 let Inst{29-27} = 0b101;
3241 let Inst{26} = V;
3242 let Inst{25-23} = 0b011;
3243 let Inst{22} = L;
3244 let Inst{21-15} = offset;
3245 let Inst{14-10} = Rt2;
3246 let Inst{9-5} = Rn;
3247 let Inst{4-0} = Rt;
3248
3249 let DecoderMethod = "DecodePairLdStInstruction";
3250}
3251
3252let hasSideEffects = 0 in {
3253let mayStore = 0, mayLoad = 1 in
3254class LoadPairPreIdx<bits<2> opc, bit V, RegisterClass regtype,
3255 Operand indextype, string asm>
3256 : BaseLoadStorePairPreIdx<opc, V, 1,
3257 (outs GPR64sp:$wback, regtype:$Rt, regtype:$Rt2),
3258 (ins GPR64sp:$Rn, indextype:$offset), asm>,
3259 Sched<[WriteLD, WriteLDHi, WriteAdr]>;
3260
3261let mayStore = 1, mayLoad = 0 in
3262class StorePairPreIdx<bits<2> opc, bit V, RegisterClass regtype,
3263 Operand indextype, string asm>
3264 : BaseLoadStorePairPreIdx<opc, V, 0, (outs GPR64sp:$wback),
3265 (ins regtype:$Rt, regtype:$Rt2,
3266 GPR64sp:$Rn, indextype:$offset),
3267 asm>,
3268 Sched<[WriteAdr, WriteSTP]>;
3269} // hasSideEffects = 0
3270
3271// (post-indexed)
3272
3273class BaseLoadStorePairPostIdx<bits<2> opc, bit V, bit L, dag oops, dag iops,
3274 string asm>
Quentin Colombetc64c1752014-08-11 21:39:53 +00003275 : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn], $offset", "$Rn = $wback,@earlyclobber $wback", []> {
Tim Northover3b0846e2014-05-24 12:50:23 +00003276 bits<5> Rt;
3277 bits<5> Rt2;
3278 bits<5> Rn;
3279 bits<7> offset;
3280 let Inst{31-30} = opc;
3281 let Inst{29-27} = 0b101;
3282 let Inst{26} = V;
3283 let Inst{25-23} = 0b001;
3284 let Inst{22} = L;
3285 let Inst{21-15} = offset;
3286 let Inst{14-10} = Rt2;
3287 let Inst{9-5} = Rn;
3288 let Inst{4-0} = Rt;
3289
3290 let DecoderMethod = "DecodePairLdStInstruction";
3291}
3292
3293let hasSideEffects = 0 in {
3294let mayStore = 0, mayLoad = 1 in
3295class LoadPairPostIdx<bits<2> opc, bit V, RegisterClass regtype,
3296 Operand idxtype, string asm>
3297 : BaseLoadStorePairPostIdx<opc, V, 1,
3298 (outs GPR64sp:$wback, regtype:$Rt, regtype:$Rt2),
3299 (ins GPR64sp:$Rn, idxtype:$offset), asm>,
3300 Sched<[WriteLD, WriteLDHi, WriteAdr]>;
3301
3302let mayStore = 1, mayLoad = 0 in
3303class StorePairPostIdx<bits<2> opc, bit V, RegisterClass regtype,
3304 Operand idxtype, string asm>
Chad Rosier7cd472b2015-09-24 19:21:42 +00003305 : BaseLoadStorePairPostIdx<opc, V, 0, (outs GPR64sp:$wback),
3306 (ins regtype:$Rt, regtype:$Rt2,
Tim Northover3b0846e2014-05-24 12:50:23 +00003307 GPR64sp:$Rn, idxtype:$offset),
3308 asm>,
3309 Sched<[WriteAdr, WriteSTP]>;
3310} // hasSideEffects = 0
3311
3312// (no-allocate)
3313
3314class BaseLoadStorePairNoAlloc<bits<2> opc, bit V, bit L, dag oops, dag iops,
3315 string asm>
3316 : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn, $offset]", "", []> {
3317 bits<5> Rt;
3318 bits<5> Rt2;
3319 bits<5> Rn;
3320 bits<7> offset;
3321 let Inst{31-30} = opc;
3322 let Inst{29-27} = 0b101;
3323 let Inst{26} = V;
3324 let Inst{25-23} = 0b000;
3325 let Inst{22} = L;
3326 let Inst{21-15} = offset;
3327 let Inst{14-10} = Rt2;
3328 let Inst{9-5} = Rn;
3329 let Inst{4-0} = Rt;
3330
3331 let DecoderMethod = "DecodePairLdStInstruction";
3332}
3333
3334multiclass LoadPairNoAlloc<bits<2> opc, bit V, RegisterClass regtype,
3335 Operand indextype, string asm> {
3336 let hasSideEffects = 0, mayStore = 0, mayLoad = 1 in
3337 def i : BaseLoadStorePairNoAlloc<opc, V, 1,
3338 (outs regtype:$Rt, regtype:$Rt2),
3339 (ins GPR64sp:$Rn, indextype:$offset), asm>,
3340 Sched<[WriteLD, WriteLDHi]>;
3341
3342
3343 def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]",
3344 (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2,
3345 GPR64sp:$Rn, 0)>;
3346}
3347
3348multiclass StorePairNoAlloc<bits<2> opc, bit V, RegisterClass regtype,
3349 Operand indextype, string asm> {
3350 let hasSideEffects = 0, mayStore = 1, mayLoad = 0 in
3351 def i : BaseLoadStorePairNoAlloc<opc, V, 0, (outs),
3352 (ins regtype:$Rt, regtype:$Rt2,
3353 GPR64sp:$Rn, indextype:$offset),
3354 asm>,
3355 Sched<[WriteSTP]>;
3356
3357 def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]",
3358 (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2,
3359 GPR64sp:$Rn, 0)>;
3360}
3361
3362//---
3363// Load/store exclusive
3364//---
3365
3366// True exclusive operations write to and/or read from the system's exclusive
3367// monitors, which as far as a compiler is concerned can be modelled as a
3368// random shared memory address. Hence LoadExclusive mayStore.
3369//
3370// Since these instructions have the undefined register bits set to 1 in
3371// their canonical form, we need a post encoder method to set those bits
3372// to 1 when encoding these instructions. We do this using the
3373// fixLoadStoreExclusive function. This function has template parameters:
3374//
3375// fixLoadStoreExclusive<int hasRs, int hasRt2>
3376//
3377// hasRs indicates that the instruction uses the Rs field, so we won't set
3378// it to 1 (and the same for Rt2). We don't need template parameters for
3379// the other register fields since Rt and Rn are always used.
3380//
3381let hasSideEffects = 1, mayLoad = 1, mayStore = 1 in
3382class BaseLoadStoreExclusive<bits<2> sz, bit o2, bit L, bit o1, bit o0,
3383 dag oops, dag iops, string asm, string operands>
3384 : I<oops, iops, asm, operands, "", []> {
3385 let Inst{31-30} = sz;
3386 let Inst{29-24} = 0b001000;
3387 let Inst{23} = o2;
3388 let Inst{22} = L;
3389 let Inst{21} = o1;
3390 let Inst{15} = o0;
3391
3392 let DecoderMethod = "DecodeExclusiveLdStInstruction";
3393}
3394
3395// Neither Rs nor Rt2 operands.
3396class LoadStoreExclusiveSimple<bits<2> sz, bit o2, bit L, bit o1, bit o0,
3397 dag oops, dag iops, string asm, string operands>
3398 : BaseLoadStoreExclusive<sz, o2, L, o1, o0, oops, iops, asm, operands> {
3399 bits<5> Rt;
3400 bits<5> Rn;
Vladimir Sukharevd49cb8f2015-04-16 15:30:43 +00003401 let Inst{20-16} = 0b11111;
3402 let Unpredictable{20-16} = 0b11111;
3403 let Inst{14-10} = 0b11111;
3404 let Unpredictable{14-10} = 0b11111;
Tim Northover3b0846e2014-05-24 12:50:23 +00003405 let Inst{9-5} = Rn;
3406 let Inst{4-0} = Rt;
3407
3408 let PostEncoderMethod = "fixLoadStoreExclusive<0,0>";
3409}
3410
3411// Simple load acquires don't set the exclusive monitor
3412let mayLoad = 1, mayStore = 0 in
3413class LoadAcquire<bits<2> sz, bit o2, bit L, bit o1, bit o0,
3414 RegisterClass regtype, string asm>
3415 : LoadStoreExclusiveSimple<sz, o2, L, o1, o0, (outs regtype:$Rt),
3416 (ins GPR64sp0:$Rn), asm, "\t$Rt, [$Rn]">,
3417 Sched<[WriteLD]>;
3418
3419class LoadExclusive<bits<2> sz, bit o2, bit L, bit o1, bit o0,
3420 RegisterClass regtype, string asm>
3421 : LoadStoreExclusiveSimple<sz, o2, L, o1, o0, (outs regtype:$Rt),
3422 (ins GPR64sp0:$Rn), asm, "\t$Rt, [$Rn]">,
3423 Sched<[WriteLD]>;
3424
3425class LoadExclusivePair<bits<2> sz, bit o2, bit L, bit o1, bit o0,
3426 RegisterClass regtype, string asm>
3427 : BaseLoadStoreExclusive<sz, o2, L, o1, o0,
3428 (outs regtype:$Rt, regtype:$Rt2),
3429 (ins GPR64sp0:$Rn), asm,
3430 "\t$Rt, $Rt2, [$Rn]">,
3431 Sched<[WriteLD, WriteLDHi]> {
3432 bits<5> Rt;
3433 bits<5> Rt2;
3434 bits<5> Rn;
3435 let Inst{14-10} = Rt2;
3436 let Inst{9-5} = Rn;
3437 let Inst{4-0} = Rt;
3438
3439 let PostEncoderMethod = "fixLoadStoreExclusive<0,1>";
3440}
3441
3442// Simple store release operations do not check the exclusive monitor.
3443let mayLoad = 0, mayStore = 1 in
3444class StoreRelease<bits<2> sz, bit o2, bit L, bit o1, bit o0,
3445 RegisterClass regtype, string asm>
3446 : LoadStoreExclusiveSimple<sz, o2, L, o1, o0, (outs),
3447 (ins regtype:$Rt, GPR64sp0:$Rn),
3448 asm, "\t$Rt, [$Rn]">,
3449 Sched<[WriteST]>;
3450
3451let mayLoad = 1, mayStore = 1 in
3452class StoreExclusive<bits<2> sz, bit o2, bit L, bit o1, bit o0,
3453 RegisterClass regtype, string asm>
3454 : BaseLoadStoreExclusive<sz, o2, L, o1, o0, (outs GPR32:$Ws),
3455 (ins regtype:$Rt, GPR64sp0:$Rn),
3456 asm, "\t$Ws, $Rt, [$Rn]">,
3457 Sched<[WriteSTX]> {
3458 bits<5> Ws;
3459 bits<5> Rt;
3460 bits<5> Rn;
3461 let Inst{20-16} = Ws;
3462 let Inst{9-5} = Rn;
3463 let Inst{4-0} = Rt;
3464
3465 let Constraints = "@earlyclobber $Ws";
3466 let PostEncoderMethod = "fixLoadStoreExclusive<1,0>";
3467}
3468
3469class StoreExclusivePair<bits<2> sz, bit o2, bit L, bit o1, bit o0,
3470 RegisterClass regtype, string asm>
3471 : BaseLoadStoreExclusive<sz, o2, L, o1, o0,
3472 (outs GPR32:$Ws),
3473 (ins regtype:$Rt, regtype:$Rt2, GPR64sp0:$Rn),
3474 asm, "\t$Ws, $Rt, $Rt2, [$Rn]">,
3475 Sched<[WriteSTX]> {
3476 bits<5> Ws;
3477 bits<5> Rt;
3478 bits<5> Rt2;
3479 bits<5> Rn;
3480 let Inst{20-16} = Ws;
3481 let Inst{14-10} = Rt2;
3482 let Inst{9-5} = Rn;
3483 let Inst{4-0} = Rt;
3484
3485 let Constraints = "@earlyclobber $Ws";
3486}
3487
3488//---
3489// Exception generation
3490//---
3491
3492let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in
3493class ExceptionGeneration<bits<3> op1, bits<2> ll, string asm>
3494 : I<(outs), (ins imm0_65535:$imm), asm, "\t$imm", "", []>,
3495 Sched<[WriteSys]> {
3496 bits<16> imm;
3497 let Inst{31-24} = 0b11010100;
3498 let Inst{23-21} = op1;
3499 let Inst{20-5} = imm;
3500 let Inst{4-2} = 0b000;
3501 let Inst{1-0} = ll;
3502}
3503
3504let Predicates = [HasFPARMv8] in {
3505
3506//---
3507// Floating point to integer conversion
3508//---
3509
3510class BaseFPToIntegerUnscaled<bits<2> type, bits<2> rmode, bits<3> opcode,
3511 RegisterClass srcType, RegisterClass dstType,
3512 string asm, list<dag> pattern>
3513 : I<(outs dstType:$Rd), (ins srcType:$Rn),
3514 asm, "\t$Rd, $Rn", "", pattern>,
3515 Sched<[WriteFCvt]> {
3516 bits<5> Rd;
3517 bits<5> Rn;
3518 let Inst{30-29} = 0b00;
3519 let Inst{28-24} = 0b11110;
3520 let Inst{23-22} = type;
3521 let Inst{21} = 1;
3522 let Inst{20-19} = rmode;
3523 let Inst{18-16} = opcode;
3524 let Inst{15-10} = 0;
3525 let Inst{9-5} = Rn;
3526 let Inst{4-0} = Rd;
3527}
3528
3529let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
3530class BaseFPToInteger<bits<2> type, bits<2> rmode, bits<3> opcode,
3531 RegisterClass srcType, RegisterClass dstType,
3532 Operand immType, string asm, list<dag> pattern>
3533 : I<(outs dstType:$Rd), (ins srcType:$Rn, immType:$scale),
3534 asm, "\t$Rd, $Rn, $scale", "", pattern>,
3535 Sched<[WriteFCvt]> {
3536 bits<5> Rd;
3537 bits<5> Rn;
3538 bits<6> scale;
3539 let Inst{30-29} = 0b00;
3540 let Inst{28-24} = 0b11110;
3541 let Inst{23-22} = type;
3542 let Inst{21} = 0;
3543 let Inst{20-19} = rmode;
3544 let Inst{18-16} = opcode;
3545 let Inst{15-10} = scale;
3546 let Inst{9-5} = Rn;
3547 let Inst{4-0} = Rd;
3548}
3549
3550multiclass FPToIntegerUnscaled<bits<2> rmode, bits<3> opcode, string asm,
3551 SDPatternOperator OpN> {
Oliver Stannardb25914e2015-11-27 13:04:48 +00003552 // Unscaled half-precision to 32-bit
3553 def UWHr : BaseFPToIntegerUnscaled<0b11, rmode, opcode, FPR16, GPR32, asm,
3554 [(set GPR32:$Rd, (OpN FPR16:$Rn))]> {
3555 let Inst{31} = 0; // 32-bit GPR flag
3556 let Predicates = [HasFullFP16];
3557 }
3558
3559 // Unscaled half-precision to 64-bit
3560 def UXHr : BaseFPToIntegerUnscaled<0b11, rmode, opcode, FPR16, GPR64, asm,
3561 [(set GPR64:$Rd, (OpN FPR16:$Rn))]> {
3562 let Inst{31} = 1; // 64-bit GPR flag
3563 let Predicates = [HasFullFP16];
3564 }
3565
Tim Northover3b0846e2014-05-24 12:50:23 +00003566 // Unscaled single-precision to 32-bit
3567 def UWSr : BaseFPToIntegerUnscaled<0b00, rmode, opcode, FPR32, GPR32, asm,
3568 [(set GPR32:$Rd, (OpN FPR32:$Rn))]> {
3569 let Inst{31} = 0; // 32-bit GPR flag
3570 }
3571
3572 // Unscaled single-precision to 64-bit
3573 def UXSr : BaseFPToIntegerUnscaled<0b00, rmode, opcode, FPR32, GPR64, asm,
3574 [(set GPR64:$Rd, (OpN FPR32:$Rn))]> {
3575 let Inst{31} = 1; // 64-bit GPR flag
3576 }
3577
3578 // Unscaled double-precision to 32-bit
3579 def UWDr : BaseFPToIntegerUnscaled<0b01, rmode, opcode, FPR64, GPR32, asm,
3580 [(set GPR32:$Rd, (OpN (f64 FPR64:$Rn)))]> {
3581 let Inst{31} = 0; // 32-bit GPR flag
3582 }
3583
3584 // Unscaled double-precision to 64-bit
3585 def UXDr : BaseFPToIntegerUnscaled<0b01, rmode, opcode, FPR64, GPR64, asm,
3586 [(set GPR64:$Rd, (OpN (f64 FPR64:$Rn)))]> {
3587 let Inst{31} = 1; // 64-bit GPR flag
3588 }
3589}
3590
3591multiclass FPToIntegerScaled<bits<2> rmode, bits<3> opcode, string asm,
3592 SDPatternOperator OpN> {
Oliver Stannardb25914e2015-11-27 13:04:48 +00003593 // Scaled half-precision to 32-bit
3594 def SWHri : BaseFPToInteger<0b11, rmode, opcode, FPR16, GPR32,
3595 fixedpoint_f16_i32, asm,
3596 [(set GPR32:$Rd, (OpN (fmul FPR16:$Rn,
3597 fixedpoint_f16_i32:$scale)))]> {
3598 let Inst{31} = 0; // 32-bit GPR flag
3599 let scale{5} = 1;
3600 let Predicates = [HasFullFP16];
3601 }
3602
3603 // Scaled half-precision to 64-bit
3604 def SXHri : BaseFPToInteger<0b11, rmode, opcode, FPR16, GPR64,
3605 fixedpoint_f16_i64, asm,
3606 [(set GPR64:$Rd, (OpN (fmul FPR16:$Rn,
3607 fixedpoint_f16_i64:$scale)))]> {
3608 let Inst{31} = 1; // 64-bit GPR flag
3609 let Predicates = [HasFullFP16];
3610 }
3611
Tim Northover3b0846e2014-05-24 12:50:23 +00003612 // Scaled single-precision to 32-bit
3613 def SWSri : BaseFPToInteger<0b00, rmode, opcode, FPR32, GPR32,
3614 fixedpoint_f32_i32, asm,
3615 [(set GPR32:$Rd, (OpN (fmul FPR32:$Rn,
3616 fixedpoint_f32_i32:$scale)))]> {
3617 let Inst{31} = 0; // 32-bit GPR flag
3618 let scale{5} = 1;
3619 }
3620
3621 // Scaled single-precision to 64-bit
3622 def SXSri : BaseFPToInteger<0b00, rmode, opcode, FPR32, GPR64,
3623 fixedpoint_f32_i64, asm,
3624 [(set GPR64:$Rd, (OpN (fmul FPR32:$Rn,
3625 fixedpoint_f32_i64:$scale)))]> {
3626 let Inst{31} = 1; // 64-bit GPR flag
3627 }
3628
3629 // Scaled double-precision to 32-bit
3630 def SWDri : BaseFPToInteger<0b01, rmode, opcode, FPR64, GPR32,
3631 fixedpoint_f64_i32, asm,
3632 [(set GPR32:$Rd, (OpN (fmul FPR64:$Rn,
3633 fixedpoint_f64_i32:$scale)))]> {
3634 let Inst{31} = 0; // 32-bit GPR flag
3635 let scale{5} = 1;
3636 }
3637
3638 // Scaled double-precision to 64-bit
3639 def SXDri : BaseFPToInteger<0b01, rmode, opcode, FPR64, GPR64,
3640 fixedpoint_f64_i64, asm,
3641 [(set GPR64:$Rd, (OpN (fmul FPR64:$Rn,
3642 fixedpoint_f64_i64:$scale)))]> {
3643 let Inst{31} = 1; // 64-bit GPR flag
3644 }
3645}
3646
3647//---
3648// Integer to floating point conversion
3649//---
3650
3651let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
3652class BaseIntegerToFP<bit isUnsigned,
3653 RegisterClass srcType, RegisterClass dstType,
3654 Operand immType, string asm, list<dag> pattern>
3655 : I<(outs dstType:$Rd), (ins srcType:$Rn, immType:$scale),
3656 asm, "\t$Rd, $Rn, $scale", "", pattern>,
3657 Sched<[WriteFCvt]> {
3658 bits<5> Rd;
3659 bits<5> Rn;
3660 bits<6> scale;
Oliver Stannardb25914e2015-11-27 13:04:48 +00003661 let Inst{30-24} = 0b0011110;
Tim Northover3b0846e2014-05-24 12:50:23 +00003662 let Inst{21-17} = 0b00001;
3663 let Inst{16} = isUnsigned;
3664 let Inst{15-10} = scale;
3665 let Inst{9-5} = Rn;
3666 let Inst{4-0} = Rd;
3667}
3668
3669class BaseIntegerToFPUnscaled<bit isUnsigned,
3670 RegisterClass srcType, RegisterClass dstType,
3671 ValueType dvt, string asm, SDNode node>
3672 : I<(outs dstType:$Rd), (ins srcType:$Rn),
3673 asm, "\t$Rd, $Rn", "", [(set (dvt dstType:$Rd), (node srcType:$Rn))]>,
3674 Sched<[WriteFCvt]> {
3675 bits<5> Rd;
3676 bits<5> Rn;
3677 bits<6> scale;
Oliver Stannardb25914e2015-11-27 13:04:48 +00003678 let Inst{30-24} = 0b0011110;
Tim Northover3b0846e2014-05-24 12:50:23 +00003679 let Inst{21-17} = 0b10001;
3680 let Inst{16} = isUnsigned;
3681 let Inst{15-10} = 0b000000;
3682 let Inst{9-5} = Rn;
3683 let Inst{4-0} = Rd;
3684}
3685
3686multiclass IntegerToFP<bit isUnsigned, string asm, SDNode node> {
3687 // Unscaled
Oliver Stannardb25914e2015-11-27 13:04:48 +00003688 def UWHri: BaseIntegerToFPUnscaled<isUnsigned, GPR32, FPR16, f16, asm, node> {
3689 let Inst{31} = 0; // 32-bit GPR flag
3690 let Inst{23-22} = 0b11; // 16-bit FPR flag
3691 let Predicates = [HasFullFP16];
3692 }
3693
Tim Northover3b0846e2014-05-24 12:50:23 +00003694 def UWSri: BaseIntegerToFPUnscaled<isUnsigned, GPR32, FPR32, f32, asm, node> {
3695 let Inst{31} = 0; // 32-bit GPR flag
Oliver Stannardb25914e2015-11-27 13:04:48 +00003696 let Inst{23-22} = 0b00; // 32-bit FPR flag
Tim Northover3b0846e2014-05-24 12:50:23 +00003697 }
3698
3699 def UWDri: BaseIntegerToFPUnscaled<isUnsigned, GPR32, FPR64, f64, asm, node> {
3700 let Inst{31} = 0; // 32-bit GPR flag
Oliver Stannardb25914e2015-11-27 13:04:48 +00003701 let Inst{23-22} = 0b01; // 64-bit FPR flag
3702 }
3703
3704 def UXHri: BaseIntegerToFPUnscaled<isUnsigned, GPR64, FPR16, f16, asm, node> {
3705 let Inst{31} = 1; // 64-bit GPR flag
3706 let Inst{23-22} = 0b11; // 16-bit FPR flag
3707 let Predicates = [HasFullFP16];
Tim Northover3b0846e2014-05-24 12:50:23 +00003708 }
3709
3710 def UXSri: BaseIntegerToFPUnscaled<isUnsigned, GPR64, FPR32, f32, asm, node> {
3711 let Inst{31} = 1; // 64-bit GPR flag
Oliver Stannardb25914e2015-11-27 13:04:48 +00003712 let Inst{23-22} = 0b00; // 32-bit FPR flag
Tim Northover3b0846e2014-05-24 12:50:23 +00003713 }
3714
3715 def UXDri: BaseIntegerToFPUnscaled<isUnsigned, GPR64, FPR64, f64, asm, node> {
3716 let Inst{31} = 1; // 64-bit GPR flag
Oliver Stannardb25914e2015-11-27 13:04:48 +00003717 let Inst{23-22} = 0b01; // 64-bit FPR flag
Tim Northover3b0846e2014-05-24 12:50:23 +00003718 }
3719
3720 // Scaled
Oliver Stannardb25914e2015-11-27 13:04:48 +00003721 def SWHri: BaseIntegerToFP<isUnsigned, GPR32, FPR16, fixedpoint_f16_i32, asm,
3722 [(set FPR16:$Rd,
3723 (fdiv (node GPR32:$Rn),
3724 fixedpoint_f16_i32:$scale))]> {
3725 let Inst{31} = 0; // 32-bit GPR flag
3726 let Inst{23-22} = 0b11; // 16-bit FPR flag
3727 let scale{5} = 1;
3728 let Predicates = [HasFullFP16];
3729 }
3730
Tim Northover3b0846e2014-05-24 12:50:23 +00003731 def SWSri: BaseIntegerToFP<isUnsigned, GPR32, FPR32, fixedpoint_f32_i32, asm,
3732 [(set FPR32:$Rd,
3733 (fdiv (node GPR32:$Rn),
3734 fixedpoint_f32_i32:$scale))]> {
3735 let Inst{31} = 0; // 32-bit GPR flag
Oliver Stannardb25914e2015-11-27 13:04:48 +00003736 let Inst{23-22} = 0b00; // 32-bit FPR flag
Tim Northover3b0846e2014-05-24 12:50:23 +00003737 let scale{5} = 1;
3738 }
3739
3740 def SWDri: BaseIntegerToFP<isUnsigned, GPR32, FPR64, fixedpoint_f64_i32, asm,
3741 [(set FPR64:$Rd,
3742 (fdiv (node GPR32:$Rn),
3743 fixedpoint_f64_i32:$scale))]> {
3744 let Inst{31} = 0; // 32-bit GPR flag
Oliver Stannardb25914e2015-11-27 13:04:48 +00003745 let Inst{23-22} = 0b01; // 64-bit FPR flag
Tim Northover3b0846e2014-05-24 12:50:23 +00003746 let scale{5} = 1;
3747 }
3748
Oliver Stannardb25914e2015-11-27 13:04:48 +00003749 def SXHri: BaseIntegerToFP<isUnsigned, GPR64, FPR16, fixedpoint_f16_i64, asm,
3750 [(set FPR16:$Rd,
3751 (fdiv (node GPR64:$Rn),
3752 fixedpoint_f16_i64:$scale))]> {
3753 let Inst{31} = 1; // 64-bit GPR flag
3754 let Inst{23-22} = 0b11; // 16-bit FPR flag
3755 let Predicates = [HasFullFP16];
3756 }
3757
Tim Northover3b0846e2014-05-24 12:50:23 +00003758 def SXSri: BaseIntegerToFP<isUnsigned, GPR64, FPR32, fixedpoint_f32_i64, asm,
3759 [(set FPR32:$Rd,
3760 (fdiv (node GPR64:$Rn),
3761 fixedpoint_f32_i64:$scale))]> {
3762 let Inst{31} = 1; // 64-bit GPR flag
Oliver Stannardb25914e2015-11-27 13:04:48 +00003763 let Inst{23-22} = 0b00; // 32-bit FPR flag
Tim Northover3b0846e2014-05-24 12:50:23 +00003764 }
3765
3766 def SXDri: BaseIntegerToFP<isUnsigned, GPR64, FPR64, fixedpoint_f64_i64, asm,
3767 [(set FPR64:$Rd,
3768 (fdiv (node GPR64:$Rn),
3769 fixedpoint_f64_i64:$scale))]> {
3770 let Inst{31} = 1; // 64-bit GPR flag
Oliver Stannardb25914e2015-11-27 13:04:48 +00003771 let Inst{23-22} = 0b01; // 64-bit FPR flag
Tim Northover3b0846e2014-05-24 12:50:23 +00003772 }
3773}
3774
3775//---
3776// Unscaled integer <-> floating point conversion (i.e. FMOV)
3777//---
3778
3779let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
3780class BaseUnscaledConversion<bits<2> rmode, bits<3> opcode,
3781 RegisterClass srcType, RegisterClass dstType,
3782 string asm>
3783 : I<(outs dstType:$Rd), (ins srcType:$Rn), asm, "\t$Rd, $Rn", "",
3784 // We use COPY_TO_REGCLASS for these bitconvert operations.
3785 // copyPhysReg() expands the resultant COPY instructions after
3786 // regalloc is done. This gives greater freedom for the allocator
3787 // and related passes (coalescing, copy propagation, et. al.) to
3788 // be more effective.
3789 [/*(set (dvt dstType:$Rd), (bitconvert (svt srcType:$Rn)))*/]>,
3790 Sched<[WriteFCopy]> {
3791 bits<5> Rd;
3792 bits<5> Rn;
Oliver Stannardb25914e2015-11-27 13:04:48 +00003793 let Inst{30-24} = 0b0011110;
Tim Northover3b0846e2014-05-24 12:50:23 +00003794 let Inst{21} = 1;
3795 let Inst{20-19} = rmode;
3796 let Inst{18-16} = opcode;
3797 let Inst{15-10} = 0b000000;
3798 let Inst{9-5} = Rn;
3799 let Inst{4-0} = Rd;
3800}
3801
3802let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
3803class BaseUnscaledConversionToHigh<bits<2> rmode, bits<3> opcode,
3804 RegisterClass srcType, RegisterOperand dstType, string asm,
3805 string kind>
3806 : I<(outs dstType:$Rd), (ins srcType:$Rn, VectorIndex1:$idx), asm,
3807 "{\t$Rd"#kind#"$idx, $Rn|"#kind#"\t$Rd$idx, $Rn}", "", []>,
3808 Sched<[WriteFCopy]> {
3809 bits<5> Rd;
3810 bits<5> Rn;
3811 let Inst{30-23} = 0b00111101;
3812 let Inst{21} = 1;
3813 let Inst{20-19} = rmode;
3814 let Inst{18-16} = opcode;
3815 let Inst{15-10} = 0b000000;
3816 let Inst{9-5} = Rn;
3817 let Inst{4-0} = Rd;
3818
3819 let DecoderMethod = "DecodeFMOVLaneInstruction";
3820}
3821
3822let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
3823class BaseUnscaledConversionFromHigh<bits<2> rmode, bits<3> opcode,
3824 RegisterOperand srcType, RegisterClass dstType, string asm,
3825 string kind>
3826 : I<(outs dstType:$Rd), (ins srcType:$Rn, VectorIndex1:$idx), asm,
3827 "{\t$Rd, $Rn"#kind#"$idx|"#kind#"\t$Rd, $Rn$idx}", "", []>,
3828 Sched<[WriteFCopy]> {
3829 bits<5> Rd;
3830 bits<5> Rn;
3831 let Inst{30-23} = 0b00111101;
3832 let Inst{21} = 1;
3833 let Inst{20-19} = rmode;
3834 let Inst{18-16} = opcode;
3835 let Inst{15-10} = 0b000000;
3836 let Inst{9-5} = Rn;
3837 let Inst{4-0} = Rd;
3838
3839 let DecoderMethod = "DecodeFMOVLaneInstruction";
3840}
3841
3842
Tim Northover3b0846e2014-05-24 12:50:23 +00003843multiclass UnscaledConversion<string asm> {
Oliver Stannardb25914e2015-11-27 13:04:48 +00003844 def WHr : BaseUnscaledConversion<0b00, 0b111, GPR32, FPR16, asm> {
3845 let Inst{31} = 0; // 32-bit GPR flag
3846 let Inst{23-22} = 0b11; // 16-bit FPR flag
3847 let Predicates = [HasFullFP16];
3848 }
3849
3850 def XHr : BaseUnscaledConversion<0b00, 0b111, GPR64, FPR16, asm> {
3851 let Inst{31} = 1; // 64-bit GPR flag
3852 let Inst{23-22} = 0b11; // 16-bit FPR flag
3853 let Predicates = [HasFullFP16];
3854 }
3855
Tim Northover3b0846e2014-05-24 12:50:23 +00003856 def WSr : BaseUnscaledConversion<0b00, 0b111, GPR32, FPR32, asm> {
3857 let Inst{31} = 0; // 32-bit GPR flag
Oliver Stannardb25914e2015-11-27 13:04:48 +00003858 let Inst{23-22} = 0b00; // 32-bit FPR flag
Tim Northover3b0846e2014-05-24 12:50:23 +00003859 }
3860
3861 def XDr : BaseUnscaledConversion<0b00, 0b111, GPR64, FPR64, asm> {
3862 let Inst{31} = 1; // 64-bit GPR flag
Oliver Stannardb25914e2015-11-27 13:04:48 +00003863 let Inst{23-22} = 0b01; // 64-bit FPR flag
3864 }
3865
3866 def HWr : BaseUnscaledConversion<0b00, 0b110, FPR16, GPR32, asm> {
3867 let Inst{31} = 0; // 32-bit GPR flag
3868 let Inst{23-22} = 0b11; // 16-bit FPR flag
3869 let Predicates = [HasFullFP16];
3870 }
3871
3872 def HXr : BaseUnscaledConversion<0b00, 0b110, FPR16, GPR64, asm> {
3873 let Inst{31} = 1; // 64-bit GPR flag
3874 let Inst{23-22} = 0b11; // 16-bit FPR flag
3875 let Predicates = [HasFullFP16];
Tim Northover3b0846e2014-05-24 12:50:23 +00003876 }
3877
3878 def SWr : BaseUnscaledConversion<0b00, 0b110, FPR32, GPR32, asm> {
3879 let Inst{31} = 0; // 32-bit GPR flag
Oliver Stannardb25914e2015-11-27 13:04:48 +00003880 let Inst{23-22} = 0b00; // 32-bit FPR flag
Tim Northover3b0846e2014-05-24 12:50:23 +00003881 }
3882
3883 def DXr : BaseUnscaledConversion<0b00, 0b110, FPR64, GPR64, asm> {
3884 let Inst{31} = 1; // 64-bit GPR flag
Oliver Stannardb25914e2015-11-27 13:04:48 +00003885 let Inst{23-22} = 0b01; // 64-bit FPR flag
Tim Northover3b0846e2014-05-24 12:50:23 +00003886 }
3887
3888 def XDHighr : BaseUnscaledConversionToHigh<0b01, 0b111, GPR64, V128,
3889 asm, ".d"> {
3890 let Inst{31} = 1;
3891 let Inst{22} = 0;
3892 }
3893
3894 def DXHighr : BaseUnscaledConversionFromHigh<0b01, 0b110, V128, GPR64,
3895 asm, ".d"> {
3896 let Inst{31} = 1;
3897 let Inst{22} = 0;
3898 }
3899}
3900
3901//---
3902// Floating point conversion
3903//---
3904
3905class BaseFPConversion<bits<2> type, bits<2> opcode, RegisterClass dstType,
3906 RegisterClass srcType, string asm, list<dag> pattern>
3907 : I<(outs dstType:$Rd), (ins srcType:$Rn), asm, "\t$Rd, $Rn", "", pattern>,
3908 Sched<[WriteFCvt]> {
3909 bits<5> Rd;
3910 bits<5> Rn;
3911 let Inst{31-24} = 0b00011110;
3912 let Inst{23-22} = type;
3913 let Inst{21-17} = 0b10001;
3914 let Inst{16-15} = opcode;
3915 let Inst{14-10} = 0b10000;
3916 let Inst{9-5} = Rn;
3917 let Inst{4-0} = Rd;
3918}
3919
3920multiclass FPConversion<string asm> {
3921 // Double-precision to Half-precision
3922 def HDr : BaseFPConversion<0b01, 0b11, FPR16, FPR64, asm,
3923 [(set FPR16:$Rd, (fround FPR64:$Rn))]>;
3924
3925 // Double-precision to Single-precision
3926 def SDr : BaseFPConversion<0b01, 0b00, FPR32, FPR64, asm,
3927 [(set FPR32:$Rd, (fround FPR64:$Rn))]>;
3928
3929 // Half-precision to Double-precision
3930 def DHr : BaseFPConversion<0b11, 0b01, FPR64, FPR16, asm,
3931 [(set FPR64:$Rd, (fextend FPR16:$Rn))]>;
3932
3933 // Half-precision to Single-precision
3934 def SHr : BaseFPConversion<0b11, 0b00, FPR32, FPR16, asm,
3935 [(set FPR32:$Rd, (fextend FPR16:$Rn))]>;
3936
3937 // Single-precision to Double-precision
3938 def DSr : BaseFPConversion<0b00, 0b01, FPR64, FPR32, asm,
3939 [(set FPR64:$Rd, (fextend FPR32:$Rn))]>;
3940
3941 // Single-precision to Half-precision
3942 def HSr : BaseFPConversion<0b00, 0b11, FPR16, FPR32, asm,
3943 [(set FPR16:$Rd, (fround FPR32:$Rn))]>;
3944}
3945
3946//---
3947// Single operand floating point data processing
3948//---
3949
3950let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
3951class BaseSingleOperandFPData<bits<4> opcode, RegisterClass regtype,
3952 ValueType vt, string asm, SDPatternOperator node>
3953 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm, "\t$Rd, $Rn", "",
3954 [(set (vt regtype:$Rd), (node (vt regtype:$Rn)))]>,
3955 Sched<[WriteF]> {
3956 bits<5> Rd;
3957 bits<5> Rn;
Oliver Stannardb25914e2015-11-27 13:04:48 +00003958 let Inst{31-24} = 0b00011110;
Tim Northover3b0846e2014-05-24 12:50:23 +00003959 let Inst{21-19} = 0b100;
3960 let Inst{18-15} = opcode;
3961 let Inst{14-10} = 0b10000;
3962 let Inst{9-5} = Rn;
3963 let Inst{4-0} = Rd;
3964}
3965
3966multiclass SingleOperandFPData<bits<4> opcode, string asm,
3967 SDPatternOperator node = null_frag> {
Oliver Stannardb25914e2015-11-27 13:04:48 +00003968 def Hr : BaseSingleOperandFPData<opcode, FPR16, f16, asm, node> {
3969 let Inst{23-22} = 0b11; // 16-bit size flag
3970 let Predicates = [HasFullFP16];
3971 }
3972
Tim Northover3b0846e2014-05-24 12:50:23 +00003973 def Sr : BaseSingleOperandFPData<opcode, FPR32, f32, asm, node> {
Oliver Stannardb25914e2015-11-27 13:04:48 +00003974 let Inst{23-22} = 0b00; // 32-bit size flag
Tim Northover3b0846e2014-05-24 12:50:23 +00003975 }
3976
3977 def Dr : BaseSingleOperandFPData<opcode, FPR64, f64, asm, node> {
Oliver Stannardb25914e2015-11-27 13:04:48 +00003978 let Inst{23-22} = 0b01; // 64-bit size flag
Tim Northover3b0846e2014-05-24 12:50:23 +00003979 }
3980}
3981
3982//---
3983// Two operand floating point data processing
3984//---
3985
3986let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
3987class BaseTwoOperandFPData<bits<4> opcode, RegisterClass regtype,
3988 string asm, list<dag> pat>
3989 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm),
3990 asm, "\t$Rd, $Rn, $Rm", "", pat>,
3991 Sched<[WriteF]> {
3992 bits<5> Rd;
3993 bits<5> Rn;
3994 bits<5> Rm;
Oliver Stannardb25914e2015-11-27 13:04:48 +00003995 let Inst{31-24} = 0b00011110;
Tim Northover3b0846e2014-05-24 12:50:23 +00003996 let Inst{21} = 1;
3997 let Inst{20-16} = Rm;
3998 let Inst{15-12} = opcode;
3999 let Inst{11-10} = 0b10;
4000 let Inst{9-5} = Rn;
4001 let Inst{4-0} = Rd;
4002}
4003
4004multiclass TwoOperandFPData<bits<4> opcode, string asm,
4005 SDPatternOperator node = null_frag> {
Oliver Stannardb25914e2015-11-27 13:04:48 +00004006 def Hrr : BaseTwoOperandFPData<opcode, FPR16, asm,
4007 [(set (f16 FPR16:$Rd),
4008 (node (f16 FPR16:$Rn), (f16 FPR16:$Rm)))]> {
4009 let Inst{23-22} = 0b11; // 16-bit size flag
4010 let Predicates = [HasFullFP16];
4011 }
4012
Tim Northover3b0846e2014-05-24 12:50:23 +00004013 def Srr : BaseTwoOperandFPData<opcode, FPR32, asm,
4014 [(set (f32 FPR32:$Rd),
4015 (node (f32 FPR32:$Rn), (f32 FPR32:$Rm)))]> {
Oliver Stannardb25914e2015-11-27 13:04:48 +00004016 let Inst{23-22} = 0b00; // 32-bit size flag
Tim Northover3b0846e2014-05-24 12:50:23 +00004017 }
4018
4019 def Drr : BaseTwoOperandFPData<opcode, FPR64, asm,
4020 [(set (f64 FPR64:$Rd),
4021 (node (f64 FPR64:$Rn), (f64 FPR64:$Rm)))]> {
Oliver Stannardb25914e2015-11-27 13:04:48 +00004022 let Inst{23-22} = 0b01; // 64-bit size flag
Tim Northover3b0846e2014-05-24 12:50:23 +00004023 }
4024}
4025
4026multiclass TwoOperandFPDataNeg<bits<4> opcode, string asm, SDNode node> {
Oliver Stannardb25914e2015-11-27 13:04:48 +00004027 def Hrr : BaseTwoOperandFPData<opcode, FPR16, asm,
4028 [(set FPR16:$Rd, (fneg (node FPR16:$Rn, (f16 FPR16:$Rm))))]> {
4029 let Inst{23-22} = 0b11; // 16-bit size flag
4030 let Predicates = [HasFullFP16];
4031 }
4032
Tim Northover3b0846e2014-05-24 12:50:23 +00004033 def Srr : BaseTwoOperandFPData<opcode, FPR32, asm,
4034 [(set FPR32:$Rd, (fneg (node FPR32:$Rn, (f32 FPR32:$Rm))))]> {
Oliver Stannardb25914e2015-11-27 13:04:48 +00004035 let Inst{23-22} = 0b00; // 32-bit size flag
Tim Northover3b0846e2014-05-24 12:50:23 +00004036 }
4037
4038 def Drr : BaseTwoOperandFPData<opcode, FPR64, asm,
4039 [(set FPR64:$Rd, (fneg (node FPR64:$Rn, (f64 FPR64:$Rm))))]> {
Oliver Stannardb25914e2015-11-27 13:04:48 +00004040 let Inst{23-22} = 0b01; // 64-bit size flag
Tim Northover3b0846e2014-05-24 12:50:23 +00004041 }
4042}
4043
4044
4045//---
4046// Three operand floating point data processing
4047//---
4048
4049class BaseThreeOperandFPData<bit isNegated, bit isSub,
4050 RegisterClass regtype, string asm, list<dag> pat>
4051 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, regtype: $Ra),
4052 asm, "\t$Rd, $Rn, $Rm, $Ra", "", pat>,
4053 Sched<[WriteFMul]> {
4054 bits<5> Rd;
4055 bits<5> Rn;
4056 bits<5> Rm;
4057 bits<5> Ra;
Oliver Stannardb25914e2015-11-27 13:04:48 +00004058 let Inst{31-24} = 0b00011111;
Tim Northover3b0846e2014-05-24 12:50:23 +00004059 let Inst{21} = isNegated;
4060 let Inst{20-16} = Rm;
4061 let Inst{15} = isSub;
4062 let Inst{14-10} = Ra;
4063 let Inst{9-5} = Rn;
4064 let Inst{4-0} = Rd;
4065}
4066
4067multiclass ThreeOperandFPData<bit isNegated, bit isSub,string asm,
4068 SDPatternOperator node> {
Oliver Stannardb25914e2015-11-27 13:04:48 +00004069 def Hrrr : BaseThreeOperandFPData<isNegated, isSub, FPR16, asm,
4070 [(set FPR16:$Rd,
4071 (node (f16 FPR16:$Rn), (f16 FPR16:$Rm), (f16 FPR16:$Ra)))]> {
4072 let Inst{23-22} = 0b11; // 16-bit size flag
4073 let Predicates = [HasFullFP16];
4074 }
4075
Tim Northover3b0846e2014-05-24 12:50:23 +00004076 def Srrr : BaseThreeOperandFPData<isNegated, isSub, FPR32, asm,
4077 [(set FPR32:$Rd,
4078 (node (f32 FPR32:$Rn), (f32 FPR32:$Rm), (f32 FPR32:$Ra)))]> {
Oliver Stannardb25914e2015-11-27 13:04:48 +00004079 let Inst{23-22} = 0b00; // 32-bit size flag
Tim Northover3b0846e2014-05-24 12:50:23 +00004080 }
4081
4082 def Drrr : BaseThreeOperandFPData<isNegated, isSub, FPR64, asm,
4083 [(set FPR64:$Rd,
4084 (node (f64 FPR64:$Rn), (f64 FPR64:$Rm), (f64 FPR64:$Ra)))]> {
Oliver Stannardb25914e2015-11-27 13:04:48 +00004085 let Inst{23-22} = 0b01; // 64-bit size flag
Tim Northover3b0846e2014-05-24 12:50:23 +00004086 }
4087}
4088
4089//---
4090// Floating point data comparisons
4091//---
4092
4093let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
4094class BaseOneOperandFPComparison<bit signalAllNans,
4095 RegisterClass regtype, string asm,
4096 list<dag> pat>
4097 : I<(outs), (ins regtype:$Rn), asm, "\t$Rn, #0.0", "", pat>,
4098 Sched<[WriteFCmp]> {
4099 bits<5> Rn;
Oliver Stannardb25914e2015-11-27 13:04:48 +00004100 let Inst{31-24} = 0b00011110;
Tim Northover3b0846e2014-05-24 12:50:23 +00004101 let Inst{21} = 1;
4102
4103 let Inst{15-10} = 0b001000;
4104 let Inst{9-5} = Rn;
4105 let Inst{4} = signalAllNans;
4106 let Inst{3-0} = 0b1000;
4107
4108 // Rm should be 0b00000 canonically, but we need to accept any value.
4109 let PostEncoderMethod = "fixOneOperandFPComparison";
4110}
4111
4112let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
4113class BaseTwoOperandFPComparison<bit signalAllNans, RegisterClass regtype,
4114 string asm, list<dag> pat>
4115 : I<(outs), (ins regtype:$Rn, regtype:$Rm), asm, "\t$Rn, $Rm", "", pat>,
4116 Sched<[WriteFCmp]> {
4117 bits<5> Rm;
4118 bits<5> Rn;
Oliver Stannardb25914e2015-11-27 13:04:48 +00004119 let Inst{31-24} = 0b00011110;
Tim Northover3b0846e2014-05-24 12:50:23 +00004120 let Inst{21} = 1;
4121 let Inst{20-16} = Rm;
4122 let Inst{15-10} = 0b001000;
4123 let Inst{9-5} = Rn;
4124 let Inst{4} = signalAllNans;
4125 let Inst{3-0} = 0b0000;
4126}
4127
4128multiclass FPComparison<bit signalAllNans, string asm,
4129 SDPatternOperator OpNode = null_frag> {
4130 let Defs = [NZCV] in {
Oliver Stannardb25914e2015-11-27 13:04:48 +00004131 def Hrr : BaseTwoOperandFPComparison<signalAllNans, FPR16, asm,
4132 [(OpNode FPR16:$Rn, (f16 FPR16:$Rm)), (implicit NZCV)]> {
4133 let Inst{23-22} = 0b11;
4134 let Predicates = [HasFullFP16];
4135 }
4136
4137 def Hri : BaseOneOperandFPComparison<signalAllNans, FPR16, asm,
4138 [(OpNode (f16 FPR16:$Rn), fpimm0), (implicit NZCV)]> {
4139 let Inst{23-22} = 0b11;
4140 let Predicates = [HasFullFP16];
4141 }
4142
Tim Northover3b0846e2014-05-24 12:50:23 +00004143 def Srr : BaseTwoOperandFPComparison<signalAllNans, FPR32, asm,
4144 [(OpNode FPR32:$Rn, (f32 FPR32:$Rm)), (implicit NZCV)]> {
Oliver Stannardb25914e2015-11-27 13:04:48 +00004145 let Inst{23-22} = 0b00;
Tim Northover3b0846e2014-05-24 12:50:23 +00004146 }
4147
4148 def Sri : BaseOneOperandFPComparison<signalAllNans, FPR32, asm,
4149 [(OpNode (f32 FPR32:$Rn), fpimm0), (implicit NZCV)]> {
Oliver Stannardb25914e2015-11-27 13:04:48 +00004150 let Inst{23-22} = 0b00;
Tim Northover3b0846e2014-05-24 12:50:23 +00004151 }
4152
4153 def Drr : BaseTwoOperandFPComparison<signalAllNans, FPR64, asm,
4154 [(OpNode FPR64:$Rn, (f64 FPR64:$Rm)), (implicit NZCV)]> {
Oliver Stannardb25914e2015-11-27 13:04:48 +00004155 let Inst{23-22} = 0b01;
Tim Northover3b0846e2014-05-24 12:50:23 +00004156 }
4157
4158 def Dri : BaseOneOperandFPComparison<signalAllNans, FPR64, asm,
4159 [(OpNode (f64 FPR64:$Rn), fpimm0), (implicit NZCV)]> {
Oliver Stannardb25914e2015-11-27 13:04:48 +00004160 let Inst{23-22} = 0b01;
Tim Northover3b0846e2014-05-24 12:50:23 +00004161 }
4162 } // Defs = [NZCV]
4163}
4164
4165//---
4166// Floating point conditional comparisons
4167//---
4168
4169let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
Matthias Braunaf7d7702015-07-16 20:02:37 +00004170class BaseFPCondComparison<bit signalAllNans, RegisterClass regtype,
4171 string mnemonic, list<dag> pat>
4172 : I<(outs), (ins regtype:$Rn, regtype:$Rm, imm32_0_15:$nzcv, ccode:$cond),
4173 mnemonic, "\t$Rn, $Rm, $nzcv, $cond", "", pat>,
Tim Northover3b0846e2014-05-24 12:50:23 +00004174 Sched<[WriteFCmp]> {
Matthias Braunaf7d7702015-07-16 20:02:37 +00004175 let Uses = [NZCV];
4176 let Defs = [NZCV];
4177
Tim Northover3b0846e2014-05-24 12:50:23 +00004178 bits<5> Rn;
4179 bits<5> Rm;
4180 bits<4> nzcv;
4181 bits<4> cond;
4182
Oliver Stannardb25914e2015-11-27 13:04:48 +00004183 let Inst{31-24} = 0b00011110;
Tim Northover3b0846e2014-05-24 12:50:23 +00004184 let Inst{21} = 1;
4185 let Inst{20-16} = Rm;
4186 let Inst{15-12} = cond;
4187 let Inst{11-10} = 0b01;
4188 let Inst{9-5} = Rn;
4189 let Inst{4} = signalAllNans;
4190 let Inst{3-0} = nzcv;
4191}
4192
Matthias Braunaf7d7702015-07-16 20:02:37 +00004193multiclass FPCondComparison<bit signalAllNans, string mnemonic,
4194 SDPatternOperator OpNode = null_frag> {
Oliver Stannardb25914e2015-11-27 13:04:48 +00004195 def Hrr : BaseFPCondComparison<signalAllNans, FPR16, mnemonic, []> {
4196 let Inst{23-22} = 0b11;
4197 let Predicates = [HasFullFP16];
4198 }
4199
Matthias Braunaf7d7702015-07-16 20:02:37 +00004200 def Srr : BaseFPCondComparison<signalAllNans, FPR32, mnemonic,
4201 [(set NZCV, (OpNode (f32 FPR32:$Rn), (f32 FPR32:$Rm), (i32 imm:$nzcv),
4202 (i32 imm:$cond), NZCV))]> {
Oliver Stannardb25914e2015-11-27 13:04:48 +00004203 let Inst{23-22} = 0b00;
Tim Northover3b0846e2014-05-24 12:50:23 +00004204 }
Oliver Stannardb25914e2015-11-27 13:04:48 +00004205
Matthias Braunaf7d7702015-07-16 20:02:37 +00004206 def Drr : BaseFPCondComparison<signalAllNans, FPR64, mnemonic,
4207 [(set NZCV, (OpNode (f64 FPR64:$Rn), (f64 FPR64:$Rm), (i32 imm:$nzcv),
4208 (i32 imm:$cond), NZCV))]> {
Oliver Stannardb25914e2015-11-27 13:04:48 +00004209 let Inst{23-22} = 0b01;
Tim Northover3b0846e2014-05-24 12:50:23 +00004210 }
Tim Northover3b0846e2014-05-24 12:50:23 +00004211}
4212
4213//---
4214// Floating point conditional select
4215//---
4216
4217class BaseFPCondSelect<RegisterClass regtype, ValueType vt, string asm>
4218 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, ccode:$cond),
4219 asm, "\t$Rd, $Rn, $Rm, $cond", "",
4220 [(set regtype:$Rd,
4221 (AArch64csel (vt regtype:$Rn), regtype:$Rm,
4222 (i32 imm:$cond), NZCV))]>,
4223 Sched<[WriteF]> {
4224 bits<5> Rd;
4225 bits<5> Rn;
4226 bits<5> Rm;
4227 bits<4> cond;
4228
Oliver Stannardb25914e2015-11-27 13:04:48 +00004229 let Inst{31-24} = 0b00011110;
Tim Northover3b0846e2014-05-24 12:50:23 +00004230 let Inst{21} = 1;
4231 let Inst{20-16} = Rm;
4232 let Inst{15-12} = cond;
4233 let Inst{11-10} = 0b11;
4234 let Inst{9-5} = Rn;
4235 let Inst{4-0} = Rd;
4236}
4237
4238multiclass FPCondSelect<string asm> {
4239 let Uses = [NZCV] in {
Oliver Stannardb25914e2015-11-27 13:04:48 +00004240 def Hrrr : BaseFPCondSelect<FPR16, f16, asm> {
4241 let Inst{23-22} = 0b11;
4242 let Predicates = [HasFullFP16];
4243 }
4244
Tim Northover3b0846e2014-05-24 12:50:23 +00004245 def Srrr : BaseFPCondSelect<FPR32, f32, asm> {
Oliver Stannardb25914e2015-11-27 13:04:48 +00004246 let Inst{23-22} = 0b00;
Tim Northover3b0846e2014-05-24 12:50:23 +00004247 }
4248
4249 def Drrr : BaseFPCondSelect<FPR64, f64, asm> {
Oliver Stannardb25914e2015-11-27 13:04:48 +00004250 let Inst{23-22} = 0b01;
Tim Northover3b0846e2014-05-24 12:50:23 +00004251 }
4252 } // Uses = [NZCV]
4253}
4254
4255//---
4256// Floating move immediate
4257//---
4258
4259class BaseFPMoveImmediate<RegisterClass regtype, Operand fpimmtype, string asm>
4260 : I<(outs regtype:$Rd), (ins fpimmtype:$imm), asm, "\t$Rd, $imm", "",
4261 [(set regtype:$Rd, fpimmtype:$imm)]>,
4262 Sched<[WriteFImm]> {
4263 bits<5> Rd;
4264 bits<8> imm;
Oliver Stannardb25914e2015-11-27 13:04:48 +00004265 let Inst{31-24} = 0b00011110;
Tim Northover3b0846e2014-05-24 12:50:23 +00004266 let Inst{21} = 1;
4267 let Inst{20-13} = imm;
4268 let Inst{12-5} = 0b10000000;
4269 let Inst{4-0} = Rd;
4270}
4271
4272multiclass FPMoveImmediate<string asm> {
Oliver Stannardb25914e2015-11-27 13:04:48 +00004273 def Hi : BaseFPMoveImmediate<FPR16, fpimm16, asm> {
4274 let Inst{23-22} = 0b11;
4275 let Predicates = [HasFullFP16];
4276 }
4277
Tim Northover3b0846e2014-05-24 12:50:23 +00004278 def Si : BaseFPMoveImmediate<FPR32, fpimm32, asm> {
Oliver Stannardb25914e2015-11-27 13:04:48 +00004279 let Inst{23-22} = 0b00;
Tim Northover3b0846e2014-05-24 12:50:23 +00004280 }
4281
4282 def Di : BaseFPMoveImmediate<FPR64, fpimm64, asm> {
Oliver Stannardb25914e2015-11-27 13:04:48 +00004283 let Inst{23-22} = 0b01;
Tim Northover3b0846e2014-05-24 12:50:23 +00004284 }
4285}
4286} // end of 'let Predicates = [HasFPARMv8]'
4287
4288//----------------------------------------------------------------------------
4289// AdvSIMD
4290//----------------------------------------------------------------------------
4291
4292let Predicates = [HasNEON] in {
4293
4294//----------------------------------------------------------------------------
4295// AdvSIMD three register vector instructions
4296//----------------------------------------------------------------------------
4297
4298let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
4299class BaseSIMDThreeSameVector<bit Q, bit U, bits<2> size, bits<5> opcode,
4300 RegisterOperand regtype, string asm, string kind,
4301 list<dag> pattern>
4302 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), asm,
4303 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind #
4304 "|" # kind # "\t$Rd, $Rn, $Rm|}", "", pattern>,
4305 Sched<[WriteV]> {
4306 bits<5> Rd;
4307 bits<5> Rn;
4308 bits<5> Rm;
4309 let Inst{31} = 0;
4310 let Inst{30} = Q;
4311 let Inst{29} = U;
4312 let Inst{28-24} = 0b01110;
4313 let Inst{23-22} = size;
4314 let Inst{21} = 1;
4315 let Inst{20-16} = Rm;
4316 let Inst{15-11} = opcode;
4317 let Inst{10} = 1;
4318 let Inst{9-5} = Rn;
4319 let Inst{4-0} = Rd;
4320}
4321
4322let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
4323class BaseSIMDThreeSameVectorTied<bit Q, bit U, bits<2> size, bits<5> opcode,
4324 RegisterOperand regtype, string asm, string kind,
4325 list<dag> pattern>
4326 : I<(outs regtype:$dst), (ins regtype:$Rd, regtype:$Rn, regtype:$Rm), asm,
4327 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind #
4328 "|" # kind # "\t$Rd, $Rn, $Rm}", "$Rd = $dst", pattern>,
4329 Sched<[WriteV]> {
4330 bits<5> Rd;
4331 bits<5> Rn;
4332 bits<5> Rm;
4333 let Inst{31} = 0;
4334 let Inst{30} = Q;
4335 let Inst{29} = U;
4336 let Inst{28-24} = 0b01110;
4337 let Inst{23-22} = size;
4338 let Inst{21} = 1;
4339 let Inst{20-16} = Rm;
4340 let Inst{15-11} = opcode;
4341 let Inst{10} = 1;
4342 let Inst{9-5} = Rn;
4343 let Inst{4-0} = Rd;
4344}
4345
4346// All operand sizes distinguished in the encoding.
4347multiclass SIMDThreeSameVector<bit U, bits<5> opc, string asm,
4348 SDPatternOperator OpNode> {
4349 def v8i8 : BaseSIMDThreeSameVector<0, U, 0b00, opc, V64,
4350 asm, ".8b",
4351 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
4352 def v16i8 : BaseSIMDThreeSameVector<1, U, 0b00, opc, V128,
4353 asm, ".16b",
4354 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn), (v16i8 V128:$Rm)))]>;
4355 def v4i16 : BaseSIMDThreeSameVector<0, U, 0b01, opc, V64,
4356 asm, ".4h",
4357 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>;
4358 def v8i16 : BaseSIMDThreeSameVector<1, U, 0b01, opc, V128,
4359 asm, ".8h",
4360 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>;
4361 def v2i32 : BaseSIMDThreeSameVector<0, U, 0b10, opc, V64,
4362 asm, ".2s",
4363 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>;
4364 def v4i32 : BaseSIMDThreeSameVector<1, U, 0b10, opc, V128,
4365 asm, ".4s",
4366 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>;
4367 def v2i64 : BaseSIMDThreeSameVector<1, U, 0b11, opc, V128,
4368 asm, ".2d",
4369 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn), (v2i64 V128:$Rm)))]>;
4370}
4371
4372// As above, but D sized elements unsupported.
4373multiclass SIMDThreeSameVectorBHS<bit U, bits<5> opc, string asm,
4374 SDPatternOperator OpNode> {
4375 def v8i8 : BaseSIMDThreeSameVector<0, U, 0b00, opc, V64,
4376 asm, ".8b",
4377 [(set V64:$Rd, (v8i8 (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm))))]>;
4378 def v16i8 : BaseSIMDThreeSameVector<1, U, 0b00, opc, V128,
4379 asm, ".16b",
4380 [(set V128:$Rd, (v16i8 (OpNode (v16i8 V128:$Rn), (v16i8 V128:$Rm))))]>;
4381 def v4i16 : BaseSIMDThreeSameVector<0, U, 0b01, opc, V64,
4382 asm, ".4h",
4383 [(set V64:$Rd, (v4i16 (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm))))]>;
4384 def v8i16 : BaseSIMDThreeSameVector<1, U, 0b01, opc, V128,
4385 asm, ".8h",
4386 [(set V128:$Rd, (v8i16 (OpNode (v8i16 V128:$Rn), (v8i16 V128:$Rm))))]>;
4387 def v2i32 : BaseSIMDThreeSameVector<0, U, 0b10, opc, V64,
4388 asm, ".2s",
4389 [(set V64:$Rd, (v2i32 (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm))))]>;
4390 def v4i32 : BaseSIMDThreeSameVector<1, U, 0b10, opc, V128,
4391 asm, ".4s",
4392 [(set V128:$Rd, (v4i32 (OpNode (v4i32 V128:$Rn), (v4i32 V128:$Rm))))]>;
4393}
4394
4395multiclass SIMDThreeSameVectorBHSTied<bit U, bits<5> opc, string asm,
4396 SDPatternOperator OpNode> {
4397 def v8i8 : BaseSIMDThreeSameVectorTied<0, U, 0b00, opc, V64,
4398 asm, ".8b",
4399 [(set (v8i8 V64:$dst),
4400 (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
4401 def v16i8 : BaseSIMDThreeSameVectorTied<1, U, 0b00, opc, V128,
4402 asm, ".16b",
4403 [(set (v16i8 V128:$dst),
4404 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn), (v16i8 V128:$Rm)))]>;
4405 def v4i16 : BaseSIMDThreeSameVectorTied<0, U, 0b01, opc, V64,
4406 asm, ".4h",
4407 [(set (v4i16 V64:$dst),
4408 (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>;
4409 def v8i16 : BaseSIMDThreeSameVectorTied<1, U, 0b01, opc, V128,
4410 asm, ".8h",
4411 [(set (v8i16 V128:$dst),
4412 (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>;
4413 def v2i32 : BaseSIMDThreeSameVectorTied<0, U, 0b10, opc, V64,
4414 asm, ".2s",
4415 [(set (v2i32 V64:$dst),
4416 (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>;
4417 def v4i32 : BaseSIMDThreeSameVectorTied<1, U, 0b10, opc, V128,
4418 asm, ".4s",
4419 [(set (v4i32 V128:$dst),
4420 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>;
4421}
4422
4423// As above, but only B sized elements supported.
4424multiclass SIMDThreeSameVectorB<bit U, bits<5> opc, string asm,
4425 SDPatternOperator OpNode> {
4426 def v8i8 : BaseSIMDThreeSameVector<0, U, 0b00, opc, V64,
4427 asm, ".8b",
4428 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
4429 def v16i8 : BaseSIMDThreeSameVector<1, U, 0b00, opc, V128,
4430 asm, ".16b",
4431 [(set (v16i8 V128:$Rd),
4432 (OpNode (v16i8 V128:$Rn), (v16i8 V128:$Rm)))]>;
4433}
4434
4435// As above, but only S and D sized floating point elements supported.
4436multiclass SIMDThreeSameVectorFP<bit U, bit S, bits<5> opc,
4437 string asm, SDPatternOperator OpNode> {
4438 def v2f32 : BaseSIMDThreeSameVector<0, U, {S,0}, opc, V64,
4439 asm, ".2s",
4440 [(set (v2f32 V64:$Rd), (OpNode (v2f32 V64:$Rn), (v2f32 V64:$Rm)))]>;
4441 def v4f32 : BaseSIMDThreeSameVector<1, U, {S,0}, opc, V128,
4442 asm, ".4s",
4443 [(set (v4f32 V128:$Rd), (OpNode (v4f32 V128:$Rn), (v4f32 V128:$Rm)))]>;
4444 def v2f64 : BaseSIMDThreeSameVector<1, U, {S,1}, opc, V128,
4445 asm, ".2d",
4446 [(set (v2f64 V128:$Rd), (OpNode (v2f64 V128:$Rn), (v2f64 V128:$Rm)))]>;
4447}
4448
4449multiclass SIMDThreeSameVectorFPCmp<bit U, bit S, bits<5> opc,
4450 string asm,
4451 SDPatternOperator OpNode> {
4452 def v2f32 : BaseSIMDThreeSameVector<0, U, {S,0}, opc, V64,
4453 asm, ".2s",
4454 [(set (v2i32 V64:$Rd), (OpNode (v2f32 V64:$Rn), (v2f32 V64:$Rm)))]>;
4455 def v4f32 : BaseSIMDThreeSameVector<1, U, {S,0}, opc, V128,
4456 asm, ".4s",
4457 [(set (v4i32 V128:$Rd), (OpNode (v4f32 V128:$Rn), (v4f32 V128:$Rm)))]>;
4458 def v2f64 : BaseSIMDThreeSameVector<1, U, {S,1}, opc, V128,
4459 asm, ".2d",
4460 [(set (v2i64 V128:$Rd), (OpNode (v2f64 V128:$Rn), (v2f64 V128:$Rm)))]>;
4461}
4462
4463multiclass SIMDThreeSameVectorFPTied<bit U, bit S, bits<5> opc,
4464 string asm, SDPatternOperator OpNode> {
4465 def v2f32 : BaseSIMDThreeSameVectorTied<0, U, {S,0}, opc, V64,
4466 asm, ".2s",
4467 [(set (v2f32 V64:$dst),
4468 (OpNode (v2f32 V64:$Rd), (v2f32 V64:$Rn), (v2f32 V64:$Rm)))]>;
4469 def v4f32 : BaseSIMDThreeSameVectorTied<1, U, {S,0}, opc, V128,
4470 asm, ".4s",
4471 [(set (v4f32 V128:$dst),
4472 (OpNode (v4f32 V128:$Rd), (v4f32 V128:$Rn), (v4f32 V128:$Rm)))]>;
4473 def v2f64 : BaseSIMDThreeSameVectorTied<1, U, {S,1}, opc, V128,
4474 asm, ".2d",
4475 [(set (v2f64 V128:$dst),
4476 (OpNode (v2f64 V128:$Rd), (v2f64 V128:$Rn), (v2f64 V128:$Rm)))]>;
4477}
4478
4479// As above, but D and B sized elements unsupported.
4480multiclass SIMDThreeSameVectorHS<bit U, bits<5> opc, string asm,
4481 SDPatternOperator OpNode> {
4482 def v4i16 : BaseSIMDThreeSameVector<0, U, 0b01, opc, V64,
4483 asm, ".4h",
4484 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>;
4485 def v8i16 : BaseSIMDThreeSameVector<1, U, 0b01, opc, V128,
4486 asm, ".8h",
4487 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>;
4488 def v2i32 : BaseSIMDThreeSameVector<0, U, 0b10, opc, V64,
4489 asm, ".2s",
4490 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>;
4491 def v4i32 : BaseSIMDThreeSameVector<1, U, 0b10, opc, V128,
4492 asm, ".4s",
4493 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>;
4494}
4495
4496// Logical three vector ops share opcode bits, and only use B sized elements.
4497multiclass SIMDLogicalThreeVector<bit U, bits<2> size, string asm,
4498 SDPatternOperator OpNode = null_frag> {
4499 def v8i8 : BaseSIMDThreeSameVector<0, U, size, 0b00011, V64,
4500 asm, ".8b",
4501 [(set (v8i8 V64:$Rd), (OpNode V64:$Rn, V64:$Rm))]>;
4502 def v16i8 : BaseSIMDThreeSameVector<1, U, size, 0b00011, V128,
4503 asm, ".16b",
4504 [(set (v16i8 V128:$Rd), (OpNode V128:$Rn, V128:$Rm))]>;
4505
4506 def : Pat<(v4i16 (OpNode V64:$LHS, V64:$RHS)),
4507 (!cast<Instruction>(NAME#"v8i8") V64:$LHS, V64:$RHS)>;
4508 def : Pat<(v2i32 (OpNode V64:$LHS, V64:$RHS)),
4509 (!cast<Instruction>(NAME#"v8i8") V64:$LHS, V64:$RHS)>;
4510 def : Pat<(v1i64 (OpNode V64:$LHS, V64:$RHS)),
4511 (!cast<Instruction>(NAME#"v8i8") V64:$LHS, V64:$RHS)>;
4512
4513 def : Pat<(v8i16 (OpNode V128:$LHS, V128:$RHS)),
4514 (!cast<Instruction>(NAME#"v16i8") V128:$LHS, V128:$RHS)>;
4515 def : Pat<(v4i32 (OpNode V128:$LHS, V128:$RHS)),
4516 (!cast<Instruction>(NAME#"v16i8") V128:$LHS, V128:$RHS)>;
4517 def : Pat<(v2i64 (OpNode V128:$LHS, V128:$RHS)),
4518 (!cast<Instruction>(NAME#"v16i8") V128:$LHS, V128:$RHS)>;
4519}
4520
4521multiclass SIMDLogicalThreeVectorTied<bit U, bits<2> size,
4522 string asm, SDPatternOperator OpNode> {
4523 def v8i8 : BaseSIMDThreeSameVectorTied<0, U, size, 0b00011, V64,
4524 asm, ".8b",
4525 [(set (v8i8 V64:$dst),
4526 (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
4527 def v16i8 : BaseSIMDThreeSameVectorTied<1, U, size, 0b00011, V128,
4528 asm, ".16b",
4529 [(set (v16i8 V128:$dst),
4530 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn),
4531 (v16i8 V128:$Rm)))]>;
4532
4533 def : Pat<(v4i16 (OpNode (v4i16 V64:$LHS), (v4i16 V64:$MHS),
4534 (v4i16 V64:$RHS))),
4535 (!cast<Instruction>(NAME#"v8i8")
4536 V64:$LHS, V64:$MHS, V64:$RHS)>;
4537 def : Pat<(v2i32 (OpNode (v2i32 V64:$LHS), (v2i32 V64:$MHS),
4538 (v2i32 V64:$RHS))),
4539 (!cast<Instruction>(NAME#"v8i8")
4540 V64:$LHS, V64:$MHS, V64:$RHS)>;
4541 def : Pat<(v1i64 (OpNode (v1i64 V64:$LHS), (v1i64 V64:$MHS),
4542 (v1i64 V64:$RHS))),
4543 (!cast<Instruction>(NAME#"v8i8")
4544 V64:$LHS, V64:$MHS, V64:$RHS)>;
4545
4546 def : Pat<(v8i16 (OpNode (v8i16 V128:$LHS), (v8i16 V128:$MHS),
4547 (v8i16 V128:$RHS))),
4548 (!cast<Instruction>(NAME#"v16i8")
4549 V128:$LHS, V128:$MHS, V128:$RHS)>;
4550 def : Pat<(v4i32 (OpNode (v4i32 V128:$LHS), (v4i32 V128:$MHS),
4551 (v4i32 V128:$RHS))),
4552 (!cast<Instruction>(NAME#"v16i8")
4553 V128:$LHS, V128:$MHS, V128:$RHS)>;
4554 def : Pat<(v2i64 (OpNode (v2i64 V128:$LHS), (v2i64 V128:$MHS),
4555 (v2i64 V128:$RHS))),
4556 (!cast<Instruction>(NAME#"v16i8")
4557 V128:$LHS, V128:$MHS, V128:$RHS)>;
4558}
4559
4560
4561//----------------------------------------------------------------------------
4562// AdvSIMD two register vector instructions.
4563//----------------------------------------------------------------------------
4564
4565let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
4566class BaseSIMDTwoSameVector<bit Q, bit U, bits<2> size, bits<5> opcode,
4567 RegisterOperand regtype, string asm, string dstkind,
4568 string srckind, list<dag> pattern>
4569 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm,
4570 "{\t$Rd" # dstkind # ", $Rn" # srckind #
4571 "|" # dstkind # "\t$Rd, $Rn}", "", pattern>,
4572 Sched<[WriteV]> {
4573 bits<5> Rd;
4574 bits<5> Rn;
4575 let Inst{31} = 0;
4576 let Inst{30} = Q;
4577 let Inst{29} = U;
4578 let Inst{28-24} = 0b01110;
4579 let Inst{23-22} = size;
4580 let Inst{21-17} = 0b10000;
4581 let Inst{16-12} = opcode;
4582 let Inst{11-10} = 0b10;
4583 let Inst{9-5} = Rn;
4584 let Inst{4-0} = Rd;
4585}
4586
4587let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
4588class BaseSIMDTwoSameVectorTied<bit Q, bit U, bits<2> size, bits<5> opcode,
4589 RegisterOperand regtype, string asm, string dstkind,
4590 string srckind, list<dag> pattern>
4591 : I<(outs regtype:$dst), (ins regtype:$Rd, regtype:$Rn), asm,
4592 "{\t$Rd" # dstkind # ", $Rn" # srckind #
4593 "|" # dstkind # "\t$Rd, $Rn}", "$Rd = $dst", pattern>,
4594 Sched<[WriteV]> {
4595 bits<5> Rd;
4596 bits<5> Rn;
4597 let Inst{31} = 0;
4598 let Inst{30} = Q;
4599 let Inst{29} = U;
4600 let Inst{28-24} = 0b01110;
4601 let Inst{23-22} = size;
4602 let Inst{21-17} = 0b10000;
4603 let Inst{16-12} = opcode;
4604 let Inst{11-10} = 0b10;
4605 let Inst{9-5} = Rn;
4606 let Inst{4-0} = Rd;
4607}
4608
4609// Supports B, H, and S element sizes.
4610multiclass SIMDTwoVectorBHS<bit U, bits<5> opc, string asm,
4611 SDPatternOperator OpNode> {
4612 def v8i8 : BaseSIMDTwoSameVector<0, U, 0b00, opc, V64,
4613 asm, ".8b", ".8b",
4614 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>;
4615 def v16i8 : BaseSIMDTwoSameVector<1, U, 0b00, opc, V128,
4616 asm, ".16b", ".16b",
4617 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>;
4618 def v4i16 : BaseSIMDTwoSameVector<0, U, 0b01, opc, V64,
4619 asm, ".4h", ".4h",
4620 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>;
4621 def v8i16 : BaseSIMDTwoSameVector<1, U, 0b01, opc, V128,
4622 asm, ".8h", ".8h",
4623 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>;
4624 def v2i32 : BaseSIMDTwoSameVector<0, U, 0b10, opc, V64,
4625 asm, ".2s", ".2s",
4626 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>;
4627 def v4i32 : BaseSIMDTwoSameVector<1, U, 0b10, opc, V128,
4628 asm, ".4s", ".4s",
4629 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>;
4630}
4631
4632class BaseSIMDVectorLShiftLongBySize<bit Q, bits<2> size,
4633 RegisterOperand regtype, string asm, string dstkind,
4634 string srckind, string amount>
4635 : I<(outs V128:$Rd), (ins regtype:$Rn), asm,
4636 "{\t$Rd" # dstkind # ", $Rn" # srckind # ", #" # amount #
4637 "|" # dstkind # "\t$Rd, $Rn, #" # amount # "}", "", []>,
4638 Sched<[WriteV]> {
4639 bits<5> Rd;
4640 bits<5> Rn;
4641 let Inst{31} = 0;
4642 let Inst{30} = Q;
4643 let Inst{29-24} = 0b101110;
4644 let Inst{23-22} = size;
4645 let Inst{21-10} = 0b100001001110;
4646 let Inst{9-5} = Rn;
4647 let Inst{4-0} = Rd;
4648}
4649
4650multiclass SIMDVectorLShiftLongBySizeBHS {
Craig Topperc50d64b2014-11-26 00:46:26 +00004651 let hasSideEffects = 0 in {
Tim Northover3b0846e2014-05-24 12:50:23 +00004652 def v8i8 : BaseSIMDVectorLShiftLongBySize<0, 0b00, V64,
4653 "shll", ".8h", ".8b", "8">;
4654 def v16i8 : BaseSIMDVectorLShiftLongBySize<1, 0b00, V128,
4655 "shll2", ".8h", ".16b", "8">;
4656 def v4i16 : BaseSIMDVectorLShiftLongBySize<0, 0b01, V64,
4657 "shll", ".4s", ".4h", "16">;
4658 def v8i16 : BaseSIMDVectorLShiftLongBySize<1, 0b01, V128,
4659 "shll2", ".4s", ".8h", "16">;
4660 def v2i32 : BaseSIMDVectorLShiftLongBySize<0, 0b10, V64,
4661 "shll", ".2d", ".2s", "32">;
4662 def v4i32 : BaseSIMDVectorLShiftLongBySize<1, 0b10, V128,
4663 "shll2", ".2d", ".4s", "32">;
4664 }
4665}
4666
4667// Supports all element sizes.
4668multiclass SIMDLongTwoVector<bit U, bits<5> opc, string asm,
4669 SDPatternOperator OpNode> {
4670 def v8i8_v4i16 : BaseSIMDTwoSameVector<0, U, 0b00, opc, V64,
4671 asm, ".4h", ".8b",
4672 [(set (v4i16 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>;
4673 def v16i8_v8i16 : BaseSIMDTwoSameVector<1, U, 0b00, opc, V128,
4674 asm, ".8h", ".16b",
4675 [(set (v8i16 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>;
4676 def v4i16_v2i32 : BaseSIMDTwoSameVector<0, U, 0b01, opc, V64,
4677 asm, ".2s", ".4h",
4678 [(set (v2i32 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>;
4679 def v8i16_v4i32 : BaseSIMDTwoSameVector<1, U, 0b01, opc, V128,
4680 asm, ".4s", ".8h",
4681 [(set (v4i32 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>;
4682 def v2i32_v1i64 : BaseSIMDTwoSameVector<0, U, 0b10, opc, V64,
4683 asm, ".1d", ".2s",
4684 [(set (v1i64 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>;
4685 def v4i32_v2i64 : BaseSIMDTwoSameVector<1, U, 0b10, opc, V128,
4686 asm, ".2d", ".4s",
4687 [(set (v2i64 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>;
4688}
4689
4690multiclass SIMDLongTwoVectorTied<bit U, bits<5> opc, string asm,
4691 SDPatternOperator OpNode> {
4692 def v8i8_v4i16 : BaseSIMDTwoSameVectorTied<0, U, 0b00, opc, V64,
4693 asm, ".4h", ".8b",
4694 [(set (v4i16 V64:$dst), (OpNode (v4i16 V64:$Rd),
4695 (v8i8 V64:$Rn)))]>;
4696 def v16i8_v8i16 : BaseSIMDTwoSameVectorTied<1, U, 0b00, opc, V128,
4697 asm, ".8h", ".16b",
4698 [(set (v8i16 V128:$dst), (OpNode (v8i16 V128:$Rd),
4699 (v16i8 V128:$Rn)))]>;
4700 def v4i16_v2i32 : BaseSIMDTwoSameVectorTied<0, U, 0b01, opc, V64,
4701 asm, ".2s", ".4h",
4702 [(set (v2i32 V64:$dst), (OpNode (v2i32 V64:$Rd),
4703 (v4i16 V64:$Rn)))]>;
4704 def v8i16_v4i32 : BaseSIMDTwoSameVectorTied<1, U, 0b01, opc, V128,
4705 asm, ".4s", ".8h",
4706 [(set (v4i32 V128:$dst), (OpNode (v4i32 V128:$Rd),
4707 (v8i16 V128:$Rn)))]>;
4708 def v2i32_v1i64 : BaseSIMDTwoSameVectorTied<0, U, 0b10, opc, V64,
4709 asm, ".1d", ".2s",
4710 [(set (v1i64 V64:$dst), (OpNode (v1i64 V64:$Rd),
4711 (v2i32 V64:$Rn)))]>;
4712 def v4i32_v2i64 : BaseSIMDTwoSameVectorTied<1, U, 0b10, opc, V128,
4713 asm, ".2d", ".4s",
4714 [(set (v2i64 V128:$dst), (OpNode (v2i64 V128:$Rd),
4715 (v4i32 V128:$Rn)))]>;
4716}
4717
4718// Supports all element sizes, except 1xD.
4719multiclass SIMDTwoVectorBHSDTied<bit U, bits<5> opc, string asm,
4720 SDPatternOperator OpNode> {
4721 def v8i8 : BaseSIMDTwoSameVectorTied<0, U, 0b00, opc, V64,
4722 asm, ".8b", ".8b",
4723 [(set (v8i8 V64:$dst), (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn)))]>;
4724 def v16i8 : BaseSIMDTwoSameVectorTied<1, U, 0b00, opc, V128,
4725 asm, ".16b", ".16b",
4726 [(set (v16i8 V128:$dst), (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn)))]>;
4727 def v4i16 : BaseSIMDTwoSameVectorTied<0, U, 0b01, opc, V64,
4728 asm, ".4h", ".4h",
4729 [(set (v4i16 V64:$dst), (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn)))]>;
4730 def v8i16 : BaseSIMDTwoSameVectorTied<1, U, 0b01, opc, V128,
4731 asm, ".8h", ".8h",
4732 [(set (v8i16 V128:$dst), (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn)))]>;
4733 def v2i32 : BaseSIMDTwoSameVectorTied<0, U, 0b10, opc, V64,
4734 asm, ".2s", ".2s",
4735 [(set (v2i32 V64:$dst), (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn)))]>;
4736 def v4i32 : BaseSIMDTwoSameVectorTied<1, U, 0b10, opc, V128,
4737 asm, ".4s", ".4s",
4738 [(set (v4i32 V128:$dst), (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn)))]>;
4739 def v2i64 : BaseSIMDTwoSameVectorTied<1, U, 0b11, opc, V128,
4740 asm, ".2d", ".2d",
4741 [(set (v2i64 V128:$dst), (OpNode (v2i64 V128:$Rd), (v2i64 V128:$Rn)))]>;
4742}
4743
4744multiclass SIMDTwoVectorBHSD<bit U, bits<5> opc, string asm,
4745 SDPatternOperator OpNode = null_frag> {
4746 def v8i8 : BaseSIMDTwoSameVector<0, U, 0b00, opc, V64,
4747 asm, ".8b", ".8b",
4748 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>;
4749 def v16i8 : BaseSIMDTwoSameVector<1, U, 0b00, opc, V128,
4750 asm, ".16b", ".16b",
4751 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>;
4752 def v4i16 : BaseSIMDTwoSameVector<0, U, 0b01, opc, V64,
4753 asm, ".4h", ".4h",
4754 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>;
4755 def v8i16 : BaseSIMDTwoSameVector<1, U, 0b01, opc, V128,
4756 asm, ".8h", ".8h",
4757 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>;
4758 def v2i32 : BaseSIMDTwoSameVector<0, U, 0b10, opc, V64,
4759 asm, ".2s", ".2s",
4760 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>;
4761 def v4i32 : BaseSIMDTwoSameVector<1, U, 0b10, opc, V128,
4762 asm, ".4s", ".4s",
4763 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>;
4764 def v2i64 : BaseSIMDTwoSameVector<1, U, 0b11, opc, V128,
4765 asm, ".2d", ".2d",
4766 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn)))]>;
4767}
4768
4769
4770// Supports only B element sizes.
4771multiclass SIMDTwoVectorB<bit U, bits<2> size, bits<5> opc, string asm,
4772 SDPatternOperator OpNode> {
4773 def v8i8 : BaseSIMDTwoSameVector<0, U, size, opc, V64,
4774 asm, ".8b", ".8b",
4775 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>;
4776 def v16i8 : BaseSIMDTwoSameVector<1, U, size, opc, V128,
4777 asm, ".16b", ".16b",
4778 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>;
4779
4780}
4781
4782// Supports only B and H element sizes.
4783multiclass SIMDTwoVectorBH<bit U, bits<5> opc, string asm,
4784 SDPatternOperator OpNode> {
4785 def v8i8 : BaseSIMDTwoSameVector<0, U, 0b00, opc, V64,
4786 asm, ".8b", ".8b",
4787 [(set (v8i8 V64:$Rd), (OpNode V64:$Rn))]>;
4788 def v16i8 : BaseSIMDTwoSameVector<1, U, 0b00, opc, V128,
4789 asm, ".16b", ".16b",
4790 [(set (v16i8 V128:$Rd), (OpNode V128:$Rn))]>;
4791 def v4i16 : BaseSIMDTwoSameVector<0, U, 0b01, opc, V64,
4792 asm, ".4h", ".4h",
4793 [(set (v4i16 V64:$Rd), (OpNode V64:$Rn))]>;
4794 def v8i16 : BaseSIMDTwoSameVector<1, U, 0b01, opc, V128,
4795 asm, ".8h", ".8h",
4796 [(set (v8i16 V128:$Rd), (OpNode V128:$Rn))]>;
4797}
4798
4799// Supports only S and D element sizes, uses high bit of the size field
4800// as an extra opcode bit.
4801multiclass SIMDTwoVectorFP<bit U, bit S, bits<5> opc, string asm,
4802 SDPatternOperator OpNode> {
4803 def v2f32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, V64,
4804 asm, ".2s", ".2s",
4805 [(set (v2f32 V64:$Rd), (OpNode (v2f32 V64:$Rn)))]>;
4806 def v4f32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, V128,
4807 asm, ".4s", ".4s",
4808 [(set (v4f32 V128:$Rd), (OpNode (v4f32 V128:$Rn)))]>;
4809 def v2f64 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, V128,
4810 asm, ".2d", ".2d",
4811 [(set (v2f64 V128:$Rd), (OpNode (v2f64 V128:$Rn)))]>;
4812}
4813
4814// Supports only S element size.
4815multiclass SIMDTwoVectorS<bit U, bit S, bits<5> opc, string asm,
4816 SDPatternOperator OpNode> {
4817 def v2i32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, V64,
4818 asm, ".2s", ".2s",
4819 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>;
4820 def v4i32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, V128,
4821 asm, ".4s", ".4s",
4822 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>;
4823}
4824
4825
4826multiclass SIMDTwoVectorFPToInt<bit U, bit S, bits<5> opc, string asm,
4827 SDPatternOperator OpNode> {
4828 def v2f32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, V64,
4829 asm, ".2s", ".2s",
4830 [(set (v2i32 V64:$Rd), (OpNode (v2f32 V64:$Rn)))]>;
4831 def v4f32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, V128,
4832 asm, ".4s", ".4s",
4833 [(set (v4i32 V128:$Rd), (OpNode (v4f32 V128:$Rn)))]>;
4834 def v2f64 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, V128,
4835 asm, ".2d", ".2d",
4836 [(set (v2i64 V128:$Rd), (OpNode (v2f64 V128:$Rn)))]>;
4837}
4838
4839multiclass SIMDTwoVectorIntToFP<bit U, bit S, bits<5> opc, string asm,
4840 SDPatternOperator OpNode> {
4841 def v2f32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, V64,
4842 asm, ".2s", ".2s",
4843 [(set (v2f32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>;
4844 def v4f32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, V128,
4845 asm, ".4s", ".4s",
4846 [(set (v4f32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>;
4847 def v2f64 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, V128,
4848 asm, ".2d", ".2d",
4849 [(set (v2f64 V128:$Rd), (OpNode (v2i64 V128:$Rn)))]>;
4850}
4851
4852
4853class BaseSIMDMixedTwoVector<bit Q, bit U, bits<2> size, bits<5> opcode,
4854 RegisterOperand inreg, RegisterOperand outreg,
4855 string asm, string outkind, string inkind,
4856 list<dag> pattern>
4857 : I<(outs outreg:$Rd), (ins inreg:$Rn), asm,
4858 "{\t$Rd" # outkind # ", $Rn" # inkind #
4859 "|" # outkind # "\t$Rd, $Rn}", "", pattern>,
4860 Sched<[WriteV]> {
4861 bits<5> Rd;
4862 bits<5> Rn;
4863 let Inst{31} = 0;
4864 let Inst{30} = Q;
4865 let Inst{29} = U;
4866 let Inst{28-24} = 0b01110;
4867 let Inst{23-22} = size;
4868 let Inst{21-17} = 0b10000;
4869 let Inst{16-12} = opcode;
4870 let Inst{11-10} = 0b10;
4871 let Inst{9-5} = Rn;
4872 let Inst{4-0} = Rd;
4873}
4874
4875class BaseSIMDMixedTwoVectorTied<bit Q, bit U, bits<2> size, bits<5> opcode,
4876 RegisterOperand inreg, RegisterOperand outreg,
4877 string asm, string outkind, string inkind,
4878 list<dag> pattern>
4879 : I<(outs outreg:$dst), (ins outreg:$Rd, inreg:$Rn), asm,
4880 "{\t$Rd" # outkind # ", $Rn" # inkind #
4881 "|" # outkind # "\t$Rd, $Rn}", "$Rd = $dst", pattern>,
4882 Sched<[WriteV]> {
4883 bits<5> Rd;
4884 bits<5> Rn;
4885 let Inst{31} = 0;
4886 let Inst{30} = Q;
4887 let Inst{29} = U;
4888 let Inst{28-24} = 0b01110;
4889 let Inst{23-22} = size;
4890 let Inst{21-17} = 0b10000;
4891 let Inst{16-12} = opcode;
4892 let Inst{11-10} = 0b10;
4893 let Inst{9-5} = Rn;
4894 let Inst{4-0} = Rd;
4895}
4896
4897multiclass SIMDMixedTwoVector<bit U, bits<5> opc, string asm,
4898 SDPatternOperator OpNode> {
4899 def v8i8 : BaseSIMDMixedTwoVector<0, U, 0b00, opc, V128, V64,
4900 asm, ".8b", ".8h",
4901 [(set (v8i8 V64:$Rd), (OpNode (v8i16 V128:$Rn)))]>;
4902 def v16i8 : BaseSIMDMixedTwoVectorTied<1, U, 0b00, opc, V128, V128,
4903 asm#"2", ".16b", ".8h", []>;
4904 def v4i16 : BaseSIMDMixedTwoVector<0, U, 0b01, opc, V128, V64,
4905 asm, ".4h", ".4s",
4906 [(set (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn)))]>;
4907 def v8i16 : BaseSIMDMixedTwoVectorTied<1, U, 0b01, opc, V128, V128,
4908 asm#"2", ".8h", ".4s", []>;
4909 def v2i32 : BaseSIMDMixedTwoVector<0, U, 0b10, opc, V128, V64,
4910 asm, ".2s", ".2d",
4911 [(set (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn)))]>;
4912 def v4i32 : BaseSIMDMixedTwoVectorTied<1, U, 0b10, opc, V128, V128,
4913 asm#"2", ".4s", ".2d", []>;
4914
4915 def : Pat<(concat_vectors (v8i8 V64:$Rd), (OpNode (v8i16 V128:$Rn))),
4916 (!cast<Instruction>(NAME # "v16i8")
4917 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>;
4918 def : Pat<(concat_vectors (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn))),
4919 (!cast<Instruction>(NAME # "v8i16")
4920 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>;
4921 def : Pat<(concat_vectors (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn))),
4922 (!cast<Instruction>(NAME # "v4i32")
4923 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>;
4924}
4925
4926class BaseSIMDCmpTwoVector<bit Q, bit U, bits<2> size, bits<5> opcode,
4927 RegisterOperand regtype,
4928 string asm, string kind, string zero,
4929 ValueType dty, ValueType sty, SDNode OpNode>
4930 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm,
4931 "{\t$Rd" # kind # ", $Rn" # kind # ", #" # zero #
4932 "|" # kind # "\t$Rd, $Rn, #" # zero # "}", "",
4933 [(set (dty regtype:$Rd), (OpNode (sty regtype:$Rn)))]>,
4934 Sched<[WriteV]> {
4935 bits<5> Rd;
4936 bits<5> Rn;
4937 let Inst{31} = 0;
4938 let Inst{30} = Q;
4939 let Inst{29} = U;
4940 let Inst{28-24} = 0b01110;
4941 let Inst{23-22} = size;
4942 let Inst{21-17} = 0b10000;
4943 let Inst{16-12} = opcode;
4944 let Inst{11-10} = 0b10;
4945 let Inst{9-5} = Rn;
4946 let Inst{4-0} = Rd;
4947}
4948
4949// Comparisons support all element sizes, except 1xD.
4950multiclass SIMDCmpTwoVector<bit U, bits<5> opc, string asm,
4951 SDNode OpNode> {
4952 def v8i8rz : BaseSIMDCmpTwoVector<0, U, 0b00, opc, V64,
4953 asm, ".8b", "0",
4954 v8i8, v8i8, OpNode>;
4955 def v16i8rz : BaseSIMDCmpTwoVector<1, U, 0b00, opc, V128,
4956 asm, ".16b", "0",
4957 v16i8, v16i8, OpNode>;
4958 def v4i16rz : BaseSIMDCmpTwoVector<0, U, 0b01, opc, V64,
4959 asm, ".4h", "0",
4960 v4i16, v4i16, OpNode>;
4961 def v8i16rz : BaseSIMDCmpTwoVector<1, U, 0b01, opc, V128,
4962 asm, ".8h", "0",
4963 v8i16, v8i16, OpNode>;
4964 def v2i32rz : BaseSIMDCmpTwoVector<0, U, 0b10, opc, V64,
4965 asm, ".2s", "0",
4966 v2i32, v2i32, OpNode>;
4967 def v4i32rz : BaseSIMDCmpTwoVector<1, U, 0b10, opc, V128,
4968 asm, ".4s", "0",
4969 v4i32, v4i32, OpNode>;
4970 def v2i64rz : BaseSIMDCmpTwoVector<1, U, 0b11, opc, V128,
4971 asm, ".2d", "0",
4972 v2i64, v2i64, OpNode>;
4973}
4974
4975// FP Comparisons support only S and D element sizes.
4976multiclass SIMDFPCmpTwoVector<bit U, bit S, bits<5> opc,
4977 string asm, SDNode OpNode> {
4978
4979 def v2i32rz : BaseSIMDCmpTwoVector<0, U, {S,0}, opc, V64,
4980 asm, ".2s", "0.0",
4981 v2i32, v2f32, OpNode>;
4982 def v4i32rz : BaseSIMDCmpTwoVector<1, U, {S,0}, opc, V128,
4983 asm, ".4s", "0.0",
4984 v4i32, v4f32, OpNode>;
4985 def v2i64rz : BaseSIMDCmpTwoVector<1, U, {S,1}, opc, V128,
4986 asm, ".2d", "0.0",
4987 v2i64, v2f64, OpNode>;
4988
Ahmed Bougachacca07712015-09-02 18:38:36 +00004989 def : InstAlias<asm # "\t$Vd.2s, $Vn.2s, #0",
Tim Northover3b0846e2014-05-24 12:50:23 +00004990 (!cast<Instruction>(NAME # v2i32rz) V64:$Vd, V64:$Vn), 0>;
Ahmed Bougachacca07712015-09-02 18:38:36 +00004991 def : InstAlias<asm # "\t$Vd.4s, $Vn.4s, #0",
Tim Northover3b0846e2014-05-24 12:50:23 +00004992 (!cast<Instruction>(NAME # v4i32rz) V128:$Vd, V128:$Vn), 0>;
Ahmed Bougachacca07712015-09-02 18:38:36 +00004993 def : InstAlias<asm # "\t$Vd.2d, $Vn.2d, #0",
Tim Northover3b0846e2014-05-24 12:50:23 +00004994 (!cast<Instruction>(NAME # v2i64rz) V128:$Vd, V128:$Vn), 0>;
Ahmed Bougachacca07712015-09-02 18:38:36 +00004995 def : InstAlias<asm # ".2s\t$Vd, $Vn, #0",
Tim Northover3b0846e2014-05-24 12:50:23 +00004996 (!cast<Instruction>(NAME # v2i32rz) V64:$Vd, V64:$Vn), 0>;
Ahmed Bougachacca07712015-09-02 18:38:36 +00004997 def : InstAlias<asm # ".4s\t$Vd, $Vn, #0",
Tim Northover3b0846e2014-05-24 12:50:23 +00004998 (!cast<Instruction>(NAME # v4i32rz) V128:$Vd, V128:$Vn), 0>;
Ahmed Bougachacca07712015-09-02 18:38:36 +00004999 def : InstAlias<asm # ".2d\t$Vd, $Vn, #0",
Tim Northover3b0846e2014-05-24 12:50:23 +00005000 (!cast<Instruction>(NAME # v2i64rz) V128:$Vd, V128:$Vn), 0>;
5001}
5002
5003let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5004class BaseSIMDFPCvtTwoVector<bit Q, bit U, bits<2> size, bits<5> opcode,
5005 RegisterOperand outtype, RegisterOperand intype,
5006 string asm, string VdTy, string VnTy,
5007 list<dag> pattern>
5008 : I<(outs outtype:$Rd), (ins intype:$Rn), asm,
5009 !strconcat("\t$Rd", VdTy, ", $Rn", VnTy), "", pattern>,
5010 Sched<[WriteV]> {
5011 bits<5> Rd;
5012 bits<5> Rn;
5013 let Inst{31} = 0;
5014 let Inst{30} = Q;
5015 let Inst{29} = U;
5016 let Inst{28-24} = 0b01110;
5017 let Inst{23-22} = size;
5018 let Inst{21-17} = 0b10000;
5019 let Inst{16-12} = opcode;
5020 let Inst{11-10} = 0b10;
5021 let Inst{9-5} = Rn;
5022 let Inst{4-0} = Rd;
5023}
5024
5025class BaseSIMDFPCvtTwoVectorTied<bit Q, bit U, bits<2> size, bits<5> opcode,
5026 RegisterOperand outtype, RegisterOperand intype,
5027 string asm, string VdTy, string VnTy,
5028 list<dag> pattern>
5029 : I<(outs outtype:$dst), (ins outtype:$Rd, intype:$Rn), asm,
5030 !strconcat("\t$Rd", VdTy, ", $Rn", VnTy), "$Rd = $dst", pattern>,
5031 Sched<[WriteV]> {
5032 bits<5> Rd;
5033 bits<5> Rn;
5034 let Inst{31} = 0;
5035 let Inst{30} = Q;
5036 let Inst{29} = U;
5037 let Inst{28-24} = 0b01110;
5038 let Inst{23-22} = size;
5039 let Inst{21-17} = 0b10000;
5040 let Inst{16-12} = opcode;
5041 let Inst{11-10} = 0b10;
5042 let Inst{9-5} = Rn;
5043 let Inst{4-0} = Rd;
5044}
5045
5046multiclass SIMDFPWidenTwoVector<bit U, bit S, bits<5> opc, string asm> {
5047 def v4i16 : BaseSIMDFPCvtTwoVector<0, U, {S,0}, opc, V128, V64,
5048 asm, ".4s", ".4h", []>;
5049 def v8i16 : BaseSIMDFPCvtTwoVector<1, U, {S,0}, opc, V128, V128,
5050 asm#"2", ".4s", ".8h", []>;
5051 def v2i32 : BaseSIMDFPCvtTwoVector<0, U, {S,1}, opc, V128, V64,
5052 asm, ".2d", ".2s", []>;
5053 def v4i32 : BaseSIMDFPCvtTwoVector<1, U, {S,1}, opc, V128, V128,
5054 asm#"2", ".2d", ".4s", []>;
5055}
5056
5057multiclass SIMDFPNarrowTwoVector<bit U, bit S, bits<5> opc, string asm> {
5058 def v4i16 : BaseSIMDFPCvtTwoVector<0, U, {S,0}, opc, V64, V128,
5059 asm, ".4h", ".4s", []>;
5060 def v8i16 : BaseSIMDFPCvtTwoVectorTied<1, U, {S,0}, opc, V128, V128,
5061 asm#"2", ".8h", ".4s", []>;
5062 def v2i32 : BaseSIMDFPCvtTwoVector<0, U, {S,1}, opc, V64, V128,
5063 asm, ".2s", ".2d", []>;
5064 def v4i32 : BaseSIMDFPCvtTwoVectorTied<1, U, {S,1}, opc, V128, V128,
5065 asm#"2", ".4s", ".2d", []>;
5066}
5067
5068multiclass SIMDFPInexactCvtTwoVector<bit U, bit S, bits<5> opc, string asm,
5069 Intrinsic OpNode> {
5070 def v2f32 : BaseSIMDFPCvtTwoVector<0, U, {S,1}, opc, V64, V128,
5071 asm, ".2s", ".2d",
5072 [(set (v2f32 V64:$Rd), (OpNode (v2f64 V128:$Rn)))]>;
5073 def v4f32 : BaseSIMDFPCvtTwoVectorTied<1, U, {S,1}, opc, V128, V128,
5074 asm#"2", ".4s", ".2d", []>;
5075
5076 def : Pat<(concat_vectors (v2f32 V64:$Rd), (OpNode (v2f64 V128:$Rn))),
5077 (!cast<Instruction>(NAME # "v4f32")
5078 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>;
5079}
5080
5081//----------------------------------------------------------------------------
5082// AdvSIMD three register different-size vector instructions.
5083//----------------------------------------------------------------------------
5084
5085let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5086class BaseSIMDDifferentThreeVector<bit U, bits<3> size, bits<4> opcode,
5087 RegisterOperand outtype, RegisterOperand intype1,
5088 RegisterOperand intype2, string asm,
5089 string outkind, string inkind1, string inkind2,
5090 list<dag> pattern>
5091 : I<(outs outtype:$Rd), (ins intype1:$Rn, intype2:$Rm), asm,
5092 "{\t$Rd" # outkind # ", $Rn" # inkind1 # ", $Rm" # inkind2 #
5093 "|" # outkind # "\t$Rd, $Rn, $Rm}", "", pattern>,
5094 Sched<[WriteV]> {
5095 bits<5> Rd;
5096 bits<5> Rn;
5097 bits<5> Rm;
5098 let Inst{31} = 0;
5099 let Inst{30} = size{0};
5100 let Inst{29} = U;
5101 let Inst{28-24} = 0b01110;
5102 let Inst{23-22} = size{2-1};
5103 let Inst{21} = 1;
5104 let Inst{20-16} = Rm;
5105 let Inst{15-12} = opcode;
5106 let Inst{11-10} = 0b00;
5107 let Inst{9-5} = Rn;
5108 let Inst{4-0} = Rd;
5109}
5110
5111let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5112class BaseSIMDDifferentThreeVectorTied<bit U, bits<3> size, bits<4> opcode,
5113 RegisterOperand outtype, RegisterOperand intype1,
5114 RegisterOperand intype2, string asm,
5115 string outkind, string inkind1, string inkind2,
5116 list<dag> pattern>
5117 : I<(outs outtype:$dst), (ins outtype:$Rd, intype1:$Rn, intype2:$Rm), asm,
5118 "{\t$Rd" # outkind # ", $Rn" # inkind1 # ", $Rm" # inkind2 #
5119 "|" # outkind # "\t$Rd, $Rn, $Rm}", "$Rd = $dst", pattern>,
5120 Sched<[WriteV]> {
5121 bits<5> Rd;
5122 bits<5> Rn;
5123 bits<5> Rm;
5124 let Inst{31} = 0;
5125 let Inst{30} = size{0};
5126 let Inst{29} = U;
5127 let Inst{28-24} = 0b01110;
5128 let Inst{23-22} = size{2-1};
5129 let Inst{21} = 1;
5130 let Inst{20-16} = Rm;
5131 let Inst{15-12} = opcode;
5132 let Inst{11-10} = 0b00;
5133 let Inst{9-5} = Rn;
5134 let Inst{4-0} = Rd;
5135}
5136
5137// FIXME: TableGen doesn't know how to deal with expanded types that also
5138// change the element count (in this case, placing the results in
5139// the high elements of the result register rather than the low
5140// elements). Until that's fixed, we can't code-gen those.
5141multiclass SIMDNarrowThreeVectorBHS<bit U, bits<4> opc, string asm,
5142 Intrinsic IntOp> {
5143 def v8i16_v8i8 : BaseSIMDDifferentThreeVector<U, 0b000, opc,
5144 V64, V128, V128,
5145 asm, ".8b", ".8h", ".8h",
5146 [(set (v8i8 V64:$Rd), (IntOp (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>;
5147 def v8i16_v16i8 : BaseSIMDDifferentThreeVectorTied<U, 0b001, opc,
5148 V128, V128, V128,
5149 asm#"2", ".16b", ".8h", ".8h",
5150 []>;
5151 def v4i32_v4i16 : BaseSIMDDifferentThreeVector<U, 0b010, opc,
5152 V64, V128, V128,
5153 asm, ".4h", ".4s", ".4s",
5154 [(set (v4i16 V64:$Rd), (IntOp (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>;
5155 def v4i32_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc,
5156 V128, V128, V128,
5157 asm#"2", ".8h", ".4s", ".4s",
5158 []>;
5159 def v2i64_v2i32 : BaseSIMDDifferentThreeVector<U, 0b100, opc,
5160 V64, V128, V128,
5161 asm, ".2s", ".2d", ".2d",
5162 [(set (v2i32 V64:$Rd), (IntOp (v2i64 V128:$Rn), (v2i64 V128:$Rm)))]>;
5163 def v2i64_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc,
5164 V128, V128, V128,
5165 asm#"2", ".4s", ".2d", ".2d",
5166 []>;
5167
5168
5169 // Patterns for the '2' variants involve INSERT_SUBREG, which you can't put in
5170 // a version attached to an instruction.
5171 def : Pat<(concat_vectors (v8i8 V64:$Rd), (IntOp (v8i16 V128:$Rn),
5172 (v8i16 V128:$Rm))),
5173 (!cast<Instruction>(NAME # "v8i16_v16i8")
5174 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub),
5175 V128:$Rn, V128:$Rm)>;
5176 def : Pat<(concat_vectors (v4i16 V64:$Rd), (IntOp (v4i32 V128:$Rn),
5177 (v4i32 V128:$Rm))),
5178 (!cast<Instruction>(NAME # "v4i32_v8i16")
5179 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub),
5180 V128:$Rn, V128:$Rm)>;
5181 def : Pat<(concat_vectors (v2i32 V64:$Rd), (IntOp (v2i64 V128:$Rn),
5182 (v2i64 V128:$Rm))),
5183 (!cast<Instruction>(NAME # "v2i64_v4i32")
5184 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub),
5185 V128:$Rn, V128:$Rm)>;
5186}
5187
5188multiclass SIMDDifferentThreeVectorBD<bit U, bits<4> opc, string asm,
5189 Intrinsic IntOp> {
5190 def v8i8 : BaseSIMDDifferentThreeVector<U, 0b000, opc,
5191 V128, V64, V64,
5192 asm, ".8h", ".8b", ".8b",
5193 [(set (v8i16 V128:$Rd), (IntOp (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
5194 def v16i8 : BaseSIMDDifferentThreeVector<U, 0b001, opc,
5195 V128, V128, V128,
5196 asm#"2", ".8h", ".16b", ".16b", []>;
5197 let Predicates = [HasCrypto] in {
5198 def v1i64 : BaseSIMDDifferentThreeVector<U, 0b110, opc,
5199 V128, V64, V64,
5200 asm, ".1q", ".1d", ".1d", []>;
5201 def v2i64 : BaseSIMDDifferentThreeVector<U, 0b111, opc,
5202 V128, V128, V128,
5203 asm#"2", ".1q", ".2d", ".2d", []>;
5204 }
5205
5206 def : Pat<(v8i16 (IntOp (v8i8 (extract_high_v16i8 V128:$Rn)),
5207 (v8i8 (extract_high_v16i8 V128:$Rm)))),
5208 (!cast<Instruction>(NAME#"v16i8") V128:$Rn, V128:$Rm)>;
5209}
5210
5211multiclass SIMDLongThreeVectorHS<bit U, bits<4> opc, string asm,
5212 SDPatternOperator OpNode> {
5213 def v4i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b010, opc,
5214 V128, V64, V64,
5215 asm, ".4s", ".4h", ".4h",
5216 [(set (v4i32 V128:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>;
5217 def v8i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b011, opc,
5218 V128, V128, V128,
5219 asm#"2", ".4s", ".8h", ".8h",
5220 [(set (v4i32 V128:$Rd), (OpNode (extract_high_v8i16 V128:$Rn),
5221 (extract_high_v8i16 V128:$Rm)))]>;
5222 def v2i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b100, opc,
5223 V128, V64, V64,
5224 asm, ".2d", ".2s", ".2s",
5225 [(set (v2i64 V128:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>;
5226 def v4i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b101, opc,
5227 V128, V128, V128,
5228 asm#"2", ".2d", ".4s", ".4s",
5229 [(set (v2i64 V128:$Rd), (OpNode (extract_high_v4i32 V128:$Rn),
5230 (extract_high_v4i32 V128:$Rm)))]>;
5231}
5232
5233multiclass SIMDLongThreeVectorBHSabdl<bit U, bits<4> opc, string asm,
5234 SDPatternOperator OpNode = null_frag> {
5235 def v8i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b000, opc,
5236 V128, V64, V64,
5237 asm, ".8h", ".8b", ".8b",
5238 [(set (v8i16 V128:$Rd),
5239 (zext (v8i8 (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))))]>;
5240 def v16i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b001, opc,
5241 V128, V128, V128,
5242 asm#"2", ".8h", ".16b", ".16b",
5243 [(set (v8i16 V128:$Rd),
5244 (zext (v8i8 (OpNode (extract_high_v16i8 V128:$Rn),
5245 (extract_high_v16i8 V128:$Rm)))))]>;
5246 def v4i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b010, opc,
5247 V128, V64, V64,
5248 asm, ".4s", ".4h", ".4h",
5249 [(set (v4i32 V128:$Rd),
5250 (zext (v4i16 (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))))]>;
5251 def v8i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b011, opc,
5252 V128, V128, V128,
5253 asm#"2", ".4s", ".8h", ".8h",
5254 [(set (v4i32 V128:$Rd),
5255 (zext (v4i16 (OpNode (extract_high_v8i16 V128:$Rn),
5256 (extract_high_v8i16 V128:$Rm)))))]>;
5257 def v2i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b100, opc,
5258 V128, V64, V64,
5259 asm, ".2d", ".2s", ".2s",
5260 [(set (v2i64 V128:$Rd),
5261 (zext (v2i32 (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))))]>;
5262 def v4i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b101, opc,
5263 V128, V128, V128,
5264 asm#"2", ".2d", ".4s", ".4s",
5265 [(set (v2i64 V128:$Rd),
5266 (zext (v2i32 (OpNode (extract_high_v4i32 V128:$Rn),
5267 (extract_high_v4i32 V128:$Rm)))))]>;
5268}
5269
5270multiclass SIMDLongThreeVectorTiedBHSabal<bit U, bits<4> opc,
5271 string asm,
5272 SDPatternOperator OpNode> {
5273 def v8i8_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b000, opc,
5274 V128, V64, V64,
5275 asm, ".8h", ".8b", ".8b",
5276 [(set (v8i16 V128:$dst),
5277 (add (v8i16 V128:$Rd),
5278 (zext (v8i8 (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm))))))]>;
5279 def v16i8_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b001, opc,
5280 V128, V128, V128,
5281 asm#"2", ".8h", ".16b", ".16b",
5282 [(set (v8i16 V128:$dst),
5283 (add (v8i16 V128:$Rd),
5284 (zext (v8i8 (OpNode (extract_high_v16i8 V128:$Rn),
5285 (extract_high_v16i8 V128:$Rm))))))]>;
5286 def v4i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b010, opc,
5287 V128, V64, V64,
5288 asm, ".4s", ".4h", ".4h",
5289 [(set (v4i32 V128:$dst),
5290 (add (v4i32 V128:$Rd),
5291 (zext (v4i16 (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm))))))]>;
5292 def v8i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc,
5293 V128, V128, V128,
5294 asm#"2", ".4s", ".8h", ".8h",
5295 [(set (v4i32 V128:$dst),
5296 (add (v4i32 V128:$Rd),
5297 (zext (v4i16 (OpNode (extract_high_v8i16 V128:$Rn),
5298 (extract_high_v8i16 V128:$Rm))))))]>;
5299 def v2i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b100, opc,
5300 V128, V64, V64,
5301 asm, ".2d", ".2s", ".2s",
5302 [(set (v2i64 V128:$dst),
5303 (add (v2i64 V128:$Rd),
5304 (zext (v2i32 (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm))))))]>;
5305 def v4i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc,
5306 V128, V128, V128,
5307 asm#"2", ".2d", ".4s", ".4s",
5308 [(set (v2i64 V128:$dst),
5309 (add (v2i64 V128:$Rd),
5310 (zext (v2i32 (OpNode (extract_high_v4i32 V128:$Rn),
5311 (extract_high_v4i32 V128:$Rm))))))]>;
5312}
5313
5314multiclass SIMDLongThreeVectorBHS<bit U, bits<4> opc, string asm,
5315 SDPatternOperator OpNode = null_frag> {
5316 def v8i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b000, opc,
5317 V128, V64, V64,
5318 asm, ".8h", ".8b", ".8b",
5319 [(set (v8i16 V128:$Rd), (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
5320 def v16i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b001, opc,
5321 V128, V128, V128,
5322 asm#"2", ".8h", ".16b", ".16b",
5323 [(set (v8i16 V128:$Rd), (OpNode (extract_high_v16i8 V128:$Rn),
5324 (extract_high_v16i8 V128:$Rm)))]>;
5325 def v4i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b010, opc,
5326 V128, V64, V64,
5327 asm, ".4s", ".4h", ".4h",
5328 [(set (v4i32 V128:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>;
5329 def v8i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b011, opc,
5330 V128, V128, V128,
5331 asm#"2", ".4s", ".8h", ".8h",
5332 [(set (v4i32 V128:$Rd), (OpNode (extract_high_v8i16 V128:$Rn),
5333 (extract_high_v8i16 V128:$Rm)))]>;
5334 def v2i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b100, opc,
5335 V128, V64, V64,
5336 asm, ".2d", ".2s", ".2s",
5337 [(set (v2i64 V128:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>;
5338 def v4i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b101, opc,
5339 V128, V128, V128,
5340 asm#"2", ".2d", ".4s", ".4s",
5341 [(set (v2i64 V128:$Rd), (OpNode (extract_high_v4i32 V128:$Rn),
5342 (extract_high_v4i32 V128:$Rm)))]>;
5343}
5344
5345multiclass SIMDLongThreeVectorTiedBHS<bit U, bits<4> opc,
5346 string asm,
5347 SDPatternOperator OpNode> {
5348 def v8i8_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b000, opc,
5349 V128, V64, V64,
5350 asm, ".8h", ".8b", ".8b",
5351 [(set (v8i16 V128:$dst),
5352 (OpNode (v8i16 V128:$Rd), (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
5353 def v16i8_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b001, opc,
5354 V128, V128, V128,
5355 asm#"2", ".8h", ".16b", ".16b",
5356 [(set (v8i16 V128:$dst),
5357 (OpNode (v8i16 V128:$Rd),
5358 (extract_high_v16i8 V128:$Rn),
5359 (extract_high_v16i8 V128:$Rm)))]>;
5360 def v4i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b010, opc,
5361 V128, V64, V64,
5362 asm, ".4s", ".4h", ".4h",
5363 [(set (v4i32 V128:$dst),
5364 (OpNode (v4i32 V128:$Rd), (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>;
5365 def v8i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc,
5366 V128, V128, V128,
5367 asm#"2", ".4s", ".8h", ".8h",
5368 [(set (v4i32 V128:$dst),
5369 (OpNode (v4i32 V128:$Rd),
5370 (extract_high_v8i16 V128:$Rn),
5371 (extract_high_v8i16 V128:$Rm)))]>;
5372 def v2i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b100, opc,
5373 V128, V64, V64,
5374 asm, ".2d", ".2s", ".2s",
5375 [(set (v2i64 V128:$dst),
5376 (OpNode (v2i64 V128:$Rd), (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>;
5377 def v4i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc,
5378 V128, V128, V128,
5379 asm#"2", ".2d", ".4s", ".4s",
5380 [(set (v2i64 V128:$dst),
5381 (OpNode (v2i64 V128:$Rd),
5382 (extract_high_v4i32 V128:$Rn),
5383 (extract_high_v4i32 V128:$Rm)))]>;
5384}
5385
5386multiclass SIMDLongThreeVectorSQDMLXTiedHS<bit U, bits<4> opc, string asm,
5387 SDPatternOperator Accum> {
5388 def v4i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b010, opc,
5389 V128, V64, V64,
5390 asm, ".4s", ".4h", ".4h",
5391 [(set (v4i32 V128:$dst),
5392 (Accum (v4i32 V128:$Rd),
5393 (v4i32 (int_aarch64_neon_sqdmull (v4i16 V64:$Rn),
5394 (v4i16 V64:$Rm)))))]>;
5395 def v8i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc,
5396 V128, V128, V128,
5397 asm#"2", ".4s", ".8h", ".8h",
5398 [(set (v4i32 V128:$dst),
5399 (Accum (v4i32 V128:$Rd),
5400 (v4i32 (int_aarch64_neon_sqdmull (extract_high_v8i16 V128:$Rn),
5401 (extract_high_v8i16 V128:$Rm)))))]>;
5402 def v2i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b100, opc,
5403 V128, V64, V64,
5404 asm, ".2d", ".2s", ".2s",
5405 [(set (v2i64 V128:$dst),
5406 (Accum (v2i64 V128:$Rd),
5407 (v2i64 (int_aarch64_neon_sqdmull (v2i32 V64:$Rn),
5408 (v2i32 V64:$Rm)))))]>;
5409 def v4i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc,
5410 V128, V128, V128,
5411 asm#"2", ".2d", ".4s", ".4s",
5412 [(set (v2i64 V128:$dst),
5413 (Accum (v2i64 V128:$Rd),
5414 (v2i64 (int_aarch64_neon_sqdmull (extract_high_v4i32 V128:$Rn),
5415 (extract_high_v4i32 V128:$Rm)))))]>;
5416}
5417
5418multiclass SIMDWideThreeVectorBHS<bit U, bits<4> opc, string asm,
5419 SDPatternOperator OpNode> {
5420 def v8i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b000, opc,
5421 V128, V128, V64,
5422 asm, ".8h", ".8h", ".8b",
5423 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (v8i8 V64:$Rm)))]>;
5424 def v16i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b001, opc,
5425 V128, V128, V128,
5426 asm#"2", ".8h", ".8h", ".16b",
5427 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn),
5428 (extract_high_v16i8 V128:$Rm)))]>;
5429 def v4i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b010, opc,
5430 V128, V128, V64,
5431 asm, ".4s", ".4s", ".4h",
5432 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (v4i16 V64:$Rm)))]>;
5433 def v8i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b011, opc,
5434 V128, V128, V128,
5435 asm#"2", ".4s", ".4s", ".8h",
5436 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn),
5437 (extract_high_v8i16 V128:$Rm)))]>;
5438 def v2i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b100, opc,
5439 V128, V128, V64,
5440 asm, ".2d", ".2d", ".2s",
5441 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn), (v2i32 V64:$Rm)))]>;
5442 def v4i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b101, opc,
5443 V128, V128, V128,
5444 asm#"2", ".2d", ".2d", ".4s",
5445 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn),
5446 (extract_high_v4i32 V128:$Rm)))]>;
5447}
5448
5449//----------------------------------------------------------------------------
5450// AdvSIMD bitwise extract from vector
5451//----------------------------------------------------------------------------
5452
5453class BaseSIMDBitwiseExtract<bit size, RegisterOperand regtype, ValueType vty,
5454 string asm, string kind>
5455 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, i32imm:$imm), asm,
5456 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind # ", $imm" #
5457 "|" # kind # "\t$Rd, $Rn, $Rm, $imm}", "",
5458 [(set (vty regtype:$Rd),
5459 (AArch64ext regtype:$Rn, regtype:$Rm, (i32 imm:$imm)))]>,
5460 Sched<[WriteV]> {
5461 bits<5> Rd;
5462 bits<5> Rn;
5463 bits<5> Rm;
5464 bits<4> imm;
5465 let Inst{31} = 0;
5466 let Inst{30} = size;
5467 let Inst{29-21} = 0b101110000;
5468 let Inst{20-16} = Rm;
5469 let Inst{15} = 0;
5470 let Inst{14-11} = imm;
5471 let Inst{10} = 0;
5472 let Inst{9-5} = Rn;
5473 let Inst{4-0} = Rd;
5474}
5475
5476
5477multiclass SIMDBitwiseExtract<string asm> {
5478 def v8i8 : BaseSIMDBitwiseExtract<0, V64, v8i8, asm, ".8b"> {
5479 let imm{3} = 0;
5480 }
5481 def v16i8 : BaseSIMDBitwiseExtract<1, V128, v16i8, asm, ".16b">;
5482}
5483
5484//----------------------------------------------------------------------------
5485// AdvSIMD zip vector
5486//----------------------------------------------------------------------------
5487
5488class BaseSIMDZipVector<bits<3> size, bits<3> opc, RegisterOperand regtype,
5489 string asm, string kind, SDNode OpNode, ValueType valty>
5490 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), asm,
5491 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind #
5492 "|" # kind # "\t$Rd, $Rn, $Rm}", "",
5493 [(set (valty regtype:$Rd), (OpNode regtype:$Rn, regtype:$Rm))]>,
5494 Sched<[WriteV]> {
5495 bits<5> Rd;
5496 bits<5> Rn;
5497 bits<5> Rm;
5498 let Inst{31} = 0;
5499 let Inst{30} = size{0};
5500 let Inst{29-24} = 0b001110;
5501 let Inst{23-22} = size{2-1};
5502 let Inst{21} = 0;
5503 let Inst{20-16} = Rm;
5504 let Inst{15} = 0;
5505 let Inst{14-12} = opc;
5506 let Inst{11-10} = 0b10;
5507 let Inst{9-5} = Rn;
5508 let Inst{4-0} = Rd;
5509}
5510
5511multiclass SIMDZipVector<bits<3>opc, string asm,
5512 SDNode OpNode> {
5513 def v8i8 : BaseSIMDZipVector<0b000, opc, V64,
5514 asm, ".8b", OpNode, v8i8>;
5515 def v16i8 : BaseSIMDZipVector<0b001, opc, V128,
5516 asm, ".16b", OpNode, v16i8>;
5517 def v4i16 : BaseSIMDZipVector<0b010, opc, V64,
5518 asm, ".4h", OpNode, v4i16>;
5519 def v8i16 : BaseSIMDZipVector<0b011, opc, V128,
5520 asm, ".8h", OpNode, v8i16>;
5521 def v2i32 : BaseSIMDZipVector<0b100, opc, V64,
5522 asm, ".2s", OpNode, v2i32>;
5523 def v4i32 : BaseSIMDZipVector<0b101, opc, V128,
5524 asm, ".4s", OpNode, v4i32>;
5525 def v2i64 : BaseSIMDZipVector<0b111, opc, V128,
5526 asm, ".2d", OpNode, v2i64>;
5527
Oliver Stannard89d15422014-08-27 16:16:04 +00005528 def : Pat<(v4f16 (OpNode V64:$Rn, V64:$Rm)),
5529 (!cast<Instruction>(NAME#"v4i16") V64:$Rn, V64:$Rm)>;
5530 def : Pat<(v8f16 (OpNode V128:$Rn, V128:$Rm)),
5531 (!cast<Instruction>(NAME#"v8i16") V128:$Rn, V128:$Rm)>;
Tim Northover3b0846e2014-05-24 12:50:23 +00005532 def : Pat<(v2f32 (OpNode V64:$Rn, V64:$Rm)),
5533 (!cast<Instruction>(NAME#"v2i32") V64:$Rn, V64:$Rm)>;
5534 def : Pat<(v4f32 (OpNode V128:$Rn, V128:$Rm)),
5535 (!cast<Instruction>(NAME#"v4i32") V128:$Rn, V128:$Rm)>;
5536 def : Pat<(v2f64 (OpNode V128:$Rn, V128:$Rm)),
5537 (!cast<Instruction>(NAME#"v2i64") V128:$Rn, V128:$Rm)>;
5538}
5539
5540//----------------------------------------------------------------------------
5541// AdvSIMD three register scalar instructions
5542//----------------------------------------------------------------------------
5543
5544let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
5545class BaseSIMDThreeScalar<bit U, bits<2> size, bits<5> opcode,
5546 RegisterClass regtype, string asm,
5547 list<dag> pattern>
5548 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), asm,
5549 "\t$Rd, $Rn, $Rm", "", pattern>,
5550 Sched<[WriteV]> {
5551 bits<5> Rd;
5552 bits<5> Rn;
5553 bits<5> Rm;
5554 let Inst{31-30} = 0b01;
5555 let Inst{29} = U;
5556 let Inst{28-24} = 0b11110;
5557 let Inst{23-22} = size;
5558 let Inst{21} = 1;
5559 let Inst{20-16} = Rm;
5560 let Inst{15-11} = opcode;
5561 let Inst{10} = 1;
5562 let Inst{9-5} = Rn;
5563 let Inst{4-0} = Rd;
5564}
5565
Vladimir Sukharev297bf0e2015-03-31 13:15:48 +00005566let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
5567class BaseSIMDThreeScalarTied<bit U, bits<2> size, bit R, bits<5> opcode,
5568 dag oops, dag iops, string asm,
5569 list<dag> pattern>
5570 : I<oops, iops, asm, "\t$Rd, $Rn, $Rm", "$Rd = $dst", pattern>,
5571 Sched<[WriteV]> {
5572 bits<5> Rd;
5573 bits<5> Rn;
5574 bits<5> Rm;
5575 let Inst{31-30} = 0b01;
5576 let Inst{29} = U;
5577 let Inst{28-24} = 0b11110;
5578 let Inst{23-22} = size;
5579 let Inst{21} = R;
5580 let Inst{20-16} = Rm;
5581 let Inst{15-11} = opcode;
5582 let Inst{10} = 1;
5583 let Inst{9-5} = Rn;
5584 let Inst{4-0} = Rd;
5585}
5586
Tim Northover3b0846e2014-05-24 12:50:23 +00005587multiclass SIMDThreeScalarD<bit U, bits<5> opc, string asm,
5588 SDPatternOperator OpNode> {
5589 def v1i64 : BaseSIMDThreeScalar<U, 0b11, opc, FPR64, asm,
5590 [(set (v1i64 FPR64:$Rd), (OpNode (v1i64 FPR64:$Rn), (v1i64 FPR64:$Rm)))]>;
5591}
5592
5593multiclass SIMDThreeScalarBHSD<bit U, bits<5> opc, string asm,
5594 SDPatternOperator OpNode> {
5595 def v1i64 : BaseSIMDThreeScalar<U, 0b11, opc, FPR64, asm,
5596 [(set (v1i64 FPR64:$Rd), (OpNode (v1i64 FPR64:$Rn), (v1i64 FPR64:$Rm)))]>;
5597 def v1i32 : BaseSIMDThreeScalar<U, 0b10, opc, FPR32, asm, []>;
5598 def v1i16 : BaseSIMDThreeScalar<U, 0b01, opc, FPR16, asm, []>;
5599 def v1i8 : BaseSIMDThreeScalar<U, 0b00, opc, FPR8 , asm, []>;
5600
5601 def : Pat<(i64 (OpNode (i64 FPR64:$Rn), (i64 FPR64:$Rm))),
5602 (!cast<Instruction>(NAME#"v1i64") FPR64:$Rn, FPR64:$Rm)>;
5603 def : Pat<(i32 (OpNode (i32 FPR32:$Rn), (i32 FPR32:$Rm))),
5604 (!cast<Instruction>(NAME#"v1i32") FPR32:$Rn, FPR32:$Rm)>;
5605}
5606
5607multiclass SIMDThreeScalarHS<bit U, bits<5> opc, string asm,
5608 SDPatternOperator OpNode> {
5609 def v1i32 : BaseSIMDThreeScalar<U, 0b10, opc, FPR32, asm,
5610 [(set FPR32:$Rd, (OpNode FPR32:$Rn, FPR32:$Rm))]>;
5611 def v1i16 : BaseSIMDThreeScalar<U, 0b01, opc, FPR16, asm, []>;
5612}
5613
Vladimir Sukharev297bf0e2015-03-31 13:15:48 +00005614multiclass SIMDThreeScalarHSTied<bit U, bit R, bits<5> opc, string asm,
5615 SDPatternOperator OpNode = null_frag> {
5616 def v1i32: BaseSIMDThreeScalarTied<U, 0b10, R, opc, (outs FPR32:$dst),
5617 (ins FPR32:$Rd, FPR32:$Rn, FPR32:$Rm),
5618 asm, []>;
5619 def v1i16: BaseSIMDThreeScalarTied<U, 0b01, R, opc, (outs FPR16:$dst),
5620 (ins FPR16:$Rd, FPR16:$Rn, FPR16:$Rm),
5621 asm, []>;
5622}
5623
Tim Northover3b0846e2014-05-24 12:50:23 +00005624multiclass SIMDThreeScalarSD<bit U, bit S, bits<5> opc, string asm,
5625 SDPatternOperator OpNode = null_frag> {
5626 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
5627 def #NAME#64 : BaseSIMDThreeScalar<U, {S,1}, opc, FPR64, asm,
5628 [(set (f64 FPR64:$Rd), (OpNode (f64 FPR64:$Rn), (f64 FPR64:$Rm)))]>;
5629 def #NAME#32 : BaseSIMDThreeScalar<U, {S,0}, opc, FPR32, asm,
5630 [(set FPR32:$Rd, (OpNode FPR32:$Rn, FPR32:$Rm))]>;
5631 }
5632
5633 def : Pat<(v1f64 (OpNode (v1f64 FPR64:$Rn), (v1f64 FPR64:$Rm))),
5634 (!cast<Instruction>(NAME # "64") FPR64:$Rn, FPR64:$Rm)>;
5635}
5636
5637multiclass SIMDThreeScalarFPCmp<bit U, bit S, bits<5> opc, string asm,
5638 SDPatternOperator OpNode = null_frag> {
5639 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
5640 def #NAME#64 : BaseSIMDThreeScalar<U, {S,1}, opc, FPR64, asm,
5641 [(set (i64 FPR64:$Rd), (OpNode (f64 FPR64:$Rn), (f64 FPR64:$Rm)))]>;
5642 def #NAME#32 : BaseSIMDThreeScalar<U, {S,0}, opc, FPR32, asm,
5643 [(set (i32 FPR32:$Rd), (OpNode (f32 FPR32:$Rn), (f32 FPR32:$Rm)))]>;
5644 }
5645
5646 def : Pat<(v1i64 (OpNode (v1f64 FPR64:$Rn), (v1f64 FPR64:$Rm))),
5647 (!cast<Instruction>(NAME # "64") FPR64:$Rn, FPR64:$Rm)>;
5648}
5649
5650class BaseSIMDThreeScalarMixed<bit U, bits<2> size, bits<5> opcode,
5651 dag oops, dag iops, string asm, string cstr, list<dag> pat>
5652 : I<oops, iops, asm,
5653 "\t$Rd, $Rn, $Rm", cstr, pat>,
5654 Sched<[WriteV]> {
5655 bits<5> Rd;
5656 bits<5> Rn;
5657 bits<5> Rm;
5658 let Inst{31-30} = 0b01;
5659 let Inst{29} = U;
5660 let Inst{28-24} = 0b11110;
5661 let Inst{23-22} = size;
5662 let Inst{21} = 1;
5663 let Inst{20-16} = Rm;
5664 let Inst{15-11} = opcode;
5665 let Inst{10} = 0;
5666 let Inst{9-5} = Rn;
5667 let Inst{4-0} = Rd;
5668}
5669
5670let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5671multiclass SIMDThreeScalarMixedHS<bit U, bits<5> opc, string asm,
5672 SDPatternOperator OpNode = null_frag> {
5673 def i16 : BaseSIMDThreeScalarMixed<U, 0b01, opc,
5674 (outs FPR32:$Rd),
5675 (ins FPR16:$Rn, FPR16:$Rm), asm, "", []>;
5676 def i32 : BaseSIMDThreeScalarMixed<U, 0b10, opc,
5677 (outs FPR64:$Rd),
5678 (ins FPR32:$Rn, FPR32:$Rm), asm, "",
5679 [(set (i64 FPR64:$Rd), (OpNode (i32 FPR32:$Rn), (i32 FPR32:$Rm)))]>;
5680}
5681
5682let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5683multiclass SIMDThreeScalarMixedTiedHS<bit U, bits<5> opc, string asm,
5684 SDPatternOperator OpNode = null_frag> {
5685 def i16 : BaseSIMDThreeScalarMixed<U, 0b01, opc,
5686 (outs FPR32:$dst),
5687 (ins FPR32:$Rd, FPR16:$Rn, FPR16:$Rm),
5688 asm, "$Rd = $dst", []>;
5689 def i32 : BaseSIMDThreeScalarMixed<U, 0b10, opc,
5690 (outs FPR64:$dst),
5691 (ins FPR64:$Rd, FPR32:$Rn, FPR32:$Rm),
5692 asm, "$Rd = $dst",
5693 [(set (i64 FPR64:$dst),
5694 (OpNode (i64 FPR64:$Rd), (i32 FPR32:$Rn), (i32 FPR32:$Rm)))]>;
5695}
5696
5697//----------------------------------------------------------------------------
5698// AdvSIMD two register scalar instructions
5699//----------------------------------------------------------------------------
5700
5701let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5702class BaseSIMDTwoScalar<bit U, bits<2> size, bits<5> opcode,
5703 RegisterClass regtype, RegisterClass regtype2,
5704 string asm, list<dag> pat>
5705 : I<(outs regtype:$Rd), (ins regtype2:$Rn), asm,
5706 "\t$Rd, $Rn", "", pat>,
5707 Sched<[WriteV]> {
5708 bits<5> Rd;
5709 bits<5> Rn;
5710 let Inst{31-30} = 0b01;
5711 let Inst{29} = U;
5712 let Inst{28-24} = 0b11110;
5713 let Inst{23-22} = size;
5714 let Inst{21-17} = 0b10000;
5715 let Inst{16-12} = opcode;
5716 let Inst{11-10} = 0b10;
5717 let Inst{9-5} = Rn;
5718 let Inst{4-0} = Rd;
5719}
5720
5721let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5722class BaseSIMDTwoScalarTied<bit U, bits<2> size, bits<5> opcode,
5723 RegisterClass regtype, RegisterClass regtype2,
5724 string asm, list<dag> pat>
5725 : I<(outs regtype:$dst), (ins regtype:$Rd, regtype2:$Rn), asm,
5726 "\t$Rd, $Rn", "$Rd = $dst", pat>,
5727 Sched<[WriteV]> {
5728 bits<5> Rd;
5729 bits<5> Rn;
5730 let Inst{31-30} = 0b01;
5731 let Inst{29} = U;
5732 let Inst{28-24} = 0b11110;
5733 let Inst{23-22} = size;
5734 let Inst{21-17} = 0b10000;
5735 let Inst{16-12} = opcode;
5736 let Inst{11-10} = 0b10;
5737 let Inst{9-5} = Rn;
5738 let Inst{4-0} = Rd;
5739}
5740
5741
5742let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5743class BaseSIMDCmpTwoScalar<bit U, bits<2> size, bits<5> opcode,
5744 RegisterClass regtype, string asm, string zero>
5745 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm,
5746 "\t$Rd, $Rn, #" # zero, "", []>,
5747 Sched<[WriteV]> {
5748 bits<5> Rd;
5749 bits<5> Rn;
5750 let Inst{31-30} = 0b01;
5751 let Inst{29} = U;
5752 let Inst{28-24} = 0b11110;
5753 let Inst{23-22} = size;
5754 let Inst{21-17} = 0b10000;
5755 let Inst{16-12} = opcode;
5756 let Inst{11-10} = 0b10;
5757 let Inst{9-5} = Rn;
5758 let Inst{4-0} = Rd;
5759}
5760
5761class SIMDInexactCvtTwoScalar<bits<5> opcode, string asm>
5762 : I<(outs FPR32:$Rd), (ins FPR64:$Rn), asm, "\t$Rd, $Rn", "",
5763 [(set (f32 FPR32:$Rd), (int_aarch64_sisd_fcvtxn (f64 FPR64:$Rn)))]>,
5764 Sched<[WriteV]> {
5765 bits<5> Rd;
5766 bits<5> Rn;
5767 let Inst{31-17} = 0b011111100110000;
5768 let Inst{16-12} = opcode;
5769 let Inst{11-10} = 0b10;
5770 let Inst{9-5} = Rn;
5771 let Inst{4-0} = Rd;
5772}
5773
5774multiclass SIMDCmpTwoScalarD<bit U, bits<5> opc, string asm,
5775 SDPatternOperator OpNode> {
5776 def v1i64rz : BaseSIMDCmpTwoScalar<U, 0b11, opc, FPR64, asm, "0">;
5777
5778 def : Pat<(v1i64 (OpNode FPR64:$Rn)),
5779 (!cast<Instruction>(NAME # v1i64rz) FPR64:$Rn)>;
5780}
5781
Ahmed Bougacha81fda182015-08-04 01:38:08 +00005782multiclass SIMDFPCmpTwoScalar<bit U, bit S, bits<5> opc, string asm,
Tim Northover3b0846e2014-05-24 12:50:23 +00005783 SDPatternOperator OpNode> {
5784 def v1i64rz : BaseSIMDCmpTwoScalar<U, {S,1}, opc, FPR64, asm, "0.0">;
5785 def v1i32rz : BaseSIMDCmpTwoScalar<U, {S,0}, opc, FPR32, asm, "0.0">;
5786
Ahmed Bougachacca07712015-09-02 18:38:36 +00005787 def : InstAlias<asm # "\t$Rd, $Rn, #0",
Tim Northover3b0846e2014-05-24 12:50:23 +00005788 (!cast<Instruction>(NAME # v1i64rz) FPR64:$Rd, FPR64:$Rn), 0>;
Ahmed Bougachacca07712015-09-02 18:38:36 +00005789 def : InstAlias<asm # "\t$Rd, $Rn, #0",
Tim Northover3b0846e2014-05-24 12:50:23 +00005790 (!cast<Instruction>(NAME # v1i32rz) FPR32:$Rd, FPR32:$Rn), 0>;
5791
5792 def : Pat<(v1i64 (OpNode (v1f64 FPR64:$Rn))),
5793 (!cast<Instruction>(NAME # v1i64rz) FPR64:$Rn)>;
5794}
5795
5796multiclass SIMDTwoScalarD<bit U, bits<5> opc, string asm,
5797 SDPatternOperator OpNode = null_frag> {
5798 def v1i64 : BaseSIMDTwoScalar<U, 0b11, opc, FPR64, FPR64, asm,
5799 [(set (v1i64 FPR64:$Rd), (OpNode (v1i64 FPR64:$Rn)))]>;
5800
5801 def : Pat<(i64 (OpNode (i64 FPR64:$Rn))),
5802 (!cast<Instruction>(NAME # "v1i64") FPR64:$Rn)>;
5803}
5804
Ahmed Bougacha81fda182015-08-04 01:38:08 +00005805multiclass SIMDFPTwoScalar<bit U, bit S, bits<5> opc, string asm> {
Tim Northover3b0846e2014-05-24 12:50:23 +00005806 def v1i64 : BaseSIMDTwoScalar<U, {S,1}, opc, FPR64, FPR64, asm,[]>;
5807 def v1i32 : BaseSIMDTwoScalar<U, {S,0}, opc, FPR32, FPR32, asm,[]>;
5808}
5809
5810multiclass SIMDTwoScalarCVTSD<bit U, bit S, bits<5> opc, string asm,
5811 SDPatternOperator OpNode> {
5812 def v1i64 : BaseSIMDTwoScalar<U, {S,1}, opc, FPR64, FPR64, asm,
5813 [(set FPR64:$Rd, (OpNode (f64 FPR64:$Rn)))]>;
5814 def v1i32 : BaseSIMDTwoScalar<U, {S,0}, opc, FPR32, FPR32, asm,
5815 [(set FPR32:$Rd, (OpNode (f32 FPR32:$Rn)))]>;
5816}
5817
5818multiclass SIMDTwoScalarBHSD<bit U, bits<5> opc, string asm,
5819 SDPatternOperator OpNode = null_frag> {
5820 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
5821 def v1i64 : BaseSIMDTwoScalar<U, 0b11, opc, FPR64, FPR64, asm,
5822 [(set (i64 FPR64:$Rd), (OpNode (i64 FPR64:$Rn)))]>;
5823 def v1i32 : BaseSIMDTwoScalar<U, 0b10, opc, FPR32, FPR32, asm,
5824 [(set (i32 FPR32:$Rd), (OpNode (i32 FPR32:$Rn)))]>;
5825 def v1i16 : BaseSIMDTwoScalar<U, 0b01, opc, FPR16, FPR16, asm, []>;
5826 def v1i8 : BaseSIMDTwoScalar<U, 0b00, opc, FPR8 , FPR8 , asm, []>;
5827 }
5828
5829 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rn))),
5830 (!cast<Instruction>(NAME # v1i64) FPR64:$Rn)>;
5831}
5832
5833multiclass SIMDTwoScalarBHSDTied<bit U, bits<5> opc, string asm,
5834 Intrinsic OpNode> {
5835 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
5836 def v1i64 : BaseSIMDTwoScalarTied<U, 0b11, opc, FPR64, FPR64, asm,
5837 [(set (i64 FPR64:$dst), (OpNode (i64 FPR64:$Rd), (i64 FPR64:$Rn)))]>;
5838 def v1i32 : BaseSIMDTwoScalarTied<U, 0b10, opc, FPR32, FPR32, asm,
5839 [(set (i32 FPR32:$dst), (OpNode (i32 FPR32:$Rd), (i32 FPR32:$Rn)))]>;
5840 def v1i16 : BaseSIMDTwoScalarTied<U, 0b01, opc, FPR16, FPR16, asm, []>;
5841 def v1i8 : BaseSIMDTwoScalarTied<U, 0b00, opc, FPR8 , FPR8 , asm, []>;
5842 }
5843
5844 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rd), (v1i64 FPR64:$Rn))),
5845 (!cast<Instruction>(NAME # v1i64) FPR64:$Rd, FPR64:$Rn)>;
5846}
5847
5848
5849
5850let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5851multiclass SIMDTwoScalarMixedBHS<bit U, bits<5> opc, string asm,
5852 SDPatternOperator OpNode = null_frag> {
5853 def v1i32 : BaseSIMDTwoScalar<U, 0b10, opc, FPR32, FPR64, asm,
5854 [(set (i32 FPR32:$Rd), (OpNode (i64 FPR64:$Rn)))]>;
5855 def v1i16 : BaseSIMDTwoScalar<U, 0b01, opc, FPR16, FPR32, asm, []>;
5856 def v1i8 : BaseSIMDTwoScalar<U, 0b00, opc, FPR8 , FPR16, asm, []>;
5857}
5858
5859//----------------------------------------------------------------------------
5860// AdvSIMD scalar pairwise instructions
5861//----------------------------------------------------------------------------
5862
5863let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5864class BaseSIMDPairwiseScalar<bit U, bits<2> size, bits<5> opcode,
5865 RegisterOperand regtype, RegisterOperand vectype,
5866 string asm, string kind>
5867 : I<(outs regtype:$Rd), (ins vectype:$Rn), asm,
5868 "{\t$Rd, $Rn" # kind # "|" # kind # "\t$Rd, $Rn}", "", []>,
5869 Sched<[WriteV]> {
5870 bits<5> Rd;
5871 bits<5> Rn;
5872 let Inst{31-30} = 0b01;
5873 let Inst{29} = U;
5874 let Inst{28-24} = 0b11110;
5875 let Inst{23-22} = size;
5876 let Inst{21-17} = 0b11000;
5877 let Inst{16-12} = opcode;
5878 let Inst{11-10} = 0b10;
5879 let Inst{9-5} = Rn;
5880 let Inst{4-0} = Rd;
5881}
5882
5883multiclass SIMDPairwiseScalarD<bit U, bits<5> opc, string asm> {
5884 def v2i64p : BaseSIMDPairwiseScalar<U, 0b11, opc, FPR64Op, V128,
5885 asm, ".2d">;
5886}
5887
Ahmed Bougacha81fda182015-08-04 01:38:08 +00005888multiclass SIMDFPPairwiseScalar<bit U, bit S, bits<5> opc, string asm> {
Tim Northover3b0846e2014-05-24 12:50:23 +00005889 def v2i32p : BaseSIMDPairwiseScalar<U, {S,0}, opc, FPR32Op, V64,
5890 asm, ".2s">;
5891 def v2i64p : BaseSIMDPairwiseScalar<U, {S,1}, opc, FPR64Op, V128,
5892 asm, ".2d">;
5893}
5894
5895//----------------------------------------------------------------------------
5896// AdvSIMD across lanes instructions
5897//----------------------------------------------------------------------------
5898
5899let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5900class BaseSIMDAcrossLanes<bit Q, bit U, bits<2> size, bits<5> opcode,
5901 RegisterClass regtype, RegisterOperand vectype,
5902 string asm, string kind, list<dag> pattern>
5903 : I<(outs regtype:$Rd), (ins vectype:$Rn), asm,
5904 "{\t$Rd, $Rn" # kind # "|" # kind # "\t$Rd, $Rn}", "", pattern>,
5905 Sched<[WriteV]> {
5906 bits<5> Rd;
5907 bits<5> Rn;
5908 let Inst{31} = 0;
5909 let Inst{30} = Q;
5910 let Inst{29} = U;
5911 let Inst{28-24} = 0b01110;
5912 let Inst{23-22} = size;
5913 let Inst{21-17} = 0b11000;
5914 let Inst{16-12} = opcode;
5915 let Inst{11-10} = 0b10;
5916 let Inst{9-5} = Rn;
5917 let Inst{4-0} = Rd;
5918}
5919
5920multiclass SIMDAcrossLanesBHS<bit U, bits<5> opcode,
5921 string asm> {
5922 def v8i8v : BaseSIMDAcrossLanes<0, U, 0b00, opcode, FPR8, V64,
5923 asm, ".8b", []>;
5924 def v16i8v : BaseSIMDAcrossLanes<1, U, 0b00, opcode, FPR8, V128,
5925 asm, ".16b", []>;
5926 def v4i16v : BaseSIMDAcrossLanes<0, U, 0b01, opcode, FPR16, V64,
5927 asm, ".4h", []>;
5928 def v8i16v : BaseSIMDAcrossLanes<1, U, 0b01, opcode, FPR16, V128,
5929 asm, ".8h", []>;
5930 def v4i32v : BaseSIMDAcrossLanes<1, U, 0b10, opcode, FPR32, V128,
5931 asm, ".4s", []>;
5932}
5933
5934multiclass SIMDAcrossLanesHSD<bit U, bits<5> opcode, string asm> {
5935 def v8i8v : BaseSIMDAcrossLanes<0, U, 0b00, opcode, FPR16, V64,
5936 asm, ".8b", []>;
5937 def v16i8v : BaseSIMDAcrossLanes<1, U, 0b00, opcode, FPR16, V128,
5938 asm, ".16b", []>;
5939 def v4i16v : BaseSIMDAcrossLanes<0, U, 0b01, opcode, FPR32, V64,
5940 asm, ".4h", []>;
5941 def v8i16v : BaseSIMDAcrossLanes<1, U, 0b01, opcode, FPR32, V128,
5942 asm, ".8h", []>;
5943 def v4i32v : BaseSIMDAcrossLanes<1, U, 0b10, opcode, FPR64, V128,
5944 asm, ".4s", []>;
5945}
5946
5947multiclass SIMDAcrossLanesS<bits<5> opcode, bit sz1, string asm,
5948 Intrinsic intOp> {
5949 def v4i32v : BaseSIMDAcrossLanes<1, 1, {sz1, 0}, opcode, FPR32, V128,
5950 asm, ".4s",
5951 [(set FPR32:$Rd, (intOp (v4f32 V128:$Rn)))]>;
5952}
5953
5954//----------------------------------------------------------------------------
5955// AdvSIMD INS/DUP instructions
5956//----------------------------------------------------------------------------
5957
5958// FIXME: There has got to be a better way to factor these. ugh.
5959
5960class BaseSIMDInsDup<bit Q, bit op, dag outs, dag ins, string asm,
5961 string operands, string constraints, list<dag> pattern>
5962 : I<outs, ins, asm, operands, constraints, pattern>,
5963 Sched<[WriteV]> {
5964 bits<5> Rd;
5965 bits<5> Rn;
5966 let Inst{31} = 0;
5967 let Inst{30} = Q;
5968 let Inst{29} = op;
5969 let Inst{28-21} = 0b01110000;
5970 let Inst{15} = 0;
5971 let Inst{10} = 1;
5972 let Inst{9-5} = Rn;
5973 let Inst{4-0} = Rd;
5974}
5975
5976class SIMDDupFromMain<bit Q, bits<5> imm5, string size, ValueType vectype,
5977 RegisterOperand vecreg, RegisterClass regtype>
5978 : BaseSIMDInsDup<Q, 0, (outs vecreg:$Rd), (ins regtype:$Rn), "dup",
5979 "{\t$Rd" # size # ", $Rn" #
5980 "|" # size # "\t$Rd, $Rn}", "",
5981 [(set (vectype vecreg:$Rd), (AArch64dup regtype:$Rn))]> {
5982 let Inst{20-16} = imm5;
5983 let Inst{14-11} = 0b0001;
5984}
5985
5986class SIMDDupFromElement<bit Q, string dstkind, string srckind,
5987 ValueType vectype, ValueType insreg,
5988 RegisterOperand vecreg, Operand idxtype,
5989 ValueType elttype, SDNode OpNode>
5990 : BaseSIMDInsDup<Q, 0, (outs vecreg:$Rd), (ins V128:$Rn, idxtype:$idx), "dup",
5991 "{\t$Rd" # dstkind # ", $Rn" # srckind # "$idx" #
5992 "|" # dstkind # "\t$Rd, $Rn$idx}", "",
5993 [(set (vectype vecreg:$Rd),
5994 (OpNode (insreg V128:$Rn), idxtype:$idx))]> {
5995 let Inst{14-11} = 0b0000;
5996}
5997
5998class SIMDDup64FromElement
5999 : SIMDDupFromElement<1, ".2d", ".d", v2i64, v2i64, V128,
6000 VectorIndexD, i64, AArch64duplane64> {
6001 bits<1> idx;
6002 let Inst{20} = idx;
6003 let Inst{19-16} = 0b1000;
6004}
6005
6006class SIMDDup32FromElement<bit Q, string size, ValueType vectype,
6007 RegisterOperand vecreg>
6008 : SIMDDupFromElement<Q, size, ".s", vectype, v4i32, vecreg,
6009 VectorIndexS, i64, AArch64duplane32> {
6010 bits<2> idx;
6011 let Inst{20-19} = idx;
6012 let Inst{18-16} = 0b100;
6013}
6014
6015class SIMDDup16FromElement<bit Q, string size, ValueType vectype,
6016 RegisterOperand vecreg>
6017 : SIMDDupFromElement<Q, size, ".h", vectype, v8i16, vecreg,
6018 VectorIndexH, i64, AArch64duplane16> {
6019 bits<3> idx;
6020 let Inst{20-18} = idx;
6021 let Inst{17-16} = 0b10;
6022}
6023
6024class SIMDDup8FromElement<bit Q, string size, ValueType vectype,
6025 RegisterOperand vecreg>
6026 : SIMDDupFromElement<Q, size, ".b", vectype, v16i8, vecreg,
6027 VectorIndexB, i64, AArch64duplane8> {
6028 bits<4> idx;
6029 let Inst{20-17} = idx;
6030 let Inst{16} = 1;
6031}
6032
6033class BaseSIMDMov<bit Q, string size, bits<4> imm4, RegisterClass regtype,
6034 Operand idxtype, string asm, list<dag> pattern>
6035 : BaseSIMDInsDup<Q, 0, (outs regtype:$Rd), (ins V128:$Rn, idxtype:$idx), asm,
6036 "{\t$Rd, $Rn" # size # "$idx" #
6037 "|" # size # "\t$Rd, $Rn$idx}", "", pattern> {
6038 let Inst{14-11} = imm4;
6039}
6040
6041class SIMDSMov<bit Q, string size, RegisterClass regtype,
6042 Operand idxtype>
6043 : BaseSIMDMov<Q, size, 0b0101, regtype, idxtype, "smov", []>;
6044class SIMDUMov<bit Q, string size, ValueType vectype, RegisterClass regtype,
6045 Operand idxtype>
6046 : BaseSIMDMov<Q, size, 0b0111, regtype, idxtype, "umov",
6047 [(set regtype:$Rd, (vector_extract (vectype V128:$Rn), idxtype:$idx))]>;
6048
6049class SIMDMovAlias<string asm, string size, Instruction inst,
6050 RegisterClass regtype, Operand idxtype>
6051 : InstAlias<asm#"{\t$dst, $src"#size#"$idx" #
6052 "|" # size # "\t$dst, $src$idx}",
6053 (inst regtype:$dst, V128:$src, idxtype:$idx)>;
6054
6055multiclass SMov {
6056 def vi8to32 : SIMDSMov<0, ".b", GPR32, VectorIndexB> {
6057 bits<4> idx;
6058 let Inst{20-17} = idx;
6059 let Inst{16} = 1;
6060 }
6061 def vi8to64 : SIMDSMov<1, ".b", GPR64, VectorIndexB> {
6062 bits<4> idx;
6063 let Inst{20-17} = idx;
6064 let Inst{16} = 1;
6065 }
6066 def vi16to32 : SIMDSMov<0, ".h", GPR32, VectorIndexH> {
6067 bits<3> idx;
6068 let Inst{20-18} = idx;
6069 let Inst{17-16} = 0b10;
6070 }
6071 def vi16to64 : SIMDSMov<1, ".h", GPR64, VectorIndexH> {
6072 bits<3> idx;
6073 let Inst{20-18} = idx;
6074 let Inst{17-16} = 0b10;
6075 }
6076 def vi32to64 : SIMDSMov<1, ".s", GPR64, VectorIndexS> {
6077 bits<2> idx;
6078 let Inst{20-19} = idx;
6079 let Inst{18-16} = 0b100;
6080 }
6081}
6082
6083multiclass UMov {
6084 def vi8 : SIMDUMov<0, ".b", v16i8, GPR32, VectorIndexB> {
6085 bits<4> idx;
6086 let Inst{20-17} = idx;
6087 let Inst{16} = 1;
6088 }
6089 def vi16 : SIMDUMov<0, ".h", v8i16, GPR32, VectorIndexH> {
6090 bits<3> idx;
6091 let Inst{20-18} = idx;
6092 let Inst{17-16} = 0b10;
6093 }
6094 def vi32 : SIMDUMov<0, ".s", v4i32, GPR32, VectorIndexS> {
6095 bits<2> idx;
6096 let Inst{20-19} = idx;
6097 let Inst{18-16} = 0b100;
6098 }
6099 def vi64 : SIMDUMov<1, ".d", v2i64, GPR64, VectorIndexD> {
6100 bits<1> idx;
6101 let Inst{20} = idx;
6102 let Inst{19-16} = 0b1000;
6103 }
6104 def : SIMDMovAlias<"mov", ".s",
6105 !cast<Instruction>(NAME#"vi32"),
6106 GPR32, VectorIndexS>;
6107 def : SIMDMovAlias<"mov", ".d",
6108 !cast<Instruction>(NAME#"vi64"),
6109 GPR64, VectorIndexD>;
6110}
6111
6112class SIMDInsFromMain<string size, ValueType vectype,
6113 RegisterClass regtype, Operand idxtype>
6114 : BaseSIMDInsDup<1, 0, (outs V128:$dst),
6115 (ins V128:$Rd, idxtype:$idx, regtype:$Rn), "ins",
6116 "{\t$Rd" # size # "$idx, $Rn" #
6117 "|" # size # "\t$Rd$idx, $Rn}",
6118 "$Rd = $dst",
6119 [(set V128:$dst,
6120 (vector_insert (vectype V128:$Rd), regtype:$Rn, idxtype:$idx))]> {
6121 let Inst{14-11} = 0b0011;
6122}
6123
6124class SIMDInsFromElement<string size, ValueType vectype,
6125 ValueType elttype, Operand idxtype>
6126 : BaseSIMDInsDup<1, 1, (outs V128:$dst),
6127 (ins V128:$Rd, idxtype:$idx, V128:$Rn, idxtype:$idx2), "ins",
6128 "{\t$Rd" # size # "$idx, $Rn" # size # "$idx2" #
6129 "|" # size # "\t$Rd$idx, $Rn$idx2}",
6130 "$Rd = $dst",
6131 [(set V128:$dst,
6132 (vector_insert
6133 (vectype V128:$Rd),
6134 (elttype (vector_extract (vectype V128:$Rn), idxtype:$idx2)),
6135 idxtype:$idx))]>;
6136
6137class SIMDInsMainMovAlias<string size, Instruction inst,
6138 RegisterClass regtype, Operand idxtype>
6139 : InstAlias<"mov" # "{\t$dst" # size # "$idx, $src" #
6140 "|" # size #"\t$dst$idx, $src}",
6141 (inst V128:$dst, idxtype:$idx, regtype:$src)>;
6142class SIMDInsElementMovAlias<string size, Instruction inst,
6143 Operand idxtype>
6144 : InstAlias<"mov" # "{\t$dst" # size # "$idx, $src" # size # "$idx2" #
Ahmed Bougachacca07712015-09-02 18:38:36 +00006145 # "|" # size #"\t$dst$idx, $src$idx2}",
Tim Northover3b0846e2014-05-24 12:50:23 +00006146 (inst V128:$dst, idxtype:$idx, V128:$src, idxtype:$idx2)>;
6147
6148
6149multiclass SIMDIns {
6150 def vi8gpr : SIMDInsFromMain<".b", v16i8, GPR32, VectorIndexB> {
6151 bits<4> idx;
6152 let Inst{20-17} = idx;
6153 let Inst{16} = 1;
6154 }
6155 def vi16gpr : SIMDInsFromMain<".h", v8i16, GPR32, VectorIndexH> {
6156 bits<3> idx;
6157 let Inst{20-18} = idx;
6158 let Inst{17-16} = 0b10;
6159 }
6160 def vi32gpr : SIMDInsFromMain<".s", v4i32, GPR32, VectorIndexS> {
6161 bits<2> idx;
6162 let Inst{20-19} = idx;
6163 let Inst{18-16} = 0b100;
6164 }
6165 def vi64gpr : SIMDInsFromMain<".d", v2i64, GPR64, VectorIndexD> {
6166 bits<1> idx;
6167 let Inst{20} = idx;
6168 let Inst{19-16} = 0b1000;
6169 }
6170
6171 def vi8lane : SIMDInsFromElement<".b", v16i8, i32, VectorIndexB> {
6172 bits<4> idx;
6173 bits<4> idx2;
6174 let Inst{20-17} = idx;
6175 let Inst{16} = 1;
6176 let Inst{14-11} = idx2;
6177 }
6178 def vi16lane : SIMDInsFromElement<".h", v8i16, i32, VectorIndexH> {
6179 bits<3> idx;
6180 bits<3> idx2;
6181 let Inst{20-18} = idx;
6182 let Inst{17-16} = 0b10;
6183 let Inst{14-12} = idx2;
Bradley Smithb9136532015-04-14 15:07:26 +00006184 let Inst{11} = {?};
Tim Northover3b0846e2014-05-24 12:50:23 +00006185 }
6186 def vi32lane : SIMDInsFromElement<".s", v4i32, i32, VectorIndexS> {
6187 bits<2> idx;
6188 bits<2> idx2;
6189 let Inst{20-19} = idx;
6190 let Inst{18-16} = 0b100;
6191 let Inst{14-13} = idx2;
Bradley Smithb9136532015-04-14 15:07:26 +00006192 let Inst{12-11} = {?,?};
Tim Northover3b0846e2014-05-24 12:50:23 +00006193 }
6194 def vi64lane : SIMDInsFromElement<".d", v2i64, i64, VectorIndexD> {
6195 bits<1> idx;
6196 bits<1> idx2;
6197 let Inst{20} = idx;
6198 let Inst{19-16} = 0b1000;
6199 let Inst{14} = idx2;
Bradley Smithb9136532015-04-14 15:07:26 +00006200 let Inst{13-11} = {?,?,?};
Tim Northover3b0846e2014-05-24 12:50:23 +00006201 }
6202
6203 // For all forms of the INS instruction, the "mov" mnemonic is the
6204 // preferred alias. Why they didn't just call the instruction "mov" in
6205 // the first place is a very good question indeed...
6206 def : SIMDInsMainMovAlias<".b", !cast<Instruction>(NAME#"vi8gpr"),
6207 GPR32, VectorIndexB>;
6208 def : SIMDInsMainMovAlias<".h", !cast<Instruction>(NAME#"vi16gpr"),
6209 GPR32, VectorIndexH>;
6210 def : SIMDInsMainMovAlias<".s", !cast<Instruction>(NAME#"vi32gpr"),
6211 GPR32, VectorIndexS>;
6212 def : SIMDInsMainMovAlias<".d", !cast<Instruction>(NAME#"vi64gpr"),
6213 GPR64, VectorIndexD>;
6214
6215 def : SIMDInsElementMovAlias<".b", !cast<Instruction>(NAME#"vi8lane"),
6216 VectorIndexB>;
6217 def : SIMDInsElementMovAlias<".h", !cast<Instruction>(NAME#"vi16lane"),
6218 VectorIndexH>;
6219 def : SIMDInsElementMovAlias<".s", !cast<Instruction>(NAME#"vi32lane"),
6220 VectorIndexS>;
6221 def : SIMDInsElementMovAlias<".d", !cast<Instruction>(NAME#"vi64lane"),
6222 VectorIndexD>;
6223}
6224
6225//----------------------------------------------------------------------------
6226// AdvSIMD TBL/TBX
6227//----------------------------------------------------------------------------
6228
6229let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
6230class BaseSIMDTableLookup<bit Q, bits<2> len, bit op, RegisterOperand vectype,
6231 RegisterOperand listtype, string asm, string kind>
6232 : I<(outs vectype:$Vd), (ins listtype:$Vn, vectype:$Vm), asm,
6233 "\t$Vd" # kind # ", $Vn, $Vm" # kind, "", []>,
6234 Sched<[WriteV]> {
6235 bits<5> Vd;
6236 bits<5> Vn;
6237 bits<5> Vm;
6238 let Inst{31} = 0;
6239 let Inst{30} = Q;
6240 let Inst{29-21} = 0b001110000;
6241 let Inst{20-16} = Vm;
6242 let Inst{15} = 0;
6243 let Inst{14-13} = len;
6244 let Inst{12} = op;
6245 let Inst{11-10} = 0b00;
6246 let Inst{9-5} = Vn;
6247 let Inst{4-0} = Vd;
6248}
6249
6250let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
6251class BaseSIMDTableLookupTied<bit Q, bits<2> len, bit op, RegisterOperand vectype,
6252 RegisterOperand listtype, string asm, string kind>
6253 : I<(outs vectype:$dst), (ins vectype:$Vd, listtype:$Vn, vectype:$Vm), asm,
6254 "\t$Vd" # kind # ", $Vn, $Vm" # kind, "$Vd = $dst", []>,
6255 Sched<[WriteV]> {
6256 bits<5> Vd;
6257 bits<5> Vn;
6258 bits<5> Vm;
6259 let Inst{31} = 0;
6260 let Inst{30} = Q;
6261 let Inst{29-21} = 0b001110000;
6262 let Inst{20-16} = Vm;
6263 let Inst{15} = 0;
6264 let Inst{14-13} = len;
6265 let Inst{12} = op;
6266 let Inst{11-10} = 0b00;
6267 let Inst{9-5} = Vn;
6268 let Inst{4-0} = Vd;
6269}
6270
6271class SIMDTableLookupAlias<string asm, Instruction inst,
6272 RegisterOperand vectype, RegisterOperand listtype>
6273 : InstAlias<!strconcat(asm, "\t$dst, $lst, $index"),
6274 (inst vectype:$dst, listtype:$lst, vectype:$index), 0>;
6275
6276multiclass SIMDTableLookup<bit op, string asm> {
6277 def v8i8One : BaseSIMDTableLookup<0, 0b00, op, V64, VecListOne16b,
6278 asm, ".8b">;
6279 def v8i8Two : BaseSIMDTableLookup<0, 0b01, op, V64, VecListTwo16b,
6280 asm, ".8b">;
6281 def v8i8Three : BaseSIMDTableLookup<0, 0b10, op, V64, VecListThree16b,
6282 asm, ".8b">;
6283 def v8i8Four : BaseSIMDTableLookup<0, 0b11, op, V64, VecListFour16b,
6284 asm, ".8b">;
6285 def v16i8One : BaseSIMDTableLookup<1, 0b00, op, V128, VecListOne16b,
6286 asm, ".16b">;
6287 def v16i8Two : BaseSIMDTableLookup<1, 0b01, op, V128, VecListTwo16b,
6288 asm, ".16b">;
6289 def v16i8Three: BaseSIMDTableLookup<1, 0b10, op, V128, VecListThree16b,
6290 asm, ".16b">;
6291 def v16i8Four : BaseSIMDTableLookup<1, 0b11, op, V128, VecListFour16b,
6292 asm, ".16b">;
6293
6294 def : SIMDTableLookupAlias<asm # ".8b",
6295 !cast<Instruction>(NAME#"v8i8One"),
6296 V64, VecListOne128>;
6297 def : SIMDTableLookupAlias<asm # ".8b",
6298 !cast<Instruction>(NAME#"v8i8Two"),
6299 V64, VecListTwo128>;
6300 def : SIMDTableLookupAlias<asm # ".8b",
6301 !cast<Instruction>(NAME#"v8i8Three"),
6302 V64, VecListThree128>;
6303 def : SIMDTableLookupAlias<asm # ".8b",
6304 !cast<Instruction>(NAME#"v8i8Four"),
6305 V64, VecListFour128>;
6306 def : SIMDTableLookupAlias<asm # ".16b",
6307 !cast<Instruction>(NAME#"v16i8One"),
6308 V128, VecListOne128>;
6309 def : SIMDTableLookupAlias<asm # ".16b",
6310 !cast<Instruction>(NAME#"v16i8Two"),
6311 V128, VecListTwo128>;
6312 def : SIMDTableLookupAlias<asm # ".16b",
6313 !cast<Instruction>(NAME#"v16i8Three"),
6314 V128, VecListThree128>;
6315 def : SIMDTableLookupAlias<asm # ".16b",
6316 !cast<Instruction>(NAME#"v16i8Four"),
6317 V128, VecListFour128>;
6318}
6319
6320multiclass SIMDTableLookupTied<bit op, string asm> {
6321 def v8i8One : BaseSIMDTableLookupTied<0, 0b00, op, V64, VecListOne16b,
6322 asm, ".8b">;
6323 def v8i8Two : BaseSIMDTableLookupTied<0, 0b01, op, V64, VecListTwo16b,
6324 asm, ".8b">;
6325 def v8i8Three : BaseSIMDTableLookupTied<0, 0b10, op, V64, VecListThree16b,
6326 asm, ".8b">;
6327 def v8i8Four : BaseSIMDTableLookupTied<0, 0b11, op, V64, VecListFour16b,
6328 asm, ".8b">;
6329 def v16i8One : BaseSIMDTableLookupTied<1, 0b00, op, V128, VecListOne16b,
6330 asm, ".16b">;
6331 def v16i8Two : BaseSIMDTableLookupTied<1, 0b01, op, V128, VecListTwo16b,
6332 asm, ".16b">;
6333 def v16i8Three: BaseSIMDTableLookupTied<1, 0b10, op, V128, VecListThree16b,
6334 asm, ".16b">;
6335 def v16i8Four : BaseSIMDTableLookupTied<1, 0b11, op, V128, VecListFour16b,
6336 asm, ".16b">;
6337
6338 def : SIMDTableLookupAlias<asm # ".8b",
6339 !cast<Instruction>(NAME#"v8i8One"),
6340 V64, VecListOne128>;
6341 def : SIMDTableLookupAlias<asm # ".8b",
6342 !cast<Instruction>(NAME#"v8i8Two"),
6343 V64, VecListTwo128>;
6344 def : SIMDTableLookupAlias<asm # ".8b",
6345 !cast<Instruction>(NAME#"v8i8Three"),
6346 V64, VecListThree128>;
6347 def : SIMDTableLookupAlias<asm # ".8b",
6348 !cast<Instruction>(NAME#"v8i8Four"),
6349 V64, VecListFour128>;
6350 def : SIMDTableLookupAlias<asm # ".16b",
6351 !cast<Instruction>(NAME#"v16i8One"),
6352 V128, VecListOne128>;
6353 def : SIMDTableLookupAlias<asm # ".16b",
6354 !cast<Instruction>(NAME#"v16i8Two"),
6355 V128, VecListTwo128>;
6356 def : SIMDTableLookupAlias<asm # ".16b",
6357 !cast<Instruction>(NAME#"v16i8Three"),
6358 V128, VecListThree128>;
6359 def : SIMDTableLookupAlias<asm # ".16b",
6360 !cast<Instruction>(NAME#"v16i8Four"),
6361 V128, VecListFour128>;
6362}
6363
6364
6365//----------------------------------------------------------------------------
6366// AdvSIMD scalar CPY
6367//----------------------------------------------------------------------------
6368let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
6369class BaseSIMDScalarCPY<RegisterClass regtype, RegisterOperand vectype,
6370 string kind, Operand idxtype>
6371 : I<(outs regtype:$dst), (ins vectype:$src, idxtype:$idx), "mov",
6372 "{\t$dst, $src" # kind # "$idx" #
6373 "|\t$dst, $src$idx}", "", []>,
6374 Sched<[WriteV]> {
6375 bits<5> dst;
6376 bits<5> src;
6377 let Inst{31-21} = 0b01011110000;
6378 let Inst{15-10} = 0b000001;
6379 let Inst{9-5} = src;
6380 let Inst{4-0} = dst;
6381}
6382
6383class SIMDScalarCPYAlias<string asm, string size, Instruction inst,
6384 RegisterClass regtype, RegisterOperand vectype, Operand idxtype>
6385 : InstAlias<asm # "{\t$dst, $src" # size # "$index" #
6386 # "|\t$dst, $src$index}",
6387 (inst regtype:$dst, vectype:$src, idxtype:$index), 0>;
6388
6389
6390multiclass SIMDScalarCPY<string asm> {
6391 def i8 : BaseSIMDScalarCPY<FPR8, V128, ".b", VectorIndexB> {
6392 bits<4> idx;
6393 let Inst{20-17} = idx;
6394 let Inst{16} = 1;
6395 }
6396 def i16 : BaseSIMDScalarCPY<FPR16, V128, ".h", VectorIndexH> {
6397 bits<3> idx;
6398 let Inst{20-18} = idx;
6399 let Inst{17-16} = 0b10;
6400 }
6401 def i32 : BaseSIMDScalarCPY<FPR32, V128, ".s", VectorIndexS> {
6402 bits<2> idx;
6403 let Inst{20-19} = idx;
6404 let Inst{18-16} = 0b100;
6405 }
6406 def i64 : BaseSIMDScalarCPY<FPR64, V128, ".d", VectorIndexD> {
6407 bits<1> idx;
6408 let Inst{20} = idx;
6409 let Inst{19-16} = 0b1000;
6410 }
6411
6412 def : Pat<(v1i64 (scalar_to_vector (i64 (vector_extract (v2i64 V128:$src),
6413 VectorIndexD:$idx)))),
6414 (!cast<Instruction>(NAME # i64) V128:$src, VectorIndexD:$idx)>;
6415
6416 // 'DUP' mnemonic aliases.
6417 def : SIMDScalarCPYAlias<"dup", ".b",
6418 !cast<Instruction>(NAME#"i8"),
6419 FPR8, V128, VectorIndexB>;
6420 def : SIMDScalarCPYAlias<"dup", ".h",
6421 !cast<Instruction>(NAME#"i16"),
6422 FPR16, V128, VectorIndexH>;
6423 def : SIMDScalarCPYAlias<"dup", ".s",
6424 !cast<Instruction>(NAME#"i32"),
6425 FPR32, V128, VectorIndexS>;
6426 def : SIMDScalarCPYAlias<"dup", ".d",
6427 !cast<Instruction>(NAME#"i64"),
6428 FPR64, V128, VectorIndexD>;
6429}
6430
6431//----------------------------------------------------------------------------
6432// AdvSIMD modified immediate instructions
6433//----------------------------------------------------------------------------
6434
6435class BaseSIMDModifiedImm<bit Q, bit op, dag oops, dag iops,
6436 string asm, string op_string,
6437 string cstr, list<dag> pattern>
6438 : I<oops, iops, asm, op_string, cstr, pattern>,
6439 Sched<[WriteV]> {
6440 bits<5> Rd;
6441 bits<8> imm8;
6442 let Inst{31} = 0;
6443 let Inst{30} = Q;
6444 let Inst{29} = op;
6445 let Inst{28-19} = 0b0111100000;
6446 let Inst{18-16} = imm8{7-5};
6447 let Inst{11-10} = 0b01;
6448 let Inst{9-5} = imm8{4-0};
6449 let Inst{4-0} = Rd;
6450}
6451
6452class BaseSIMDModifiedImmVector<bit Q, bit op, RegisterOperand vectype,
6453 Operand immtype, dag opt_shift_iop,
6454 string opt_shift, string asm, string kind,
6455 list<dag> pattern>
6456 : BaseSIMDModifiedImm<Q, op, (outs vectype:$Rd),
6457 !con((ins immtype:$imm8), opt_shift_iop), asm,
6458 "{\t$Rd" # kind # ", $imm8" # opt_shift #
6459 "|" # kind # "\t$Rd, $imm8" # opt_shift # "}",
6460 "", pattern> {
6461 let DecoderMethod = "DecodeModImmInstruction";
6462}
6463
6464class BaseSIMDModifiedImmVectorTied<bit Q, bit op, RegisterOperand vectype,
6465 Operand immtype, dag opt_shift_iop,
6466 string opt_shift, string asm, string kind,
6467 list<dag> pattern>
6468 : BaseSIMDModifiedImm<Q, op, (outs vectype:$dst),
6469 !con((ins vectype:$Rd, immtype:$imm8), opt_shift_iop),
6470 asm, "{\t$Rd" # kind # ", $imm8" # opt_shift #
6471 "|" # kind # "\t$Rd, $imm8" # opt_shift # "}",
6472 "$Rd = $dst", pattern> {
6473 let DecoderMethod = "DecodeModImmTiedInstruction";
6474}
6475
6476class BaseSIMDModifiedImmVectorShift<bit Q, bit op, bits<2> b15_b12,
6477 RegisterOperand vectype, string asm,
6478 string kind, list<dag> pattern>
6479 : BaseSIMDModifiedImmVector<Q, op, vectype, imm0_255,
6480 (ins logical_vec_shift:$shift),
6481 "$shift", asm, kind, pattern> {
6482 bits<2> shift;
6483 let Inst{15} = b15_b12{1};
6484 let Inst{14-13} = shift;
6485 let Inst{12} = b15_b12{0};
6486}
6487
6488class BaseSIMDModifiedImmVectorShiftTied<bit Q, bit op, bits<2> b15_b12,
6489 RegisterOperand vectype, string asm,
6490 string kind, list<dag> pattern>
6491 : BaseSIMDModifiedImmVectorTied<Q, op, vectype, imm0_255,
6492 (ins logical_vec_shift:$shift),
6493 "$shift", asm, kind, pattern> {
6494 bits<2> shift;
6495 let Inst{15} = b15_b12{1};
6496 let Inst{14-13} = shift;
6497 let Inst{12} = b15_b12{0};
6498}
6499
6500
6501class BaseSIMDModifiedImmVectorShiftHalf<bit Q, bit op, bits<2> b15_b12,
6502 RegisterOperand vectype, string asm,
6503 string kind, list<dag> pattern>
6504 : BaseSIMDModifiedImmVector<Q, op, vectype, imm0_255,
6505 (ins logical_vec_hw_shift:$shift),
6506 "$shift", asm, kind, pattern> {
6507 bits<2> shift;
6508 let Inst{15} = b15_b12{1};
6509 let Inst{14} = 0;
6510 let Inst{13} = shift{0};
6511 let Inst{12} = b15_b12{0};
6512}
6513
6514class BaseSIMDModifiedImmVectorShiftHalfTied<bit Q, bit op, bits<2> b15_b12,
6515 RegisterOperand vectype, string asm,
6516 string kind, list<dag> pattern>
6517 : BaseSIMDModifiedImmVectorTied<Q, op, vectype, imm0_255,
6518 (ins logical_vec_hw_shift:$shift),
6519 "$shift", asm, kind, pattern> {
6520 bits<2> shift;
6521 let Inst{15} = b15_b12{1};
6522 let Inst{14} = 0;
6523 let Inst{13} = shift{0};
6524 let Inst{12} = b15_b12{0};
6525}
6526
6527multiclass SIMDModifiedImmVectorShift<bit op, bits<2> hw_cmode, bits<2> w_cmode,
6528 string asm> {
6529 def v4i16 : BaseSIMDModifiedImmVectorShiftHalf<0, op, hw_cmode, V64,
6530 asm, ".4h", []>;
6531 def v8i16 : BaseSIMDModifiedImmVectorShiftHalf<1, op, hw_cmode, V128,
6532 asm, ".8h", []>;
6533
6534 def v2i32 : BaseSIMDModifiedImmVectorShift<0, op, w_cmode, V64,
6535 asm, ".2s", []>;
6536 def v4i32 : BaseSIMDModifiedImmVectorShift<1, op, w_cmode, V128,
6537 asm, ".4s", []>;
6538}
6539
6540multiclass SIMDModifiedImmVectorShiftTied<bit op, bits<2> hw_cmode,
6541 bits<2> w_cmode, string asm,
6542 SDNode OpNode> {
6543 def v4i16 : BaseSIMDModifiedImmVectorShiftHalfTied<0, op, hw_cmode, V64,
6544 asm, ".4h",
6545 [(set (v4i16 V64:$dst), (OpNode V64:$Rd,
6546 imm0_255:$imm8,
6547 (i32 imm:$shift)))]>;
6548 def v8i16 : BaseSIMDModifiedImmVectorShiftHalfTied<1, op, hw_cmode, V128,
6549 asm, ".8h",
6550 [(set (v8i16 V128:$dst), (OpNode V128:$Rd,
6551 imm0_255:$imm8,
6552 (i32 imm:$shift)))]>;
6553
6554 def v2i32 : BaseSIMDModifiedImmVectorShiftTied<0, op, w_cmode, V64,
6555 asm, ".2s",
6556 [(set (v2i32 V64:$dst), (OpNode V64:$Rd,
6557 imm0_255:$imm8,
6558 (i32 imm:$shift)))]>;
6559 def v4i32 : BaseSIMDModifiedImmVectorShiftTied<1, op, w_cmode, V128,
6560 asm, ".4s",
6561 [(set (v4i32 V128:$dst), (OpNode V128:$Rd,
6562 imm0_255:$imm8,
6563 (i32 imm:$shift)))]>;
6564}
6565
6566class SIMDModifiedImmMoveMSL<bit Q, bit op, bits<4> cmode,
6567 RegisterOperand vectype, string asm,
6568 string kind, list<dag> pattern>
6569 : BaseSIMDModifiedImmVector<Q, op, vectype, imm0_255,
6570 (ins move_vec_shift:$shift),
6571 "$shift", asm, kind, pattern> {
6572 bits<1> shift;
6573 let Inst{15-13} = cmode{3-1};
6574 let Inst{12} = shift;
6575}
6576
6577class SIMDModifiedImmVectorNoShift<bit Q, bit op, bits<4> cmode,
6578 RegisterOperand vectype,
6579 Operand imm_type, string asm,
6580 string kind, list<dag> pattern>
6581 : BaseSIMDModifiedImmVector<Q, op, vectype, imm_type, (ins), "",
6582 asm, kind, pattern> {
6583 let Inst{15-12} = cmode;
6584}
6585
6586class SIMDModifiedImmScalarNoShift<bit Q, bit op, bits<4> cmode, string asm,
6587 list<dag> pattern>
6588 : BaseSIMDModifiedImm<Q, op, (outs FPR64:$Rd), (ins simdimmtype10:$imm8), asm,
6589 "\t$Rd, $imm8", "", pattern> {
6590 let Inst{15-12} = cmode;
6591 let DecoderMethod = "DecodeModImmInstruction";
6592}
6593
6594//----------------------------------------------------------------------------
6595// AdvSIMD indexed element
6596//----------------------------------------------------------------------------
6597
6598let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
6599class BaseSIMDIndexed<bit Q, bit U, bit Scalar, bits<2> size, bits<4> opc,
6600 RegisterOperand dst_reg, RegisterOperand lhs_reg,
6601 RegisterOperand rhs_reg, Operand vec_idx, string asm,
6602 string apple_kind, string dst_kind, string lhs_kind,
6603 string rhs_kind, list<dag> pattern>
6604 : I<(outs dst_reg:$Rd), (ins lhs_reg:$Rn, rhs_reg:$Rm, vec_idx:$idx),
6605 asm,
6606 "{\t$Rd" # dst_kind # ", $Rn" # lhs_kind # ", $Rm" # rhs_kind # "$idx" #
6607 "|" # apple_kind # "\t$Rd, $Rn, $Rm$idx}", "", pattern>,
6608 Sched<[WriteV]> {
6609 bits<5> Rd;
6610 bits<5> Rn;
6611 bits<5> Rm;
6612
6613 let Inst{31} = 0;
6614 let Inst{30} = Q;
6615 let Inst{29} = U;
6616 let Inst{28} = Scalar;
6617 let Inst{27-24} = 0b1111;
6618 let Inst{23-22} = size;
6619 // Bit 21 must be set by the derived class.
6620 let Inst{20-16} = Rm;
6621 let Inst{15-12} = opc;
6622 // Bit 11 must be set by the derived class.
6623 let Inst{10} = 0;
6624 let Inst{9-5} = Rn;
6625 let Inst{4-0} = Rd;
6626}
6627
6628let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
6629class BaseSIMDIndexedTied<bit Q, bit U, bit Scalar, bits<2> size, bits<4> opc,
6630 RegisterOperand dst_reg, RegisterOperand lhs_reg,
6631 RegisterOperand rhs_reg, Operand vec_idx, string asm,
6632 string apple_kind, string dst_kind, string lhs_kind,
6633 string rhs_kind, list<dag> pattern>
6634 : I<(outs dst_reg:$dst),
6635 (ins dst_reg:$Rd, lhs_reg:$Rn, rhs_reg:$Rm, vec_idx:$idx), asm,
6636 "{\t$Rd" # dst_kind # ", $Rn" # lhs_kind # ", $Rm" # rhs_kind # "$idx" #
6637 "|" # apple_kind # "\t$Rd, $Rn, $Rm$idx}", "$Rd = $dst", pattern>,
6638 Sched<[WriteV]> {
6639 bits<5> Rd;
6640 bits<5> Rn;
6641 bits<5> Rm;
6642
6643 let Inst{31} = 0;
6644 let Inst{30} = Q;
6645 let Inst{29} = U;
6646 let Inst{28} = Scalar;
6647 let Inst{27-24} = 0b1111;
6648 let Inst{23-22} = size;
6649 // Bit 21 must be set by the derived class.
6650 let Inst{20-16} = Rm;
6651 let Inst{15-12} = opc;
6652 // Bit 11 must be set by the derived class.
6653 let Inst{10} = 0;
6654 let Inst{9-5} = Rn;
6655 let Inst{4-0} = Rd;
6656}
6657
Ahmed Bougacha81fda182015-08-04 01:38:08 +00006658multiclass SIMDFPIndexed<bit U, bits<4> opc, string asm,
6659 SDPatternOperator OpNode> {
Tim Northover3b0846e2014-05-24 12:50:23 +00006660 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc,
6661 V64, V64,
6662 V128, VectorIndexS,
6663 asm, ".2s", ".2s", ".2s", ".s",
6664 [(set (v2f32 V64:$Rd),
6665 (OpNode (v2f32 V64:$Rn),
6666 (v2f32 (AArch64duplane32 (v4f32 V128:$Rm), VectorIndexS:$idx))))]> {
6667 bits<2> idx;
6668 let Inst{11} = idx{1};
6669 let Inst{21} = idx{0};
6670 }
6671
6672 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc,
6673 V128, V128,
6674 V128, VectorIndexS,
6675 asm, ".4s", ".4s", ".4s", ".s",
6676 [(set (v4f32 V128:$Rd),
6677 (OpNode (v4f32 V128:$Rn),
6678 (v4f32 (AArch64duplane32 (v4f32 V128:$Rm), VectorIndexS:$idx))))]> {
6679 bits<2> idx;
6680 let Inst{11} = idx{1};
6681 let Inst{21} = idx{0};
6682 }
6683
6684 def v2i64_indexed : BaseSIMDIndexed<1, U, 0, 0b11, opc,
6685 V128, V128,
6686 V128, VectorIndexD,
6687 asm, ".2d", ".2d", ".2d", ".d",
6688 [(set (v2f64 V128:$Rd),
6689 (OpNode (v2f64 V128:$Rn),
6690 (v2f64 (AArch64duplane64 (v2f64 V128:$Rm), VectorIndexD:$idx))))]> {
6691 bits<1> idx;
6692 let Inst{11} = idx{0};
6693 let Inst{21} = 0;
6694 }
6695
6696 def v1i32_indexed : BaseSIMDIndexed<1, U, 1, 0b10, opc,
6697 FPR32Op, FPR32Op, V128, VectorIndexS,
6698 asm, ".s", "", "", ".s",
6699 [(set (f32 FPR32Op:$Rd),
6700 (OpNode (f32 FPR32Op:$Rn),
6701 (f32 (vector_extract (v4f32 V128:$Rm),
6702 VectorIndexS:$idx))))]> {
6703 bits<2> idx;
6704 let Inst{11} = idx{1};
6705 let Inst{21} = idx{0};
6706 }
6707
6708 def v1i64_indexed : BaseSIMDIndexed<1, U, 1, 0b11, opc,
6709 FPR64Op, FPR64Op, V128, VectorIndexD,
6710 asm, ".d", "", "", ".d",
6711 [(set (f64 FPR64Op:$Rd),
6712 (OpNode (f64 FPR64Op:$Rn),
6713 (f64 (vector_extract (v2f64 V128:$Rm),
6714 VectorIndexD:$idx))))]> {
6715 bits<1> idx;
6716 let Inst{11} = idx{0};
6717 let Inst{21} = 0;
6718 }
6719}
6720
Ahmed Bougacha81fda182015-08-04 01:38:08 +00006721multiclass SIMDFPIndexedTiedPatterns<string INST, SDPatternOperator OpNode> {
Tim Northover3b0846e2014-05-24 12:50:23 +00006722 // 2 variants for the .2s version: DUPLANE from 128-bit and DUP scalar.
6723 def : Pat<(v2f32 (OpNode (v2f32 V64:$Rd), (v2f32 V64:$Rn),
6724 (AArch64duplane32 (v4f32 V128:$Rm),
6725 VectorIndexS:$idx))),
6726 (!cast<Instruction>(INST # v2i32_indexed)
6727 V64:$Rd, V64:$Rn, V128:$Rm, VectorIndexS:$idx)>;
6728 def : Pat<(v2f32 (OpNode (v2f32 V64:$Rd), (v2f32 V64:$Rn),
6729 (AArch64dup (f32 FPR32Op:$Rm)))),
6730 (!cast<Instruction>(INST # "v2i32_indexed") V64:$Rd, V64:$Rn,
6731 (SUBREG_TO_REG (i32 0), FPR32Op:$Rm, ssub), (i64 0))>;
6732
6733
6734 // 2 variants for the .4s version: DUPLANE from 128-bit and DUP scalar.
6735 def : Pat<(v4f32 (OpNode (v4f32 V128:$Rd), (v4f32 V128:$Rn),
6736 (AArch64duplane32 (v4f32 V128:$Rm),
6737 VectorIndexS:$idx))),
6738 (!cast<Instruction>(INST # "v4i32_indexed")
6739 V128:$Rd, V128:$Rn, V128:$Rm, VectorIndexS:$idx)>;
6740 def : Pat<(v4f32 (OpNode (v4f32 V128:$Rd), (v4f32 V128:$Rn),
6741 (AArch64dup (f32 FPR32Op:$Rm)))),
6742 (!cast<Instruction>(INST # "v4i32_indexed") V128:$Rd, V128:$Rn,
6743 (SUBREG_TO_REG (i32 0), FPR32Op:$Rm, ssub), (i64 0))>;
6744
6745 // 2 variants for the .2d version: DUPLANE from 128-bit and DUP scalar.
6746 def : Pat<(v2f64 (OpNode (v2f64 V128:$Rd), (v2f64 V128:$Rn),
6747 (AArch64duplane64 (v2f64 V128:$Rm),
6748 VectorIndexD:$idx))),
6749 (!cast<Instruction>(INST # "v2i64_indexed")
6750 V128:$Rd, V128:$Rn, V128:$Rm, VectorIndexS:$idx)>;
6751 def : Pat<(v2f64 (OpNode (v2f64 V128:$Rd), (v2f64 V128:$Rn),
6752 (AArch64dup (f64 FPR64Op:$Rm)))),
6753 (!cast<Instruction>(INST # "v2i64_indexed") V128:$Rd, V128:$Rn,
6754 (SUBREG_TO_REG (i32 0), FPR64Op:$Rm, dsub), (i64 0))>;
6755
6756 // 2 variants for 32-bit scalar version: extract from .2s or from .4s
6757 def : Pat<(f32 (OpNode (f32 FPR32:$Rd), (f32 FPR32:$Rn),
6758 (vector_extract (v4f32 V128:$Rm), VectorIndexS:$idx))),
6759 (!cast<Instruction>(INST # "v1i32_indexed") FPR32:$Rd, FPR32:$Rn,
6760 V128:$Rm, VectorIndexS:$idx)>;
6761 def : Pat<(f32 (OpNode (f32 FPR32:$Rd), (f32 FPR32:$Rn),
6762 (vector_extract (v2f32 V64:$Rm), VectorIndexS:$idx))),
6763 (!cast<Instruction>(INST # "v1i32_indexed") FPR32:$Rd, FPR32:$Rn,
6764 (SUBREG_TO_REG (i32 0), V64:$Rm, dsub), VectorIndexS:$idx)>;
6765
6766 // 1 variant for 64-bit scalar version: extract from .1d or from .2d
6767 def : Pat<(f64 (OpNode (f64 FPR64:$Rd), (f64 FPR64:$Rn),
6768 (vector_extract (v2f64 V128:$Rm), VectorIndexD:$idx))),
6769 (!cast<Instruction>(INST # "v1i64_indexed") FPR64:$Rd, FPR64:$Rn,
6770 V128:$Rm, VectorIndexD:$idx)>;
6771}
6772
Ahmed Bougacha81fda182015-08-04 01:38:08 +00006773multiclass SIMDFPIndexedTied<bit U, bits<4> opc, string asm> {
Tim Northover3b0846e2014-05-24 12:50:23 +00006774 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc, V64, V64,
6775 V128, VectorIndexS,
6776 asm, ".2s", ".2s", ".2s", ".s", []> {
6777 bits<2> idx;
6778 let Inst{11} = idx{1};
6779 let Inst{21} = idx{0};
6780 }
6781
6782 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc,
6783 V128, V128,
6784 V128, VectorIndexS,
6785 asm, ".4s", ".4s", ".4s", ".s", []> {
6786 bits<2> idx;
6787 let Inst{11} = idx{1};
6788 let Inst{21} = idx{0};
6789 }
6790
6791 def v2i64_indexed : BaseSIMDIndexedTied<1, U, 0, 0b11, opc,
6792 V128, V128,
6793 V128, VectorIndexD,
6794 asm, ".2d", ".2d", ".2d", ".d", []> {
6795 bits<1> idx;
6796 let Inst{11} = idx{0};
6797 let Inst{21} = 0;
6798 }
6799
6800
6801 def v1i32_indexed : BaseSIMDIndexedTied<1, U, 1, 0b10, opc,
6802 FPR32Op, FPR32Op, V128, VectorIndexS,
6803 asm, ".s", "", "", ".s", []> {
6804 bits<2> idx;
6805 let Inst{11} = idx{1};
6806 let Inst{21} = idx{0};
6807 }
6808
6809 def v1i64_indexed : BaseSIMDIndexedTied<1, U, 1, 0b11, opc,
6810 FPR64Op, FPR64Op, V128, VectorIndexD,
6811 asm, ".d", "", "", ".d", []> {
6812 bits<1> idx;
6813 let Inst{11} = idx{0};
6814 let Inst{21} = 0;
6815 }
6816}
6817
6818multiclass SIMDIndexedHS<bit U, bits<4> opc, string asm,
6819 SDPatternOperator OpNode> {
6820 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc, V64, V64,
6821 V128_lo, VectorIndexH,
6822 asm, ".4h", ".4h", ".4h", ".h",
6823 [(set (v4i16 V64:$Rd),
6824 (OpNode (v4i16 V64:$Rn),
6825 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
6826 bits<3> idx;
6827 let Inst{11} = idx{2};
6828 let Inst{21} = idx{1};
6829 let Inst{20} = idx{0};
6830 }
6831
6832 def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc,
6833 V128, V128,
6834 V128_lo, VectorIndexH,
6835 asm, ".8h", ".8h", ".8h", ".h",
6836 [(set (v8i16 V128:$Rd),
6837 (OpNode (v8i16 V128:$Rn),
6838 (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
6839 bits<3> idx;
6840 let Inst{11} = idx{2};
6841 let Inst{21} = idx{1};
6842 let Inst{20} = idx{0};
6843 }
6844
6845 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc,
6846 V64, V64,
6847 V128, VectorIndexS,
6848 asm, ".2s", ".2s", ".2s", ".s",
6849 [(set (v2i32 V64:$Rd),
6850 (OpNode (v2i32 V64:$Rn),
6851 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
6852 bits<2> idx;
6853 let Inst{11} = idx{1};
6854 let Inst{21} = idx{0};
6855 }
6856
6857 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc,
6858 V128, V128,
6859 V128, VectorIndexS,
6860 asm, ".4s", ".4s", ".4s", ".s",
6861 [(set (v4i32 V128:$Rd),
6862 (OpNode (v4i32 V128:$Rn),
6863 (v4i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
6864 bits<2> idx;
6865 let Inst{11} = idx{1};
6866 let Inst{21} = idx{0};
6867 }
6868
6869 def v1i16_indexed : BaseSIMDIndexed<1, U, 1, 0b01, opc,
6870 FPR16Op, FPR16Op, V128_lo, VectorIndexH,
6871 asm, ".h", "", "", ".h", []> {
6872 bits<3> idx;
6873 let Inst{11} = idx{2};
6874 let Inst{21} = idx{1};
6875 let Inst{20} = idx{0};
6876 }
6877
6878 def v1i32_indexed : BaseSIMDIndexed<1, U, 1, 0b10, opc,
6879 FPR32Op, FPR32Op, V128, VectorIndexS,
6880 asm, ".s", "", "", ".s",
6881 [(set (i32 FPR32Op:$Rd),
6882 (OpNode FPR32Op:$Rn,
6883 (i32 (vector_extract (v4i32 V128:$Rm),
6884 VectorIndexS:$idx))))]> {
6885 bits<2> idx;
6886 let Inst{11} = idx{1};
6887 let Inst{21} = idx{0};
6888 }
6889}
6890
6891multiclass SIMDVectorIndexedHS<bit U, bits<4> opc, string asm,
6892 SDPatternOperator OpNode> {
6893 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc,
6894 V64, V64,
6895 V128_lo, VectorIndexH,
6896 asm, ".4h", ".4h", ".4h", ".h",
6897 [(set (v4i16 V64:$Rd),
6898 (OpNode (v4i16 V64:$Rn),
6899 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
6900 bits<3> idx;
6901 let Inst{11} = idx{2};
6902 let Inst{21} = idx{1};
6903 let Inst{20} = idx{0};
6904 }
6905
6906 def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc,
6907 V128, V128,
6908 V128_lo, VectorIndexH,
6909 asm, ".8h", ".8h", ".8h", ".h",
6910 [(set (v8i16 V128:$Rd),
6911 (OpNode (v8i16 V128:$Rn),
6912 (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
6913 bits<3> idx;
6914 let Inst{11} = idx{2};
6915 let Inst{21} = idx{1};
6916 let Inst{20} = idx{0};
6917 }
6918
6919 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc,
6920 V64, V64,
6921 V128, VectorIndexS,
6922 asm, ".2s", ".2s", ".2s", ".s",
6923 [(set (v2i32 V64:$Rd),
6924 (OpNode (v2i32 V64:$Rn),
6925 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
6926 bits<2> idx;
6927 let Inst{11} = idx{1};
6928 let Inst{21} = idx{0};
6929 }
6930
6931 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc,
6932 V128, V128,
6933 V128, VectorIndexS,
6934 asm, ".4s", ".4s", ".4s", ".s",
6935 [(set (v4i32 V128:$Rd),
6936 (OpNode (v4i32 V128:$Rn),
6937 (v4i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
6938 bits<2> idx;
6939 let Inst{11} = idx{1};
6940 let Inst{21} = idx{0};
6941 }
6942}
6943
6944multiclass SIMDVectorIndexedHSTied<bit U, bits<4> opc, string asm,
6945 SDPatternOperator OpNode> {
6946 def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc, V64, V64,
6947 V128_lo, VectorIndexH,
6948 asm, ".4h", ".4h", ".4h", ".h",
6949 [(set (v4i16 V64:$dst),
6950 (OpNode (v4i16 V64:$Rd),(v4i16 V64:$Rn),
6951 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
6952 bits<3> idx;
6953 let Inst{11} = idx{2};
6954 let Inst{21} = idx{1};
6955 let Inst{20} = idx{0};
6956 }
6957
6958 def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc,
6959 V128, V128,
6960 V128_lo, VectorIndexH,
6961 asm, ".8h", ".8h", ".8h", ".h",
6962 [(set (v8i16 V128:$dst),
6963 (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn),
6964 (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
6965 bits<3> idx;
6966 let Inst{11} = idx{2};
6967 let Inst{21} = idx{1};
6968 let Inst{20} = idx{0};
6969 }
6970
6971 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc,
6972 V64, V64,
6973 V128, VectorIndexS,
6974 asm, ".2s", ".2s", ".2s", ".s",
6975 [(set (v2i32 V64:$dst),
6976 (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn),
6977 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
6978 bits<2> idx;
6979 let Inst{11} = idx{1};
6980 let Inst{21} = idx{0};
6981 }
6982
6983 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc,
6984 V128, V128,
6985 V128, VectorIndexS,
6986 asm, ".4s", ".4s", ".4s", ".s",
6987 [(set (v4i32 V128:$dst),
6988 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn),
6989 (v4i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
6990 bits<2> idx;
6991 let Inst{11} = idx{1};
6992 let Inst{21} = idx{0};
6993 }
6994}
6995
6996multiclass SIMDIndexedLongSD<bit U, bits<4> opc, string asm,
6997 SDPatternOperator OpNode> {
6998 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc,
6999 V128, V64,
7000 V128_lo, VectorIndexH,
7001 asm, ".4s", ".4s", ".4h", ".h",
7002 [(set (v4i32 V128:$Rd),
7003 (OpNode (v4i16 V64:$Rn),
7004 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
7005 bits<3> idx;
7006 let Inst{11} = idx{2};
7007 let Inst{21} = idx{1};
7008 let Inst{20} = idx{0};
7009 }
7010
7011 def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc,
7012 V128, V128,
7013 V128_lo, VectorIndexH,
7014 asm#"2", ".4s", ".4s", ".8h", ".h",
7015 [(set (v4i32 V128:$Rd),
7016 (OpNode (extract_high_v8i16 V128:$Rn),
7017 (extract_high_v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm),
7018 VectorIndexH:$idx))))]> {
7019
7020 bits<3> idx;
7021 let Inst{11} = idx{2};
7022 let Inst{21} = idx{1};
7023 let Inst{20} = idx{0};
7024 }
7025
7026 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc,
7027 V128, V64,
7028 V128, VectorIndexS,
7029 asm, ".2d", ".2d", ".2s", ".s",
7030 [(set (v2i64 V128:$Rd),
7031 (OpNode (v2i32 V64:$Rn),
7032 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
7033 bits<2> idx;
7034 let Inst{11} = idx{1};
7035 let Inst{21} = idx{0};
7036 }
7037
7038 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc,
7039 V128, V128,
7040 V128, VectorIndexS,
7041 asm#"2", ".2d", ".2d", ".4s", ".s",
7042 [(set (v2i64 V128:$Rd),
7043 (OpNode (extract_high_v4i32 V128:$Rn),
7044 (extract_high_v4i32 (AArch64duplane32 (v4i32 V128:$Rm),
7045 VectorIndexS:$idx))))]> {
7046 bits<2> idx;
7047 let Inst{11} = idx{1};
7048 let Inst{21} = idx{0};
7049 }
7050
7051 def v1i32_indexed : BaseSIMDIndexed<1, U, 1, 0b01, opc,
7052 FPR32Op, FPR16Op, V128_lo, VectorIndexH,
7053 asm, ".h", "", "", ".h", []> {
7054 bits<3> idx;
7055 let Inst{11} = idx{2};
7056 let Inst{21} = idx{1};
7057 let Inst{20} = idx{0};
7058 }
7059
7060 def v1i64_indexed : BaseSIMDIndexed<1, U, 1, 0b10, opc,
7061 FPR64Op, FPR32Op, V128, VectorIndexS,
7062 asm, ".s", "", "", ".s", []> {
7063 bits<2> idx;
7064 let Inst{11} = idx{1};
7065 let Inst{21} = idx{0};
7066 }
7067}
7068
7069multiclass SIMDIndexedLongSQDMLXSDTied<bit U, bits<4> opc, string asm,
7070 SDPatternOperator Accum> {
7071 def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc,
7072 V128, V64,
7073 V128_lo, VectorIndexH,
7074 asm, ".4s", ".4s", ".4h", ".h",
7075 [(set (v4i32 V128:$dst),
7076 (Accum (v4i32 V128:$Rd),
7077 (v4i32 (int_aarch64_neon_sqdmull
7078 (v4i16 V64:$Rn),
7079 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm),
7080 VectorIndexH:$idx))))))]> {
7081 bits<3> idx;
7082 let Inst{11} = idx{2};
7083 let Inst{21} = idx{1};
7084 let Inst{20} = idx{0};
7085 }
7086
7087 // FIXME: it would be nice to use the scalar (v1i32) instruction here, but an
7088 // intermediate EXTRACT_SUBREG would be untyped.
7089 def : Pat<(i32 (Accum (i32 FPR32Op:$Rd),
7090 (i32 (vector_extract (v4i32
7091 (int_aarch64_neon_sqdmull (v4i16 V64:$Rn),
7092 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm),
7093 VectorIndexH:$idx)))),
7094 (i64 0))))),
7095 (EXTRACT_SUBREG
7096 (!cast<Instruction>(NAME # v4i16_indexed)
7097 (SUBREG_TO_REG (i32 0), FPR32Op:$Rd, ssub), V64:$Rn,
7098 V128_lo:$Rm, VectorIndexH:$idx),
7099 ssub)>;
7100
7101 def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc,
7102 V128, V128,
7103 V128_lo, VectorIndexH,
7104 asm#"2", ".4s", ".4s", ".8h", ".h",
7105 [(set (v4i32 V128:$dst),
7106 (Accum (v4i32 V128:$Rd),
7107 (v4i32 (int_aarch64_neon_sqdmull
7108 (extract_high_v8i16 V128:$Rn),
7109 (extract_high_v8i16
7110 (AArch64duplane16 (v8i16 V128_lo:$Rm),
7111 VectorIndexH:$idx))))))]> {
7112 bits<3> idx;
7113 let Inst{11} = idx{2};
7114 let Inst{21} = idx{1};
7115 let Inst{20} = idx{0};
7116 }
7117
7118 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc,
7119 V128, V64,
7120 V128, VectorIndexS,
7121 asm, ".2d", ".2d", ".2s", ".s",
7122 [(set (v2i64 V128:$dst),
7123 (Accum (v2i64 V128:$Rd),
7124 (v2i64 (int_aarch64_neon_sqdmull
7125 (v2i32 V64:$Rn),
7126 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm),
7127 VectorIndexS:$idx))))))]> {
7128 bits<2> idx;
7129 let Inst{11} = idx{1};
7130 let Inst{21} = idx{0};
7131 }
7132
7133 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc,
7134 V128, V128,
7135 V128, VectorIndexS,
7136 asm#"2", ".2d", ".2d", ".4s", ".s",
7137 [(set (v2i64 V128:$dst),
7138 (Accum (v2i64 V128:$Rd),
7139 (v2i64 (int_aarch64_neon_sqdmull
7140 (extract_high_v4i32 V128:$Rn),
7141 (extract_high_v4i32
7142 (AArch64duplane32 (v4i32 V128:$Rm),
7143 VectorIndexS:$idx))))))]> {
7144 bits<2> idx;
7145 let Inst{11} = idx{1};
7146 let Inst{21} = idx{0};
7147 }
7148
7149 def v1i32_indexed : BaseSIMDIndexedTied<1, U, 1, 0b01, opc,
7150 FPR32Op, FPR16Op, V128_lo, VectorIndexH,
7151 asm, ".h", "", "", ".h", []> {
7152 bits<3> idx;
7153 let Inst{11} = idx{2};
7154 let Inst{21} = idx{1};
7155 let Inst{20} = idx{0};
7156 }
7157
7158
7159 def v1i64_indexed : BaseSIMDIndexedTied<1, U, 1, 0b10, opc,
7160 FPR64Op, FPR32Op, V128, VectorIndexS,
7161 asm, ".s", "", "", ".s",
7162 [(set (i64 FPR64Op:$dst),
7163 (Accum (i64 FPR64Op:$Rd),
7164 (i64 (int_aarch64_neon_sqdmulls_scalar
7165 (i32 FPR32Op:$Rn),
7166 (i32 (vector_extract (v4i32 V128:$Rm),
7167 VectorIndexS:$idx))))))]> {
7168
7169 bits<2> idx;
7170 let Inst{11} = idx{1};
7171 let Inst{21} = idx{0};
7172 }
7173}
7174
7175multiclass SIMDVectorIndexedLongSD<bit U, bits<4> opc, string asm,
7176 SDPatternOperator OpNode> {
7177 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
7178 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc,
7179 V128, V64,
7180 V128_lo, VectorIndexH,
7181 asm, ".4s", ".4s", ".4h", ".h",
7182 [(set (v4i32 V128:$Rd),
7183 (OpNode (v4i16 V64:$Rn),
7184 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
7185 bits<3> idx;
7186 let Inst{11} = idx{2};
7187 let Inst{21} = idx{1};
7188 let Inst{20} = idx{0};
7189 }
7190
7191 def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc,
7192 V128, V128,
7193 V128_lo, VectorIndexH,
7194 asm#"2", ".4s", ".4s", ".8h", ".h",
7195 [(set (v4i32 V128:$Rd),
7196 (OpNode (extract_high_v8i16 V128:$Rn),
7197 (extract_high_v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm),
7198 VectorIndexH:$idx))))]> {
7199
7200 bits<3> idx;
7201 let Inst{11} = idx{2};
7202 let Inst{21} = idx{1};
7203 let Inst{20} = idx{0};
7204 }
7205
7206 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc,
7207 V128, V64,
7208 V128, VectorIndexS,
7209 asm, ".2d", ".2d", ".2s", ".s",
7210 [(set (v2i64 V128:$Rd),
7211 (OpNode (v2i32 V64:$Rn),
7212 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
7213 bits<2> idx;
7214 let Inst{11} = idx{1};
7215 let Inst{21} = idx{0};
7216 }
7217
7218 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc,
7219 V128, V128,
7220 V128, VectorIndexS,
7221 asm#"2", ".2d", ".2d", ".4s", ".s",
7222 [(set (v2i64 V128:$Rd),
7223 (OpNode (extract_high_v4i32 V128:$Rn),
7224 (extract_high_v4i32 (AArch64duplane32 (v4i32 V128:$Rm),
7225 VectorIndexS:$idx))))]> {
7226 bits<2> idx;
7227 let Inst{11} = idx{1};
7228 let Inst{21} = idx{0};
7229 }
7230 }
7231}
7232
7233multiclass SIMDVectorIndexedLongSDTied<bit U, bits<4> opc, string asm,
7234 SDPatternOperator OpNode> {
7235 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
7236 def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc,
7237 V128, V64,
7238 V128_lo, VectorIndexH,
7239 asm, ".4s", ".4s", ".4h", ".h",
7240 [(set (v4i32 V128:$dst),
7241 (OpNode (v4i32 V128:$Rd), (v4i16 V64:$Rn),
7242 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
7243 bits<3> idx;
7244 let Inst{11} = idx{2};
7245 let Inst{21} = idx{1};
7246 let Inst{20} = idx{0};
7247 }
7248
7249 def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc,
7250 V128, V128,
7251 V128_lo, VectorIndexH,
7252 asm#"2", ".4s", ".4s", ".8h", ".h",
7253 [(set (v4i32 V128:$dst),
7254 (OpNode (v4i32 V128:$Rd),
7255 (extract_high_v8i16 V128:$Rn),
7256 (extract_high_v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm),
7257 VectorIndexH:$idx))))]> {
7258 bits<3> idx;
7259 let Inst{11} = idx{2};
7260 let Inst{21} = idx{1};
7261 let Inst{20} = idx{0};
7262 }
7263
7264 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc,
7265 V128, V64,
7266 V128, VectorIndexS,
7267 asm, ".2d", ".2d", ".2s", ".s",
7268 [(set (v2i64 V128:$dst),
7269 (OpNode (v2i64 V128:$Rd), (v2i32 V64:$Rn),
7270 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
7271 bits<2> idx;
7272 let Inst{11} = idx{1};
7273 let Inst{21} = idx{0};
7274 }
7275
7276 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc,
7277 V128, V128,
7278 V128, VectorIndexS,
7279 asm#"2", ".2d", ".2d", ".4s", ".s",
7280 [(set (v2i64 V128:$dst),
7281 (OpNode (v2i64 V128:$Rd),
7282 (extract_high_v4i32 V128:$Rn),
7283 (extract_high_v4i32 (AArch64duplane32 (v4i32 V128:$Rm),
7284 VectorIndexS:$idx))))]> {
7285 bits<2> idx;
7286 let Inst{11} = idx{1};
7287 let Inst{21} = idx{0};
7288 }
7289 }
7290}
7291
7292//----------------------------------------------------------------------------
7293// AdvSIMD scalar shift by immediate
7294//----------------------------------------------------------------------------
7295
7296let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
7297class BaseSIMDScalarShift<bit U, bits<5> opc, bits<7> fixed_imm,
7298 RegisterClass regtype1, RegisterClass regtype2,
7299 Operand immtype, string asm, list<dag> pattern>
7300 : I<(outs regtype1:$Rd), (ins regtype2:$Rn, immtype:$imm),
7301 asm, "\t$Rd, $Rn, $imm", "", pattern>,
7302 Sched<[WriteV]> {
7303 bits<5> Rd;
7304 bits<5> Rn;
7305 bits<7> imm;
7306 let Inst{31-30} = 0b01;
7307 let Inst{29} = U;
7308 let Inst{28-23} = 0b111110;
7309 let Inst{22-16} = fixed_imm;
7310 let Inst{15-11} = opc;
7311 let Inst{10} = 1;
7312 let Inst{9-5} = Rn;
7313 let Inst{4-0} = Rd;
7314}
7315
7316let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
7317class BaseSIMDScalarShiftTied<bit U, bits<5> opc, bits<7> fixed_imm,
7318 RegisterClass regtype1, RegisterClass regtype2,
7319 Operand immtype, string asm, list<dag> pattern>
7320 : I<(outs regtype1:$dst), (ins regtype1:$Rd, regtype2:$Rn, immtype:$imm),
7321 asm, "\t$Rd, $Rn, $imm", "$Rd = $dst", pattern>,
7322 Sched<[WriteV]> {
7323 bits<5> Rd;
7324 bits<5> Rn;
7325 bits<7> imm;
7326 let Inst{31-30} = 0b01;
7327 let Inst{29} = U;
7328 let Inst{28-23} = 0b111110;
7329 let Inst{22-16} = fixed_imm;
7330 let Inst{15-11} = opc;
7331 let Inst{10} = 1;
7332 let Inst{9-5} = Rn;
7333 let Inst{4-0} = Rd;
7334}
7335
7336
7337multiclass SIMDScalarRShiftSD<bit U, bits<5> opc, string asm> {
7338 def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?},
7339 FPR32, FPR32, vecshiftR32, asm, []> {
7340 let Inst{20-16} = imm{4-0};
7341 }
7342
7343 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?},
7344 FPR64, FPR64, vecshiftR64, asm, []> {
7345 let Inst{21-16} = imm{5-0};
7346 }
7347}
7348
7349multiclass SIMDScalarRShiftD<bit U, bits<5> opc, string asm,
7350 SDPatternOperator OpNode> {
7351 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?},
7352 FPR64, FPR64, vecshiftR64, asm,
7353 [(set (i64 FPR64:$Rd),
7354 (OpNode (i64 FPR64:$Rn), (i32 vecshiftR64:$imm)))]> {
7355 let Inst{21-16} = imm{5-0};
7356 }
7357
7358 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rn), (i32 vecshiftR64:$imm))),
7359 (!cast<Instruction>(NAME # "d") FPR64:$Rn, vecshiftR64:$imm)>;
7360}
7361
7362multiclass SIMDScalarRShiftDTied<bit U, bits<5> opc, string asm,
7363 SDPatternOperator OpNode = null_frag> {
7364 def d : BaseSIMDScalarShiftTied<U, opc, {1,?,?,?,?,?,?},
7365 FPR64, FPR64, vecshiftR64, asm,
7366 [(set (i64 FPR64:$dst), (OpNode (i64 FPR64:$Rd), (i64 FPR64:$Rn),
7367 (i32 vecshiftR64:$imm)))]> {
7368 let Inst{21-16} = imm{5-0};
7369 }
7370
7371 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rd), (v1i64 FPR64:$Rn),
7372 (i32 vecshiftR64:$imm))),
7373 (!cast<Instruction>(NAME # "d") FPR64:$Rd, FPR64:$Rn,
7374 vecshiftR64:$imm)>;
7375}
7376
7377multiclass SIMDScalarLShiftD<bit U, bits<5> opc, string asm,
7378 SDPatternOperator OpNode> {
7379 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?},
7380 FPR64, FPR64, vecshiftL64, asm,
7381 [(set (v1i64 FPR64:$Rd),
7382 (OpNode (v1i64 FPR64:$Rn), (i32 vecshiftL64:$imm)))]> {
7383 let Inst{21-16} = imm{5-0};
7384 }
7385}
7386
7387let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
7388multiclass SIMDScalarLShiftDTied<bit U, bits<5> opc, string asm> {
7389 def d : BaseSIMDScalarShiftTied<U, opc, {1,?,?,?,?,?,?},
7390 FPR64, FPR64, vecshiftL64, asm, []> {
7391 let Inst{21-16} = imm{5-0};
7392 }
7393}
7394
7395let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
7396multiclass SIMDScalarRShiftBHS<bit U, bits<5> opc, string asm,
7397 SDPatternOperator OpNode = null_frag> {
7398 def b : BaseSIMDScalarShift<U, opc, {0,0,0,1,?,?,?},
7399 FPR8, FPR16, vecshiftR8, asm, []> {
7400 let Inst{18-16} = imm{2-0};
7401 }
7402
7403 def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?},
7404 FPR16, FPR32, vecshiftR16, asm, []> {
7405 let Inst{19-16} = imm{3-0};
7406 }
7407
7408 def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?},
7409 FPR32, FPR64, vecshiftR32, asm,
7410 [(set (i32 FPR32:$Rd), (OpNode (i64 FPR64:$Rn), vecshiftR32:$imm))]> {
7411 let Inst{20-16} = imm{4-0};
7412 }
7413}
7414
7415multiclass SIMDScalarLShiftBHSD<bit U, bits<5> opc, string asm,
7416 SDPatternOperator OpNode> {
7417 def b : BaseSIMDScalarShift<U, opc, {0,0,0,1,?,?,?},
7418 FPR8, FPR8, vecshiftL8, asm, []> {
7419 let Inst{18-16} = imm{2-0};
7420 }
7421
7422 def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?},
7423 FPR16, FPR16, vecshiftL16, asm, []> {
7424 let Inst{19-16} = imm{3-0};
7425 }
7426
7427 def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?},
7428 FPR32, FPR32, vecshiftL32, asm,
7429 [(set (i32 FPR32:$Rd), (OpNode (i32 FPR32:$Rn), (i32 vecshiftL32:$imm)))]> {
7430 let Inst{20-16} = imm{4-0};
7431 }
7432
7433 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?},
7434 FPR64, FPR64, vecshiftL64, asm,
7435 [(set (i64 FPR64:$Rd), (OpNode (i64 FPR64:$Rn), (i32 vecshiftL64:$imm)))]> {
7436 let Inst{21-16} = imm{5-0};
7437 }
7438
7439 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rn), (i32 vecshiftL64:$imm))),
7440 (!cast<Instruction>(NAME # "d") FPR64:$Rn, vecshiftL64:$imm)>;
7441}
7442
7443multiclass SIMDScalarRShiftBHSD<bit U, bits<5> opc, string asm> {
7444 def b : BaseSIMDScalarShift<U, opc, {0,0,0,1,?,?,?},
7445 FPR8, FPR8, vecshiftR8, asm, []> {
7446 let Inst{18-16} = imm{2-0};
7447 }
7448
7449 def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?},
7450 FPR16, FPR16, vecshiftR16, asm, []> {
7451 let Inst{19-16} = imm{3-0};
7452 }
7453
7454 def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?},
7455 FPR32, FPR32, vecshiftR32, asm, []> {
7456 let Inst{20-16} = imm{4-0};
7457 }
7458
7459 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?},
7460 FPR64, FPR64, vecshiftR64, asm, []> {
7461 let Inst{21-16} = imm{5-0};
7462 }
7463}
7464
7465//----------------------------------------------------------------------------
7466// AdvSIMD vector x indexed element
7467//----------------------------------------------------------------------------
7468
7469let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
7470class BaseSIMDVectorShift<bit Q, bit U, bits<5> opc, bits<7> fixed_imm,
7471 RegisterOperand dst_reg, RegisterOperand src_reg,
7472 Operand immtype,
7473 string asm, string dst_kind, string src_kind,
7474 list<dag> pattern>
7475 : I<(outs dst_reg:$Rd), (ins src_reg:$Rn, immtype:$imm),
7476 asm, "{\t$Rd" # dst_kind # ", $Rn" # src_kind # ", $imm" #
7477 "|" # dst_kind # "\t$Rd, $Rn, $imm}", "", pattern>,
7478 Sched<[WriteV]> {
7479 bits<5> Rd;
7480 bits<5> Rn;
7481 let Inst{31} = 0;
7482 let Inst{30} = Q;
7483 let Inst{29} = U;
7484 let Inst{28-23} = 0b011110;
7485 let Inst{22-16} = fixed_imm;
7486 let Inst{15-11} = opc;
7487 let Inst{10} = 1;
7488 let Inst{9-5} = Rn;
7489 let Inst{4-0} = Rd;
7490}
7491
7492let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
7493class BaseSIMDVectorShiftTied<bit Q, bit U, bits<5> opc, bits<7> fixed_imm,
7494 RegisterOperand vectype1, RegisterOperand vectype2,
7495 Operand immtype,
7496 string asm, string dst_kind, string src_kind,
7497 list<dag> pattern>
7498 : I<(outs vectype1:$dst), (ins vectype1:$Rd, vectype2:$Rn, immtype:$imm),
7499 asm, "{\t$Rd" # dst_kind # ", $Rn" # src_kind # ", $imm" #
7500 "|" # dst_kind # "\t$Rd, $Rn, $imm}", "$Rd = $dst", pattern>,
7501 Sched<[WriteV]> {
7502 bits<5> Rd;
7503 bits<5> Rn;
7504 let Inst{31} = 0;
7505 let Inst{30} = Q;
7506 let Inst{29} = U;
7507 let Inst{28-23} = 0b011110;
7508 let Inst{22-16} = fixed_imm;
7509 let Inst{15-11} = opc;
7510 let Inst{10} = 1;
7511 let Inst{9-5} = Rn;
7512 let Inst{4-0} = Rd;
7513}
7514
7515multiclass SIMDVectorRShiftSD<bit U, bits<5> opc, string asm,
7516 Intrinsic OpNode> {
7517 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?},
7518 V64, V64, vecshiftR32,
7519 asm, ".2s", ".2s",
7520 [(set (v2i32 V64:$Rd), (OpNode (v2f32 V64:$Rn), (i32 imm:$imm)))]> {
7521 bits<5> imm;
7522 let Inst{20-16} = imm;
7523 }
7524
7525 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?},
7526 V128, V128, vecshiftR32,
7527 asm, ".4s", ".4s",
7528 [(set (v4i32 V128:$Rd), (OpNode (v4f32 V128:$Rn), (i32 imm:$imm)))]> {
7529 bits<5> imm;
7530 let Inst{20-16} = imm;
7531 }
7532
7533 def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?},
7534 V128, V128, vecshiftR64,
7535 asm, ".2d", ".2d",
7536 [(set (v2i64 V128:$Rd), (OpNode (v2f64 V128:$Rn), (i32 imm:$imm)))]> {
7537 bits<6> imm;
7538 let Inst{21-16} = imm;
7539 }
7540}
7541
7542multiclass SIMDVectorRShiftSDToFP<bit U, bits<5> opc, string asm,
7543 Intrinsic OpNode> {
7544 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?},
7545 V64, V64, vecshiftR32,
7546 asm, ".2s", ".2s",
7547 [(set (v2f32 V64:$Rd), (OpNode (v2i32 V64:$Rn), (i32 imm:$imm)))]> {
7548 bits<5> imm;
7549 let Inst{20-16} = imm;
7550 }
7551
7552 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?},
7553 V128, V128, vecshiftR32,
7554 asm, ".4s", ".4s",
7555 [(set (v4f32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (i32 imm:$imm)))]> {
7556 bits<5> imm;
7557 let Inst{20-16} = imm;
7558 }
7559
7560 def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?},
7561 V128, V128, vecshiftR64,
7562 asm, ".2d", ".2d",
7563 [(set (v2f64 V128:$Rd), (OpNode (v2i64 V128:$Rn), (i32 imm:$imm)))]> {
7564 bits<6> imm;
7565 let Inst{21-16} = imm;
7566 }
7567}
7568
7569multiclass SIMDVectorRShiftNarrowBHS<bit U, bits<5> opc, string asm,
7570 SDPatternOperator OpNode> {
7571 def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?},
7572 V64, V128, vecshiftR16Narrow,
7573 asm, ".8b", ".8h",
7574 [(set (v8i8 V64:$Rd), (OpNode (v8i16 V128:$Rn), vecshiftR16Narrow:$imm))]> {
7575 bits<3> imm;
7576 let Inst{18-16} = imm;
7577 }
7578
7579 def v16i8_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,0,1,?,?,?},
7580 V128, V128, vecshiftR16Narrow,
7581 asm#"2", ".16b", ".8h", []> {
7582 bits<3> imm;
7583 let Inst{18-16} = imm;
7584 let hasSideEffects = 0;
7585 }
7586
7587 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?},
7588 V64, V128, vecshiftR32Narrow,
7589 asm, ".4h", ".4s",
7590 [(set (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn), vecshiftR32Narrow:$imm))]> {
7591 bits<4> imm;
7592 let Inst{19-16} = imm;
7593 }
7594
7595 def v8i16_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,1,?,?,?,?},
7596 V128, V128, vecshiftR32Narrow,
7597 asm#"2", ".8h", ".4s", []> {
7598 bits<4> imm;
7599 let Inst{19-16} = imm;
7600 let hasSideEffects = 0;
7601 }
7602
7603 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?},
7604 V64, V128, vecshiftR64Narrow,
7605 asm, ".2s", ".2d",
7606 [(set (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn), vecshiftR64Narrow:$imm))]> {
7607 bits<5> imm;
7608 let Inst{20-16} = imm;
7609 }
7610
7611 def v4i32_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,1,?,?,?,?,?},
7612 V128, V128, vecshiftR64Narrow,
7613 asm#"2", ".4s", ".2d", []> {
7614 bits<5> imm;
7615 let Inst{20-16} = imm;
7616 let hasSideEffects = 0;
7617 }
7618
7619 // TableGen doesn't like patters w/ INSERT_SUBREG on the instructions
7620 // themselves, so put them here instead.
7621
7622 // Patterns involving what's effectively an insert high and a normal
7623 // intrinsic, represented by CONCAT_VECTORS.
7624 def : Pat<(concat_vectors (v8i8 V64:$Rd),(OpNode (v8i16 V128:$Rn),
7625 vecshiftR16Narrow:$imm)),
7626 (!cast<Instruction>(NAME # "v16i8_shift")
7627 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub),
7628 V128:$Rn, vecshiftR16Narrow:$imm)>;
7629 def : Pat<(concat_vectors (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn),
7630 vecshiftR32Narrow:$imm)),
7631 (!cast<Instruction>(NAME # "v8i16_shift")
7632 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub),
7633 V128:$Rn, vecshiftR32Narrow:$imm)>;
7634 def : Pat<(concat_vectors (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn),
7635 vecshiftR64Narrow:$imm)),
7636 (!cast<Instruction>(NAME # "v4i32_shift")
7637 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub),
7638 V128:$Rn, vecshiftR64Narrow:$imm)>;
7639}
7640
7641multiclass SIMDVectorLShiftBHSD<bit U, bits<5> opc, string asm,
7642 SDPatternOperator OpNode> {
7643 def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?},
7644 V64, V64, vecshiftL8,
7645 asm, ".8b", ".8b",
7646 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn),
7647 (i32 vecshiftL8:$imm)))]> {
7648 bits<3> imm;
7649 let Inst{18-16} = imm;
7650 }
7651
7652 def v16i8_shift : BaseSIMDVectorShift<1, U, opc, {0,0,0,1,?,?,?},
7653 V128, V128, vecshiftL8,
7654 asm, ".16b", ".16b",
7655 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn),
7656 (i32 vecshiftL8:$imm)))]> {
7657 bits<3> imm;
7658 let Inst{18-16} = imm;
7659 }
7660
7661 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?},
7662 V64, V64, vecshiftL16,
7663 asm, ".4h", ".4h",
7664 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn),
7665 (i32 vecshiftL16:$imm)))]> {
7666 bits<4> imm;
7667 let Inst{19-16} = imm;
7668 }
7669
7670 def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?},
7671 V128, V128, vecshiftL16,
7672 asm, ".8h", ".8h",
7673 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn),
7674 (i32 vecshiftL16:$imm)))]> {
7675 bits<4> imm;
7676 let Inst{19-16} = imm;
7677 }
7678
7679 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?},
7680 V64, V64, vecshiftL32,
7681 asm, ".2s", ".2s",
7682 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn),
7683 (i32 vecshiftL32:$imm)))]> {
7684 bits<5> imm;
7685 let Inst{20-16} = imm;
7686 }
7687
7688 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?},
7689 V128, V128, vecshiftL32,
7690 asm, ".4s", ".4s",
7691 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn),
7692 (i32 vecshiftL32:$imm)))]> {
7693 bits<5> imm;
7694 let Inst{20-16} = imm;
7695 }
7696
7697 def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?},
7698 V128, V128, vecshiftL64,
7699 asm, ".2d", ".2d",
7700 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn),
7701 (i32 vecshiftL64:$imm)))]> {
7702 bits<6> imm;
7703 let Inst{21-16} = imm;
7704 }
7705}
7706
7707multiclass SIMDVectorRShiftBHSD<bit U, bits<5> opc, string asm,
7708 SDPatternOperator OpNode> {
7709 def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?},
7710 V64, V64, vecshiftR8,
7711 asm, ".8b", ".8b",
7712 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn),
7713 (i32 vecshiftR8:$imm)))]> {
7714 bits<3> imm;
7715 let Inst{18-16} = imm;
7716 }
7717
7718 def v16i8_shift : BaseSIMDVectorShift<1, U, opc, {0,0,0,1,?,?,?},
7719 V128, V128, vecshiftR8,
7720 asm, ".16b", ".16b",
7721 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn),
7722 (i32 vecshiftR8:$imm)))]> {
7723 bits<3> imm;
7724 let Inst{18-16} = imm;
7725 }
7726
7727 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?},
7728 V64, V64, vecshiftR16,
7729 asm, ".4h", ".4h",
7730 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn),
7731 (i32 vecshiftR16:$imm)))]> {
7732 bits<4> imm;
7733 let Inst{19-16} = imm;
7734 }
7735
7736 def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?},
7737 V128, V128, vecshiftR16,
7738 asm, ".8h", ".8h",
7739 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn),
7740 (i32 vecshiftR16:$imm)))]> {
7741 bits<4> imm;
7742 let Inst{19-16} = imm;
7743 }
7744
7745 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?},
7746 V64, V64, vecshiftR32,
7747 asm, ".2s", ".2s",
7748 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn),
7749 (i32 vecshiftR32:$imm)))]> {
7750 bits<5> imm;
7751 let Inst{20-16} = imm;
7752 }
7753
7754 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?},
7755 V128, V128, vecshiftR32,
7756 asm, ".4s", ".4s",
7757 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn),
7758 (i32 vecshiftR32:$imm)))]> {
7759 bits<5> imm;
7760 let Inst{20-16} = imm;
7761 }
7762
7763 def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?},
7764 V128, V128, vecshiftR64,
7765 asm, ".2d", ".2d",
7766 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn),
7767 (i32 vecshiftR64:$imm)))]> {
7768 bits<6> imm;
7769 let Inst{21-16} = imm;
7770 }
7771}
7772
7773let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
7774multiclass SIMDVectorRShiftBHSDTied<bit U, bits<5> opc, string asm,
7775 SDPatternOperator OpNode = null_frag> {
7776 def v8i8_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,0,1,?,?,?},
7777 V64, V64, vecshiftR8, asm, ".8b", ".8b",
7778 [(set (v8i8 V64:$dst),
7779 (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn),
7780 (i32 vecshiftR8:$imm)))]> {
7781 bits<3> imm;
7782 let Inst{18-16} = imm;
7783 }
7784
7785 def v16i8_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,0,1,?,?,?},
7786 V128, V128, vecshiftR8, asm, ".16b", ".16b",
7787 [(set (v16i8 V128:$dst),
7788 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn),
7789 (i32 vecshiftR8:$imm)))]> {
7790 bits<3> imm;
7791 let Inst{18-16} = imm;
7792 }
7793
7794 def v4i16_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,1,?,?,?,?},
7795 V64, V64, vecshiftR16, asm, ".4h", ".4h",
7796 [(set (v4i16 V64:$dst),
7797 (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn),
7798 (i32 vecshiftR16:$imm)))]> {
7799 bits<4> imm;
7800 let Inst{19-16} = imm;
7801 }
7802
7803 def v8i16_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,1,?,?,?,?},
7804 V128, V128, vecshiftR16, asm, ".8h", ".8h",
7805 [(set (v8i16 V128:$dst),
7806 (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn),
7807 (i32 vecshiftR16:$imm)))]> {
7808 bits<4> imm;
7809 let Inst{19-16} = imm;
7810 }
7811
7812 def v2i32_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,1,?,?,?,?,?},
7813 V64, V64, vecshiftR32, asm, ".2s", ".2s",
7814 [(set (v2i32 V64:$dst),
7815 (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn),
7816 (i32 vecshiftR32:$imm)))]> {
7817 bits<5> imm;
7818 let Inst{20-16} = imm;
7819 }
7820
7821 def v4i32_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,1,?,?,?,?,?},
7822 V128, V128, vecshiftR32, asm, ".4s", ".4s",
7823 [(set (v4i32 V128:$dst),
7824 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn),
7825 (i32 vecshiftR32:$imm)))]> {
7826 bits<5> imm;
7827 let Inst{20-16} = imm;
7828 }
7829
7830 def v2i64_shift : BaseSIMDVectorShiftTied<1, U, opc, {1,?,?,?,?,?,?},
7831 V128, V128, vecshiftR64,
7832 asm, ".2d", ".2d", [(set (v2i64 V128:$dst),
7833 (OpNode (v2i64 V128:$Rd), (v2i64 V128:$Rn),
7834 (i32 vecshiftR64:$imm)))]> {
7835 bits<6> imm;
7836 let Inst{21-16} = imm;
7837 }
7838}
7839
7840multiclass SIMDVectorLShiftBHSDTied<bit U, bits<5> opc, string asm,
7841 SDPatternOperator OpNode = null_frag> {
7842 def v8i8_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,0,1,?,?,?},
7843 V64, V64, vecshiftL8,
7844 asm, ".8b", ".8b",
7845 [(set (v8i8 V64:$dst),
7846 (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn),
7847 (i32 vecshiftL8:$imm)))]> {
7848 bits<3> imm;
7849 let Inst{18-16} = imm;
7850 }
7851
7852 def v16i8_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,0,1,?,?,?},
7853 V128, V128, vecshiftL8,
7854 asm, ".16b", ".16b",
7855 [(set (v16i8 V128:$dst),
7856 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn),
7857 (i32 vecshiftL8:$imm)))]> {
7858 bits<3> imm;
7859 let Inst{18-16} = imm;
7860 }
7861
7862 def v4i16_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,1,?,?,?,?},
7863 V64, V64, vecshiftL16,
7864 asm, ".4h", ".4h",
7865 [(set (v4i16 V64:$dst),
7866 (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn),
7867 (i32 vecshiftL16:$imm)))]> {
7868 bits<4> imm;
7869 let Inst{19-16} = imm;
7870 }
7871
7872 def v8i16_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,1,?,?,?,?},
7873 V128, V128, vecshiftL16,
7874 asm, ".8h", ".8h",
7875 [(set (v8i16 V128:$dst),
7876 (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn),
7877 (i32 vecshiftL16:$imm)))]> {
7878 bits<4> imm;
7879 let Inst{19-16} = imm;
7880 }
7881
7882 def v2i32_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,1,?,?,?,?,?},
7883 V64, V64, vecshiftL32,
7884 asm, ".2s", ".2s",
7885 [(set (v2i32 V64:$dst),
7886 (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn),
7887 (i32 vecshiftL32:$imm)))]> {
7888 bits<5> imm;
7889 let Inst{20-16} = imm;
7890 }
7891
7892 def v4i32_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,1,?,?,?,?,?},
7893 V128, V128, vecshiftL32,
7894 asm, ".4s", ".4s",
7895 [(set (v4i32 V128:$dst),
7896 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn),
7897 (i32 vecshiftL32:$imm)))]> {
7898 bits<5> imm;
7899 let Inst{20-16} = imm;
7900 }
7901
7902 def v2i64_shift : BaseSIMDVectorShiftTied<1, U, opc, {1,?,?,?,?,?,?},
7903 V128, V128, vecshiftL64,
7904 asm, ".2d", ".2d",
7905 [(set (v2i64 V128:$dst),
7906 (OpNode (v2i64 V128:$Rd), (v2i64 V128:$Rn),
7907 (i32 vecshiftL64:$imm)))]> {
7908 bits<6> imm;
7909 let Inst{21-16} = imm;
7910 }
7911}
7912
7913multiclass SIMDVectorLShiftLongBHSD<bit U, bits<5> opc, string asm,
7914 SDPatternOperator OpNode> {
7915 def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?},
7916 V128, V64, vecshiftL8, asm, ".8h", ".8b",
7917 [(set (v8i16 V128:$Rd), (OpNode (v8i8 V64:$Rn), vecshiftL8:$imm))]> {
7918 bits<3> imm;
7919 let Inst{18-16} = imm;
7920 }
7921
7922 def v16i8_shift : BaseSIMDVectorShift<1, U, opc, {0,0,0,1,?,?,?},
7923 V128, V128, vecshiftL8,
7924 asm#"2", ".8h", ".16b",
7925 [(set (v8i16 V128:$Rd),
7926 (OpNode (extract_high_v16i8 V128:$Rn), vecshiftL8:$imm))]> {
7927 bits<3> imm;
7928 let Inst{18-16} = imm;
7929 }
7930
7931 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?},
7932 V128, V64, vecshiftL16, asm, ".4s", ".4h",
7933 [(set (v4i32 V128:$Rd), (OpNode (v4i16 V64:$Rn), vecshiftL16:$imm))]> {
7934 bits<4> imm;
7935 let Inst{19-16} = imm;
7936 }
7937
7938 def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?},
7939 V128, V128, vecshiftL16,
7940 asm#"2", ".4s", ".8h",
7941 [(set (v4i32 V128:$Rd),
7942 (OpNode (extract_high_v8i16 V128:$Rn), vecshiftL16:$imm))]> {
7943
7944 bits<4> imm;
7945 let Inst{19-16} = imm;
7946 }
7947
7948 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?},
7949 V128, V64, vecshiftL32, asm, ".2d", ".2s",
7950 [(set (v2i64 V128:$Rd), (OpNode (v2i32 V64:$Rn), vecshiftL32:$imm))]> {
7951 bits<5> imm;
7952 let Inst{20-16} = imm;
7953 }
7954
7955 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?},
7956 V128, V128, vecshiftL32,
7957 asm#"2", ".2d", ".4s",
7958 [(set (v2i64 V128:$Rd),
7959 (OpNode (extract_high_v4i32 V128:$Rn), vecshiftL32:$imm))]> {
7960 bits<5> imm;
7961 let Inst{20-16} = imm;
7962 }
7963}
7964
7965
7966//---
7967// Vector load/store
7968//---
7969// SIMD ldX/stX no-index memory references don't allow the optional
7970// ", #0" constant and handle post-indexing explicitly, so we use
7971// a more specialized parse method for them. Otherwise, it's the same as
7972// the general GPR64sp handling.
7973
7974class BaseSIMDLdSt<bit Q, bit L, bits<4> opcode, bits<2> size,
7975 string asm, dag oops, dag iops, list<dag> pattern>
7976 : I<oops, iops, asm, "\t$Vt, [$Rn]", "", pattern> {
7977 bits<5> Vt;
7978 bits<5> Rn;
7979 let Inst{31} = 0;
7980 let Inst{30} = Q;
7981 let Inst{29-23} = 0b0011000;
7982 let Inst{22} = L;
7983 let Inst{21-16} = 0b000000;
7984 let Inst{15-12} = opcode;
7985 let Inst{11-10} = size;
7986 let Inst{9-5} = Rn;
7987 let Inst{4-0} = Vt;
7988}
7989
7990class BaseSIMDLdStPost<bit Q, bit L, bits<4> opcode, bits<2> size,
7991 string asm, dag oops, dag iops>
7992 : I<oops, iops, asm, "\t$Vt, [$Rn], $Xm", "$Rn = $wback", []> {
7993 bits<5> Vt;
7994 bits<5> Rn;
7995 bits<5> Xm;
7996 let Inst{31} = 0;
7997 let Inst{30} = Q;
7998 let Inst{29-23} = 0b0011001;
7999 let Inst{22} = L;
8000 let Inst{21} = 0;
8001 let Inst{20-16} = Xm;
8002 let Inst{15-12} = opcode;
8003 let Inst{11-10} = size;
8004 let Inst{9-5} = Rn;
8005 let Inst{4-0} = Vt;
8006}
8007
8008// The immediate form of AdvSIMD post-indexed addressing is encoded with
8009// register post-index addressing from the zero register.
8010multiclass SIMDLdStAliases<string asm, string layout, string Count,
8011 int Offset, int Size> {
8012 // E.g. "ld1 { v0.8b, v1.8b }, [x1], #16"
8013 // "ld1\t$Vt, [$Rn], #16"
8014 // may get mapped to
8015 // (LD1Twov8b_POST VecListTwo8b:$Vt, GPR64sp:$Rn, XZR)
8016 def : InstAlias<asm # "\t$Vt, [$Rn], #" # Offset,
8017 (!cast<Instruction>(NAME # Count # "v" # layout # "_POST")
8018 GPR64sp:$Rn,
8019 !cast<RegisterOperand>("VecList" # Count # layout):$Vt,
8020 XZR), 1>;
8021
8022 // E.g. "ld1.8b { v0, v1 }, [x1], #16"
8023 // "ld1.8b\t$Vt, [$Rn], #16"
8024 // may get mapped to
8025 // (LD1Twov8b_POST VecListTwo64:$Vt, GPR64sp:$Rn, XZR)
8026 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], #" # Offset,
8027 (!cast<Instruction>(NAME # Count # "v" # layout # "_POST")
8028 GPR64sp:$Rn,
8029 !cast<RegisterOperand>("VecList" # Count # Size):$Vt,
8030 XZR), 0>;
8031
8032 // E.g. "ld1.8b { v0, v1 }, [x1]"
8033 // "ld1\t$Vt, [$Rn]"
8034 // may get mapped to
8035 // (LD1Twov8b VecListTwo64:$Vt, GPR64sp:$Rn)
8036 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn]",
8037 (!cast<Instruction>(NAME # Count # "v" # layout)
8038 !cast<RegisterOperand>("VecList" # Count # Size):$Vt,
8039 GPR64sp:$Rn), 0>;
8040
8041 // E.g. "ld1.8b { v0, v1 }, [x1], x2"
8042 // "ld1\t$Vt, [$Rn], $Xm"
8043 // may get mapped to
8044 // (LD1Twov8b_POST VecListTwo64:$Vt, GPR64sp:$Rn, GPR64pi8:$Xm)
8045 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], $Xm",
8046 (!cast<Instruction>(NAME # Count # "v" # layout # "_POST")
8047 GPR64sp:$Rn,
8048 !cast<RegisterOperand>("VecList" # Count # Size):$Vt,
8049 !cast<RegisterOperand>("GPR64pi" # Offset):$Xm), 0>;
8050}
8051
8052multiclass BaseSIMDLdN<string Count, string asm, string veclist, int Offset128,
8053 int Offset64, bits<4> opcode> {
8054 let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in {
8055 def v16b: BaseSIMDLdSt<1, 1, opcode, 0b00, asm,
8056 (outs !cast<RegisterOperand>(veclist # "16b"):$Vt),
8057 (ins GPR64sp:$Rn), []>;
8058 def v8h : BaseSIMDLdSt<1, 1, opcode, 0b01, asm,
8059 (outs !cast<RegisterOperand>(veclist # "8h"):$Vt),
8060 (ins GPR64sp:$Rn), []>;
8061 def v4s : BaseSIMDLdSt<1, 1, opcode, 0b10, asm,
8062 (outs !cast<RegisterOperand>(veclist # "4s"):$Vt),
8063 (ins GPR64sp:$Rn), []>;
8064 def v2d : BaseSIMDLdSt<1, 1, opcode, 0b11, asm,
8065 (outs !cast<RegisterOperand>(veclist # "2d"):$Vt),
8066 (ins GPR64sp:$Rn), []>;
8067 def v8b : BaseSIMDLdSt<0, 1, opcode, 0b00, asm,
8068 (outs !cast<RegisterOperand>(veclist # "8b"):$Vt),
8069 (ins GPR64sp:$Rn), []>;
8070 def v4h : BaseSIMDLdSt<0, 1, opcode, 0b01, asm,
8071 (outs !cast<RegisterOperand>(veclist # "4h"):$Vt),
8072 (ins GPR64sp:$Rn), []>;
8073 def v2s : BaseSIMDLdSt<0, 1, opcode, 0b10, asm,
8074 (outs !cast<RegisterOperand>(veclist # "2s"):$Vt),
8075 (ins GPR64sp:$Rn), []>;
8076
8077
8078 def v16b_POST: BaseSIMDLdStPost<1, 1, opcode, 0b00, asm,
8079 (outs GPR64sp:$wback,
8080 !cast<RegisterOperand>(veclist # "16b"):$Vt),
8081 (ins GPR64sp:$Rn,
8082 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
8083 def v8h_POST : BaseSIMDLdStPost<1, 1, opcode, 0b01, asm,
8084 (outs GPR64sp:$wback,
8085 !cast<RegisterOperand>(veclist # "8h"):$Vt),
8086 (ins GPR64sp:$Rn,
8087 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
8088 def v4s_POST : BaseSIMDLdStPost<1, 1, opcode, 0b10, asm,
8089 (outs GPR64sp:$wback,
8090 !cast<RegisterOperand>(veclist # "4s"):$Vt),
8091 (ins GPR64sp:$Rn,
8092 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
8093 def v2d_POST : BaseSIMDLdStPost<1, 1, opcode, 0b11, asm,
8094 (outs GPR64sp:$wback,
8095 !cast<RegisterOperand>(veclist # "2d"):$Vt),
8096 (ins GPR64sp:$Rn,
8097 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
8098 def v8b_POST : BaseSIMDLdStPost<0, 1, opcode, 0b00, asm,
8099 (outs GPR64sp:$wback,
8100 !cast<RegisterOperand>(veclist # "8b"):$Vt),
8101 (ins GPR64sp:$Rn,
8102 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
8103 def v4h_POST : BaseSIMDLdStPost<0, 1, opcode, 0b01, asm,
8104 (outs GPR64sp:$wback,
8105 !cast<RegisterOperand>(veclist # "4h"):$Vt),
8106 (ins GPR64sp:$Rn,
8107 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
8108 def v2s_POST : BaseSIMDLdStPost<0, 1, opcode, 0b10, asm,
8109 (outs GPR64sp:$wback,
8110 !cast<RegisterOperand>(veclist # "2s"):$Vt),
8111 (ins GPR64sp:$Rn,
8112 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
8113 }
8114
8115 defm : SIMDLdStAliases<asm, "16b", Count, Offset128, 128>;
8116 defm : SIMDLdStAliases<asm, "8h", Count, Offset128, 128>;
8117 defm : SIMDLdStAliases<asm, "4s", Count, Offset128, 128>;
8118 defm : SIMDLdStAliases<asm, "2d", Count, Offset128, 128>;
8119 defm : SIMDLdStAliases<asm, "8b", Count, Offset64, 64>;
8120 defm : SIMDLdStAliases<asm, "4h", Count, Offset64, 64>;
8121 defm : SIMDLdStAliases<asm, "2s", Count, Offset64, 64>;
8122}
8123
8124// Only ld1/st1 has a v1d version.
8125multiclass BaseSIMDStN<string Count, string asm, string veclist, int Offset128,
8126 int Offset64, bits<4> opcode> {
8127 let hasSideEffects = 0, mayStore = 1, mayLoad = 0 in {
8128 def v16b : BaseSIMDLdSt<1, 0, opcode, 0b00, asm, (outs),
8129 (ins !cast<RegisterOperand>(veclist # "16b"):$Vt,
8130 GPR64sp:$Rn), []>;
8131 def v8h : BaseSIMDLdSt<1, 0, opcode, 0b01, asm, (outs),
8132 (ins !cast<RegisterOperand>(veclist # "8h"):$Vt,
8133 GPR64sp:$Rn), []>;
8134 def v4s : BaseSIMDLdSt<1, 0, opcode, 0b10, asm, (outs),
8135 (ins !cast<RegisterOperand>(veclist # "4s"):$Vt,
8136 GPR64sp:$Rn), []>;
8137 def v2d : BaseSIMDLdSt<1, 0, opcode, 0b11, asm, (outs),
8138 (ins !cast<RegisterOperand>(veclist # "2d"):$Vt,
8139 GPR64sp:$Rn), []>;
8140 def v8b : BaseSIMDLdSt<0, 0, opcode, 0b00, asm, (outs),
8141 (ins !cast<RegisterOperand>(veclist # "8b"):$Vt,
8142 GPR64sp:$Rn), []>;
8143 def v4h : BaseSIMDLdSt<0, 0, opcode, 0b01, asm, (outs),
8144 (ins !cast<RegisterOperand>(veclist # "4h"):$Vt,
8145 GPR64sp:$Rn), []>;
8146 def v2s : BaseSIMDLdSt<0, 0, opcode, 0b10, asm, (outs),
8147 (ins !cast<RegisterOperand>(veclist # "2s"):$Vt,
8148 GPR64sp:$Rn), []>;
8149
8150 def v16b_POST : BaseSIMDLdStPost<1, 0, opcode, 0b00, asm,
8151 (outs GPR64sp:$wback),
8152 (ins !cast<RegisterOperand>(veclist # "16b"):$Vt,
8153 GPR64sp:$Rn,
8154 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
8155 def v8h_POST : BaseSIMDLdStPost<1, 0, opcode, 0b01, asm,
8156 (outs GPR64sp:$wback),
8157 (ins !cast<RegisterOperand>(veclist # "8h"):$Vt,
8158 GPR64sp:$Rn,
8159 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
8160 def v4s_POST : BaseSIMDLdStPost<1, 0, opcode, 0b10, asm,
8161 (outs GPR64sp:$wback),
8162 (ins !cast<RegisterOperand>(veclist # "4s"):$Vt,
8163 GPR64sp:$Rn,
8164 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
8165 def v2d_POST : BaseSIMDLdStPost<1, 0, opcode, 0b11, asm,
8166 (outs GPR64sp:$wback),
8167 (ins !cast<RegisterOperand>(veclist # "2d"):$Vt,
8168 GPR64sp:$Rn,
8169 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
8170 def v8b_POST : BaseSIMDLdStPost<0, 0, opcode, 0b00, asm,
8171 (outs GPR64sp:$wback),
8172 (ins !cast<RegisterOperand>(veclist # "8b"):$Vt,
8173 GPR64sp:$Rn,
8174 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
8175 def v4h_POST : BaseSIMDLdStPost<0, 0, opcode, 0b01, asm,
8176 (outs GPR64sp:$wback),
8177 (ins !cast<RegisterOperand>(veclist # "4h"):$Vt,
8178 GPR64sp:$Rn,
8179 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
8180 def v2s_POST : BaseSIMDLdStPost<0, 0, opcode, 0b10, asm,
8181 (outs GPR64sp:$wback),
8182 (ins !cast<RegisterOperand>(veclist # "2s"):$Vt,
8183 GPR64sp:$Rn,
8184 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
8185 }
8186
8187 defm : SIMDLdStAliases<asm, "16b", Count, Offset128, 128>;
8188 defm : SIMDLdStAliases<asm, "8h", Count, Offset128, 128>;
8189 defm : SIMDLdStAliases<asm, "4s", Count, Offset128, 128>;
8190 defm : SIMDLdStAliases<asm, "2d", Count, Offset128, 128>;
8191 defm : SIMDLdStAliases<asm, "8b", Count, Offset64, 64>;
8192 defm : SIMDLdStAliases<asm, "4h", Count, Offset64, 64>;
8193 defm : SIMDLdStAliases<asm, "2s", Count, Offset64, 64>;
8194}
8195
8196multiclass BaseSIMDLd1<string Count, string asm, string veclist,
8197 int Offset128, int Offset64, bits<4> opcode>
8198 : BaseSIMDLdN<Count, asm, veclist, Offset128, Offset64, opcode> {
8199
8200 // LD1 instructions have extra "1d" variants.
8201 let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in {
8202 def v1d : BaseSIMDLdSt<0, 1, opcode, 0b11, asm,
8203 (outs !cast<RegisterOperand>(veclist # "1d"):$Vt),
8204 (ins GPR64sp:$Rn), []>;
8205
8206 def v1d_POST : BaseSIMDLdStPost<0, 1, opcode, 0b11, asm,
8207 (outs GPR64sp:$wback,
8208 !cast<RegisterOperand>(veclist # "1d"):$Vt),
8209 (ins GPR64sp:$Rn,
8210 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
8211 }
8212
8213 defm : SIMDLdStAliases<asm, "1d", Count, Offset64, 64>;
8214}
8215
8216multiclass BaseSIMDSt1<string Count, string asm, string veclist,
8217 int Offset128, int Offset64, bits<4> opcode>
8218 : BaseSIMDStN<Count, asm, veclist, Offset128, Offset64, opcode> {
8219
8220 // ST1 instructions have extra "1d" variants.
8221 let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in {
8222 def v1d : BaseSIMDLdSt<0, 0, opcode, 0b11, asm, (outs),
8223 (ins !cast<RegisterOperand>(veclist # "1d"):$Vt,
8224 GPR64sp:$Rn), []>;
8225
8226 def v1d_POST : BaseSIMDLdStPost<0, 0, opcode, 0b11, asm,
8227 (outs GPR64sp:$wback),
8228 (ins !cast<RegisterOperand>(veclist # "1d"):$Vt,
8229 GPR64sp:$Rn,
8230 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
8231 }
8232
8233 defm : SIMDLdStAliases<asm, "1d", Count, Offset64, 64>;
8234}
8235
8236multiclass SIMDLd1Multiple<string asm> {
8237 defm One : BaseSIMDLd1<"One", asm, "VecListOne", 16, 8, 0b0111>;
8238 defm Two : BaseSIMDLd1<"Two", asm, "VecListTwo", 32, 16, 0b1010>;
8239 defm Three : BaseSIMDLd1<"Three", asm, "VecListThree", 48, 24, 0b0110>;
8240 defm Four : BaseSIMDLd1<"Four", asm, "VecListFour", 64, 32, 0b0010>;
8241}
8242
8243multiclass SIMDSt1Multiple<string asm> {
8244 defm One : BaseSIMDSt1<"One", asm, "VecListOne", 16, 8, 0b0111>;
8245 defm Two : BaseSIMDSt1<"Two", asm, "VecListTwo", 32, 16, 0b1010>;
8246 defm Three : BaseSIMDSt1<"Three", asm, "VecListThree", 48, 24, 0b0110>;
8247 defm Four : BaseSIMDSt1<"Four", asm, "VecListFour", 64, 32, 0b0010>;
8248}
8249
8250multiclass SIMDLd2Multiple<string asm> {
8251 defm Two : BaseSIMDLdN<"Two", asm, "VecListTwo", 32, 16, 0b1000>;
8252}
8253
8254multiclass SIMDSt2Multiple<string asm> {
8255 defm Two : BaseSIMDStN<"Two", asm, "VecListTwo", 32, 16, 0b1000>;
8256}
8257
8258multiclass SIMDLd3Multiple<string asm> {
8259 defm Three : BaseSIMDLdN<"Three", asm, "VecListThree", 48, 24, 0b0100>;
8260}
8261
8262multiclass SIMDSt3Multiple<string asm> {
8263 defm Three : BaseSIMDStN<"Three", asm, "VecListThree", 48, 24, 0b0100>;
8264}
8265
8266multiclass SIMDLd4Multiple<string asm> {
8267 defm Four : BaseSIMDLdN<"Four", asm, "VecListFour", 64, 32, 0b0000>;
8268}
8269
8270multiclass SIMDSt4Multiple<string asm> {
8271 defm Four : BaseSIMDStN<"Four", asm, "VecListFour", 64, 32, 0b0000>;
8272}
8273
8274//---
8275// AdvSIMD Load/store single-element
8276//---
8277
8278class BaseSIMDLdStSingle<bit L, bit R, bits<3> opcode,
8279 string asm, string operands, string cst,
8280 dag oops, dag iops, list<dag> pattern>
8281 : I<oops, iops, asm, operands, cst, pattern> {
8282 bits<5> Vt;
8283 bits<5> Rn;
8284 let Inst{31} = 0;
8285 let Inst{29-24} = 0b001101;
8286 let Inst{22} = L;
8287 let Inst{21} = R;
8288 let Inst{15-13} = opcode;
8289 let Inst{9-5} = Rn;
8290 let Inst{4-0} = Vt;
8291}
8292
8293class BaseSIMDLdStSingleTied<bit L, bit R, bits<3> opcode,
8294 string asm, string operands, string cst,
8295 dag oops, dag iops, list<dag> pattern>
8296 : I<oops, iops, asm, operands, "$Vt = $dst," # cst, pattern> {
8297 bits<5> Vt;
8298 bits<5> Rn;
8299 let Inst{31} = 0;
8300 let Inst{29-24} = 0b001101;
8301 let Inst{22} = L;
8302 let Inst{21} = R;
8303 let Inst{15-13} = opcode;
8304 let Inst{9-5} = Rn;
8305 let Inst{4-0} = Vt;
8306}
8307
8308
8309let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
8310class BaseSIMDLdR<bit Q, bit R, bits<3> opcode, bit S, bits<2> size, string asm,
8311 Operand listtype>
8312 : BaseSIMDLdStSingle<1, R, opcode, asm, "\t$Vt, [$Rn]", "",
8313 (outs listtype:$Vt), (ins GPR64sp:$Rn),
8314 []> {
8315 let Inst{30} = Q;
8316 let Inst{23} = 0;
8317 let Inst{20-16} = 0b00000;
8318 let Inst{12} = S;
8319 let Inst{11-10} = size;
8320}
8321let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
8322class BaseSIMDLdRPost<bit Q, bit R, bits<3> opcode, bit S, bits<2> size,
8323 string asm, Operand listtype, Operand GPR64pi>
8324 : BaseSIMDLdStSingle<1, R, opcode, asm, "\t$Vt, [$Rn], $Xm",
8325 "$Rn = $wback",
8326 (outs GPR64sp:$wback, listtype:$Vt),
8327 (ins GPR64sp:$Rn, GPR64pi:$Xm), []> {
8328 bits<5> Xm;
8329 let Inst{30} = Q;
8330 let Inst{23} = 1;
8331 let Inst{20-16} = Xm;
8332 let Inst{12} = S;
8333 let Inst{11-10} = size;
8334}
8335
8336multiclass SIMDLdrAliases<string asm, string layout, string Count,
8337 int Offset, int Size> {
8338 // E.g. "ld1r { v0.8b }, [x1], #1"
8339 // "ld1r.8b\t$Vt, [$Rn], #1"
8340 // may get mapped to
8341 // (LD1Rv8b_POST VecListOne8b:$Vt, GPR64sp:$Rn, XZR)
8342 def : InstAlias<asm # "\t$Vt, [$Rn], #" # Offset,
8343 (!cast<Instruction>(NAME # "v" # layout # "_POST")
8344 GPR64sp:$Rn,
8345 !cast<RegisterOperand>("VecList" # Count # layout):$Vt,
8346 XZR), 1>;
8347
8348 // E.g. "ld1r.8b { v0 }, [x1], #1"
8349 // "ld1r.8b\t$Vt, [$Rn], #1"
8350 // may get mapped to
8351 // (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, XZR)
8352 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], #" # Offset,
8353 (!cast<Instruction>(NAME # "v" # layout # "_POST")
8354 GPR64sp:$Rn,
8355 !cast<RegisterOperand>("VecList" # Count # Size):$Vt,
8356 XZR), 0>;
8357
8358 // E.g. "ld1r.8b { v0 }, [x1]"
8359 // "ld1r.8b\t$Vt, [$Rn]"
8360 // may get mapped to
8361 // (LD1Rv8b VecListOne64:$Vt, GPR64sp:$Rn)
8362 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn]",
8363 (!cast<Instruction>(NAME # "v" # layout)
8364 !cast<RegisterOperand>("VecList" # Count # Size):$Vt,
8365 GPR64sp:$Rn), 0>;
8366
8367 // E.g. "ld1r.8b { v0 }, [x1], x2"
8368 // "ld1r.8b\t$Vt, [$Rn], $Xm"
8369 // may get mapped to
8370 // (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, GPR64pi1:$Xm)
8371 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], $Xm",
8372 (!cast<Instruction>(NAME # "v" # layout # "_POST")
8373 GPR64sp:$Rn,
8374 !cast<RegisterOperand>("VecList" # Count # Size):$Vt,
8375 !cast<RegisterOperand>("GPR64pi" # Offset):$Xm), 0>;
8376}
8377
8378multiclass SIMDLdR<bit R, bits<3> opcode, bit S, string asm, string Count,
8379 int Offset1, int Offset2, int Offset4, int Offset8> {
8380 def v8b : BaseSIMDLdR<0, R, opcode, S, 0b00, asm,
8381 !cast<Operand>("VecList" # Count # "8b")>;
8382 def v16b: BaseSIMDLdR<1, R, opcode, S, 0b00, asm,
8383 !cast<Operand>("VecList" # Count #"16b")>;
8384 def v4h : BaseSIMDLdR<0, R, opcode, S, 0b01, asm,
8385 !cast<Operand>("VecList" # Count #"4h")>;
8386 def v8h : BaseSIMDLdR<1, R, opcode, S, 0b01, asm,
8387 !cast<Operand>("VecList" # Count #"8h")>;
8388 def v2s : BaseSIMDLdR<0, R, opcode, S, 0b10, asm,
8389 !cast<Operand>("VecList" # Count #"2s")>;
8390 def v4s : BaseSIMDLdR<1, R, opcode, S, 0b10, asm,
8391 !cast<Operand>("VecList" # Count #"4s")>;
8392 def v1d : BaseSIMDLdR<0, R, opcode, S, 0b11, asm,
8393 !cast<Operand>("VecList" # Count #"1d")>;
8394 def v2d : BaseSIMDLdR<1, R, opcode, S, 0b11, asm,
8395 !cast<Operand>("VecList" # Count #"2d")>;
8396
8397 def v8b_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b00, asm,
8398 !cast<Operand>("VecList" # Count # "8b"),
8399 !cast<Operand>("GPR64pi" # Offset1)>;
8400 def v16b_POST: BaseSIMDLdRPost<1, R, opcode, S, 0b00, asm,
8401 !cast<Operand>("VecList" # Count # "16b"),
8402 !cast<Operand>("GPR64pi" # Offset1)>;
8403 def v4h_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b01, asm,
8404 !cast<Operand>("VecList" # Count # "4h"),
8405 !cast<Operand>("GPR64pi" # Offset2)>;
8406 def v8h_POST : BaseSIMDLdRPost<1, R, opcode, S, 0b01, asm,
8407 !cast<Operand>("VecList" # Count # "8h"),
8408 !cast<Operand>("GPR64pi" # Offset2)>;
8409 def v2s_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b10, asm,
8410 !cast<Operand>("VecList" # Count # "2s"),
8411 !cast<Operand>("GPR64pi" # Offset4)>;
8412 def v4s_POST : BaseSIMDLdRPost<1, R, opcode, S, 0b10, asm,
8413 !cast<Operand>("VecList" # Count # "4s"),
8414 !cast<Operand>("GPR64pi" # Offset4)>;
8415 def v1d_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b11, asm,
8416 !cast<Operand>("VecList" # Count # "1d"),
8417 !cast<Operand>("GPR64pi" # Offset8)>;
8418 def v2d_POST : BaseSIMDLdRPost<1, R, opcode, S, 0b11, asm,
8419 !cast<Operand>("VecList" # Count # "2d"),
8420 !cast<Operand>("GPR64pi" # Offset8)>;
8421
8422 defm : SIMDLdrAliases<asm, "8b", Count, Offset1, 64>;
8423 defm : SIMDLdrAliases<asm, "16b", Count, Offset1, 128>;
8424 defm : SIMDLdrAliases<asm, "4h", Count, Offset2, 64>;
8425 defm : SIMDLdrAliases<asm, "8h", Count, Offset2, 128>;
8426 defm : SIMDLdrAliases<asm, "2s", Count, Offset4, 64>;
8427 defm : SIMDLdrAliases<asm, "4s", Count, Offset4, 128>;
8428 defm : SIMDLdrAliases<asm, "1d", Count, Offset8, 64>;
8429 defm : SIMDLdrAliases<asm, "2d", Count, Offset8, 128>;
8430}
8431
8432class SIMDLdStSingleB<bit L, bit R, bits<3> opcode, string asm,
8433 dag oops, dag iops, list<dag> pattern>
8434 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops,
8435 pattern> {
8436 // idx encoded in Q:S:size fields.
8437 bits<4> idx;
8438 let Inst{30} = idx{3};
8439 let Inst{23} = 0;
8440 let Inst{20-16} = 0b00000;
8441 let Inst{12} = idx{2};
8442 let Inst{11-10} = idx{1-0};
8443}
8444class SIMDLdStSingleBTied<bit L, bit R, bits<3> opcode, string asm,
8445 dag oops, dag iops, list<dag> pattern>
8446 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "",
8447 oops, iops, pattern> {
8448 // idx encoded in Q:S:size fields.
8449 bits<4> idx;
8450 let Inst{30} = idx{3};
8451 let Inst{23} = 0;
8452 let Inst{20-16} = 0b00000;
8453 let Inst{12} = idx{2};
8454 let Inst{11-10} = idx{1-0};
8455}
8456class SIMDLdStSingleBPost<bit L, bit R, bits<3> opcode, string asm,
8457 dag oops, dag iops>
8458 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
8459 "$Rn = $wback", oops, iops, []> {
8460 // idx encoded in Q:S:size fields.
8461 bits<4> idx;
8462 bits<5> Xm;
8463 let Inst{30} = idx{3};
8464 let Inst{23} = 1;
8465 let Inst{20-16} = Xm;
8466 let Inst{12} = idx{2};
8467 let Inst{11-10} = idx{1-0};
8468}
8469class SIMDLdStSingleBTiedPost<bit L, bit R, bits<3> opcode, string asm,
8470 dag oops, dag iops>
8471 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
8472 "$Rn = $wback", oops, iops, []> {
8473 // idx encoded in Q:S:size fields.
8474 bits<4> idx;
8475 bits<5> Xm;
8476 let Inst{30} = idx{3};
8477 let Inst{23} = 1;
8478 let Inst{20-16} = Xm;
8479 let Inst{12} = idx{2};
8480 let Inst{11-10} = idx{1-0};
8481}
8482
8483class SIMDLdStSingleH<bit L, bit R, bits<3> opcode, bit size, string asm,
8484 dag oops, dag iops, list<dag> pattern>
8485 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops,
8486 pattern> {
8487 // idx encoded in Q:S:size<1> fields.
8488 bits<3> idx;
8489 let Inst{30} = idx{2};
8490 let Inst{23} = 0;
8491 let Inst{20-16} = 0b00000;
8492 let Inst{12} = idx{1};
8493 let Inst{11} = idx{0};
8494 let Inst{10} = size;
8495}
8496class SIMDLdStSingleHTied<bit L, bit R, bits<3> opcode, bit size, string asm,
8497 dag oops, dag iops, list<dag> pattern>
8498 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "",
8499 oops, iops, pattern> {
8500 // idx encoded in Q:S:size<1> fields.
8501 bits<3> idx;
8502 let Inst{30} = idx{2};
8503 let Inst{23} = 0;
8504 let Inst{20-16} = 0b00000;
8505 let Inst{12} = idx{1};
8506 let Inst{11} = idx{0};
8507 let Inst{10} = size;
8508}
8509
8510class SIMDLdStSingleHPost<bit L, bit R, bits<3> opcode, bit size, string asm,
8511 dag oops, dag iops>
8512 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
8513 "$Rn = $wback", oops, iops, []> {
8514 // idx encoded in Q:S:size<1> fields.
8515 bits<3> idx;
8516 bits<5> Xm;
8517 let Inst{30} = idx{2};
8518 let Inst{23} = 1;
8519 let Inst{20-16} = Xm;
8520 let Inst{12} = idx{1};
8521 let Inst{11} = idx{0};
8522 let Inst{10} = size;
8523}
8524class SIMDLdStSingleHTiedPost<bit L, bit R, bits<3> opcode, bit size, string asm,
8525 dag oops, dag iops>
8526 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
8527 "$Rn = $wback", oops, iops, []> {
8528 // idx encoded in Q:S:size<1> fields.
8529 bits<3> idx;
8530 bits<5> Xm;
8531 let Inst{30} = idx{2};
8532 let Inst{23} = 1;
8533 let Inst{20-16} = Xm;
8534 let Inst{12} = idx{1};
8535 let Inst{11} = idx{0};
8536 let Inst{10} = size;
8537}
8538class SIMDLdStSingleS<bit L, bit R, bits<3> opcode, bits<2> size, string asm,
8539 dag oops, dag iops, list<dag> pattern>
8540 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops,
8541 pattern> {
8542 // idx encoded in Q:S fields.
8543 bits<2> idx;
8544 let Inst{30} = idx{1};
8545 let Inst{23} = 0;
8546 let Inst{20-16} = 0b00000;
8547 let Inst{12} = idx{0};
8548 let Inst{11-10} = size;
8549}
8550class SIMDLdStSingleSTied<bit L, bit R, bits<3> opcode, bits<2> size, string asm,
8551 dag oops, dag iops, list<dag> pattern>
8552 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "",
8553 oops, iops, pattern> {
8554 // idx encoded in Q:S fields.
8555 bits<2> idx;
8556 let Inst{30} = idx{1};
8557 let Inst{23} = 0;
8558 let Inst{20-16} = 0b00000;
8559 let Inst{12} = idx{0};
8560 let Inst{11-10} = size;
8561}
8562class SIMDLdStSingleSPost<bit L, bit R, bits<3> opcode, bits<2> size,
8563 string asm, dag oops, dag iops>
8564 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
8565 "$Rn = $wback", oops, iops, []> {
8566 // idx encoded in Q:S fields.
8567 bits<2> idx;
8568 bits<5> Xm;
8569 let Inst{30} = idx{1};
8570 let Inst{23} = 1;
8571 let Inst{20-16} = Xm;
8572 let Inst{12} = idx{0};
8573 let Inst{11-10} = size;
8574}
8575class SIMDLdStSingleSTiedPost<bit L, bit R, bits<3> opcode, bits<2> size,
8576 string asm, dag oops, dag iops>
8577 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
8578 "$Rn = $wback", oops, iops, []> {
8579 // idx encoded in Q:S fields.
8580 bits<2> idx;
8581 bits<5> Xm;
8582 let Inst{30} = idx{1};
8583 let Inst{23} = 1;
8584 let Inst{20-16} = Xm;
8585 let Inst{12} = idx{0};
8586 let Inst{11-10} = size;
8587}
8588class SIMDLdStSingleD<bit L, bit R, bits<3> opcode, bits<2> size, string asm,
8589 dag oops, dag iops, list<dag> pattern>
8590 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops,
8591 pattern> {
8592 // idx encoded in Q field.
8593 bits<1> idx;
8594 let Inst{30} = idx;
8595 let Inst{23} = 0;
8596 let Inst{20-16} = 0b00000;
8597 let Inst{12} = 0;
8598 let Inst{11-10} = size;
8599}
8600class SIMDLdStSingleDTied<bit L, bit R, bits<3> opcode, bits<2> size, string asm,
8601 dag oops, dag iops, list<dag> pattern>
8602 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "",
8603 oops, iops, pattern> {
8604 // idx encoded in Q field.
8605 bits<1> idx;
8606 let Inst{30} = idx;
8607 let Inst{23} = 0;
8608 let Inst{20-16} = 0b00000;
8609 let Inst{12} = 0;
8610 let Inst{11-10} = size;
8611}
8612class SIMDLdStSingleDPost<bit L, bit R, bits<3> opcode, bits<2> size,
8613 string asm, dag oops, dag iops>
8614 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
8615 "$Rn = $wback", oops, iops, []> {
8616 // idx encoded in Q field.
8617 bits<1> idx;
8618 bits<5> Xm;
8619 let Inst{30} = idx;
8620 let Inst{23} = 1;
8621 let Inst{20-16} = Xm;
8622 let Inst{12} = 0;
8623 let Inst{11-10} = size;
8624}
8625class SIMDLdStSingleDTiedPost<bit L, bit R, bits<3> opcode, bits<2> size,
8626 string asm, dag oops, dag iops>
8627 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
8628 "$Rn = $wback", oops, iops, []> {
8629 // idx encoded in Q field.
8630 bits<1> idx;
8631 bits<5> Xm;
8632 let Inst{30} = idx;
8633 let Inst{23} = 1;
8634 let Inst{20-16} = Xm;
8635 let Inst{12} = 0;
8636 let Inst{11-10} = size;
8637}
8638
8639let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
8640multiclass SIMDLdSingleBTied<bit R, bits<3> opcode, string asm,
8641 RegisterOperand listtype,
8642 RegisterOperand GPR64pi> {
8643 def i8 : SIMDLdStSingleBTied<1, R, opcode, asm,
8644 (outs listtype:$dst),
8645 (ins listtype:$Vt, VectorIndexB:$idx,
8646 GPR64sp:$Rn), []>;
8647
8648 def i8_POST : SIMDLdStSingleBTiedPost<1, R, opcode, asm,
8649 (outs GPR64sp:$wback, listtype:$dst),
8650 (ins listtype:$Vt, VectorIndexB:$idx,
8651 GPR64sp:$Rn, GPR64pi:$Xm)>;
8652}
8653let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
8654multiclass SIMDLdSingleHTied<bit R, bits<3> opcode, bit size, string asm,
8655 RegisterOperand listtype,
8656 RegisterOperand GPR64pi> {
8657 def i16 : SIMDLdStSingleHTied<1, R, opcode, size, asm,
8658 (outs listtype:$dst),
8659 (ins listtype:$Vt, VectorIndexH:$idx,
8660 GPR64sp:$Rn), []>;
8661
8662 def i16_POST : SIMDLdStSingleHTiedPost<1, R, opcode, size, asm,
8663 (outs GPR64sp:$wback, listtype:$dst),
8664 (ins listtype:$Vt, VectorIndexH:$idx,
8665 GPR64sp:$Rn, GPR64pi:$Xm)>;
8666}
8667let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
8668multiclass SIMDLdSingleSTied<bit R, bits<3> opcode, bits<2> size,string asm,
8669 RegisterOperand listtype,
8670 RegisterOperand GPR64pi> {
8671 def i32 : SIMDLdStSingleSTied<1, R, opcode, size, asm,
8672 (outs listtype:$dst),
8673 (ins listtype:$Vt, VectorIndexS:$idx,
8674 GPR64sp:$Rn), []>;
8675
8676 def i32_POST : SIMDLdStSingleSTiedPost<1, R, opcode, size, asm,
8677 (outs GPR64sp:$wback, listtype:$dst),
8678 (ins listtype:$Vt, VectorIndexS:$idx,
8679 GPR64sp:$Rn, GPR64pi:$Xm)>;
8680}
8681let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
8682multiclass SIMDLdSingleDTied<bit R, bits<3> opcode, bits<2> size, string asm,
8683 RegisterOperand listtype, RegisterOperand GPR64pi> {
8684 def i64 : SIMDLdStSingleDTied<1, R, opcode, size, asm,
8685 (outs listtype:$dst),
8686 (ins listtype:$Vt, VectorIndexD:$idx,
8687 GPR64sp:$Rn), []>;
8688
8689 def i64_POST : SIMDLdStSingleDTiedPost<1, R, opcode, size, asm,
8690 (outs GPR64sp:$wback, listtype:$dst),
8691 (ins listtype:$Vt, VectorIndexD:$idx,
8692 GPR64sp:$Rn, GPR64pi:$Xm)>;
8693}
8694let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
8695multiclass SIMDStSingleB<bit R, bits<3> opcode, string asm,
8696 RegisterOperand listtype, RegisterOperand GPR64pi> {
8697 def i8 : SIMDLdStSingleB<0, R, opcode, asm,
8698 (outs), (ins listtype:$Vt, VectorIndexB:$idx,
8699 GPR64sp:$Rn), []>;
8700
8701 def i8_POST : SIMDLdStSingleBPost<0, R, opcode, asm,
8702 (outs GPR64sp:$wback),
8703 (ins listtype:$Vt, VectorIndexB:$idx,
8704 GPR64sp:$Rn, GPR64pi:$Xm)>;
8705}
8706let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
8707multiclass SIMDStSingleH<bit R, bits<3> opcode, bit size, string asm,
8708 RegisterOperand listtype, RegisterOperand GPR64pi> {
8709 def i16 : SIMDLdStSingleH<0, R, opcode, size, asm,
8710 (outs), (ins listtype:$Vt, VectorIndexH:$idx,
8711 GPR64sp:$Rn), []>;
8712
8713 def i16_POST : SIMDLdStSingleHPost<0, R, opcode, size, asm,
8714 (outs GPR64sp:$wback),
8715 (ins listtype:$Vt, VectorIndexH:$idx,
8716 GPR64sp:$Rn, GPR64pi:$Xm)>;
8717}
8718let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
8719multiclass SIMDStSingleS<bit R, bits<3> opcode, bits<2> size,string asm,
8720 RegisterOperand listtype, RegisterOperand GPR64pi> {
8721 def i32 : SIMDLdStSingleS<0, R, opcode, size, asm,
8722 (outs), (ins listtype:$Vt, VectorIndexS:$idx,
8723 GPR64sp:$Rn), []>;
8724
8725 def i32_POST : SIMDLdStSingleSPost<0, R, opcode, size, asm,
8726 (outs GPR64sp:$wback),
8727 (ins listtype:$Vt, VectorIndexS:$idx,
8728 GPR64sp:$Rn, GPR64pi:$Xm)>;
8729}
8730let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
8731multiclass SIMDStSingleD<bit R, bits<3> opcode, bits<2> size, string asm,
8732 RegisterOperand listtype, RegisterOperand GPR64pi> {
8733 def i64 : SIMDLdStSingleD<0, R, opcode, size, asm,
8734 (outs), (ins listtype:$Vt, VectorIndexD:$idx,
8735 GPR64sp:$Rn), []>;
8736
8737 def i64_POST : SIMDLdStSingleDPost<0, R, opcode, size, asm,
8738 (outs GPR64sp:$wback),
8739 (ins listtype:$Vt, VectorIndexD:$idx,
8740 GPR64sp:$Rn, GPR64pi:$Xm)>;
8741}
8742
8743multiclass SIMDLdStSingleAliases<string asm, string layout, string Type,
8744 string Count, int Offset, Operand idxtype> {
8745 // E.g. "ld1 { v0.8b }[0], [x1], #1"
8746 // "ld1\t$Vt, [$Rn], #1"
8747 // may get mapped to
8748 // (LD1Rv8b_POST VecListOne8b:$Vt, GPR64sp:$Rn, XZR)
8749 def : InstAlias<asm # "\t$Vt$idx, [$Rn], #" # Offset,
8750 (!cast<Instruction>(NAME # Type # "_POST")
8751 GPR64sp:$Rn,
8752 !cast<RegisterOperand>("VecList" # Count # layout):$Vt,
8753 idxtype:$idx, XZR), 1>;
8754
8755 // E.g. "ld1.8b { v0 }[0], [x1], #1"
8756 // "ld1.8b\t$Vt, [$Rn], #1"
8757 // may get mapped to
8758 // (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, XZR)
8759 def : InstAlias<asm # "." # layout # "\t$Vt$idx, [$Rn], #" # Offset,
8760 (!cast<Instruction>(NAME # Type # "_POST")
8761 GPR64sp:$Rn,
8762 !cast<RegisterOperand>("VecList" # Count # "128"):$Vt,
8763 idxtype:$idx, XZR), 0>;
8764
8765 // E.g. "ld1.8b { v0 }[0], [x1]"
8766 // "ld1.8b\t$Vt, [$Rn]"
8767 // may get mapped to
8768 // (LD1Rv8b VecListOne64:$Vt, GPR64sp:$Rn)
8769 def : InstAlias<asm # "." # layout # "\t$Vt$idx, [$Rn]",
8770 (!cast<Instruction>(NAME # Type)
8771 !cast<RegisterOperand>("VecList" # Count # "128"):$Vt,
8772 idxtype:$idx, GPR64sp:$Rn), 0>;
8773
8774 // E.g. "ld1.8b { v0 }[0], [x1], x2"
8775 // "ld1.8b\t$Vt, [$Rn], $Xm"
8776 // may get mapped to
8777 // (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, GPR64pi1:$Xm)
8778 def : InstAlias<asm # "." # layout # "\t$Vt$idx, [$Rn], $Xm",
8779 (!cast<Instruction>(NAME # Type # "_POST")
8780 GPR64sp:$Rn,
8781 !cast<RegisterOperand>("VecList" # Count # "128"):$Vt,
8782 idxtype:$idx,
8783 !cast<RegisterOperand>("GPR64pi" # Offset):$Xm), 0>;
8784}
8785
8786multiclass SIMDLdSt1SingleAliases<string asm> {
8787 defm : SIMDLdStSingleAliases<asm, "b", "i8", "One", 1, VectorIndexB>;
8788 defm : SIMDLdStSingleAliases<asm, "h", "i16", "One", 2, VectorIndexH>;
8789 defm : SIMDLdStSingleAliases<asm, "s", "i32", "One", 4, VectorIndexS>;
8790 defm : SIMDLdStSingleAliases<asm, "d", "i64", "One", 8, VectorIndexD>;
8791}
8792
8793multiclass SIMDLdSt2SingleAliases<string asm> {
8794 defm : SIMDLdStSingleAliases<asm, "b", "i8", "Two", 2, VectorIndexB>;
8795 defm : SIMDLdStSingleAliases<asm, "h", "i16", "Two", 4, VectorIndexH>;
8796 defm : SIMDLdStSingleAliases<asm, "s", "i32", "Two", 8, VectorIndexS>;
8797 defm : SIMDLdStSingleAliases<asm, "d", "i64", "Two", 16, VectorIndexD>;
8798}
8799
8800multiclass SIMDLdSt3SingleAliases<string asm> {
8801 defm : SIMDLdStSingleAliases<asm, "b", "i8", "Three", 3, VectorIndexB>;
8802 defm : SIMDLdStSingleAliases<asm, "h", "i16", "Three", 6, VectorIndexH>;
8803 defm : SIMDLdStSingleAliases<asm, "s", "i32", "Three", 12, VectorIndexS>;
8804 defm : SIMDLdStSingleAliases<asm, "d", "i64", "Three", 24, VectorIndexD>;
8805}
8806
8807multiclass SIMDLdSt4SingleAliases<string asm> {
8808 defm : SIMDLdStSingleAliases<asm, "b", "i8", "Four", 4, VectorIndexB>;
8809 defm : SIMDLdStSingleAliases<asm, "h", "i16", "Four", 8, VectorIndexH>;
8810 defm : SIMDLdStSingleAliases<asm, "s", "i32", "Four", 16, VectorIndexS>;
8811 defm : SIMDLdStSingleAliases<asm, "d", "i64", "Four", 32, VectorIndexD>;
8812}
8813} // end of 'let Predicates = [HasNEON]'
8814
8815//----------------------------------------------------------------------------
Vladimir Sukharev297bf0e2015-03-31 13:15:48 +00008816// AdvSIMD v8.1 Rounding Double Multiply Add/Subtract
8817//----------------------------------------------------------------------------
8818
8819let Predicates = [HasNEON, HasV8_1a] in {
8820
8821class BaseSIMDThreeSameVectorTiedR0<bit Q, bit U, bits<2> size, bits<5> opcode,
8822 RegisterOperand regtype, string asm,
8823 string kind, list<dag> pattern>
8824 : BaseSIMDThreeSameVectorTied<Q, U, size, opcode, regtype, asm, kind,
8825 pattern> {
8826 let Inst{21}=0;
8827}
8828multiclass SIMDThreeSameVectorSQRDMLxHTiedHS<bit U, bits<5> opc, string asm,
8829 SDPatternOperator Accum> {
8830 def v4i16 : BaseSIMDThreeSameVectorTiedR0<0, U, 0b01, opc, V64, asm, ".4h",
8831 [(set (v4i16 V64:$dst),
8832 (Accum (v4i16 V64:$Rd),
8833 (v4i16 (int_aarch64_neon_sqrdmulh (v4i16 V64:$Rn),
8834 (v4i16 V64:$Rm)))))]>;
8835 def v8i16 : BaseSIMDThreeSameVectorTiedR0<1, U, 0b01, opc, V128, asm, ".8h",
8836 [(set (v8i16 V128:$dst),
8837 (Accum (v8i16 V128:$Rd),
8838 (v8i16 (int_aarch64_neon_sqrdmulh (v8i16 V128:$Rn),
8839 (v8i16 V128:$Rm)))))]>;
8840 def v2i32 : BaseSIMDThreeSameVectorTiedR0<0, U, 0b10, opc, V64, asm, ".2s",
8841 [(set (v2i32 V64:$dst),
8842 (Accum (v2i32 V64:$Rd),
8843 (v2i32 (int_aarch64_neon_sqrdmulh (v2i32 V64:$Rn),
8844 (v2i32 V64:$Rm)))))]>;
8845 def v4i32 : BaseSIMDThreeSameVectorTiedR0<1, U, 0b10, opc, V128, asm, ".4s",
8846 [(set (v4i32 V128:$dst),
8847 (Accum (v4i32 V128:$Rd),
8848 (v4i32 (int_aarch64_neon_sqrdmulh (v4i32 V128:$Rn),
8849 (v4i32 V128:$Rm)))))]>;
8850}
8851
8852multiclass SIMDIndexedSQRDMLxHSDTied<bit U, bits<4> opc, string asm,
8853 SDPatternOperator Accum> {
8854 def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc,
8855 V64, V64, V128_lo, VectorIndexH,
8856 asm, ".4h", ".4h", ".4h", ".h",
8857 [(set (v4i16 V64:$dst),
8858 (Accum (v4i16 V64:$Rd),
8859 (v4i16 (int_aarch64_neon_sqrdmulh
8860 (v4i16 V64:$Rn),
8861 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm),
8862 VectorIndexH:$idx))))))]> {
8863 bits<3> idx;
8864 let Inst{11} = idx{2};
8865 let Inst{21} = idx{1};
8866 let Inst{20} = idx{0};
8867 }
8868
8869 def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc,
8870 V128, V128, V128_lo, VectorIndexH,
8871 asm, ".8h", ".8h", ".8h", ".h",
8872 [(set (v8i16 V128:$dst),
8873 (Accum (v8i16 V128:$Rd),
8874 (v8i16 (int_aarch64_neon_sqrdmulh
8875 (v8i16 V128:$Rn),
8876 (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm),
8877 VectorIndexH:$idx))))))]> {
8878 bits<3> idx;
8879 let Inst{11} = idx{2};
8880 let Inst{21} = idx{1};
8881 let Inst{20} = idx{0};
8882 }
8883
8884 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc,
8885 V64, V64, V128, VectorIndexS,
8886 asm, ".2s", ".2s", ".2s", ".s",
8887 [(set (v2i32 V64:$dst),
8888 (Accum (v2i32 V64:$Rd),
8889 (v2i32 (int_aarch64_neon_sqrdmulh
8890 (v2i32 V64:$Rn),
8891 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm),
8892 VectorIndexS:$idx))))))]> {
8893 bits<2> idx;
8894 let Inst{11} = idx{1};
8895 let Inst{21} = idx{0};
8896 }
8897
8898 // FIXME: it would be nice to use the scalar (v1i32) instruction here, but
8899 // an intermediate EXTRACT_SUBREG would be untyped.
8900 // FIXME: direct EXTRACT_SUBREG from v2i32 to i32 is illegal, that's why we
8901 // got it lowered here as (i32 vector_extract (v4i32 insert_subvector(..)))
8902 def : Pat<(i32 (Accum (i32 FPR32Op:$Rd),
8903 (i32 (vector_extract
8904 (v4i32 (insert_subvector
8905 (undef),
8906 (v2i32 (int_aarch64_neon_sqrdmulh
8907 (v2i32 V64:$Rn),
8908 (v2i32 (AArch64duplane32
8909 (v4i32 V128:$Rm),
8910 VectorIndexS:$idx)))),
8911 (i32 0))),
8912 (i64 0))))),
8913 (EXTRACT_SUBREG
8914 (v2i32 (!cast<Instruction>(NAME # v2i32_indexed)
8915 (v2i32 (INSERT_SUBREG (v2i32 (IMPLICIT_DEF)),
8916 FPR32Op:$Rd,
8917 ssub)),
8918 V64:$Rn,
8919 V128:$Rm,
8920 VectorIndexS:$idx)),
8921 ssub)>;
8922
8923 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc,
8924 V128, V128, V128, VectorIndexS,
8925 asm, ".4s", ".4s", ".4s", ".s",
8926 [(set (v4i32 V128:$dst),
8927 (Accum (v4i32 V128:$Rd),
8928 (v4i32 (int_aarch64_neon_sqrdmulh
8929 (v4i32 V128:$Rn),
8930 (v4i32 (AArch64duplane32 (v4i32 V128:$Rm),
8931 VectorIndexS:$idx))))))]> {
8932 bits<2> idx;
8933 let Inst{11} = idx{1};
8934 let Inst{21} = idx{0};
8935 }
8936
8937 // FIXME: it would be nice to use the scalar (v1i32) instruction here, but
8938 // an intermediate EXTRACT_SUBREG would be untyped.
8939 def : Pat<(i32 (Accum (i32 FPR32Op:$Rd),
8940 (i32 (vector_extract
8941 (v4i32 (int_aarch64_neon_sqrdmulh
8942 (v4i32 V128:$Rn),
8943 (v4i32 (AArch64duplane32
8944 (v4i32 V128:$Rm),
8945 VectorIndexS:$idx)))),
8946 (i64 0))))),
8947 (EXTRACT_SUBREG
8948 (v4i32 (!cast<Instruction>(NAME # v4i32_indexed)
8949 (v4i32 (INSERT_SUBREG (v4i32 (IMPLICIT_DEF)),
8950 FPR32Op:$Rd,
8951 ssub)),
8952 V128:$Rn,
8953 V128:$Rm,
8954 VectorIndexS:$idx)),
8955 ssub)>;
8956
8957 def i16_indexed : BaseSIMDIndexedTied<1, U, 1, 0b01, opc,
8958 FPR16Op, FPR16Op, V128_lo,
8959 VectorIndexH, asm, ".h", "", "", ".h",
8960 []> {
8961 bits<3> idx;
8962 let Inst{11} = idx{2};
8963 let Inst{21} = idx{1};
8964 let Inst{20} = idx{0};
8965 }
8966
8967 def i32_indexed : BaseSIMDIndexedTied<1, U, 1, 0b10, opc,
8968 FPR32Op, FPR32Op, V128, VectorIndexS,
8969 asm, ".s", "", "", ".s",
8970 [(set (i32 FPR32Op:$dst),
8971 (Accum (i32 FPR32Op:$Rd),
8972 (i32 (int_aarch64_neon_sqrdmulh
8973 (i32 FPR32Op:$Rn),
8974 (i32 (vector_extract (v4i32 V128:$Rm),
8975 VectorIndexS:$idx))))))]> {
8976 bits<2> idx;
8977 let Inst{11} = idx{1};
8978 let Inst{21} = idx{0};
8979 }
8980}
8981} // let Predicates = [HasNeon, HasV8_1a]
8982
8983//----------------------------------------------------------------------------
Tim Northover3b0846e2014-05-24 12:50:23 +00008984// Crypto extensions
8985//----------------------------------------------------------------------------
8986
8987let Predicates = [HasCrypto] in {
8988let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
8989class AESBase<bits<4> opc, string asm, dag outs, dag ins, string cstr,
8990 list<dag> pat>
8991 : I<outs, ins, asm, "{\t$Rd.16b, $Rn.16b|.16b\t$Rd, $Rn}", cstr, pat>,
8992 Sched<[WriteV]>{
8993 bits<5> Rd;
8994 bits<5> Rn;
8995 let Inst{31-16} = 0b0100111000101000;
8996 let Inst{15-12} = opc;
8997 let Inst{11-10} = 0b10;
8998 let Inst{9-5} = Rn;
8999 let Inst{4-0} = Rd;
9000}
9001
9002class AESInst<bits<4> opc, string asm, Intrinsic OpNode>
9003 : AESBase<opc, asm, (outs V128:$Rd), (ins V128:$Rn), "",
9004 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>;
9005
9006class AESTiedInst<bits<4> opc, string asm, Intrinsic OpNode>
9007 : AESBase<opc, asm, (outs V128:$dst), (ins V128:$Rd, V128:$Rn),
9008 "$Rd = $dst",
9009 [(set (v16i8 V128:$dst),
9010 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn)))]>;
9011
9012let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
9013class SHA3OpTiedInst<bits<3> opc, string asm, string dst_lhs_kind,
9014 dag oops, dag iops, list<dag> pat>
9015 : I<oops, iops, asm,
9016 "{\t$Rd" # dst_lhs_kind # ", $Rn" # dst_lhs_kind # ", $Rm.4s" #
9017 "|.4s\t$Rd, $Rn, $Rm}", "$Rd = $dst", pat>,
9018 Sched<[WriteV]>{
9019 bits<5> Rd;
9020 bits<5> Rn;
9021 bits<5> Rm;
9022 let Inst{31-21} = 0b01011110000;
9023 let Inst{20-16} = Rm;
9024 let Inst{15} = 0;
9025 let Inst{14-12} = opc;
9026 let Inst{11-10} = 0b00;
9027 let Inst{9-5} = Rn;
9028 let Inst{4-0} = Rd;
9029}
9030
9031class SHATiedInstQSV<bits<3> opc, string asm, Intrinsic OpNode>
9032 : SHA3OpTiedInst<opc, asm, "", (outs FPR128:$dst),
9033 (ins FPR128:$Rd, FPR32:$Rn, V128:$Rm),
9034 [(set (v4i32 FPR128:$dst),
9035 (OpNode (v4i32 FPR128:$Rd), (i32 FPR32:$Rn),
9036 (v4i32 V128:$Rm)))]>;
9037
9038class SHATiedInstVVV<bits<3> opc, string asm, Intrinsic OpNode>
9039 : SHA3OpTiedInst<opc, asm, ".4s", (outs V128:$dst),
9040 (ins V128:$Rd, V128:$Rn, V128:$Rm),
9041 [(set (v4i32 V128:$dst),
9042 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn),
9043 (v4i32 V128:$Rm)))]>;
9044
9045class SHATiedInstQQV<bits<3> opc, string asm, Intrinsic OpNode>
9046 : SHA3OpTiedInst<opc, asm, "", (outs FPR128:$dst),
9047 (ins FPR128:$Rd, FPR128:$Rn, V128:$Rm),
9048 [(set (v4i32 FPR128:$dst),
9049 (OpNode (v4i32 FPR128:$Rd), (v4i32 FPR128:$Rn),
9050 (v4i32 V128:$Rm)))]>;
9051
9052let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
9053class SHA2OpInst<bits<4> opc, string asm, string kind,
9054 string cstr, dag oops, dag iops,
9055 list<dag> pat>
9056 : I<oops, iops, asm, "{\t$Rd" # kind # ", $Rn" # kind #
9057 "|" # kind # "\t$Rd, $Rn}", cstr, pat>,
9058 Sched<[WriteV]>{
9059 bits<5> Rd;
9060 bits<5> Rn;
9061 let Inst{31-16} = 0b0101111000101000;
9062 let Inst{15-12} = opc;
9063 let Inst{11-10} = 0b10;
9064 let Inst{9-5} = Rn;
9065 let Inst{4-0} = Rd;
9066}
9067
9068class SHATiedInstVV<bits<4> opc, string asm, Intrinsic OpNode>
9069 : SHA2OpInst<opc, asm, ".4s", "$Rd = $dst", (outs V128:$dst),
9070 (ins V128:$Rd, V128:$Rn),
9071 [(set (v4i32 V128:$dst),
9072 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn)))]>;
9073
9074class SHAInstSS<bits<4> opc, string asm, Intrinsic OpNode>
9075 : SHA2OpInst<opc, asm, "", "", (outs FPR32:$Rd), (ins FPR32:$Rn),
9076 [(set (i32 FPR32:$Rd), (OpNode (i32 FPR32:$Rn)))]>;
9077} // end of 'let Predicates = [HasCrypto]'
9078
Vladimir Sukharev5f6f60d2015-06-02 10:58:41 +00009079//----------------------------------------------------------------------------
9080// v8.1 atomic instructions extension:
9081// * CAS
9082// * CASP
9083// * SWP
9084// * LDOPregister<OP>, and aliases STOPregister<OP>
9085
9086// Instruction encodings:
9087//
9088// 31 30|29 24|23|22|21|20 16|15|14 10|9 5|4 0
9089// CAS SZ |001000|1 |A |1 |Rs |R |11111 |Rn |Rt
9090// CASP 0|SZ|001000|0 |A |1 |Rs |R |11111 |Rn |Rt
9091// SWP SZ |111000|A |R |1 |Rs |1 |OPC|00|Rn |Rt
9092// LD SZ |111000|A |R |1 |Rs |0 |OPC|00|Rn |Rt
9093// ST SZ |111000|A |R |1 |Rs |0 |OPC|00|Rn |11111
9094
9095// Instruction syntax:
9096//
9097// CAS{<order>}[<size>] <Ws>, <Wt>, [<Xn|SP>]
9098// CAS{<order>} <Xs>, <Xt>, [<Xn|SP>]
9099// CASP{<order>} <Ws>, <W(s+1)>, <Wt>, <W(t+1)>, [<Xn|SP>]
9100// CASP{<order>} <Xs>, <X(s+1)>, <Xt>, <X(t+1)>, [<Xn|SP>]
9101// SWP{<order>}[<size>] <Ws>, <Wt>, [<Xn|SP>]
9102// SWP{<order>} <Xs>, <Xt>, [<Xn|SP>]
9103// LD<OP>{<order>}[<size>] <Ws>, <Wt>, [<Xn|SP>]
9104// LD<OP>{<order>} <Xs>, <Xt>, [<Xn|SP>]
9105// ST<OP>{<order>}[<size>] <Ws>, [<Xn|SP>]
9106// ST<OP>{<order>} <Xs>, [<Xn|SP>]
9107
9108let Predicates = [HasV8_1a], mayLoad = 1, mayStore = 1, hasSideEffects = 1 in
9109class BaseCASEncoding<dag oops, dag iops, string asm, string operands,
9110 string cstr, list<dag> pattern>
9111 : I<oops, iops, asm, operands, cstr, pattern> {
9112 bits<2> Sz;
9113 bit NP;
9114 bit Acq;
9115 bit Rel;
9116 bits<5> Rs;
9117 bits<5> Rn;
9118 bits<5> Rt;
9119 let Inst{31-30} = Sz;
9120 let Inst{29-24} = 0b001000;
9121 let Inst{23} = NP;
9122 let Inst{22} = Acq;
9123 let Inst{21} = 0b1;
9124 let Inst{20-16} = Rs;
9125 let Inst{15} = Rel;
9126 let Inst{14-10} = 0b11111;
9127 let Inst{9-5} = Rn;
9128 let Inst{4-0} = Rt;
9129}
9130
9131class BaseCAS<string order, string size, RegisterClass RC>
9132 : BaseCASEncoding<(outs RC:$out),(ins RC:$Rs, RC:$Rt, GPR64sp:$Rn),
9133 "cas" # order # size, "\t$Rs, $Rt, [$Rn]",
9134 "$out = $Rs",[]> {
9135 let NP = 1;
9136}
9137
9138multiclass CompareAndSwap<bits<1> Acq, bits<1> Rel, string order> {
9139 let Sz = 0b00, Acq = Acq, Rel = Rel in def b : BaseCAS<order, "b", GPR32>;
9140 let Sz = 0b01, Acq = Acq, Rel = Rel in def h : BaseCAS<order, "h", GPR32>;
9141 let Sz = 0b10, Acq = Acq, Rel = Rel in def s : BaseCAS<order, "", GPR32>;
9142 let Sz = 0b11, Acq = Acq, Rel = Rel in def d : BaseCAS<order, "", GPR64>;
9143}
9144
9145class BaseCASP<string order, string size, RegisterOperand RC>
9146 : BaseCASEncoding<(outs RC:$out),(ins RC:$Rs, RC:$Rt, GPR64sp:$Rn),
9147 "casp" # order # size, "\t$Rs, $Rt, [$Rn]",
9148 "$out = $Rs",[]> {
9149 let NP = 0;
9150}
9151
9152multiclass CompareAndSwapPair<bits<1> Acq, bits<1> Rel, string order> {
9153 let Sz = 0b00, Acq = Acq, Rel = Rel in
9154 def s : BaseCASP<order, "", WSeqPairClassOperand>;
9155 let Sz = 0b01, Acq = Acq, Rel = Rel in
9156 def d : BaseCASP<order, "", XSeqPairClassOperand>;
9157}
9158
9159let Predicates = [HasV8_1a] in
9160class BaseSWP<string order, string size, RegisterClass RC>
9161 : I<(outs RC:$Rt),(ins RC:$Rs, GPR64sp:$Rn), "swp" # order # size,
9162 "\t$Rs, $Rt, [$Rn]","",[]> {
9163 bits<2> Sz;
9164 bit Acq;
9165 bit Rel;
9166 bits<5> Rs;
9167 bits<3> opc = 0b000;
9168 bits<5> Rn;
9169 bits<5> Rt;
9170 let Inst{31-30} = Sz;
9171 let Inst{29-24} = 0b111000;
9172 let Inst{23} = Acq;
9173 let Inst{22} = Rel;
9174 let Inst{21} = 0b1;
9175 let Inst{20-16} = Rs;
9176 let Inst{15} = 0b1;
9177 let Inst{14-12} = opc;
9178 let Inst{11-10} = 0b00;
9179 let Inst{9-5} = Rn;
9180 let Inst{4-0} = Rt;
9181}
9182
9183multiclass Swap<bits<1> Acq, bits<1> Rel, string order> {
9184 let Sz = 0b00, Acq = Acq, Rel = Rel in def b : BaseSWP<order, "b", GPR32>;
9185 let Sz = 0b01, Acq = Acq, Rel = Rel in def h : BaseSWP<order, "h", GPR32>;
9186 let Sz = 0b10, Acq = Acq, Rel = Rel in def s : BaseSWP<order, "", GPR32>;
9187 let Sz = 0b11, Acq = Acq, Rel = Rel in def d : BaseSWP<order, "", GPR64>;
9188}
9189
9190let Predicates = [HasV8_1a], mayLoad = 1, mayStore = 1, hasSideEffects = 1 in
9191class BaseLDOPregister<string op, string order, string size, RegisterClass RC>
9192 : I<(outs RC:$Rt),(ins RC:$Rs, GPR64sp:$Rn), "ld" # op # order # size,
9193 "\t$Rs, $Rt, [$Rn]","",[]> {
9194 bits<2> Sz;
9195 bit Acq;
9196 bit Rel;
9197 bits<5> Rs;
9198 bits<3> opc;
9199 bits<5> Rn;
9200 bits<5> Rt;
9201 let Inst{31-30} = Sz;
9202 let Inst{29-24} = 0b111000;
9203 let Inst{23} = Acq;
9204 let Inst{22} = Rel;
9205 let Inst{21} = 0b1;
9206 let Inst{20-16} = Rs;
9207 let Inst{15} = 0b0;
9208 let Inst{14-12} = opc;
9209 let Inst{11-10} = 0b00;
9210 let Inst{9-5} = Rn;
9211 let Inst{4-0} = Rt;
9212}
9213
9214multiclass LDOPregister<bits<3> opc, string op, bits<1> Acq, bits<1> Rel,
9215 string order> {
9216 let Sz = 0b00, Acq = Acq, Rel = Rel, opc = opc in
9217 def b : BaseLDOPregister<op, order, "b", GPR32>;
9218 let Sz = 0b01, Acq = Acq, Rel = Rel, opc = opc in
9219 def h : BaseLDOPregister<op, order, "h", GPR32>;
9220 let Sz = 0b10, Acq = Acq, Rel = Rel, opc = opc in
9221 def s : BaseLDOPregister<op, order, "", GPR32>;
9222 let Sz = 0b11, Acq = Acq, Rel = Rel, opc = opc in
9223 def d : BaseLDOPregister<op, order, "", GPR64>;
9224}
9225
9226let Predicates = [HasV8_1a] in
9227class BaseSTOPregister<string asm, RegisterClass OP, Register Reg,
9228 Instruction inst> :
9229 InstAlias<asm # "\t$Rs, [$Rn]", (inst Reg, OP:$Rs, GPR64sp:$Rn)>;
9230
9231multiclass STOPregister<string asm, string instr> {
9232 def : BaseSTOPregister<asm # "lb", GPR32, WZR,
9233 !cast<Instruction>(instr # "Lb")>;
9234 def : BaseSTOPregister<asm # "lh", GPR32, WZR,
9235 !cast<Instruction>(instr # "Lh")>;
9236 def : BaseSTOPregister<asm # "l", GPR32, WZR,
9237 !cast<Instruction>(instr # "Ls")>;
9238 def : BaseSTOPregister<asm # "l", GPR64, XZR,
9239 !cast<Instruction>(instr # "Ld")>;
9240 def : BaseSTOPregister<asm # "b", GPR32, WZR,
9241 !cast<Instruction>(instr # "b")>;
9242 def : BaseSTOPregister<asm # "h", GPR32, WZR,
9243 !cast<Instruction>(instr # "h")>;
9244 def : BaseSTOPregister<asm, GPR32, WZR,
9245 !cast<Instruction>(instr # "s")>;
9246 def : BaseSTOPregister<asm, GPR64, XZR,
9247 !cast<Instruction>(instr # "d")>;
9248}
9249
9250//----------------------------------------------------------------------------
Tim Northover3b0846e2014-05-24 12:50:23 +00009251// Allow the size specifier tokens to be upper case, not just lower.
9252def : TokenAlias<".8B", ".8b">;
9253def : TokenAlias<".4H", ".4h">;
9254def : TokenAlias<".2S", ".2s">;
9255def : TokenAlias<".1D", ".1d">;
9256def : TokenAlias<".16B", ".16b">;
9257def : TokenAlias<".8H", ".8h">;
9258def : TokenAlias<".4S", ".4s">;
9259def : TokenAlias<".2D", ".2d">;
9260def : TokenAlias<".1Q", ".1q">;
9261def : TokenAlias<".B", ".b">;
9262def : TokenAlias<".H", ".h">;
9263def : TokenAlias<".S", ".s">;
9264def : TokenAlias<".D", ".d">;
9265def : TokenAlias<".Q", ".q">;