blob: 101b0f7e1d3a96a89bcd23fcbd678d60d1042189 [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
Oliver Stannarda34e4702015-12-01 10:48:51 +0000914def PSBHintOperand : AsmOperandClass {
915 let Name = "PSBHint";
916 let ParserMethod = "tryParsePSBHint";
917}
918def psbhint_op : Operand<i32> {
919 let ParserMatchClass = PSBHintOperand;
920 let PrintMethod = "printPSBHintOp";
921 let MCOperandPredicate = [{
922 // Check, if operand is valid, to fix exhaustive aliasing in disassembly.
923 // "psb" is an alias to "hint" only for certain values of CRm:Op2 fields.
924 if (!MCOp.isImm())
925 return false;
926 bool ValidNamed;
927 (void)AArch64PSBHint::PSBHintMapper().toString(MCOp.getImm(),
928 STI.getFeatureBits(), ValidNamed);
929 return ValidNamed;
930 }];
931}
932
Tim Northover3b0846e2014-05-24 12:50:23 +0000933class MRSI : RtSystemI<1, (outs GPR64:$Rt), (ins mrs_sysreg_op:$systemreg),
934 "mrs", "\t$Rt, $systemreg"> {
Tom Coxone493f172014-10-01 10:13:59 +0000935 bits<16> systemreg;
936 let Inst{20-5} = systemreg;
Tim Northover3b0846e2014-05-24 12:50:23 +0000937}
938
939// FIXME: Some of these def NZCV, others don't. Best way to model that?
940// Explicitly modeling each of the system register as a register class
941// would do it, but feels like overkill at this point.
942class MSRI : RtSystemI<0, (outs), (ins msr_sysreg_op:$systemreg, GPR64:$Rt),
943 "msr", "\t$systemreg, $Rt"> {
Tom Coxone493f172014-10-01 10:13:59 +0000944 bits<16> systemreg;
945 let Inst{20-5} = systemreg;
Tim Northover3b0846e2014-05-24 12:50:23 +0000946}
947
Alexandros Lamprineas1bab1912015-10-05 13:42:31 +0000948def SystemPStateFieldWithImm0_15Operand : AsmOperandClass {
949 let Name = "SystemPStateFieldWithImm0_15";
Tim Northover3b0846e2014-05-24 12:50:23 +0000950 let ParserMethod = "tryParseSysReg";
951}
Alexandros Lamprineas1bab1912015-10-05 13:42:31 +0000952def pstatefield4_op : Operand<i32> {
953 let ParserMatchClass = SystemPStateFieldWithImm0_15Operand;
Tim Northover3b0846e2014-05-24 12:50:23 +0000954 let PrintMethod = "printSystemPStateField";
955}
956
957let Defs = [NZCV] in
Alexandros Lamprineas1bab1912015-10-05 13:42:31 +0000958class MSRpstateImm0_15
959 : SimpleSystemI<0, (ins pstatefield4_op:$pstatefield, imm0_15:$imm),
960 "msr", "\t$pstatefield, $imm">,
Tim Northover3b0846e2014-05-24 12:50:23 +0000961 Sched<[WriteSys]> {
962 bits<6> pstatefield;
963 bits<4> imm;
964 let Inst{20-19} = 0b00;
965 let Inst{18-16} = pstatefield{5-3};
966 let Inst{15-12} = 0b0100;
967 let Inst{11-8} = imm;
968 let Inst{7-5} = pstatefield{2-0};
969
970 let DecoderMethod = "DecodeSystemPStateInstruction";
Petr Pavlu097adfb2015-07-15 08:10:30 +0000971 // MSRpstateI aliases with MSRI. When the MSRpstateI decoder method returns
972 // Fail the decoder should attempt to decode the instruction as MSRI.
973 let hasCompleteDecoder = 0;
Tim Northover3b0846e2014-05-24 12:50:23 +0000974}
975
Alexandros Lamprineas1bab1912015-10-05 13:42:31 +0000976def SystemPStateFieldWithImm0_1Operand : AsmOperandClass {
977 let Name = "SystemPStateFieldWithImm0_1";
978 let ParserMethod = "tryParseSysReg";
979}
980def pstatefield1_op : Operand<i32> {
981 let ParserMatchClass = SystemPStateFieldWithImm0_1Operand;
982 let PrintMethod = "printSystemPStateField";
983}
984
985let Defs = [NZCV] in
986class MSRpstateImm0_1
987 : SimpleSystemI<0, (ins pstatefield1_op:$pstatefield, imm0_1:$imm),
988 "msr", "\t$pstatefield, $imm">,
989 Sched<[WriteSys]> {
990 bits<6> pstatefield;
991 bit imm;
992 let Inst{20-19} = 0b00;
993 let Inst{18-16} = pstatefield{5-3};
994 let Inst{15-9} = 0b0100000;
995 let Inst{8} = imm;
996 let Inst{7-5} = pstatefield{2-0};
997
998 let DecoderMethod = "DecodeSystemPStateInstruction";
999 // MSRpstateI aliases with MSRI. When the MSRpstateI decoder method returns
1000 // Fail the decoder should attempt to decode the instruction as MSRI.
1001 let hasCompleteDecoder = 0;
1002}
1003
Tim Northover3b0846e2014-05-24 12:50:23 +00001004// SYS and SYSL generic system instructions.
1005def SysCRAsmOperand : AsmOperandClass {
1006 let Name = "SysCR";
1007 let ParserMethod = "tryParseSysCROperand";
1008}
1009
1010def sys_cr_op : Operand<i32> {
1011 let PrintMethod = "printSysCROperand";
1012 let ParserMatchClass = SysCRAsmOperand;
1013}
1014
1015class SystemXtI<bit L, string asm>
1016 : RtSystemI<L, (outs),
1017 (ins imm0_7:$op1, sys_cr_op:$Cn, sys_cr_op:$Cm, imm0_7:$op2, GPR64:$Rt),
1018 asm, "\t$op1, $Cn, $Cm, $op2, $Rt"> {
1019 bits<3> op1;
1020 bits<4> Cn;
1021 bits<4> Cm;
1022 bits<3> op2;
1023 let Inst{20-19} = 0b01;
1024 let Inst{18-16} = op1;
1025 let Inst{15-12} = Cn;
1026 let Inst{11-8} = Cm;
1027 let Inst{7-5} = op2;
1028}
1029
1030class SystemLXtI<bit L, string asm>
1031 : RtSystemI<L, (outs),
1032 (ins GPR64:$Rt, imm0_7:$op1, sys_cr_op:$Cn, sys_cr_op:$Cm, imm0_7:$op2),
1033 asm, "\t$Rt, $op1, $Cn, $Cm, $op2"> {
1034 bits<3> op1;
1035 bits<4> Cn;
1036 bits<4> Cm;
1037 bits<3> op2;
1038 let Inst{20-19} = 0b01;
1039 let Inst{18-16} = op1;
1040 let Inst{15-12} = Cn;
1041 let Inst{11-8} = Cm;
1042 let Inst{7-5} = op2;
1043}
1044
1045
1046// Branch (register) instructions:
1047//
1048// case opc of
1049// 0001 blr
1050// 0000 br
1051// 0101 dret
1052// 0100 eret
1053// 0010 ret
1054// otherwise UNDEFINED
1055class BaseBranchReg<bits<4> opc, dag oops, dag iops, string asm,
1056 string operands, list<dag> pattern>
1057 : I<oops, iops, asm, operands, "", pattern>, Sched<[WriteBrReg]> {
1058 let Inst{31-25} = 0b1101011;
1059 let Inst{24-21} = opc;
1060 let Inst{20-16} = 0b11111;
1061 let Inst{15-10} = 0b000000;
1062 let Inst{4-0} = 0b00000;
1063}
1064
1065class BranchReg<bits<4> opc, string asm, list<dag> pattern>
1066 : BaseBranchReg<opc, (outs), (ins GPR64:$Rn), asm, "\t$Rn", pattern> {
1067 bits<5> Rn;
1068 let Inst{9-5} = Rn;
1069}
1070
1071let mayLoad = 0, mayStore = 0, hasSideEffects = 1, isReturn = 1 in
1072class SpecialReturn<bits<4> opc, string asm>
1073 : BaseBranchReg<opc, (outs), (ins), asm, "", []> {
1074 let Inst{9-5} = 0b11111;
1075}
1076
1077//---
1078// Conditional branch instruction.
1079//---
1080
1081// Condition code.
1082// 4-bit immediate. Pretty-printed as <cc>
1083def ccode : Operand<i32> {
1084 let PrintMethod = "printCondCode";
1085 let ParserMatchClass = CondCode;
1086}
1087def inv_ccode : Operand<i32> {
Artyom Skrobov6c8682e2014-06-10 13:11:35 +00001088 // AL and NV are invalid in the aliases which use inv_ccode
Tim Northover3b0846e2014-05-24 12:50:23 +00001089 let PrintMethod = "printInverseCondCode";
1090 let ParserMatchClass = CondCode;
Artyom Skrobov6c8682e2014-06-10 13:11:35 +00001091 let MCOperandPredicate = [{
1092 return MCOp.isImm() &&
1093 MCOp.getImm() != AArch64CC::AL &&
1094 MCOp.getImm() != AArch64CC::NV;
1095 }];
Tim Northover3b0846e2014-05-24 12:50:23 +00001096}
1097
1098// Conditional branch target. 19-bit immediate. The low two bits of the target
1099// offset are implied zero and so are not part of the immediate.
1100def PCRelLabel19Operand : AsmOperandClass {
1101 let Name = "PCRelLabel19";
1102 let DiagnosticType = "InvalidLabel";
1103}
1104def am_brcond : Operand<OtherVT> {
1105 let EncoderMethod = "getCondBranchTargetOpValue";
1106 let DecoderMethod = "DecodePCRelLabel19";
1107 let PrintMethod = "printAlignedLabel";
1108 let ParserMatchClass = PCRelLabel19Operand;
1109}
1110
1111class BranchCond : I<(outs), (ins ccode:$cond, am_brcond:$target),
1112 "b", ".$cond\t$target", "",
1113 [(AArch64brcond bb:$target, imm:$cond, NZCV)]>,
1114 Sched<[WriteBr]> {
1115 let isBranch = 1;
1116 let isTerminator = 1;
1117 let Uses = [NZCV];
1118
1119 bits<4> cond;
1120 bits<19> target;
1121 let Inst{31-24} = 0b01010100;
1122 let Inst{23-5} = target;
1123 let Inst{4} = 0;
1124 let Inst{3-0} = cond;
1125}
1126
1127//---
1128// Compare-and-branch instructions.
1129//---
1130class BaseCmpBranch<RegisterClass regtype, bit op, string asm, SDNode node>
1131 : I<(outs), (ins regtype:$Rt, am_brcond:$target),
1132 asm, "\t$Rt, $target", "",
1133 [(node regtype:$Rt, bb:$target)]>,
1134 Sched<[WriteBr]> {
1135 let isBranch = 1;
1136 let isTerminator = 1;
1137
1138 bits<5> Rt;
1139 bits<19> target;
1140 let Inst{30-25} = 0b011010;
1141 let Inst{24} = op;
1142 let Inst{23-5} = target;
1143 let Inst{4-0} = Rt;
1144}
1145
1146multiclass CmpBranch<bit op, string asm, SDNode node> {
1147 def W : BaseCmpBranch<GPR32, op, asm, node> {
1148 let Inst{31} = 0;
1149 }
1150 def X : BaseCmpBranch<GPR64, op, asm, node> {
1151 let Inst{31} = 1;
1152 }
1153}
1154
1155//---
1156// Test-bit-and-branch instructions.
1157//---
1158// Test-and-branch target. 14-bit sign-extended immediate. The low two bits of
1159// the target offset are implied zero and so are not part of the immediate.
1160def BranchTarget14Operand : AsmOperandClass {
1161 let Name = "BranchTarget14";
1162}
1163def am_tbrcond : Operand<OtherVT> {
1164 let EncoderMethod = "getTestBranchTargetOpValue";
1165 let PrintMethod = "printAlignedLabel";
1166 let ParserMatchClass = BranchTarget14Operand;
1167}
1168
1169// AsmOperand classes to emit (or not) special diagnostics
1170def TBZImm0_31Operand : AsmOperandClass {
1171 let Name = "TBZImm0_31";
1172 let PredicateMethod = "isImm0_31";
1173 let RenderMethod = "addImm0_31Operands";
1174}
1175def TBZImm32_63Operand : AsmOperandClass {
1176 let Name = "Imm32_63";
1177 let DiagnosticType = "InvalidImm0_63";
1178}
1179
1180class tbz_imm0_31<AsmOperandClass matcher> : Operand<i64>, ImmLeaf<i64, [{
1181 return (((uint32_t)Imm) < 32);
1182}]> {
1183 let ParserMatchClass = matcher;
1184}
1185
1186def tbz_imm0_31_diag : tbz_imm0_31<Imm0_31Operand>;
1187def tbz_imm0_31_nodiag : tbz_imm0_31<TBZImm0_31Operand>;
1188
1189def tbz_imm32_63 : Operand<i64>, ImmLeaf<i64, [{
1190 return (((uint32_t)Imm) > 31) && (((uint32_t)Imm) < 64);
1191}]> {
1192 let ParserMatchClass = TBZImm32_63Operand;
1193}
1194
1195class BaseTestBranch<RegisterClass regtype, Operand immtype,
1196 bit op, string asm, SDNode node>
1197 : I<(outs), (ins regtype:$Rt, immtype:$bit_off, am_tbrcond:$target),
1198 asm, "\t$Rt, $bit_off, $target", "",
1199 [(node regtype:$Rt, immtype:$bit_off, bb:$target)]>,
1200 Sched<[WriteBr]> {
1201 let isBranch = 1;
1202 let isTerminator = 1;
1203
1204 bits<5> Rt;
1205 bits<6> bit_off;
1206 bits<14> target;
1207
1208 let Inst{30-25} = 0b011011;
1209 let Inst{24} = op;
1210 let Inst{23-19} = bit_off{4-0};
1211 let Inst{18-5} = target;
1212 let Inst{4-0} = Rt;
1213
1214 let DecoderMethod = "DecodeTestAndBranch";
1215}
1216
1217multiclass TestBranch<bit op, string asm, SDNode node> {
1218 def W : BaseTestBranch<GPR32, tbz_imm0_31_diag, op, asm, node> {
1219 let Inst{31} = 0;
1220 }
1221
1222 def X : BaseTestBranch<GPR64, tbz_imm32_63, op, asm, node> {
1223 let Inst{31} = 1;
1224 }
1225
1226 // Alias X-reg with 0-31 imm to W-Reg.
1227 def : InstAlias<asm # "\t$Rd, $imm, $target",
1228 (!cast<Instruction>(NAME#"W") GPR32as64:$Rd,
1229 tbz_imm0_31_nodiag:$imm, am_tbrcond:$target), 0>;
1230 def : Pat<(node GPR64:$Rn, tbz_imm0_31_diag:$imm, bb:$target),
1231 (!cast<Instruction>(NAME#"W") (EXTRACT_SUBREG GPR64:$Rn, sub_32),
1232 tbz_imm0_31_diag:$imm, bb:$target)>;
1233}
1234
1235//---
1236// Unconditional branch (immediate) instructions.
1237//---
1238def BranchTarget26Operand : AsmOperandClass {
1239 let Name = "BranchTarget26";
1240 let DiagnosticType = "InvalidLabel";
1241}
1242def am_b_target : Operand<OtherVT> {
1243 let EncoderMethod = "getBranchTargetOpValue";
1244 let PrintMethod = "printAlignedLabel";
1245 let ParserMatchClass = BranchTarget26Operand;
1246}
1247def am_bl_target : Operand<i64> {
1248 let EncoderMethod = "getBranchTargetOpValue";
1249 let PrintMethod = "printAlignedLabel";
1250 let ParserMatchClass = BranchTarget26Operand;
1251}
1252
1253class BImm<bit op, dag iops, string asm, list<dag> pattern>
1254 : I<(outs), iops, asm, "\t$addr", "", pattern>, Sched<[WriteBr]> {
1255 bits<26> addr;
1256 let Inst{31} = op;
1257 let Inst{30-26} = 0b00101;
1258 let Inst{25-0} = addr;
1259
1260 let DecoderMethod = "DecodeUnconditionalBranch";
1261}
1262
1263class BranchImm<bit op, string asm, list<dag> pattern>
1264 : BImm<op, (ins am_b_target:$addr), asm, pattern>;
1265class CallImm<bit op, string asm, list<dag> pattern>
1266 : BImm<op, (ins am_bl_target:$addr), asm, pattern>;
1267
1268//---
1269// Basic one-operand data processing instructions.
1270//---
1271
1272let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
1273class BaseOneOperandData<bits<3> opc, RegisterClass regtype, string asm,
1274 SDPatternOperator node>
1275 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm, "\t$Rd, $Rn", "",
1276 [(set regtype:$Rd, (node regtype:$Rn))]>,
1277 Sched<[WriteI, ReadI]> {
1278 bits<5> Rd;
1279 bits<5> Rn;
1280
1281 let Inst{30-13} = 0b101101011000000000;
1282 let Inst{12-10} = opc;
1283 let Inst{9-5} = Rn;
1284 let Inst{4-0} = Rd;
1285}
1286
1287let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
1288multiclass OneOperandData<bits<3> opc, string asm,
1289 SDPatternOperator node = null_frag> {
1290 def Wr : BaseOneOperandData<opc, GPR32, asm, node> {
1291 let Inst{31} = 0;
1292 }
1293
1294 def Xr : BaseOneOperandData<opc, GPR64, asm, node> {
1295 let Inst{31} = 1;
1296 }
1297}
1298
1299class OneWRegData<bits<3> opc, string asm, SDPatternOperator node>
1300 : BaseOneOperandData<opc, GPR32, asm, node> {
1301 let Inst{31} = 0;
1302}
1303
1304class OneXRegData<bits<3> opc, string asm, SDPatternOperator node>
1305 : BaseOneOperandData<opc, GPR64, asm, node> {
1306 let Inst{31} = 1;
1307}
1308
1309//---
1310// Basic two-operand data processing instructions.
1311//---
1312class BaseBaseAddSubCarry<bit isSub, RegisterClass regtype, string asm,
1313 list<dag> pattern>
1314 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm),
1315 asm, "\t$Rd, $Rn, $Rm", "", pattern>,
1316 Sched<[WriteI, ReadI, ReadI]> {
1317 let Uses = [NZCV];
1318 bits<5> Rd;
1319 bits<5> Rn;
1320 bits<5> Rm;
1321 let Inst{30} = isSub;
1322 let Inst{28-21} = 0b11010000;
1323 let Inst{20-16} = Rm;
1324 let Inst{15-10} = 0;
1325 let Inst{9-5} = Rn;
1326 let Inst{4-0} = Rd;
1327}
1328
1329class BaseAddSubCarry<bit isSub, RegisterClass regtype, string asm,
1330 SDNode OpNode>
1331 : BaseBaseAddSubCarry<isSub, regtype, asm,
1332 [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm, NZCV))]>;
1333
1334class BaseAddSubCarrySetFlags<bit isSub, RegisterClass regtype, string asm,
1335 SDNode OpNode>
1336 : BaseBaseAddSubCarry<isSub, regtype, asm,
1337 [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm, NZCV)),
1338 (implicit NZCV)]> {
1339 let Defs = [NZCV];
1340}
1341
1342multiclass AddSubCarry<bit isSub, string asm, string asm_setflags,
1343 SDNode OpNode, SDNode OpNode_setflags> {
1344 def Wr : BaseAddSubCarry<isSub, GPR32, asm, OpNode> {
1345 let Inst{31} = 0;
1346 let Inst{29} = 0;
1347 }
1348 def Xr : BaseAddSubCarry<isSub, GPR64, asm, OpNode> {
1349 let Inst{31} = 1;
1350 let Inst{29} = 0;
1351 }
1352
1353 // Sets flags.
1354 def SWr : BaseAddSubCarrySetFlags<isSub, GPR32, asm_setflags,
1355 OpNode_setflags> {
1356 let Inst{31} = 0;
1357 let Inst{29} = 1;
1358 }
1359 def SXr : BaseAddSubCarrySetFlags<isSub, GPR64, asm_setflags,
1360 OpNode_setflags> {
1361 let Inst{31} = 1;
1362 let Inst{29} = 1;
1363 }
1364}
1365
1366class BaseTwoOperand<bits<4> opc, RegisterClass regtype, string asm,
1367 SDPatternOperator OpNode>
1368 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm),
1369 asm, "\t$Rd, $Rn, $Rm", "",
1370 [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm))]> {
1371 bits<5> Rd;
1372 bits<5> Rn;
1373 bits<5> Rm;
1374 let Inst{30-21} = 0b0011010110;
1375 let Inst{20-16} = Rm;
1376 let Inst{15-14} = 0b00;
1377 let Inst{13-10} = opc;
1378 let Inst{9-5} = Rn;
1379 let Inst{4-0} = Rd;
1380}
1381
1382class BaseDiv<bit isSigned, RegisterClass regtype, string asm,
1383 SDPatternOperator OpNode>
1384 : BaseTwoOperand<{0,0,1,?}, regtype, asm, OpNode> {
1385 let Inst{10} = isSigned;
1386}
1387
1388multiclass Div<bit isSigned, string asm, SDPatternOperator OpNode> {
1389 def Wr : BaseDiv<isSigned, GPR32, asm, OpNode>,
1390 Sched<[WriteID32, ReadID, ReadID]> {
1391 let Inst{31} = 0;
1392 }
1393 def Xr : BaseDiv<isSigned, GPR64, asm, OpNode>,
1394 Sched<[WriteID64, ReadID, ReadID]> {
1395 let Inst{31} = 1;
1396 }
1397}
1398
1399class BaseShift<bits<2> shift_type, RegisterClass regtype, string asm,
1400 SDPatternOperator OpNode = null_frag>
1401 : BaseTwoOperand<{1,0,?,?}, regtype, asm, OpNode>,
1402 Sched<[WriteIS, ReadI]> {
1403 let Inst{11-10} = shift_type;
1404}
1405
1406multiclass Shift<bits<2> shift_type, string asm, SDNode OpNode> {
1407 def Wr : BaseShift<shift_type, GPR32, asm> {
1408 let Inst{31} = 0;
1409 }
1410
1411 def Xr : BaseShift<shift_type, GPR64, asm, OpNode> {
1412 let Inst{31} = 1;
1413 }
1414
1415 def : Pat<(i32 (OpNode GPR32:$Rn, i64:$Rm)),
1416 (!cast<Instruction>(NAME # "Wr") GPR32:$Rn,
1417 (EXTRACT_SUBREG i64:$Rm, sub_32))>;
1418
1419 def : Pat<(i32 (OpNode GPR32:$Rn, (i64 (zext GPR32:$Rm)))),
1420 (!cast<Instruction>(NAME # "Wr") GPR32:$Rn, GPR32:$Rm)>;
1421
1422 def : Pat<(i32 (OpNode GPR32:$Rn, (i64 (anyext GPR32:$Rm)))),
1423 (!cast<Instruction>(NAME # "Wr") GPR32:$Rn, GPR32:$Rm)>;
1424
1425 def : Pat<(i32 (OpNode GPR32:$Rn, (i64 (sext GPR32:$Rm)))),
1426 (!cast<Instruction>(NAME # "Wr") GPR32:$Rn, GPR32:$Rm)>;
1427}
1428
1429class ShiftAlias<string asm, Instruction inst, RegisterClass regtype>
Ahmed Bougacha63fae0e2015-09-02 18:52:54 +00001430 : InstAlias<asm#"\t$dst, $src1, $src2",
Tim Northover3b0846e2014-05-24 12:50:23 +00001431 (inst regtype:$dst, regtype:$src1, regtype:$src2), 0>;
1432
1433class BaseMulAccum<bit isSub, bits<3> opc, RegisterClass multype,
1434 RegisterClass addtype, string asm,
1435 list<dag> pattern>
1436 : I<(outs addtype:$Rd), (ins multype:$Rn, multype:$Rm, addtype:$Ra),
1437 asm, "\t$Rd, $Rn, $Rm, $Ra", "", pattern> {
1438 bits<5> Rd;
1439 bits<5> Rn;
1440 bits<5> Rm;
1441 bits<5> Ra;
1442 let Inst{30-24} = 0b0011011;
1443 let Inst{23-21} = opc;
1444 let Inst{20-16} = Rm;
1445 let Inst{15} = isSub;
1446 let Inst{14-10} = Ra;
1447 let Inst{9-5} = Rn;
1448 let Inst{4-0} = Rd;
1449}
1450
1451multiclass MulAccum<bit isSub, string asm, SDNode AccNode> {
Gerolf Hoflehner97c383b2014-08-07 21:40:58 +00001452 // MADD/MSUB generation is decided by MachineCombiner.cpp
Tim Northover3b0846e2014-05-24 12:50:23 +00001453 def Wrrr : BaseMulAccum<isSub, 0b000, GPR32, GPR32, asm,
Gerolf Hoflehner97c383b2014-08-07 21:40:58 +00001454 [/*(set GPR32:$Rd, (AccNode GPR32:$Ra, (mul GPR32:$Rn, GPR32:$Rm)))*/]>,
Chad Rosier3fe0c872014-06-09 01:54:00 +00001455 Sched<[WriteIM32, ReadIM, ReadIM, ReadIMA]> {
Tim Northover3b0846e2014-05-24 12:50:23 +00001456 let Inst{31} = 0;
1457 }
1458
1459 def Xrrr : BaseMulAccum<isSub, 0b000, GPR64, GPR64, asm,
Gerolf Hoflehner97c383b2014-08-07 21:40:58 +00001460 [/*(set GPR64:$Rd, (AccNode GPR64:$Ra, (mul GPR64:$Rn, GPR64:$Rm)))*/]>,
Chad Rosier3fe0c872014-06-09 01:54:00 +00001461 Sched<[WriteIM64, ReadIM, ReadIM, ReadIMA]> {
Tim Northover3b0846e2014-05-24 12:50:23 +00001462 let Inst{31} = 1;
1463 }
1464}
1465
1466class WideMulAccum<bit isSub, bits<3> opc, string asm,
1467 SDNode AccNode, SDNode ExtNode>
1468 : BaseMulAccum<isSub, opc, GPR32, GPR64, asm,
1469 [(set GPR64:$Rd, (AccNode GPR64:$Ra,
1470 (mul (ExtNode GPR32:$Rn), (ExtNode GPR32:$Rm))))]>,
Chad Rosier3fe0c872014-06-09 01:54:00 +00001471 Sched<[WriteIM32, ReadIM, ReadIM, ReadIMA]> {
Tim Northover3b0846e2014-05-24 12:50:23 +00001472 let Inst{31} = 1;
1473}
1474
1475class MulHi<bits<3> opc, string asm, SDNode OpNode>
1476 : I<(outs GPR64:$Rd), (ins GPR64:$Rn, GPR64:$Rm),
1477 asm, "\t$Rd, $Rn, $Rm", "",
1478 [(set GPR64:$Rd, (OpNode GPR64:$Rn, GPR64:$Rm))]>,
1479 Sched<[WriteIM64, ReadIM, ReadIM]> {
1480 bits<5> Rd;
1481 bits<5> Rn;
1482 bits<5> Rm;
1483 let Inst{31-24} = 0b10011011;
1484 let Inst{23-21} = opc;
1485 let Inst{20-16} = Rm;
1486 let Inst{15} = 0;
1487 let Inst{9-5} = Rn;
1488 let Inst{4-0} = Rd;
1489
1490 // The Ra field of SMULH and UMULH is unused: it should be assembled as 31
1491 // (i.e. all bits 1) but is ignored by the processor.
1492 let PostEncoderMethod = "fixMulHigh";
1493}
1494
1495class MulAccumWAlias<string asm, Instruction inst>
Ahmed Bougacha63fae0e2015-09-02 18:52:54 +00001496 : InstAlias<asm#"\t$dst, $src1, $src2",
Tim Northover3b0846e2014-05-24 12:50:23 +00001497 (inst GPR32:$dst, GPR32:$src1, GPR32:$src2, WZR)>;
1498class MulAccumXAlias<string asm, Instruction inst>
Ahmed Bougacha63fae0e2015-09-02 18:52:54 +00001499 : InstAlias<asm#"\t$dst, $src1, $src2",
Tim Northover3b0846e2014-05-24 12:50:23 +00001500 (inst GPR64:$dst, GPR64:$src1, GPR64:$src2, XZR)>;
1501class WideMulAccumAlias<string asm, Instruction inst>
Ahmed Bougacha63fae0e2015-09-02 18:52:54 +00001502 : InstAlias<asm#"\t$dst, $src1, $src2",
Tim Northover3b0846e2014-05-24 12:50:23 +00001503 (inst GPR64:$dst, GPR32:$src1, GPR32:$src2, XZR)>;
1504
1505class BaseCRC32<bit sf, bits<2> sz, bit C, RegisterClass StreamReg,
1506 SDPatternOperator OpNode, string asm>
1507 : I<(outs GPR32:$Rd), (ins GPR32:$Rn, StreamReg:$Rm),
1508 asm, "\t$Rd, $Rn, $Rm", "",
1509 [(set GPR32:$Rd, (OpNode GPR32:$Rn, StreamReg:$Rm))]>,
1510 Sched<[WriteISReg, ReadI, ReadISReg]> {
1511 bits<5> Rd;
1512 bits<5> Rn;
1513 bits<5> Rm;
1514
1515 let Inst{31} = sf;
1516 let Inst{30-21} = 0b0011010110;
1517 let Inst{20-16} = Rm;
1518 let Inst{15-13} = 0b010;
1519 let Inst{12} = C;
1520 let Inst{11-10} = sz;
1521 let Inst{9-5} = Rn;
1522 let Inst{4-0} = Rd;
1523 let Predicates = [HasCRC];
1524}
1525
1526//---
1527// Address generation.
1528//---
1529
1530class ADRI<bit page, string asm, Operand adr, list<dag> pattern>
1531 : I<(outs GPR64:$Xd), (ins adr:$label), asm, "\t$Xd, $label", "",
1532 pattern>,
1533 Sched<[WriteI]> {
1534 bits<5> Xd;
1535 bits<21> label;
1536 let Inst{31} = page;
1537 let Inst{30-29} = label{1-0};
1538 let Inst{28-24} = 0b10000;
1539 let Inst{23-5} = label{20-2};
1540 let Inst{4-0} = Xd;
1541
1542 let DecoderMethod = "DecodeAdrInstruction";
1543}
1544
1545//---
1546// Move immediate.
1547//---
1548
1549def movimm32_imm : Operand<i32> {
1550 let ParserMatchClass = Imm0_65535Operand;
1551 let EncoderMethod = "getMoveWideImmOpValue";
1552 let PrintMethod = "printHexImm";
1553}
1554def movimm32_shift : Operand<i32> {
1555 let PrintMethod = "printShifter";
1556 let ParserMatchClass = MovImm32ShifterOperand;
1557}
1558def movimm64_shift : Operand<i32> {
1559 let PrintMethod = "printShifter";
1560 let ParserMatchClass = MovImm64ShifterOperand;
1561}
1562
1563let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
1564class BaseMoveImmediate<bits<2> opc, RegisterClass regtype, Operand shifter,
1565 string asm>
1566 : I<(outs regtype:$Rd), (ins movimm32_imm:$imm, shifter:$shift),
1567 asm, "\t$Rd, $imm$shift", "", []>,
1568 Sched<[WriteImm]> {
1569 bits<5> Rd;
1570 bits<16> imm;
1571 bits<6> shift;
1572 let Inst{30-29} = opc;
1573 let Inst{28-23} = 0b100101;
1574 let Inst{22-21} = shift{5-4};
1575 let Inst{20-5} = imm;
1576 let Inst{4-0} = Rd;
1577
1578 let DecoderMethod = "DecodeMoveImmInstruction";
1579}
1580
1581multiclass MoveImmediate<bits<2> opc, string asm> {
1582 def Wi : BaseMoveImmediate<opc, GPR32, movimm32_shift, asm> {
1583 let Inst{31} = 0;
1584 }
1585
1586 def Xi : BaseMoveImmediate<opc, GPR64, movimm64_shift, asm> {
1587 let Inst{31} = 1;
1588 }
1589}
1590
1591let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
1592class BaseInsertImmediate<bits<2> opc, RegisterClass regtype, Operand shifter,
1593 string asm>
1594 : I<(outs regtype:$Rd),
1595 (ins regtype:$src, movimm32_imm:$imm, shifter:$shift),
1596 asm, "\t$Rd, $imm$shift", "$src = $Rd", []>,
1597 Sched<[WriteI, ReadI]> {
1598 bits<5> Rd;
1599 bits<16> imm;
1600 bits<6> shift;
1601 let Inst{30-29} = opc;
1602 let Inst{28-23} = 0b100101;
1603 let Inst{22-21} = shift{5-4};
1604 let Inst{20-5} = imm;
1605 let Inst{4-0} = Rd;
1606
1607 let DecoderMethod = "DecodeMoveImmInstruction";
1608}
1609
1610multiclass InsertImmediate<bits<2> opc, string asm> {
1611 def Wi : BaseInsertImmediate<opc, GPR32, movimm32_shift, asm> {
1612 let Inst{31} = 0;
1613 }
1614
1615 def Xi : BaseInsertImmediate<opc, GPR64, movimm64_shift, asm> {
1616 let Inst{31} = 1;
1617 }
1618}
1619
1620//---
1621// Add/Subtract
1622//---
1623
1624class BaseAddSubImm<bit isSub, bit setFlags, RegisterClass dstRegtype,
1625 RegisterClass srcRegtype, addsub_shifted_imm immtype,
1626 string asm, SDPatternOperator OpNode>
1627 : I<(outs dstRegtype:$Rd), (ins srcRegtype:$Rn, immtype:$imm),
1628 asm, "\t$Rd, $Rn, $imm", "",
1629 [(set dstRegtype:$Rd, (OpNode srcRegtype:$Rn, immtype:$imm))]>,
1630 Sched<[WriteI, ReadI]> {
1631 bits<5> Rd;
1632 bits<5> Rn;
1633 bits<14> imm;
1634 let Inst{30} = isSub;
1635 let Inst{29} = setFlags;
1636 let Inst{28-24} = 0b10001;
1637 let Inst{23-22} = imm{13-12}; // '00' => lsl #0, '01' => lsl #12
1638 let Inst{21-10} = imm{11-0};
1639 let Inst{9-5} = Rn;
1640 let Inst{4-0} = Rd;
1641 let DecoderMethod = "DecodeBaseAddSubImm";
1642}
1643
1644class BaseAddSubRegPseudo<RegisterClass regtype,
1645 SDPatternOperator OpNode>
1646 : Pseudo<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm),
1647 [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm))]>,
1648 Sched<[WriteI, ReadI, ReadI]>;
1649
1650class BaseAddSubSReg<bit isSub, bit setFlags, RegisterClass regtype,
1651 arith_shifted_reg shifted_regtype, string asm,
1652 SDPatternOperator OpNode>
1653 : I<(outs regtype:$Rd), (ins regtype:$Rn, shifted_regtype:$Rm),
1654 asm, "\t$Rd, $Rn, $Rm", "",
1655 [(set regtype:$Rd, (OpNode regtype:$Rn, shifted_regtype:$Rm))]>,
1656 Sched<[WriteISReg, ReadI, ReadISReg]> {
1657 // The operands are in order to match the 'addr' MI operands, so we
1658 // don't need an encoder method and by-name matching. Just use the default
1659 // in-order handling. Since we're using by-order, make sure the names
1660 // do not match.
1661 bits<5> dst;
1662 bits<5> src1;
1663 bits<5> src2;
1664 bits<8> shift;
1665 let Inst{30} = isSub;
1666 let Inst{29} = setFlags;
1667 let Inst{28-24} = 0b01011;
1668 let Inst{23-22} = shift{7-6};
1669 let Inst{21} = 0;
1670 let Inst{20-16} = src2;
1671 let Inst{15-10} = shift{5-0};
1672 let Inst{9-5} = src1;
1673 let Inst{4-0} = dst;
1674
1675 let DecoderMethod = "DecodeThreeAddrSRegInstruction";
1676}
1677
1678class BaseAddSubEReg<bit isSub, bit setFlags, RegisterClass dstRegtype,
1679 RegisterClass src1Regtype, Operand src2Regtype,
1680 string asm, SDPatternOperator OpNode>
1681 : I<(outs dstRegtype:$R1),
1682 (ins src1Regtype:$R2, src2Regtype:$R3),
1683 asm, "\t$R1, $R2, $R3", "",
1684 [(set dstRegtype:$R1, (OpNode src1Regtype:$R2, src2Regtype:$R3))]>,
1685 Sched<[WriteIEReg, ReadI, ReadIEReg]> {
1686 bits<5> Rd;
1687 bits<5> Rn;
1688 bits<5> Rm;
1689 bits<6> ext;
1690 let Inst{30} = isSub;
1691 let Inst{29} = setFlags;
1692 let Inst{28-24} = 0b01011;
1693 let Inst{23-21} = 0b001;
1694 let Inst{20-16} = Rm;
1695 let Inst{15-13} = ext{5-3};
1696 let Inst{12-10} = ext{2-0};
1697 let Inst{9-5} = Rn;
1698 let Inst{4-0} = Rd;
1699
1700 let DecoderMethod = "DecodeAddSubERegInstruction";
1701}
1702
1703let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
1704class BaseAddSubEReg64<bit isSub, bit setFlags, RegisterClass dstRegtype,
1705 RegisterClass src1Regtype, RegisterClass src2Regtype,
1706 Operand ext_op, string asm>
1707 : I<(outs dstRegtype:$Rd),
1708 (ins src1Regtype:$Rn, src2Regtype:$Rm, ext_op:$ext),
1709 asm, "\t$Rd, $Rn, $Rm$ext", "", []>,
1710 Sched<[WriteIEReg, ReadI, ReadIEReg]> {
1711 bits<5> Rd;
1712 bits<5> Rn;
1713 bits<5> Rm;
1714 bits<6> ext;
1715 let Inst{30} = isSub;
1716 let Inst{29} = setFlags;
1717 let Inst{28-24} = 0b01011;
1718 let Inst{23-21} = 0b001;
1719 let Inst{20-16} = Rm;
1720 let Inst{15} = ext{5};
1721 let Inst{12-10} = ext{2-0};
1722 let Inst{9-5} = Rn;
1723 let Inst{4-0} = Rd;
1724
1725 let DecoderMethod = "DecodeAddSubERegInstruction";
1726}
1727
1728// Aliases for register+register add/subtract.
1729class AddSubRegAlias<string asm, Instruction inst, RegisterClass dstRegtype,
1730 RegisterClass src1Regtype, RegisterClass src2Regtype,
1731 int shiftExt>
Ahmed Bougacha63fae0e2015-09-02 18:52:54 +00001732 : InstAlias<asm#"\t$dst, $src1, $src2",
Tim Northover3b0846e2014-05-24 12:50:23 +00001733 (inst dstRegtype:$dst, src1Regtype:$src1, src2Regtype:$src2,
1734 shiftExt)>;
1735
Arnaud A. de Grandmaison650c5202015-07-01 15:05:58 +00001736multiclass AddSub<bit isSub, string mnemonic, string alias,
Tim Northover3b0846e2014-05-24 12:50:23 +00001737 SDPatternOperator OpNode = null_frag> {
Jiangning Liucd296372014-07-29 02:09:26 +00001738 let hasSideEffects = 0, isReMaterializable = 1, isAsCheapAsAMove = 1 in {
Tim Northover3b0846e2014-05-24 12:50:23 +00001739 // Add/Subtract immediate
Quentin Colombeta64723c2015-04-02 18:54:23 +00001740 // Increase the weight of the immediate variant to try to match it before
1741 // the extended register variant.
1742 // We used to match the register variant before the immediate when the
1743 // register argument could be implicitly zero-extended.
Quentin Colombet387a0e72015-03-31 00:31:13 +00001744 let AddedComplexity = 6 in
Tim Northover3b0846e2014-05-24 12:50:23 +00001745 def Wri : BaseAddSubImm<isSub, 0, GPR32sp, GPR32sp, addsub_shifted_imm32,
1746 mnemonic, OpNode> {
1747 let Inst{31} = 0;
1748 }
Quentin Colombet387a0e72015-03-31 00:31:13 +00001749 let AddedComplexity = 6 in
Tim Northover3b0846e2014-05-24 12:50:23 +00001750 def Xri : BaseAddSubImm<isSub, 0, GPR64sp, GPR64sp, addsub_shifted_imm64,
1751 mnemonic, OpNode> {
1752 let Inst{31} = 1;
1753 }
1754
1755 // Add/Subtract register - Only used for CodeGen
1756 def Wrr : BaseAddSubRegPseudo<GPR32, OpNode>;
1757 def Xrr : BaseAddSubRegPseudo<GPR64, OpNode>;
1758
1759 // Add/Subtract shifted register
1760 def Wrs : BaseAddSubSReg<isSub, 0, GPR32, arith_shifted_reg32, mnemonic,
1761 OpNode> {
1762 let Inst{31} = 0;
1763 }
1764 def Xrs : BaseAddSubSReg<isSub, 0, GPR64, arith_shifted_reg64, mnemonic,
1765 OpNode> {
1766 let Inst{31} = 1;
1767 }
1768 }
1769
1770 // Add/Subtract extended register
1771 let AddedComplexity = 1, hasSideEffects = 0 in {
1772 def Wrx : BaseAddSubEReg<isSub, 0, GPR32sp, GPR32sp,
1773 arith_extended_reg32<i32>, mnemonic, OpNode> {
1774 let Inst{31} = 0;
1775 }
1776 def Xrx : BaseAddSubEReg<isSub, 0, GPR64sp, GPR64sp,
1777 arith_extended_reg32to64<i64>, mnemonic, OpNode> {
1778 let Inst{31} = 1;
1779 }
1780 }
1781
1782 def Xrx64 : BaseAddSubEReg64<isSub, 0, GPR64sp, GPR64sp, GPR64,
1783 arith_extendlsl64, mnemonic> {
1784 // UXTX and SXTX only.
1785 let Inst{14-13} = 0b11;
1786 let Inst{31} = 1;
1787 }
1788
Arnaud A. de Grandmaison650c5202015-07-01 15:05:58 +00001789 // add Rd, Rb, -imm -> sub Rd, Rn, imm
Ahmed Bougacha63fae0e2015-09-02 18:52:54 +00001790 def : InstAlias<alias#"\t$Rd, $Rn, $imm",
Arnaud A. de Grandmaison650c5202015-07-01 15:05:58 +00001791 (!cast<Instruction>(NAME # "Wri") GPR32sp:$Rd, GPR32sp:$Rn,
1792 addsub_shifted_imm32_neg:$imm), 0>;
Ahmed Bougacha63fae0e2015-09-02 18:52:54 +00001793 def : InstAlias<alias#"\t$Rd, $Rn, $imm",
Arnaud A. de Grandmaison650c5202015-07-01 15:05:58 +00001794 (!cast<Instruction>(NAME # "Xri") GPR64sp:$Rd, GPR64sp:$Rn,
1795 addsub_shifted_imm64_neg:$imm), 0>;
1796
Tim Northover3b0846e2014-05-24 12:50:23 +00001797 // Register/register aliases with no shift when SP is not used.
1798 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrs"),
1799 GPR32, GPR32, GPR32, 0>;
1800 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Xrs"),
1801 GPR64, GPR64, GPR64, 0>;
1802
1803 // Register/register aliases with no shift when either the destination or
1804 // first source register is SP.
1805 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrx"),
1806 GPR32sponly, GPR32sp, GPR32, 16>; // UXTW #0
1807 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrx"),
1808 GPR32sp, GPR32sponly, GPR32, 16>; // UXTW #0
1809 def : AddSubRegAlias<mnemonic,
1810 !cast<Instruction>(NAME#"Xrx64"),
1811 GPR64sponly, GPR64sp, GPR64, 24>; // UXTX #0
1812 def : AddSubRegAlias<mnemonic,
1813 !cast<Instruction>(NAME#"Xrx64"),
1814 GPR64sp, GPR64sponly, GPR64, 24>; // UXTX #0
1815}
1816
Arnaud A. de Grandmaison650c5202015-07-01 15:05:58 +00001817multiclass AddSubS<bit isSub, string mnemonic, SDNode OpNode, string cmp,
1818 string alias, string cmpAlias> {
Tim Northover3b0846e2014-05-24 12:50:23 +00001819 let isCompare = 1, Defs = [NZCV] in {
1820 // Add/Subtract immediate
1821 def Wri : BaseAddSubImm<isSub, 1, GPR32, GPR32sp, addsub_shifted_imm32,
1822 mnemonic, OpNode> {
1823 let Inst{31} = 0;
1824 }
1825 def Xri : BaseAddSubImm<isSub, 1, GPR64, GPR64sp, addsub_shifted_imm64,
1826 mnemonic, OpNode> {
1827 let Inst{31} = 1;
1828 }
1829
1830 // Add/Subtract register
1831 def Wrr : BaseAddSubRegPseudo<GPR32, OpNode>;
1832 def Xrr : BaseAddSubRegPseudo<GPR64, OpNode>;
1833
1834 // Add/Subtract shifted register
1835 def Wrs : BaseAddSubSReg<isSub, 1, GPR32, arith_shifted_reg32, mnemonic,
1836 OpNode> {
1837 let Inst{31} = 0;
1838 }
1839 def Xrs : BaseAddSubSReg<isSub, 1, GPR64, arith_shifted_reg64, mnemonic,
1840 OpNode> {
1841 let Inst{31} = 1;
1842 }
1843
1844 // Add/Subtract extended register
1845 let AddedComplexity = 1 in {
1846 def Wrx : BaseAddSubEReg<isSub, 1, GPR32, GPR32sp,
1847 arith_extended_reg32<i32>, mnemonic, OpNode> {
1848 let Inst{31} = 0;
1849 }
1850 def Xrx : BaseAddSubEReg<isSub, 1, GPR64, GPR64sp,
1851 arith_extended_reg32<i64>, mnemonic, OpNode> {
1852 let Inst{31} = 1;
1853 }
1854 }
1855
1856 def Xrx64 : BaseAddSubEReg64<isSub, 1, GPR64, GPR64sp, GPR64,
1857 arith_extendlsl64, mnemonic> {
1858 // UXTX and SXTX only.
1859 let Inst{14-13} = 0b11;
1860 let Inst{31} = 1;
1861 }
1862 } // Defs = [NZCV]
1863
Arnaud A. de Grandmaison650c5202015-07-01 15:05:58 +00001864 // Support negative immediates, e.g. adds Rd, Rn, -imm -> subs Rd, Rn, imm
Ahmed Bougacha63fae0e2015-09-02 18:52:54 +00001865 def : InstAlias<alias#"\t$Rd, $Rn, $imm",
Arnaud A. de Grandmaison650c5202015-07-01 15:05:58 +00001866 (!cast<Instruction>(NAME # "Wri") GPR32:$Rd, GPR32sp:$Rn,
1867 addsub_shifted_imm32_neg:$imm), 0>;
Ahmed Bougacha63fae0e2015-09-02 18:52:54 +00001868 def : InstAlias<alias#"\t$Rd, $Rn, $imm",
Arnaud A. de Grandmaison650c5202015-07-01 15:05:58 +00001869 (!cast<Instruction>(NAME # "Xri") GPR64:$Rd, GPR64sp:$Rn,
1870 addsub_shifted_imm64_neg:$imm), 0>;
1871
Tim Northover3b0846e2014-05-24 12:50:23 +00001872 // Compare aliases
Ahmed Bougacha63fae0e2015-09-02 18:52:54 +00001873 def : InstAlias<cmp#"\t$src, $imm", (!cast<Instruction>(NAME#"Wri")
Tim Northover3b0846e2014-05-24 12:50:23 +00001874 WZR, GPR32sp:$src, addsub_shifted_imm32:$imm), 5>;
Ahmed Bougacha63fae0e2015-09-02 18:52:54 +00001875 def : InstAlias<cmp#"\t$src, $imm", (!cast<Instruction>(NAME#"Xri")
Tim Northover3b0846e2014-05-24 12:50:23 +00001876 XZR, GPR64sp:$src, addsub_shifted_imm64:$imm), 5>;
Ahmed Bougacha63fae0e2015-09-02 18:52:54 +00001877 def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Wrx")
Tim Northover3b0846e2014-05-24 12:50:23 +00001878 WZR, GPR32sp:$src1, GPR32:$src2, arith_extend:$sh), 4>;
Ahmed Bougacha63fae0e2015-09-02 18:52:54 +00001879 def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Xrx")
Tim Northover3b0846e2014-05-24 12:50:23 +00001880 XZR, GPR64sp:$src1, GPR32:$src2, arith_extend:$sh), 4>;
Ahmed Bougacha63fae0e2015-09-02 18:52:54 +00001881 def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Xrx64")
Tim Northover3b0846e2014-05-24 12:50:23 +00001882 XZR, GPR64sp:$src1, GPR64:$src2, arith_extendlsl64:$sh), 4>;
Ahmed Bougacha63fae0e2015-09-02 18:52:54 +00001883 def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Wrs")
Tim Northover3b0846e2014-05-24 12:50:23 +00001884 WZR, GPR32:$src1, GPR32:$src2, arith_shift32:$sh), 4>;
Ahmed Bougacha63fae0e2015-09-02 18:52:54 +00001885 def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Xrs")
Tim Northover3b0846e2014-05-24 12:50:23 +00001886 XZR, GPR64:$src1, GPR64:$src2, arith_shift64:$sh), 4>;
1887
Arnaud A. de Grandmaison650c5202015-07-01 15:05:58 +00001888 // Support negative immediates, e.g. cmp Rn, -imm -> cmn Rn, imm
Ahmed Bougacha63fae0e2015-09-02 18:52:54 +00001889 def : InstAlias<cmpAlias#"\t$src, $imm", (!cast<Instruction>(NAME#"Wri")
Arnaud A. de Grandmaison650c5202015-07-01 15:05:58 +00001890 WZR, GPR32sp:$src, addsub_shifted_imm32_neg:$imm), 0>;
Ahmed Bougacha63fae0e2015-09-02 18:52:54 +00001891 def : InstAlias<cmpAlias#"\t$src, $imm", (!cast<Instruction>(NAME#"Xri")
Arnaud A. de Grandmaison650c5202015-07-01 15:05:58 +00001892 XZR, GPR64sp:$src, addsub_shifted_imm64_neg:$imm), 0>;
1893
Tim Northover3b0846e2014-05-24 12:50:23 +00001894 // Compare shorthands
Ahmed Bougacha63fae0e2015-09-02 18:52:54 +00001895 def : InstAlias<cmp#"\t$src1, $src2", (!cast<Instruction>(NAME#"Wrs")
Tim Northover3b0846e2014-05-24 12:50:23 +00001896 WZR, GPR32:$src1, GPR32:$src2, 0), 5>;
Ahmed Bougacha63fae0e2015-09-02 18:52:54 +00001897 def : InstAlias<cmp#"\t$src1, $src2", (!cast<Instruction>(NAME#"Xrs")
Tim Northover3b0846e2014-05-24 12:50:23 +00001898 XZR, GPR64:$src1, GPR64:$src2, 0), 5>;
Ahmed Bougacha63fae0e2015-09-02 18:52:54 +00001899 def : InstAlias<cmp#"\t$src1, $src2", (!cast<Instruction>(NAME#"Wrx")
Artyom Skrobov82ae94f2014-06-09 11:10:14 +00001900 WZR, GPR32sponly:$src1, GPR32:$src2, 16), 5>;
Ahmed Bougacha63fae0e2015-09-02 18:52:54 +00001901 def : InstAlias<cmp#"\t$src1, $src2", (!cast<Instruction>(NAME#"Xrx64")
Artyom Skrobov82ae94f2014-06-09 11:10:14 +00001902 XZR, GPR64sponly:$src1, GPR64:$src2, 24), 5>;
Tim Northover3b0846e2014-05-24 12:50:23 +00001903
1904 // Register/register aliases with no shift when SP is not used.
1905 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrs"),
1906 GPR32, GPR32, GPR32, 0>;
1907 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Xrs"),
1908 GPR64, GPR64, GPR64, 0>;
1909
1910 // Register/register aliases with no shift when the first source register
1911 // is SP.
1912 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrx"),
1913 GPR32, GPR32sponly, GPR32, 16>; // UXTW #0
1914 def : AddSubRegAlias<mnemonic,
1915 !cast<Instruction>(NAME#"Xrx64"),
1916 GPR64, GPR64sponly, GPR64, 24>; // UXTX #0
1917}
1918
1919//---
1920// Extract
1921//---
1922def SDTA64EXTR : SDTypeProfile<1, 3, [SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>,
1923 SDTCisPtrTy<3>]>;
1924def AArch64Extr : SDNode<"AArch64ISD::EXTR", SDTA64EXTR>;
1925
1926class BaseExtractImm<RegisterClass regtype, Operand imm_type, string asm,
1927 list<dag> patterns>
1928 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, imm_type:$imm),
1929 asm, "\t$Rd, $Rn, $Rm, $imm", "", patterns>,
1930 Sched<[WriteExtr, ReadExtrHi]> {
1931 bits<5> Rd;
1932 bits<5> Rn;
1933 bits<5> Rm;
1934 bits<6> imm;
1935
1936 let Inst{30-23} = 0b00100111;
1937 let Inst{21} = 0;
1938 let Inst{20-16} = Rm;
1939 let Inst{15-10} = imm;
1940 let Inst{9-5} = Rn;
1941 let Inst{4-0} = Rd;
1942}
1943
1944multiclass ExtractImm<string asm> {
1945 def Wrri : BaseExtractImm<GPR32, imm0_31, asm,
1946 [(set GPR32:$Rd,
1947 (AArch64Extr GPR32:$Rn, GPR32:$Rm, imm0_31:$imm))]> {
1948 let Inst{31} = 0;
1949 let Inst{22} = 0;
1950 // imm<5> must be zero.
1951 let imm{5} = 0;
1952 }
1953 def Xrri : BaseExtractImm<GPR64, imm0_63, asm,
1954 [(set GPR64:$Rd,
1955 (AArch64Extr GPR64:$Rn, GPR64:$Rm, imm0_63:$imm))]> {
1956
1957 let Inst{31} = 1;
1958 let Inst{22} = 1;
1959 }
1960}
1961
1962//---
1963// Bitfield
1964//---
1965
1966let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
1967class BaseBitfieldImm<bits<2> opc,
1968 RegisterClass regtype, Operand imm_type, string asm>
1969 : I<(outs regtype:$Rd), (ins regtype:$Rn, imm_type:$immr, imm_type:$imms),
1970 asm, "\t$Rd, $Rn, $immr, $imms", "", []>,
1971 Sched<[WriteIS, ReadI]> {
1972 bits<5> Rd;
1973 bits<5> Rn;
1974 bits<6> immr;
1975 bits<6> imms;
1976
1977 let Inst{30-29} = opc;
1978 let Inst{28-23} = 0b100110;
1979 let Inst{21-16} = immr;
1980 let Inst{15-10} = imms;
1981 let Inst{9-5} = Rn;
1982 let Inst{4-0} = Rd;
1983}
1984
1985multiclass BitfieldImm<bits<2> opc, string asm> {
1986 def Wri : BaseBitfieldImm<opc, GPR32, imm0_31, asm> {
1987 let Inst{31} = 0;
1988 let Inst{22} = 0;
1989 // imms<5> and immr<5> must be zero, else ReservedValue().
1990 let Inst{21} = 0;
1991 let Inst{15} = 0;
1992 }
1993 def Xri : BaseBitfieldImm<opc, GPR64, imm0_63, asm> {
1994 let Inst{31} = 1;
1995 let Inst{22} = 1;
1996 }
1997}
1998
1999let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
2000class BaseBitfieldImmWith2RegArgs<bits<2> opc,
2001 RegisterClass regtype, Operand imm_type, string asm>
2002 : I<(outs regtype:$Rd), (ins regtype:$src, regtype:$Rn, imm_type:$immr,
2003 imm_type:$imms),
2004 asm, "\t$Rd, $Rn, $immr, $imms", "$src = $Rd", []>,
2005 Sched<[WriteIS, ReadI]> {
2006 bits<5> Rd;
2007 bits<5> Rn;
2008 bits<6> immr;
2009 bits<6> imms;
2010
2011 let Inst{30-29} = opc;
2012 let Inst{28-23} = 0b100110;
2013 let Inst{21-16} = immr;
2014 let Inst{15-10} = imms;
2015 let Inst{9-5} = Rn;
2016 let Inst{4-0} = Rd;
2017}
2018
2019multiclass BitfieldImmWith2RegArgs<bits<2> opc, string asm> {
2020 def Wri : BaseBitfieldImmWith2RegArgs<opc, GPR32, imm0_31, asm> {
2021 let Inst{31} = 0;
2022 let Inst{22} = 0;
2023 // imms<5> and immr<5> must be zero, else ReservedValue().
2024 let Inst{21} = 0;
2025 let Inst{15} = 0;
2026 }
2027 def Xri : BaseBitfieldImmWith2RegArgs<opc, GPR64, imm0_63, asm> {
2028 let Inst{31} = 1;
2029 let Inst{22} = 1;
2030 }
2031}
2032
2033//---
2034// Logical
2035//---
2036
2037// Logical (immediate)
2038class BaseLogicalImm<bits<2> opc, RegisterClass dregtype,
2039 RegisterClass sregtype, Operand imm_type, string asm,
2040 list<dag> pattern>
2041 : I<(outs dregtype:$Rd), (ins sregtype:$Rn, imm_type:$imm),
2042 asm, "\t$Rd, $Rn, $imm", "", pattern>,
2043 Sched<[WriteI, ReadI]> {
2044 bits<5> Rd;
2045 bits<5> Rn;
2046 bits<13> imm;
2047 let Inst{30-29} = opc;
2048 let Inst{28-23} = 0b100100;
2049 let Inst{22} = imm{12};
2050 let Inst{21-16} = imm{11-6};
2051 let Inst{15-10} = imm{5-0};
2052 let Inst{9-5} = Rn;
2053 let Inst{4-0} = Rd;
2054
2055 let DecoderMethod = "DecodeLogicalImmInstruction";
2056}
2057
2058// Logical (shifted register)
2059class BaseLogicalSReg<bits<2> opc, bit N, RegisterClass regtype,
2060 logical_shifted_reg shifted_regtype, string asm,
2061 list<dag> pattern>
2062 : I<(outs regtype:$Rd), (ins regtype:$Rn, shifted_regtype:$Rm),
2063 asm, "\t$Rd, $Rn, $Rm", "", pattern>,
2064 Sched<[WriteISReg, ReadI, ReadISReg]> {
2065 // The operands are in order to match the 'addr' MI operands, so we
2066 // don't need an encoder method and by-name matching. Just use the default
2067 // in-order handling. Since we're using by-order, make sure the names
2068 // do not match.
2069 bits<5> dst;
2070 bits<5> src1;
2071 bits<5> src2;
2072 bits<8> shift;
2073 let Inst{30-29} = opc;
2074 let Inst{28-24} = 0b01010;
2075 let Inst{23-22} = shift{7-6};
2076 let Inst{21} = N;
2077 let Inst{20-16} = src2;
2078 let Inst{15-10} = shift{5-0};
2079 let Inst{9-5} = src1;
2080 let Inst{4-0} = dst;
2081
2082 let DecoderMethod = "DecodeThreeAddrSRegInstruction";
2083}
2084
2085// Aliases for register+register logical instructions.
2086class LogicalRegAlias<string asm, Instruction inst, RegisterClass regtype>
Ahmed Bougacha63fae0e2015-09-02 18:52:54 +00002087 : InstAlias<asm#"\t$dst, $src1, $src2",
Tim Northover3b0846e2014-05-24 12:50:23 +00002088 (inst regtype:$dst, regtype:$src1, regtype:$src2, 0)>;
2089
Arnaud A. de Grandmaisonf6432312014-07-10 15:12:26 +00002090multiclass LogicalImm<bits<2> opc, string mnemonic, SDNode OpNode,
2091 string Alias> {
Jiangning Liucd296372014-07-29 02:09:26 +00002092 let AddedComplexity = 6, isReMaterializable = 1, isAsCheapAsAMove = 1 in
Tim Northover3b0846e2014-05-24 12:50:23 +00002093 def Wri : BaseLogicalImm<opc, GPR32sp, GPR32, logical_imm32, mnemonic,
2094 [(set GPR32sp:$Rd, (OpNode GPR32:$Rn,
2095 logical_imm32:$imm))]> {
2096 let Inst{31} = 0;
2097 let Inst{22} = 0; // 64-bit version has an additional bit of immediate.
2098 }
Jiangning Liucd296372014-07-29 02:09:26 +00002099 let AddedComplexity = 6, isReMaterializable = 1, isAsCheapAsAMove = 1 in
Tim Northover3b0846e2014-05-24 12:50:23 +00002100 def Xri : BaseLogicalImm<opc, GPR64sp, GPR64, logical_imm64, mnemonic,
2101 [(set GPR64sp:$Rd, (OpNode GPR64:$Rn,
2102 logical_imm64:$imm))]> {
2103 let Inst{31} = 1;
2104 }
Arnaud A. de Grandmaisonf6432312014-07-10 15:12:26 +00002105
Ahmed Bougacha63fae0e2015-09-02 18:52:54 +00002106 def : InstAlias<Alias # "\t$Rd, $Rn, $imm",
Arnaud A. de Grandmaisonf6432312014-07-10 15:12:26 +00002107 (!cast<Instruction>(NAME # "Wri") GPR32sp:$Rd, GPR32:$Rn,
2108 logical_imm32_not:$imm), 0>;
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 # "Xri") GPR64sp:$Rd, GPR64:$Rn,
2111 logical_imm64_not:$imm), 0>;
Tim Northover3b0846e2014-05-24 12:50:23 +00002112}
2113
Arnaud A. de Grandmaisonf6432312014-07-10 15:12:26 +00002114multiclass LogicalImmS<bits<2> opc, string mnemonic, SDNode OpNode,
2115 string Alias> {
Tim Northover3b0846e2014-05-24 12:50:23 +00002116 let isCompare = 1, Defs = [NZCV] in {
2117 def Wri : BaseLogicalImm<opc, GPR32, GPR32, logical_imm32, mnemonic,
2118 [(set GPR32:$Rd, (OpNode GPR32:$Rn, logical_imm32:$imm))]> {
2119 let Inst{31} = 0;
2120 let Inst{22} = 0; // 64-bit version has an additional bit of immediate.
2121 }
2122 def Xri : BaseLogicalImm<opc, GPR64, GPR64, logical_imm64, mnemonic,
2123 [(set GPR64:$Rd, (OpNode GPR64:$Rn, logical_imm64:$imm))]> {
2124 let Inst{31} = 1;
2125 }
2126 } // end Defs = [NZCV]
Arnaud A. de Grandmaisonf6432312014-07-10 15:12:26 +00002127
Ahmed Bougacha63fae0e2015-09-02 18:52:54 +00002128 def : InstAlias<Alias # "\t$Rd, $Rn, $imm",
Arnaud A. de Grandmaisonf6432312014-07-10 15:12:26 +00002129 (!cast<Instruction>(NAME # "Wri") GPR32:$Rd, GPR32:$Rn,
2130 logical_imm32_not:$imm), 0>;
Ahmed Bougacha63fae0e2015-09-02 18:52:54 +00002131 def : InstAlias<Alias # "\t$Rd, $Rn, $imm",
Arnaud A. de Grandmaisonf6432312014-07-10 15:12:26 +00002132 (!cast<Instruction>(NAME # "Xri") GPR64:$Rd, GPR64:$Rn,
2133 logical_imm64_not:$imm), 0>;
Tim Northover3b0846e2014-05-24 12:50:23 +00002134}
2135
2136class BaseLogicalRegPseudo<RegisterClass regtype, SDPatternOperator OpNode>
2137 : Pseudo<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm),
2138 [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm))]>,
2139 Sched<[WriteI, ReadI, ReadI]>;
2140
2141// Split from LogicalImm as not all instructions have both.
2142multiclass LogicalReg<bits<2> opc, bit N, string mnemonic,
2143 SDPatternOperator OpNode> {
Jiangning Liucd296372014-07-29 02:09:26 +00002144 let isReMaterializable = 1, isAsCheapAsAMove = 1 in {
Tim Northover3b0846e2014-05-24 12:50:23 +00002145 def Wrr : BaseLogicalRegPseudo<GPR32, OpNode>;
2146 def Xrr : BaseLogicalRegPseudo<GPR64, OpNode>;
Jiangning Liucd296372014-07-29 02:09:26 +00002147 }
Tim Northover3b0846e2014-05-24 12:50:23 +00002148
2149 def Wrs : BaseLogicalSReg<opc, N, GPR32, logical_shifted_reg32, mnemonic,
2150 [(set GPR32:$Rd, (OpNode GPR32:$Rn,
2151 logical_shifted_reg32:$Rm))]> {
2152 let Inst{31} = 0;
2153 }
2154 def Xrs : BaseLogicalSReg<opc, N, GPR64, logical_shifted_reg64, mnemonic,
2155 [(set GPR64:$Rd, (OpNode GPR64:$Rn,
2156 logical_shifted_reg64:$Rm))]> {
2157 let Inst{31} = 1;
2158 }
2159
2160 def : LogicalRegAlias<mnemonic,
2161 !cast<Instruction>(NAME#"Wrs"), GPR32>;
2162 def : LogicalRegAlias<mnemonic,
2163 !cast<Instruction>(NAME#"Xrs"), GPR64>;
2164}
2165
2166// Split from LogicalReg to allow setting NZCV Defs
2167multiclass LogicalRegS<bits<2> opc, bit N, string mnemonic,
2168 SDPatternOperator OpNode = null_frag> {
2169 let Defs = [NZCV], mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
2170 def Wrr : BaseLogicalRegPseudo<GPR32, OpNode>;
2171 def Xrr : BaseLogicalRegPseudo<GPR64, OpNode>;
2172
2173 def Wrs : BaseLogicalSReg<opc, N, GPR32, logical_shifted_reg32, mnemonic,
2174 [(set GPR32:$Rd, (OpNode GPR32:$Rn, logical_shifted_reg32:$Rm))]> {
2175 let Inst{31} = 0;
2176 }
2177 def Xrs : BaseLogicalSReg<opc, N, GPR64, logical_shifted_reg64, mnemonic,
2178 [(set GPR64:$Rd, (OpNode GPR64:$Rn, logical_shifted_reg64:$Rm))]> {
2179 let Inst{31} = 1;
2180 }
2181 } // Defs = [NZCV]
2182
2183 def : LogicalRegAlias<mnemonic,
2184 !cast<Instruction>(NAME#"Wrs"), GPR32>;
2185 def : LogicalRegAlias<mnemonic,
2186 !cast<Instruction>(NAME#"Xrs"), GPR64>;
2187}
2188
2189//---
2190// Conditionally set flags
2191//---
2192
2193let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
Matthias Braunaf7d7702015-07-16 20:02:37 +00002194class BaseCondComparisonImm<bit op, RegisterClass regtype, ImmLeaf immtype,
2195 string mnemonic, SDNode OpNode>
2196 : I<(outs), (ins regtype:$Rn, immtype:$imm, imm32_0_15:$nzcv, ccode:$cond),
2197 mnemonic, "\t$Rn, $imm, $nzcv, $cond", "",
2198 [(set NZCV, (OpNode regtype:$Rn, immtype:$imm, (i32 imm:$nzcv),
2199 (i32 imm:$cond), NZCV))]>,
Tim Northover3b0846e2014-05-24 12:50:23 +00002200 Sched<[WriteI, ReadI]> {
2201 let Uses = [NZCV];
2202 let Defs = [NZCV];
2203
2204 bits<5> Rn;
2205 bits<5> imm;
2206 bits<4> nzcv;
2207 bits<4> cond;
2208
2209 let Inst{30} = op;
2210 let Inst{29-21} = 0b111010010;
2211 let Inst{20-16} = imm;
2212 let Inst{15-12} = cond;
2213 let Inst{11-10} = 0b10;
2214 let Inst{9-5} = Rn;
2215 let Inst{4} = 0b0;
2216 let Inst{3-0} = nzcv;
2217}
2218
Tim Northover3b0846e2014-05-24 12:50:23 +00002219let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
Matthias Braunaf7d7702015-07-16 20:02:37 +00002220class BaseCondComparisonReg<bit op, RegisterClass regtype, string mnemonic,
2221 SDNode OpNode>
2222 : I<(outs), (ins regtype:$Rn, regtype:$Rm, imm32_0_15:$nzcv, ccode:$cond),
2223 mnemonic, "\t$Rn, $Rm, $nzcv, $cond", "",
2224 [(set NZCV, (OpNode regtype:$Rn, regtype:$Rm, (i32 imm:$nzcv),
2225 (i32 imm:$cond), NZCV))]>,
Tim Northover3b0846e2014-05-24 12:50:23 +00002226 Sched<[WriteI, ReadI, ReadI]> {
2227 let Uses = [NZCV];
2228 let Defs = [NZCV];
2229
2230 bits<5> Rn;
2231 bits<5> Rm;
2232 bits<4> nzcv;
2233 bits<4> cond;
2234
2235 let Inst{30} = op;
2236 let Inst{29-21} = 0b111010010;
2237 let Inst{20-16} = Rm;
2238 let Inst{15-12} = cond;
2239 let Inst{11-10} = 0b00;
2240 let Inst{9-5} = Rn;
2241 let Inst{4} = 0b0;
2242 let Inst{3-0} = nzcv;
2243}
2244
Matthias Braunaf7d7702015-07-16 20:02:37 +00002245multiclass CondComparison<bit op, string mnemonic, SDNode OpNode> {
2246 // immediate operand variants
2247 def Wi : BaseCondComparisonImm<op, GPR32, imm32_0_31, mnemonic, OpNode> {
Tim Northover3b0846e2014-05-24 12:50:23 +00002248 let Inst{31} = 0;
2249 }
Matthias Braunaf7d7702015-07-16 20:02:37 +00002250 def Xi : BaseCondComparisonImm<op, GPR64, imm0_31, mnemonic, OpNode> {
2251 let Inst{31} = 1;
2252 }
2253 // register operand variants
2254 def Wr : BaseCondComparisonReg<op, GPR32, mnemonic, OpNode> {
2255 let Inst{31} = 0;
2256 }
2257 def Xr : BaseCondComparisonReg<op, GPR64, mnemonic, OpNode> {
Tim Northover3b0846e2014-05-24 12:50:23 +00002258 let Inst{31} = 1;
2259 }
2260}
2261
2262//---
2263// Conditional select
2264//---
2265
2266class BaseCondSelect<bit op, bits<2> op2, RegisterClass regtype, string asm>
2267 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, ccode:$cond),
2268 asm, "\t$Rd, $Rn, $Rm, $cond", "",
2269 [(set regtype:$Rd,
2270 (AArch64csel regtype:$Rn, regtype:$Rm, (i32 imm:$cond), NZCV))]>,
2271 Sched<[WriteI, ReadI, ReadI]> {
2272 let Uses = [NZCV];
2273
2274 bits<5> Rd;
2275 bits<5> Rn;
2276 bits<5> Rm;
2277 bits<4> cond;
2278
2279 let Inst{30} = op;
2280 let Inst{29-21} = 0b011010100;
2281 let Inst{20-16} = Rm;
2282 let Inst{15-12} = cond;
2283 let Inst{11-10} = op2;
2284 let Inst{9-5} = Rn;
2285 let Inst{4-0} = Rd;
2286}
2287
2288multiclass CondSelect<bit op, bits<2> op2, string asm> {
2289 def Wr : BaseCondSelect<op, op2, GPR32, asm> {
2290 let Inst{31} = 0;
2291 }
2292 def Xr : BaseCondSelect<op, op2, GPR64, asm> {
2293 let Inst{31} = 1;
2294 }
2295}
2296
2297class BaseCondSelectOp<bit op, bits<2> op2, RegisterClass regtype, string asm,
2298 PatFrag frag>
2299 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, ccode:$cond),
2300 asm, "\t$Rd, $Rn, $Rm, $cond", "",
2301 [(set regtype:$Rd,
2302 (AArch64csel regtype:$Rn, (frag regtype:$Rm),
2303 (i32 imm:$cond), NZCV))]>,
2304 Sched<[WriteI, ReadI, ReadI]> {
2305 let Uses = [NZCV];
2306
2307 bits<5> Rd;
2308 bits<5> Rn;
2309 bits<5> Rm;
2310 bits<4> cond;
2311
2312 let Inst{30} = op;
2313 let Inst{29-21} = 0b011010100;
2314 let Inst{20-16} = Rm;
2315 let Inst{15-12} = cond;
2316 let Inst{11-10} = op2;
2317 let Inst{9-5} = Rn;
2318 let Inst{4-0} = Rd;
2319}
2320
2321def inv_cond_XFORM : SDNodeXForm<imm, [{
2322 AArch64CC::CondCode CC = static_cast<AArch64CC::CondCode>(N->getZExtValue());
Sergey Dmitrouk842a51b2015-04-28 14:05:47 +00002323 return CurDAG->getTargetConstant(AArch64CC::getInvertedCondCode(CC), SDLoc(N),
2324 MVT::i32);
Tim Northover3b0846e2014-05-24 12:50:23 +00002325}]>;
2326
2327multiclass CondSelectOp<bit op, bits<2> op2, string asm, PatFrag frag> {
2328 def Wr : BaseCondSelectOp<op, op2, GPR32, asm, frag> {
2329 let Inst{31} = 0;
2330 }
2331 def Xr : BaseCondSelectOp<op, op2, GPR64, asm, frag> {
2332 let Inst{31} = 1;
2333 }
2334
2335 def : Pat<(AArch64csel (frag GPR32:$Rm), GPR32:$Rn, (i32 imm:$cond), NZCV),
2336 (!cast<Instruction>(NAME # Wr) GPR32:$Rn, GPR32:$Rm,
2337 (inv_cond_XFORM imm:$cond))>;
2338
2339 def : Pat<(AArch64csel (frag GPR64:$Rm), GPR64:$Rn, (i32 imm:$cond), NZCV),
2340 (!cast<Instruction>(NAME # Xr) GPR64:$Rn, GPR64:$Rm,
2341 (inv_cond_XFORM imm:$cond))>;
2342}
2343
2344//---
2345// Special Mask Value
2346//---
2347def maski8_or_more : Operand<i32>,
2348 ImmLeaf<i32, [{ return (Imm & 0xff) == 0xff; }]> {
2349}
2350def maski16_or_more : Operand<i32>,
2351 ImmLeaf<i32, [{ return (Imm & 0xffff) == 0xffff; }]> {
2352}
2353
2354
2355//---
2356// Load/store
2357//---
2358
2359// (unsigned immediate)
2360// Indexed for 8-bit registers. offset is in range [0,4095].
2361def am_indexed8 : ComplexPattern<i64, 2, "SelectAddrModeIndexed8", []>;
2362def am_indexed16 : ComplexPattern<i64, 2, "SelectAddrModeIndexed16", []>;
2363def am_indexed32 : ComplexPattern<i64, 2, "SelectAddrModeIndexed32", []>;
2364def am_indexed64 : ComplexPattern<i64, 2, "SelectAddrModeIndexed64", []>;
2365def am_indexed128 : ComplexPattern<i64, 2, "SelectAddrModeIndexed128", []>;
2366
2367class UImm12OffsetOperand<int Scale> : AsmOperandClass {
2368 let Name = "UImm12Offset" # Scale;
2369 let RenderMethod = "addUImm12OffsetOperands<" # Scale # ">";
2370 let PredicateMethod = "isUImm12Offset<" # Scale # ">";
2371 let DiagnosticType = "InvalidMemoryIndexed" # Scale;
2372}
2373
2374def UImm12OffsetScale1Operand : UImm12OffsetOperand<1>;
2375def UImm12OffsetScale2Operand : UImm12OffsetOperand<2>;
2376def UImm12OffsetScale4Operand : UImm12OffsetOperand<4>;
2377def UImm12OffsetScale8Operand : UImm12OffsetOperand<8>;
2378def UImm12OffsetScale16Operand : UImm12OffsetOperand<16>;
2379
2380class uimm12_scaled<int Scale> : Operand<i64> {
2381 let ParserMatchClass
2382 = !cast<AsmOperandClass>("UImm12OffsetScale" # Scale # "Operand");
2383 let EncoderMethod
2384 = "getLdStUImm12OpValue<AArch64::fixup_aarch64_ldst_imm12_scale" # Scale # ">";
2385 let PrintMethod = "printUImm12Offset<" # Scale # ">";
2386}
2387
2388def uimm12s1 : uimm12_scaled<1>;
2389def uimm12s2 : uimm12_scaled<2>;
2390def uimm12s4 : uimm12_scaled<4>;
2391def uimm12s8 : uimm12_scaled<8>;
2392def uimm12s16 : uimm12_scaled<16>;
2393
2394class BaseLoadStoreUI<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops,
2395 string asm, list<dag> pattern>
2396 : I<oops, iops, asm, "\t$Rt, [$Rn, $offset]", "", pattern> {
2397 bits<5> Rt;
2398
2399 bits<5> Rn;
2400 bits<12> offset;
2401
2402 let Inst{31-30} = sz;
2403 let Inst{29-27} = 0b111;
2404 let Inst{26} = V;
2405 let Inst{25-24} = 0b01;
2406 let Inst{23-22} = opc;
2407 let Inst{21-10} = offset;
2408 let Inst{9-5} = Rn;
2409 let Inst{4-0} = Rt;
2410
2411 let DecoderMethod = "DecodeUnsignedLdStInstruction";
2412}
2413
2414multiclass LoadUI<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2415 Operand indextype, string asm, list<dag> pattern> {
2416 let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
2417 def ui : BaseLoadStoreUI<sz, V, opc, (outs regtype:$Rt),
2418 (ins GPR64sp:$Rn, indextype:$offset),
2419 asm, pattern>,
2420 Sched<[WriteLD]>;
2421
Ahmed Bougacha63fae0e2015-09-02 18:52:54 +00002422 def : InstAlias<asm # "\t$Rt, [$Rn]",
Tim Northover3b0846e2014-05-24 12:50:23 +00002423 (!cast<Instruction>(NAME # "ui") regtype:$Rt, GPR64sp:$Rn, 0)>;
2424}
2425
2426multiclass StoreUI<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2427 Operand indextype, string asm, list<dag> pattern> {
2428 let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
2429 def ui : BaseLoadStoreUI<sz, V, opc, (outs),
2430 (ins regtype:$Rt, GPR64sp:$Rn, indextype:$offset),
2431 asm, pattern>,
2432 Sched<[WriteST]>;
2433
Ahmed Bougacha63fae0e2015-09-02 18:52:54 +00002434 def : InstAlias<asm # "\t$Rt, [$Rn]",
Tim Northover3b0846e2014-05-24 12:50:23 +00002435 (!cast<Instruction>(NAME # "ui") regtype:$Rt, GPR64sp:$Rn, 0)>;
2436}
2437
2438def PrefetchOperand : AsmOperandClass {
2439 let Name = "Prefetch";
2440 let ParserMethod = "tryParsePrefetch";
2441}
2442def prfop : Operand<i32> {
2443 let PrintMethod = "printPrefetchOp";
2444 let ParserMatchClass = PrefetchOperand;
2445}
2446
2447let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in
2448class PrefetchUI<bits<2> sz, bit V, bits<2> opc, string asm, list<dag> pat>
2449 : BaseLoadStoreUI<sz, V, opc,
2450 (outs), (ins prfop:$Rt, GPR64sp:$Rn, uimm12s8:$offset),
2451 asm, pat>,
2452 Sched<[WriteLD]>;
2453
2454//---
2455// Load literal
2456//---
2457
2458// Load literal address: 19-bit immediate. The low two bits of the target
2459// offset are implied zero and so are not part of the immediate.
2460def am_ldrlit : Operand<OtherVT> {
2461 let EncoderMethod = "getLoadLiteralOpValue";
2462 let DecoderMethod = "DecodePCRelLabel19";
2463 let PrintMethod = "printAlignedLabel";
2464 let ParserMatchClass = PCRelLabel19Operand;
2465}
2466
2467let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
2468class LoadLiteral<bits<2> opc, bit V, RegisterClass regtype, string asm>
2469 : I<(outs regtype:$Rt), (ins am_ldrlit:$label),
2470 asm, "\t$Rt, $label", "", []>,
2471 Sched<[WriteLD]> {
2472 bits<5> Rt;
2473 bits<19> label;
2474 let Inst{31-30} = opc;
2475 let Inst{29-27} = 0b011;
2476 let Inst{26} = V;
2477 let Inst{25-24} = 0b00;
2478 let Inst{23-5} = label;
2479 let Inst{4-0} = Rt;
2480}
2481
2482let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in
2483class PrefetchLiteral<bits<2> opc, bit V, string asm, list<dag> pat>
2484 : I<(outs), (ins prfop:$Rt, am_ldrlit:$label),
2485 asm, "\t$Rt, $label", "", pat>,
2486 Sched<[WriteLD]> {
2487 bits<5> Rt;
2488 bits<19> label;
2489 let Inst{31-30} = opc;
2490 let Inst{29-27} = 0b011;
2491 let Inst{26} = V;
2492 let Inst{25-24} = 0b00;
2493 let Inst{23-5} = label;
2494 let Inst{4-0} = Rt;
2495}
2496
2497//---
2498// Load/store register offset
2499//---
2500
2501def ro_Xindexed8 : ComplexPattern<i64, 4, "SelectAddrModeXRO<8>", []>;
2502def ro_Xindexed16 : ComplexPattern<i64, 4, "SelectAddrModeXRO<16>", []>;
2503def ro_Xindexed32 : ComplexPattern<i64, 4, "SelectAddrModeXRO<32>", []>;
2504def ro_Xindexed64 : ComplexPattern<i64, 4, "SelectAddrModeXRO<64>", []>;
2505def ro_Xindexed128 : ComplexPattern<i64, 4, "SelectAddrModeXRO<128>", []>;
2506
2507def ro_Windexed8 : ComplexPattern<i64, 4, "SelectAddrModeWRO<8>", []>;
2508def ro_Windexed16 : ComplexPattern<i64, 4, "SelectAddrModeWRO<16>", []>;
2509def ro_Windexed32 : ComplexPattern<i64, 4, "SelectAddrModeWRO<32>", []>;
2510def ro_Windexed64 : ComplexPattern<i64, 4, "SelectAddrModeWRO<64>", []>;
2511def ro_Windexed128 : ComplexPattern<i64, 4, "SelectAddrModeWRO<128>", []>;
2512
2513class MemExtendOperand<string Reg, int Width> : AsmOperandClass {
2514 let Name = "Mem" # Reg # "Extend" # Width;
2515 let PredicateMethod = "isMem" # Reg # "Extend<" # Width # ">";
2516 let RenderMethod = "addMemExtendOperands";
2517 let DiagnosticType = "InvalidMemory" # Reg # "Extend" # Width;
2518}
2519
2520def MemWExtend8Operand : MemExtendOperand<"W", 8> {
2521 // The address "[x0, x1, lsl #0]" actually maps to the variant which performs
2522 // the trivial shift.
2523 let RenderMethod = "addMemExtend8Operands";
2524}
2525def MemWExtend16Operand : MemExtendOperand<"W", 16>;
2526def MemWExtend32Operand : MemExtendOperand<"W", 32>;
2527def MemWExtend64Operand : MemExtendOperand<"W", 64>;
2528def MemWExtend128Operand : MemExtendOperand<"W", 128>;
2529
2530def MemXExtend8Operand : MemExtendOperand<"X", 8> {
2531 // The address "[x0, x1, lsl #0]" actually maps to the variant which performs
2532 // the trivial shift.
2533 let RenderMethod = "addMemExtend8Operands";
2534}
2535def MemXExtend16Operand : MemExtendOperand<"X", 16>;
2536def MemXExtend32Operand : MemExtendOperand<"X", 32>;
2537def MemXExtend64Operand : MemExtendOperand<"X", 64>;
2538def MemXExtend128Operand : MemExtendOperand<"X", 128>;
2539
2540class ro_extend<AsmOperandClass ParserClass, string Reg, int Width>
2541 : Operand<i32> {
2542 let ParserMatchClass = ParserClass;
2543 let PrintMethod = "printMemExtend<'" # Reg # "', " # Width # ">";
2544 let DecoderMethod = "DecodeMemExtend";
2545 let EncoderMethod = "getMemExtendOpValue";
2546 let MIOperandInfo = (ops i32imm:$signed, i32imm:$doshift);
2547}
2548
2549def ro_Wextend8 : ro_extend<MemWExtend8Operand, "w", 8>;
2550def ro_Wextend16 : ro_extend<MemWExtend16Operand, "w", 16>;
2551def ro_Wextend32 : ro_extend<MemWExtend32Operand, "w", 32>;
2552def ro_Wextend64 : ro_extend<MemWExtend64Operand, "w", 64>;
2553def ro_Wextend128 : ro_extend<MemWExtend128Operand, "w", 128>;
2554
2555def ro_Xextend8 : ro_extend<MemXExtend8Operand, "x", 8>;
2556def ro_Xextend16 : ro_extend<MemXExtend16Operand, "x", 16>;
2557def ro_Xextend32 : ro_extend<MemXExtend32Operand, "x", 32>;
2558def ro_Xextend64 : ro_extend<MemXExtend64Operand, "x", 64>;
2559def ro_Xextend128 : ro_extend<MemXExtend128Operand, "x", 128>;
2560
2561class ROAddrMode<ComplexPattern windex, ComplexPattern xindex,
2562 Operand wextend, Operand xextend> {
2563 // CodeGen-level pattern covering the entire addressing mode.
2564 ComplexPattern Wpat = windex;
2565 ComplexPattern Xpat = xindex;
2566
2567 // Asm-level Operand covering the valid "uxtw #3" style syntax.
2568 Operand Wext = wextend;
2569 Operand Xext = xextend;
2570}
2571
2572def ro8 : ROAddrMode<ro_Windexed8, ro_Xindexed8, ro_Wextend8, ro_Xextend8>;
2573def ro16 : ROAddrMode<ro_Windexed16, ro_Xindexed16, ro_Wextend16, ro_Xextend16>;
2574def ro32 : ROAddrMode<ro_Windexed32, ro_Xindexed32, ro_Wextend32, ro_Xextend32>;
2575def ro64 : ROAddrMode<ro_Windexed64, ro_Xindexed64, ro_Wextend64, ro_Xextend64>;
2576def ro128 : ROAddrMode<ro_Windexed128, ro_Xindexed128, ro_Wextend128,
2577 ro_Xextend128>;
2578
2579class LoadStore8RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2580 string asm, dag ins, dag outs, list<dag> pat>
2581 : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> {
2582 bits<5> Rt;
2583 bits<5> Rn;
2584 bits<5> Rm;
2585 bits<2> extend;
2586 let Inst{31-30} = sz;
2587 let Inst{29-27} = 0b111;
2588 let Inst{26} = V;
2589 let Inst{25-24} = 0b00;
2590 let Inst{23-22} = opc;
2591 let Inst{21} = 1;
2592 let Inst{20-16} = Rm;
2593 let Inst{15} = extend{1}; // sign extend Rm?
2594 let Inst{14} = 1;
2595 let Inst{12} = extend{0}; // do shift?
2596 let Inst{11-10} = 0b10;
2597 let Inst{9-5} = Rn;
2598 let Inst{4-0} = Rt;
2599}
2600
2601class ROInstAlias<string asm, RegisterClass regtype, Instruction INST>
Ahmed Bougachacca07712015-09-02 18:38:36 +00002602 : InstAlias<asm # "\t$Rt, [$Rn, $Rm]",
Tim Northover3b0846e2014-05-24 12:50:23 +00002603 (INST regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, 0, 0)>;
2604
2605multiclass Load8RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2606 string asm, ValueType Ty, SDPatternOperator loadop> {
2607 let AddedComplexity = 10 in
2608 def roW : LoadStore8RO<sz, V, opc, regtype, asm,
2609 (outs regtype:$Rt),
2610 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend8:$extend),
2611 [(set (Ty regtype:$Rt),
2612 (loadop (ro_Windexed8 GPR64sp:$Rn, GPR32:$Rm,
2613 ro_Wextend8:$extend)))]>,
2614 Sched<[WriteLDIdx, ReadAdrBase]> {
2615 let Inst{13} = 0b0;
2616 }
2617
2618 let AddedComplexity = 10 in
2619 def roX : LoadStore8RO<sz, V, opc, regtype, asm,
2620 (outs regtype:$Rt),
2621 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend8:$extend),
2622 [(set (Ty regtype:$Rt),
2623 (loadop (ro_Xindexed8 GPR64sp:$Rn, GPR64:$Rm,
2624 ro_Xextend8:$extend)))]>,
2625 Sched<[WriteLDIdx, ReadAdrBase]> {
2626 let Inst{13} = 0b1;
2627 }
2628
2629 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
2630}
2631
2632multiclass Store8RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2633 string asm, ValueType Ty, SDPatternOperator storeop> {
2634 let AddedComplexity = 10 in
2635 def roW : LoadStore8RO<sz, V, opc, regtype, asm, (outs),
2636 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend8:$extend),
2637 [(storeop (Ty regtype:$Rt),
2638 (ro_Windexed8 GPR64sp:$Rn, GPR32:$Rm,
2639 ro_Wextend8:$extend))]>,
2640 Sched<[WriteSTIdx, ReadAdrBase]> {
2641 let Inst{13} = 0b0;
2642 }
2643
2644 let AddedComplexity = 10 in
2645 def roX : LoadStore8RO<sz, V, opc, regtype, asm, (outs),
2646 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend8:$extend),
2647 [(storeop (Ty regtype:$Rt),
2648 (ro_Xindexed8 GPR64sp:$Rn, GPR64:$Rm,
2649 ro_Xextend8:$extend))]>,
2650 Sched<[WriteSTIdx, ReadAdrBase]> {
2651 let Inst{13} = 0b1;
2652 }
2653
2654 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
2655}
2656
2657class LoadStore16RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2658 string asm, dag ins, dag outs, list<dag> pat>
2659 : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> {
2660 bits<5> Rt;
2661 bits<5> Rn;
2662 bits<5> Rm;
2663 bits<2> extend;
2664 let Inst{31-30} = sz;
2665 let Inst{29-27} = 0b111;
2666 let Inst{26} = V;
2667 let Inst{25-24} = 0b00;
2668 let Inst{23-22} = opc;
2669 let Inst{21} = 1;
2670 let Inst{20-16} = Rm;
2671 let Inst{15} = extend{1}; // sign extend Rm?
2672 let Inst{14} = 1;
2673 let Inst{12} = extend{0}; // do shift?
2674 let Inst{11-10} = 0b10;
2675 let Inst{9-5} = Rn;
2676 let Inst{4-0} = Rt;
2677}
2678
2679multiclass Load16RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2680 string asm, ValueType Ty, SDPatternOperator loadop> {
2681 let AddedComplexity = 10 in
2682 def roW : LoadStore16RO<sz, V, opc, regtype, asm, (outs regtype:$Rt),
2683 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend16:$extend),
2684 [(set (Ty regtype:$Rt),
2685 (loadop (ro_Windexed16 GPR64sp:$Rn, GPR32:$Rm,
2686 ro_Wextend16:$extend)))]>,
2687 Sched<[WriteLDIdx, ReadAdrBase]> {
2688 let Inst{13} = 0b0;
2689 }
2690
2691 let AddedComplexity = 10 in
2692 def roX : LoadStore16RO<sz, V, opc, regtype, asm, (outs regtype:$Rt),
2693 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend16:$extend),
2694 [(set (Ty regtype:$Rt),
2695 (loadop (ro_Xindexed16 GPR64sp:$Rn, GPR64:$Rm,
2696 ro_Xextend16:$extend)))]>,
2697 Sched<[WriteLDIdx, ReadAdrBase]> {
2698 let Inst{13} = 0b1;
2699 }
2700
2701 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
2702}
2703
2704multiclass Store16RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2705 string asm, ValueType Ty, SDPatternOperator storeop> {
2706 let AddedComplexity = 10 in
2707 def roW : LoadStore16RO<sz, V, opc, regtype, asm, (outs),
2708 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend16:$extend),
2709 [(storeop (Ty regtype:$Rt),
2710 (ro_Windexed16 GPR64sp:$Rn, GPR32:$Rm,
2711 ro_Wextend16:$extend))]>,
2712 Sched<[WriteSTIdx, ReadAdrBase]> {
2713 let Inst{13} = 0b0;
2714 }
2715
2716 let AddedComplexity = 10 in
2717 def roX : LoadStore16RO<sz, V, opc, regtype, asm, (outs),
2718 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend16:$extend),
2719 [(storeop (Ty regtype:$Rt),
2720 (ro_Xindexed16 GPR64sp:$Rn, GPR64:$Rm,
2721 ro_Xextend16:$extend))]>,
2722 Sched<[WriteSTIdx, ReadAdrBase]> {
2723 let Inst{13} = 0b1;
2724 }
2725
2726 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
2727}
2728
2729class LoadStore32RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2730 string asm, dag ins, dag outs, list<dag> pat>
2731 : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> {
2732 bits<5> Rt;
2733 bits<5> Rn;
2734 bits<5> Rm;
2735 bits<2> extend;
2736 let Inst{31-30} = sz;
2737 let Inst{29-27} = 0b111;
2738 let Inst{26} = V;
2739 let Inst{25-24} = 0b00;
2740 let Inst{23-22} = opc;
2741 let Inst{21} = 1;
2742 let Inst{20-16} = Rm;
2743 let Inst{15} = extend{1}; // sign extend Rm?
2744 let Inst{14} = 1;
2745 let Inst{12} = extend{0}; // do shift?
2746 let Inst{11-10} = 0b10;
2747 let Inst{9-5} = Rn;
2748 let Inst{4-0} = Rt;
2749}
2750
2751multiclass Load32RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2752 string asm, ValueType Ty, SDPatternOperator loadop> {
2753 let AddedComplexity = 10 in
2754 def roW : LoadStore32RO<sz, V, opc, regtype, asm, (outs regtype:$Rt),
2755 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend32:$extend),
2756 [(set (Ty regtype:$Rt),
2757 (loadop (ro_Windexed32 GPR64sp:$Rn, GPR32:$Rm,
2758 ro_Wextend32:$extend)))]>,
2759 Sched<[WriteLDIdx, ReadAdrBase]> {
2760 let Inst{13} = 0b0;
2761 }
2762
2763 let AddedComplexity = 10 in
2764 def roX : LoadStore32RO<sz, V, opc, regtype, asm, (outs regtype:$Rt),
2765 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend32:$extend),
2766 [(set (Ty regtype:$Rt),
2767 (loadop (ro_Xindexed32 GPR64sp:$Rn, GPR64:$Rm,
2768 ro_Xextend32:$extend)))]>,
2769 Sched<[WriteLDIdx, ReadAdrBase]> {
2770 let Inst{13} = 0b1;
2771 }
2772
2773 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
2774}
2775
2776multiclass Store32RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2777 string asm, ValueType Ty, SDPatternOperator storeop> {
2778 let AddedComplexity = 10 in
2779 def roW : LoadStore32RO<sz, V, opc, regtype, asm, (outs),
2780 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend32:$extend),
2781 [(storeop (Ty regtype:$Rt),
2782 (ro_Windexed32 GPR64sp:$Rn, GPR32:$Rm,
2783 ro_Wextend32:$extend))]>,
2784 Sched<[WriteSTIdx, ReadAdrBase]> {
2785 let Inst{13} = 0b0;
2786 }
2787
2788 let AddedComplexity = 10 in
2789 def roX : LoadStore32RO<sz, V, opc, regtype, asm, (outs),
2790 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend32:$extend),
2791 [(storeop (Ty regtype:$Rt),
2792 (ro_Xindexed32 GPR64sp:$Rn, GPR64:$Rm,
2793 ro_Xextend32:$extend))]>,
2794 Sched<[WriteSTIdx, ReadAdrBase]> {
2795 let Inst{13} = 0b1;
2796 }
2797
2798 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
2799}
2800
2801class LoadStore64RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2802 string asm, dag ins, dag outs, list<dag> pat>
2803 : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> {
2804 bits<5> Rt;
2805 bits<5> Rn;
2806 bits<5> Rm;
2807 bits<2> extend;
2808 let Inst{31-30} = sz;
2809 let Inst{29-27} = 0b111;
2810 let Inst{26} = V;
2811 let Inst{25-24} = 0b00;
2812 let Inst{23-22} = opc;
2813 let Inst{21} = 1;
2814 let Inst{20-16} = Rm;
2815 let Inst{15} = extend{1}; // sign extend Rm?
2816 let Inst{14} = 1;
2817 let Inst{12} = extend{0}; // do shift?
2818 let Inst{11-10} = 0b10;
2819 let Inst{9-5} = Rn;
2820 let Inst{4-0} = Rt;
2821}
2822
2823multiclass Load64RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2824 string asm, ValueType Ty, SDPatternOperator loadop> {
2825 let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
2826 def roW : LoadStore64RO<sz, V, opc, regtype, asm, (outs regtype:$Rt),
2827 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend64:$extend),
2828 [(set (Ty regtype:$Rt),
2829 (loadop (ro_Windexed64 GPR64sp:$Rn, GPR32:$Rm,
2830 ro_Wextend64:$extend)))]>,
2831 Sched<[WriteLDIdx, ReadAdrBase]> {
2832 let Inst{13} = 0b0;
2833 }
2834
2835 let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
2836 def roX : LoadStore64RO<sz, V, opc, regtype, asm, (outs regtype:$Rt),
2837 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend64:$extend),
2838 [(set (Ty regtype:$Rt),
2839 (loadop (ro_Xindexed64 GPR64sp:$Rn, GPR64:$Rm,
2840 ro_Xextend64:$extend)))]>,
2841 Sched<[WriteLDIdx, ReadAdrBase]> {
2842 let Inst{13} = 0b1;
2843 }
2844
2845 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
2846}
2847
2848multiclass Store64RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2849 string asm, ValueType Ty, SDPatternOperator storeop> {
2850 let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
2851 def roW : LoadStore64RO<sz, V, opc, regtype, asm, (outs),
2852 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend64:$extend),
2853 [(storeop (Ty regtype:$Rt),
2854 (ro_Windexed64 GPR64sp:$Rn, GPR32:$Rm,
2855 ro_Wextend64:$extend))]>,
2856 Sched<[WriteSTIdx, ReadAdrBase]> {
2857 let Inst{13} = 0b0;
2858 }
2859
2860 let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
2861 def roX : LoadStore64RO<sz, V, opc, regtype, asm, (outs),
2862 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend64:$extend),
2863 [(storeop (Ty regtype:$Rt),
2864 (ro_Xindexed64 GPR64sp:$Rn, GPR64:$Rm,
2865 ro_Xextend64:$extend))]>,
2866 Sched<[WriteSTIdx, ReadAdrBase]> {
2867 let Inst{13} = 0b1;
2868 }
2869
2870 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
2871}
2872
2873class LoadStore128RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2874 string asm, dag ins, dag outs, list<dag> pat>
2875 : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> {
2876 bits<5> Rt;
2877 bits<5> Rn;
2878 bits<5> Rm;
2879 bits<2> extend;
2880 let Inst{31-30} = sz;
2881 let Inst{29-27} = 0b111;
2882 let Inst{26} = V;
2883 let Inst{25-24} = 0b00;
2884 let Inst{23-22} = opc;
2885 let Inst{21} = 1;
2886 let Inst{20-16} = Rm;
2887 let Inst{15} = extend{1}; // sign extend Rm?
2888 let Inst{14} = 1;
2889 let Inst{12} = extend{0}; // do shift?
2890 let Inst{11-10} = 0b10;
2891 let Inst{9-5} = Rn;
2892 let Inst{4-0} = Rt;
2893}
2894
2895multiclass Load128RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2896 string asm, ValueType Ty, SDPatternOperator loadop> {
2897 let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
2898 def roW : LoadStore128RO<sz, V, opc, regtype, asm, (outs regtype:$Rt),
2899 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend128:$extend),
2900 [(set (Ty regtype:$Rt),
2901 (loadop (ro_Windexed128 GPR64sp:$Rn, GPR32:$Rm,
2902 ro_Wextend128:$extend)))]>,
2903 Sched<[WriteLDIdx, ReadAdrBase]> {
2904 let Inst{13} = 0b0;
2905 }
2906
2907 let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
2908 def roX : LoadStore128RO<sz, V, opc, regtype, asm, (outs regtype:$Rt),
2909 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend128:$extend),
2910 [(set (Ty regtype:$Rt),
2911 (loadop (ro_Xindexed128 GPR64sp:$Rn, GPR64:$Rm,
2912 ro_Xextend128:$extend)))]>,
2913 Sched<[WriteLDIdx, ReadAdrBase]> {
2914 let Inst{13} = 0b1;
2915 }
2916
2917 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
2918}
2919
2920multiclass Store128RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2921 string asm, ValueType Ty, SDPatternOperator storeop> {
2922 let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
2923 def roW : LoadStore128RO<sz, V, opc, regtype, asm, (outs),
2924 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend128:$extend),
2925 [(storeop (Ty regtype:$Rt),
2926 (ro_Windexed128 GPR64sp:$Rn, GPR32:$Rm,
2927 ro_Wextend128:$extend))]>,
2928 Sched<[WriteSTIdx, ReadAdrBase]> {
2929 let Inst{13} = 0b0;
2930 }
2931
2932 let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
2933 def roX : LoadStore128RO<sz, V, opc, regtype, asm, (outs),
2934 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend128:$extend),
2935 [(storeop (Ty regtype:$Rt),
2936 (ro_Xindexed128 GPR64sp:$Rn, GPR64:$Rm,
2937 ro_Xextend128:$extend))]>,
2938 Sched<[WriteSTIdx, ReadAdrBase]> {
2939 let Inst{13} = 0b1;
2940 }
2941
2942 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
2943}
2944
2945let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in
2946class BasePrefetchRO<bits<2> sz, bit V, bits<2> opc, dag outs, dag ins,
2947 string asm, list<dag> pat>
2948 : I<outs, ins, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat>,
2949 Sched<[WriteLD]> {
2950 bits<5> Rt;
2951 bits<5> Rn;
2952 bits<5> Rm;
2953 bits<2> extend;
2954 let Inst{31-30} = sz;
2955 let Inst{29-27} = 0b111;
2956 let Inst{26} = V;
2957 let Inst{25-24} = 0b00;
2958 let Inst{23-22} = opc;
2959 let Inst{21} = 1;
2960 let Inst{20-16} = Rm;
2961 let Inst{15} = extend{1}; // sign extend Rm?
2962 let Inst{14} = 1;
2963 let Inst{12} = extend{0}; // do shift?
2964 let Inst{11-10} = 0b10;
2965 let Inst{9-5} = Rn;
2966 let Inst{4-0} = Rt;
2967}
2968
2969multiclass PrefetchRO<bits<2> sz, bit V, bits<2> opc, string asm> {
2970 def roW : BasePrefetchRO<sz, V, opc, (outs),
2971 (ins prfop:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend64:$extend),
2972 asm, [(AArch64Prefetch imm:$Rt,
2973 (ro_Windexed64 GPR64sp:$Rn, GPR32:$Rm,
2974 ro_Wextend64:$extend))]> {
2975 let Inst{13} = 0b0;
2976 }
2977
2978 def roX : BasePrefetchRO<sz, V, opc, (outs),
2979 (ins prfop:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend64:$extend),
2980 asm, [(AArch64Prefetch imm:$Rt,
2981 (ro_Xindexed64 GPR64sp:$Rn, GPR64:$Rm,
2982 ro_Xextend64:$extend))]> {
2983 let Inst{13} = 0b1;
2984 }
2985
2986 def : InstAlias<"prfm $Rt, [$Rn, $Rm]",
2987 (!cast<Instruction>(NAME # "roX") prfop:$Rt,
2988 GPR64sp:$Rn, GPR64:$Rm, 0, 0)>;
2989}
2990
2991//---
2992// Load/store unscaled immediate
2993//---
2994
2995def am_unscaled8 : ComplexPattern<i64, 2, "SelectAddrModeUnscaled8", []>;
2996def am_unscaled16 : ComplexPattern<i64, 2, "SelectAddrModeUnscaled16", []>;
2997def am_unscaled32 : ComplexPattern<i64, 2, "SelectAddrModeUnscaled32", []>;
2998def am_unscaled64 : ComplexPattern<i64, 2, "SelectAddrModeUnscaled64", []>;
2999def am_unscaled128 :ComplexPattern<i64, 2, "SelectAddrModeUnscaled128", []>;
3000
3001class BaseLoadStoreUnscale<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops,
3002 string asm, list<dag> pattern>
3003 : I<oops, iops, asm, "\t$Rt, [$Rn, $offset]", "", pattern> {
3004 bits<5> Rt;
3005 bits<5> Rn;
3006 bits<9> offset;
3007 let Inst{31-30} = sz;
3008 let Inst{29-27} = 0b111;
3009 let Inst{26} = V;
3010 let Inst{25-24} = 0b00;
3011 let Inst{23-22} = opc;
3012 let Inst{21} = 0;
3013 let Inst{20-12} = offset;
3014 let Inst{11-10} = 0b00;
3015 let Inst{9-5} = Rn;
3016 let Inst{4-0} = Rt;
3017
3018 let DecoderMethod = "DecodeSignedLdStInstruction";
3019}
3020
3021multiclass LoadUnscaled<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
3022 string asm, list<dag> pattern> {
3023 let AddedComplexity = 1 in // try this before LoadUI
3024 def i : BaseLoadStoreUnscale<sz, V, opc, (outs regtype:$Rt),
3025 (ins GPR64sp:$Rn, simm9:$offset), asm, pattern>,
3026 Sched<[WriteLD]>;
3027
Ahmed Bougachacca07712015-09-02 18:38:36 +00003028 def : InstAlias<asm # "\t$Rt, [$Rn]",
Tim Northover3b0846e2014-05-24 12:50:23 +00003029 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>;
3030}
3031
3032multiclass StoreUnscaled<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
3033 string asm, list<dag> pattern> {
3034 let AddedComplexity = 1 in // try this before StoreUI
3035 def i : BaseLoadStoreUnscale<sz, V, opc, (outs),
3036 (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset),
3037 asm, pattern>,
3038 Sched<[WriteST]>;
3039
Ahmed Bougachacca07712015-09-02 18:38:36 +00003040 def : InstAlias<asm # "\t$Rt, [$Rn]",
Tim Northover3b0846e2014-05-24 12:50:23 +00003041 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>;
3042}
3043
3044multiclass PrefetchUnscaled<bits<2> sz, bit V, bits<2> opc, string asm,
3045 list<dag> pat> {
3046 let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in
3047 def i : BaseLoadStoreUnscale<sz, V, opc, (outs),
3048 (ins prfop:$Rt, GPR64sp:$Rn, simm9:$offset),
3049 asm, pat>,
3050 Sched<[WriteLD]>;
3051
Ahmed Bougachacca07712015-09-02 18:38:36 +00003052 def : InstAlias<asm # "\t$Rt, [$Rn]",
Tim Northover3b0846e2014-05-24 12:50:23 +00003053 (!cast<Instruction>(NAME # "i") prfop:$Rt, GPR64sp:$Rn, 0)>;
3054}
3055
3056//---
3057// Load/store unscaled immediate, unprivileged
3058//---
3059
3060class BaseLoadStoreUnprivileged<bits<2> sz, bit V, bits<2> opc,
3061 dag oops, dag iops, string asm>
3062 : I<oops, iops, asm, "\t$Rt, [$Rn, $offset]", "", []> {
3063 bits<5> Rt;
3064 bits<5> Rn;
3065 bits<9> offset;
3066 let Inst{31-30} = sz;
3067 let Inst{29-27} = 0b111;
3068 let Inst{26} = V;
3069 let Inst{25-24} = 0b00;
3070 let Inst{23-22} = opc;
3071 let Inst{21} = 0;
3072 let Inst{20-12} = offset;
3073 let Inst{11-10} = 0b10;
3074 let Inst{9-5} = Rn;
3075 let Inst{4-0} = Rt;
3076
3077 let DecoderMethod = "DecodeSignedLdStInstruction";
3078}
3079
3080multiclass LoadUnprivileged<bits<2> sz, bit V, bits<2> opc,
3081 RegisterClass regtype, string asm> {
3082 let mayStore = 0, mayLoad = 1, hasSideEffects = 0 in
3083 def i : BaseLoadStoreUnprivileged<sz, V, opc, (outs regtype:$Rt),
3084 (ins GPR64sp:$Rn, simm9:$offset), asm>,
3085 Sched<[WriteLD]>;
3086
Ahmed Bougachacca07712015-09-02 18:38:36 +00003087 def : InstAlias<asm # "\t$Rt, [$Rn]",
Tim Northover3b0846e2014-05-24 12:50:23 +00003088 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>;
3089}
3090
3091multiclass StoreUnprivileged<bits<2> sz, bit V, bits<2> opc,
3092 RegisterClass regtype, string asm> {
3093 let mayStore = 1, mayLoad = 0, hasSideEffects = 0 in
3094 def i : BaseLoadStoreUnprivileged<sz, V, opc, (outs),
3095 (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset),
3096 asm>,
3097 Sched<[WriteST]>;
3098
Ahmed Bougachacca07712015-09-02 18:38:36 +00003099 def : InstAlias<asm # "\t$Rt, [$Rn]",
Tim Northover3b0846e2014-05-24 12:50:23 +00003100 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>;
3101}
3102
3103//---
3104// Load/store pre-indexed
3105//---
3106
3107class BaseLoadStorePreIdx<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops,
3108 string asm, string cstr, list<dag> pat>
3109 : I<oops, iops, asm, "\t$Rt, [$Rn, $offset]!", cstr, pat> {
3110 bits<5> Rt;
3111 bits<5> Rn;
3112 bits<9> offset;
3113 let Inst{31-30} = sz;
3114 let Inst{29-27} = 0b111;
3115 let Inst{26} = V;
3116 let Inst{25-24} = 0;
3117 let Inst{23-22} = opc;
3118 let Inst{21} = 0;
3119 let Inst{20-12} = offset;
3120 let Inst{11-10} = 0b11;
3121 let Inst{9-5} = Rn;
3122 let Inst{4-0} = Rt;
3123
3124 let DecoderMethod = "DecodeSignedLdStInstruction";
3125}
3126
3127let hasSideEffects = 0 in {
3128let mayStore = 0, mayLoad = 1 in
3129class LoadPreIdx<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
3130 string asm>
3131 : BaseLoadStorePreIdx<sz, V, opc,
3132 (outs GPR64sp:$wback, regtype:$Rt),
3133 (ins GPR64sp:$Rn, simm9:$offset), asm,
Quentin Colombetc64c1752014-08-11 21:39:53 +00003134 "$Rn = $wback,@earlyclobber $wback", []>,
Tim Northover3b0846e2014-05-24 12:50:23 +00003135 Sched<[WriteLD, WriteAdr]>;
3136
3137let mayStore = 1, mayLoad = 0 in
3138class StorePreIdx<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
3139 string asm, SDPatternOperator storeop, ValueType Ty>
3140 : BaseLoadStorePreIdx<sz, V, opc,
3141 (outs GPR64sp:$wback),
3142 (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset),
Quentin Colombetc64c1752014-08-11 21:39:53 +00003143 asm, "$Rn = $wback,@earlyclobber $wback",
Tim Northover3b0846e2014-05-24 12:50:23 +00003144 [(set GPR64sp:$wback,
3145 (storeop (Ty regtype:$Rt), GPR64sp:$Rn, simm9:$offset))]>,
3146 Sched<[WriteAdr, WriteST]>;
3147} // hasSideEffects = 0
3148
3149//---
3150// Load/store post-indexed
3151//---
3152
Tim Northover3b0846e2014-05-24 12:50:23 +00003153class BaseLoadStorePostIdx<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops,
3154 string asm, string cstr, list<dag> pat>
3155 : I<oops, iops, asm, "\t$Rt, [$Rn], $offset", cstr, pat> {
3156 bits<5> Rt;
3157 bits<5> Rn;
3158 bits<9> offset;
3159 let Inst{31-30} = sz;
3160 let Inst{29-27} = 0b111;
3161 let Inst{26} = V;
3162 let Inst{25-24} = 0b00;
3163 let Inst{23-22} = opc;
3164 let Inst{21} = 0b0;
3165 let Inst{20-12} = offset;
3166 let Inst{11-10} = 0b01;
3167 let Inst{9-5} = Rn;
3168 let Inst{4-0} = Rt;
3169
3170 let DecoderMethod = "DecodeSignedLdStInstruction";
3171}
3172
3173let hasSideEffects = 0 in {
3174let mayStore = 0, mayLoad = 1 in
3175class LoadPostIdx<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
3176 string asm>
3177 : BaseLoadStorePostIdx<sz, V, opc,
3178 (outs GPR64sp:$wback, regtype:$Rt),
3179 (ins GPR64sp:$Rn, simm9:$offset),
Quentin Colombetc64c1752014-08-11 21:39:53 +00003180 asm, "$Rn = $wback,@earlyclobber $wback", []>,
Tim Northover3b0846e2014-05-24 12:50:23 +00003181 Sched<[WriteLD, WriteI]>;
3182
3183let mayStore = 1, mayLoad = 0 in
3184class StorePostIdx<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
3185 string asm, SDPatternOperator storeop, ValueType Ty>
3186 : BaseLoadStorePostIdx<sz, V, opc,
3187 (outs GPR64sp:$wback),
3188 (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset),
Quentin Colombetc64c1752014-08-11 21:39:53 +00003189 asm, "$Rn = $wback,@earlyclobber $wback",
Tim Northover3b0846e2014-05-24 12:50:23 +00003190 [(set GPR64sp:$wback,
3191 (storeop (Ty regtype:$Rt), GPR64sp:$Rn, simm9:$offset))]>,
3192 Sched<[WriteAdr, WriteST, ReadAdrBase]>;
3193} // hasSideEffects = 0
3194
3195
3196//---
3197// Load/store pair
3198//---
3199
3200// (indexed, offset)
3201
3202class BaseLoadStorePairOffset<bits<2> opc, bit V, bit L, dag oops, dag iops,
3203 string asm>
3204 : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn, $offset]", "", []> {
3205 bits<5> Rt;
3206 bits<5> Rt2;
3207 bits<5> Rn;
3208 bits<7> offset;
3209 let Inst{31-30} = opc;
3210 let Inst{29-27} = 0b101;
3211 let Inst{26} = V;
3212 let Inst{25-23} = 0b010;
3213 let Inst{22} = L;
3214 let Inst{21-15} = offset;
3215 let Inst{14-10} = Rt2;
3216 let Inst{9-5} = Rn;
3217 let Inst{4-0} = Rt;
3218
3219 let DecoderMethod = "DecodePairLdStInstruction";
3220}
3221
3222multiclass LoadPairOffset<bits<2> opc, bit V, RegisterClass regtype,
3223 Operand indextype, string asm> {
3224 let hasSideEffects = 0, mayStore = 0, mayLoad = 1 in
3225 def i : BaseLoadStorePairOffset<opc, V, 1,
3226 (outs regtype:$Rt, regtype:$Rt2),
3227 (ins GPR64sp:$Rn, indextype:$offset), asm>,
3228 Sched<[WriteLD, WriteLDHi]>;
3229
Ahmed Bougachacca07712015-09-02 18:38:36 +00003230 def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]",
Tim Northover3b0846e2014-05-24 12:50:23 +00003231 (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2,
3232 GPR64sp:$Rn, 0)>;
3233}
3234
3235
3236multiclass StorePairOffset<bits<2> opc, bit V, RegisterClass regtype,
3237 Operand indextype, string asm> {
3238 let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in
3239 def i : BaseLoadStorePairOffset<opc, V, 0, (outs),
3240 (ins regtype:$Rt, regtype:$Rt2,
3241 GPR64sp:$Rn, indextype:$offset),
3242 asm>,
3243 Sched<[WriteSTP]>;
3244
Ahmed Bougachacca07712015-09-02 18:38:36 +00003245 def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]",
Tim Northover3b0846e2014-05-24 12:50:23 +00003246 (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2,
3247 GPR64sp:$Rn, 0)>;
3248}
3249
3250// (pre-indexed)
3251class BaseLoadStorePairPreIdx<bits<2> opc, bit V, bit L, dag oops, dag iops,
3252 string asm>
Quentin Colombetc64c1752014-08-11 21:39:53 +00003253 : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn, $offset]!", "$Rn = $wback,@earlyclobber $wback", []> {
Tim Northover3b0846e2014-05-24 12:50:23 +00003254 bits<5> Rt;
3255 bits<5> Rt2;
3256 bits<5> Rn;
3257 bits<7> offset;
3258 let Inst{31-30} = opc;
3259 let Inst{29-27} = 0b101;
3260 let Inst{26} = V;
3261 let Inst{25-23} = 0b011;
3262 let Inst{22} = L;
3263 let Inst{21-15} = offset;
3264 let Inst{14-10} = Rt2;
3265 let Inst{9-5} = Rn;
3266 let Inst{4-0} = Rt;
3267
3268 let DecoderMethod = "DecodePairLdStInstruction";
3269}
3270
3271let hasSideEffects = 0 in {
3272let mayStore = 0, mayLoad = 1 in
3273class LoadPairPreIdx<bits<2> opc, bit V, RegisterClass regtype,
3274 Operand indextype, string asm>
3275 : BaseLoadStorePairPreIdx<opc, V, 1,
3276 (outs GPR64sp:$wback, regtype:$Rt, regtype:$Rt2),
3277 (ins GPR64sp:$Rn, indextype:$offset), asm>,
3278 Sched<[WriteLD, WriteLDHi, WriteAdr]>;
3279
3280let mayStore = 1, mayLoad = 0 in
3281class StorePairPreIdx<bits<2> opc, bit V, RegisterClass regtype,
3282 Operand indextype, string asm>
3283 : BaseLoadStorePairPreIdx<opc, V, 0, (outs GPR64sp:$wback),
3284 (ins regtype:$Rt, regtype:$Rt2,
3285 GPR64sp:$Rn, indextype:$offset),
3286 asm>,
3287 Sched<[WriteAdr, WriteSTP]>;
3288} // hasSideEffects = 0
3289
3290// (post-indexed)
3291
3292class BaseLoadStorePairPostIdx<bits<2> opc, bit V, bit L, dag oops, dag iops,
3293 string asm>
Quentin Colombetc64c1752014-08-11 21:39:53 +00003294 : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn], $offset", "$Rn = $wback,@earlyclobber $wback", []> {
Tim Northover3b0846e2014-05-24 12:50:23 +00003295 bits<5> Rt;
3296 bits<5> Rt2;
3297 bits<5> Rn;
3298 bits<7> offset;
3299 let Inst{31-30} = opc;
3300 let Inst{29-27} = 0b101;
3301 let Inst{26} = V;
3302 let Inst{25-23} = 0b001;
3303 let Inst{22} = L;
3304 let Inst{21-15} = offset;
3305 let Inst{14-10} = Rt2;
3306 let Inst{9-5} = Rn;
3307 let Inst{4-0} = Rt;
3308
3309 let DecoderMethod = "DecodePairLdStInstruction";
3310}
3311
3312let hasSideEffects = 0 in {
3313let mayStore = 0, mayLoad = 1 in
3314class LoadPairPostIdx<bits<2> opc, bit V, RegisterClass regtype,
3315 Operand idxtype, string asm>
3316 : BaseLoadStorePairPostIdx<opc, V, 1,
3317 (outs GPR64sp:$wback, regtype:$Rt, regtype:$Rt2),
3318 (ins GPR64sp:$Rn, idxtype:$offset), asm>,
3319 Sched<[WriteLD, WriteLDHi, WriteAdr]>;
3320
3321let mayStore = 1, mayLoad = 0 in
3322class StorePairPostIdx<bits<2> opc, bit V, RegisterClass regtype,
3323 Operand idxtype, string asm>
Chad Rosier7cd472b2015-09-24 19:21:42 +00003324 : BaseLoadStorePairPostIdx<opc, V, 0, (outs GPR64sp:$wback),
3325 (ins regtype:$Rt, regtype:$Rt2,
Tim Northover3b0846e2014-05-24 12:50:23 +00003326 GPR64sp:$Rn, idxtype:$offset),
3327 asm>,
3328 Sched<[WriteAdr, WriteSTP]>;
3329} // hasSideEffects = 0
3330
3331// (no-allocate)
3332
3333class BaseLoadStorePairNoAlloc<bits<2> opc, bit V, bit L, dag oops, dag iops,
3334 string asm>
3335 : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn, $offset]", "", []> {
3336 bits<5> Rt;
3337 bits<5> Rt2;
3338 bits<5> Rn;
3339 bits<7> offset;
3340 let Inst{31-30} = opc;
3341 let Inst{29-27} = 0b101;
3342 let Inst{26} = V;
3343 let Inst{25-23} = 0b000;
3344 let Inst{22} = L;
3345 let Inst{21-15} = offset;
3346 let Inst{14-10} = Rt2;
3347 let Inst{9-5} = Rn;
3348 let Inst{4-0} = Rt;
3349
3350 let DecoderMethod = "DecodePairLdStInstruction";
3351}
3352
3353multiclass LoadPairNoAlloc<bits<2> opc, bit V, RegisterClass regtype,
3354 Operand indextype, string asm> {
3355 let hasSideEffects = 0, mayStore = 0, mayLoad = 1 in
3356 def i : BaseLoadStorePairNoAlloc<opc, V, 1,
3357 (outs regtype:$Rt, regtype:$Rt2),
3358 (ins GPR64sp:$Rn, indextype:$offset), asm>,
3359 Sched<[WriteLD, WriteLDHi]>;
3360
3361
3362 def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]",
3363 (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2,
3364 GPR64sp:$Rn, 0)>;
3365}
3366
3367multiclass StorePairNoAlloc<bits<2> opc, bit V, RegisterClass regtype,
3368 Operand indextype, string asm> {
3369 let hasSideEffects = 0, mayStore = 1, mayLoad = 0 in
3370 def i : BaseLoadStorePairNoAlloc<opc, V, 0, (outs),
3371 (ins regtype:$Rt, regtype:$Rt2,
3372 GPR64sp:$Rn, indextype:$offset),
3373 asm>,
3374 Sched<[WriteSTP]>;
3375
3376 def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]",
3377 (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2,
3378 GPR64sp:$Rn, 0)>;
3379}
3380
3381//---
3382// Load/store exclusive
3383//---
3384
3385// True exclusive operations write to and/or read from the system's exclusive
3386// monitors, which as far as a compiler is concerned can be modelled as a
3387// random shared memory address. Hence LoadExclusive mayStore.
3388//
3389// Since these instructions have the undefined register bits set to 1 in
3390// their canonical form, we need a post encoder method to set those bits
3391// to 1 when encoding these instructions. We do this using the
3392// fixLoadStoreExclusive function. This function has template parameters:
3393//
3394// fixLoadStoreExclusive<int hasRs, int hasRt2>
3395//
3396// hasRs indicates that the instruction uses the Rs field, so we won't set
3397// it to 1 (and the same for Rt2). We don't need template parameters for
3398// the other register fields since Rt and Rn are always used.
3399//
3400let hasSideEffects = 1, mayLoad = 1, mayStore = 1 in
3401class BaseLoadStoreExclusive<bits<2> sz, bit o2, bit L, bit o1, bit o0,
3402 dag oops, dag iops, string asm, string operands>
3403 : I<oops, iops, asm, operands, "", []> {
3404 let Inst{31-30} = sz;
3405 let Inst{29-24} = 0b001000;
3406 let Inst{23} = o2;
3407 let Inst{22} = L;
3408 let Inst{21} = o1;
3409 let Inst{15} = o0;
3410
3411 let DecoderMethod = "DecodeExclusiveLdStInstruction";
3412}
3413
3414// Neither Rs nor Rt2 operands.
3415class LoadStoreExclusiveSimple<bits<2> sz, bit o2, bit L, bit o1, bit o0,
3416 dag oops, dag iops, string asm, string operands>
3417 : BaseLoadStoreExclusive<sz, o2, L, o1, o0, oops, iops, asm, operands> {
3418 bits<5> Rt;
3419 bits<5> Rn;
Vladimir Sukharevd49cb8f2015-04-16 15:30:43 +00003420 let Inst{20-16} = 0b11111;
3421 let Unpredictable{20-16} = 0b11111;
3422 let Inst{14-10} = 0b11111;
3423 let Unpredictable{14-10} = 0b11111;
Tim Northover3b0846e2014-05-24 12:50:23 +00003424 let Inst{9-5} = Rn;
3425 let Inst{4-0} = Rt;
3426
3427 let PostEncoderMethod = "fixLoadStoreExclusive<0,0>";
3428}
3429
3430// Simple load acquires don't set the exclusive monitor
3431let mayLoad = 1, mayStore = 0 in
3432class LoadAcquire<bits<2> sz, bit o2, bit L, bit o1, bit o0,
3433 RegisterClass regtype, string asm>
3434 : LoadStoreExclusiveSimple<sz, o2, L, o1, o0, (outs regtype:$Rt),
3435 (ins GPR64sp0:$Rn), asm, "\t$Rt, [$Rn]">,
3436 Sched<[WriteLD]>;
3437
3438class LoadExclusive<bits<2> sz, bit o2, bit L, bit o1, bit o0,
3439 RegisterClass regtype, string asm>
3440 : LoadStoreExclusiveSimple<sz, o2, L, o1, o0, (outs regtype:$Rt),
3441 (ins GPR64sp0:$Rn), asm, "\t$Rt, [$Rn]">,
3442 Sched<[WriteLD]>;
3443
3444class LoadExclusivePair<bits<2> sz, bit o2, bit L, bit o1, bit o0,
3445 RegisterClass regtype, string asm>
3446 : BaseLoadStoreExclusive<sz, o2, L, o1, o0,
3447 (outs regtype:$Rt, regtype:$Rt2),
3448 (ins GPR64sp0:$Rn), asm,
3449 "\t$Rt, $Rt2, [$Rn]">,
3450 Sched<[WriteLD, WriteLDHi]> {
3451 bits<5> Rt;
3452 bits<5> Rt2;
3453 bits<5> Rn;
3454 let Inst{14-10} = Rt2;
3455 let Inst{9-5} = Rn;
3456 let Inst{4-0} = Rt;
3457
3458 let PostEncoderMethod = "fixLoadStoreExclusive<0,1>";
3459}
3460
3461// Simple store release operations do not check the exclusive monitor.
3462let mayLoad = 0, mayStore = 1 in
3463class StoreRelease<bits<2> sz, bit o2, bit L, bit o1, bit o0,
3464 RegisterClass regtype, string asm>
3465 : LoadStoreExclusiveSimple<sz, o2, L, o1, o0, (outs),
3466 (ins regtype:$Rt, GPR64sp0:$Rn),
3467 asm, "\t$Rt, [$Rn]">,
3468 Sched<[WriteST]>;
3469
3470let mayLoad = 1, mayStore = 1 in
3471class StoreExclusive<bits<2> sz, bit o2, bit L, bit o1, bit o0,
3472 RegisterClass regtype, string asm>
3473 : BaseLoadStoreExclusive<sz, o2, L, o1, o0, (outs GPR32:$Ws),
3474 (ins regtype:$Rt, GPR64sp0:$Rn),
3475 asm, "\t$Ws, $Rt, [$Rn]">,
3476 Sched<[WriteSTX]> {
3477 bits<5> Ws;
3478 bits<5> Rt;
3479 bits<5> Rn;
3480 let Inst{20-16} = Ws;
3481 let Inst{9-5} = Rn;
3482 let Inst{4-0} = Rt;
3483
3484 let Constraints = "@earlyclobber $Ws";
3485 let PostEncoderMethod = "fixLoadStoreExclusive<1,0>";
3486}
3487
3488class StoreExclusivePair<bits<2> sz, bit o2, bit L, bit o1, bit o0,
3489 RegisterClass regtype, string asm>
3490 : BaseLoadStoreExclusive<sz, o2, L, o1, o0,
3491 (outs GPR32:$Ws),
3492 (ins regtype:$Rt, regtype:$Rt2, GPR64sp0:$Rn),
3493 asm, "\t$Ws, $Rt, $Rt2, [$Rn]">,
3494 Sched<[WriteSTX]> {
3495 bits<5> Ws;
3496 bits<5> Rt;
3497 bits<5> Rt2;
3498 bits<5> Rn;
3499 let Inst{20-16} = Ws;
3500 let Inst{14-10} = Rt2;
3501 let Inst{9-5} = Rn;
3502 let Inst{4-0} = Rt;
3503
3504 let Constraints = "@earlyclobber $Ws";
3505}
3506
3507//---
3508// Exception generation
3509//---
3510
3511let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in
3512class ExceptionGeneration<bits<3> op1, bits<2> ll, string asm>
3513 : I<(outs), (ins imm0_65535:$imm), asm, "\t$imm", "", []>,
3514 Sched<[WriteSys]> {
3515 bits<16> imm;
3516 let Inst{31-24} = 0b11010100;
3517 let Inst{23-21} = op1;
3518 let Inst{20-5} = imm;
3519 let Inst{4-2} = 0b000;
3520 let Inst{1-0} = ll;
3521}
3522
3523let Predicates = [HasFPARMv8] in {
3524
3525//---
3526// Floating point to integer conversion
3527//---
3528
3529class BaseFPToIntegerUnscaled<bits<2> type, bits<2> rmode, bits<3> opcode,
3530 RegisterClass srcType, RegisterClass dstType,
3531 string asm, list<dag> pattern>
3532 : I<(outs dstType:$Rd), (ins srcType:$Rn),
3533 asm, "\t$Rd, $Rn", "", pattern>,
3534 Sched<[WriteFCvt]> {
3535 bits<5> Rd;
3536 bits<5> Rn;
3537 let Inst{30-29} = 0b00;
3538 let Inst{28-24} = 0b11110;
3539 let Inst{23-22} = type;
3540 let Inst{21} = 1;
3541 let Inst{20-19} = rmode;
3542 let Inst{18-16} = opcode;
3543 let Inst{15-10} = 0;
3544 let Inst{9-5} = Rn;
3545 let Inst{4-0} = Rd;
3546}
3547
3548let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
3549class BaseFPToInteger<bits<2> type, bits<2> rmode, bits<3> opcode,
3550 RegisterClass srcType, RegisterClass dstType,
3551 Operand immType, string asm, list<dag> pattern>
3552 : I<(outs dstType:$Rd), (ins srcType:$Rn, immType:$scale),
3553 asm, "\t$Rd, $Rn, $scale", "", pattern>,
3554 Sched<[WriteFCvt]> {
3555 bits<5> Rd;
3556 bits<5> Rn;
3557 bits<6> scale;
3558 let Inst{30-29} = 0b00;
3559 let Inst{28-24} = 0b11110;
3560 let Inst{23-22} = type;
3561 let Inst{21} = 0;
3562 let Inst{20-19} = rmode;
3563 let Inst{18-16} = opcode;
3564 let Inst{15-10} = scale;
3565 let Inst{9-5} = Rn;
3566 let Inst{4-0} = Rd;
3567}
3568
3569multiclass FPToIntegerUnscaled<bits<2> rmode, bits<3> opcode, string asm,
3570 SDPatternOperator OpN> {
Oliver Stannardb25914e2015-11-27 13:04:48 +00003571 // Unscaled half-precision to 32-bit
3572 def UWHr : BaseFPToIntegerUnscaled<0b11, rmode, opcode, FPR16, GPR32, asm,
3573 [(set GPR32:$Rd, (OpN FPR16:$Rn))]> {
3574 let Inst{31} = 0; // 32-bit GPR flag
3575 let Predicates = [HasFullFP16];
3576 }
3577
3578 // Unscaled half-precision to 64-bit
3579 def UXHr : BaseFPToIntegerUnscaled<0b11, rmode, opcode, FPR16, GPR64, asm,
3580 [(set GPR64:$Rd, (OpN FPR16:$Rn))]> {
3581 let Inst{31} = 1; // 64-bit GPR flag
3582 let Predicates = [HasFullFP16];
3583 }
3584
Tim Northover3b0846e2014-05-24 12:50:23 +00003585 // Unscaled single-precision to 32-bit
3586 def UWSr : BaseFPToIntegerUnscaled<0b00, rmode, opcode, FPR32, GPR32, asm,
3587 [(set GPR32:$Rd, (OpN FPR32:$Rn))]> {
3588 let Inst{31} = 0; // 32-bit GPR flag
3589 }
3590
3591 // Unscaled single-precision to 64-bit
3592 def UXSr : BaseFPToIntegerUnscaled<0b00, rmode, opcode, FPR32, GPR64, asm,
3593 [(set GPR64:$Rd, (OpN FPR32:$Rn))]> {
3594 let Inst{31} = 1; // 64-bit GPR flag
3595 }
3596
3597 // Unscaled double-precision to 32-bit
3598 def UWDr : BaseFPToIntegerUnscaled<0b01, rmode, opcode, FPR64, GPR32, asm,
3599 [(set GPR32:$Rd, (OpN (f64 FPR64:$Rn)))]> {
3600 let Inst{31} = 0; // 32-bit GPR flag
3601 }
3602
3603 // Unscaled double-precision to 64-bit
3604 def UXDr : BaseFPToIntegerUnscaled<0b01, rmode, opcode, FPR64, GPR64, asm,
3605 [(set GPR64:$Rd, (OpN (f64 FPR64:$Rn)))]> {
3606 let Inst{31} = 1; // 64-bit GPR flag
3607 }
3608}
3609
3610multiclass FPToIntegerScaled<bits<2> rmode, bits<3> opcode, string asm,
3611 SDPatternOperator OpN> {
Oliver Stannardb25914e2015-11-27 13:04:48 +00003612 // Scaled half-precision to 32-bit
3613 def SWHri : BaseFPToInteger<0b11, rmode, opcode, FPR16, GPR32,
3614 fixedpoint_f16_i32, asm,
3615 [(set GPR32:$Rd, (OpN (fmul FPR16:$Rn,
3616 fixedpoint_f16_i32:$scale)))]> {
3617 let Inst{31} = 0; // 32-bit GPR flag
3618 let scale{5} = 1;
3619 let Predicates = [HasFullFP16];
3620 }
3621
3622 // Scaled half-precision to 64-bit
3623 def SXHri : BaseFPToInteger<0b11, rmode, opcode, FPR16, GPR64,
3624 fixedpoint_f16_i64, asm,
3625 [(set GPR64:$Rd, (OpN (fmul FPR16:$Rn,
3626 fixedpoint_f16_i64:$scale)))]> {
3627 let Inst{31} = 1; // 64-bit GPR flag
3628 let Predicates = [HasFullFP16];
3629 }
3630
Tim Northover3b0846e2014-05-24 12:50:23 +00003631 // Scaled single-precision to 32-bit
3632 def SWSri : BaseFPToInteger<0b00, rmode, opcode, FPR32, GPR32,
3633 fixedpoint_f32_i32, asm,
3634 [(set GPR32:$Rd, (OpN (fmul FPR32:$Rn,
3635 fixedpoint_f32_i32:$scale)))]> {
3636 let Inst{31} = 0; // 32-bit GPR flag
3637 let scale{5} = 1;
3638 }
3639
3640 // Scaled single-precision to 64-bit
3641 def SXSri : BaseFPToInteger<0b00, rmode, opcode, FPR32, GPR64,
3642 fixedpoint_f32_i64, asm,
3643 [(set GPR64:$Rd, (OpN (fmul FPR32:$Rn,
3644 fixedpoint_f32_i64:$scale)))]> {
3645 let Inst{31} = 1; // 64-bit GPR flag
3646 }
3647
3648 // Scaled double-precision to 32-bit
3649 def SWDri : BaseFPToInteger<0b01, rmode, opcode, FPR64, GPR32,
3650 fixedpoint_f64_i32, asm,
3651 [(set GPR32:$Rd, (OpN (fmul FPR64:$Rn,
3652 fixedpoint_f64_i32:$scale)))]> {
3653 let Inst{31} = 0; // 32-bit GPR flag
3654 let scale{5} = 1;
3655 }
3656
3657 // Scaled double-precision to 64-bit
3658 def SXDri : BaseFPToInteger<0b01, rmode, opcode, FPR64, GPR64,
3659 fixedpoint_f64_i64, asm,
3660 [(set GPR64:$Rd, (OpN (fmul FPR64:$Rn,
3661 fixedpoint_f64_i64:$scale)))]> {
3662 let Inst{31} = 1; // 64-bit GPR flag
3663 }
3664}
3665
3666//---
3667// Integer to floating point conversion
3668//---
3669
3670let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
3671class BaseIntegerToFP<bit isUnsigned,
3672 RegisterClass srcType, RegisterClass dstType,
3673 Operand immType, string asm, list<dag> pattern>
3674 : I<(outs dstType:$Rd), (ins srcType:$Rn, immType:$scale),
3675 asm, "\t$Rd, $Rn, $scale", "", pattern>,
3676 Sched<[WriteFCvt]> {
3677 bits<5> Rd;
3678 bits<5> Rn;
3679 bits<6> scale;
Oliver Stannardb25914e2015-11-27 13:04:48 +00003680 let Inst{30-24} = 0b0011110;
Tim Northover3b0846e2014-05-24 12:50:23 +00003681 let Inst{21-17} = 0b00001;
3682 let Inst{16} = isUnsigned;
3683 let Inst{15-10} = scale;
3684 let Inst{9-5} = Rn;
3685 let Inst{4-0} = Rd;
3686}
3687
3688class BaseIntegerToFPUnscaled<bit isUnsigned,
3689 RegisterClass srcType, RegisterClass dstType,
3690 ValueType dvt, string asm, SDNode node>
3691 : I<(outs dstType:$Rd), (ins srcType:$Rn),
3692 asm, "\t$Rd, $Rn", "", [(set (dvt dstType:$Rd), (node srcType:$Rn))]>,
3693 Sched<[WriteFCvt]> {
3694 bits<5> Rd;
3695 bits<5> Rn;
3696 bits<6> scale;
Oliver Stannardb25914e2015-11-27 13:04:48 +00003697 let Inst{30-24} = 0b0011110;
Tim Northover3b0846e2014-05-24 12:50:23 +00003698 let Inst{21-17} = 0b10001;
3699 let Inst{16} = isUnsigned;
3700 let Inst{15-10} = 0b000000;
3701 let Inst{9-5} = Rn;
3702 let Inst{4-0} = Rd;
3703}
3704
3705multiclass IntegerToFP<bit isUnsigned, string asm, SDNode node> {
3706 // Unscaled
Oliver Stannardb25914e2015-11-27 13:04:48 +00003707 def UWHri: BaseIntegerToFPUnscaled<isUnsigned, GPR32, FPR16, f16, asm, node> {
3708 let Inst{31} = 0; // 32-bit GPR flag
3709 let Inst{23-22} = 0b11; // 16-bit FPR flag
3710 let Predicates = [HasFullFP16];
3711 }
3712
Tim Northover3b0846e2014-05-24 12:50:23 +00003713 def UWSri: BaseIntegerToFPUnscaled<isUnsigned, GPR32, FPR32, f32, asm, node> {
3714 let Inst{31} = 0; // 32-bit GPR flag
Oliver Stannardb25914e2015-11-27 13:04:48 +00003715 let Inst{23-22} = 0b00; // 32-bit FPR flag
Tim Northover3b0846e2014-05-24 12:50:23 +00003716 }
3717
3718 def UWDri: BaseIntegerToFPUnscaled<isUnsigned, GPR32, FPR64, f64, asm, node> {
3719 let Inst{31} = 0; // 32-bit GPR flag
Oliver Stannardb25914e2015-11-27 13:04:48 +00003720 let Inst{23-22} = 0b01; // 64-bit FPR flag
3721 }
3722
3723 def UXHri: BaseIntegerToFPUnscaled<isUnsigned, GPR64, FPR16, f16, asm, node> {
3724 let Inst{31} = 1; // 64-bit GPR flag
3725 let Inst{23-22} = 0b11; // 16-bit FPR flag
3726 let Predicates = [HasFullFP16];
Tim Northover3b0846e2014-05-24 12:50:23 +00003727 }
3728
3729 def UXSri: BaseIntegerToFPUnscaled<isUnsigned, GPR64, FPR32, f32, asm, node> {
3730 let Inst{31} = 1; // 64-bit GPR flag
Oliver Stannardb25914e2015-11-27 13:04:48 +00003731 let Inst{23-22} = 0b00; // 32-bit FPR flag
Tim Northover3b0846e2014-05-24 12:50:23 +00003732 }
3733
3734 def UXDri: BaseIntegerToFPUnscaled<isUnsigned, GPR64, FPR64, f64, asm, node> {
3735 let Inst{31} = 1; // 64-bit GPR flag
Oliver Stannardb25914e2015-11-27 13:04:48 +00003736 let Inst{23-22} = 0b01; // 64-bit FPR flag
Tim Northover3b0846e2014-05-24 12:50:23 +00003737 }
3738
3739 // Scaled
Oliver Stannardb25914e2015-11-27 13:04:48 +00003740 def SWHri: BaseIntegerToFP<isUnsigned, GPR32, FPR16, fixedpoint_f16_i32, asm,
3741 [(set FPR16:$Rd,
3742 (fdiv (node GPR32:$Rn),
3743 fixedpoint_f16_i32:$scale))]> {
3744 let Inst{31} = 0; // 32-bit GPR flag
3745 let Inst{23-22} = 0b11; // 16-bit FPR flag
3746 let scale{5} = 1;
3747 let Predicates = [HasFullFP16];
3748 }
3749
Tim Northover3b0846e2014-05-24 12:50:23 +00003750 def SWSri: BaseIntegerToFP<isUnsigned, GPR32, FPR32, fixedpoint_f32_i32, asm,
3751 [(set FPR32:$Rd,
3752 (fdiv (node GPR32:$Rn),
3753 fixedpoint_f32_i32:$scale))]> {
3754 let Inst{31} = 0; // 32-bit GPR flag
Oliver Stannardb25914e2015-11-27 13:04:48 +00003755 let Inst{23-22} = 0b00; // 32-bit FPR flag
Tim Northover3b0846e2014-05-24 12:50:23 +00003756 let scale{5} = 1;
3757 }
3758
3759 def SWDri: BaseIntegerToFP<isUnsigned, GPR32, FPR64, fixedpoint_f64_i32, asm,
3760 [(set FPR64:$Rd,
3761 (fdiv (node GPR32:$Rn),
3762 fixedpoint_f64_i32:$scale))]> {
3763 let Inst{31} = 0; // 32-bit GPR flag
Oliver Stannardb25914e2015-11-27 13:04:48 +00003764 let Inst{23-22} = 0b01; // 64-bit FPR flag
Tim Northover3b0846e2014-05-24 12:50:23 +00003765 let scale{5} = 1;
3766 }
3767
Oliver Stannardb25914e2015-11-27 13:04:48 +00003768 def SXHri: BaseIntegerToFP<isUnsigned, GPR64, FPR16, fixedpoint_f16_i64, asm,
3769 [(set FPR16:$Rd,
3770 (fdiv (node GPR64:$Rn),
3771 fixedpoint_f16_i64:$scale))]> {
3772 let Inst{31} = 1; // 64-bit GPR flag
3773 let Inst{23-22} = 0b11; // 16-bit FPR flag
3774 let Predicates = [HasFullFP16];
3775 }
3776
Tim Northover3b0846e2014-05-24 12:50:23 +00003777 def SXSri: BaseIntegerToFP<isUnsigned, GPR64, FPR32, fixedpoint_f32_i64, asm,
3778 [(set FPR32:$Rd,
3779 (fdiv (node GPR64:$Rn),
3780 fixedpoint_f32_i64:$scale))]> {
3781 let Inst{31} = 1; // 64-bit GPR flag
Oliver Stannardb25914e2015-11-27 13:04:48 +00003782 let Inst{23-22} = 0b00; // 32-bit FPR flag
Tim Northover3b0846e2014-05-24 12:50:23 +00003783 }
3784
3785 def SXDri: BaseIntegerToFP<isUnsigned, GPR64, FPR64, fixedpoint_f64_i64, asm,
3786 [(set FPR64:$Rd,
3787 (fdiv (node GPR64:$Rn),
3788 fixedpoint_f64_i64:$scale))]> {
3789 let Inst{31} = 1; // 64-bit GPR flag
Oliver Stannardb25914e2015-11-27 13:04:48 +00003790 let Inst{23-22} = 0b01; // 64-bit FPR flag
Tim Northover3b0846e2014-05-24 12:50:23 +00003791 }
3792}
3793
3794//---
3795// Unscaled integer <-> floating point conversion (i.e. FMOV)
3796//---
3797
3798let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
3799class BaseUnscaledConversion<bits<2> rmode, bits<3> opcode,
3800 RegisterClass srcType, RegisterClass dstType,
3801 string asm>
3802 : I<(outs dstType:$Rd), (ins srcType:$Rn), asm, "\t$Rd, $Rn", "",
3803 // We use COPY_TO_REGCLASS for these bitconvert operations.
3804 // copyPhysReg() expands the resultant COPY instructions after
3805 // regalloc is done. This gives greater freedom for the allocator
3806 // and related passes (coalescing, copy propagation, et. al.) to
3807 // be more effective.
3808 [/*(set (dvt dstType:$Rd), (bitconvert (svt srcType:$Rn)))*/]>,
3809 Sched<[WriteFCopy]> {
3810 bits<5> Rd;
3811 bits<5> Rn;
Oliver Stannardb25914e2015-11-27 13:04:48 +00003812 let Inst{30-24} = 0b0011110;
Tim Northover3b0846e2014-05-24 12:50:23 +00003813 let Inst{21} = 1;
3814 let Inst{20-19} = rmode;
3815 let Inst{18-16} = opcode;
3816 let Inst{15-10} = 0b000000;
3817 let Inst{9-5} = Rn;
3818 let Inst{4-0} = Rd;
3819}
3820
3821let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
3822class BaseUnscaledConversionToHigh<bits<2> rmode, bits<3> opcode,
3823 RegisterClass srcType, RegisterOperand dstType, string asm,
3824 string kind>
3825 : I<(outs dstType:$Rd), (ins srcType:$Rn, VectorIndex1:$idx), asm,
3826 "{\t$Rd"#kind#"$idx, $Rn|"#kind#"\t$Rd$idx, $Rn}", "", []>,
3827 Sched<[WriteFCopy]> {
3828 bits<5> Rd;
3829 bits<5> Rn;
3830 let Inst{30-23} = 0b00111101;
3831 let Inst{21} = 1;
3832 let Inst{20-19} = rmode;
3833 let Inst{18-16} = opcode;
3834 let Inst{15-10} = 0b000000;
3835 let Inst{9-5} = Rn;
3836 let Inst{4-0} = Rd;
3837
3838 let DecoderMethod = "DecodeFMOVLaneInstruction";
3839}
3840
3841let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
3842class BaseUnscaledConversionFromHigh<bits<2> rmode, bits<3> opcode,
3843 RegisterOperand srcType, RegisterClass dstType, string asm,
3844 string kind>
3845 : I<(outs dstType:$Rd), (ins srcType:$Rn, VectorIndex1:$idx), asm,
3846 "{\t$Rd, $Rn"#kind#"$idx|"#kind#"\t$Rd, $Rn$idx}", "", []>,
3847 Sched<[WriteFCopy]> {
3848 bits<5> Rd;
3849 bits<5> Rn;
3850 let Inst{30-23} = 0b00111101;
3851 let Inst{21} = 1;
3852 let Inst{20-19} = rmode;
3853 let Inst{18-16} = opcode;
3854 let Inst{15-10} = 0b000000;
3855 let Inst{9-5} = Rn;
3856 let Inst{4-0} = Rd;
3857
3858 let DecoderMethod = "DecodeFMOVLaneInstruction";
3859}
3860
3861
Tim Northover3b0846e2014-05-24 12:50:23 +00003862multiclass UnscaledConversion<string asm> {
Oliver Stannardb25914e2015-11-27 13:04:48 +00003863 def WHr : BaseUnscaledConversion<0b00, 0b111, GPR32, FPR16, asm> {
3864 let Inst{31} = 0; // 32-bit GPR flag
3865 let Inst{23-22} = 0b11; // 16-bit FPR flag
3866 let Predicates = [HasFullFP16];
3867 }
3868
3869 def XHr : BaseUnscaledConversion<0b00, 0b111, GPR64, FPR16, asm> {
3870 let Inst{31} = 1; // 64-bit GPR flag
3871 let Inst{23-22} = 0b11; // 16-bit FPR flag
3872 let Predicates = [HasFullFP16];
3873 }
3874
Tim Northover3b0846e2014-05-24 12:50:23 +00003875 def WSr : BaseUnscaledConversion<0b00, 0b111, GPR32, FPR32, asm> {
3876 let Inst{31} = 0; // 32-bit GPR flag
Oliver Stannardb25914e2015-11-27 13:04:48 +00003877 let Inst{23-22} = 0b00; // 32-bit FPR flag
Tim Northover3b0846e2014-05-24 12:50:23 +00003878 }
3879
3880 def XDr : BaseUnscaledConversion<0b00, 0b111, GPR64, FPR64, asm> {
3881 let Inst{31} = 1; // 64-bit GPR flag
Oliver Stannardb25914e2015-11-27 13:04:48 +00003882 let Inst{23-22} = 0b01; // 64-bit FPR flag
3883 }
3884
3885 def HWr : BaseUnscaledConversion<0b00, 0b110, FPR16, GPR32, asm> {
3886 let Inst{31} = 0; // 32-bit GPR flag
3887 let Inst{23-22} = 0b11; // 16-bit FPR flag
3888 let Predicates = [HasFullFP16];
3889 }
3890
3891 def HXr : BaseUnscaledConversion<0b00, 0b110, FPR16, GPR64, asm> {
3892 let Inst{31} = 1; // 64-bit GPR flag
3893 let Inst{23-22} = 0b11; // 16-bit FPR flag
3894 let Predicates = [HasFullFP16];
Tim Northover3b0846e2014-05-24 12:50:23 +00003895 }
3896
3897 def SWr : BaseUnscaledConversion<0b00, 0b110, FPR32, GPR32, asm> {
3898 let Inst{31} = 0; // 32-bit GPR flag
Oliver Stannardb25914e2015-11-27 13:04:48 +00003899 let Inst{23-22} = 0b00; // 32-bit FPR flag
Tim Northover3b0846e2014-05-24 12:50:23 +00003900 }
3901
3902 def DXr : BaseUnscaledConversion<0b00, 0b110, FPR64, GPR64, asm> {
3903 let Inst{31} = 1; // 64-bit GPR flag
Oliver Stannardb25914e2015-11-27 13:04:48 +00003904 let Inst{23-22} = 0b01; // 64-bit FPR flag
Tim Northover3b0846e2014-05-24 12:50:23 +00003905 }
3906
3907 def XDHighr : BaseUnscaledConversionToHigh<0b01, 0b111, GPR64, V128,
3908 asm, ".d"> {
3909 let Inst{31} = 1;
3910 let Inst{22} = 0;
3911 }
3912
3913 def DXHighr : BaseUnscaledConversionFromHigh<0b01, 0b110, V128, GPR64,
3914 asm, ".d"> {
3915 let Inst{31} = 1;
3916 let Inst{22} = 0;
3917 }
3918}
3919
3920//---
3921// Floating point conversion
3922//---
3923
3924class BaseFPConversion<bits<2> type, bits<2> opcode, RegisterClass dstType,
3925 RegisterClass srcType, string asm, list<dag> pattern>
3926 : I<(outs dstType:$Rd), (ins srcType:$Rn), asm, "\t$Rd, $Rn", "", pattern>,
3927 Sched<[WriteFCvt]> {
3928 bits<5> Rd;
3929 bits<5> Rn;
3930 let Inst{31-24} = 0b00011110;
3931 let Inst{23-22} = type;
3932 let Inst{21-17} = 0b10001;
3933 let Inst{16-15} = opcode;
3934 let Inst{14-10} = 0b10000;
3935 let Inst{9-5} = Rn;
3936 let Inst{4-0} = Rd;
3937}
3938
3939multiclass FPConversion<string asm> {
3940 // Double-precision to Half-precision
3941 def HDr : BaseFPConversion<0b01, 0b11, FPR16, FPR64, asm,
3942 [(set FPR16:$Rd, (fround FPR64:$Rn))]>;
3943
3944 // Double-precision to Single-precision
3945 def SDr : BaseFPConversion<0b01, 0b00, FPR32, FPR64, asm,
3946 [(set FPR32:$Rd, (fround FPR64:$Rn))]>;
3947
3948 // Half-precision to Double-precision
3949 def DHr : BaseFPConversion<0b11, 0b01, FPR64, FPR16, asm,
3950 [(set FPR64:$Rd, (fextend FPR16:$Rn))]>;
3951
3952 // Half-precision to Single-precision
3953 def SHr : BaseFPConversion<0b11, 0b00, FPR32, FPR16, asm,
3954 [(set FPR32:$Rd, (fextend FPR16:$Rn))]>;
3955
3956 // Single-precision to Double-precision
3957 def DSr : BaseFPConversion<0b00, 0b01, FPR64, FPR32, asm,
3958 [(set FPR64:$Rd, (fextend FPR32:$Rn))]>;
3959
3960 // Single-precision to Half-precision
3961 def HSr : BaseFPConversion<0b00, 0b11, FPR16, FPR32, asm,
3962 [(set FPR16:$Rd, (fround FPR32:$Rn))]>;
3963}
3964
3965//---
3966// Single operand floating point data processing
3967//---
3968
3969let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
3970class BaseSingleOperandFPData<bits<4> opcode, RegisterClass regtype,
3971 ValueType vt, string asm, SDPatternOperator node>
3972 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm, "\t$Rd, $Rn", "",
3973 [(set (vt regtype:$Rd), (node (vt regtype:$Rn)))]>,
3974 Sched<[WriteF]> {
3975 bits<5> Rd;
3976 bits<5> Rn;
Oliver Stannardb25914e2015-11-27 13:04:48 +00003977 let Inst{31-24} = 0b00011110;
Tim Northover3b0846e2014-05-24 12:50:23 +00003978 let Inst{21-19} = 0b100;
3979 let Inst{18-15} = opcode;
3980 let Inst{14-10} = 0b10000;
3981 let Inst{9-5} = Rn;
3982 let Inst{4-0} = Rd;
3983}
3984
3985multiclass SingleOperandFPData<bits<4> opcode, string asm,
3986 SDPatternOperator node = null_frag> {
Oliver Stannardb25914e2015-11-27 13:04:48 +00003987 def Hr : BaseSingleOperandFPData<opcode, FPR16, f16, asm, node> {
3988 let Inst{23-22} = 0b11; // 16-bit size flag
3989 let Predicates = [HasFullFP16];
3990 }
3991
Tim Northover3b0846e2014-05-24 12:50:23 +00003992 def Sr : BaseSingleOperandFPData<opcode, FPR32, f32, asm, node> {
Oliver Stannardb25914e2015-11-27 13:04:48 +00003993 let Inst{23-22} = 0b00; // 32-bit size flag
Tim Northover3b0846e2014-05-24 12:50:23 +00003994 }
3995
3996 def Dr : BaseSingleOperandFPData<opcode, FPR64, f64, asm, node> {
Oliver Stannardb25914e2015-11-27 13:04:48 +00003997 let Inst{23-22} = 0b01; // 64-bit size flag
Tim Northover3b0846e2014-05-24 12:50:23 +00003998 }
3999}
4000
4001//---
4002// Two operand floating point data processing
4003//---
4004
4005let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
4006class BaseTwoOperandFPData<bits<4> opcode, RegisterClass regtype,
4007 string asm, list<dag> pat>
4008 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm),
4009 asm, "\t$Rd, $Rn, $Rm", "", pat>,
4010 Sched<[WriteF]> {
4011 bits<5> Rd;
4012 bits<5> Rn;
4013 bits<5> Rm;
Oliver Stannardb25914e2015-11-27 13:04:48 +00004014 let Inst{31-24} = 0b00011110;
Tim Northover3b0846e2014-05-24 12:50:23 +00004015 let Inst{21} = 1;
4016 let Inst{20-16} = Rm;
4017 let Inst{15-12} = opcode;
4018 let Inst{11-10} = 0b10;
4019 let Inst{9-5} = Rn;
4020 let Inst{4-0} = Rd;
4021}
4022
4023multiclass TwoOperandFPData<bits<4> opcode, string asm,
4024 SDPatternOperator node = null_frag> {
Oliver Stannardb25914e2015-11-27 13:04:48 +00004025 def Hrr : BaseTwoOperandFPData<opcode, FPR16, asm,
4026 [(set (f16 FPR16:$Rd),
4027 (node (f16 FPR16:$Rn), (f16 FPR16:$Rm)))]> {
4028 let Inst{23-22} = 0b11; // 16-bit size flag
4029 let Predicates = [HasFullFP16];
4030 }
4031
Tim Northover3b0846e2014-05-24 12:50:23 +00004032 def Srr : BaseTwoOperandFPData<opcode, FPR32, asm,
4033 [(set (f32 FPR32:$Rd),
4034 (node (f32 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 (f64 FPR64:$Rd),
4040 (node (f64 FPR64:$Rn), (f64 FPR64:$Rm)))]> {
Oliver Stannardb25914e2015-11-27 13:04:48 +00004041 let Inst{23-22} = 0b01; // 64-bit size flag
Tim Northover3b0846e2014-05-24 12:50:23 +00004042 }
4043}
4044
4045multiclass TwoOperandFPDataNeg<bits<4> opcode, string asm, SDNode node> {
Oliver Stannardb25914e2015-11-27 13:04:48 +00004046 def Hrr : BaseTwoOperandFPData<opcode, FPR16, asm,
4047 [(set FPR16:$Rd, (fneg (node FPR16:$Rn, (f16 FPR16:$Rm))))]> {
4048 let Inst{23-22} = 0b11; // 16-bit size flag
4049 let Predicates = [HasFullFP16];
4050 }
4051
Tim Northover3b0846e2014-05-24 12:50:23 +00004052 def Srr : BaseTwoOperandFPData<opcode, FPR32, asm,
4053 [(set FPR32:$Rd, (fneg (node FPR32:$Rn, (f32 FPR32:$Rm))))]> {
Oliver Stannardb25914e2015-11-27 13:04:48 +00004054 let Inst{23-22} = 0b00; // 32-bit size flag
Tim Northover3b0846e2014-05-24 12:50:23 +00004055 }
4056
4057 def Drr : BaseTwoOperandFPData<opcode, FPR64, asm,
4058 [(set FPR64:$Rd, (fneg (node FPR64:$Rn, (f64 FPR64:$Rm))))]> {
Oliver Stannardb25914e2015-11-27 13:04:48 +00004059 let Inst{23-22} = 0b01; // 64-bit size flag
Tim Northover3b0846e2014-05-24 12:50:23 +00004060 }
4061}
4062
4063
4064//---
4065// Three operand floating point data processing
4066//---
4067
4068class BaseThreeOperandFPData<bit isNegated, bit isSub,
4069 RegisterClass regtype, string asm, list<dag> pat>
4070 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, regtype: $Ra),
4071 asm, "\t$Rd, $Rn, $Rm, $Ra", "", pat>,
4072 Sched<[WriteFMul]> {
4073 bits<5> Rd;
4074 bits<5> Rn;
4075 bits<5> Rm;
4076 bits<5> Ra;
Oliver Stannardb25914e2015-11-27 13:04:48 +00004077 let Inst{31-24} = 0b00011111;
Tim Northover3b0846e2014-05-24 12:50:23 +00004078 let Inst{21} = isNegated;
4079 let Inst{20-16} = Rm;
4080 let Inst{15} = isSub;
4081 let Inst{14-10} = Ra;
4082 let Inst{9-5} = Rn;
4083 let Inst{4-0} = Rd;
4084}
4085
4086multiclass ThreeOperandFPData<bit isNegated, bit isSub,string asm,
4087 SDPatternOperator node> {
Oliver Stannardb25914e2015-11-27 13:04:48 +00004088 def Hrrr : BaseThreeOperandFPData<isNegated, isSub, FPR16, asm,
4089 [(set FPR16:$Rd,
4090 (node (f16 FPR16:$Rn), (f16 FPR16:$Rm), (f16 FPR16:$Ra)))]> {
4091 let Inst{23-22} = 0b11; // 16-bit size flag
4092 let Predicates = [HasFullFP16];
4093 }
4094
Tim Northover3b0846e2014-05-24 12:50:23 +00004095 def Srrr : BaseThreeOperandFPData<isNegated, isSub, FPR32, asm,
4096 [(set FPR32:$Rd,
4097 (node (f32 FPR32:$Rn), (f32 FPR32:$Rm), (f32 FPR32:$Ra)))]> {
Oliver Stannardb25914e2015-11-27 13:04:48 +00004098 let Inst{23-22} = 0b00; // 32-bit size flag
Tim Northover3b0846e2014-05-24 12:50:23 +00004099 }
4100
4101 def Drrr : BaseThreeOperandFPData<isNegated, isSub, FPR64, asm,
4102 [(set FPR64:$Rd,
4103 (node (f64 FPR64:$Rn), (f64 FPR64:$Rm), (f64 FPR64:$Ra)))]> {
Oliver Stannardb25914e2015-11-27 13:04:48 +00004104 let Inst{23-22} = 0b01; // 64-bit size flag
Tim Northover3b0846e2014-05-24 12:50:23 +00004105 }
4106}
4107
4108//---
4109// Floating point data comparisons
4110//---
4111
4112let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
4113class BaseOneOperandFPComparison<bit signalAllNans,
4114 RegisterClass regtype, string asm,
4115 list<dag> pat>
4116 : I<(outs), (ins regtype:$Rn), asm, "\t$Rn, #0.0", "", pat>,
4117 Sched<[WriteFCmp]> {
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
4122 let Inst{15-10} = 0b001000;
4123 let Inst{9-5} = Rn;
4124 let Inst{4} = signalAllNans;
4125 let Inst{3-0} = 0b1000;
4126
4127 // Rm should be 0b00000 canonically, but we need to accept any value.
4128 let PostEncoderMethod = "fixOneOperandFPComparison";
4129}
4130
4131let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
4132class BaseTwoOperandFPComparison<bit signalAllNans, RegisterClass regtype,
4133 string asm, list<dag> pat>
4134 : I<(outs), (ins regtype:$Rn, regtype:$Rm), asm, "\t$Rn, $Rm", "", pat>,
4135 Sched<[WriteFCmp]> {
4136 bits<5> Rm;
4137 bits<5> Rn;
Oliver Stannardb25914e2015-11-27 13:04:48 +00004138 let Inst{31-24} = 0b00011110;
Tim Northover3b0846e2014-05-24 12:50:23 +00004139 let Inst{21} = 1;
4140 let Inst{20-16} = Rm;
4141 let Inst{15-10} = 0b001000;
4142 let Inst{9-5} = Rn;
4143 let Inst{4} = signalAllNans;
4144 let Inst{3-0} = 0b0000;
4145}
4146
4147multiclass FPComparison<bit signalAllNans, string asm,
4148 SDPatternOperator OpNode = null_frag> {
4149 let Defs = [NZCV] in {
Oliver Stannardb25914e2015-11-27 13:04:48 +00004150 def Hrr : BaseTwoOperandFPComparison<signalAllNans, FPR16, asm,
4151 [(OpNode FPR16:$Rn, (f16 FPR16:$Rm)), (implicit NZCV)]> {
4152 let Inst{23-22} = 0b11;
4153 let Predicates = [HasFullFP16];
4154 }
4155
4156 def Hri : BaseOneOperandFPComparison<signalAllNans, FPR16, asm,
4157 [(OpNode (f16 FPR16:$Rn), fpimm0), (implicit NZCV)]> {
4158 let Inst{23-22} = 0b11;
4159 let Predicates = [HasFullFP16];
4160 }
4161
Tim Northover3b0846e2014-05-24 12:50:23 +00004162 def Srr : BaseTwoOperandFPComparison<signalAllNans, FPR32, asm,
4163 [(OpNode FPR32:$Rn, (f32 FPR32:$Rm)), (implicit NZCV)]> {
Oliver Stannardb25914e2015-11-27 13:04:48 +00004164 let Inst{23-22} = 0b00;
Tim Northover3b0846e2014-05-24 12:50:23 +00004165 }
4166
4167 def Sri : BaseOneOperandFPComparison<signalAllNans, FPR32, asm,
4168 [(OpNode (f32 FPR32:$Rn), fpimm0), (implicit NZCV)]> {
Oliver Stannardb25914e2015-11-27 13:04:48 +00004169 let Inst{23-22} = 0b00;
Tim Northover3b0846e2014-05-24 12:50:23 +00004170 }
4171
4172 def Drr : BaseTwoOperandFPComparison<signalAllNans, FPR64, asm,
4173 [(OpNode FPR64:$Rn, (f64 FPR64:$Rm)), (implicit NZCV)]> {
Oliver Stannardb25914e2015-11-27 13:04:48 +00004174 let Inst{23-22} = 0b01;
Tim Northover3b0846e2014-05-24 12:50:23 +00004175 }
4176
4177 def Dri : BaseOneOperandFPComparison<signalAllNans, FPR64, asm,
4178 [(OpNode (f64 FPR64:$Rn), fpimm0), (implicit NZCV)]> {
Oliver Stannardb25914e2015-11-27 13:04:48 +00004179 let Inst{23-22} = 0b01;
Tim Northover3b0846e2014-05-24 12:50:23 +00004180 }
4181 } // Defs = [NZCV]
4182}
4183
4184//---
4185// Floating point conditional comparisons
4186//---
4187
4188let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
Matthias Braunaf7d7702015-07-16 20:02:37 +00004189class BaseFPCondComparison<bit signalAllNans, RegisterClass regtype,
4190 string mnemonic, list<dag> pat>
4191 : I<(outs), (ins regtype:$Rn, regtype:$Rm, imm32_0_15:$nzcv, ccode:$cond),
4192 mnemonic, "\t$Rn, $Rm, $nzcv, $cond", "", pat>,
Tim Northover3b0846e2014-05-24 12:50:23 +00004193 Sched<[WriteFCmp]> {
Matthias Braunaf7d7702015-07-16 20:02:37 +00004194 let Uses = [NZCV];
4195 let Defs = [NZCV];
4196
Tim Northover3b0846e2014-05-24 12:50:23 +00004197 bits<5> Rn;
4198 bits<5> Rm;
4199 bits<4> nzcv;
4200 bits<4> cond;
4201
Oliver Stannardb25914e2015-11-27 13:04:48 +00004202 let Inst{31-24} = 0b00011110;
Tim Northover3b0846e2014-05-24 12:50:23 +00004203 let Inst{21} = 1;
4204 let Inst{20-16} = Rm;
4205 let Inst{15-12} = cond;
4206 let Inst{11-10} = 0b01;
4207 let Inst{9-5} = Rn;
4208 let Inst{4} = signalAllNans;
4209 let Inst{3-0} = nzcv;
4210}
4211
Matthias Braunaf7d7702015-07-16 20:02:37 +00004212multiclass FPCondComparison<bit signalAllNans, string mnemonic,
4213 SDPatternOperator OpNode = null_frag> {
Oliver Stannardb25914e2015-11-27 13:04:48 +00004214 def Hrr : BaseFPCondComparison<signalAllNans, FPR16, mnemonic, []> {
4215 let Inst{23-22} = 0b11;
4216 let Predicates = [HasFullFP16];
4217 }
4218
Matthias Braunaf7d7702015-07-16 20:02:37 +00004219 def Srr : BaseFPCondComparison<signalAllNans, FPR32, mnemonic,
4220 [(set NZCV, (OpNode (f32 FPR32:$Rn), (f32 FPR32:$Rm), (i32 imm:$nzcv),
4221 (i32 imm:$cond), NZCV))]> {
Oliver Stannardb25914e2015-11-27 13:04:48 +00004222 let Inst{23-22} = 0b00;
Tim Northover3b0846e2014-05-24 12:50:23 +00004223 }
Oliver Stannardb25914e2015-11-27 13:04:48 +00004224
Matthias Braunaf7d7702015-07-16 20:02:37 +00004225 def Drr : BaseFPCondComparison<signalAllNans, FPR64, mnemonic,
4226 [(set NZCV, (OpNode (f64 FPR64:$Rn), (f64 FPR64:$Rm), (i32 imm:$nzcv),
4227 (i32 imm:$cond), NZCV))]> {
Oliver Stannardb25914e2015-11-27 13:04:48 +00004228 let Inst{23-22} = 0b01;
Tim Northover3b0846e2014-05-24 12:50:23 +00004229 }
Tim Northover3b0846e2014-05-24 12:50:23 +00004230}
4231
4232//---
4233// Floating point conditional select
4234//---
4235
4236class BaseFPCondSelect<RegisterClass regtype, ValueType vt, string asm>
4237 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, ccode:$cond),
4238 asm, "\t$Rd, $Rn, $Rm, $cond", "",
4239 [(set regtype:$Rd,
4240 (AArch64csel (vt regtype:$Rn), regtype:$Rm,
4241 (i32 imm:$cond), NZCV))]>,
4242 Sched<[WriteF]> {
4243 bits<5> Rd;
4244 bits<5> Rn;
4245 bits<5> Rm;
4246 bits<4> cond;
4247
Oliver Stannardb25914e2015-11-27 13:04:48 +00004248 let Inst{31-24} = 0b00011110;
Tim Northover3b0846e2014-05-24 12:50:23 +00004249 let Inst{21} = 1;
4250 let Inst{20-16} = Rm;
4251 let Inst{15-12} = cond;
4252 let Inst{11-10} = 0b11;
4253 let Inst{9-5} = Rn;
4254 let Inst{4-0} = Rd;
4255}
4256
4257multiclass FPCondSelect<string asm> {
4258 let Uses = [NZCV] in {
Oliver Stannardb25914e2015-11-27 13:04:48 +00004259 def Hrrr : BaseFPCondSelect<FPR16, f16, asm> {
4260 let Inst{23-22} = 0b11;
4261 let Predicates = [HasFullFP16];
4262 }
4263
Tim Northover3b0846e2014-05-24 12:50:23 +00004264 def Srrr : BaseFPCondSelect<FPR32, f32, asm> {
Oliver Stannardb25914e2015-11-27 13:04:48 +00004265 let Inst{23-22} = 0b00;
Tim Northover3b0846e2014-05-24 12:50:23 +00004266 }
4267
4268 def Drrr : BaseFPCondSelect<FPR64, f64, asm> {
Oliver Stannardb25914e2015-11-27 13:04:48 +00004269 let Inst{23-22} = 0b01;
Tim Northover3b0846e2014-05-24 12:50:23 +00004270 }
4271 } // Uses = [NZCV]
4272}
4273
4274//---
4275// Floating move immediate
4276//---
4277
4278class BaseFPMoveImmediate<RegisterClass regtype, Operand fpimmtype, string asm>
4279 : I<(outs regtype:$Rd), (ins fpimmtype:$imm), asm, "\t$Rd, $imm", "",
4280 [(set regtype:$Rd, fpimmtype:$imm)]>,
4281 Sched<[WriteFImm]> {
4282 bits<5> Rd;
4283 bits<8> imm;
Oliver Stannardb25914e2015-11-27 13:04:48 +00004284 let Inst{31-24} = 0b00011110;
Tim Northover3b0846e2014-05-24 12:50:23 +00004285 let Inst{21} = 1;
4286 let Inst{20-13} = imm;
4287 let Inst{12-5} = 0b10000000;
4288 let Inst{4-0} = Rd;
4289}
4290
4291multiclass FPMoveImmediate<string asm> {
Oliver Stannardb25914e2015-11-27 13:04:48 +00004292 def Hi : BaseFPMoveImmediate<FPR16, fpimm16, asm> {
4293 let Inst{23-22} = 0b11;
4294 let Predicates = [HasFullFP16];
4295 }
4296
Tim Northover3b0846e2014-05-24 12:50:23 +00004297 def Si : BaseFPMoveImmediate<FPR32, fpimm32, asm> {
Oliver Stannardb25914e2015-11-27 13:04:48 +00004298 let Inst{23-22} = 0b00;
Tim Northover3b0846e2014-05-24 12:50:23 +00004299 }
4300
4301 def Di : BaseFPMoveImmediate<FPR64, fpimm64, asm> {
Oliver Stannardb25914e2015-11-27 13:04:48 +00004302 let Inst{23-22} = 0b01;
Tim Northover3b0846e2014-05-24 12:50:23 +00004303 }
4304}
4305} // end of 'let Predicates = [HasFPARMv8]'
4306
4307//----------------------------------------------------------------------------
4308// AdvSIMD
4309//----------------------------------------------------------------------------
4310
4311let Predicates = [HasNEON] in {
4312
4313//----------------------------------------------------------------------------
4314// AdvSIMD three register vector instructions
4315//----------------------------------------------------------------------------
4316
4317let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
Oliver Stannarde4c3d212015-12-08 12:16:10 +00004318class BaseSIMDThreeSameVector<bit Q, bit U, bits<3> size, bits<5> opcode,
Tim Northover3b0846e2014-05-24 12:50:23 +00004319 RegisterOperand regtype, string asm, string kind,
4320 list<dag> pattern>
4321 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), asm,
4322 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind #
4323 "|" # kind # "\t$Rd, $Rn, $Rm|}", "", pattern>,
4324 Sched<[WriteV]> {
4325 bits<5> Rd;
4326 bits<5> Rn;
4327 bits<5> Rm;
4328 let Inst{31} = 0;
4329 let Inst{30} = Q;
4330 let Inst{29} = U;
4331 let Inst{28-24} = 0b01110;
Oliver Stannarde4c3d212015-12-08 12:16:10 +00004332 let Inst{23-21} = size;
Tim Northover3b0846e2014-05-24 12:50:23 +00004333 let Inst{20-16} = Rm;
4334 let Inst{15-11} = opcode;
4335 let Inst{10} = 1;
4336 let Inst{9-5} = Rn;
4337 let Inst{4-0} = Rd;
4338}
4339
4340let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
Oliver Stannarde4c3d212015-12-08 12:16:10 +00004341class BaseSIMDThreeSameVectorTied<bit Q, bit U, bits<3> size, bits<5> opcode,
Tim Northover3b0846e2014-05-24 12:50:23 +00004342 RegisterOperand regtype, string asm, string kind,
4343 list<dag> pattern>
4344 : I<(outs regtype:$dst), (ins regtype:$Rd, regtype:$Rn, regtype:$Rm), asm,
4345 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind #
4346 "|" # kind # "\t$Rd, $Rn, $Rm}", "$Rd = $dst", pattern>,
4347 Sched<[WriteV]> {
4348 bits<5> Rd;
4349 bits<5> Rn;
4350 bits<5> Rm;
4351 let Inst{31} = 0;
4352 let Inst{30} = Q;
4353 let Inst{29} = U;
4354 let Inst{28-24} = 0b01110;
Oliver Stannarde4c3d212015-12-08 12:16:10 +00004355 let Inst{23-21} = size;
Tim Northover3b0846e2014-05-24 12:50:23 +00004356 let Inst{20-16} = Rm;
4357 let Inst{15-11} = opcode;
4358 let Inst{10} = 1;
4359 let Inst{9-5} = Rn;
4360 let Inst{4-0} = Rd;
4361}
4362
4363// All operand sizes distinguished in the encoding.
4364multiclass SIMDThreeSameVector<bit U, bits<5> opc, string asm,
4365 SDPatternOperator OpNode> {
Oliver Stannarde4c3d212015-12-08 12:16:10 +00004366 def v8i8 : BaseSIMDThreeSameVector<0, U, 0b001, opc, V64,
Tim Northover3b0846e2014-05-24 12:50:23 +00004367 asm, ".8b",
4368 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
Oliver Stannarde4c3d212015-12-08 12:16:10 +00004369 def v16i8 : BaseSIMDThreeSameVector<1, U, 0b001, opc, V128,
Tim Northover3b0846e2014-05-24 12:50:23 +00004370 asm, ".16b",
4371 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn), (v16i8 V128:$Rm)))]>;
Oliver Stannarde4c3d212015-12-08 12:16:10 +00004372 def v4i16 : BaseSIMDThreeSameVector<0, U, 0b011, opc, V64,
Tim Northover3b0846e2014-05-24 12:50:23 +00004373 asm, ".4h",
4374 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>;
Oliver Stannarde4c3d212015-12-08 12:16:10 +00004375 def v8i16 : BaseSIMDThreeSameVector<1, U, 0b011, opc, V128,
Tim Northover3b0846e2014-05-24 12:50:23 +00004376 asm, ".8h",
4377 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>;
Oliver Stannarde4c3d212015-12-08 12:16:10 +00004378 def v2i32 : BaseSIMDThreeSameVector<0, U, 0b101, opc, V64,
Tim Northover3b0846e2014-05-24 12:50:23 +00004379 asm, ".2s",
4380 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>;
Oliver Stannarde4c3d212015-12-08 12:16:10 +00004381 def v4i32 : BaseSIMDThreeSameVector<1, U, 0b101, opc, V128,
Tim Northover3b0846e2014-05-24 12:50:23 +00004382 asm, ".4s",
4383 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>;
Oliver Stannarde4c3d212015-12-08 12:16:10 +00004384 def v2i64 : BaseSIMDThreeSameVector<1, U, 0b111, opc, V128,
Tim Northover3b0846e2014-05-24 12:50:23 +00004385 asm, ".2d",
4386 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn), (v2i64 V128:$Rm)))]>;
4387}
4388
4389// As above, but D sized elements unsupported.
4390multiclass SIMDThreeSameVectorBHS<bit U, bits<5> opc, string asm,
4391 SDPatternOperator OpNode> {
Oliver Stannarde4c3d212015-12-08 12:16:10 +00004392 def v8i8 : BaseSIMDThreeSameVector<0, U, 0b001, opc, V64,
Tim Northover3b0846e2014-05-24 12:50:23 +00004393 asm, ".8b",
4394 [(set V64:$Rd, (v8i8 (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm))))]>;
Oliver Stannarde4c3d212015-12-08 12:16:10 +00004395 def v16i8 : BaseSIMDThreeSameVector<1, U, 0b001, opc, V128,
Tim Northover3b0846e2014-05-24 12:50:23 +00004396 asm, ".16b",
4397 [(set V128:$Rd, (v16i8 (OpNode (v16i8 V128:$Rn), (v16i8 V128:$Rm))))]>;
Oliver Stannarde4c3d212015-12-08 12:16:10 +00004398 def v4i16 : BaseSIMDThreeSameVector<0, U, 0b011, opc, V64,
Tim Northover3b0846e2014-05-24 12:50:23 +00004399 asm, ".4h",
4400 [(set V64:$Rd, (v4i16 (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm))))]>;
Oliver Stannarde4c3d212015-12-08 12:16:10 +00004401 def v8i16 : BaseSIMDThreeSameVector<1, U, 0b011, opc, V128,
Tim Northover3b0846e2014-05-24 12:50:23 +00004402 asm, ".8h",
4403 [(set V128:$Rd, (v8i16 (OpNode (v8i16 V128:$Rn), (v8i16 V128:$Rm))))]>;
Oliver Stannarde4c3d212015-12-08 12:16:10 +00004404 def v2i32 : BaseSIMDThreeSameVector<0, U, 0b101, opc, V64,
Tim Northover3b0846e2014-05-24 12:50:23 +00004405 asm, ".2s",
4406 [(set V64:$Rd, (v2i32 (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm))))]>;
Oliver Stannarde4c3d212015-12-08 12:16:10 +00004407 def v4i32 : BaseSIMDThreeSameVector<1, U, 0b101, opc, V128,
Tim Northover3b0846e2014-05-24 12:50:23 +00004408 asm, ".4s",
4409 [(set V128:$Rd, (v4i32 (OpNode (v4i32 V128:$Rn), (v4i32 V128:$Rm))))]>;
4410}
4411
4412multiclass SIMDThreeSameVectorBHSTied<bit U, bits<5> opc, string asm,
4413 SDPatternOperator OpNode> {
Oliver Stannarde4c3d212015-12-08 12:16:10 +00004414 def v8i8 : BaseSIMDThreeSameVectorTied<0, U, 0b001, opc, V64,
Tim Northover3b0846e2014-05-24 12:50:23 +00004415 asm, ".8b",
4416 [(set (v8i8 V64:$dst),
4417 (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
Oliver Stannarde4c3d212015-12-08 12:16:10 +00004418 def v16i8 : BaseSIMDThreeSameVectorTied<1, U, 0b001, opc, V128,
Tim Northover3b0846e2014-05-24 12:50:23 +00004419 asm, ".16b",
4420 [(set (v16i8 V128:$dst),
4421 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn), (v16i8 V128:$Rm)))]>;
Oliver Stannarde4c3d212015-12-08 12:16:10 +00004422 def v4i16 : BaseSIMDThreeSameVectorTied<0, U, 0b011, opc, V64,
Tim Northover3b0846e2014-05-24 12:50:23 +00004423 asm, ".4h",
4424 [(set (v4i16 V64:$dst),
4425 (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>;
Oliver Stannarde4c3d212015-12-08 12:16:10 +00004426 def v8i16 : BaseSIMDThreeSameVectorTied<1, U, 0b011, opc, V128,
Tim Northover3b0846e2014-05-24 12:50:23 +00004427 asm, ".8h",
4428 [(set (v8i16 V128:$dst),
4429 (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>;
Oliver Stannarde4c3d212015-12-08 12:16:10 +00004430 def v2i32 : BaseSIMDThreeSameVectorTied<0, U, 0b101, opc, V64,
Tim Northover3b0846e2014-05-24 12:50:23 +00004431 asm, ".2s",
4432 [(set (v2i32 V64:$dst),
4433 (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>;
Oliver Stannarde4c3d212015-12-08 12:16:10 +00004434 def v4i32 : BaseSIMDThreeSameVectorTied<1, U, 0b101, opc, V128,
Tim Northover3b0846e2014-05-24 12:50:23 +00004435 asm, ".4s",
4436 [(set (v4i32 V128:$dst),
4437 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>;
4438}
4439
4440// As above, but only B sized elements supported.
4441multiclass SIMDThreeSameVectorB<bit U, bits<5> opc, string asm,
4442 SDPatternOperator OpNode> {
Oliver Stannarde4c3d212015-12-08 12:16:10 +00004443 def v8i8 : BaseSIMDThreeSameVector<0, U, 0b001, opc, V64,
Tim Northover3b0846e2014-05-24 12:50:23 +00004444 asm, ".8b",
4445 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
Oliver Stannarde4c3d212015-12-08 12:16:10 +00004446 def v16i8 : BaseSIMDThreeSameVector<1, U, 0b001, opc, V128,
Tim Northover3b0846e2014-05-24 12:50:23 +00004447 asm, ".16b",
4448 [(set (v16i8 V128:$Rd),
4449 (OpNode (v16i8 V128:$Rn), (v16i8 V128:$Rm)))]>;
4450}
4451
Oliver Stannarde4c3d212015-12-08 12:16:10 +00004452// As above, but only floating point elements supported.
4453multiclass SIMDThreeSameVectorFP<bit U, bit S, bits<3> opc,
Tim Northover3b0846e2014-05-24 12:50:23 +00004454 string asm, SDPatternOperator OpNode> {
Oliver Stannarde4c3d212015-12-08 12:16:10 +00004455 let Predicates = [HasNEON, HasFullFP16] in {
4456 def v4f16 : BaseSIMDThreeSameVector<0, U, {S,0b10}, {0b00,opc}, V64,
4457 asm, ".4h",
4458 [(set (v4f16 V64:$Rd), (OpNode (v4f16 V64:$Rn), (v4f16 V64:$Rm)))]>;
4459 def v8f16 : BaseSIMDThreeSameVector<1, U, {S,0b10}, {0b00,opc}, V128,
4460 asm, ".8h",
4461 [(set (v8f16 V128:$Rd), (OpNode (v8f16 V128:$Rn), (v8f16 V128:$Rm)))]>;
4462 } // Predicates = [HasNEON, HasFullFP16]
4463 def v2f32 : BaseSIMDThreeSameVector<0, U, {S,0b01}, {0b11,opc}, V64,
Tim Northover3b0846e2014-05-24 12:50:23 +00004464 asm, ".2s",
4465 [(set (v2f32 V64:$Rd), (OpNode (v2f32 V64:$Rn), (v2f32 V64:$Rm)))]>;
Oliver Stannarde4c3d212015-12-08 12:16:10 +00004466 def v4f32 : BaseSIMDThreeSameVector<1, U, {S,0b01}, {0b11,opc}, V128,
Tim Northover3b0846e2014-05-24 12:50:23 +00004467 asm, ".4s",
4468 [(set (v4f32 V128:$Rd), (OpNode (v4f32 V128:$Rn), (v4f32 V128:$Rm)))]>;
Oliver Stannarde4c3d212015-12-08 12:16:10 +00004469 def v2f64 : BaseSIMDThreeSameVector<1, U, {S,0b11}, {0b11,opc}, V128,
Tim Northover3b0846e2014-05-24 12:50:23 +00004470 asm, ".2d",
4471 [(set (v2f64 V128:$Rd), (OpNode (v2f64 V128:$Rn), (v2f64 V128:$Rm)))]>;
4472}
4473
Oliver Stannarde4c3d212015-12-08 12:16:10 +00004474multiclass SIMDThreeSameVectorFPCmp<bit U, bit S, bits<3> opc,
Tim Northover3b0846e2014-05-24 12:50:23 +00004475 string asm,
4476 SDPatternOperator OpNode> {
Oliver Stannarde4c3d212015-12-08 12:16:10 +00004477 let Predicates = [HasNEON, HasFullFP16] in {
4478 def v4f16 : BaseSIMDThreeSameVector<0, U, {S,0b10}, {0b00,opc}, V64,
4479 asm, ".4h",
4480 [(set (v4i16 V64:$Rd), (OpNode (v4f16 V64:$Rn), (v4f16 V64:$Rm)))]>;
4481 def v8f16 : BaseSIMDThreeSameVector<1, U, {S,0b10}, {0b00,opc}, V128,
4482 asm, ".8h",
4483 [(set (v8i16 V128:$Rd), (OpNode (v8f16 V128:$Rn), (v8f16 V128:$Rm)))]>;
4484 } // Predicates = [HasNEON, HasFullFP16]
4485 def v2f32 : BaseSIMDThreeSameVector<0, U, {S,0b01}, {0b11,opc}, V64,
Tim Northover3b0846e2014-05-24 12:50:23 +00004486 asm, ".2s",
4487 [(set (v2i32 V64:$Rd), (OpNode (v2f32 V64:$Rn), (v2f32 V64:$Rm)))]>;
Oliver Stannarde4c3d212015-12-08 12:16:10 +00004488 def v4f32 : BaseSIMDThreeSameVector<1, U, {S,0b01}, {0b11,opc}, V128,
Tim Northover3b0846e2014-05-24 12:50:23 +00004489 asm, ".4s",
4490 [(set (v4i32 V128:$Rd), (OpNode (v4f32 V128:$Rn), (v4f32 V128:$Rm)))]>;
Oliver Stannarde4c3d212015-12-08 12:16:10 +00004491 def v2f64 : BaseSIMDThreeSameVector<1, U, {S,0b11}, {0b11,opc}, V128,
Tim Northover3b0846e2014-05-24 12:50:23 +00004492 asm, ".2d",
4493 [(set (v2i64 V128:$Rd), (OpNode (v2f64 V128:$Rn), (v2f64 V128:$Rm)))]>;
4494}
4495
Oliver Stannarde4c3d212015-12-08 12:16:10 +00004496multiclass SIMDThreeSameVectorFPTied<bit U, bit S, bits<3> opc,
Tim Northover3b0846e2014-05-24 12:50:23 +00004497 string asm, SDPatternOperator OpNode> {
Oliver Stannarde4c3d212015-12-08 12:16:10 +00004498 let Predicates = [HasNEON, HasFullFP16] in {
4499 def v4f16 : BaseSIMDThreeSameVectorTied<0, U, {S,0b10}, {0b00,opc}, V64,
4500 asm, ".4h",
4501 [(set (v4f16 V64:$dst),
4502 (OpNode (v4f16 V64:$Rd), (v4f16 V64:$Rn), (v4f16 V64:$Rm)))]>;
4503 def v8f16 : BaseSIMDThreeSameVectorTied<1, U, {S,0b10}, {0b00,opc}, V128,
4504 asm, ".8h",
4505 [(set (v8f16 V128:$dst),
4506 (OpNode (v8f16 V128:$Rd), (v8f16 V128:$Rn), (v8f16 V128:$Rm)))]>;
4507 } // Predicates = [HasNEON, HasFullFP16]
4508 def v2f32 : BaseSIMDThreeSameVectorTied<0, U, {S,0b01}, {0b11,opc}, V64,
Tim Northover3b0846e2014-05-24 12:50:23 +00004509 asm, ".2s",
4510 [(set (v2f32 V64:$dst),
4511 (OpNode (v2f32 V64:$Rd), (v2f32 V64:$Rn), (v2f32 V64:$Rm)))]>;
Oliver Stannarde4c3d212015-12-08 12:16:10 +00004512 def v4f32 : BaseSIMDThreeSameVectorTied<1, U, {S,0b01}, {0b11,opc}, V128,
Tim Northover3b0846e2014-05-24 12:50:23 +00004513 asm, ".4s",
4514 [(set (v4f32 V128:$dst),
4515 (OpNode (v4f32 V128:$Rd), (v4f32 V128:$Rn), (v4f32 V128:$Rm)))]>;
Oliver Stannarde4c3d212015-12-08 12:16:10 +00004516 def v2f64 : BaseSIMDThreeSameVectorTied<1, U, {S,0b11}, {0b11,opc}, V128,
Tim Northover3b0846e2014-05-24 12:50:23 +00004517 asm, ".2d",
4518 [(set (v2f64 V128:$dst),
4519 (OpNode (v2f64 V128:$Rd), (v2f64 V128:$Rn), (v2f64 V128:$Rm)))]>;
4520}
4521
4522// As above, but D and B sized elements unsupported.
4523multiclass SIMDThreeSameVectorHS<bit U, bits<5> opc, string asm,
4524 SDPatternOperator OpNode> {
Oliver Stannarde4c3d212015-12-08 12:16:10 +00004525 def v4i16 : BaseSIMDThreeSameVector<0, U, 0b011, opc, V64,
Tim Northover3b0846e2014-05-24 12:50:23 +00004526 asm, ".4h",
4527 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>;
Oliver Stannarde4c3d212015-12-08 12:16:10 +00004528 def v8i16 : BaseSIMDThreeSameVector<1, U, 0b011, opc, V128,
Tim Northover3b0846e2014-05-24 12:50:23 +00004529 asm, ".8h",
4530 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>;
Oliver Stannarde4c3d212015-12-08 12:16:10 +00004531 def v2i32 : BaseSIMDThreeSameVector<0, U, 0b101, opc, V64,
Tim Northover3b0846e2014-05-24 12:50:23 +00004532 asm, ".2s",
4533 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>;
Oliver Stannarde4c3d212015-12-08 12:16:10 +00004534 def v4i32 : BaseSIMDThreeSameVector<1, U, 0b101, opc, V128,
Tim Northover3b0846e2014-05-24 12:50:23 +00004535 asm, ".4s",
4536 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>;
4537}
4538
4539// Logical three vector ops share opcode bits, and only use B sized elements.
4540multiclass SIMDLogicalThreeVector<bit U, bits<2> size, string asm,
4541 SDPatternOperator OpNode = null_frag> {
Oliver Stannarde4c3d212015-12-08 12:16:10 +00004542 def v8i8 : BaseSIMDThreeSameVector<0, U, {size,1}, 0b00011, V64,
Tim Northover3b0846e2014-05-24 12:50:23 +00004543 asm, ".8b",
4544 [(set (v8i8 V64:$Rd), (OpNode V64:$Rn, V64:$Rm))]>;
Oliver Stannarde4c3d212015-12-08 12:16:10 +00004545 def v16i8 : BaseSIMDThreeSameVector<1, U, {size,1}, 0b00011, V128,
Tim Northover3b0846e2014-05-24 12:50:23 +00004546 asm, ".16b",
4547 [(set (v16i8 V128:$Rd), (OpNode V128:$Rn, V128:$Rm))]>;
4548
4549 def : Pat<(v4i16 (OpNode V64:$LHS, V64:$RHS)),
4550 (!cast<Instruction>(NAME#"v8i8") V64:$LHS, V64:$RHS)>;
4551 def : Pat<(v2i32 (OpNode V64:$LHS, V64:$RHS)),
4552 (!cast<Instruction>(NAME#"v8i8") V64:$LHS, V64:$RHS)>;
4553 def : Pat<(v1i64 (OpNode V64:$LHS, V64:$RHS)),
4554 (!cast<Instruction>(NAME#"v8i8") V64:$LHS, V64:$RHS)>;
4555
4556 def : Pat<(v8i16 (OpNode V128:$LHS, V128:$RHS)),
4557 (!cast<Instruction>(NAME#"v16i8") V128:$LHS, V128:$RHS)>;
4558 def : Pat<(v4i32 (OpNode V128:$LHS, V128:$RHS)),
4559 (!cast<Instruction>(NAME#"v16i8") V128:$LHS, V128:$RHS)>;
4560 def : Pat<(v2i64 (OpNode V128:$LHS, V128:$RHS)),
4561 (!cast<Instruction>(NAME#"v16i8") V128:$LHS, V128:$RHS)>;
4562}
4563
4564multiclass SIMDLogicalThreeVectorTied<bit U, bits<2> size,
4565 string asm, SDPatternOperator OpNode> {
Oliver Stannarde4c3d212015-12-08 12:16:10 +00004566 def v8i8 : BaseSIMDThreeSameVectorTied<0, U, {size,1}, 0b00011, V64,
Tim Northover3b0846e2014-05-24 12:50:23 +00004567 asm, ".8b",
4568 [(set (v8i8 V64:$dst),
4569 (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
Oliver Stannarde4c3d212015-12-08 12:16:10 +00004570 def v16i8 : BaseSIMDThreeSameVectorTied<1, U, {size,1}, 0b00011, V128,
Tim Northover3b0846e2014-05-24 12:50:23 +00004571 asm, ".16b",
4572 [(set (v16i8 V128:$dst),
4573 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn),
4574 (v16i8 V128:$Rm)))]>;
4575
4576 def : Pat<(v4i16 (OpNode (v4i16 V64:$LHS), (v4i16 V64:$MHS),
4577 (v4i16 V64:$RHS))),
4578 (!cast<Instruction>(NAME#"v8i8")
4579 V64:$LHS, V64:$MHS, V64:$RHS)>;
4580 def : Pat<(v2i32 (OpNode (v2i32 V64:$LHS), (v2i32 V64:$MHS),
4581 (v2i32 V64:$RHS))),
4582 (!cast<Instruction>(NAME#"v8i8")
4583 V64:$LHS, V64:$MHS, V64:$RHS)>;
4584 def : Pat<(v1i64 (OpNode (v1i64 V64:$LHS), (v1i64 V64:$MHS),
4585 (v1i64 V64:$RHS))),
4586 (!cast<Instruction>(NAME#"v8i8")
4587 V64:$LHS, V64:$MHS, V64:$RHS)>;
4588
4589 def : Pat<(v8i16 (OpNode (v8i16 V128:$LHS), (v8i16 V128:$MHS),
4590 (v8i16 V128:$RHS))),
4591 (!cast<Instruction>(NAME#"v16i8")
4592 V128:$LHS, V128:$MHS, V128:$RHS)>;
4593 def : Pat<(v4i32 (OpNode (v4i32 V128:$LHS), (v4i32 V128:$MHS),
4594 (v4i32 V128:$RHS))),
4595 (!cast<Instruction>(NAME#"v16i8")
4596 V128:$LHS, V128:$MHS, V128:$RHS)>;
4597 def : Pat<(v2i64 (OpNode (v2i64 V128:$LHS), (v2i64 V128:$MHS),
4598 (v2i64 V128:$RHS))),
4599 (!cast<Instruction>(NAME#"v16i8")
4600 V128:$LHS, V128:$MHS, V128:$RHS)>;
4601}
4602
4603
4604//----------------------------------------------------------------------------
4605// AdvSIMD two register vector instructions.
4606//----------------------------------------------------------------------------
4607
4608let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
4609class BaseSIMDTwoSameVector<bit Q, bit U, bits<2> size, bits<5> opcode,
Oliver Stannarde4c3d212015-12-08 12:16:10 +00004610 bits<2> size2, RegisterOperand regtype, string asm,
4611 string dstkind, string srckind, list<dag> pattern>
Tim Northover3b0846e2014-05-24 12:50:23 +00004612 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm,
4613 "{\t$Rd" # dstkind # ", $Rn" # srckind #
4614 "|" # dstkind # "\t$Rd, $Rn}", "", pattern>,
4615 Sched<[WriteV]> {
4616 bits<5> Rd;
4617 bits<5> Rn;
4618 let Inst{31} = 0;
4619 let Inst{30} = Q;
4620 let Inst{29} = U;
4621 let Inst{28-24} = 0b01110;
4622 let Inst{23-22} = size;
Oliver Stannarde4c3d212015-12-08 12:16:10 +00004623 let Inst{21} = 0b1;
4624 let Inst{20-19} = size2;
4625 let Inst{18-17} = 0b00;
Tim Northover3b0846e2014-05-24 12:50:23 +00004626 let Inst{16-12} = opcode;
4627 let Inst{11-10} = 0b10;
4628 let Inst{9-5} = Rn;
4629 let Inst{4-0} = Rd;
4630}
4631
4632let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
4633class BaseSIMDTwoSameVectorTied<bit Q, bit U, bits<2> size, bits<5> opcode,
Oliver Stannarde4c3d212015-12-08 12:16:10 +00004634 bits<2> size2, RegisterOperand regtype,
4635 string asm, string dstkind, string srckind,
4636 list<dag> pattern>
Tim Northover3b0846e2014-05-24 12:50:23 +00004637 : I<(outs regtype:$dst), (ins regtype:$Rd, regtype:$Rn), asm,
4638 "{\t$Rd" # dstkind # ", $Rn" # srckind #
4639 "|" # dstkind # "\t$Rd, $Rn}", "$Rd = $dst", pattern>,
4640 Sched<[WriteV]> {
4641 bits<5> Rd;
4642 bits<5> Rn;
4643 let Inst{31} = 0;
4644 let Inst{30} = Q;
4645 let Inst{29} = U;
4646 let Inst{28-24} = 0b01110;
4647 let Inst{23-22} = size;
Oliver Stannarde4c3d212015-12-08 12:16:10 +00004648 let Inst{21} = 0b1;
4649 let Inst{20-19} = size2;
4650 let Inst{18-17} = 0b00;
Tim Northover3b0846e2014-05-24 12:50:23 +00004651 let Inst{16-12} = opcode;
4652 let Inst{11-10} = 0b10;
4653 let Inst{9-5} = Rn;
4654 let Inst{4-0} = Rd;
4655}
4656
4657// Supports B, H, and S element sizes.
4658multiclass SIMDTwoVectorBHS<bit U, bits<5> opc, string asm,
4659 SDPatternOperator OpNode> {
Oliver Stannarde4c3d212015-12-08 12:16:10 +00004660 def v8i8 : BaseSIMDTwoSameVector<0, U, 0b00, opc, 0b00, V64,
Tim Northover3b0846e2014-05-24 12:50:23 +00004661 asm, ".8b", ".8b",
4662 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>;
Oliver Stannarde4c3d212015-12-08 12:16:10 +00004663 def v16i8 : BaseSIMDTwoSameVector<1, U, 0b00, opc, 0b00, V128,
Tim Northover3b0846e2014-05-24 12:50:23 +00004664 asm, ".16b", ".16b",
4665 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>;
Oliver Stannarde4c3d212015-12-08 12:16:10 +00004666 def v4i16 : BaseSIMDTwoSameVector<0, U, 0b01, opc, 0b00, V64,
Tim Northover3b0846e2014-05-24 12:50:23 +00004667 asm, ".4h", ".4h",
4668 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>;
Oliver Stannarde4c3d212015-12-08 12:16:10 +00004669 def v8i16 : BaseSIMDTwoSameVector<1, U, 0b01, opc, 0b00, V128,
Tim Northover3b0846e2014-05-24 12:50:23 +00004670 asm, ".8h", ".8h",
4671 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>;
Oliver Stannarde4c3d212015-12-08 12:16:10 +00004672 def v2i32 : BaseSIMDTwoSameVector<0, U, 0b10, opc, 0b00, V64,
Tim Northover3b0846e2014-05-24 12:50:23 +00004673 asm, ".2s", ".2s",
4674 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>;
Oliver Stannarde4c3d212015-12-08 12:16:10 +00004675 def v4i32 : BaseSIMDTwoSameVector<1, U, 0b10, opc, 0b00, V128,
Tim Northover3b0846e2014-05-24 12:50:23 +00004676 asm, ".4s", ".4s",
4677 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>;
4678}
4679
4680class BaseSIMDVectorLShiftLongBySize<bit Q, bits<2> size,
4681 RegisterOperand regtype, string asm, string dstkind,
4682 string srckind, string amount>
4683 : I<(outs V128:$Rd), (ins regtype:$Rn), asm,
4684 "{\t$Rd" # dstkind # ", $Rn" # srckind # ", #" # amount #
4685 "|" # dstkind # "\t$Rd, $Rn, #" # amount # "}", "", []>,
4686 Sched<[WriteV]> {
4687 bits<5> Rd;
4688 bits<5> Rn;
4689 let Inst{31} = 0;
4690 let Inst{30} = Q;
4691 let Inst{29-24} = 0b101110;
4692 let Inst{23-22} = size;
4693 let Inst{21-10} = 0b100001001110;
4694 let Inst{9-5} = Rn;
4695 let Inst{4-0} = Rd;
4696}
4697
4698multiclass SIMDVectorLShiftLongBySizeBHS {
Craig Topperc50d64b2014-11-26 00:46:26 +00004699 let hasSideEffects = 0 in {
Tim Northover3b0846e2014-05-24 12:50:23 +00004700 def v8i8 : BaseSIMDVectorLShiftLongBySize<0, 0b00, V64,
4701 "shll", ".8h", ".8b", "8">;
4702 def v16i8 : BaseSIMDVectorLShiftLongBySize<1, 0b00, V128,
4703 "shll2", ".8h", ".16b", "8">;
4704 def v4i16 : BaseSIMDVectorLShiftLongBySize<0, 0b01, V64,
4705 "shll", ".4s", ".4h", "16">;
4706 def v8i16 : BaseSIMDVectorLShiftLongBySize<1, 0b01, V128,
4707 "shll2", ".4s", ".8h", "16">;
4708 def v2i32 : BaseSIMDVectorLShiftLongBySize<0, 0b10, V64,
4709 "shll", ".2d", ".2s", "32">;
4710 def v4i32 : BaseSIMDVectorLShiftLongBySize<1, 0b10, V128,
4711 "shll2", ".2d", ".4s", "32">;
4712 }
4713}
4714
4715// Supports all element sizes.
4716multiclass SIMDLongTwoVector<bit U, bits<5> opc, string asm,
4717 SDPatternOperator OpNode> {
Oliver Stannarde4c3d212015-12-08 12:16:10 +00004718 def v8i8_v4i16 : BaseSIMDTwoSameVector<0, U, 0b00, opc, 0b00, V64,
Tim Northover3b0846e2014-05-24 12:50:23 +00004719 asm, ".4h", ".8b",
4720 [(set (v4i16 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>;
Oliver Stannarde4c3d212015-12-08 12:16:10 +00004721 def v16i8_v8i16 : BaseSIMDTwoSameVector<1, U, 0b00, opc, 0b00, V128,
Tim Northover3b0846e2014-05-24 12:50:23 +00004722 asm, ".8h", ".16b",
4723 [(set (v8i16 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>;
Oliver Stannarde4c3d212015-12-08 12:16:10 +00004724 def v4i16_v2i32 : BaseSIMDTwoSameVector<0, U, 0b01, opc, 0b00, V64,
Tim Northover3b0846e2014-05-24 12:50:23 +00004725 asm, ".2s", ".4h",
4726 [(set (v2i32 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>;
Oliver Stannarde4c3d212015-12-08 12:16:10 +00004727 def v8i16_v4i32 : BaseSIMDTwoSameVector<1, U, 0b01, opc, 0b00, V128,
Tim Northover3b0846e2014-05-24 12:50:23 +00004728 asm, ".4s", ".8h",
4729 [(set (v4i32 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>;
Oliver Stannarde4c3d212015-12-08 12:16:10 +00004730 def v2i32_v1i64 : BaseSIMDTwoSameVector<0, U, 0b10, opc, 0b00, V64,
Tim Northover3b0846e2014-05-24 12:50:23 +00004731 asm, ".1d", ".2s",
4732 [(set (v1i64 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>;
Oliver Stannarde4c3d212015-12-08 12:16:10 +00004733 def v4i32_v2i64 : BaseSIMDTwoSameVector<1, U, 0b10, opc, 0b00, V128,
Tim Northover3b0846e2014-05-24 12:50:23 +00004734 asm, ".2d", ".4s",
4735 [(set (v2i64 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>;
4736}
4737
4738multiclass SIMDLongTwoVectorTied<bit U, bits<5> opc, string asm,
4739 SDPatternOperator OpNode> {
Oliver Stannarde4c3d212015-12-08 12:16:10 +00004740 def v8i8_v4i16 : BaseSIMDTwoSameVectorTied<0, U, 0b00, opc, 0b00, V64,
Tim Northover3b0846e2014-05-24 12:50:23 +00004741 asm, ".4h", ".8b",
4742 [(set (v4i16 V64:$dst), (OpNode (v4i16 V64:$Rd),
4743 (v8i8 V64:$Rn)))]>;
Oliver Stannarde4c3d212015-12-08 12:16:10 +00004744 def v16i8_v8i16 : BaseSIMDTwoSameVectorTied<1, U, 0b00, opc, 0b00, V128,
Tim Northover3b0846e2014-05-24 12:50:23 +00004745 asm, ".8h", ".16b",
4746 [(set (v8i16 V128:$dst), (OpNode (v8i16 V128:$Rd),
4747 (v16i8 V128:$Rn)))]>;
Oliver Stannarde4c3d212015-12-08 12:16:10 +00004748 def v4i16_v2i32 : BaseSIMDTwoSameVectorTied<0, U, 0b01, opc, 0b00, V64,
Tim Northover3b0846e2014-05-24 12:50:23 +00004749 asm, ".2s", ".4h",
4750 [(set (v2i32 V64:$dst), (OpNode (v2i32 V64:$Rd),
4751 (v4i16 V64:$Rn)))]>;
Oliver Stannarde4c3d212015-12-08 12:16:10 +00004752 def v8i16_v4i32 : BaseSIMDTwoSameVectorTied<1, U, 0b01, opc, 0b00, V128,
Tim Northover3b0846e2014-05-24 12:50:23 +00004753 asm, ".4s", ".8h",
4754 [(set (v4i32 V128:$dst), (OpNode (v4i32 V128:$Rd),
4755 (v8i16 V128:$Rn)))]>;
Oliver Stannarde4c3d212015-12-08 12:16:10 +00004756 def v2i32_v1i64 : BaseSIMDTwoSameVectorTied<0, U, 0b10, opc, 0b00, V64,
Tim Northover3b0846e2014-05-24 12:50:23 +00004757 asm, ".1d", ".2s",
4758 [(set (v1i64 V64:$dst), (OpNode (v1i64 V64:$Rd),
4759 (v2i32 V64:$Rn)))]>;
Oliver Stannarde4c3d212015-12-08 12:16:10 +00004760 def v4i32_v2i64 : BaseSIMDTwoSameVectorTied<1, U, 0b10, opc, 0b00, V128,
Tim Northover3b0846e2014-05-24 12:50:23 +00004761 asm, ".2d", ".4s",
4762 [(set (v2i64 V128:$dst), (OpNode (v2i64 V128:$Rd),
4763 (v4i32 V128:$Rn)))]>;
4764}
4765
4766// Supports all element sizes, except 1xD.
4767multiclass SIMDTwoVectorBHSDTied<bit U, bits<5> opc, string asm,
4768 SDPatternOperator OpNode> {
Oliver Stannarde4c3d212015-12-08 12:16:10 +00004769 def v8i8 : BaseSIMDTwoSameVectorTied<0, U, 0b00, opc, 0b00, V64,
Tim Northover3b0846e2014-05-24 12:50:23 +00004770 asm, ".8b", ".8b",
4771 [(set (v8i8 V64:$dst), (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn)))]>;
Oliver Stannarde4c3d212015-12-08 12:16:10 +00004772 def v16i8 : BaseSIMDTwoSameVectorTied<1, U, 0b00, opc, 0b00, V128,
Tim Northover3b0846e2014-05-24 12:50:23 +00004773 asm, ".16b", ".16b",
4774 [(set (v16i8 V128:$dst), (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn)))]>;
Oliver Stannarde4c3d212015-12-08 12:16:10 +00004775 def v4i16 : BaseSIMDTwoSameVectorTied<0, U, 0b01, opc, 0b00, V64,
Tim Northover3b0846e2014-05-24 12:50:23 +00004776 asm, ".4h", ".4h",
4777 [(set (v4i16 V64:$dst), (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn)))]>;
Oliver Stannarde4c3d212015-12-08 12:16:10 +00004778 def v8i16 : BaseSIMDTwoSameVectorTied<1, U, 0b01, opc, 0b00, V128,
Tim Northover3b0846e2014-05-24 12:50:23 +00004779 asm, ".8h", ".8h",
4780 [(set (v8i16 V128:$dst), (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn)))]>;
Oliver Stannarde4c3d212015-12-08 12:16:10 +00004781 def v2i32 : BaseSIMDTwoSameVectorTied<0, U, 0b10, opc, 0b00, V64,
Tim Northover3b0846e2014-05-24 12:50:23 +00004782 asm, ".2s", ".2s",
4783 [(set (v2i32 V64:$dst), (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn)))]>;
Oliver Stannarde4c3d212015-12-08 12:16:10 +00004784 def v4i32 : BaseSIMDTwoSameVectorTied<1, U, 0b10, opc, 0b00, V128,
Tim Northover3b0846e2014-05-24 12:50:23 +00004785 asm, ".4s", ".4s",
4786 [(set (v4i32 V128:$dst), (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn)))]>;
Oliver Stannarde4c3d212015-12-08 12:16:10 +00004787 def v2i64 : BaseSIMDTwoSameVectorTied<1, U, 0b11, opc, 0b00, V128,
Tim Northover3b0846e2014-05-24 12:50:23 +00004788 asm, ".2d", ".2d",
4789 [(set (v2i64 V128:$dst), (OpNode (v2i64 V128:$Rd), (v2i64 V128:$Rn)))]>;
4790}
4791
4792multiclass SIMDTwoVectorBHSD<bit U, bits<5> opc, string asm,
4793 SDPatternOperator OpNode = null_frag> {
Oliver Stannarde4c3d212015-12-08 12:16:10 +00004794 def v8i8 : BaseSIMDTwoSameVector<0, U, 0b00, opc, 0b00, V64,
Tim Northover3b0846e2014-05-24 12:50:23 +00004795 asm, ".8b", ".8b",
4796 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>;
Oliver Stannarde4c3d212015-12-08 12:16:10 +00004797 def v16i8 : BaseSIMDTwoSameVector<1, U, 0b00, opc, 0b00, V128,
Tim Northover3b0846e2014-05-24 12:50:23 +00004798 asm, ".16b", ".16b",
4799 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>;
Oliver Stannarde4c3d212015-12-08 12:16:10 +00004800 def v4i16 : BaseSIMDTwoSameVector<0, U, 0b01, opc, 0b00, V64,
Tim Northover3b0846e2014-05-24 12:50:23 +00004801 asm, ".4h", ".4h",
4802 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>;
Oliver Stannarde4c3d212015-12-08 12:16:10 +00004803 def v8i16 : BaseSIMDTwoSameVector<1, U, 0b01, opc, 0b00, V128,
Tim Northover3b0846e2014-05-24 12:50:23 +00004804 asm, ".8h", ".8h",
4805 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>;
Oliver Stannarde4c3d212015-12-08 12:16:10 +00004806 def v2i32 : BaseSIMDTwoSameVector<0, U, 0b10, opc, 0b00, V64,
Tim Northover3b0846e2014-05-24 12:50:23 +00004807 asm, ".2s", ".2s",
4808 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>;
Oliver Stannarde4c3d212015-12-08 12:16:10 +00004809 def v4i32 : BaseSIMDTwoSameVector<1, U, 0b10, opc, 0b00, V128,
Tim Northover3b0846e2014-05-24 12:50:23 +00004810 asm, ".4s", ".4s",
4811 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>;
Oliver Stannarde4c3d212015-12-08 12:16:10 +00004812 def v2i64 : BaseSIMDTwoSameVector<1, U, 0b11, opc, 0b00, V128,
Tim Northover3b0846e2014-05-24 12:50:23 +00004813 asm, ".2d", ".2d",
4814 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn)))]>;
4815}
4816
4817
4818// Supports only B element sizes.
4819multiclass SIMDTwoVectorB<bit U, bits<2> size, bits<5> opc, string asm,
4820 SDPatternOperator OpNode> {
Oliver Stannarde4c3d212015-12-08 12:16:10 +00004821 def v8i8 : BaseSIMDTwoSameVector<0, U, size, opc, 0b00, V64,
Tim Northover3b0846e2014-05-24 12:50:23 +00004822 asm, ".8b", ".8b",
4823 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>;
Oliver Stannarde4c3d212015-12-08 12:16:10 +00004824 def v16i8 : BaseSIMDTwoSameVector<1, U, size, opc, 0b00, V128,
Tim Northover3b0846e2014-05-24 12:50:23 +00004825 asm, ".16b", ".16b",
4826 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>;
4827
4828}
4829
4830// Supports only B and H element sizes.
4831multiclass SIMDTwoVectorBH<bit U, bits<5> opc, string asm,
4832 SDPatternOperator OpNode> {
Oliver Stannarde4c3d212015-12-08 12:16:10 +00004833 def v8i8 : BaseSIMDTwoSameVector<0, U, 0b00, opc, 0b00, V64,
Tim Northover3b0846e2014-05-24 12:50:23 +00004834 asm, ".8b", ".8b",
4835 [(set (v8i8 V64:$Rd), (OpNode V64:$Rn))]>;
Oliver Stannarde4c3d212015-12-08 12:16:10 +00004836 def v16i8 : BaseSIMDTwoSameVector<1, U, 0b00, opc, 0b00, V128,
Tim Northover3b0846e2014-05-24 12:50:23 +00004837 asm, ".16b", ".16b",
4838 [(set (v16i8 V128:$Rd), (OpNode V128:$Rn))]>;
Oliver Stannarde4c3d212015-12-08 12:16:10 +00004839 def v4i16 : BaseSIMDTwoSameVector<0, U, 0b01, opc, 0b00, V64,
Tim Northover3b0846e2014-05-24 12:50:23 +00004840 asm, ".4h", ".4h",
4841 [(set (v4i16 V64:$Rd), (OpNode V64:$Rn))]>;
Oliver Stannarde4c3d212015-12-08 12:16:10 +00004842 def v8i16 : BaseSIMDTwoSameVector<1, U, 0b01, opc, 0b00, V128,
Tim Northover3b0846e2014-05-24 12:50:23 +00004843 asm, ".8h", ".8h",
4844 [(set (v8i16 V128:$Rd), (OpNode V128:$Rn))]>;
4845}
4846
4847// Supports only S and D element sizes, uses high bit of the size field
4848// as an extra opcode bit.
4849multiclass SIMDTwoVectorFP<bit U, bit S, bits<5> opc, string asm,
4850 SDPatternOperator OpNode> {
Oliver Stannarde4c3d212015-12-08 12:16:10 +00004851 let Predicates = [HasNEON, HasFullFP16] in {
4852 def v4f16 : BaseSIMDTwoSameVector<0, U, {S,1}, opc, 0b11, V64,
4853 asm, ".4h", ".4h",
4854 [(set (v4f16 V64:$Rd), (OpNode (v4f16 V64:$Rn)))]>;
4855 def v8f16 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b11, V128,
4856 asm, ".8h", ".8h",
4857 [(set (v8f16 V128:$Rd), (OpNode (v8f16 V128:$Rn)))]>;
4858 } // Predicates = [HasNEON, HasFullFP16]
4859 def v2f32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, 0b00, V64,
Tim Northover3b0846e2014-05-24 12:50:23 +00004860 asm, ".2s", ".2s",
4861 [(set (v2f32 V64:$Rd), (OpNode (v2f32 V64:$Rn)))]>;
Oliver Stannarde4c3d212015-12-08 12:16:10 +00004862 def v4f32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, 0b00, V128,
Tim Northover3b0846e2014-05-24 12:50:23 +00004863 asm, ".4s", ".4s",
4864 [(set (v4f32 V128:$Rd), (OpNode (v4f32 V128:$Rn)))]>;
Oliver Stannarde4c3d212015-12-08 12:16:10 +00004865 def v2f64 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b00, V128,
Tim Northover3b0846e2014-05-24 12:50:23 +00004866 asm, ".2d", ".2d",
4867 [(set (v2f64 V128:$Rd), (OpNode (v2f64 V128:$Rn)))]>;
4868}
4869
4870// Supports only S element size.
4871multiclass SIMDTwoVectorS<bit U, bit S, bits<5> opc, string asm,
4872 SDPatternOperator OpNode> {
Oliver Stannarde4c3d212015-12-08 12:16:10 +00004873 def v2i32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, 0b00, V64,
Tim Northover3b0846e2014-05-24 12:50:23 +00004874 asm, ".2s", ".2s",
4875 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>;
Oliver Stannarde4c3d212015-12-08 12:16:10 +00004876 def v4i32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, 0b00, V128,
Tim Northover3b0846e2014-05-24 12:50:23 +00004877 asm, ".4s", ".4s",
4878 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>;
4879}
4880
4881
4882multiclass SIMDTwoVectorFPToInt<bit U, bit S, bits<5> opc, string asm,
4883 SDPatternOperator OpNode> {
Oliver Stannarde4c3d212015-12-08 12:16:10 +00004884 let Predicates = [HasNEON, HasFullFP16] in {
4885 def v4f16 : BaseSIMDTwoSameVector<0, U, {S,1}, opc, 0b11, V64,
4886 asm, ".4h", ".4h",
4887 [(set (v4i16 V64:$Rd), (OpNode (v4f16 V64:$Rn)))]>;
4888 def v8f16 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b11, V128,
4889 asm, ".8h", ".8h",
4890 [(set (v8i16 V128:$Rd), (OpNode (v8f16 V128:$Rn)))]>;
4891 } // Predicates = [HasNEON, HasFullFP16]
4892 def v2f32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, 0b00, V64,
Tim Northover3b0846e2014-05-24 12:50:23 +00004893 asm, ".2s", ".2s",
4894 [(set (v2i32 V64:$Rd), (OpNode (v2f32 V64:$Rn)))]>;
Oliver Stannarde4c3d212015-12-08 12:16:10 +00004895 def v4f32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, 0b00, V128,
Tim Northover3b0846e2014-05-24 12:50:23 +00004896 asm, ".4s", ".4s",
4897 [(set (v4i32 V128:$Rd), (OpNode (v4f32 V128:$Rn)))]>;
Oliver Stannarde4c3d212015-12-08 12:16:10 +00004898 def v2f64 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b00, V128,
Tim Northover3b0846e2014-05-24 12:50:23 +00004899 asm, ".2d", ".2d",
4900 [(set (v2i64 V128:$Rd), (OpNode (v2f64 V128:$Rn)))]>;
4901}
4902
4903multiclass SIMDTwoVectorIntToFP<bit U, bit S, bits<5> opc, string asm,
4904 SDPatternOperator OpNode> {
Oliver Stannarde4c3d212015-12-08 12:16:10 +00004905 let Predicates = [HasNEON, HasFullFP16] in {
4906 def v4f16 : BaseSIMDTwoSameVector<0, U, {S,1}, opc, 0b11, V64,
4907 asm, ".4h", ".4h",
4908 [(set (v4f16 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>;
4909 def v8f16 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b11, V128,
4910 asm, ".8h", ".8h",
4911 [(set (v8f16 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>;
4912 } // Predicates = [HasNEON, HasFullFP16]
4913 def v2f32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, 0b00, V64,
Tim Northover3b0846e2014-05-24 12:50:23 +00004914 asm, ".2s", ".2s",
4915 [(set (v2f32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>;
Oliver Stannarde4c3d212015-12-08 12:16:10 +00004916 def v4f32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, 0b00, V128,
Tim Northover3b0846e2014-05-24 12:50:23 +00004917 asm, ".4s", ".4s",
4918 [(set (v4f32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>;
Oliver Stannarde4c3d212015-12-08 12:16:10 +00004919 def v2f64 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b00, V128,
Tim Northover3b0846e2014-05-24 12:50:23 +00004920 asm, ".2d", ".2d",
4921 [(set (v2f64 V128:$Rd), (OpNode (v2i64 V128:$Rn)))]>;
4922}
4923
4924
4925class BaseSIMDMixedTwoVector<bit Q, bit U, bits<2> size, bits<5> opcode,
4926 RegisterOperand inreg, RegisterOperand outreg,
4927 string asm, string outkind, string inkind,
4928 list<dag> pattern>
4929 : I<(outs outreg:$Rd), (ins inreg:$Rn), asm,
4930 "{\t$Rd" # outkind # ", $Rn" # inkind #
4931 "|" # outkind # "\t$Rd, $Rn}", "", pattern>,
4932 Sched<[WriteV]> {
4933 bits<5> Rd;
4934 bits<5> Rn;
4935 let Inst{31} = 0;
4936 let Inst{30} = Q;
4937 let Inst{29} = U;
4938 let Inst{28-24} = 0b01110;
4939 let Inst{23-22} = size;
4940 let Inst{21-17} = 0b10000;
4941 let Inst{16-12} = opcode;
4942 let Inst{11-10} = 0b10;
4943 let Inst{9-5} = Rn;
4944 let Inst{4-0} = Rd;
4945}
4946
4947class BaseSIMDMixedTwoVectorTied<bit Q, bit U, bits<2> size, bits<5> opcode,
4948 RegisterOperand inreg, RegisterOperand outreg,
4949 string asm, string outkind, string inkind,
4950 list<dag> pattern>
4951 : I<(outs outreg:$dst), (ins outreg:$Rd, inreg:$Rn), asm,
4952 "{\t$Rd" # outkind # ", $Rn" # inkind #
4953 "|" # outkind # "\t$Rd, $Rn}", "$Rd = $dst", pattern>,
4954 Sched<[WriteV]> {
4955 bits<5> Rd;
4956 bits<5> Rn;
4957 let Inst{31} = 0;
4958 let Inst{30} = Q;
4959 let Inst{29} = U;
4960 let Inst{28-24} = 0b01110;
4961 let Inst{23-22} = size;
4962 let Inst{21-17} = 0b10000;
4963 let Inst{16-12} = opcode;
4964 let Inst{11-10} = 0b10;
4965 let Inst{9-5} = Rn;
4966 let Inst{4-0} = Rd;
4967}
4968
4969multiclass SIMDMixedTwoVector<bit U, bits<5> opc, string asm,
4970 SDPatternOperator OpNode> {
4971 def v8i8 : BaseSIMDMixedTwoVector<0, U, 0b00, opc, V128, V64,
4972 asm, ".8b", ".8h",
4973 [(set (v8i8 V64:$Rd), (OpNode (v8i16 V128:$Rn)))]>;
4974 def v16i8 : BaseSIMDMixedTwoVectorTied<1, U, 0b00, opc, V128, V128,
4975 asm#"2", ".16b", ".8h", []>;
4976 def v4i16 : BaseSIMDMixedTwoVector<0, U, 0b01, opc, V128, V64,
4977 asm, ".4h", ".4s",
4978 [(set (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn)))]>;
4979 def v8i16 : BaseSIMDMixedTwoVectorTied<1, U, 0b01, opc, V128, V128,
4980 asm#"2", ".8h", ".4s", []>;
4981 def v2i32 : BaseSIMDMixedTwoVector<0, U, 0b10, opc, V128, V64,
4982 asm, ".2s", ".2d",
4983 [(set (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn)))]>;
4984 def v4i32 : BaseSIMDMixedTwoVectorTied<1, U, 0b10, opc, V128, V128,
4985 asm#"2", ".4s", ".2d", []>;
4986
4987 def : Pat<(concat_vectors (v8i8 V64:$Rd), (OpNode (v8i16 V128:$Rn))),
4988 (!cast<Instruction>(NAME # "v16i8")
4989 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>;
4990 def : Pat<(concat_vectors (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn))),
4991 (!cast<Instruction>(NAME # "v8i16")
4992 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>;
4993 def : Pat<(concat_vectors (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn))),
4994 (!cast<Instruction>(NAME # "v4i32")
4995 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>;
4996}
4997
Oliver Stannarde4c3d212015-12-08 12:16:10 +00004998class BaseSIMDCmpTwoVector<bit Q, bit U, bits<2> size, bits<2> size2,
4999 bits<5> opcode, RegisterOperand regtype, string asm,
5000 string kind, string zero, ValueType dty,
5001 ValueType sty, SDNode OpNode>
Tim Northover3b0846e2014-05-24 12:50:23 +00005002 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm,
5003 "{\t$Rd" # kind # ", $Rn" # kind # ", #" # zero #
5004 "|" # kind # "\t$Rd, $Rn, #" # zero # "}", "",
5005 [(set (dty regtype:$Rd), (OpNode (sty regtype:$Rn)))]>,
5006 Sched<[WriteV]> {
5007 bits<5> Rd;
5008 bits<5> Rn;
5009 let Inst{31} = 0;
5010 let Inst{30} = Q;
5011 let Inst{29} = U;
5012 let Inst{28-24} = 0b01110;
5013 let Inst{23-22} = size;
Oliver Stannarde4c3d212015-12-08 12:16:10 +00005014 let Inst{21} = 0b1;
5015 let Inst{20-19} = size2;
5016 let Inst{18-17} = 0b00;
Tim Northover3b0846e2014-05-24 12:50:23 +00005017 let Inst{16-12} = opcode;
5018 let Inst{11-10} = 0b10;
5019 let Inst{9-5} = Rn;
5020 let Inst{4-0} = Rd;
5021}
5022
5023// Comparisons support all element sizes, except 1xD.
5024multiclass SIMDCmpTwoVector<bit U, bits<5> opc, string asm,
5025 SDNode OpNode> {
Oliver Stannarde4c3d212015-12-08 12:16:10 +00005026 def v8i8rz : BaseSIMDCmpTwoVector<0, U, 0b00, 0b00, opc, V64,
Tim Northover3b0846e2014-05-24 12:50:23 +00005027 asm, ".8b", "0",
5028 v8i8, v8i8, OpNode>;
Oliver Stannarde4c3d212015-12-08 12:16:10 +00005029 def v16i8rz : BaseSIMDCmpTwoVector<1, U, 0b00, 0b00, opc, V128,
Tim Northover3b0846e2014-05-24 12:50:23 +00005030 asm, ".16b", "0",
5031 v16i8, v16i8, OpNode>;
Oliver Stannarde4c3d212015-12-08 12:16:10 +00005032 def v4i16rz : BaseSIMDCmpTwoVector<0, U, 0b01, 0b00, opc, V64,
Tim Northover3b0846e2014-05-24 12:50:23 +00005033 asm, ".4h", "0",
5034 v4i16, v4i16, OpNode>;
Oliver Stannarde4c3d212015-12-08 12:16:10 +00005035 def v8i16rz : BaseSIMDCmpTwoVector<1, U, 0b01, 0b00, opc, V128,
Tim Northover3b0846e2014-05-24 12:50:23 +00005036 asm, ".8h", "0",
5037 v8i16, v8i16, OpNode>;
Oliver Stannarde4c3d212015-12-08 12:16:10 +00005038 def v2i32rz : BaseSIMDCmpTwoVector<0, U, 0b10, 0b00, opc, V64,
Tim Northover3b0846e2014-05-24 12:50:23 +00005039 asm, ".2s", "0",
5040 v2i32, v2i32, OpNode>;
Oliver Stannarde4c3d212015-12-08 12:16:10 +00005041 def v4i32rz : BaseSIMDCmpTwoVector<1, U, 0b10, 0b00, opc, V128,
Tim Northover3b0846e2014-05-24 12:50:23 +00005042 asm, ".4s", "0",
5043 v4i32, v4i32, OpNode>;
Oliver Stannarde4c3d212015-12-08 12:16:10 +00005044 def v2i64rz : BaseSIMDCmpTwoVector<1, U, 0b11, 0b00, opc, V128,
Tim Northover3b0846e2014-05-24 12:50:23 +00005045 asm, ".2d", "0",
5046 v2i64, v2i64, OpNode>;
5047}
5048
Oliver Stannarde4c3d212015-12-08 12:16:10 +00005049// FP Comparisons support only S and D element sizes (and H for v8.2a).
Tim Northover3b0846e2014-05-24 12:50:23 +00005050multiclass SIMDFPCmpTwoVector<bit U, bit S, bits<5> opc,
5051 string asm, SDNode OpNode> {
5052
Oliver Stannarde4c3d212015-12-08 12:16:10 +00005053 let Predicates = [HasNEON, HasFullFP16] in {
5054 def v4i16rz : BaseSIMDCmpTwoVector<0, U, {S,1}, 0b11, opc, V64,
5055 asm, ".4h", "0.0",
5056 v4i16, v4f16, OpNode>;
5057 def v8i16rz : BaseSIMDCmpTwoVector<1, U, {S,1}, 0b11, opc, V128,
5058 asm, ".8h", "0.0",
5059 v8i16, v8f16, OpNode>;
5060 } // Predicates = [HasNEON, HasFullFP16]
5061 def v2i32rz : BaseSIMDCmpTwoVector<0, U, {S,0}, 0b00, opc, V64,
Tim Northover3b0846e2014-05-24 12:50:23 +00005062 asm, ".2s", "0.0",
5063 v2i32, v2f32, OpNode>;
Oliver Stannarde4c3d212015-12-08 12:16:10 +00005064 def v4i32rz : BaseSIMDCmpTwoVector<1, U, {S,0}, 0b00, opc, V128,
Tim Northover3b0846e2014-05-24 12:50:23 +00005065 asm, ".4s", "0.0",
5066 v4i32, v4f32, OpNode>;
Oliver Stannarde4c3d212015-12-08 12:16:10 +00005067 def v2i64rz : BaseSIMDCmpTwoVector<1, U, {S,1}, 0b00, opc, V128,
Tim Northover3b0846e2014-05-24 12:50:23 +00005068 asm, ".2d", "0.0",
5069 v2i64, v2f64, OpNode>;
5070
Oliver Stannarde4c3d212015-12-08 12:16:10 +00005071 let Predicates = [HasNEON, HasFullFP16] in {
5072 def : InstAlias<asm # "\t$Vd.4h, $Vn.4h, #0",
5073 (!cast<Instruction>(NAME # v4i16rz) V64:$Vd, V64:$Vn), 0>;
5074 def : InstAlias<asm # "\t$Vd.8h, $Vn.8h, #0",
5075 (!cast<Instruction>(NAME # v8i16rz) V128:$Vd, V128:$Vn), 0>;
5076 }
Ahmed Bougachacca07712015-09-02 18:38:36 +00005077 def : InstAlias<asm # "\t$Vd.2s, $Vn.2s, #0",
Tim Northover3b0846e2014-05-24 12:50:23 +00005078 (!cast<Instruction>(NAME # v2i32rz) V64:$Vd, V64:$Vn), 0>;
Ahmed Bougachacca07712015-09-02 18:38:36 +00005079 def : InstAlias<asm # "\t$Vd.4s, $Vn.4s, #0",
Tim Northover3b0846e2014-05-24 12:50:23 +00005080 (!cast<Instruction>(NAME # v4i32rz) V128:$Vd, V128:$Vn), 0>;
Ahmed Bougachacca07712015-09-02 18:38:36 +00005081 def : InstAlias<asm # "\t$Vd.2d, $Vn.2d, #0",
Tim Northover3b0846e2014-05-24 12:50:23 +00005082 (!cast<Instruction>(NAME # v2i64rz) V128:$Vd, V128:$Vn), 0>;
Oliver Stannarde4c3d212015-12-08 12:16:10 +00005083 let Predicates = [HasNEON, HasFullFP16] in {
5084 def : InstAlias<asm # ".4h\t$Vd, $Vn, #0",
5085 (!cast<Instruction>(NAME # v4i16rz) V64:$Vd, V64:$Vn), 0>;
5086 def : InstAlias<asm # ".8h\t$Vd, $Vn, #0",
5087 (!cast<Instruction>(NAME # v8i16rz) V128:$Vd, V128:$Vn), 0>;
5088 }
Ahmed Bougachacca07712015-09-02 18:38:36 +00005089 def : InstAlias<asm # ".2s\t$Vd, $Vn, #0",
Tim Northover3b0846e2014-05-24 12:50:23 +00005090 (!cast<Instruction>(NAME # v2i32rz) V64:$Vd, V64:$Vn), 0>;
Ahmed Bougachacca07712015-09-02 18:38:36 +00005091 def : InstAlias<asm # ".4s\t$Vd, $Vn, #0",
Tim Northover3b0846e2014-05-24 12:50:23 +00005092 (!cast<Instruction>(NAME # v4i32rz) V128:$Vd, V128:$Vn), 0>;
Ahmed Bougachacca07712015-09-02 18:38:36 +00005093 def : InstAlias<asm # ".2d\t$Vd, $Vn, #0",
Tim Northover3b0846e2014-05-24 12:50:23 +00005094 (!cast<Instruction>(NAME # v2i64rz) V128:$Vd, V128:$Vn), 0>;
5095}
5096
5097let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5098class BaseSIMDFPCvtTwoVector<bit Q, bit U, bits<2> size, bits<5> opcode,
5099 RegisterOperand outtype, RegisterOperand intype,
5100 string asm, string VdTy, string VnTy,
5101 list<dag> pattern>
5102 : I<(outs outtype:$Rd), (ins intype:$Rn), asm,
5103 !strconcat("\t$Rd", VdTy, ", $Rn", VnTy), "", pattern>,
5104 Sched<[WriteV]> {
5105 bits<5> Rd;
5106 bits<5> Rn;
5107 let Inst{31} = 0;
5108 let Inst{30} = Q;
5109 let Inst{29} = U;
5110 let Inst{28-24} = 0b01110;
5111 let Inst{23-22} = size;
5112 let Inst{21-17} = 0b10000;
5113 let Inst{16-12} = opcode;
5114 let Inst{11-10} = 0b10;
5115 let Inst{9-5} = Rn;
5116 let Inst{4-0} = Rd;
5117}
5118
5119class BaseSIMDFPCvtTwoVectorTied<bit Q, bit U, bits<2> size, bits<5> opcode,
5120 RegisterOperand outtype, RegisterOperand intype,
5121 string asm, string VdTy, string VnTy,
5122 list<dag> pattern>
5123 : I<(outs outtype:$dst), (ins outtype:$Rd, intype:$Rn), asm,
5124 !strconcat("\t$Rd", VdTy, ", $Rn", VnTy), "$Rd = $dst", pattern>,
5125 Sched<[WriteV]> {
5126 bits<5> Rd;
5127 bits<5> Rn;
5128 let Inst{31} = 0;
5129 let Inst{30} = Q;
5130 let Inst{29} = U;
5131 let Inst{28-24} = 0b01110;
5132 let Inst{23-22} = size;
5133 let Inst{21-17} = 0b10000;
5134 let Inst{16-12} = opcode;
5135 let Inst{11-10} = 0b10;
5136 let Inst{9-5} = Rn;
5137 let Inst{4-0} = Rd;
5138}
5139
5140multiclass SIMDFPWidenTwoVector<bit U, bit S, bits<5> opc, string asm> {
5141 def v4i16 : BaseSIMDFPCvtTwoVector<0, U, {S,0}, opc, V128, V64,
5142 asm, ".4s", ".4h", []>;
5143 def v8i16 : BaseSIMDFPCvtTwoVector<1, U, {S,0}, opc, V128, V128,
5144 asm#"2", ".4s", ".8h", []>;
5145 def v2i32 : BaseSIMDFPCvtTwoVector<0, U, {S,1}, opc, V128, V64,
5146 asm, ".2d", ".2s", []>;
5147 def v4i32 : BaseSIMDFPCvtTwoVector<1, U, {S,1}, opc, V128, V128,
5148 asm#"2", ".2d", ".4s", []>;
5149}
5150
5151multiclass SIMDFPNarrowTwoVector<bit U, bit S, bits<5> opc, string asm> {
5152 def v4i16 : BaseSIMDFPCvtTwoVector<0, U, {S,0}, opc, V64, V128,
5153 asm, ".4h", ".4s", []>;
5154 def v8i16 : BaseSIMDFPCvtTwoVectorTied<1, U, {S,0}, opc, V128, V128,
5155 asm#"2", ".8h", ".4s", []>;
5156 def v2i32 : BaseSIMDFPCvtTwoVector<0, U, {S,1}, opc, V64, V128,
5157 asm, ".2s", ".2d", []>;
5158 def v4i32 : BaseSIMDFPCvtTwoVectorTied<1, U, {S,1}, opc, V128, V128,
5159 asm#"2", ".4s", ".2d", []>;
5160}
5161
5162multiclass SIMDFPInexactCvtTwoVector<bit U, bit S, bits<5> opc, string asm,
5163 Intrinsic OpNode> {
5164 def v2f32 : BaseSIMDFPCvtTwoVector<0, U, {S,1}, opc, V64, V128,
5165 asm, ".2s", ".2d",
5166 [(set (v2f32 V64:$Rd), (OpNode (v2f64 V128:$Rn)))]>;
5167 def v4f32 : BaseSIMDFPCvtTwoVectorTied<1, U, {S,1}, opc, V128, V128,
5168 asm#"2", ".4s", ".2d", []>;
5169
5170 def : Pat<(concat_vectors (v2f32 V64:$Rd), (OpNode (v2f64 V128:$Rn))),
5171 (!cast<Instruction>(NAME # "v4f32")
5172 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>;
5173}
5174
5175//----------------------------------------------------------------------------
5176// AdvSIMD three register different-size vector instructions.
5177//----------------------------------------------------------------------------
5178
5179let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5180class BaseSIMDDifferentThreeVector<bit U, bits<3> size, bits<4> opcode,
5181 RegisterOperand outtype, RegisterOperand intype1,
5182 RegisterOperand intype2, string asm,
5183 string outkind, string inkind1, string inkind2,
5184 list<dag> pattern>
5185 : I<(outs outtype:$Rd), (ins intype1:$Rn, intype2:$Rm), asm,
5186 "{\t$Rd" # outkind # ", $Rn" # inkind1 # ", $Rm" # inkind2 #
5187 "|" # outkind # "\t$Rd, $Rn, $Rm}", "", pattern>,
5188 Sched<[WriteV]> {
5189 bits<5> Rd;
5190 bits<5> Rn;
5191 bits<5> Rm;
5192 let Inst{31} = 0;
5193 let Inst{30} = size{0};
5194 let Inst{29} = U;
5195 let Inst{28-24} = 0b01110;
5196 let Inst{23-22} = size{2-1};
5197 let Inst{21} = 1;
5198 let Inst{20-16} = Rm;
5199 let Inst{15-12} = opcode;
5200 let Inst{11-10} = 0b00;
5201 let Inst{9-5} = Rn;
5202 let Inst{4-0} = Rd;
5203}
5204
5205let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5206class BaseSIMDDifferentThreeVectorTied<bit U, bits<3> size, bits<4> opcode,
5207 RegisterOperand outtype, RegisterOperand intype1,
5208 RegisterOperand intype2, string asm,
5209 string outkind, string inkind1, string inkind2,
5210 list<dag> pattern>
5211 : I<(outs outtype:$dst), (ins outtype:$Rd, intype1:$Rn, intype2:$Rm), asm,
5212 "{\t$Rd" # outkind # ", $Rn" # inkind1 # ", $Rm" # inkind2 #
5213 "|" # outkind # "\t$Rd, $Rn, $Rm}", "$Rd = $dst", pattern>,
5214 Sched<[WriteV]> {
5215 bits<5> Rd;
5216 bits<5> Rn;
5217 bits<5> Rm;
5218 let Inst{31} = 0;
5219 let Inst{30} = size{0};
5220 let Inst{29} = U;
5221 let Inst{28-24} = 0b01110;
5222 let Inst{23-22} = size{2-1};
5223 let Inst{21} = 1;
5224 let Inst{20-16} = Rm;
5225 let Inst{15-12} = opcode;
5226 let Inst{11-10} = 0b00;
5227 let Inst{9-5} = Rn;
5228 let Inst{4-0} = Rd;
5229}
5230
5231// FIXME: TableGen doesn't know how to deal with expanded types that also
5232// change the element count (in this case, placing the results in
5233// the high elements of the result register rather than the low
5234// elements). Until that's fixed, we can't code-gen those.
5235multiclass SIMDNarrowThreeVectorBHS<bit U, bits<4> opc, string asm,
5236 Intrinsic IntOp> {
5237 def v8i16_v8i8 : BaseSIMDDifferentThreeVector<U, 0b000, opc,
5238 V64, V128, V128,
5239 asm, ".8b", ".8h", ".8h",
5240 [(set (v8i8 V64:$Rd), (IntOp (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>;
5241 def v8i16_v16i8 : BaseSIMDDifferentThreeVectorTied<U, 0b001, opc,
5242 V128, V128, V128,
5243 asm#"2", ".16b", ".8h", ".8h",
5244 []>;
5245 def v4i32_v4i16 : BaseSIMDDifferentThreeVector<U, 0b010, opc,
5246 V64, V128, V128,
5247 asm, ".4h", ".4s", ".4s",
5248 [(set (v4i16 V64:$Rd), (IntOp (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>;
5249 def v4i32_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc,
5250 V128, V128, V128,
5251 asm#"2", ".8h", ".4s", ".4s",
5252 []>;
5253 def v2i64_v2i32 : BaseSIMDDifferentThreeVector<U, 0b100, opc,
5254 V64, V128, V128,
5255 asm, ".2s", ".2d", ".2d",
5256 [(set (v2i32 V64:$Rd), (IntOp (v2i64 V128:$Rn), (v2i64 V128:$Rm)))]>;
5257 def v2i64_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc,
5258 V128, V128, V128,
5259 asm#"2", ".4s", ".2d", ".2d",
5260 []>;
5261
5262
5263 // Patterns for the '2' variants involve INSERT_SUBREG, which you can't put in
5264 // a version attached to an instruction.
5265 def : Pat<(concat_vectors (v8i8 V64:$Rd), (IntOp (v8i16 V128:$Rn),
5266 (v8i16 V128:$Rm))),
5267 (!cast<Instruction>(NAME # "v8i16_v16i8")
5268 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub),
5269 V128:$Rn, V128:$Rm)>;
5270 def : Pat<(concat_vectors (v4i16 V64:$Rd), (IntOp (v4i32 V128:$Rn),
5271 (v4i32 V128:$Rm))),
5272 (!cast<Instruction>(NAME # "v4i32_v8i16")
5273 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub),
5274 V128:$Rn, V128:$Rm)>;
5275 def : Pat<(concat_vectors (v2i32 V64:$Rd), (IntOp (v2i64 V128:$Rn),
5276 (v2i64 V128:$Rm))),
5277 (!cast<Instruction>(NAME # "v2i64_v4i32")
5278 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub),
5279 V128:$Rn, V128:$Rm)>;
5280}
5281
5282multiclass SIMDDifferentThreeVectorBD<bit U, bits<4> opc, string asm,
5283 Intrinsic IntOp> {
5284 def v8i8 : BaseSIMDDifferentThreeVector<U, 0b000, opc,
5285 V128, V64, V64,
5286 asm, ".8h", ".8b", ".8b",
5287 [(set (v8i16 V128:$Rd), (IntOp (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
5288 def v16i8 : BaseSIMDDifferentThreeVector<U, 0b001, opc,
5289 V128, V128, V128,
5290 asm#"2", ".8h", ".16b", ".16b", []>;
5291 let Predicates = [HasCrypto] in {
5292 def v1i64 : BaseSIMDDifferentThreeVector<U, 0b110, opc,
5293 V128, V64, V64,
5294 asm, ".1q", ".1d", ".1d", []>;
5295 def v2i64 : BaseSIMDDifferentThreeVector<U, 0b111, opc,
5296 V128, V128, V128,
5297 asm#"2", ".1q", ".2d", ".2d", []>;
5298 }
5299
5300 def : Pat<(v8i16 (IntOp (v8i8 (extract_high_v16i8 V128:$Rn)),
5301 (v8i8 (extract_high_v16i8 V128:$Rm)))),
5302 (!cast<Instruction>(NAME#"v16i8") V128:$Rn, V128:$Rm)>;
5303}
5304
5305multiclass SIMDLongThreeVectorHS<bit U, bits<4> opc, string asm,
5306 SDPatternOperator OpNode> {
5307 def v4i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b010, opc,
5308 V128, V64, V64,
5309 asm, ".4s", ".4h", ".4h",
5310 [(set (v4i32 V128:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>;
5311 def v8i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b011, opc,
5312 V128, V128, V128,
5313 asm#"2", ".4s", ".8h", ".8h",
5314 [(set (v4i32 V128:$Rd), (OpNode (extract_high_v8i16 V128:$Rn),
5315 (extract_high_v8i16 V128:$Rm)))]>;
5316 def v2i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b100, opc,
5317 V128, V64, V64,
5318 asm, ".2d", ".2s", ".2s",
5319 [(set (v2i64 V128:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>;
5320 def v4i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b101, opc,
5321 V128, V128, V128,
5322 asm#"2", ".2d", ".4s", ".4s",
5323 [(set (v2i64 V128:$Rd), (OpNode (extract_high_v4i32 V128:$Rn),
5324 (extract_high_v4i32 V128:$Rm)))]>;
5325}
5326
5327multiclass SIMDLongThreeVectorBHSabdl<bit U, bits<4> opc, string asm,
5328 SDPatternOperator OpNode = null_frag> {
5329 def v8i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b000, opc,
5330 V128, V64, V64,
5331 asm, ".8h", ".8b", ".8b",
5332 [(set (v8i16 V128:$Rd),
5333 (zext (v8i8 (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))))]>;
5334 def v16i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b001, opc,
5335 V128, V128, V128,
5336 asm#"2", ".8h", ".16b", ".16b",
5337 [(set (v8i16 V128:$Rd),
5338 (zext (v8i8 (OpNode (extract_high_v16i8 V128:$Rn),
5339 (extract_high_v16i8 V128:$Rm)))))]>;
5340 def v4i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b010, opc,
5341 V128, V64, V64,
5342 asm, ".4s", ".4h", ".4h",
5343 [(set (v4i32 V128:$Rd),
5344 (zext (v4i16 (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))))]>;
5345 def v8i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b011, opc,
5346 V128, V128, V128,
5347 asm#"2", ".4s", ".8h", ".8h",
5348 [(set (v4i32 V128:$Rd),
5349 (zext (v4i16 (OpNode (extract_high_v8i16 V128:$Rn),
5350 (extract_high_v8i16 V128:$Rm)))))]>;
5351 def v2i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b100, opc,
5352 V128, V64, V64,
5353 asm, ".2d", ".2s", ".2s",
5354 [(set (v2i64 V128:$Rd),
5355 (zext (v2i32 (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))))]>;
5356 def v4i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b101, opc,
5357 V128, V128, V128,
5358 asm#"2", ".2d", ".4s", ".4s",
5359 [(set (v2i64 V128:$Rd),
5360 (zext (v2i32 (OpNode (extract_high_v4i32 V128:$Rn),
5361 (extract_high_v4i32 V128:$Rm)))))]>;
5362}
5363
5364multiclass SIMDLongThreeVectorTiedBHSabal<bit U, bits<4> opc,
5365 string asm,
5366 SDPatternOperator OpNode> {
5367 def v8i8_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b000, opc,
5368 V128, V64, V64,
5369 asm, ".8h", ".8b", ".8b",
5370 [(set (v8i16 V128:$dst),
5371 (add (v8i16 V128:$Rd),
5372 (zext (v8i8 (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm))))))]>;
5373 def v16i8_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b001, opc,
5374 V128, V128, V128,
5375 asm#"2", ".8h", ".16b", ".16b",
5376 [(set (v8i16 V128:$dst),
5377 (add (v8i16 V128:$Rd),
5378 (zext (v8i8 (OpNode (extract_high_v16i8 V128:$Rn),
5379 (extract_high_v16i8 V128:$Rm))))))]>;
5380 def v4i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b010, opc,
5381 V128, V64, V64,
5382 asm, ".4s", ".4h", ".4h",
5383 [(set (v4i32 V128:$dst),
5384 (add (v4i32 V128:$Rd),
5385 (zext (v4i16 (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm))))))]>;
5386 def v8i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc,
5387 V128, V128, V128,
5388 asm#"2", ".4s", ".8h", ".8h",
5389 [(set (v4i32 V128:$dst),
5390 (add (v4i32 V128:$Rd),
5391 (zext (v4i16 (OpNode (extract_high_v8i16 V128:$Rn),
5392 (extract_high_v8i16 V128:$Rm))))))]>;
5393 def v2i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b100, opc,
5394 V128, V64, V64,
5395 asm, ".2d", ".2s", ".2s",
5396 [(set (v2i64 V128:$dst),
5397 (add (v2i64 V128:$Rd),
5398 (zext (v2i32 (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm))))))]>;
5399 def v4i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc,
5400 V128, V128, V128,
5401 asm#"2", ".2d", ".4s", ".4s",
5402 [(set (v2i64 V128:$dst),
5403 (add (v2i64 V128:$Rd),
5404 (zext (v2i32 (OpNode (extract_high_v4i32 V128:$Rn),
5405 (extract_high_v4i32 V128:$Rm))))))]>;
5406}
5407
5408multiclass SIMDLongThreeVectorBHS<bit U, bits<4> opc, string asm,
5409 SDPatternOperator OpNode = null_frag> {
5410 def v8i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b000, opc,
5411 V128, V64, V64,
5412 asm, ".8h", ".8b", ".8b",
5413 [(set (v8i16 V128:$Rd), (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
5414 def v16i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b001, opc,
5415 V128, V128, V128,
5416 asm#"2", ".8h", ".16b", ".16b",
5417 [(set (v8i16 V128:$Rd), (OpNode (extract_high_v16i8 V128:$Rn),
5418 (extract_high_v16i8 V128:$Rm)))]>;
5419 def v4i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b010, opc,
5420 V128, V64, V64,
5421 asm, ".4s", ".4h", ".4h",
5422 [(set (v4i32 V128:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>;
5423 def v8i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b011, opc,
5424 V128, V128, V128,
5425 asm#"2", ".4s", ".8h", ".8h",
5426 [(set (v4i32 V128:$Rd), (OpNode (extract_high_v8i16 V128:$Rn),
5427 (extract_high_v8i16 V128:$Rm)))]>;
5428 def v2i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b100, opc,
5429 V128, V64, V64,
5430 asm, ".2d", ".2s", ".2s",
5431 [(set (v2i64 V128:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>;
5432 def v4i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b101, opc,
5433 V128, V128, V128,
5434 asm#"2", ".2d", ".4s", ".4s",
5435 [(set (v2i64 V128:$Rd), (OpNode (extract_high_v4i32 V128:$Rn),
5436 (extract_high_v4i32 V128:$Rm)))]>;
5437}
5438
5439multiclass SIMDLongThreeVectorTiedBHS<bit U, bits<4> opc,
5440 string asm,
5441 SDPatternOperator OpNode> {
5442 def v8i8_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b000, opc,
5443 V128, V64, V64,
5444 asm, ".8h", ".8b", ".8b",
5445 [(set (v8i16 V128:$dst),
5446 (OpNode (v8i16 V128:$Rd), (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
5447 def v16i8_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b001, opc,
5448 V128, V128, V128,
5449 asm#"2", ".8h", ".16b", ".16b",
5450 [(set (v8i16 V128:$dst),
5451 (OpNode (v8i16 V128:$Rd),
5452 (extract_high_v16i8 V128:$Rn),
5453 (extract_high_v16i8 V128:$Rm)))]>;
5454 def v4i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b010, opc,
5455 V128, V64, V64,
5456 asm, ".4s", ".4h", ".4h",
5457 [(set (v4i32 V128:$dst),
5458 (OpNode (v4i32 V128:$Rd), (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>;
5459 def v8i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc,
5460 V128, V128, V128,
5461 asm#"2", ".4s", ".8h", ".8h",
5462 [(set (v4i32 V128:$dst),
5463 (OpNode (v4i32 V128:$Rd),
5464 (extract_high_v8i16 V128:$Rn),
5465 (extract_high_v8i16 V128:$Rm)))]>;
5466 def v2i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b100, opc,
5467 V128, V64, V64,
5468 asm, ".2d", ".2s", ".2s",
5469 [(set (v2i64 V128:$dst),
5470 (OpNode (v2i64 V128:$Rd), (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>;
5471 def v4i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc,
5472 V128, V128, V128,
5473 asm#"2", ".2d", ".4s", ".4s",
5474 [(set (v2i64 V128:$dst),
5475 (OpNode (v2i64 V128:$Rd),
5476 (extract_high_v4i32 V128:$Rn),
5477 (extract_high_v4i32 V128:$Rm)))]>;
5478}
5479
5480multiclass SIMDLongThreeVectorSQDMLXTiedHS<bit U, bits<4> opc, string asm,
5481 SDPatternOperator Accum> {
5482 def v4i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b010, opc,
5483 V128, V64, V64,
5484 asm, ".4s", ".4h", ".4h",
5485 [(set (v4i32 V128:$dst),
5486 (Accum (v4i32 V128:$Rd),
5487 (v4i32 (int_aarch64_neon_sqdmull (v4i16 V64:$Rn),
5488 (v4i16 V64:$Rm)))))]>;
5489 def v8i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc,
5490 V128, V128, V128,
5491 asm#"2", ".4s", ".8h", ".8h",
5492 [(set (v4i32 V128:$dst),
5493 (Accum (v4i32 V128:$Rd),
5494 (v4i32 (int_aarch64_neon_sqdmull (extract_high_v8i16 V128:$Rn),
5495 (extract_high_v8i16 V128:$Rm)))))]>;
5496 def v2i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b100, opc,
5497 V128, V64, V64,
5498 asm, ".2d", ".2s", ".2s",
5499 [(set (v2i64 V128:$dst),
5500 (Accum (v2i64 V128:$Rd),
5501 (v2i64 (int_aarch64_neon_sqdmull (v2i32 V64:$Rn),
5502 (v2i32 V64:$Rm)))))]>;
5503 def v4i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc,
5504 V128, V128, V128,
5505 asm#"2", ".2d", ".4s", ".4s",
5506 [(set (v2i64 V128:$dst),
5507 (Accum (v2i64 V128:$Rd),
5508 (v2i64 (int_aarch64_neon_sqdmull (extract_high_v4i32 V128:$Rn),
5509 (extract_high_v4i32 V128:$Rm)))))]>;
5510}
5511
5512multiclass SIMDWideThreeVectorBHS<bit U, bits<4> opc, string asm,
5513 SDPatternOperator OpNode> {
5514 def v8i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b000, opc,
5515 V128, V128, V64,
5516 asm, ".8h", ".8h", ".8b",
5517 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (v8i8 V64:$Rm)))]>;
5518 def v16i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b001, opc,
5519 V128, V128, V128,
5520 asm#"2", ".8h", ".8h", ".16b",
5521 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn),
5522 (extract_high_v16i8 V128:$Rm)))]>;
5523 def v4i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b010, opc,
5524 V128, V128, V64,
5525 asm, ".4s", ".4s", ".4h",
5526 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (v4i16 V64:$Rm)))]>;
5527 def v8i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b011, opc,
5528 V128, V128, V128,
5529 asm#"2", ".4s", ".4s", ".8h",
5530 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn),
5531 (extract_high_v8i16 V128:$Rm)))]>;
5532 def v2i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b100, opc,
5533 V128, V128, V64,
5534 asm, ".2d", ".2d", ".2s",
5535 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn), (v2i32 V64:$Rm)))]>;
5536 def v4i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b101, opc,
5537 V128, V128, V128,
5538 asm#"2", ".2d", ".2d", ".4s",
5539 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn),
5540 (extract_high_v4i32 V128:$Rm)))]>;
5541}
5542
5543//----------------------------------------------------------------------------
5544// AdvSIMD bitwise extract from vector
5545//----------------------------------------------------------------------------
5546
5547class BaseSIMDBitwiseExtract<bit size, RegisterOperand regtype, ValueType vty,
5548 string asm, string kind>
5549 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, i32imm:$imm), asm,
5550 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind # ", $imm" #
5551 "|" # kind # "\t$Rd, $Rn, $Rm, $imm}", "",
5552 [(set (vty regtype:$Rd),
5553 (AArch64ext regtype:$Rn, regtype:$Rm, (i32 imm:$imm)))]>,
5554 Sched<[WriteV]> {
5555 bits<5> Rd;
5556 bits<5> Rn;
5557 bits<5> Rm;
5558 bits<4> imm;
5559 let Inst{31} = 0;
5560 let Inst{30} = size;
5561 let Inst{29-21} = 0b101110000;
5562 let Inst{20-16} = Rm;
5563 let Inst{15} = 0;
5564 let Inst{14-11} = imm;
5565 let Inst{10} = 0;
5566 let Inst{9-5} = Rn;
5567 let Inst{4-0} = Rd;
5568}
5569
5570
5571multiclass SIMDBitwiseExtract<string asm> {
5572 def v8i8 : BaseSIMDBitwiseExtract<0, V64, v8i8, asm, ".8b"> {
5573 let imm{3} = 0;
5574 }
5575 def v16i8 : BaseSIMDBitwiseExtract<1, V128, v16i8, asm, ".16b">;
5576}
5577
5578//----------------------------------------------------------------------------
5579// AdvSIMD zip vector
5580//----------------------------------------------------------------------------
5581
5582class BaseSIMDZipVector<bits<3> size, bits<3> opc, RegisterOperand regtype,
5583 string asm, string kind, SDNode OpNode, ValueType valty>
5584 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), asm,
5585 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind #
5586 "|" # kind # "\t$Rd, $Rn, $Rm}", "",
5587 [(set (valty regtype:$Rd), (OpNode regtype:$Rn, regtype:$Rm))]>,
5588 Sched<[WriteV]> {
5589 bits<5> Rd;
5590 bits<5> Rn;
5591 bits<5> Rm;
5592 let Inst{31} = 0;
5593 let Inst{30} = size{0};
5594 let Inst{29-24} = 0b001110;
5595 let Inst{23-22} = size{2-1};
5596 let Inst{21} = 0;
5597 let Inst{20-16} = Rm;
5598 let Inst{15} = 0;
5599 let Inst{14-12} = opc;
5600 let Inst{11-10} = 0b10;
5601 let Inst{9-5} = Rn;
5602 let Inst{4-0} = Rd;
5603}
5604
5605multiclass SIMDZipVector<bits<3>opc, string asm,
5606 SDNode OpNode> {
5607 def v8i8 : BaseSIMDZipVector<0b000, opc, V64,
5608 asm, ".8b", OpNode, v8i8>;
5609 def v16i8 : BaseSIMDZipVector<0b001, opc, V128,
5610 asm, ".16b", OpNode, v16i8>;
5611 def v4i16 : BaseSIMDZipVector<0b010, opc, V64,
5612 asm, ".4h", OpNode, v4i16>;
5613 def v8i16 : BaseSIMDZipVector<0b011, opc, V128,
5614 asm, ".8h", OpNode, v8i16>;
5615 def v2i32 : BaseSIMDZipVector<0b100, opc, V64,
5616 asm, ".2s", OpNode, v2i32>;
5617 def v4i32 : BaseSIMDZipVector<0b101, opc, V128,
5618 asm, ".4s", OpNode, v4i32>;
5619 def v2i64 : BaseSIMDZipVector<0b111, opc, V128,
5620 asm, ".2d", OpNode, v2i64>;
5621
Oliver Stannard89d15422014-08-27 16:16:04 +00005622 def : Pat<(v4f16 (OpNode V64:$Rn, V64:$Rm)),
5623 (!cast<Instruction>(NAME#"v4i16") V64:$Rn, V64:$Rm)>;
5624 def : Pat<(v8f16 (OpNode V128:$Rn, V128:$Rm)),
5625 (!cast<Instruction>(NAME#"v8i16") V128:$Rn, V128:$Rm)>;
Tim Northover3b0846e2014-05-24 12:50:23 +00005626 def : Pat<(v2f32 (OpNode V64:$Rn, V64:$Rm)),
5627 (!cast<Instruction>(NAME#"v2i32") V64:$Rn, V64:$Rm)>;
5628 def : Pat<(v4f32 (OpNode V128:$Rn, V128:$Rm)),
5629 (!cast<Instruction>(NAME#"v4i32") V128:$Rn, V128:$Rm)>;
5630 def : Pat<(v2f64 (OpNode V128:$Rn, V128:$Rm)),
5631 (!cast<Instruction>(NAME#"v2i64") V128:$Rn, V128:$Rm)>;
5632}
5633
5634//----------------------------------------------------------------------------
5635// AdvSIMD three register scalar instructions
5636//----------------------------------------------------------------------------
5637
5638let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
Oliver Stannarde4c3d212015-12-08 12:16:10 +00005639class BaseSIMDThreeScalar<bit U, bits<3> size, bits<5> opcode,
Tim Northover3b0846e2014-05-24 12:50:23 +00005640 RegisterClass regtype, string asm,
5641 list<dag> pattern>
5642 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), asm,
5643 "\t$Rd, $Rn, $Rm", "", pattern>,
5644 Sched<[WriteV]> {
5645 bits<5> Rd;
5646 bits<5> Rn;
5647 bits<5> Rm;
5648 let Inst{31-30} = 0b01;
5649 let Inst{29} = U;
5650 let Inst{28-24} = 0b11110;
Oliver Stannarde4c3d212015-12-08 12:16:10 +00005651 let Inst{23-21} = size;
Tim Northover3b0846e2014-05-24 12:50:23 +00005652 let Inst{20-16} = Rm;
5653 let Inst{15-11} = opcode;
5654 let Inst{10} = 1;
5655 let Inst{9-5} = Rn;
5656 let Inst{4-0} = Rd;
5657}
5658
Vladimir Sukharev297bf0e2015-03-31 13:15:48 +00005659let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
5660class BaseSIMDThreeScalarTied<bit U, bits<2> size, bit R, bits<5> opcode,
5661 dag oops, dag iops, string asm,
5662 list<dag> pattern>
5663 : I<oops, iops, asm, "\t$Rd, $Rn, $Rm", "$Rd = $dst", pattern>,
5664 Sched<[WriteV]> {
5665 bits<5> Rd;
5666 bits<5> Rn;
5667 bits<5> Rm;
5668 let Inst{31-30} = 0b01;
5669 let Inst{29} = U;
5670 let Inst{28-24} = 0b11110;
5671 let Inst{23-22} = size;
5672 let Inst{21} = R;
5673 let Inst{20-16} = Rm;
5674 let Inst{15-11} = opcode;
5675 let Inst{10} = 1;
5676 let Inst{9-5} = Rn;
5677 let Inst{4-0} = Rd;
5678}
5679
Tim Northover3b0846e2014-05-24 12:50:23 +00005680multiclass SIMDThreeScalarD<bit U, bits<5> opc, string asm,
5681 SDPatternOperator OpNode> {
Oliver Stannarde4c3d212015-12-08 12:16:10 +00005682 def v1i64 : BaseSIMDThreeScalar<U, 0b111, opc, FPR64, asm,
Tim Northover3b0846e2014-05-24 12:50:23 +00005683 [(set (v1i64 FPR64:$Rd), (OpNode (v1i64 FPR64:$Rn), (v1i64 FPR64:$Rm)))]>;
5684}
5685
5686multiclass SIMDThreeScalarBHSD<bit U, bits<5> opc, string asm,
5687 SDPatternOperator OpNode> {
Oliver Stannarde4c3d212015-12-08 12:16:10 +00005688 def v1i64 : BaseSIMDThreeScalar<U, 0b111, opc, FPR64, asm,
Tim Northover3b0846e2014-05-24 12:50:23 +00005689 [(set (v1i64 FPR64:$Rd), (OpNode (v1i64 FPR64:$Rn), (v1i64 FPR64:$Rm)))]>;
Oliver Stannarde4c3d212015-12-08 12:16:10 +00005690 def v1i32 : BaseSIMDThreeScalar<U, 0b101, opc, FPR32, asm, []>;
5691 def v1i16 : BaseSIMDThreeScalar<U, 0b011, opc, FPR16, asm, []>;
5692 def v1i8 : BaseSIMDThreeScalar<U, 0b001, opc, FPR8 , asm, []>;
Tim Northover3b0846e2014-05-24 12:50:23 +00005693
5694 def : Pat<(i64 (OpNode (i64 FPR64:$Rn), (i64 FPR64:$Rm))),
5695 (!cast<Instruction>(NAME#"v1i64") FPR64:$Rn, FPR64:$Rm)>;
5696 def : Pat<(i32 (OpNode (i32 FPR32:$Rn), (i32 FPR32:$Rm))),
5697 (!cast<Instruction>(NAME#"v1i32") FPR32:$Rn, FPR32:$Rm)>;
5698}
5699
5700multiclass SIMDThreeScalarHS<bit U, bits<5> opc, string asm,
5701 SDPatternOperator OpNode> {
Oliver Stannarde4c3d212015-12-08 12:16:10 +00005702 def v1i32 : BaseSIMDThreeScalar<U, 0b101, opc, FPR32, asm,
Tim Northover3b0846e2014-05-24 12:50:23 +00005703 [(set FPR32:$Rd, (OpNode FPR32:$Rn, FPR32:$Rm))]>;
Oliver Stannarde4c3d212015-12-08 12:16:10 +00005704 def v1i16 : BaseSIMDThreeScalar<U, 0b011, opc, FPR16, asm, []>;
Tim Northover3b0846e2014-05-24 12:50:23 +00005705}
5706
Vladimir Sukharev297bf0e2015-03-31 13:15:48 +00005707multiclass SIMDThreeScalarHSTied<bit U, bit R, bits<5> opc, string asm,
5708 SDPatternOperator OpNode = null_frag> {
5709 def v1i32: BaseSIMDThreeScalarTied<U, 0b10, R, opc, (outs FPR32:$dst),
5710 (ins FPR32:$Rd, FPR32:$Rn, FPR32:$Rm),
5711 asm, []>;
5712 def v1i16: BaseSIMDThreeScalarTied<U, 0b01, R, opc, (outs FPR16:$dst),
5713 (ins FPR16:$Rd, FPR16:$Rn, FPR16:$Rm),
5714 asm, []>;
5715}
5716
Oliver Stannarde4c3d212015-12-08 12:16:10 +00005717multiclass SIMDFPThreeScalar<bit U, bit S, bits<3> opc, string asm,
Tim Northover3b0846e2014-05-24 12:50:23 +00005718 SDPatternOperator OpNode = null_frag> {
5719 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
Oliver Stannarde4c3d212015-12-08 12:16:10 +00005720 def #NAME#64 : BaseSIMDThreeScalar<U, {S,0b11}, {0b11,opc}, FPR64, asm,
Tim Northover3b0846e2014-05-24 12:50:23 +00005721 [(set (f64 FPR64:$Rd), (OpNode (f64 FPR64:$Rn), (f64 FPR64:$Rm)))]>;
Oliver Stannarde4c3d212015-12-08 12:16:10 +00005722 def #NAME#32 : BaseSIMDThreeScalar<U, {S,0b01}, {0b11,opc}, FPR32, asm,
Tim Northover3b0846e2014-05-24 12:50:23 +00005723 [(set FPR32:$Rd, (OpNode FPR32:$Rn, FPR32:$Rm))]>;
Oliver Stannarde4c3d212015-12-08 12:16:10 +00005724 let Predicates = [HasNEON, HasFullFP16] in {
5725 def #NAME#16 : BaseSIMDThreeScalar<U, {S,0b10}, {0b00,opc}, FPR16, asm,
5726 [(set FPR16:$Rd, (OpNode FPR16:$Rn, FPR16:$Rm))]>;
5727 } // Predicates = [HasNEON, HasFullFP16]
Tim Northover3b0846e2014-05-24 12:50:23 +00005728 }
5729
5730 def : Pat<(v1f64 (OpNode (v1f64 FPR64:$Rn), (v1f64 FPR64:$Rm))),
5731 (!cast<Instruction>(NAME # "64") FPR64:$Rn, FPR64:$Rm)>;
5732}
5733
Oliver Stannarde4c3d212015-12-08 12:16:10 +00005734multiclass SIMDThreeScalarFPCmp<bit U, bit S, bits<3> opc, string asm,
Tim Northover3b0846e2014-05-24 12:50:23 +00005735 SDPatternOperator OpNode = null_frag> {
5736 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
Oliver Stannarde4c3d212015-12-08 12:16:10 +00005737 def #NAME#64 : BaseSIMDThreeScalar<U, {S,0b11}, {0b11,opc}, FPR64, asm,
Tim Northover3b0846e2014-05-24 12:50:23 +00005738 [(set (i64 FPR64:$Rd), (OpNode (f64 FPR64:$Rn), (f64 FPR64:$Rm)))]>;
Oliver Stannarde4c3d212015-12-08 12:16:10 +00005739 def #NAME#32 : BaseSIMDThreeScalar<U, {S,0b01}, {0b11,opc}, FPR32, asm,
Tim Northover3b0846e2014-05-24 12:50:23 +00005740 [(set (i32 FPR32:$Rd), (OpNode (f32 FPR32:$Rn), (f32 FPR32:$Rm)))]>;
Oliver Stannarde4c3d212015-12-08 12:16:10 +00005741 let Predicates = [HasNEON, HasFullFP16] in {
5742 def #NAME#16 : BaseSIMDThreeScalar<U, {S,0b10}, {0b00,opc}, FPR16, asm,
5743 []>;
5744 } // Predicates = [HasNEON, HasFullFP16]
Tim Northover3b0846e2014-05-24 12:50:23 +00005745 }
5746
5747 def : Pat<(v1i64 (OpNode (v1f64 FPR64:$Rn), (v1f64 FPR64:$Rm))),
5748 (!cast<Instruction>(NAME # "64") FPR64:$Rn, FPR64:$Rm)>;
5749}
5750
5751class BaseSIMDThreeScalarMixed<bit U, bits<2> size, bits<5> opcode,
5752 dag oops, dag iops, string asm, string cstr, list<dag> pat>
5753 : I<oops, iops, asm,
5754 "\t$Rd, $Rn, $Rm", cstr, pat>,
5755 Sched<[WriteV]> {
5756 bits<5> Rd;
5757 bits<5> Rn;
5758 bits<5> Rm;
5759 let Inst{31-30} = 0b01;
5760 let Inst{29} = U;
5761 let Inst{28-24} = 0b11110;
5762 let Inst{23-22} = size;
5763 let Inst{21} = 1;
5764 let Inst{20-16} = Rm;
5765 let Inst{15-11} = opcode;
5766 let Inst{10} = 0;
5767 let Inst{9-5} = Rn;
5768 let Inst{4-0} = Rd;
5769}
5770
5771let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5772multiclass SIMDThreeScalarMixedHS<bit U, bits<5> opc, string asm,
5773 SDPatternOperator OpNode = null_frag> {
5774 def i16 : BaseSIMDThreeScalarMixed<U, 0b01, opc,
5775 (outs FPR32:$Rd),
5776 (ins FPR16:$Rn, FPR16:$Rm), asm, "", []>;
5777 def i32 : BaseSIMDThreeScalarMixed<U, 0b10, opc,
5778 (outs FPR64:$Rd),
5779 (ins FPR32:$Rn, FPR32:$Rm), asm, "",
5780 [(set (i64 FPR64:$Rd), (OpNode (i32 FPR32:$Rn), (i32 FPR32:$Rm)))]>;
5781}
5782
5783let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5784multiclass SIMDThreeScalarMixedTiedHS<bit U, bits<5> opc, string asm,
5785 SDPatternOperator OpNode = null_frag> {
5786 def i16 : BaseSIMDThreeScalarMixed<U, 0b01, opc,
5787 (outs FPR32:$dst),
5788 (ins FPR32:$Rd, FPR16:$Rn, FPR16:$Rm),
5789 asm, "$Rd = $dst", []>;
5790 def i32 : BaseSIMDThreeScalarMixed<U, 0b10, opc,
5791 (outs FPR64:$dst),
5792 (ins FPR64:$Rd, FPR32:$Rn, FPR32:$Rm),
5793 asm, "$Rd = $dst",
5794 [(set (i64 FPR64:$dst),
5795 (OpNode (i64 FPR64:$Rd), (i32 FPR32:$Rn), (i32 FPR32:$Rm)))]>;
5796}
5797
5798//----------------------------------------------------------------------------
5799// AdvSIMD two register scalar instructions
5800//----------------------------------------------------------------------------
5801
5802let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
Oliver Stannarde4c3d212015-12-08 12:16:10 +00005803class BaseSIMDTwoScalar<bit U, bits<2> size, bits<2> size2, bits<5> opcode,
Tim Northover3b0846e2014-05-24 12:50:23 +00005804 RegisterClass regtype, RegisterClass regtype2,
5805 string asm, list<dag> pat>
5806 : I<(outs regtype:$Rd), (ins regtype2:$Rn), asm,
5807 "\t$Rd, $Rn", "", pat>,
5808 Sched<[WriteV]> {
5809 bits<5> Rd;
5810 bits<5> Rn;
5811 let Inst{31-30} = 0b01;
5812 let Inst{29} = U;
5813 let Inst{28-24} = 0b11110;
5814 let Inst{23-22} = size;
Oliver Stannarde4c3d212015-12-08 12:16:10 +00005815 let Inst{21} = 0b1;
5816 let Inst{20-19} = size2;
5817 let Inst{18-17} = 0b00;
Tim Northover3b0846e2014-05-24 12:50:23 +00005818 let Inst{16-12} = opcode;
5819 let Inst{11-10} = 0b10;
5820 let Inst{9-5} = Rn;
5821 let Inst{4-0} = Rd;
5822}
5823
5824let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5825class BaseSIMDTwoScalarTied<bit U, bits<2> size, bits<5> opcode,
5826 RegisterClass regtype, RegisterClass regtype2,
5827 string asm, list<dag> pat>
5828 : I<(outs regtype:$dst), (ins regtype:$Rd, regtype2:$Rn), asm,
5829 "\t$Rd, $Rn", "$Rd = $dst", pat>,
5830 Sched<[WriteV]> {
5831 bits<5> Rd;
5832 bits<5> Rn;
5833 let Inst{31-30} = 0b01;
5834 let Inst{29} = U;
5835 let Inst{28-24} = 0b11110;
5836 let Inst{23-22} = size;
5837 let Inst{21-17} = 0b10000;
5838 let Inst{16-12} = opcode;
5839 let Inst{11-10} = 0b10;
5840 let Inst{9-5} = Rn;
5841 let Inst{4-0} = Rd;
5842}
5843
5844
5845let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
Oliver Stannarde4c3d212015-12-08 12:16:10 +00005846class BaseSIMDCmpTwoScalar<bit U, bits<2> size, bits<2> size2, bits<5> opcode,
Tim Northover3b0846e2014-05-24 12:50:23 +00005847 RegisterClass regtype, string asm, string zero>
5848 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm,
5849 "\t$Rd, $Rn, #" # zero, "", []>,
5850 Sched<[WriteV]> {
5851 bits<5> Rd;
5852 bits<5> Rn;
5853 let Inst{31-30} = 0b01;
5854 let Inst{29} = U;
5855 let Inst{28-24} = 0b11110;
5856 let Inst{23-22} = size;
Oliver Stannarde4c3d212015-12-08 12:16:10 +00005857 let Inst{21} = 0b1;
5858 let Inst{20-19} = size2;
5859 let Inst{18-17} = 0b00;
Tim Northover3b0846e2014-05-24 12:50:23 +00005860 let Inst{16-12} = opcode;
5861 let Inst{11-10} = 0b10;
5862 let Inst{9-5} = Rn;
5863 let Inst{4-0} = Rd;
5864}
5865
5866class SIMDInexactCvtTwoScalar<bits<5> opcode, string asm>
5867 : I<(outs FPR32:$Rd), (ins FPR64:$Rn), asm, "\t$Rd, $Rn", "",
5868 [(set (f32 FPR32:$Rd), (int_aarch64_sisd_fcvtxn (f64 FPR64:$Rn)))]>,
5869 Sched<[WriteV]> {
5870 bits<5> Rd;
5871 bits<5> Rn;
5872 let Inst{31-17} = 0b011111100110000;
5873 let Inst{16-12} = opcode;
5874 let Inst{11-10} = 0b10;
5875 let Inst{9-5} = Rn;
5876 let Inst{4-0} = Rd;
5877}
5878
5879multiclass SIMDCmpTwoScalarD<bit U, bits<5> opc, string asm,
5880 SDPatternOperator OpNode> {
Oliver Stannarde4c3d212015-12-08 12:16:10 +00005881 def v1i64rz : BaseSIMDCmpTwoScalar<U, 0b11, 0b00, opc, FPR64, asm, "0">;
Tim Northover3b0846e2014-05-24 12:50:23 +00005882
5883 def : Pat<(v1i64 (OpNode FPR64:$Rn)),
5884 (!cast<Instruction>(NAME # v1i64rz) FPR64:$Rn)>;
5885}
5886
Ahmed Bougacha81fda182015-08-04 01:38:08 +00005887multiclass SIMDFPCmpTwoScalar<bit U, bit S, bits<5> opc, string asm,
Tim Northover3b0846e2014-05-24 12:50:23 +00005888 SDPatternOperator OpNode> {
Oliver Stannarde4c3d212015-12-08 12:16:10 +00005889 def v1i64rz : BaseSIMDCmpTwoScalar<U, {S,1}, 0b00, opc, FPR64, asm, "0.0">;
5890 def v1i32rz : BaseSIMDCmpTwoScalar<U, {S,0}, 0b00, opc, FPR32, asm, "0.0">;
5891 let Predicates = [HasNEON, HasFullFP16] in {
5892 def v1i16rz : BaseSIMDCmpTwoScalar<U, {S,1}, 0b11, opc, FPR16, asm, "0.0">;
5893 }
Tim Northover3b0846e2014-05-24 12:50:23 +00005894
Ahmed Bougachacca07712015-09-02 18:38:36 +00005895 def : InstAlias<asm # "\t$Rd, $Rn, #0",
Tim Northover3b0846e2014-05-24 12:50:23 +00005896 (!cast<Instruction>(NAME # v1i64rz) FPR64:$Rd, FPR64:$Rn), 0>;
Ahmed Bougachacca07712015-09-02 18:38:36 +00005897 def : InstAlias<asm # "\t$Rd, $Rn, #0",
Tim Northover3b0846e2014-05-24 12:50:23 +00005898 (!cast<Instruction>(NAME # v1i32rz) FPR32:$Rd, FPR32:$Rn), 0>;
Oliver Stannarde4c3d212015-12-08 12:16:10 +00005899 let Predicates = [HasNEON, HasFullFP16] in {
5900 def : InstAlias<asm # "\t$Rd, $Rn, #0",
5901 (!cast<Instruction>(NAME # v1i16rz) FPR16:$Rd, FPR16:$Rn), 0>;
5902 }
Tim Northover3b0846e2014-05-24 12:50:23 +00005903
5904 def : Pat<(v1i64 (OpNode (v1f64 FPR64:$Rn))),
5905 (!cast<Instruction>(NAME # v1i64rz) FPR64:$Rn)>;
5906}
5907
5908multiclass SIMDTwoScalarD<bit U, bits<5> opc, string asm,
5909 SDPatternOperator OpNode = null_frag> {
Oliver Stannarde4c3d212015-12-08 12:16:10 +00005910 def v1i64 : BaseSIMDTwoScalar<U, 0b11, 0b00, opc, FPR64, FPR64, asm,
Tim Northover3b0846e2014-05-24 12:50:23 +00005911 [(set (v1i64 FPR64:$Rd), (OpNode (v1i64 FPR64:$Rn)))]>;
5912
5913 def : Pat<(i64 (OpNode (i64 FPR64:$Rn))),
5914 (!cast<Instruction>(NAME # "v1i64") FPR64:$Rn)>;
5915}
5916
Ahmed Bougacha81fda182015-08-04 01:38:08 +00005917multiclass SIMDFPTwoScalar<bit U, bit S, bits<5> opc, string asm> {
Oliver Stannarde4c3d212015-12-08 12:16:10 +00005918 def v1i64 : BaseSIMDTwoScalar<U, {S,1}, 0b00, opc, FPR64, FPR64, asm,[]>;
5919 def v1i32 : BaseSIMDTwoScalar<U, {S,0}, 0b00, opc, FPR32, FPR32, asm,[]>;
5920 let Predicates = [HasNEON, HasFullFP16] in {
5921 def v1f16 : BaseSIMDTwoScalar<U, {S,1}, 0b11, opc, FPR16, FPR16, asm,[]>;
5922 }
Tim Northover3b0846e2014-05-24 12:50:23 +00005923}
5924
Oliver Stannarde4c3d212015-12-08 12:16:10 +00005925multiclass SIMDFPTwoScalarCVT<bit U, bit S, bits<5> opc, string asm,
Tim Northover3b0846e2014-05-24 12:50:23 +00005926 SDPatternOperator OpNode> {
Oliver Stannarde4c3d212015-12-08 12:16:10 +00005927 def v1i64 : BaseSIMDTwoScalar<U, {S,1}, 0b00, opc, FPR64, FPR64, asm,
Tim Northover3b0846e2014-05-24 12:50:23 +00005928 [(set FPR64:$Rd, (OpNode (f64 FPR64:$Rn)))]>;
Oliver Stannarde4c3d212015-12-08 12:16:10 +00005929 def v1i32 : BaseSIMDTwoScalar<U, {S,0}, 0b00, opc, FPR32, FPR32, asm,
Tim Northover3b0846e2014-05-24 12:50:23 +00005930 [(set FPR32:$Rd, (OpNode (f32 FPR32:$Rn)))]>;
Oliver Stannarde4c3d212015-12-08 12:16:10 +00005931 let Predicates = [HasNEON, HasFullFP16] in {
5932 def v1i16 : BaseSIMDTwoScalar<U, {S,1}, 0b11, opc, FPR16, FPR16, asm,
5933 [(set FPR16:$Rd, (OpNode (f16 FPR16:$Rn)))]>;
5934 }
Tim Northover3b0846e2014-05-24 12:50:23 +00005935}
5936
5937multiclass SIMDTwoScalarBHSD<bit U, bits<5> opc, string asm,
5938 SDPatternOperator OpNode = null_frag> {
5939 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
Oliver Stannarde4c3d212015-12-08 12:16:10 +00005940 def v1i64 : BaseSIMDTwoScalar<U, 0b11, 0b00, opc, FPR64, FPR64, asm,
Tim Northover3b0846e2014-05-24 12:50:23 +00005941 [(set (i64 FPR64:$Rd), (OpNode (i64 FPR64:$Rn)))]>;
Oliver Stannarde4c3d212015-12-08 12:16:10 +00005942 def v1i32 : BaseSIMDTwoScalar<U, 0b10, 0b00, opc, FPR32, FPR32, asm,
Tim Northover3b0846e2014-05-24 12:50:23 +00005943 [(set (i32 FPR32:$Rd), (OpNode (i32 FPR32:$Rn)))]>;
Oliver Stannarde4c3d212015-12-08 12:16:10 +00005944 def v1i16 : BaseSIMDTwoScalar<U, 0b01, 0b00, opc, FPR16, FPR16, asm, []>;
5945 def v1i8 : BaseSIMDTwoScalar<U, 0b00, 0b00, opc, FPR8 , FPR8 , asm, []>;
Tim Northover3b0846e2014-05-24 12:50:23 +00005946 }
5947
5948 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rn))),
5949 (!cast<Instruction>(NAME # v1i64) FPR64:$Rn)>;
5950}
5951
5952multiclass SIMDTwoScalarBHSDTied<bit U, bits<5> opc, string asm,
5953 Intrinsic OpNode> {
5954 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
5955 def v1i64 : BaseSIMDTwoScalarTied<U, 0b11, opc, FPR64, FPR64, asm,
5956 [(set (i64 FPR64:$dst), (OpNode (i64 FPR64:$Rd), (i64 FPR64:$Rn)))]>;
5957 def v1i32 : BaseSIMDTwoScalarTied<U, 0b10, opc, FPR32, FPR32, asm,
5958 [(set (i32 FPR32:$dst), (OpNode (i32 FPR32:$Rd), (i32 FPR32:$Rn)))]>;
5959 def v1i16 : BaseSIMDTwoScalarTied<U, 0b01, opc, FPR16, FPR16, asm, []>;
5960 def v1i8 : BaseSIMDTwoScalarTied<U, 0b00, opc, FPR8 , FPR8 , asm, []>;
5961 }
5962
5963 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rd), (v1i64 FPR64:$Rn))),
5964 (!cast<Instruction>(NAME # v1i64) FPR64:$Rd, FPR64:$Rn)>;
5965}
5966
5967
5968
5969let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5970multiclass SIMDTwoScalarMixedBHS<bit U, bits<5> opc, string asm,
5971 SDPatternOperator OpNode = null_frag> {
Oliver Stannarde4c3d212015-12-08 12:16:10 +00005972 def v1i32 : BaseSIMDTwoScalar<U, 0b10, 0b00, opc, FPR32, FPR64, asm,
Tim Northover3b0846e2014-05-24 12:50:23 +00005973 [(set (i32 FPR32:$Rd), (OpNode (i64 FPR64:$Rn)))]>;
Oliver Stannarde4c3d212015-12-08 12:16:10 +00005974 def v1i16 : BaseSIMDTwoScalar<U, 0b01, 0b00, opc, FPR16, FPR32, asm, []>;
5975 def v1i8 : BaseSIMDTwoScalar<U, 0b00, 0b00, opc, FPR8 , FPR16, asm, []>;
Tim Northover3b0846e2014-05-24 12:50:23 +00005976}
5977
5978//----------------------------------------------------------------------------
5979// AdvSIMD scalar pairwise instructions
5980//----------------------------------------------------------------------------
5981
5982let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5983class BaseSIMDPairwiseScalar<bit U, bits<2> size, bits<5> opcode,
5984 RegisterOperand regtype, RegisterOperand vectype,
5985 string asm, string kind>
5986 : I<(outs regtype:$Rd), (ins vectype:$Rn), asm,
5987 "{\t$Rd, $Rn" # kind # "|" # kind # "\t$Rd, $Rn}", "", []>,
5988 Sched<[WriteV]> {
5989 bits<5> Rd;
5990 bits<5> Rn;
5991 let Inst{31-30} = 0b01;
5992 let Inst{29} = U;
5993 let Inst{28-24} = 0b11110;
5994 let Inst{23-22} = size;
5995 let Inst{21-17} = 0b11000;
5996 let Inst{16-12} = opcode;
5997 let Inst{11-10} = 0b10;
5998 let Inst{9-5} = Rn;
5999 let Inst{4-0} = Rd;
6000}
6001
6002multiclass SIMDPairwiseScalarD<bit U, bits<5> opc, string asm> {
6003 def v2i64p : BaseSIMDPairwiseScalar<U, 0b11, opc, FPR64Op, V128,
6004 asm, ".2d">;
6005}
6006
Oliver Stannarde4c3d212015-12-08 12:16:10 +00006007multiclass SIMDFPPairwiseScalar<bit S, bits<5> opc, string asm> {
6008 let Predicates = [HasNEON, HasFullFP16] in {
6009 def v2i16p : BaseSIMDPairwiseScalar<0, {S,0}, opc, FPR16Op, V64,
6010 asm, ".2h">;
6011 }
6012 def v2i32p : BaseSIMDPairwiseScalar<1, {S,0}, opc, FPR32Op, V64,
Tim Northover3b0846e2014-05-24 12:50:23 +00006013 asm, ".2s">;
Oliver Stannarde4c3d212015-12-08 12:16:10 +00006014 def v2i64p : BaseSIMDPairwiseScalar<1, {S,1}, opc, FPR64Op, V128,
Tim Northover3b0846e2014-05-24 12:50:23 +00006015 asm, ".2d">;
6016}
6017
6018//----------------------------------------------------------------------------
6019// AdvSIMD across lanes instructions
6020//----------------------------------------------------------------------------
6021
6022let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
6023class BaseSIMDAcrossLanes<bit Q, bit U, bits<2> size, bits<5> opcode,
6024 RegisterClass regtype, RegisterOperand vectype,
6025 string asm, string kind, list<dag> pattern>
6026 : I<(outs regtype:$Rd), (ins vectype:$Rn), asm,
6027 "{\t$Rd, $Rn" # kind # "|" # kind # "\t$Rd, $Rn}", "", pattern>,
6028 Sched<[WriteV]> {
6029 bits<5> Rd;
6030 bits<5> Rn;
6031 let Inst{31} = 0;
6032 let Inst{30} = Q;
6033 let Inst{29} = U;
6034 let Inst{28-24} = 0b01110;
6035 let Inst{23-22} = size;
6036 let Inst{21-17} = 0b11000;
6037 let Inst{16-12} = opcode;
6038 let Inst{11-10} = 0b10;
6039 let Inst{9-5} = Rn;
6040 let Inst{4-0} = Rd;
6041}
6042
6043multiclass SIMDAcrossLanesBHS<bit U, bits<5> opcode,
6044 string asm> {
6045 def v8i8v : BaseSIMDAcrossLanes<0, U, 0b00, opcode, FPR8, V64,
6046 asm, ".8b", []>;
6047 def v16i8v : BaseSIMDAcrossLanes<1, U, 0b00, opcode, FPR8, V128,
6048 asm, ".16b", []>;
6049 def v4i16v : BaseSIMDAcrossLanes<0, U, 0b01, opcode, FPR16, V64,
6050 asm, ".4h", []>;
6051 def v8i16v : BaseSIMDAcrossLanes<1, U, 0b01, opcode, FPR16, V128,
6052 asm, ".8h", []>;
6053 def v4i32v : BaseSIMDAcrossLanes<1, U, 0b10, opcode, FPR32, V128,
6054 asm, ".4s", []>;
6055}
6056
6057multiclass SIMDAcrossLanesHSD<bit U, bits<5> opcode, string asm> {
6058 def v8i8v : BaseSIMDAcrossLanes<0, U, 0b00, opcode, FPR16, V64,
6059 asm, ".8b", []>;
6060 def v16i8v : BaseSIMDAcrossLanes<1, U, 0b00, opcode, FPR16, V128,
6061 asm, ".16b", []>;
6062 def v4i16v : BaseSIMDAcrossLanes<0, U, 0b01, opcode, FPR32, V64,
6063 asm, ".4h", []>;
6064 def v8i16v : BaseSIMDAcrossLanes<1, U, 0b01, opcode, FPR32, V128,
6065 asm, ".8h", []>;
6066 def v4i32v : BaseSIMDAcrossLanes<1, U, 0b10, opcode, FPR64, V128,
6067 asm, ".4s", []>;
6068}
6069
Oliver Stannarde4c3d212015-12-08 12:16:10 +00006070multiclass SIMDFPAcrossLanes<bits<5> opcode, bit sz1, string asm,
Tim Northover3b0846e2014-05-24 12:50:23 +00006071 Intrinsic intOp> {
Oliver Stannarde4c3d212015-12-08 12:16:10 +00006072 let Predicates = [HasNEON, HasFullFP16] in {
6073 def v4i16v : BaseSIMDAcrossLanes<0, 0, {sz1, 0}, opcode, FPR16, V64,
6074 asm, ".4h",
6075 [(set FPR16:$Rd, (intOp (v4f16 V64:$Rn)))]>;
6076 def v8i16v : BaseSIMDAcrossLanes<1, 0, {sz1, 0}, opcode, FPR16, V128,
6077 asm, ".8h",
6078 [(set FPR16:$Rd, (intOp (v8f16 V128:$Rn)))]>;
6079 } // Predicates = [HasNEON, HasFullFP16]
Tim Northover3b0846e2014-05-24 12:50:23 +00006080 def v4i32v : BaseSIMDAcrossLanes<1, 1, {sz1, 0}, opcode, FPR32, V128,
6081 asm, ".4s",
6082 [(set FPR32:$Rd, (intOp (v4f32 V128:$Rn)))]>;
6083}
6084
6085//----------------------------------------------------------------------------
6086// AdvSIMD INS/DUP instructions
6087//----------------------------------------------------------------------------
6088
6089// FIXME: There has got to be a better way to factor these. ugh.
6090
6091class BaseSIMDInsDup<bit Q, bit op, dag outs, dag ins, string asm,
6092 string operands, string constraints, list<dag> pattern>
6093 : I<outs, ins, asm, operands, constraints, pattern>,
6094 Sched<[WriteV]> {
6095 bits<5> Rd;
6096 bits<5> Rn;
6097 let Inst{31} = 0;
6098 let Inst{30} = Q;
6099 let Inst{29} = op;
6100 let Inst{28-21} = 0b01110000;
6101 let Inst{15} = 0;
6102 let Inst{10} = 1;
6103 let Inst{9-5} = Rn;
6104 let Inst{4-0} = Rd;
6105}
6106
6107class SIMDDupFromMain<bit Q, bits<5> imm5, string size, ValueType vectype,
6108 RegisterOperand vecreg, RegisterClass regtype>
6109 : BaseSIMDInsDup<Q, 0, (outs vecreg:$Rd), (ins regtype:$Rn), "dup",
6110 "{\t$Rd" # size # ", $Rn" #
6111 "|" # size # "\t$Rd, $Rn}", "",
6112 [(set (vectype vecreg:$Rd), (AArch64dup regtype:$Rn))]> {
6113 let Inst{20-16} = imm5;
6114 let Inst{14-11} = 0b0001;
6115}
6116
6117class SIMDDupFromElement<bit Q, string dstkind, string srckind,
6118 ValueType vectype, ValueType insreg,
6119 RegisterOperand vecreg, Operand idxtype,
6120 ValueType elttype, SDNode OpNode>
6121 : BaseSIMDInsDup<Q, 0, (outs vecreg:$Rd), (ins V128:$Rn, idxtype:$idx), "dup",
6122 "{\t$Rd" # dstkind # ", $Rn" # srckind # "$idx" #
6123 "|" # dstkind # "\t$Rd, $Rn$idx}", "",
6124 [(set (vectype vecreg:$Rd),
6125 (OpNode (insreg V128:$Rn), idxtype:$idx))]> {
6126 let Inst{14-11} = 0b0000;
6127}
6128
6129class SIMDDup64FromElement
6130 : SIMDDupFromElement<1, ".2d", ".d", v2i64, v2i64, V128,
6131 VectorIndexD, i64, AArch64duplane64> {
6132 bits<1> idx;
6133 let Inst{20} = idx;
6134 let Inst{19-16} = 0b1000;
6135}
6136
6137class SIMDDup32FromElement<bit Q, string size, ValueType vectype,
6138 RegisterOperand vecreg>
6139 : SIMDDupFromElement<Q, size, ".s", vectype, v4i32, vecreg,
6140 VectorIndexS, i64, AArch64duplane32> {
6141 bits<2> idx;
6142 let Inst{20-19} = idx;
6143 let Inst{18-16} = 0b100;
6144}
6145
6146class SIMDDup16FromElement<bit Q, string size, ValueType vectype,
6147 RegisterOperand vecreg>
6148 : SIMDDupFromElement<Q, size, ".h", vectype, v8i16, vecreg,
6149 VectorIndexH, i64, AArch64duplane16> {
6150 bits<3> idx;
6151 let Inst{20-18} = idx;
6152 let Inst{17-16} = 0b10;
6153}
6154
6155class SIMDDup8FromElement<bit Q, string size, ValueType vectype,
6156 RegisterOperand vecreg>
6157 : SIMDDupFromElement<Q, size, ".b", vectype, v16i8, vecreg,
6158 VectorIndexB, i64, AArch64duplane8> {
6159 bits<4> idx;
6160 let Inst{20-17} = idx;
6161 let Inst{16} = 1;
6162}
6163
6164class BaseSIMDMov<bit Q, string size, bits<4> imm4, RegisterClass regtype,
6165 Operand idxtype, string asm, list<dag> pattern>
6166 : BaseSIMDInsDup<Q, 0, (outs regtype:$Rd), (ins V128:$Rn, idxtype:$idx), asm,
6167 "{\t$Rd, $Rn" # size # "$idx" #
6168 "|" # size # "\t$Rd, $Rn$idx}", "", pattern> {
6169 let Inst{14-11} = imm4;
6170}
6171
6172class SIMDSMov<bit Q, string size, RegisterClass regtype,
6173 Operand idxtype>
6174 : BaseSIMDMov<Q, size, 0b0101, regtype, idxtype, "smov", []>;
6175class SIMDUMov<bit Q, string size, ValueType vectype, RegisterClass regtype,
6176 Operand idxtype>
6177 : BaseSIMDMov<Q, size, 0b0111, regtype, idxtype, "umov",
6178 [(set regtype:$Rd, (vector_extract (vectype V128:$Rn), idxtype:$idx))]>;
6179
6180class SIMDMovAlias<string asm, string size, Instruction inst,
6181 RegisterClass regtype, Operand idxtype>
6182 : InstAlias<asm#"{\t$dst, $src"#size#"$idx" #
6183 "|" # size # "\t$dst, $src$idx}",
6184 (inst regtype:$dst, V128:$src, idxtype:$idx)>;
6185
6186multiclass SMov {
6187 def vi8to32 : SIMDSMov<0, ".b", GPR32, VectorIndexB> {
6188 bits<4> idx;
6189 let Inst{20-17} = idx;
6190 let Inst{16} = 1;
6191 }
6192 def vi8to64 : SIMDSMov<1, ".b", GPR64, VectorIndexB> {
6193 bits<4> idx;
6194 let Inst{20-17} = idx;
6195 let Inst{16} = 1;
6196 }
6197 def vi16to32 : SIMDSMov<0, ".h", GPR32, VectorIndexH> {
6198 bits<3> idx;
6199 let Inst{20-18} = idx;
6200 let Inst{17-16} = 0b10;
6201 }
6202 def vi16to64 : SIMDSMov<1, ".h", GPR64, VectorIndexH> {
6203 bits<3> idx;
6204 let Inst{20-18} = idx;
6205 let Inst{17-16} = 0b10;
6206 }
6207 def vi32to64 : SIMDSMov<1, ".s", GPR64, VectorIndexS> {
6208 bits<2> idx;
6209 let Inst{20-19} = idx;
6210 let Inst{18-16} = 0b100;
6211 }
6212}
6213
6214multiclass UMov {
6215 def vi8 : SIMDUMov<0, ".b", v16i8, GPR32, VectorIndexB> {
6216 bits<4> idx;
6217 let Inst{20-17} = idx;
6218 let Inst{16} = 1;
6219 }
6220 def vi16 : SIMDUMov<0, ".h", v8i16, GPR32, VectorIndexH> {
6221 bits<3> idx;
6222 let Inst{20-18} = idx;
6223 let Inst{17-16} = 0b10;
6224 }
6225 def vi32 : SIMDUMov<0, ".s", v4i32, GPR32, VectorIndexS> {
6226 bits<2> idx;
6227 let Inst{20-19} = idx;
6228 let Inst{18-16} = 0b100;
6229 }
6230 def vi64 : SIMDUMov<1, ".d", v2i64, GPR64, VectorIndexD> {
6231 bits<1> idx;
6232 let Inst{20} = idx;
6233 let Inst{19-16} = 0b1000;
6234 }
6235 def : SIMDMovAlias<"mov", ".s",
6236 !cast<Instruction>(NAME#"vi32"),
6237 GPR32, VectorIndexS>;
6238 def : SIMDMovAlias<"mov", ".d",
6239 !cast<Instruction>(NAME#"vi64"),
6240 GPR64, VectorIndexD>;
6241}
6242
6243class SIMDInsFromMain<string size, ValueType vectype,
6244 RegisterClass regtype, Operand idxtype>
6245 : BaseSIMDInsDup<1, 0, (outs V128:$dst),
6246 (ins V128:$Rd, idxtype:$idx, regtype:$Rn), "ins",
6247 "{\t$Rd" # size # "$idx, $Rn" #
6248 "|" # size # "\t$Rd$idx, $Rn}",
6249 "$Rd = $dst",
6250 [(set V128:$dst,
6251 (vector_insert (vectype V128:$Rd), regtype:$Rn, idxtype:$idx))]> {
6252 let Inst{14-11} = 0b0011;
6253}
6254
6255class SIMDInsFromElement<string size, ValueType vectype,
6256 ValueType elttype, Operand idxtype>
6257 : BaseSIMDInsDup<1, 1, (outs V128:$dst),
6258 (ins V128:$Rd, idxtype:$idx, V128:$Rn, idxtype:$idx2), "ins",
6259 "{\t$Rd" # size # "$idx, $Rn" # size # "$idx2" #
6260 "|" # size # "\t$Rd$idx, $Rn$idx2}",
6261 "$Rd = $dst",
6262 [(set V128:$dst,
6263 (vector_insert
6264 (vectype V128:$Rd),
6265 (elttype (vector_extract (vectype V128:$Rn), idxtype:$idx2)),
6266 idxtype:$idx))]>;
6267
6268class SIMDInsMainMovAlias<string size, Instruction inst,
6269 RegisterClass regtype, Operand idxtype>
6270 : InstAlias<"mov" # "{\t$dst" # size # "$idx, $src" #
6271 "|" # size #"\t$dst$idx, $src}",
6272 (inst V128:$dst, idxtype:$idx, regtype:$src)>;
6273class SIMDInsElementMovAlias<string size, Instruction inst,
6274 Operand idxtype>
6275 : InstAlias<"mov" # "{\t$dst" # size # "$idx, $src" # size # "$idx2" #
Ahmed Bougachacca07712015-09-02 18:38:36 +00006276 # "|" # size #"\t$dst$idx, $src$idx2}",
Tim Northover3b0846e2014-05-24 12:50:23 +00006277 (inst V128:$dst, idxtype:$idx, V128:$src, idxtype:$idx2)>;
6278
6279
6280multiclass SIMDIns {
6281 def vi8gpr : SIMDInsFromMain<".b", v16i8, GPR32, VectorIndexB> {
6282 bits<4> idx;
6283 let Inst{20-17} = idx;
6284 let Inst{16} = 1;
6285 }
6286 def vi16gpr : SIMDInsFromMain<".h", v8i16, GPR32, VectorIndexH> {
6287 bits<3> idx;
6288 let Inst{20-18} = idx;
6289 let Inst{17-16} = 0b10;
6290 }
6291 def vi32gpr : SIMDInsFromMain<".s", v4i32, GPR32, VectorIndexS> {
6292 bits<2> idx;
6293 let Inst{20-19} = idx;
6294 let Inst{18-16} = 0b100;
6295 }
6296 def vi64gpr : SIMDInsFromMain<".d", v2i64, GPR64, VectorIndexD> {
6297 bits<1> idx;
6298 let Inst{20} = idx;
6299 let Inst{19-16} = 0b1000;
6300 }
6301
6302 def vi8lane : SIMDInsFromElement<".b", v16i8, i32, VectorIndexB> {
6303 bits<4> idx;
6304 bits<4> idx2;
6305 let Inst{20-17} = idx;
6306 let Inst{16} = 1;
6307 let Inst{14-11} = idx2;
6308 }
6309 def vi16lane : SIMDInsFromElement<".h", v8i16, i32, VectorIndexH> {
6310 bits<3> idx;
6311 bits<3> idx2;
6312 let Inst{20-18} = idx;
6313 let Inst{17-16} = 0b10;
6314 let Inst{14-12} = idx2;
Bradley Smithb9136532015-04-14 15:07:26 +00006315 let Inst{11} = {?};
Tim Northover3b0846e2014-05-24 12:50:23 +00006316 }
6317 def vi32lane : SIMDInsFromElement<".s", v4i32, i32, VectorIndexS> {
6318 bits<2> idx;
6319 bits<2> idx2;
6320 let Inst{20-19} = idx;
6321 let Inst{18-16} = 0b100;
6322 let Inst{14-13} = idx2;
Bradley Smithb9136532015-04-14 15:07:26 +00006323 let Inst{12-11} = {?,?};
Tim Northover3b0846e2014-05-24 12:50:23 +00006324 }
6325 def vi64lane : SIMDInsFromElement<".d", v2i64, i64, VectorIndexD> {
6326 bits<1> idx;
6327 bits<1> idx2;
6328 let Inst{20} = idx;
6329 let Inst{19-16} = 0b1000;
6330 let Inst{14} = idx2;
Bradley Smithb9136532015-04-14 15:07:26 +00006331 let Inst{13-11} = {?,?,?};
Tim Northover3b0846e2014-05-24 12:50:23 +00006332 }
6333
6334 // For all forms of the INS instruction, the "mov" mnemonic is the
6335 // preferred alias. Why they didn't just call the instruction "mov" in
6336 // the first place is a very good question indeed...
6337 def : SIMDInsMainMovAlias<".b", !cast<Instruction>(NAME#"vi8gpr"),
6338 GPR32, VectorIndexB>;
6339 def : SIMDInsMainMovAlias<".h", !cast<Instruction>(NAME#"vi16gpr"),
6340 GPR32, VectorIndexH>;
6341 def : SIMDInsMainMovAlias<".s", !cast<Instruction>(NAME#"vi32gpr"),
6342 GPR32, VectorIndexS>;
6343 def : SIMDInsMainMovAlias<".d", !cast<Instruction>(NAME#"vi64gpr"),
6344 GPR64, VectorIndexD>;
6345
6346 def : SIMDInsElementMovAlias<".b", !cast<Instruction>(NAME#"vi8lane"),
6347 VectorIndexB>;
6348 def : SIMDInsElementMovAlias<".h", !cast<Instruction>(NAME#"vi16lane"),
6349 VectorIndexH>;
6350 def : SIMDInsElementMovAlias<".s", !cast<Instruction>(NAME#"vi32lane"),
6351 VectorIndexS>;
6352 def : SIMDInsElementMovAlias<".d", !cast<Instruction>(NAME#"vi64lane"),
6353 VectorIndexD>;
6354}
6355
6356//----------------------------------------------------------------------------
6357// AdvSIMD TBL/TBX
6358//----------------------------------------------------------------------------
6359
6360let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
6361class BaseSIMDTableLookup<bit Q, bits<2> len, bit op, RegisterOperand vectype,
6362 RegisterOperand listtype, string asm, string kind>
6363 : I<(outs vectype:$Vd), (ins listtype:$Vn, vectype:$Vm), asm,
6364 "\t$Vd" # kind # ", $Vn, $Vm" # kind, "", []>,
6365 Sched<[WriteV]> {
6366 bits<5> Vd;
6367 bits<5> Vn;
6368 bits<5> Vm;
6369 let Inst{31} = 0;
6370 let Inst{30} = Q;
6371 let Inst{29-21} = 0b001110000;
6372 let Inst{20-16} = Vm;
6373 let Inst{15} = 0;
6374 let Inst{14-13} = len;
6375 let Inst{12} = op;
6376 let Inst{11-10} = 0b00;
6377 let Inst{9-5} = Vn;
6378 let Inst{4-0} = Vd;
6379}
6380
6381let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
6382class BaseSIMDTableLookupTied<bit Q, bits<2> len, bit op, RegisterOperand vectype,
6383 RegisterOperand listtype, string asm, string kind>
6384 : I<(outs vectype:$dst), (ins vectype:$Vd, listtype:$Vn, vectype:$Vm), asm,
6385 "\t$Vd" # kind # ", $Vn, $Vm" # kind, "$Vd = $dst", []>,
6386 Sched<[WriteV]> {
6387 bits<5> Vd;
6388 bits<5> Vn;
6389 bits<5> Vm;
6390 let Inst{31} = 0;
6391 let Inst{30} = Q;
6392 let Inst{29-21} = 0b001110000;
6393 let Inst{20-16} = Vm;
6394 let Inst{15} = 0;
6395 let Inst{14-13} = len;
6396 let Inst{12} = op;
6397 let Inst{11-10} = 0b00;
6398 let Inst{9-5} = Vn;
6399 let Inst{4-0} = Vd;
6400}
6401
6402class SIMDTableLookupAlias<string asm, Instruction inst,
6403 RegisterOperand vectype, RegisterOperand listtype>
6404 : InstAlias<!strconcat(asm, "\t$dst, $lst, $index"),
6405 (inst vectype:$dst, listtype:$lst, vectype:$index), 0>;
6406
6407multiclass SIMDTableLookup<bit op, string asm> {
6408 def v8i8One : BaseSIMDTableLookup<0, 0b00, op, V64, VecListOne16b,
6409 asm, ".8b">;
6410 def v8i8Two : BaseSIMDTableLookup<0, 0b01, op, V64, VecListTwo16b,
6411 asm, ".8b">;
6412 def v8i8Three : BaseSIMDTableLookup<0, 0b10, op, V64, VecListThree16b,
6413 asm, ".8b">;
6414 def v8i8Four : BaseSIMDTableLookup<0, 0b11, op, V64, VecListFour16b,
6415 asm, ".8b">;
6416 def v16i8One : BaseSIMDTableLookup<1, 0b00, op, V128, VecListOne16b,
6417 asm, ".16b">;
6418 def v16i8Two : BaseSIMDTableLookup<1, 0b01, op, V128, VecListTwo16b,
6419 asm, ".16b">;
6420 def v16i8Three: BaseSIMDTableLookup<1, 0b10, op, V128, VecListThree16b,
6421 asm, ".16b">;
6422 def v16i8Four : BaseSIMDTableLookup<1, 0b11, op, V128, VecListFour16b,
6423 asm, ".16b">;
6424
6425 def : SIMDTableLookupAlias<asm # ".8b",
6426 !cast<Instruction>(NAME#"v8i8One"),
6427 V64, VecListOne128>;
6428 def : SIMDTableLookupAlias<asm # ".8b",
6429 !cast<Instruction>(NAME#"v8i8Two"),
6430 V64, VecListTwo128>;
6431 def : SIMDTableLookupAlias<asm # ".8b",
6432 !cast<Instruction>(NAME#"v8i8Three"),
6433 V64, VecListThree128>;
6434 def : SIMDTableLookupAlias<asm # ".8b",
6435 !cast<Instruction>(NAME#"v8i8Four"),
6436 V64, VecListFour128>;
6437 def : SIMDTableLookupAlias<asm # ".16b",
6438 !cast<Instruction>(NAME#"v16i8One"),
6439 V128, VecListOne128>;
6440 def : SIMDTableLookupAlias<asm # ".16b",
6441 !cast<Instruction>(NAME#"v16i8Two"),
6442 V128, VecListTwo128>;
6443 def : SIMDTableLookupAlias<asm # ".16b",
6444 !cast<Instruction>(NAME#"v16i8Three"),
6445 V128, VecListThree128>;
6446 def : SIMDTableLookupAlias<asm # ".16b",
6447 !cast<Instruction>(NAME#"v16i8Four"),
6448 V128, VecListFour128>;
6449}
6450
6451multiclass SIMDTableLookupTied<bit op, string asm> {
6452 def v8i8One : BaseSIMDTableLookupTied<0, 0b00, op, V64, VecListOne16b,
6453 asm, ".8b">;
6454 def v8i8Two : BaseSIMDTableLookupTied<0, 0b01, op, V64, VecListTwo16b,
6455 asm, ".8b">;
6456 def v8i8Three : BaseSIMDTableLookupTied<0, 0b10, op, V64, VecListThree16b,
6457 asm, ".8b">;
6458 def v8i8Four : BaseSIMDTableLookupTied<0, 0b11, op, V64, VecListFour16b,
6459 asm, ".8b">;
6460 def v16i8One : BaseSIMDTableLookupTied<1, 0b00, op, V128, VecListOne16b,
6461 asm, ".16b">;
6462 def v16i8Two : BaseSIMDTableLookupTied<1, 0b01, op, V128, VecListTwo16b,
6463 asm, ".16b">;
6464 def v16i8Three: BaseSIMDTableLookupTied<1, 0b10, op, V128, VecListThree16b,
6465 asm, ".16b">;
6466 def v16i8Four : BaseSIMDTableLookupTied<1, 0b11, op, V128, VecListFour16b,
6467 asm, ".16b">;
6468
6469 def : SIMDTableLookupAlias<asm # ".8b",
6470 !cast<Instruction>(NAME#"v8i8One"),
6471 V64, VecListOne128>;
6472 def : SIMDTableLookupAlias<asm # ".8b",
6473 !cast<Instruction>(NAME#"v8i8Two"),
6474 V64, VecListTwo128>;
6475 def : SIMDTableLookupAlias<asm # ".8b",
6476 !cast<Instruction>(NAME#"v8i8Three"),
6477 V64, VecListThree128>;
6478 def : SIMDTableLookupAlias<asm # ".8b",
6479 !cast<Instruction>(NAME#"v8i8Four"),
6480 V64, VecListFour128>;
6481 def : SIMDTableLookupAlias<asm # ".16b",
6482 !cast<Instruction>(NAME#"v16i8One"),
6483 V128, VecListOne128>;
6484 def : SIMDTableLookupAlias<asm # ".16b",
6485 !cast<Instruction>(NAME#"v16i8Two"),
6486 V128, VecListTwo128>;
6487 def : SIMDTableLookupAlias<asm # ".16b",
6488 !cast<Instruction>(NAME#"v16i8Three"),
6489 V128, VecListThree128>;
6490 def : SIMDTableLookupAlias<asm # ".16b",
6491 !cast<Instruction>(NAME#"v16i8Four"),
6492 V128, VecListFour128>;
6493}
6494
6495
6496//----------------------------------------------------------------------------
6497// AdvSIMD scalar CPY
6498//----------------------------------------------------------------------------
6499let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
6500class BaseSIMDScalarCPY<RegisterClass regtype, RegisterOperand vectype,
6501 string kind, Operand idxtype>
6502 : I<(outs regtype:$dst), (ins vectype:$src, idxtype:$idx), "mov",
6503 "{\t$dst, $src" # kind # "$idx" #
6504 "|\t$dst, $src$idx}", "", []>,
6505 Sched<[WriteV]> {
6506 bits<5> dst;
6507 bits<5> src;
6508 let Inst{31-21} = 0b01011110000;
6509 let Inst{15-10} = 0b000001;
6510 let Inst{9-5} = src;
6511 let Inst{4-0} = dst;
6512}
6513
6514class SIMDScalarCPYAlias<string asm, string size, Instruction inst,
6515 RegisterClass regtype, RegisterOperand vectype, Operand idxtype>
6516 : InstAlias<asm # "{\t$dst, $src" # size # "$index" #
6517 # "|\t$dst, $src$index}",
6518 (inst regtype:$dst, vectype:$src, idxtype:$index), 0>;
6519
6520
6521multiclass SIMDScalarCPY<string asm> {
6522 def i8 : BaseSIMDScalarCPY<FPR8, V128, ".b", VectorIndexB> {
6523 bits<4> idx;
6524 let Inst{20-17} = idx;
6525 let Inst{16} = 1;
6526 }
6527 def i16 : BaseSIMDScalarCPY<FPR16, V128, ".h", VectorIndexH> {
6528 bits<3> idx;
6529 let Inst{20-18} = idx;
6530 let Inst{17-16} = 0b10;
6531 }
6532 def i32 : BaseSIMDScalarCPY<FPR32, V128, ".s", VectorIndexS> {
6533 bits<2> idx;
6534 let Inst{20-19} = idx;
6535 let Inst{18-16} = 0b100;
6536 }
6537 def i64 : BaseSIMDScalarCPY<FPR64, V128, ".d", VectorIndexD> {
6538 bits<1> idx;
6539 let Inst{20} = idx;
6540 let Inst{19-16} = 0b1000;
6541 }
6542
6543 def : Pat<(v1i64 (scalar_to_vector (i64 (vector_extract (v2i64 V128:$src),
6544 VectorIndexD:$idx)))),
6545 (!cast<Instruction>(NAME # i64) V128:$src, VectorIndexD:$idx)>;
6546
6547 // 'DUP' mnemonic aliases.
6548 def : SIMDScalarCPYAlias<"dup", ".b",
6549 !cast<Instruction>(NAME#"i8"),
6550 FPR8, V128, VectorIndexB>;
6551 def : SIMDScalarCPYAlias<"dup", ".h",
6552 !cast<Instruction>(NAME#"i16"),
6553 FPR16, V128, VectorIndexH>;
6554 def : SIMDScalarCPYAlias<"dup", ".s",
6555 !cast<Instruction>(NAME#"i32"),
6556 FPR32, V128, VectorIndexS>;
6557 def : SIMDScalarCPYAlias<"dup", ".d",
6558 !cast<Instruction>(NAME#"i64"),
6559 FPR64, V128, VectorIndexD>;
6560}
6561
6562//----------------------------------------------------------------------------
6563// AdvSIMD modified immediate instructions
6564//----------------------------------------------------------------------------
6565
Oliver Stannarde4c3d212015-12-08 12:16:10 +00006566class BaseSIMDModifiedImm<bit Q, bit op, bit op2, dag oops, dag iops,
Tim Northover3b0846e2014-05-24 12:50:23 +00006567 string asm, string op_string,
6568 string cstr, list<dag> pattern>
6569 : I<oops, iops, asm, op_string, cstr, pattern>,
6570 Sched<[WriteV]> {
6571 bits<5> Rd;
6572 bits<8> imm8;
6573 let Inst{31} = 0;
6574 let Inst{30} = Q;
6575 let Inst{29} = op;
6576 let Inst{28-19} = 0b0111100000;
6577 let Inst{18-16} = imm8{7-5};
Oliver Stannarde4c3d212015-12-08 12:16:10 +00006578 let Inst{11} = op2;
6579 let Inst{10} = 1;
Tim Northover3b0846e2014-05-24 12:50:23 +00006580 let Inst{9-5} = imm8{4-0};
6581 let Inst{4-0} = Rd;
6582}
6583
Oliver Stannarde4c3d212015-12-08 12:16:10 +00006584class BaseSIMDModifiedImmVector<bit Q, bit op, bit op2, RegisterOperand vectype,
Tim Northover3b0846e2014-05-24 12:50:23 +00006585 Operand immtype, dag opt_shift_iop,
6586 string opt_shift, string asm, string kind,
6587 list<dag> pattern>
Oliver Stannarde4c3d212015-12-08 12:16:10 +00006588 : BaseSIMDModifiedImm<Q, op, op2, (outs vectype:$Rd),
Tim Northover3b0846e2014-05-24 12:50:23 +00006589 !con((ins immtype:$imm8), opt_shift_iop), asm,
6590 "{\t$Rd" # kind # ", $imm8" # opt_shift #
6591 "|" # kind # "\t$Rd, $imm8" # opt_shift # "}",
6592 "", pattern> {
6593 let DecoderMethod = "DecodeModImmInstruction";
6594}
6595
6596class BaseSIMDModifiedImmVectorTied<bit Q, bit op, RegisterOperand vectype,
6597 Operand immtype, dag opt_shift_iop,
6598 string opt_shift, string asm, string kind,
6599 list<dag> pattern>
Oliver Stannarde4c3d212015-12-08 12:16:10 +00006600 : BaseSIMDModifiedImm<Q, op, 0, (outs vectype:$dst),
Tim Northover3b0846e2014-05-24 12:50:23 +00006601 !con((ins vectype:$Rd, immtype:$imm8), opt_shift_iop),
6602 asm, "{\t$Rd" # kind # ", $imm8" # opt_shift #
6603 "|" # kind # "\t$Rd, $imm8" # opt_shift # "}",
6604 "$Rd = $dst", pattern> {
6605 let DecoderMethod = "DecodeModImmTiedInstruction";
6606}
6607
6608class BaseSIMDModifiedImmVectorShift<bit Q, bit op, bits<2> b15_b12,
6609 RegisterOperand vectype, string asm,
6610 string kind, list<dag> pattern>
Oliver Stannarde4c3d212015-12-08 12:16:10 +00006611 : BaseSIMDModifiedImmVector<Q, op, 0, vectype, imm0_255,
Tim Northover3b0846e2014-05-24 12:50:23 +00006612 (ins logical_vec_shift:$shift),
6613 "$shift", asm, kind, pattern> {
6614 bits<2> shift;
6615 let Inst{15} = b15_b12{1};
6616 let Inst{14-13} = shift;
6617 let Inst{12} = b15_b12{0};
6618}
6619
6620class BaseSIMDModifiedImmVectorShiftTied<bit Q, bit op, bits<2> b15_b12,
6621 RegisterOperand vectype, string asm,
6622 string kind, list<dag> pattern>
6623 : BaseSIMDModifiedImmVectorTied<Q, op, vectype, imm0_255,
6624 (ins logical_vec_shift:$shift),
6625 "$shift", asm, kind, pattern> {
6626 bits<2> shift;
6627 let Inst{15} = b15_b12{1};
6628 let Inst{14-13} = shift;
6629 let Inst{12} = b15_b12{0};
6630}
6631
6632
6633class BaseSIMDModifiedImmVectorShiftHalf<bit Q, bit op, bits<2> b15_b12,
6634 RegisterOperand vectype, string asm,
6635 string kind, list<dag> pattern>
Oliver Stannarde4c3d212015-12-08 12:16:10 +00006636 : BaseSIMDModifiedImmVector<Q, op, 0, vectype, imm0_255,
Tim Northover3b0846e2014-05-24 12:50:23 +00006637 (ins logical_vec_hw_shift:$shift),
6638 "$shift", asm, kind, pattern> {
6639 bits<2> shift;
6640 let Inst{15} = b15_b12{1};
6641 let Inst{14} = 0;
6642 let Inst{13} = shift{0};
6643 let Inst{12} = b15_b12{0};
6644}
6645
6646class BaseSIMDModifiedImmVectorShiftHalfTied<bit Q, bit op, bits<2> b15_b12,
6647 RegisterOperand vectype, string asm,
6648 string kind, list<dag> pattern>
6649 : BaseSIMDModifiedImmVectorTied<Q, op, vectype, imm0_255,
6650 (ins logical_vec_hw_shift:$shift),
6651 "$shift", asm, kind, pattern> {
6652 bits<2> shift;
6653 let Inst{15} = b15_b12{1};
6654 let Inst{14} = 0;
6655 let Inst{13} = shift{0};
6656 let Inst{12} = b15_b12{0};
6657}
6658
6659multiclass SIMDModifiedImmVectorShift<bit op, bits<2> hw_cmode, bits<2> w_cmode,
6660 string asm> {
6661 def v4i16 : BaseSIMDModifiedImmVectorShiftHalf<0, op, hw_cmode, V64,
6662 asm, ".4h", []>;
6663 def v8i16 : BaseSIMDModifiedImmVectorShiftHalf<1, op, hw_cmode, V128,
6664 asm, ".8h", []>;
6665
6666 def v2i32 : BaseSIMDModifiedImmVectorShift<0, op, w_cmode, V64,
6667 asm, ".2s", []>;
6668 def v4i32 : BaseSIMDModifiedImmVectorShift<1, op, w_cmode, V128,
6669 asm, ".4s", []>;
6670}
6671
6672multiclass SIMDModifiedImmVectorShiftTied<bit op, bits<2> hw_cmode,
6673 bits<2> w_cmode, string asm,
6674 SDNode OpNode> {
6675 def v4i16 : BaseSIMDModifiedImmVectorShiftHalfTied<0, op, hw_cmode, V64,
6676 asm, ".4h",
6677 [(set (v4i16 V64:$dst), (OpNode V64:$Rd,
6678 imm0_255:$imm8,
6679 (i32 imm:$shift)))]>;
6680 def v8i16 : BaseSIMDModifiedImmVectorShiftHalfTied<1, op, hw_cmode, V128,
6681 asm, ".8h",
6682 [(set (v8i16 V128:$dst), (OpNode V128:$Rd,
6683 imm0_255:$imm8,
6684 (i32 imm:$shift)))]>;
6685
6686 def v2i32 : BaseSIMDModifiedImmVectorShiftTied<0, op, w_cmode, V64,
6687 asm, ".2s",
6688 [(set (v2i32 V64:$dst), (OpNode V64:$Rd,
6689 imm0_255:$imm8,
6690 (i32 imm:$shift)))]>;
6691 def v4i32 : BaseSIMDModifiedImmVectorShiftTied<1, op, w_cmode, V128,
6692 asm, ".4s",
6693 [(set (v4i32 V128:$dst), (OpNode V128:$Rd,
6694 imm0_255:$imm8,
6695 (i32 imm:$shift)))]>;
6696}
6697
6698class SIMDModifiedImmMoveMSL<bit Q, bit op, bits<4> cmode,
6699 RegisterOperand vectype, string asm,
6700 string kind, list<dag> pattern>
Oliver Stannarde4c3d212015-12-08 12:16:10 +00006701 : BaseSIMDModifiedImmVector<Q, op, 0, vectype, imm0_255,
Tim Northover3b0846e2014-05-24 12:50:23 +00006702 (ins move_vec_shift:$shift),
6703 "$shift", asm, kind, pattern> {
6704 bits<1> shift;
6705 let Inst{15-13} = cmode{3-1};
6706 let Inst{12} = shift;
6707}
6708
Oliver Stannarde4c3d212015-12-08 12:16:10 +00006709class SIMDModifiedImmVectorNoShift<bit Q, bit op, bit op2, bits<4> cmode,
Tim Northover3b0846e2014-05-24 12:50:23 +00006710 RegisterOperand vectype,
6711 Operand imm_type, string asm,
6712 string kind, list<dag> pattern>
Oliver Stannarde4c3d212015-12-08 12:16:10 +00006713 : BaseSIMDModifiedImmVector<Q, op, op2, vectype, imm_type, (ins), "",
Tim Northover3b0846e2014-05-24 12:50:23 +00006714 asm, kind, pattern> {
6715 let Inst{15-12} = cmode;
6716}
6717
6718class SIMDModifiedImmScalarNoShift<bit Q, bit op, bits<4> cmode, string asm,
6719 list<dag> pattern>
Oliver Stannarde4c3d212015-12-08 12:16:10 +00006720 : BaseSIMDModifiedImm<Q, op, 0, (outs FPR64:$Rd), (ins simdimmtype10:$imm8), asm,
Tim Northover3b0846e2014-05-24 12:50:23 +00006721 "\t$Rd, $imm8", "", pattern> {
6722 let Inst{15-12} = cmode;
6723 let DecoderMethod = "DecodeModImmInstruction";
6724}
6725
6726//----------------------------------------------------------------------------
6727// AdvSIMD indexed element
6728//----------------------------------------------------------------------------
6729
6730let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
6731class BaseSIMDIndexed<bit Q, bit U, bit Scalar, bits<2> size, bits<4> opc,
6732 RegisterOperand dst_reg, RegisterOperand lhs_reg,
6733 RegisterOperand rhs_reg, Operand vec_idx, string asm,
6734 string apple_kind, string dst_kind, string lhs_kind,
6735 string rhs_kind, list<dag> pattern>
6736 : I<(outs dst_reg:$Rd), (ins lhs_reg:$Rn, rhs_reg:$Rm, vec_idx:$idx),
6737 asm,
6738 "{\t$Rd" # dst_kind # ", $Rn" # lhs_kind # ", $Rm" # rhs_kind # "$idx" #
6739 "|" # apple_kind # "\t$Rd, $Rn, $Rm$idx}", "", pattern>,
6740 Sched<[WriteV]> {
6741 bits<5> Rd;
6742 bits<5> Rn;
6743 bits<5> Rm;
6744
6745 let Inst{31} = 0;
6746 let Inst{30} = Q;
6747 let Inst{29} = U;
6748 let Inst{28} = Scalar;
6749 let Inst{27-24} = 0b1111;
6750 let Inst{23-22} = size;
6751 // Bit 21 must be set by the derived class.
6752 let Inst{20-16} = Rm;
6753 let Inst{15-12} = opc;
6754 // Bit 11 must be set by the derived class.
6755 let Inst{10} = 0;
6756 let Inst{9-5} = Rn;
6757 let Inst{4-0} = Rd;
6758}
6759
6760let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
6761class BaseSIMDIndexedTied<bit Q, bit U, bit Scalar, bits<2> size, bits<4> opc,
6762 RegisterOperand dst_reg, RegisterOperand lhs_reg,
6763 RegisterOperand rhs_reg, Operand vec_idx, string asm,
6764 string apple_kind, string dst_kind, string lhs_kind,
6765 string rhs_kind, list<dag> pattern>
6766 : I<(outs dst_reg:$dst),
6767 (ins dst_reg:$Rd, lhs_reg:$Rn, rhs_reg:$Rm, vec_idx:$idx), asm,
6768 "{\t$Rd" # dst_kind # ", $Rn" # lhs_kind # ", $Rm" # rhs_kind # "$idx" #
6769 "|" # apple_kind # "\t$Rd, $Rn, $Rm$idx}", "$Rd = $dst", pattern>,
6770 Sched<[WriteV]> {
6771 bits<5> Rd;
6772 bits<5> Rn;
6773 bits<5> Rm;
6774
6775 let Inst{31} = 0;
6776 let Inst{30} = Q;
6777 let Inst{29} = U;
6778 let Inst{28} = Scalar;
6779 let Inst{27-24} = 0b1111;
6780 let Inst{23-22} = size;
6781 // Bit 21 must be set by the derived class.
6782 let Inst{20-16} = Rm;
6783 let Inst{15-12} = opc;
6784 // Bit 11 must be set by the derived class.
6785 let Inst{10} = 0;
6786 let Inst{9-5} = Rn;
6787 let Inst{4-0} = Rd;
6788}
6789
Ahmed Bougacha81fda182015-08-04 01:38:08 +00006790multiclass SIMDFPIndexed<bit U, bits<4> opc, string asm,
6791 SDPatternOperator OpNode> {
Oliver Stannarde4c3d212015-12-08 12:16:10 +00006792 let Predicates = [HasNEON, HasFullFP16] in {
6793 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b00, opc,
6794 V64, V64,
6795 V128_lo, VectorIndexH,
6796 asm, ".4h", ".4h", ".4h", ".h",
6797 [(set (v4f16 V64:$Rd),
6798 (OpNode (v4f16 V64:$Rn),
6799 (v4f16 (AArch64duplane16 (v8f16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
6800 bits<3> idx;
6801 let Inst{11} = idx{2};
6802 let Inst{21} = idx{1};
6803 let Inst{20} = idx{0};
6804 }
6805
6806 def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b00, opc,
6807 V128, V128,
6808 V128_lo, VectorIndexH,
6809 asm, ".8h", ".8h", ".8h", ".h",
6810 [(set (v8f16 V128:$Rd),
6811 (OpNode (v8f16 V128:$Rn),
6812 (v8f16 (AArch64duplane16 (v8f16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
6813 bits<3> idx;
6814 let Inst{11} = idx{2};
6815 let Inst{21} = idx{1};
6816 let Inst{20} = idx{0};
6817 }
6818 } // Predicates = [HasNEON, HasFullFP16]
6819
Tim Northover3b0846e2014-05-24 12:50:23 +00006820 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc,
6821 V64, V64,
6822 V128, VectorIndexS,
6823 asm, ".2s", ".2s", ".2s", ".s",
6824 [(set (v2f32 V64:$Rd),
6825 (OpNode (v2f32 V64:$Rn),
6826 (v2f32 (AArch64duplane32 (v4f32 V128:$Rm), VectorIndexS:$idx))))]> {
6827 bits<2> idx;
6828 let Inst{11} = idx{1};
6829 let Inst{21} = idx{0};
6830 }
6831
6832 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc,
6833 V128, V128,
6834 V128, VectorIndexS,
6835 asm, ".4s", ".4s", ".4s", ".s",
6836 [(set (v4f32 V128:$Rd),
6837 (OpNode (v4f32 V128:$Rn),
6838 (v4f32 (AArch64duplane32 (v4f32 V128:$Rm), VectorIndexS:$idx))))]> {
6839 bits<2> idx;
6840 let Inst{11} = idx{1};
6841 let Inst{21} = idx{0};
6842 }
6843
6844 def v2i64_indexed : BaseSIMDIndexed<1, U, 0, 0b11, opc,
6845 V128, V128,
6846 V128, VectorIndexD,
6847 asm, ".2d", ".2d", ".2d", ".d",
6848 [(set (v2f64 V128:$Rd),
6849 (OpNode (v2f64 V128:$Rn),
6850 (v2f64 (AArch64duplane64 (v2f64 V128:$Rm), VectorIndexD:$idx))))]> {
6851 bits<1> idx;
6852 let Inst{11} = idx{0};
6853 let Inst{21} = 0;
6854 }
6855
Oliver Stannarde4c3d212015-12-08 12:16:10 +00006856 let Predicates = [HasNEON, HasFullFP16] in {
6857 def v1i16_indexed : BaseSIMDIndexed<1, U, 1, 0b00, opc,
6858 FPR16Op, FPR16Op, V128, VectorIndexH,
6859 asm, ".h", "", "", ".h",
6860 [(set (f16 FPR16Op:$Rd),
6861 (OpNode (f16 FPR16Op:$Rn),
6862 (f16 (vector_extract (v8f16 V128:$Rm),
6863 VectorIndexH:$idx))))]> {
6864 bits<3> idx;
6865 let Inst{11} = idx{2};
6866 let Inst{21} = idx{1};
6867 let Inst{20} = idx{0};
6868 }
6869 } // Predicates = [HasNEON, HasFullFP16]
6870
Tim Northover3b0846e2014-05-24 12:50:23 +00006871 def v1i32_indexed : BaseSIMDIndexed<1, U, 1, 0b10, opc,
6872 FPR32Op, FPR32Op, V128, VectorIndexS,
6873 asm, ".s", "", "", ".s",
6874 [(set (f32 FPR32Op:$Rd),
6875 (OpNode (f32 FPR32Op:$Rn),
6876 (f32 (vector_extract (v4f32 V128:$Rm),
6877 VectorIndexS:$idx))))]> {
6878 bits<2> idx;
6879 let Inst{11} = idx{1};
6880 let Inst{21} = idx{0};
6881 }
6882
6883 def v1i64_indexed : BaseSIMDIndexed<1, U, 1, 0b11, opc,
6884 FPR64Op, FPR64Op, V128, VectorIndexD,
6885 asm, ".d", "", "", ".d",
6886 [(set (f64 FPR64Op:$Rd),
6887 (OpNode (f64 FPR64Op:$Rn),
6888 (f64 (vector_extract (v2f64 V128:$Rm),
6889 VectorIndexD:$idx))))]> {
6890 bits<1> idx;
6891 let Inst{11} = idx{0};
6892 let Inst{21} = 0;
6893 }
6894}
6895
Ahmed Bougacha81fda182015-08-04 01:38:08 +00006896multiclass SIMDFPIndexedTiedPatterns<string INST, SDPatternOperator OpNode> {
Tim Northover3b0846e2014-05-24 12:50:23 +00006897 // 2 variants for the .2s version: DUPLANE from 128-bit and DUP scalar.
6898 def : Pat<(v2f32 (OpNode (v2f32 V64:$Rd), (v2f32 V64:$Rn),
6899 (AArch64duplane32 (v4f32 V128:$Rm),
6900 VectorIndexS:$idx))),
6901 (!cast<Instruction>(INST # v2i32_indexed)
6902 V64:$Rd, V64:$Rn, V128:$Rm, VectorIndexS:$idx)>;
6903 def : Pat<(v2f32 (OpNode (v2f32 V64:$Rd), (v2f32 V64:$Rn),
6904 (AArch64dup (f32 FPR32Op:$Rm)))),
6905 (!cast<Instruction>(INST # "v2i32_indexed") V64:$Rd, V64:$Rn,
6906 (SUBREG_TO_REG (i32 0), FPR32Op:$Rm, ssub), (i64 0))>;
6907
6908
6909 // 2 variants for the .4s version: DUPLANE from 128-bit and DUP scalar.
6910 def : Pat<(v4f32 (OpNode (v4f32 V128:$Rd), (v4f32 V128:$Rn),
6911 (AArch64duplane32 (v4f32 V128:$Rm),
6912 VectorIndexS:$idx))),
6913 (!cast<Instruction>(INST # "v4i32_indexed")
6914 V128:$Rd, V128:$Rn, V128:$Rm, VectorIndexS:$idx)>;
6915 def : Pat<(v4f32 (OpNode (v4f32 V128:$Rd), (v4f32 V128:$Rn),
6916 (AArch64dup (f32 FPR32Op:$Rm)))),
6917 (!cast<Instruction>(INST # "v4i32_indexed") V128:$Rd, V128:$Rn,
6918 (SUBREG_TO_REG (i32 0), FPR32Op:$Rm, ssub), (i64 0))>;
6919
6920 // 2 variants for the .2d version: DUPLANE from 128-bit and DUP scalar.
6921 def : Pat<(v2f64 (OpNode (v2f64 V128:$Rd), (v2f64 V128:$Rn),
6922 (AArch64duplane64 (v2f64 V128:$Rm),
6923 VectorIndexD:$idx))),
6924 (!cast<Instruction>(INST # "v2i64_indexed")
6925 V128:$Rd, V128:$Rn, V128:$Rm, VectorIndexS:$idx)>;
6926 def : Pat<(v2f64 (OpNode (v2f64 V128:$Rd), (v2f64 V128:$Rn),
6927 (AArch64dup (f64 FPR64Op:$Rm)))),
6928 (!cast<Instruction>(INST # "v2i64_indexed") V128:$Rd, V128:$Rn,
6929 (SUBREG_TO_REG (i32 0), FPR64Op:$Rm, dsub), (i64 0))>;
6930
6931 // 2 variants for 32-bit scalar version: extract from .2s or from .4s
6932 def : Pat<(f32 (OpNode (f32 FPR32:$Rd), (f32 FPR32:$Rn),
6933 (vector_extract (v4f32 V128:$Rm), VectorIndexS:$idx))),
6934 (!cast<Instruction>(INST # "v1i32_indexed") FPR32:$Rd, FPR32:$Rn,
6935 V128:$Rm, VectorIndexS:$idx)>;
6936 def : Pat<(f32 (OpNode (f32 FPR32:$Rd), (f32 FPR32:$Rn),
6937 (vector_extract (v2f32 V64:$Rm), VectorIndexS:$idx))),
6938 (!cast<Instruction>(INST # "v1i32_indexed") FPR32:$Rd, FPR32:$Rn,
6939 (SUBREG_TO_REG (i32 0), V64:$Rm, dsub), VectorIndexS:$idx)>;
6940
6941 // 1 variant for 64-bit scalar version: extract from .1d or from .2d
6942 def : Pat<(f64 (OpNode (f64 FPR64:$Rd), (f64 FPR64:$Rn),
6943 (vector_extract (v2f64 V128:$Rm), VectorIndexD:$idx))),
6944 (!cast<Instruction>(INST # "v1i64_indexed") FPR64:$Rd, FPR64:$Rn,
6945 V128:$Rm, VectorIndexD:$idx)>;
6946}
6947
Ahmed Bougacha81fda182015-08-04 01:38:08 +00006948multiclass SIMDFPIndexedTied<bit U, bits<4> opc, string asm> {
Oliver Stannarde4c3d212015-12-08 12:16:10 +00006949 let Predicates = [HasNEON, HasFullFP16] in {
6950 def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b00, opc, V64, V64,
6951 V128_lo, VectorIndexH,
6952 asm, ".4h", ".4h", ".4h", ".h", []> {
6953 bits<3> idx;
6954 let Inst{11} = idx{2};
6955 let Inst{21} = idx{1};
6956 let Inst{20} = idx{0};
6957 }
6958
6959 def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b00, opc,
6960 V128, V128,
6961 V128_lo, VectorIndexH,
6962 asm, ".8h", ".8h", ".8h", ".h", []> {
6963 bits<3> idx;
6964 let Inst{11} = idx{2};
6965 let Inst{21} = idx{1};
6966 let Inst{20} = idx{0};
6967 }
6968 } // Predicates = [HasNEON, HasFullFP16]
6969
Tim Northover3b0846e2014-05-24 12:50:23 +00006970 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc, V64, V64,
6971 V128, VectorIndexS,
6972 asm, ".2s", ".2s", ".2s", ".s", []> {
6973 bits<2> idx;
6974 let Inst{11} = idx{1};
6975 let Inst{21} = idx{0};
6976 }
6977
6978 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc,
6979 V128, V128,
6980 V128, VectorIndexS,
6981 asm, ".4s", ".4s", ".4s", ".s", []> {
6982 bits<2> idx;
6983 let Inst{11} = idx{1};
6984 let Inst{21} = idx{0};
6985 }
6986
6987 def v2i64_indexed : BaseSIMDIndexedTied<1, U, 0, 0b11, opc,
6988 V128, V128,
6989 V128, VectorIndexD,
6990 asm, ".2d", ".2d", ".2d", ".d", []> {
6991 bits<1> idx;
6992 let Inst{11} = idx{0};
6993 let Inst{21} = 0;
6994 }
6995
Oliver Stannarde4c3d212015-12-08 12:16:10 +00006996 let Predicates = [HasNEON, HasFullFP16] in {
6997 def v1i16_indexed : BaseSIMDIndexedTied<1, U, 1, 0b00, opc,
6998 FPR16Op, FPR16Op, V128, VectorIndexH,
6999 asm, ".h", "", "", ".h", []> {
7000 bits<3> idx;
7001 let Inst{11} = idx{2};
7002 let Inst{21} = idx{1};
7003 let Inst{20} = idx{0};
7004 }
7005 } // Predicates = [HasNEON, HasFullFP16]
Tim Northover3b0846e2014-05-24 12:50:23 +00007006
7007 def v1i32_indexed : BaseSIMDIndexedTied<1, U, 1, 0b10, opc,
7008 FPR32Op, FPR32Op, V128, VectorIndexS,
7009 asm, ".s", "", "", ".s", []> {
7010 bits<2> idx;
7011 let Inst{11} = idx{1};
7012 let Inst{21} = idx{0};
7013 }
7014
7015 def v1i64_indexed : BaseSIMDIndexedTied<1, U, 1, 0b11, opc,
7016 FPR64Op, FPR64Op, V128, VectorIndexD,
7017 asm, ".d", "", "", ".d", []> {
7018 bits<1> idx;
7019 let Inst{11} = idx{0};
7020 let Inst{21} = 0;
7021 }
7022}
7023
7024multiclass SIMDIndexedHS<bit U, bits<4> opc, string asm,
7025 SDPatternOperator OpNode> {
7026 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc, V64, V64,
7027 V128_lo, VectorIndexH,
7028 asm, ".4h", ".4h", ".4h", ".h",
7029 [(set (v4i16 V64:$Rd),
7030 (OpNode (v4i16 V64:$Rn),
7031 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
7032 bits<3> idx;
7033 let Inst{11} = idx{2};
7034 let Inst{21} = idx{1};
7035 let Inst{20} = idx{0};
7036 }
7037
7038 def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc,
7039 V128, V128,
7040 V128_lo, VectorIndexH,
7041 asm, ".8h", ".8h", ".8h", ".h",
7042 [(set (v8i16 V128:$Rd),
7043 (OpNode (v8i16 V128:$Rn),
7044 (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
7045 bits<3> idx;
7046 let Inst{11} = idx{2};
7047 let Inst{21} = idx{1};
7048 let Inst{20} = idx{0};
7049 }
7050
7051 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc,
7052 V64, V64,
7053 V128, VectorIndexS,
7054 asm, ".2s", ".2s", ".2s", ".s",
7055 [(set (v2i32 V64:$Rd),
7056 (OpNode (v2i32 V64:$Rn),
7057 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
7058 bits<2> idx;
7059 let Inst{11} = idx{1};
7060 let Inst{21} = idx{0};
7061 }
7062
7063 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc,
7064 V128, V128,
7065 V128, VectorIndexS,
7066 asm, ".4s", ".4s", ".4s", ".s",
7067 [(set (v4i32 V128:$Rd),
7068 (OpNode (v4i32 V128:$Rn),
7069 (v4i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
7070 bits<2> idx;
7071 let Inst{11} = idx{1};
7072 let Inst{21} = idx{0};
7073 }
7074
7075 def v1i16_indexed : BaseSIMDIndexed<1, U, 1, 0b01, opc,
7076 FPR16Op, FPR16Op, V128_lo, VectorIndexH,
7077 asm, ".h", "", "", ".h", []> {
7078 bits<3> idx;
7079 let Inst{11} = idx{2};
7080 let Inst{21} = idx{1};
7081 let Inst{20} = idx{0};
7082 }
7083
7084 def v1i32_indexed : BaseSIMDIndexed<1, U, 1, 0b10, opc,
7085 FPR32Op, FPR32Op, V128, VectorIndexS,
7086 asm, ".s", "", "", ".s",
7087 [(set (i32 FPR32Op:$Rd),
7088 (OpNode FPR32Op:$Rn,
7089 (i32 (vector_extract (v4i32 V128:$Rm),
7090 VectorIndexS:$idx))))]> {
7091 bits<2> idx;
7092 let Inst{11} = idx{1};
7093 let Inst{21} = idx{0};
7094 }
7095}
7096
7097multiclass SIMDVectorIndexedHS<bit U, bits<4> opc, string asm,
7098 SDPatternOperator OpNode> {
7099 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc,
7100 V64, V64,
7101 V128_lo, VectorIndexH,
7102 asm, ".4h", ".4h", ".4h", ".h",
7103 [(set (v4i16 V64:$Rd),
7104 (OpNode (v4i16 V64:$Rn),
7105 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
7106 bits<3> idx;
7107 let Inst{11} = idx{2};
7108 let Inst{21} = idx{1};
7109 let Inst{20} = idx{0};
7110 }
7111
7112 def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc,
7113 V128, V128,
7114 V128_lo, VectorIndexH,
7115 asm, ".8h", ".8h", ".8h", ".h",
7116 [(set (v8i16 V128:$Rd),
7117 (OpNode (v8i16 V128:$Rn),
7118 (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
7119 bits<3> idx;
7120 let Inst{11} = idx{2};
7121 let Inst{21} = idx{1};
7122 let Inst{20} = idx{0};
7123 }
7124
7125 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc,
7126 V64, V64,
7127 V128, VectorIndexS,
7128 asm, ".2s", ".2s", ".2s", ".s",
7129 [(set (v2i32 V64:$Rd),
7130 (OpNode (v2i32 V64:$Rn),
7131 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
7132 bits<2> idx;
7133 let Inst{11} = idx{1};
7134 let Inst{21} = idx{0};
7135 }
7136
7137 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc,
7138 V128, V128,
7139 V128, VectorIndexS,
7140 asm, ".4s", ".4s", ".4s", ".s",
7141 [(set (v4i32 V128:$Rd),
7142 (OpNode (v4i32 V128:$Rn),
7143 (v4i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
7144 bits<2> idx;
7145 let Inst{11} = idx{1};
7146 let Inst{21} = idx{0};
7147 }
7148}
7149
7150multiclass SIMDVectorIndexedHSTied<bit U, bits<4> opc, string asm,
7151 SDPatternOperator OpNode> {
7152 def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc, V64, V64,
7153 V128_lo, VectorIndexH,
7154 asm, ".4h", ".4h", ".4h", ".h",
7155 [(set (v4i16 V64:$dst),
7156 (OpNode (v4i16 V64:$Rd),(v4i16 V64:$Rn),
7157 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
7158 bits<3> idx;
7159 let Inst{11} = idx{2};
7160 let Inst{21} = idx{1};
7161 let Inst{20} = idx{0};
7162 }
7163
7164 def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc,
7165 V128, V128,
7166 V128_lo, VectorIndexH,
7167 asm, ".8h", ".8h", ".8h", ".h",
7168 [(set (v8i16 V128:$dst),
7169 (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn),
7170 (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
7171 bits<3> idx;
7172 let Inst{11} = idx{2};
7173 let Inst{21} = idx{1};
7174 let Inst{20} = idx{0};
7175 }
7176
7177 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc,
7178 V64, V64,
7179 V128, VectorIndexS,
7180 asm, ".2s", ".2s", ".2s", ".s",
7181 [(set (v2i32 V64:$dst),
7182 (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn),
7183 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
7184 bits<2> idx;
7185 let Inst{11} = idx{1};
7186 let Inst{21} = idx{0};
7187 }
7188
7189 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc,
7190 V128, V128,
7191 V128, VectorIndexS,
7192 asm, ".4s", ".4s", ".4s", ".s",
7193 [(set (v4i32 V128:$dst),
7194 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn),
7195 (v4i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
7196 bits<2> idx;
7197 let Inst{11} = idx{1};
7198 let Inst{21} = idx{0};
7199 }
7200}
7201
7202multiclass SIMDIndexedLongSD<bit U, bits<4> opc, string asm,
7203 SDPatternOperator OpNode> {
7204 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc,
7205 V128, V64,
7206 V128_lo, VectorIndexH,
7207 asm, ".4s", ".4s", ".4h", ".h",
7208 [(set (v4i32 V128:$Rd),
7209 (OpNode (v4i16 V64:$Rn),
7210 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
7211 bits<3> idx;
7212 let Inst{11} = idx{2};
7213 let Inst{21} = idx{1};
7214 let Inst{20} = idx{0};
7215 }
7216
7217 def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc,
7218 V128, V128,
7219 V128_lo, VectorIndexH,
7220 asm#"2", ".4s", ".4s", ".8h", ".h",
7221 [(set (v4i32 V128:$Rd),
7222 (OpNode (extract_high_v8i16 V128:$Rn),
7223 (extract_high_v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm),
7224 VectorIndexH:$idx))))]> {
7225
7226 bits<3> idx;
7227 let Inst{11} = idx{2};
7228 let Inst{21} = idx{1};
7229 let Inst{20} = idx{0};
7230 }
7231
7232 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc,
7233 V128, V64,
7234 V128, VectorIndexS,
7235 asm, ".2d", ".2d", ".2s", ".s",
7236 [(set (v2i64 V128:$Rd),
7237 (OpNode (v2i32 V64:$Rn),
7238 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
7239 bits<2> idx;
7240 let Inst{11} = idx{1};
7241 let Inst{21} = idx{0};
7242 }
7243
7244 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc,
7245 V128, V128,
7246 V128, VectorIndexS,
7247 asm#"2", ".2d", ".2d", ".4s", ".s",
7248 [(set (v2i64 V128:$Rd),
7249 (OpNode (extract_high_v4i32 V128:$Rn),
7250 (extract_high_v4i32 (AArch64duplane32 (v4i32 V128:$Rm),
7251 VectorIndexS:$idx))))]> {
7252 bits<2> idx;
7253 let Inst{11} = idx{1};
7254 let Inst{21} = idx{0};
7255 }
7256
7257 def v1i32_indexed : BaseSIMDIndexed<1, U, 1, 0b01, opc,
7258 FPR32Op, FPR16Op, V128_lo, VectorIndexH,
7259 asm, ".h", "", "", ".h", []> {
7260 bits<3> idx;
7261 let Inst{11} = idx{2};
7262 let Inst{21} = idx{1};
7263 let Inst{20} = idx{0};
7264 }
7265
7266 def v1i64_indexed : BaseSIMDIndexed<1, U, 1, 0b10, opc,
7267 FPR64Op, FPR32Op, V128, VectorIndexS,
7268 asm, ".s", "", "", ".s", []> {
7269 bits<2> idx;
7270 let Inst{11} = idx{1};
7271 let Inst{21} = idx{0};
7272 }
7273}
7274
7275multiclass SIMDIndexedLongSQDMLXSDTied<bit U, bits<4> opc, string asm,
7276 SDPatternOperator Accum> {
7277 def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc,
7278 V128, V64,
7279 V128_lo, VectorIndexH,
7280 asm, ".4s", ".4s", ".4h", ".h",
7281 [(set (v4i32 V128:$dst),
7282 (Accum (v4i32 V128:$Rd),
7283 (v4i32 (int_aarch64_neon_sqdmull
7284 (v4i16 V64:$Rn),
7285 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm),
7286 VectorIndexH:$idx))))))]> {
7287 bits<3> idx;
7288 let Inst{11} = idx{2};
7289 let Inst{21} = idx{1};
7290 let Inst{20} = idx{0};
7291 }
7292
7293 // FIXME: it would be nice to use the scalar (v1i32) instruction here, but an
7294 // intermediate EXTRACT_SUBREG would be untyped.
7295 def : Pat<(i32 (Accum (i32 FPR32Op:$Rd),
7296 (i32 (vector_extract (v4i32
7297 (int_aarch64_neon_sqdmull (v4i16 V64:$Rn),
7298 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm),
7299 VectorIndexH:$idx)))),
7300 (i64 0))))),
7301 (EXTRACT_SUBREG
7302 (!cast<Instruction>(NAME # v4i16_indexed)
7303 (SUBREG_TO_REG (i32 0), FPR32Op:$Rd, ssub), V64:$Rn,
7304 V128_lo:$Rm, VectorIndexH:$idx),
7305 ssub)>;
7306
7307 def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc,
7308 V128, V128,
7309 V128_lo, VectorIndexH,
7310 asm#"2", ".4s", ".4s", ".8h", ".h",
7311 [(set (v4i32 V128:$dst),
7312 (Accum (v4i32 V128:$Rd),
7313 (v4i32 (int_aarch64_neon_sqdmull
7314 (extract_high_v8i16 V128:$Rn),
7315 (extract_high_v8i16
7316 (AArch64duplane16 (v8i16 V128_lo:$Rm),
7317 VectorIndexH:$idx))))))]> {
7318 bits<3> idx;
7319 let Inst{11} = idx{2};
7320 let Inst{21} = idx{1};
7321 let Inst{20} = idx{0};
7322 }
7323
7324 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc,
7325 V128, V64,
7326 V128, VectorIndexS,
7327 asm, ".2d", ".2d", ".2s", ".s",
7328 [(set (v2i64 V128:$dst),
7329 (Accum (v2i64 V128:$Rd),
7330 (v2i64 (int_aarch64_neon_sqdmull
7331 (v2i32 V64:$Rn),
7332 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm),
7333 VectorIndexS:$idx))))))]> {
7334 bits<2> idx;
7335 let Inst{11} = idx{1};
7336 let Inst{21} = idx{0};
7337 }
7338
7339 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc,
7340 V128, V128,
7341 V128, VectorIndexS,
7342 asm#"2", ".2d", ".2d", ".4s", ".s",
7343 [(set (v2i64 V128:$dst),
7344 (Accum (v2i64 V128:$Rd),
7345 (v2i64 (int_aarch64_neon_sqdmull
7346 (extract_high_v4i32 V128:$Rn),
7347 (extract_high_v4i32
7348 (AArch64duplane32 (v4i32 V128:$Rm),
7349 VectorIndexS:$idx))))))]> {
7350 bits<2> idx;
7351 let Inst{11} = idx{1};
7352 let Inst{21} = idx{0};
7353 }
7354
7355 def v1i32_indexed : BaseSIMDIndexedTied<1, U, 1, 0b01, opc,
7356 FPR32Op, FPR16Op, V128_lo, VectorIndexH,
7357 asm, ".h", "", "", ".h", []> {
7358 bits<3> idx;
7359 let Inst{11} = idx{2};
7360 let Inst{21} = idx{1};
7361 let Inst{20} = idx{0};
7362 }
7363
7364
7365 def v1i64_indexed : BaseSIMDIndexedTied<1, U, 1, 0b10, opc,
7366 FPR64Op, FPR32Op, V128, VectorIndexS,
7367 asm, ".s", "", "", ".s",
7368 [(set (i64 FPR64Op:$dst),
7369 (Accum (i64 FPR64Op:$Rd),
7370 (i64 (int_aarch64_neon_sqdmulls_scalar
7371 (i32 FPR32Op:$Rn),
7372 (i32 (vector_extract (v4i32 V128:$Rm),
7373 VectorIndexS:$idx))))))]> {
7374
7375 bits<2> idx;
7376 let Inst{11} = idx{1};
7377 let Inst{21} = idx{0};
7378 }
7379}
7380
7381multiclass SIMDVectorIndexedLongSD<bit U, bits<4> opc, string asm,
7382 SDPatternOperator OpNode> {
7383 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
7384 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc,
7385 V128, V64,
7386 V128_lo, VectorIndexH,
7387 asm, ".4s", ".4s", ".4h", ".h",
7388 [(set (v4i32 V128:$Rd),
7389 (OpNode (v4i16 V64:$Rn),
7390 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
7391 bits<3> idx;
7392 let Inst{11} = idx{2};
7393 let Inst{21} = idx{1};
7394 let Inst{20} = idx{0};
7395 }
7396
7397 def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc,
7398 V128, V128,
7399 V128_lo, VectorIndexH,
7400 asm#"2", ".4s", ".4s", ".8h", ".h",
7401 [(set (v4i32 V128:$Rd),
7402 (OpNode (extract_high_v8i16 V128:$Rn),
7403 (extract_high_v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm),
7404 VectorIndexH:$idx))))]> {
7405
7406 bits<3> idx;
7407 let Inst{11} = idx{2};
7408 let Inst{21} = idx{1};
7409 let Inst{20} = idx{0};
7410 }
7411
7412 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc,
7413 V128, V64,
7414 V128, VectorIndexS,
7415 asm, ".2d", ".2d", ".2s", ".s",
7416 [(set (v2i64 V128:$Rd),
7417 (OpNode (v2i32 V64:$Rn),
7418 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
7419 bits<2> idx;
7420 let Inst{11} = idx{1};
7421 let Inst{21} = idx{0};
7422 }
7423
7424 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc,
7425 V128, V128,
7426 V128, VectorIndexS,
7427 asm#"2", ".2d", ".2d", ".4s", ".s",
7428 [(set (v2i64 V128:$Rd),
7429 (OpNode (extract_high_v4i32 V128:$Rn),
7430 (extract_high_v4i32 (AArch64duplane32 (v4i32 V128:$Rm),
7431 VectorIndexS:$idx))))]> {
7432 bits<2> idx;
7433 let Inst{11} = idx{1};
7434 let Inst{21} = idx{0};
7435 }
7436 }
7437}
7438
7439multiclass SIMDVectorIndexedLongSDTied<bit U, bits<4> opc, string asm,
7440 SDPatternOperator OpNode> {
7441 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
7442 def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc,
7443 V128, V64,
7444 V128_lo, VectorIndexH,
7445 asm, ".4s", ".4s", ".4h", ".h",
7446 [(set (v4i32 V128:$dst),
7447 (OpNode (v4i32 V128:$Rd), (v4i16 V64:$Rn),
7448 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
7449 bits<3> idx;
7450 let Inst{11} = idx{2};
7451 let Inst{21} = idx{1};
7452 let Inst{20} = idx{0};
7453 }
7454
7455 def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc,
7456 V128, V128,
7457 V128_lo, VectorIndexH,
7458 asm#"2", ".4s", ".4s", ".8h", ".h",
7459 [(set (v4i32 V128:$dst),
7460 (OpNode (v4i32 V128:$Rd),
7461 (extract_high_v8i16 V128:$Rn),
7462 (extract_high_v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm),
7463 VectorIndexH:$idx))))]> {
7464 bits<3> idx;
7465 let Inst{11} = idx{2};
7466 let Inst{21} = idx{1};
7467 let Inst{20} = idx{0};
7468 }
7469
7470 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc,
7471 V128, V64,
7472 V128, VectorIndexS,
7473 asm, ".2d", ".2d", ".2s", ".s",
7474 [(set (v2i64 V128:$dst),
7475 (OpNode (v2i64 V128:$Rd), (v2i32 V64:$Rn),
7476 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
7477 bits<2> idx;
7478 let Inst{11} = idx{1};
7479 let Inst{21} = idx{0};
7480 }
7481
7482 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc,
7483 V128, V128,
7484 V128, VectorIndexS,
7485 asm#"2", ".2d", ".2d", ".4s", ".s",
7486 [(set (v2i64 V128:$dst),
7487 (OpNode (v2i64 V128:$Rd),
7488 (extract_high_v4i32 V128:$Rn),
7489 (extract_high_v4i32 (AArch64duplane32 (v4i32 V128:$Rm),
7490 VectorIndexS:$idx))))]> {
7491 bits<2> idx;
7492 let Inst{11} = idx{1};
7493 let Inst{21} = idx{0};
7494 }
7495 }
7496}
7497
7498//----------------------------------------------------------------------------
7499// AdvSIMD scalar shift by immediate
7500//----------------------------------------------------------------------------
7501
7502let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
7503class BaseSIMDScalarShift<bit U, bits<5> opc, bits<7> fixed_imm,
7504 RegisterClass regtype1, RegisterClass regtype2,
7505 Operand immtype, string asm, list<dag> pattern>
7506 : I<(outs regtype1:$Rd), (ins regtype2:$Rn, immtype:$imm),
7507 asm, "\t$Rd, $Rn, $imm", "", pattern>,
7508 Sched<[WriteV]> {
7509 bits<5> Rd;
7510 bits<5> Rn;
7511 bits<7> imm;
7512 let Inst{31-30} = 0b01;
7513 let Inst{29} = U;
7514 let Inst{28-23} = 0b111110;
7515 let Inst{22-16} = fixed_imm;
7516 let Inst{15-11} = opc;
7517 let Inst{10} = 1;
7518 let Inst{9-5} = Rn;
7519 let Inst{4-0} = Rd;
7520}
7521
7522let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
7523class BaseSIMDScalarShiftTied<bit U, bits<5> opc, bits<7> fixed_imm,
7524 RegisterClass regtype1, RegisterClass regtype2,
7525 Operand immtype, string asm, list<dag> pattern>
7526 : I<(outs regtype1:$dst), (ins regtype1:$Rd, regtype2:$Rn, immtype:$imm),
7527 asm, "\t$Rd, $Rn, $imm", "$Rd = $dst", pattern>,
7528 Sched<[WriteV]> {
7529 bits<5> Rd;
7530 bits<5> Rn;
7531 bits<7> imm;
7532 let Inst{31-30} = 0b01;
7533 let Inst{29} = U;
7534 let Inst{28-23} = 0b111110;
7535 let Inst{22-16} = fixed_imm;
7536 let Inst{15-11} = opc;
7537 let Inst{10} = 1;
7538 let Inst{9-5} = Rn;
7539 let Inst{4-0} = Rd;
7540}
7541
7542
Oliver Stannarde4c3d212015-12-08 12:16:10 +00007543multiclass SIMDFPScalarRShift<bit U, bits<5> opc, string asm> {
7544 let Predicates = [HasNEON, HasFullFP16] in {
7545 def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?},
7546 FPR16, FPR16, vecshiftR16, asm, []> {
7547 let Inst{19-16} = imm{3-0};
7548 }
7549 } // Predicates = [HasNEON, HasFullFP16]
Tim Northover3b0846e2014-05-24 12:50:23 +00007550 def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?},
7551 FPR32, FPR32, vecshiftR32, asm, []> {
7552 let Inst{20-16} = imm{4-0};
7553 }
7554
7555 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?},
7556 FPR64, FPR64, vecshiftR64, asm, []> {
7557 let Inst{21-16} = imm{5-0};
7558 }
7559}
7560
7561multiclass SIMDScalarRShiftD<bit U, bits<5> opc, string asm,
7562 SDPatternOperator OpNode> {
7563 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?},
7564 FPR64, FPR64, vecshiftR64, asm,
7565 [(set (i64 FPR64:$Rd),
7566 (OpNode (i64 FPR64:$Rn), (i32 vecshiftR64:$imm)))]> {
7567 let Inst{21-16} = imm{5-0};
7568 }
7569
7570 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rn), (i32 vecshiftR64:$imm))),
7571 (!cast<Instruction>(NAME # "d") FPR64:$Rn, vecshiftR64:$imm)>;
7572}
7573
7574multiclass SIMDScalarRShiftDTied<bit U, bits<5> opc, string asm,
7575 SDPatternOperator OpNode = null_frag> {
7576 def d : BaseSIMDScalarShiftTied<U, opc, {1,?,?,?,?,?,?},
7577 FPR64, FPR64, vecshiftR64, asm,
7578 [(set (i64 FPR64:$dst), (OpNode (i64 FPR64:$Rd), (i64 FPR64:$Rn),
7579 (i32 vecshiftR64:$imm)))]> {
7580 let Inst{21-16} = imm{5-0};
7581 }
7582
7583 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rd), (v1i64 FPR64:$Rn),
7584 (i32 vecshiftR64:$imm))),
7585 (!cast<Instruction>(NAME # "d") FPR64:$Rd, FPR64:$Rn,
7586 vecshiftR64:$imm)>;
7587}
7588
7589multiclass SIMDScalarLShiftD<bit U, bits<5> opc, string asm,
7590 SDPatternOperator OpNode> {
7591 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?},
7592 FPR64, FPR64, vecshiftL64, asm,
7593 [(set (v1i64 FPR64:$Rd),
7594 (OpNode (v1i64 FPR64:$Rn), (i32 vecshiftL64:$imm)))]> {
7595 let Inst{21-16} = imm{5-0};
7596 }
7597}
7598
7599let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
7600multiclass SIMDScalarLShiftDTied<bit U, bits<5> opc, string asm> {
7601 def d : BaseSIMDScalarShiftTied<U, opc, {1,?,?,?,?,?,?},
7602 FPR64, FPR64, vecshiftL64, asm, []> {
7603 let Inst{21-16} = imm{5-0};
7604 }
7605}
7606
7607let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
7608multiclass SIMDScalarRShiftBHS<bit U, bits<5> opc, string asm,
7609 SDPatternOperator OpNode = null_frag> {
7610 def b : BaseSIMDScalarShift<U, opc, {0,0,0,1,?,?,?},
7611 FPR8, FPR16, vecshiftR8, asm, []> {
7612 let Inst{18-16} = imm{2-0};
7613 }
7614
7615 def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?},
7616 FPR16, FPR32, vecshiftR16, asm, []> {
7617 let Inst{19-16} = imm{3-0};
7618 }
7619
7620 def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?},
7621 FPR32, FPR64, vecshiftR32, asm,
7622 [(set (i32 FPR32:$Rd), (OpNode (i64 FPR64:$Rn), vecshiftR32:$imm))]> {
7623 let Inst{20-16} = imm{4-0};
7624 }
7625}
7626
7627multiclass SIMDScalarLShiftBHSD<bit U, bits<5> opc, string asm,
7628 SDPatternOperator OpNode> {
7629 def b : BaseSIMDScalarShift<U, opc, {0,0,0,1,?,?,?},
7630 FPR8, FPR8, vecshiftL8, asm, []> {
7631 let Inst{18-16} = imm{2-0};
7632 }
7633
7634 def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?},
7635 FPR16, FPR16, vecshiftL16, asm, []> {
7636 let Inst{19-16} = imm{3-0};
7637 }
7638
7639 def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?},
7640 FPR32, FPR32, vecshiftL32, asm,
7641 [(set (i32 FPR32:$Rd), (OpNode (i32 FPR32:$Rn), (i32 vecshiftL32:$imm)))]> {
7642 let Inst{20-16} = imm{4-0};
7643 }
7644
7645 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?},
7646 FPR64, FPR64, vecshiftL64, asm,
7647 [(set (i64 FPR64:$Rd), (OpNode (i64 FPR64:$Rn), (i32 vecshiftL64:$imm)))]> {
7648 let Inst{21-16} = imm{5-0};
7649 }
7650
7651 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rn), (i32 vecshiftL64:$imm))),
7652 (!cast<Instruction>(NAME # "d") FPR64:$Rn, vecshiftL64:$imm)>;
7653}
7654
7655multiclass SIMDScalarRShiftBHSD<bit U, bits<5> opc, string asm> {
7656 def b : BaseSIMDScalarShift<U, opc, {0,0,0,1,?,?,?},
7657 FPR8, FPR8, vecshiftR8, asm, []> {
7658 let Inst{18-16} = imm{2-0};
7659 }
7660
7661 def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?},
7662 FPR16, FPR16, vecshiftR16, asm, []> {
7663 let Inst{19-16} = imm{3-0};
7664 }
7665
7666 def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?},
7667 FPR32, FPR32, vecshiftR32, asm, []> {
7668 let Inst{20-16} = imm{4-0};
7669 }
7670
7671 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?},
7672 FPR64, FPR64, vecshiftR64, asm, []> {
7673 let Inst{21-16} = imm{5-0};
7674 }
7675}
7676
7677//----------------------------------------------------------------------------
7678// AdvSIMD vector x indexed element
7679//----------------------------------------------------------------------------
7680
7681let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
7682class BaseSIMDVectorShift<bit Q, bit U, bits<5> opc, bits<7> fixed_imm,
7683 RegisterOperand dst_reg, RegisterOperand src_reg,
7684 Operand immtype,
7685 string asm, string dst_kind, string src_kind,
7686 list<dag> pattern>
7687 : I<(outs dst_reg:$Rd), (ins src_reg:$Rn, immtype:$imm),
7688 asm, "{\t$Rd" # dst_kind # ", $Rn" # src_kind # ", $imm" #
7689 "|" # dst_kind # "\t$Rd, $Rn, $imm}", "", pattern>,
7690 Sched<[WriteV]> {
7691 bits<5> Rd;
7692 bits<5> Rn;
7693 let Inst{31} = 0;
7694 let Inst{30} = Q;
7695 let Inst{29} = U;
7696 let Inst{28-23} = 0b011110;
7697 let Inst{22-16} = fixed_imm;
7698 let Inst{15-11} = opc;
7699 let Inst{10} = 1;
7700 let Inst{9-5} = Rn;
7701 let Inst{4-0} = Rd;
7702}
7703
7704let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
7705class BaseSIMDVectorShiftTied<bit Q, bit U, bits<5> opc, bits<7> fixed_imm,
7706 RegisterOperand vectype1, RegisterOperand vectype2,
7707 Operand immtype,
7708 string asm, string dst_kind, string src_kind,
7709 list<dag> pattern>
7710 : I<(outs vectype1:$dst), (ins vectype1:$Rd, vectype2:$Rn, immtype:$imm),
7711 asm, "{\t$Rd" # dst_kind # ", $Rn" # src_kind # ", $imm" #
7712 "|" # dst_kind # "\t$Rd, $Rn, $imm}", "$Rd = $dst", pattern>,
7713 Sched<[WriteV]> {
7714 bits<5> Rd;
7715 bits<5> Rn;
7716 let Inst{31} = 0;
7717 let Inst{30} = Q;
7718 let Inst{29} = U;
7719 let Inst{28-23} = 0b011110;
7720 let Inst{22-16} = fixed_imm;
7721 let Inst{15-11} = opc;
7722 let Inst{10} = 1;
7723 let Inst{9-5} = Rn;
7724 let Inst{4-0} = Rd;
7725}
7726
7727multiclass SIMDVectorRShiftSD<bit U, bits<5> opc, string asm,
7728 Intrinsic OpNode> {
Oliver Stannarde4c3d212015-12-08 12:16:10 +00007729 let Predicates = [HasNEON, HasFullFP16] in {
7730 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?},
7731 V64, V64, vecshiftR16,
7732 asm, ".4h", ".4h",
7733 [(set (v4i16 V64:$Rd), (OpNode (v4f16 V64:$Rn), (i32 imm:$imm)))]> {
7734 bits<4> imm;
7735 let Inst{19-16} = imm;
7736 }
7737
7738 def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?},
7739 V128, V128, vecshiftR16,
7740 asm, ".8h", ".8h",
7741 [(set (v8i16 V128:$Rd), (OpNode (v8f16 V128:$Rn), (i32 imm:$imm)))]> {
7742 bits<4> imm;
7743 let Inst{19-16} = imm;
7744 }
7745 } // Predicates = [HasNEON, HasFullFP16]
Tim Northover3b0846e2014-05-24 12:50:23 +00007746 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?},
7747 V64, V64, vecshiftR32,
7748 asm, ".2s", ".2s",
7749 [(set (v2i32 V64:$Rd), (OpNode (v2f32 V64:$Rn), (i32 imm:$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 (v4f32 V128:$Rn), (i32 imm:$imm)))]> {
7758 bits<5> imm;
7759 let Inst{20-16} = imm;
7760 }
7761
7762 def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?},
7763 V128, V128, vecshiftR64,
7764 asm, ".2d", ".2d",
7765 [(set (v2i64 V128:$Rd), (OpNode (v2f64 V128:$Rn), (i32 imm:$imm)))]> {
7766 bits<6> imm;
7767 let Inst{21-16} = imm;
7768 }
7769}
7770
Oliver Stannarde4c3d212015-12-08 12:16:10 +00007771multiclass SIMDVectorRShiftToFP<bit U, bits<5> opc, string asm,
Tim Northover3b0846e2014-05-24 12:50:23 +00007772 Intrinsic OpNode> {
Oliver Stannarde4c3d212015-12-08 12:16:10 +00007773 let Predicates = [HasNEON, HasFullFP16] in {
7774 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?},
7775 V64, V64, vecshiftR16,
7776 asm, ".4h", ".4h",
7777 [(set (v4f16 V64:$Rd), (OpNode (v4i16 V64:$Rn), (i32 imm:$imm)))]> {
7778 bits<4> imm;
7779 let Inst{19-16} = imm;
7780 }
7781
7782 def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?},
7783 V128, V128, vecshiftR16,
7784 asm, ".8h", ".8h",
7785 [(set (v8f16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (i32 imm:$imm)))]> {
7786 bits<4> imm;
7787 let Inst{19-16} = imm;
7788 }
7789 } // Predicates = [HasNEON, HasFullFP16]
7790
Tim Northover3b0846e2014-05-24 12:50:23 +00007791 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?},
7792 V64, V64, vecshiftR32,
7793 asm, ".2s", ".2s",
7794 [(set (v2f32 V64:$Rd), (OpNode (v2i32 V64:$Rn), (i32 imm:$imm)))]> {
7795 bits<5> imm;
7796 let Inst{20-16} = imm;
7797 }
7798
7799 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?},
7800 V128, V128, vecshiftR32,
7801 asm, ".4s", ".4s",
7802 [(set (v4f32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (i32 imm:$imm)))]> {
7803 bits<5> imm;
7804 let Inst{20-16} = imm;
7805 }
7806
7807 def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?},
7808 V128, V128, vecshiftR64,
7809 asm, ".2d", ".2d",
7810 [(set (v2f64 V128:$Rd), (OpNode (v2i64 V128:$Rn), (i32 imm:$imm)))]> {
7811 bits<6> imm;
7812 let Inst{21-16} = imm;
7813 }
7814}
7815
7816multiclass SIMDVectorRShiftNarrowBHS<bit U, bits<5> opc, string asm,
7817 SDPatternOperator OpNode> {
7818 def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?},
7819 V64, V128, vecshiftR16Narrow,
7820 asm, ".8b", ".8h",
7821 [(set (v8i8 V64:$Rd), (OpNode (v8i16 V128:$Rn), vecshiftR16Narrow:$imm))]> {
7822 bits<3> imm;
7823 let Inst{18-16} = imm;
7824 }
7825
7826 def v16i8_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,0,1,?,?,?},
7827 V128, V128, vecshiftR16Narrow,
7828 asm#"2", ".16b", ".8h", []> {
7829 bits<3> imm;
7830 let Inst{18-16} = imm;
7831 let hasSideEffects = 0;
7832 }
7833
7834 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?},
7835 V64, V128, vecshiftR32Narrow,
7836 asm, ".4h", ".4s",
7837 [(set (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn), vecshiftR32Narrow:$imm))]> {
7838 bits<4> imm;
7839 let Inst{19-16} = imm;
7840 }
7841
7842 def v8i16_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,1,?,?,?,?},
7843 V128, V128, vecshiftR32Narrow,
7844 asm#"2", ".8h", ".4s", []> {
7845 bits<4> imm;
7846 let Inst{19-16} = imm;
7847 let hasSideEffects = 0;
7848 }
7849
7850 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?},
7851 V64, V128, vecshiftR64Narrow,
7852 asm, ".2s", ".2d",
7853 [(set (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn), vecshiftR64Narrow:$imm))]> {
7854 bits<5> imm;
7855 let Inst{20-16} = imm;
7856 }
7857
7858 def v4i32_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,1,?,?,?,?,?},
7859 V128, V128, vecshiftR64Narrow,
7860 asm#"2", ".4s", ".2d", []> {
7861 bits<5> imm;
7862 let Inst{20-16} = imm;
7863 let hasSideEffects = 0;
7864 }
7865
7866 // TableGen doesn't like patters w/ INSERT_SUBREG on the instructions
7867 // themselves, so put them here instead.
7868
7869 // Patterns involving what's effectively an insert high and a normal
7870 // intrinsic, represented by CONCAT_VECTORS.
7871 def : Pat<(concat_vectors (v8i8 V64:$Rd),(OpNode (v8i16 V128:$Rn),
7872 vecshiftR16Narrow:$imm)),
7873 (!cast<Instruction>(NAME # "v16i8_shift")
7874 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub),
7875 V128:$Rn, vecshiftR16Narrow:$imm)>;
7876 def : Pat<(concat_vectors (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn),
7877 vecshiftR32Narrow:$imm)),
7878 (!cast<Instruction>(NAME # "v8i16_shift")
7879 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub),
7880 V128:$Rn, vecshiftR32Narrow:$imm)>;
7881 def : Pat<(concat_vectors (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn),
7882 vecshiftR64Narrow:$imm)),
7883 (!cast<Instruction>(NAME # "v4i32_shift")
7884 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub),
7885 V128:$Rn, vecshiftR64Narrow:$imm)>;
7886}
7887
7888multiclass SIMDVectorLShiftBHSD<bit U, bits<5> opc, string asm,
7889 SDPatternOperator OpNode> {
7890 def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?},
7891 V64, V64, vecshiftL8,
7892 asm, ".8b", ".8b",
7893 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn),
7894 (i32 vecshiftL8:$imm)))]> {
7895 bits<3> imm;
7896 let Inst{18-16} = imm;
7897 }
7898
7899 def v16i8_shift : BaseSIMDVectorShift<1, U, opc, {0,0,0,1,?,?,?},
7900 V128, V128, vecshiftL8,
7901 asm, ".16b", ".16b",
7902 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn),
7903 (i32 vecshiftL8:$imm)))]> {
7904 bits<3> imm;
7905 let Inst{18-16} = imm;
7906 }
7907
7908 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?},
7909 V64, V64, vecshiftL16,
7910 asm, ".4h", ".4h",
7911 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn),
7912 (i32 vecshiftL16:$imm)))]> {
7913 bits<4> imm;
7914 let Inst{19-16} = imm;
7915 }
7916
7917 def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?},
7918 V128, V128, vecshiftL16,
7919 asm, ".8h", ".8h",
7920 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn),
7921 (i32 vecshiftL16:$imm)))]> {
7922 bits<4> imm;
7923 let Inst{19-16} = imm;
7924 }
7925
7926 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?},
7927 V64, V64, vecshiftL32,
7928 asm, ".2s", ".2s",
7929 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn),
7930 (i32 vecshiftL32:$imm)))]> {
7931 bits<5> imm;
7932 let Inst{20-16} = imm;
7933 }
7934
7935 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?},
7936 V128, V128, vecshiftL32,
7937 asm, ".4s", ".4s",
7938 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn),
7939 (i32 vecshiftL32:$imm)))]> {
7940 bits<5> imm;
7941 let Inst{20-16} = imm;
7942 }
7943
7944 def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?},
7945 V128, V128, vecshiftL64,
7946 asm, ".2d", ".2d",
7947 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn),
7948 (i32 vecshiftL64:$imm)))]> {
7949 bits<6> imm;
7950 let Inst{21-16} = imm;
7951 }
7952}
7953
7954multiclass SIMDVectorRShiftBHSD<bit U, bits<5> opc, string asm,
7955 SDPatternOperator OpNode> {
7956 def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?},
7957 V64, V64, vecshiftR8,
7958 asm, ".8b", ".8b",
7959 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn),
7960 (i32 vecshiftR8:$imm)))]> {
7961 bits<3> imm;
7962 let Inst{18-16} = imm;
7963 }
7964
7965 def v16i8_shift : BaseSIMDVectorShift<1, U, opc, {0,0,0,1,?,?,?},
7966 V128, V128, vecshiftR8,
7967 asm, ".16b", ".16b",
7968 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn),
7969 (i32 vecshiftR8:$imm)))]> {
7970 bits<3> imm;
7971 let Inst{18-16} = imm;
7972 }
7973
7974 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?},
7975 V64, V64, vecshiftR16,
7976 asm, ".4h", ".4h",
7977 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn),
7978 (i32 vecshiftR16:$imm)))]> {
7979 bits<4> imm;
7980 let Inst{19-16} = imm;
7981 }
7982
7983 def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?},
7984 V128, V128, vecshiftR16,
7985 asm, ".8h", ".8h",
7986 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn),
7987 (i32 vecshiftR16:$imm)))]> {
7988 bits<4> imm;
7989 let Inst{19-16} = imm;
7990 }
7991
7992 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?},
7993 V64, V64, vecshiftR32,
7994 asm, ".2s", ".2s",
7995 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn),
7996 (i32 vecshiftR32:$imm)))]> {
7997 bits<5> imm;
7998 let Inst{20-16} = imm;
7999 }
8000
8001 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?},
8002 V128, V128, vecshiftR32,
8003 asm, ".4s", ".4s",
8004 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn),
8005 (i32 vecshiftR32:$imm)))]> {
8006 bits<5> imm;
8007 let Inst{20-16} = imm;
8008 }
8009
8010 def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?},
8011 V128, V128, vecshiftR64,
8012 asm, ".2d", ".2d",
8013 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn),
8014 (i32 vecshiftR64:$imm)))]> {
8015 bits<6> imm;
8016 let Inst{21-16} = imm;
8017 }
8018}
8019
8020let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
8021multiclass SIMDVectorRShiftBHSDTied<bit U, bits<5> opc, string asm,
8022 SDPatternOperator OpNode = null_frag> {
8023 def v8i8_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,0,1,?,?,?},
8024 V64, V64, vecshiftR8, asm, ".8b", ".8b",
8025 [(set (v8i8 V64:$dst),
8026 (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn),
8027 (i32 vecshiftR8:$imm)))]> {
8028 bits<3> imm;
8029 let Inst{18-16} = imm;
8030 }
8031
8032 def v16i8_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,0,1,?,?,?},
8033 V128, V128, vecshiftR8, asm, ".16b", ".16b",
8034 [(set (v16i8 V128:$dst),
8035 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn),
8036 (i32 vecshiftR8:$imm)))]> {
8037 bits<3> imm;
8038 let Inst{18-16} = imm;
8039 }
8040
8041 def v4i16_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,1,?,?,?,?},
8042 V64, V64, vecshiftR16, asm, ".4h", ".4h",
8043 [(set (v4i16 V64:$dst),
8044 (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn),
8045 (i32 vecshiftR16:$imm)))]> {
8046 bits<4> imm;
8047 let Inst{19-16} = imm;
8048 }
8049
8050 def v8i16_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,1,?,?,?,?},
8051 V128, V128, vecshiftR16, asm, ".8h", ".8h",
8052 [(set (v8i16 V128:$dst),
8053 (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn),
8054 (i32 vecshiftR16:$imm)))]> {
8055 bits<4> imm;
8056 let Inst{19-16} = imm;
8057 }
8058
8059 def v2i32_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,1,?,?,?,?,?},
8060 V64, V64, vecshiftR32, asm, ".2s", ".2s",
8061 [(set (v2i32 V64:$dst),
8062 (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn),
8063 (i32 vecshiftR32:$imm)))]> {
8064 bits<5> imm;
8065 let Inst{20-16} = imm;
8066 }
8067
8068 def v4i32_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,1,?,?,?,?,?},
8069 V128, V128, vecshiftR32, asm, ".4s", ".4s",
8070 [(set (v4i32 V128:$dst),
8071 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn),
8072 (i32 vecshiftR32:$imm)))]> {
8073 bits<5> imm;
8074 let Inst{20-16} = imm;
8075 }
8076
8077 def v2i64_shift : BaseSIMDVectorShiftTied<1, U, opc, {1,?,?,?,?,?,?},
8078 V128, V128, vecshiftR64,
8079 asm, ".2d", ".2d", [(set (v2i64 V128:$dst),
8080 (OpNode (v2i64 V128:$Rd), (v2i64 V128:$Rn),
8081 (i32 vecshiftR64:$imm)))]> {
8082 bits<6> imm;
8083 let Inst{21-16} = imm;
8084 }
8085}
8086
8087multiclass SIMDVectorLShiftBHSDTied<bit U, bits<5> opc, string asm,
8088 SDPatternOperator OpNode = null_frag> {
8089 def v8i8_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,0,1,?,?,?},
8090 V64, V64, vecshiftL8,
8091 asm, ".8b", ".8b",
8092 [(set (v8i8 V64:$dst),
8093 (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn),
8094 (i32 vecshiftL8:$imm)))]> {
8095 bits<3> imm;
8096 let Inst{18-16} = imm;
8097 }
8098
8099 def v16i8_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,0,1,?,?,?},
8100 V128, V128, vecshiftL8,
8101 asm, ".16b", ".16b",
8102 [(set (v16i8 V128:$dst),
8103 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn),
8104 (i32 vecshiftL8:$imm)))]> {
8105 bits<3> imm;
8106 let Inst{18-16} = imm;
8107 }
8108
8109 def v4i16_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,1,?,?,?,?},
8110 V64, V64, vecshiftL16,
8111 asm, ".4h", ".4h",
8112 [(set (v4i16 V64:$dst),
8113 (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn),
8114 (i32 vecshiftL16:$imm)))]> {
8115 bits<4> imm;
8116 let Inst{19-16} = imm;
8117 }
8118
8119 def v8i16_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,1,?,?,?,?},
8120 V128, V128, vecshiftL16,
8121 asm, ".8h", ".8h",
8122 [(set (v8i16 V128:$dst),
8123 (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn),
8124 (i32 vecshiftL16:$imm)))]> {
8125 bits<4> imm;
8126 let Inst{19-16} = imm;
8127 }
8128
8129 def v2i32_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,1,?,?,?,?,?},
8130 V64, V64, vecshiftL32,
8131 asm, ".2s", ".2s",
8132 [(set (v2i32 V64:$dst),
8133 (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn),
8134 (i32 vecshiftL32:$imm)))]> {
8135 bits<5> imm;
8136 let Inst{20-16} = imm;
8137 }
8138
8139 def v4i32_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,1,?,?,?,?,?},
8140 V128, V128, vecshiftL32,
8141 asm, ".4s", ".4s",
8142 [(set (v4i32 V128:$dst),
8143 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn),
8144 (i32 vecshiftL32:$imm)))]> {
8145 bits<5> imm;
8146 let Inst{20-16} = imm;
8147 }
8148
8149 def v2i64_shift : BaseSIMDVectorShiftTied<1, U, opc, {1,?,?,?,?,?,?},
8150 V128, V128, vecshiftL64,
8151 asm, ".2d", ".2d",
8152 [(set (v2i64 V128:$dst),
8153 (OpNode (v2i64 V128:$Rd), (v2i64 V128:$Rn),
8154 (i32 vecshiftL64:$imm)))]> {
8155 bits<6> imm;
8156 let Inst{21-16} = imm;
8157 }
8158}
8159
8160multiclass SIMDVectorLShiftLongBHSD<bit U, bits<5> opc, string asm,
8161 SDPatternOperator OpNode> {
8162 def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?},
8163 V128, V64, vecshiftL8, asm, ".8h", ".8b",
8164 [(set (v8i16 V128:$Rd), (OpNode (v8i8 V64:$Rn), vecshiftL8:$imm))]> {
8165 bits<3> imm;
8166 let Inst{18-16} = imm;
8167 }
8168
8169 def v16i8_shift : BaseSIMDVectorShift<1, U, opc, {0,0,0,1,?,?,?},
8170 V128, V128, vecshiftL8,
8171 asm#"2", ".8h", ".16b",
8172 [(set (v8i16 V128:$Rd),
8173 (OpNode (extract_high_v16i8 V128:$Rn), vecshiftL8:$imm))]> {
8174 bits<3> imm;
8175 let Inst{18-16} = imm;
8176 }
8177
8178 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?},
8179 V128, V64, vecshiftL16, asm, ".4s", ".4h",
8180 [(set (v4i32 V128:$Rd), (OpNode (v4i16 V64:$Rn), vecshiftL16:$imm))]> {
8181 bits<4> imm;
8182 let Inst{19-16} = imm;
8183 }
8184
8185 def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?},
8186 V128, V128, vecshiftL16,
8187 asm#"2", ".4s", ".8h",
8188 [(set (v4i32 V128:$Rd),
8189 (OpNode (extract_high_v8i16 V128:$Rn), vecshiftL16:$imm))]> {
8190
8191 bits<4> imm;
8192 let Inst{19-16} = imm;
8193 }
8194
8195 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?},
8196 V128, V64, vecshiftL32, asm, ".2d", ".2s",
8197 [(set (v2i64 V128:$Rd), (OpNode (v2i32 V64:$Rn), vecshiftL32:$imm))]> {
8198 bits<5> imm;
8199 let Inst{20-16} = imm;
8200 }
8201
8202 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?},
8203 V128, V128, vecshiftL32,
8204 asm#"2", ".2d", ".4s",
8205 [(set (v2i64 V128:$Rd),
8206 (OpNode (extract_high_v4i32 V128:$Rn), vecshiftL32:$imm))]> {
8207 bits<5> imm;
8208 let Inst{20-16} = imm;
8209 }
8210}
8211
8212
8213//---
8214// Vector load/store
8215//---
8216// SIMD ldX/stX no-index memory references don't allow the optional
8217// ", #0" constant and handle post-indexing explicitly, so we use
8218// a more specialized parse method for them. Otherwise, it's the same as
8219// the general GPR64sp handling.
8220
8221class BaseSIMDLdSt<bit Q, bit L, bits<4> opcode, bits<2> size,
8222 string asm, dag oops, dag iops, list<dag> pattern>
8223 : I<oops, iops, asm, "\t$Vt, [$Rn]", "", pattern> {
8224 bits<5> Vt;
8225 bits<5> Rn;
8226 let Inst{31} = 0;
8227 let Inst{30} = Q;
8228 let Inst{29-23} = 0b0011000;
8229 let Inst{22} = L;
8230 let Inst{21-16} = 0b000000;
8231 let Inst{15-12} = opcode;
8232 let Inst{11-10} = size;
8233 let Inst{9-5} = Rn;
8234 let Inst{4-0} = Vt;
8235}
8236
8237class BaseSIMDLdStPost<bit Q, bit L, bits<4> opcode, bits<2> size,
8238 string asm, dag oops, dag iops>
8239 : I<oops, iops, asm, "\t$Vt, [$Rn], $Xm", "$Rn = $wback", []> {
8240 bits<5> Vt;
8241 bits<5> Rn;
8242 bits<5> Xm;
8243 let Inst{31} = 0;
8244 let Inst{30} = Q;
8245 let Inst{29-23} = 0b0011001;
8246 let Inst{22} = L;
8247 let Inst{21} = 0;
8248 let Inst{20-16} = Xm;
8249 let Inst{15-12} = opcode;
8250 let Inst{11-10} = size;
8251 let Inst{9-5} = Rn;
8252 let Inst{4-0} = Vt;
8253}
8254
8255// The immediate form of AdvSIMD post-indexed addressing is encoded with
8256// register post-index addressing from the zero register.
8257multiclass SIMDLdStAliases<string asm, string layout, string Count,
8258 int Offset, int Size> {
8259 // E.g. "ld1 { v0.8b, v1.8b }, [x1], #16"
8260 // "ld1\t$Vt, [$Rn], #16"
8261 // may get mapped to
8262 // (LD1Twov8b_POST VecListTwo8b:$Vt, GPR64sp:$Rn, XZR)
8263 def : InstAlias<asm # "\t$Vt, [$Rn], #" # Offset,
8264 (!cast<Instruction>(NAME # Count # "v" # layout # "_POST")
8265 GPR64sp:$Rn,
8266 !cast<RegisterOperand>("VecList" # Count # layout):$Vt,
8267 XZR), 1>;
8268
8269 // E.g. "ld1.8b { v0, v1 }, [x1], #16"
8270 // "ld1.8b\t$Vt, [$Rn], #16"
8271 // may get mapped to
8272 // (LD1Twov8b_POST VecListTwo64:$Vt, GPR64sp:$Rn, XZR)
8273 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], #" # Offset,
8274 (!cast<Instruction>(NAME # Count # "v" # layout # "_POST")
8275 GPR64sp:$Rn,
8276 !cast<RegisterOperand>("VecList" # Count # Size):$Vt,
8277 XZR), 0>;
8278
8279 // E.g. "ld1.8b { v0, v1 }, [x1]"
8280 // "ld1\t$Vt, [$Rn]"
8281 // may get mapped to
8282 // (LD1Twov8b VecListTwo64:$Vt, GPR64sp:$Rn)
8283 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn]",
8284 (!cast<Instruction>(NAME # Count # "v" # layout)
8285 !cast<RegisterOperand>("VecList" # Count # Size):$Vt,
8286 GPR64sp:$Rn), 0>;
8287
8288 // E.g. "ld1.8b { v0, v1 }, [x1], x2"
8289 // "ld1\t$Vt, [$Rn], $Xm"
8290 // may get mapped to
8291 // (LD1Twov8b_POST VecListTwo64:$Vt, GPR64sp:$Rn, GPR64pi8:$Xm)
8292 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], $Xm",
8293 (!cast<Instruction>(NAME # Count # "v" # layout # "_POST")
8294 GPR64sp:$Rn,
8295 !cast<RegisterOperand>("VecList" # Count # Size):$Vt,
8296 !cast<RegisterOperand>("GPR64pi" # Offset):$Xm), 0>;
8297}
8298
8299multiclass BaseSIMDLdN<string Count, string asm, string veclist, int Offset128,
8300 int Offset64, bits<4> opcode> {
8301 let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in {
8302 def v16b: BaseSIMDLdSt<1, 1, opcode, 0b00, asm,
8303 (outs !cast<RegisterOperand>(veclist # "16b"):$Vt),
8304 (ins GPR64sp:$Rn), []>;
8305 def v8h : BaseSIMDLdSt<1, 1, opcode, 0b01, asm,
8306 (outs !cast<RegisterOperand>(veclist # "8h"):$Vt),
8307 (ins GPR64sp:$Rn), []>;
8308 def v4s : BaseSIMDLdSt<1, 1, opcode, 0b10, asm,
8309 (outs !cast<RegisterOperand>(veclist # "4s"):$Vt),
8310 (ins GPR64sp:$Rn), []>;
8311 def v2d : BaseSIMDLdSt<1, 1, opcode, 0b11, asm,
8312 (outs !cast<RegisterOperand>(veclist # "2d"):$Vt),
8313 (ins GPR64sp:$Rn), []>;
8314 def v8b : BaseSIMDLdSt<0, 1, opcode, 0b00, asm,
8315 (outs !cast<RegisterOperand>(veclist # "8b"):$Vt),
8316 (ins GPR64sp:$Rn), []>;
8317 def v4h : BaseSIMDLdSt<0, 1, opcode, 0b01, asm,
8318 (outs !cast<RegisterOperand>(veclist # "4h"):$Vt),
8319 (ins GPR64sp:$Rn), []>;
8320 def v2s : BaseSIMDLdSt<0, 1, opcode, 0b10, asm,
8321 (outs !cast<RegisterOperand>(veclist # "2s"):$Vt),
8322 (ins GPR64sp:$Rn), []>;
8323
8324
8325 def v16b_POST: BaseSIMDLdStPost<1, 1, opcode, 0b00, asm,
8326 (outs GPR64sp:$wback,
8327 !cast<RegisterOperand>(veclist # "16b"):$Vt),
8328 (ins GPR64sp:$Rn,
8329 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
8330 def v8h_POST : BaseSIMDLdStPost<1, 1, opcode, 0b01, asm,
8331 (outs GPR64sp:$wback,
8332 !cast<RegisterOperand>(veclist # "8h"):$Vt),
8333 (ins GPR64sp:$Rn,
8334 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
8335 def v4s_POST : BaseSIMDLdStPost<1, 1, opcode, 0b10, asm,
8336 (outs GPR64sp:$wback,
8337 !cast<RegisterOperand>(veclist # "4s"):$Vt),
8338 (ins GPR64sp:$Rn,
8339 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
8340 def v2d_POST : BaseSIMDLdStPost<1, 1, opcode, 0b11, asm,
8341 (outs GPR64sp:$wback,
8342 !cast<RegisterOperand>(veclist # "2d"):$Vt),
8343 (ins GPR64sp:$Rn,
8344 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
8345 def v8b_POST : BaseSIMDLdStPost<0, 1, opcode, 0b00, asm,
8346 (outs GPR64sp:$wback,
8347 !cast<RegisterOperand>(veclist # "8b"):$Vt),
8348 (ins GPR64sp:$Rn,
8349 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
8350 def v4h_POST : BaseSIMDLdStPost<0, 1, opcode, 0b01, asm,
8351 (outs GPR64sp:$wback,
8352 !cast<RegisterOperand>(veclist # "4h"):$Vt),
8353 (ins GPR64sp:$Rn,
8354 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
8355 def v2s_POST : BaseSIMDLdStPost<0, 1, opcode, 0b10, asm,
8356 (outs GPR64sp:$wback,
8357 !cast<RegisterOperand>(veclist # "2s"):$Vt),
8358 (ins GPR64sp:$Rn,
8359 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
8360 }
8361
8362 defm : SIMDLdStAliases<asm, "16b", Count, Offset128, 128>;
8363 defm : SIMDLdStAliases<asm, "8h", Count, Offset128, 128>;
8364 defm : SIMDLdStAliases<asm, "4s", Count, Offset128, 128>;
8365 defm : SIMDLdStAliases<asm, "2d", Count, Offset128, 128>;
8366 defm : SIMDLdStAliases<asm, "8b", Count, Offset64, 64>;
8367 defm : SIMDLdStAliases<asm, "4h", Count, Offset64, 64>;
8368 defm : SIMDLdStAliases<asm, "2s", Count, Offset64, 64>;
8369}
8370
8371// Only ld1/st1 has a v1d version.
8372multiclass BaseSIMDStN<string Count, string asm, string veclist, int Offset128,
8373 int Offset64, bits<4> opcode> {
8374 let hasSideEffects = 0, mayStore = 1, mayLoad = 0 in {
8375 def v16b : BaseSIMDLdSt<1, 0, opcode, 0b00, asm, (outs),
8376 (ins !cast<RegisterOperand>(veclist # "16b"):$Vt,
8377 GPR64sp:$Rn), []>;
8378 def v8h : BaseSIMDLdSt<1, 0, opcode, 0b01, asm, (outs),
8379 (ins !cast<RegisterOperand>(veclist # "8h"):$Vt,
8380 GPR64sp:$Rn), []>;
8381 def v4s : BaseSIMDLdSt<1, 0, opcode, 0b10, asm, (outs),
8382 (ins !cast<RegisterOperand>(veclist # "4s"):$Vt,
8383 GPR64sp:$Rn), []>;
8384 def v2d : BaseSIMDLdSt<1, 0, opcode, 0b11, asm, (outs),
8385 (ins !cast<RegisterOperand>(veclist # "2d"):$Vt,
8386 GPR64sp:$Rn), []>;
8387 def v8b : BaseSIMDLdSt<0, 0, opcode, 0b00, asm, (outs),
8388 (ins !cast<RegisterOperand>(veclist # "8b"):$Vt,
8389 GPR64sp:$Rn), []>;
8390 def v4h : BaseSIMDLdSt<0, 0, opcode, 0b01, asm, (outs),
8391 (ins !cast<RegisterOperand>(veclist # "4h"):$Vt,
8392 GPR64sp:$Rn), []>;
8393 def v2s : BaseSIMDLdSt<0, 0, opcode, 0b10, asm, (outs),
8394 (ins !cast<RegisterOperand>(veclist # "2s"):$Vt,
8395 GPR64sp:$Rn), []>;
8396
8397 def v16b_POST : BaseSIMDLdStPost<1, 0, opcode, 0b00, asm,
8398 (outs GPR64sp:$wback),
8399 (ins !cast<RegisterOperand>(veclist # "16b"):$Vt,
8400 GPR64sp:$Rn,
8401 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
8402 def v8h_POST : BaseSIMDLdStPost<1, 0, opcode, 0b01, asm,
8403 (outs GPR64sp:$wback),
8404 (ins !cast<RegisterOperand>(veclist # "8h"):$Vt,
8405 GPR64sp:$Rn,
8406 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
8407 def v4s_POST : BaseSIMDLdStPost<1, 0, opcode, 0b10, asm,
8408 (outs GPR64sp:$wback),
8409 (ins !cast<RegisterOperand>(veclist # "4s"):$Vt,
8410 GPR64sp:$Rn,
8411 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
8412 def v2d_POST : BaseSIMDLdStPost<1, 0, opcode, 0b11, asm,
8413 (outs GPR64sp:$wback),
8414 (ins !cast<RegisterOperand>(veclist # "2d"):$Vt,
8415 GPR64sp:$Rn,
8416 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
8417 def v8b_POST : BaseSIMDLdStPost<0, 0, opcode, 0b00, asm,
8418 (outs GPR64sp:$wback),
8419 (ins !cast<RegisterOperand>(veclist # "8b"):$Vt,
8420 GPR64sp:$Rn,
8421 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
8422 def v4h_POST : BaseSIMDLdStPost<0, 0, opcode, 0b01, asm,
8423 (outs GPR64sp:$wback),
8424 (ins !cast<RegisterOperand>(veclist # "4h"):$Vt,
8425 GPR64sp:$Rn,
8426 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
8427 def v2s_POST : BaseSIMDLdStPost<0, 0, opcode, 0b10, asm,
8428 (outs GPR64sp:$wback),
8429 (ins !cast<RegisterOperand>(veclist # "2s"):$Vt,
8430 GPR64sp:$Rn,
8431 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
8432 }
8433
8434 defm : SIMDLdStAliases<asm, "16b", Count, Offset128, 128>;
8435 defm : SIMDLdStAliases<asm, "8h", Count, Offset128, 128>;
8436 defm : SIMDLdStAliases<asm, "4s", Count, Offset128, 128>;
8437 defm : SIMDLdStAliases<asm, "2d", Count, Offset128, 128>;
8438 defm : SIMDLdStAliases<asm, "8b", Count, Offset64, 64>;
8439 defm : SIMDLdStAliases<asm, "4h", Count, Offset64, 64>;
8440 defm : SIMDLdStAliases<asm, "2s", Count, Offset64, 64>;
8441}
8442
8443multiclass BaseSIMDLd1<string Count, string asm, string veclist,
8444 int Offset128, int Offset64, bits<4> opcode>
8445 : BaseSIMDLdN<Count, asm, veclist, Offset128, Offset64, opcode> {
8446
8447 // LD1 instructions have extra "1d" variants.
8448 let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in {
8449 def v1d : BaseSIMDLdSt<0, 1, opcode, 0b11, asm,
8450 (outs !cast<RegisterOperand>(veclist # "1d"):$Vt),
8451 (ins GPR64sp:$Rn), []>;
8452
8453 def v1d_POST : BaseSIMDLdStPost<0, 1, opcode, 0b11, asm,
8454 (outs GPR64sp:$wback,
8455 !cast<RegisterOperand>(veclist # "1d"):$Vt),
8456 (ins GPR64sp:$Rn,
8457 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
8458 }
8459
8460 defm : SIMDLdStAliases<asm, "1d", Count, Offset64, 64>;
8461}
8462
8463multiclass BaseSIMDSt1<string Count, string asm, string veclist,
8464 int Offset128, int Offset64, bits<4> opcode>
8465 : BaseSIMDStN<Count, asm, veclist, Offset128, Offset64, opcode> {
8466
8467 // ST1 instructions have extra "1d" variants.
8468 let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in {
8469 def v1d : BaseSIMDLdSt<0, 0, opcode, 0b11, asm, (outs),
8470 (ins !cast<RegisterOperand>(veclist # "1d"):$Vt,
8471 GPR64sp:$Rn), []>;
8472
8473 def v1d_POST : BaseSIMDLdStPost<0, 0, opcode, 0b11, asm,
8474 (outs GPR64sp:$wback),
8475 (ins !cast<RegisterOperand>(veclist # "1d"):$Vt,
8476 GPR64sp:$Rn,
8477 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
8478 }
8479
8480 defm : SIMDLdStAliases<asm, "1d", Count, Offset64, 64>;
8481}
8482
8483multiclass SIMDLd1Multiple<string asm> {
8484 defm One : BaseSIMDLd1<"One", asm, "VecListOne", 16, 8, 0b0111>;
8485 defm Two : BaseSIMDLd1<"Two", asm, "VecListTwo", 32, 16, 0b1010>;
8486 defm Three : BaseSIMDLd1<"Three", asm, "VecListThree", 48, 24, 0b0110>;
8487 defm Four : BaseSIMDLd1<"Four", asm, "VecListFour", 64, 32, 0b0010>;
8488}
8489
8490multiclass SIMDSt1Multiple<string asm> {
8491 defm One : BaseSIMDSt1<"One", asm, "VecListOne", 16, 8, 0b0111>;
8492 defm Two : BaseSIMDSt1<"Two", asm, "VecListTwo", 32, 16, 0b1010>;
8493 defm Three : BaseSIMDSt1<"Three", asm, "VecListThree", 48, 24, 0b0110>;
8494 defm Four : BaseSIMDSt1<"Four", asm, "VecListFour", 64, 32, 0b0010>;
8495}
8496
8497multiclass SIMDLd2Multiple<string asm> {
8498 defm Two : BaseSIMDLdN<"Two", asm, "VecListTwo", 32, 16, 0b1000>;
8499}
8500
8501multiclass SIMDSt2Multiple<string asm> {
8502 defm Two : BaseSIMDStN<"Two", asm, "VecListTwo", 32, 16, 0b1000>;
8503}
8504
8505multiclass SIMDLd3Multiple<string asm> {
8506 defm Three : BaseSIMDLdN<"Three", asm, "VecListThree", 48, 24, 0b0100>;
8507}
8508
8509multiclass SIMDSt3Multiple<string asm> {
8510 defm Three : BaseSIMDStN<"Three", asm, "VecListThree", 48, 24, 0b0100>;
8511}
8512
8513multiclass SIMDLd4Multiple<string asm> {
8514 defm Four : BaseSIMDLdN<"Four", asm, "VecListFour", 64, 32, 0b0000>;
8515}
8516
8517multiclass SIMDSt4Multiple<string asm> {
8518 defm Four : BaseSIMDStN<"Four", asm, "VecListFour", 64, 32, 0b0000>;
8519}
8520
8521//---
8522// AdvSIMD Load/store single-element
8523//---
8524
8525class BaseSIMDLdStSingle<bit L, bit R, bits<3> opcode,
8526 string asm, string operands, string cst,
8527 dag oops, dag iops, list<dag> pattern>
8528 : I<oops, iops, asm, operands, cst, pattern> {
8529 bits<5> Vt;
8530 bits<5> Rn;
8531 let Inst{31} = 0;
8532 let Inst{29-24} = 0b001101;
8533 let Inst{22} = L;
8534 let Inst{21} = R;
8535 let Inst{15-13} = opcode;
8536 let Inst{9-5} = Rn;
8537 let Inst{4-0} = Vt;
8538}
8539
8540class BaseSIMDLdStSingleTied<bit L, bit R, bits<3> opcode,
8541 string asm, string operands, string cst,
8542 dag oops, dag iops, list<dag> pattern>
8543 : I<oops, iops, asm, operands, "$Vt = $dst," # cst, pattern> {
8544 bits<5> Vt;
8545 bits<5> Rn;
8546 let Inst{31} = 0;
8547 let Inst{29-24} = 0b001101;
8548 let Inst{22} = L;
8549 let Inst{21} = R;
8550 let Inst{15-13} = opcode;
8551 let Inst{9-5} = Rn;
8552 let Inst{4-0} = Vt;
8553}
8554
8555
8556let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
8557class BaseSIMDLdR<bit Q, bit R, bits<3> opcode, bit S, bits<2> size, string asm,
8558 Operand listtype>
8559 : BaseSIMDLdStSingle<1, R, opcode, asm, "\t$Vt, [$Rn]", "",
8560 (outs listtype:$Vt), (ins GPR64sp:$Rn),
8561 []> {
8562 let Inst{30} = Q;
8563 let Inst{23} = 0;
8564 let Inst{20-16} = 0b00000;
8565 let Inst{12} = S;
8566 let Inst{11-10} = size;
8567}
8568let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
8569class BaseSIMDLdRPost<bit Q, bit R, bits<3> opcode, bit S, bits<2> size,
8570 string asm, Operand listtype, Operand GPR64pi>
8571 : BaseSIMDLdStSingle<1, R, opcode, asm, "\t$Vt, [$Rn], $Xm",
8572 "$Rn = $wback",
8573 (outs GPR64sp:$wback, listtype:$Vt),
8574 (ins GPR64sp:$Rn, GPR64pi:$Xm), []> {
8575 bits<5> Xm;
8576 let Inst{30} = Q;
8577 let Inst{23} = 1;
8578 let Inst{20-16} = Xm;
8579 let Inst{12} = S;
8580 let Inst{11-10} = size;
8581}
8582
8583multiclass SIMDLdrAliases<string asm, string layout, string Count,
8584 int Offset, int Size> {
8585 // E.g. "ld1r { v0.8b }, [x1], #1"
8586 // "ld1r.8b\t$Vt, [$Rn], #1"
8587 // may get mapped to
8588 // (LD1Rv8b_POST VecListOne8b:$Vt, GPR64sp:$Rn, XZR)
8589 def : InstAlias<asm # "\t$Vt, [$Rn], #" # Offset,
8590 (!cast<Instruction>(NAME # "v" # layout # "_POST")
8591 GPR64sp:$Rn,
8592 !cast<RegisterOperand>("VecList" # Count # layout):$Vt,
8593 XZR), 1>;
8594
8595 // E.g. "ld1r.8b { v0 }, [x1], #1"
8596 // "ld1r.8b\t$Vt, [$Rn], #1"
8597 // may get mapped to
8598 // (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, XZR)
8599 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], #" # Offset,
8600 (!cast<Instruction>(NAME # "v" # layout # "_POST")
8601 GPR64sp:$Rn,
8602 !cast<RegisterOperand>("VecList" # Count # Size):$Vt,
8603 XZR), 0>;
8604
8605 // E.g. "ld1r.8b { v0 }, [x1]"
8606 // "ld1r.8b\t$Vt, [$Rn]"
8607 // may get mapped to
8608 // (LD1Rv8b VecListOne64:$Vt, GPR64sp:$Rn)
8609 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn]",
8610 (!cast<Instruction>(NAME # "v" # layout)
8611 !cast<RegisterOperand>("VecList" # Count # Size):$Vt,
8612 GPR64sp:$Rn), 0>;
8613
8614 // E.g. "ld1r.8b { v0 }, [x1], x2"
8615 // "ld1r.8b\t$Vt, [$Rn], $Xm"
8616 // may get mapped to
8617 // (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, GPR64pi1:$Xm)
8618 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], $Xm",
8619 (!cast<Instruction>(NAME # "v" # layout # "_POST")
8620 GPR64sp:$Rn,
8621 !cast<RegisterOperand>("VecList" # Count # Size):$Vt,
8622 !cast<RegisterOperand>("GPR64pi" # Offset):$Xm), 0>;
8623}
8624
8625multiclass SIMDLdR<bit R, bits<3> opcode, bit S, string asm, string Count,
8626 int Offset1, int Offset2, int Offset4, int Offset8> {
8627 def v8b : BaseSIMDLdR<0, R, opcode, S, 0b00, asm,
8628 !cast<Operand>("VecList" # Count # "8b")>;
8629 def v16b: BaseSIMDLdR<1, R, opcode, S, 0b00, asm,
8630 !cast<Operand>("VecList" # Count #"16b")>;
8631 def v4h : BaseSIMDLdR<0, R, opcode, S, 0b01, asm,
8632 !cast<Operand>("VecList" # Count #"4h")>;
8633 def v8h : BaseSIMDLdR<1, R, opcode, S, 0b01, asm,
8634 !cast<Operand>("VecList" # Count #"8h")>;
8635 def v2s : BaseSIMDLdR<0, R, opcode, S, 0b10, asm,
8636 !cast<Operand>("VecList" # Count #"2s")>;
8637 def v4s : BaseSIMDLdR<1, R, opcode, S, 0b10, asm,
8638 !cast<Operand>("VecList" # Count #"4s")>;
8639 def v1d : BaseSIMDLdR<0, R, opcode, S, 0b11, asm,
8640 !cast<Operand>("VecList" # Count #"1d")>;
8641 def v2d : BaseSIMDLdR<1, R, opcode, S, 0b11, asm,
8642 !cast<Operand>("VecList" # Count #"2d")>;
8643
8644 def v8b_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b00, asm,
8645 !cast<Operand>("VecList" # Count # "8b"),
8646 !cast<Operand>("GPR64pi" # Offset1)>;
8647 def v16b_POST: BaseSIMDLdRPost<1, R, opcode, S, 0b00, asm,
8648 !cast<Operand>("VecList" # Count # "16b"),
8649 !cast<Operand>("GPR64pi" # Offset1)>;
8650 def v4h_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b01, asm,
8651 !cast<Operand>("VecList" # Count # "4h"),
8652 !cast<Operand>("GPR64pi" # Offset2)>;
8653 def v8h_POST : BaseSIMDLdRPost<1, R, opcode, S, 0b01, asm,
8654 !cast<Operand>("VecList" # Count # "8h"),
8655 !cast<Operand>("GPR64pi" # Offset2)>;
8656 def v2s_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b10, asm,
8657 !cast<Operand>("VecList" # Count # "2s"),
8658 !cast<Operand>("GPR64pi" # Offset4)>;
8659 def v4s_POST : BaseSIMDLdRPost<1, R, opcode, S, 0b10, asm,
8660 !cast<Operand>("VecList" # Count # "4s"),
8661 !cast<Operand>("GPR64pi" # Offset4)>;
8662 def v1d_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b11, asm,
8663 !cast<Operand>("VecList" # Count # "1d"),
8664 !cast<Operand>("GPR64pi" # Offset8)>;
8665 def v2d_POST : BaseSIMDLdRPost<1, R, opcode, S, 0b11, asm,
8666 !cast<Operand>("VecList" # Count # "2d"),
8667 !cast<Operand>("GPR64pi" # Offset8)>;
8668
8669 defm : SIMDLdrAliases<asm, "8b", Count, Offset1, 64>;
8670 defm : SIMDLdrAliases<asm, "16b", Count, Offset1, 128>;
8671 defm : SIMDLdrAliases<asm, "4h", Count, Offset2, 64>;
8672 defm : SIMDLdrAliases<asm, "8h", Count, Offset2, 128>;
8673 defm : SIMDLdrAliases<asm, "2s", Count, Offset4, 64>;
8674 defm : SIMDLdrAliases<asm, "4s", Count, Offset4, 128>;
8675 defm : SIMDLdrAliases<asm, "1d", Count, Offset8, 64>;
8676 defm : SIMDLdrAliases<asm, "2d", Count, Offset8, 128>;
8677}
8678
8679class SIMDLdStSingleB<bit L, bit R, bits<3> opcode, string asm,
8680 dag oops, dag iops, list<dag> pattern>
8681 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops,
8682 pattern> {
8683 // idx encoded in Q:S:size fields.
8684 bits<4> idx;
8685 let Inst{30} = idx{3};
8686 let Inst{23} = 0;
8687 let Inst{20-16} = 0b00000;
8688 let Inst{12} = idx{2};
8689 let Inst{11-10} = idx{1-0};
8690}
8691class SIMDLdStSingleBTied<bit L, bit R, bits<3> opcode, string asm,
8692 dag oops, dag iops, list<dag> pattern>
8693 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "",
8694 oops, iops, pattern> {
8695 // idx encoded in Q:S:size fields.
8696 bits<4> idx;
8697 let Inst{30} = idx{3};
8698 let Inst{23} = 0;
8699 let Inst{20-16} = 0b00000;
8700 let Inst{12} = idx{2};
8701 let Inst{11-10} = idx{1-0};
8702}
8703class SIMDLdStSingleBPost<bit L, bit R, bits<3> opcode, string asm,
8704 dag oops, dag iops>
8705 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
8706 "$Rn = $wback", oops, iops, []> {
8707 // idx encoded in Q:S:size fields.
8708 bits<4> idx;
8709 bits<5> Xm;
8710 let Inst{30} = idx{3};
8711 let Inst{23} = 1;
8712 let Inst{20-16} = Xm;
8713 let Inst{12} = idx{2};
8714 let Inst{11-10} = idx{1-0};
8715}
8716class SIMDLdStSingleBTiedPost<bit L, bit R, bits<3> opcode, string asm,
8717 dag oops, dag iops>
8718 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
8719 "$Rn = $wback", oops, iops, []> {
8720 // idx encoded in Q:S:size fields.
8721 bits<4> idx;
8722 bits<5> Xm;
8723 let Inst{30} = idx{3};
8724 let Inst{23} = 1;
8725 let Inst{20-16} = Xm;
8726 let Inst{12} = idx{2};
8727 let Inst{11-10} = idx{1-0};
8728}
8729
8730class SIMDLdStSingleH<bit L, bit R, bits<3> opcode, bit size, string asm,
8731 dag oops, dag iops, list<dag> pattern>
8732 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops,
8733 pattern> {
8734 // idx encoded in Q:S:size<1> fields.
8735 bits<3> idx;
8736 let Inst{30} = idx{2};
8737 let Inst{23} = 0;
8738 let Inst{20-16} = 0b00000;
8739 let Inst{12} = idx{1};
8740 let Inst{11} = idx{0};
8741 let Inst{10} = size;
8742}
8743class SIMDLdStSingleHTied<bit L, bit R, bits<3> opcode, bit size, string asm,
8744 dag oops, dag iops, list<dag> pattern>
8745 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "",
8746 oops, iops, pattern> {
8747 // idx encoded in Q:S:size<1> fields.
8748 bits<3> idx;
8749 let Inst{30} = idx{2};
8750 let Inst{23} = 0;
8751 let Inst{20-16} = 0b00000;
8752 let Inst{12} = idx{1};
8753 let Inst{11} = idx{0};
8754 let Inst{10} = size;
8755}
8756
8757class SIMDLdStSingleHPost<bit L, bit R, bits<3> opcode, bit size, string asm,
8758 dag oops, dag iops>
8759 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
8760 "$Rn = $wback", oops, iops, []> {
8761 // idx encoded in Q:S:size<1> fields.
8762 bits<3> idx;
8763 bits<5> Xm;
8764 let Inst{30} = idx{2};
8765 let Inst{23} = 1;
8766 let Inst{20-16} = Xm;
8767 let Inst{12} = idx{1};
8768 let Inst{11} = idx{0};
8769 let Inst{10} = size;
8770}
8771class SIMDLdStSingleHTiedPost<bit L, bit R, bits<3> opcode, bit size, string asm,
8772 dag oops, dag iops>
8773 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
8774 "$Rn = $wback", oops, iops, []> {
8775 // idx encoded in Q:S:size<1> fields.
8776 bits<3> idx;
8777 bits<5> Xm;
8778 let Inst{30} = idx{2};
8779 let Inst{23} = 1;
8780 let Inst{20-16} = Xm;
8781 let Inst{12} = idx{1};
8782 let Inst{11} = idx{0};
8783 let Inst{10} = size;
8784}
8785class SIMDLdStSingleS<bit L, bit R, bits<3> opcode, bits<2> size, string asm,
8786 dag oops, dag iops, list<dag> pattern>
8787 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops,
8788 pattern> {
8789 // idx encoded in Q:S fields.
8790 bits<2> idx;
8791 let Inst{30} = idx{1};
8792 let Inst{23} = 0;
8793 let Inst{20-16} = 0b00000;
8794 let Inst{12} = idx{0};
8795 let Inst{11-10} = size;
8796}
8797class SIMDLdStSingleSTied<bit L, bit R, bits<3> opcode, bits<2> size, string asm,
8798 dag oops, dag iops, list<dag> pattern>
8799 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "",
8800 oops, iops, pattern> {
8801 // idx encoded in Q:S fields.
8802 bits<2> idx;
8803 let Inst{30} = idx{1};
8804 let Inst{23} = 0;
8805 let Inst{20-16} = 0b00000;
8806 let Inst{12} = idx{0};
8807 let Inst{11-10} = size;
8808}
8809class SIMDLdStSingleSPost<bit L, bit R, bits<3> opcode, bits<2> size,
8810 string asm, dag oops, dag iops>
8811 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
8812 "$Rn = $wback", oops, iops, []> {
8813 // idx encoded in Q:S fields.
8814 bits<2> idx;
8815 bits<5> Xm;
8816 let Inst{30} = idx{1};
8817 let Inst{23} = 1;
8818 let Inst{20-16} = Xm;
8819 let Inst{12} = idx{0};
8820 let Inst{11-10} = size;
8821}
8822class SIMDLdStSingleSTiedPost<bit L, bit R, bits<3> opcode, bits<2> size,
8823 string asm, dag oops, dag iops>
8824 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
8825 "$Rn = $wback", oops, iops, []> {
8826 // idx encoded in Q:S fields.
8827 bits<2> idx;
8828 bits<5> Xm;
8829 let Inst{30} = idx{1};
8830 let Inst{23} = 1;
8831 let Inst{20-16} = Xm;
8832 let Inst{12} = idx{0};
8833 let Inst{11-10} = size;
8834}
8835class SIMDLdStSingleD<bit L, bit R, bits<3> opcode, bits<2> size, string asm,
8836 dag oops, dag iops, list<dag> pattern>
8837 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops,
8838 pattern> {
8839 // idx encoded in Q field.
8840 bits<1> idx;
8841 let Inst{30} = idx;
8842 let Inst{23} = 0;
8843 let Inst{20-16} = 0b00000;
8844 let Inst{12} = 0;
8845 let Inst{11-10} = size;
8846}
8847class SIMDLdStSingleDTied<bit L, bit R, bits<3> opcode, bits<2> size, string asm,
8848 dag oops, dag iops, list<dag> pattern>
8849 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "",
8850 oops, iops, pattern> {
8851 // idx encoded in Q field.
8852 bits<1> idx;
8853 let Inst{30} = idx;
8854 let Inst{23} = 0;
8855 let Inst{20-16} = 0b00000;
8856 let Inst{12} = 0;
8857 let Inst{11-10} = size;
8858}
8859class SIMDLdStSingleDPost<bit L, bit R, bits<3> opcode, bits<2> size,
8860 string asm, dag oops, dag iops>
8861 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
8862 "$Rn = $wback", oops, iops, []> {
8863 // idx encoded in Q field.
8864 bits<1> idx;
8865 bits<5> Xm;
8866 let Inst{30} = idx;
8867 let Inst{23} = 1;
8868 let Inst{20-16} = Xm;
8869 let Inst{12} = 0;
8870 let Inst{11-10} = size;
8871}
8872class SIMDLdStSingleDTiedPost<bit L, bit R, bits<3> opcode, bits<2> size,
8873 string asm, dag oops, dag iops>
8874 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
8875 "$Rn = $wback", oops, iops, []> {
8876 // idx encoded in Q field.
8877 bits<1> idx;
8878 bits<5> Xm;
8879 let Inst{30} = idx;
8880 let Inst{23} = 1;
8881 let Inst{20-16} = Xm;
8882 let Inst{12} = 0;
8883 let Inst{11-10} = size;
8884}
8885
8886let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
8887multiclass SIMDLdSingleBTied<bit R, bits<3> opcode, string asm,
8888 RegisterOperand listtype,
8889 RegisterOperand GPR64pi> {
8890 def i8 : SIMDLdStSingleBTied<1, R, opcode, asm,
8891 (outs listtype:$dst),
8892 (ins listtype:$Vt, VectorIndexB:$idx,
8893 GPR64sp:$Rn), []>;
8894
8895 def i8_POST : SIMDLdStSingleBTiedPost<1, R, opcode, asm,
8896 (outs GPR64sp:$wback, listtype:$dst),
8897 (ins listtype:$Vt, VectorIndexB:$idx,
8898 GPR64sp:$Rn, GPR64pi:$Xm)>;
8899}
8900let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
8901multiclass SIMDLdSingleHTied<bit R, bits<3> opcode, bit size, string asm,
8902 RegisterOperand listtype,
8903 RegisterOperand GPR64pi> {
8904 def i16 : SIMDLdStSingleHTied<1, R, opcode, size, asm,
8905 (outs listtype:$dst),
8906 (ins listtype:$Vt, VectorIndexH:$idx,
8907 GPR64sp:$Rn), []>;
8908
8909 def i16_POST : SIMDLdStSingleHTiedPost<1, R, opcode, size, asm,
8910 (outs GPR64sp:$wback, listtype:$dst),
8911 (ins listtype:$Vt, VectorIndexH:$idx,
8912 GPR64sp:$Rn, GPR64pi:$Xm)>;
8913}
8914let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
8915multiclass SIMDLdSingleSTied<bit R, bits<3> opcode, bits<2> size,string asm,
8916 RegisterOperand listtype,
8917 RegisterOperand GPR64pi> {
8918 def i32 : SIMDLdStSingleSTied<1, R, opcode, size, asm,
8919 (outs listtype:$dst),
8920 (ins listtype:$Vt, VectorIndexS:$idx,
8921 GPR64sp:$Rn), []>;
8922
8923 def i32_POST : SIMDLdStSingleSTiedPost<1, R, opcode, size, asm,
8924 (outs GPR64sp:$wback, listtype:$dst),
8925 (ins listtype:$Vt, VectorIndexS:$idx,
8926 GPR64sp:$Rn, GPR64pi:$Xm)>;
8927}
8928let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
8929multiclass SIMDLdSingleDTied<bit R, bits<3> opcode, bits<2> size, string asm,
8930 RegisterOperand listtype, RegisterOperand GPR64pi> {
8931 def i64 : SIMDLdStSingleDTied<1, R, opcode, size, asm,
8932 (outs listtype:$dst),
8933 (ins listtype:$Vt, VectorIndexD:$idx,
8934 GPR64sp:$Rn), []>;
8935
8936 def i64_POST : SIMDLdStSingleDTiedPost<1, R, opcode, size, asm,
8937 (outs GPR64sp:$wback, listtype:$dst),
8938 (ins listtype:$Vt, VectorIndexD:$idx,
8939 GPR64sp:$Rn, GPR64pi:$Xm)>;
8940}
8941let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
8942multiclass SIMDStSingleB<bit R, bits<3> opcode, string asm,
8943 RegisterOperand listtype, RegisterOperand GPR64pi> {
8944 def i8 : SIMDLdStSingleB<0, R, opcode, asm,
8945 (outs), (ins listtype:$Vt, VectorIndexB:$idx,
8946 GPR64sp:$Rn), []>;
8947
8948 def i8_POST : SIMDLdStSingleBPost<0, R, opcode, asm,
8949 (outs GPR64sp:$wback),
8950 (ins listtype:$Vt, VectorIndexB:$idx,
8951 GPR64sp:$Rn, GPR64pi:$Xm)>;
8952}
8953let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
8954multiclass SIMDStSingleH<bit R, bits<3> opcode, bit size, string asm,
8955 RegisterOperand listtype, RegisterOperand GPR64pi> {
8956 def i16 : SIMDLdStSingleH<0, R, opcode, size, asm,
8957 (outs), (ins listtype:$Vt, VectorIndexH:$idx,
8958 GPR64sp:$Rn), []>;
8959
8960 def i16_POST : SIMDLdStSingleHPost<0, R, opcode, size, asm,
8961 (outs GPR64sp:$wback),
8962 (ins listtype:$Vt, VectorIndexH:$idx,
8963 GPR64sp:$Rn, GPR64pi:$Xm)>;
8964}
8965let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
8966multiclass SIMDStSingleS<bit R, bits<3> opcode, bits<2> size,string asm,
8967 RegisterOperand listtype, RegisterOperand GPR64pi> {
8968 def i32 : SIMDLdStSingleS<0, R, opcode, size, asm,
8969 (outs), (ins listtype:$Vt, VectorIndexS:$idx,
8970 GPR64sp:$Rn), []>;
8971
8972 def i32_POST : SIMDLdStSingleSPost<0, R, opcode, size, asm,
8973 (outs GPR64sp:$wback),
8974 (ins listtype:$Vt, VectorIndexS:$idx,
8975 GPR64sp:$Rn, GPR64pi:$Xm)>;
8976}
8977let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
8978multiclass SIMDStSingleD<bit R, bits<3> opcode, bits<2> size, string asm,
8979 RegisterOperand listtype, RegisterOperand GPR64pi> {
8980 def i64 : SIMDLdStSingleD<0, R, opcode, size, asm,
8981 (outs), (ins listtype:$Vt, VectorIndexD:$idx,
8982 GPR64sp:$Rn), []>;
8983
8984 def i64_POST : SIMDLdStSingleDPost<0, R, opcode, size, asm,
8985 (outs GPR64sp:$wback),
8986 (ins listtype:$Vt, VectorIndexD:$idx,
8987 GPR64sp:$Rn, GPR64pi:$Xm)>;
8988}
8989
8990multiclass SIMDLdStSingleAliases<string asm, string layout, string Type,
8991 string Count, int Offset, Operand idxtype> {
8992 // E.g. "ld1 { v0.8b }[0], [x1], #1"
8993 // "ld1\t$Vt, [$Rn], #1"
8994 // may get mapped to
8995 // (LD1Rv8b_POST VecListOne8b:$Vt, GPR64sp:$Rn, XZR)
8996 def : InstAlias<asm # "\t$Vt$idx, [$Rn], #" # Offset,
8997 (!cast<Instruction>(NAME # Type # "_POST")
8998 GPR64sp:$Rn,
8999 !cast<RegisterOperand>("VecList" # Count # layout):$Vt,
9000 idxtype:$idx, XZR), 1>;
9001
9002 // E.g. "ld1.8b { v0 }[0], [x1], #1"
9003 // "ld1.8b\t$Vt, [$Rn], #1"
9004 // may get mapped to
9005 // (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, XZR)
9006 def : InstAlias<asm # "." # layout # "\t$Vt$idx, [$Rn], #" # Offset,
9007 (!cast<Instruction>(NAME # Type # "_POST")
9008 GPR64sp:$Rn,
9009 !cast<RegisterOperand>("VecList" # Count # "128"):$Vt,
9010 idxtype:$idx, XZR), 0>;
9011
9012 // E.g. "ld1.8b { v0 }[0], [x1]"
9013 // "ld1.8b\t$Vt, [$Rn]"
9014 // may get mapped to
9015 // (LD1Rv8b VecListOne64:$Vt, GPR64sp:$Rn)
9016 def : InstAlias<asm # "." # layout # "\t$Vt$idx, [$Rn]",
9017 (!cast<Instruction>(NAME # Type)
9018 !cast<RegisterOperand>("VecList" # Count # "128"):$Vt,
9019 idxtype:$idx, GPR64sp:$Rn), 0>;
9020
9021 // E.g. "ld1.8b { v0 }[0], [x1], x2"
9022 // "ld1.8b\t$Vt, [$Rn], $Xm"
9023 // may get mapped to
9024 // (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, GPR64pi1:$Xm)
9025 def : InstAlias<asm # "." # layout # "\t$Vt$idx, [$Rn], $Xm",
9026 (!cast<Instruction>(NAME # Type # "_POST")
9027 GPR64sp:$Rn,
9028 !cast<RegisterOperand>("VecList" # Count # "128"):$Vt,
9029 idxtype:$idx,
9030 !cast<RegisterOperand>("GPR64pi" # Offset):$Xm), 0>;
9031}
9032
9033multiclass SIMDLdSt1SingleAliases<string asm> {
9034 defm : SIMDLdStSingleAliases<asm, "b", "i8", "One", 1, VectorIndexB>;
9035 defm : SIMDLdStSingleAliases<asm, "h", "i16", "One", 2, VectorIndexH>;
9036 defm : SIMDLdStSingleAliases<asm, "s", "i32", "One", 4, VectorIndexS>;
9037 defm : SIMDLdStSingleAliases<asm, "d", "i64", "One", 8, VectorIndexD>;
9038}
9039
9040multiclass SIMDLdSt2SingleAliases<string asm> {
9041 defm : SIMDLdStSingleAliases<asm, "b", "i8", "Two", 2, VectorIndexB>;
9042 defm : SIMDLdStSingleAliases<asm, "h", "i16", "Two", 4, VectorIndexH>;
9043 defm : SIMDLdStSingleAliases<asm, "s", "i32", "Two", 8, VectorIndexS>;
9044 defm : SIMDLdStSingleAliases<asm, "d", "i64", "Two", 16, VectorIndexD>;
9045}
9046
9047multiclass SIMDLdSt3SingleAliases<string asm> {
9048 defm : SIMDLdStSingleAliases<asm, "b", "i8", "Three", 3, VectorIndexB>;
9049 defm : SIMDLdStSingleAliases<asm, "h", "i16", "Three", 6, VectorIndexH>;
9050 defm : SIMDLdStSingleAliases<asm, "s", "i32", "Three", 12, VectorIndexS>;
9051 defm : SIMDLdStSingleAliases<asm, "d", "i64", "Three", 24, VectorIndexD>;
9052}
9053
9054multiclass SIMDLdSt4SingleAliases<string asm> {
9055 defm : SIMDLdStSingleAliases<asm, "b", "i8", "Four", 4, VectorIndexB>;
9056 defm : SIMDLdStSingleAliases<asm, "h", "i16", "Four", 8, VectorIndexH>;
9057 defm : SIMDLdStSingleAliases<asm, "s", "i32", "Four", 16, VectorIndexS>;
9058 defm : SIMDLdStSingleAliases<asm, "d", "i64", "Four", 32, VectorIndexD>;
9059}
9060} // end of 'let Predicates = [HasNEON]'
9061
9062//----------------------------------------------------------------------------
Vladimir Sukharev297bf0e2015-03-31 13:15:48 +00009063// AdvSIMD v8.1 Rounding Double Multiply Add/Subtract
9064//----------------------------------------------------------------------------
9065
9066let Predicates = [HasNEON, HasV8_1a] in {
9067
9068class BaseSIMDThreeSameVectorTiedR0<bit Q, bit U, bits<2> size, bits<5> opcode,
9069 RegisterOperand regtype, string asm,
9070 string kind, list<dag> pattern>
Oliver Stannarde4c3d212015-12-08 12:16:10 +00009071 : BaseSIMDThreeSameVectorTied<Q, U, {size,0}, opcode, regtype, asm, kind,
Vladimir Sukharev297bf0e2015-03-31 13:15:48 +00009072 pattern> {
Vladimir Sukharev297bf0e2015-03-31 13:15:48 +00009073}
9074multiclass SIMDThreeSameVectorSQRDMLxHTiedHS<bit U, bits<5> opc, string asm,
9075 SDPatternOperator Accum> {
9076 def v4i16 : BaseSIMDThreeSameVectorTiedR0<0, U, 0b01, opc, V64, asm, ".4h",
9077 [(set (v4i16 V64:$dst),
9078 (Accum (v4i16 V64:$Rd),
9079 (v4i16 (int_aarch64_neon_sqrdmulh (v4i16 V64:$Rn),
9080 (v4i16 V64:$Rm)))))]>;
9081 def v8i16 : BaseSIMDThreeSameVectorTiedR0<1, U, 0b01, opc, V128, asm, ".8h",
9082 [(set (v8i16 V128:$dst),
9083 (Accum (v8i16 V128:$Rd),
9084 (v8i16 (int_aarch64_neon_sqrdmulh (v8i16 V128:$Rn),
9085 (v8i16 V128:$Rm)))))]>;
9086 def v2i32 : BaseSIMDThreeSameVectorTiedR0<0, U, 0b10, opc, V64, asm, ".2s",
9087 [(set (v2i32 V64:$dst),
9088 (Accum (v2i32 V64:$Rd),
9089 (v2i32 (int_aarch64_neon_sqrdmulh (v2i32 V64:$Rn),
9090 (v2i32 V64:$Rm)))))]>;
9091 def v4i32 : BaseSIMDThreeSameVectorTiedR0<1, U, 0b10, opc, V128, asm, ".4s",
9092 [(set (v4i32 V128:$dst),
9093 (Accum (v4i32 V128:$Rd),
9094 (v4i32 (int_aarch64_neon_sqrdmulh (v4i32 V128:$Rn),
9095 (v4i32 V128:$Rm)))))]>;
9096}
9097
9098multiclass SIMDIndexedSQRDMLxHSDTied<bit U, bits<4> opc, string asm,
9099 SDPatternOperator Accum> {
9100 def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc,
9101 V64, V64, V128_lo, VectorIndexH,
9102 asm, ".4h", ".4h", ".4h", ".h",
9103 [(set (v4i16 V64:$dst),
9104 (Accum (v4i16 V64:$Rd),
9105 (v4i16 (int_aarch64_neon_sqrdmulh
9106 (v4i16 V64:$Rn),
9107 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm),
9108 VectorIndexH:$idx))))))]> {
9109 bits<3> idx;
9110 let Inst{11} = idx{2};
9111 let Inst{21} = idx{1};
9112 let Inst{20} = idx{0};
9113 }
9114
9115 def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc,
9116 V128, V128, V128_lo, VectorIndexH,
9117 asm, ".8h", ".8h", ".8h", ".h",
9118 [(set (v8i16 V128:$dst),
9119 (Accum (v8i16 V128:$Rd),
9120 (v8i16 (int_aarch64_neon_sqrdmulh
9121 (v8i16 V128:$Rn),
9122 (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm),
9123 VectorIndexH:$idx))))))]> {
9124 bits<3> idx;
9125 let Inst{11} = idx{2};
9126 let Inst{21} = idx{1};
9127 let Inst{20} = idx{0};
9128 }
9129
9130 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc,
9131 V64, V64, V128, VectorIndexS,
9132 asm, ".2s", ".2s", ".2s", ".s",
9133 [(set (v2i32 V64:$dst),
9134 (Accum (v2i32 V64:$Rd),
9135 (v2i32 (int_aarch64_neon_sqrdmulh
9136 (v2i32 V64:$Rn),
9137 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm),
9138 VectorIndexS:$idx))))))]> {
9139 bits<2> idx;
9140 let Inst{11} = idx{1};
9141 let Inst{21} = idx{0};
9142 }
9143
9144 // FIXME: it would be nice to use the scalar (v1i32) instruction here, but
9145 // an intermediate EXTRACT_SUBREG would be untyped.
9146 // FIXME: direct EXTRACT_SUBREG from v2i32 to i32 is illegal, that's why we
9147 // got it lowered here as (i32 vector_extract (v4i32 insert_subvector(..)))
9148 def : Pat<(i32 (Accum (i32 FPR32Op:$Rd),
9149 (i32 (vector_extract
9150 (v4i32 (insert_subvector
9151 (undef),
9152 (v2i32 (int_aarch64_neon_sqrdmulh
9153 (v2i32 V64:$Rn),
9154 (v2i32 (AArch64duplane32
9155 (v4i32 V128:$Rm),
9156 VectorIndexS:$idx)))),
9157 (i32 0))),
9158 (i64 0))))),
9159 (EXTRACT_SUBREG
9160 (v2i32 (!cast<Instruction>(NAME # v2i32_indexed)
9161 (v2i32 (INSERT_SUBREG (v2i32 (IMPLICIT_DEF)),
9162 FPR32Op:$Rd,
9163 ssub)),
9164 V64:$Rn,
9165 V128:$Rm,
9166 VectorIndexS:$idx)),
9167 ssub)>;
9168
9169 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc,
9170 V128, V128, V128, VectorIndexS,
9171 asm, ".4s", ".4s", ".4s", ".s",
9172 [(set (v4i32 V128:$dst),
9173 (Accum (v4i32 V128:$Rd),
9174 (v4i32 (int_aarch64_neon_sqrdmulh
9175 (v4i32 V128:$Rn),
9176 (v4i32 (AArch64duplane32 (v4i32 V128:$Rm),
9177 VectorIndexS:$idx))))))]> {
9178 bits<2> idx;
9179 let Inst{11} = idx{1};
9180 let Inst{21} = idx{0};
9181 }
9182
9183 // FIXME: it would be nice to use the scalar (v1i32) instruction here, but
9184 // an intermediate EXTRACT_SUBREG would be untyped.
9185 def : Pat<(i32 (Accum (i32 FPR32Op:$Rd),
9186 (i32 (vector_extract
9187 (v4i32 (int_aarch64_neon_sqrdmulh
9188 (v4i32 V128:$Rn),
9189 (v4i32 (AArch64duplane32
9190 (v4i32 V128:$Rm),
9191 VectorIndexS:$idx)))),
9192 (i64 0))))),
9193 (EXTRACT_SUBREG
9194 (v4i32 (!cast<Instruction>(NAME # v4i32_indexed)
9195 (v4i32 (INSERT_SUBREG (v4i32 (IMPLICIT_DEF)),
9196 FPR32Op:$Rd,
9197 ssub)),
9198 V128:$Rn,
9199 V128:$Rm,
9200 VectorIndexS:$idx)),
9201 ssub)>;
9202
9203 def i16_indexed : BaseSIMDIndexedTied<1, U, 1, 0b01, opc,
9204 FPR16Op, FPR16Op, V128_lo,
9205 VectorIndexH, asm, ".h", "", "", ".h",
9206 []> {
9207 bits<3> idx;
9208 let Inst{11} = idx{2};
9209 let Inst{21} = idx{1};
9210 let Inst{20} = idx{0};
9211 }
9212
9213 def i32_indexed : BaseSIMDIndexedTied<1, U, 1, 0b10, opc,
9214 FPR32Op, FPR32Op, V128, VectorIndexS,
9215 asm, ".s", "", "", ".s",
9216 [(set (i32 FPR32Op:$dst),
9217 (Accum (i32 FPR32Op:$Rd),
9218 (i32 (int_aarch64_neon_sqrdmulh
9219 (i32 FPR32Op:$Rn),
9220 (i32 (vector_extract (v4i32 V128:$Rm),
9221 VectorIndexS:$idx))))))]> {
9222 bits<2> idx;
9223 let Inst{11} = idx{1};
9224 let Inst{21} = idx{0};
9225 }
9226}
9227} // let Predicates = [HasNeon, HasV8_1a]
9228
9229//----------------------------------------------------------------------------
Tim Northover3b0846e2014-05-24 12:50:23 +00009230// Crypto extensions
9231//----------------------------------------------------------------------------
9232
9233let Predicates = [HasCrypto] in {
9234let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
9235class AESBase<bits<4> opc, string asm, dag outs, dag ins, string cstr,
9236 list<dag> pat>
9237 : I<outs, ins, asm, "{\t$Rd.16b, $Rn.16b|.16b\t$Rd, $Rn}", cstr, pat>,
9238 Sched<[WriteV]>{
9239 bits<5> Rd;
9240 bits<5> Rn;
9241 let Inst{31-16} = 0b0100111000101000;
9242 let Inst{15-12} = opc;
9243 let Inst{11-10} = 0b10;
9244 let Inst{9-5} = Rn;
9245 let Inst{4-0} = Rd;
9246}
9247
9248class AESInst<bits<4> opc, string asm, Intrinsic OpNode>
9249 : AESBase<opc, asm, (outs V128:$Rd), (ins V128:$Rn), "",
9250 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>;
9251
9252class AESTiedInst<bits<4> opc, string asm, Intrinsic OpNode>
9253 : AESBase<opc, asm, (outs V128:$dst), (ins V128:$Rd, V128:$Rn),
9254 "$Rd = $dst",
9255 [(set (v16i8 V128:$dst),
9256 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn)))]>;
9257
9258let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
9259class SHA3OpTiedInst<bits<3> opc, string asm, string dst_lhs_kind,
9260 dag oops, dag iops, list<dag> pat>
9261 : I<oops, iops, asm,
9262 "{\t$Rd" # dst_lhs_kind # ", $Rn" # dst_lhs_kind # ", $Rm.4s" #
9263 "|.4s\t$Rd, $Rn, $Rm}", "$Rd = $dst", pat>,
9264 Sched<[WriteV]>{
9265 bits<5> Rd;
9266 bits<5> Rn;
9267 bits<5> Rm;
9268 let Inst{31-21} = 0b01011110000;
9269 let Inst{20-16} = Rm;
9270 let Inst{15} = 0;
9271 let Inst{14-12} = opc;
9272 let Inst{11-10} = 0b00;
9273 let Inst{9-5} = Rn;
9274 let Inst{4-0} = Rd;
9275}
9276
9277class SHATiedInstQSV<bits<3> opc, string asm, Intrinsic OpNode>
9278 : SHA3OpTiedInst<opc, asm, "", (outs FPR128:$dst),
9279 (ins FPR128:$Rd, FPR32:$Rn, V128:$Rm),
9280 [(set (v4i32 FPR128:$dst),
9281 (OpNode (v4i32 FPR128:$Rd), (i32 FPR32:$Rn),
9282 (v4i32 V128:$Rm)))]>;
9283
9284class SHATiedInstVVV<bits<3> opc, string asm, Intrinsic OpNode>
9285 : SHA3OpTiedInst<opc, asm, ".4s", (outs V128:$dst),
9286 (ins V128:$Rd, V128:$Rn, V128:$Rm),
9287 [(set (v4i32 V128:$dst),
9288 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn),
9289 (v4i32 V128:$Rm)))]>;
9290
9291class SHATiedInstQQV<bits<3> opc, string asm, Intrinsic OpNode>
9292 : SHA3OpTiedInst<opc, asm, "", (outs FPR128:$dst),
9293 (ins FPR128:$Rd, FPR128:$Rn, V128:$Rm),
9294 [(set (v4i32 FPR128:$dst),
9295 (OpNode (v4i32 FPR128:$Rd), (v4i32 FPR128:$Rn),
9296 (v4i32 V128:$Rm)))]>;
9297
9298let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
9299class SHA2OpInst<bits<4> opc, string asm, string kind,
9300 string cstr, dag oops, dag iops,
9301 list<dag> pat>
9302 : I<oops, iops, asm, "{\t$Rd" # kind # ", $Rn" # kind #
9303 "|" # kind # "\t$Rd, $Rn}", cstr, pat>,
9304 Sched<[WriteV]>{
9305 bits<5> Rd;
9306 bits<5> Rn;
9307 let Inst{31-16} = 0b0101111000101000;
9308 let Inst{15-12} = opc;
9309 let Inst{11-10} = 0b10;
9310 let Inst{9-5} = Rn;
9311 let Inst{4-0} = Rd;
9312}
9313
9314class SHATiedInstVV<bits<4> opc, string asm, Intrinsic OpNode>
9315 : SHA2OpInst<opc, asm, ".4s", "$Rd = $dst", (outs V128:$dst),
9316 (ins V128:$Rd, V128:$Rn),
9317 [(set (v4i32 V128:$dst),
9318 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn)))]>;
9319
9320class SHAInstSS<bits<4> opc, string asm, Intrinsic OpNode>
9321 : SHA2OpInst<opc, asm, "", "", (outs FPR32:$Rd), (ins FPR32:$Rn),
9322 [(set (i32 FPR32:$Rd), (OpNode (i32 FPR32:$Rn)))]>;
9323} // end of 'let Predicates = [HasCrypto]'
9324
Vladimir Sukharev5f6f60d2015-06-02 10:58:41 +00009325//----------------------------------------------------------------------------
9326// v8.1 atomic instructions extension:
9327// * CAS
9328// * CASP
9329// * SWP
9330// * LDOPregister<OP>, and aliases STOPregister<OP>
9331
9332// Instruction encodings:
9333//
9334// 31 30|29 24|23|22|21|20 16|15|14 10|9 5|4 0
9335// CAS SZ |001000|1 |A |1 |Rs |R |11111 |Rn |Rt
9336// CASP 0|SZ|001000|0 |A |1 |Rs |R |11111 |Rn |Rt
9337// SWP SZ |111000|A |R |1 |Rs |1 |OPC|00|Rn |Rt
9338// LD SZ |111000|A |R |1 |Rs |0 |OPC|00|Rn |Rt
9339// ST SZ |111000|A |R |1 |Rs |0 |OPC|00|Rn |11111
9340
9341// Instruction syntax:
9342//
9343// CAS{<order>}[<size>] <Ws>, <Wt>, [<Xn|SP>]
9344// CAS{<order>} <Xs>, <Xt>, [<Xn|SP>]
9345// CASP{<order>} <Ws>, <W(s+1)>, <Wt>, <W(t+1)>, [<Xn|SP>]
9346// CASP{<order>} <Xs>, <X(s+1)>, <Xt>, <X(t+1)>, [<Xn|SP>]
9347// SWP{<order>}[<size>] <Ws>, <Wt>, [<Xn|SP>]
9348// SWP{<order>} <Xs>, <Xt>, [<Xn|SP>]
9349// LD<OP>{<order>}[<size>] <Ws>, <Wt>, [<Xn|SP>]
9350// LD<OP>{<order>} <Xs>, <Xt>, [<Xn|SP>]
9351// ST<OP>{<order>}[<size>] <Ws>, [<Xn|SP>]
9352// ST<OP>{<order>} <Xs>, [<Xn|SP>]
9353
9354let Predicates = [HasV8_1a], mayLoad = 1, mayStore = 1, hasSideEffects = 1 in
9355class BaseCASEncoding<dag oops, dag iops, string asm, string operands,
9356 string cstr, list<dag> pattern>
9357 : I<oops, iops, asm, operands, cstr, pattern> {
9358 bits<2> Sz;
9359 bit NP;
9360 bit Acq;
9361 bit Rel;
9362 bits<5> Rs;
9363 bits<5> Rn;
9364 bits<5> Rt;
9365 let Inst{31-30} = Sz;
9366 let Inst{29-24} = 0b001000;
9367 let Inst{23} = NP;
9368 let Inst{22} = Acq;
9369 let Inst{21} = 0b1;
9370 let Inst{20-16} = Rs;
9371 let Inst{15} = Rel;
9372 let Inst{14-10} = 0b11111;
9373 let Inst{9-5} = Rn;
9374 let Inst{4-0} = Rt;
9375}
9376
9377class BaseCAS<string order, string size, RegisterClass RC>
9378 : BaseCASEncoding<(outs RC:$out),(ins RC:$Rs, RC:$Rt, GPR64sp:$Rn),
9379 "cas" # order # size, "\t$Rs, $Rt, [$Rn]",
9380 "$out = $Rs",[]> {
9381 let NP = 1;
9382}
9383
9384multiclass CompareAndSwap<bits<1> Acq, bits<1> Rel, string order> {
9385 let Sz = 0b00, Acq = Acq, Rel = Rel in def b : BaseCAS<order, "b", GPR32>;
9386 let Sz = 0b01, Acq = Acq, Rel = Rel in def h : BaseCAS<order, "h", GPR32>;
9387 let Sz = 0b10, Acq = Acq, Rel = Rel in def s : BaseCAS<order, "", GPR32>;
9388 let Sz = 0b11, Acq = Acq, Rel = Rel in def d : BaseCAS<order, "", GPR64>;
9389}
9390
9391class BaseCASP<string order, string size, RegisterOperand RC>
9392 : BaseCASEncoding<(outs RC:$out),(ins RC:$Rs, RC:$Rt, GPR64sp:$Rn),
9393 "casp" # order # size, "\t$Rs, $Rt, [$Rn]",
9394 "$out = $Rs",[]> {
9395 let NP = 0;
9396}
9397
9398multiclass CompareAndSwapPair<bits<1> Acq, bits<1> Rel, string order> {
9399 let Sz = 0b00, Acq = Acq, Rel = Rel in
9400 def s : BaseCASP<order, "", WSeqPairClassOperand>;
9401 let Sz = 0b01, Acq = Acq, Rel = Rel in
9402 def d : BaseCASP<order, "", XSeqPairClassOperand>;
9403}
9404
9405let Predicates = [HasV8_1a] in
9406class BaseSWP<string order, string size, RegisterClass RC>
9407 : I<(outs RC:$Rt),(ins RC:$Rs, GPR64sp:$Rn), "swp" # order # size,
9408 "\t$Rs, $Rt, [$Rn]","",[]> {
9409 bits<2> Sz;
9410 bit Acq;
9411 bit Rel;
9412 bits<5> Rs;
9413 bits<3> opc = 0b000;
9414 bits<5> Rn;
9415 bits<5> Rt;
9416 let Inst{31-30} = Sz;
9417 let Inst{29-24} = 0b111000;
9418 let Inst{23} = Acq;
9419 let Inst{22} = Rel;
9420 let Inst{21} = 0b1;
9421 let Inst{20-16} = Rs;
9422 let Inst{15} = 0b1;
9423 let Inst{14-12} = opc;
9424 let Inst{11-10} = 0b00;
9425 let Inst{9-5} = Rn;
9426 let Inst{4-0} = Rt;
9427}
9428
9429multiclass Swap<bits<1> Acq, bits<1> Rel, string order> {
9430 let Sz = 0b00, Acq = Acq, Rel = Rel in def b : BaseSWP<order, "b", GPR32>;
9431 let Sz = 0b01, Acq = Acq, Rel = Rel in def h : BaseSWP<order, "h", GPR32>;
9432 let Sz = 0b10, Acq = Acq, Rel = Rel in def s : BaseSWP<order, "", GPR32>;
9433 let Sz = 0b11, Acq = Acq, Rel = Rel in def d : BaseSWP<order, "", GPR64>;
9434}
9435
9436let Predicates = [HasV8_1a], mayLoad = 1, mayStore = 1, hasSideEffects = 1 in
9437class BaseLDOPregister<string op, string order, string size, RegisterClass RC>
9438 : I<(outs RC:$Rt),(ins RC:$Rs, GPR64sp:$Rn), "ld" # op # order # size,
9439 "\t$Rs, $Rt, [$Rn]","",[]> {
9440 bits<2> Sz;
9441 bit Acq;
9442 bit Rel;
9443 bits<5> Rs;
9444 bits<3> opc;
9445 bits<5> Rn;
9446 bits<5> Rt;
9447 let Inst{31-30} = Sz;
9448 let Inst{29-24} = 0b111000;
9449 let Inst{23} = Acq;
9450 let Inst{22} = Rel;
9451 let Inst{21} = 0b1;
9452 let Inst{20-16} = Rs;
9453 let Inst{15} = 0b0;
9454 let Inst{14-12} = opc;
9455 let Inst{11-10} = 0b00;
9456 let Inst{9-5} = Rn;
9457 let Inst{4-0} = Rt;
9458}
9459
9460multiclass LDOPregister<bits<3> opc, string op, bits<1> Acq, bits<1> Rel,
9461 string order> {
9462 let Sz = 0b00, Acq = Acq, Rel = Rel, opc = opc in
9463 def b : BaseLDOPregister<op, order, "b", GPR32>;
9464 let Sz = 0b01, Acq = Acq, Rel = Rel, opc = opc in
9465 def h : BaseLDOPregister<op, order, "h", GPR32>;
9466 let Sz = 0b10, Acq = Acq, Rel = Rel, opc = opc in
9467 def s : BaseLDOPregister<op, order, "", GPR32>;
9468 let Sz = 0b11, Acq = Acq, Rel = Rel, opc = opc in
9469 def d : BaseLDOPregister<op, order, "", GPR64>;
9470}
9471
9472let Predicates = [HasV8_1a] in
9473class BaseSTOPregister<string asm, RegisterClass OP, Register Reg,
9474 Instruction inst> :
9475 InstAlias<asm # "\t$Rs, [$Rn]", (inst Reg, OP:$Rs, GPR64sp:$Rn)>;
9476
9477multiclass STOPregister<string asm, string instr> {
9478 def : BaseSTOPregister<asm # "lb", GPR32, WZR,
9479 !cast<Instruction>(instr # "Lb")>;
9480 def : BaseSTOPregister<asm # "lh", GPR32, WZR,
9481 !cast<Instruction>(instr # "Lh")>;
9482 def : BaseSTOPregister<asm # "l", GPR32, WZR,
9483 !cast<Instruction>(instr # "Ls")>;
9484 def : BaseSTOPregister<asm # "l", GPR64, XZR,
9485 !cast<Instruction>(instr # "Ld")>;
9486 def : BaseSTOPregister<asm # "b", GPR32, WZR,
9487 !cast<Instruction>(instr # "b")>;
9488 def : BaseSTOPregister<asm # "h", GPR32, WZR,
9489 !cast<Instruction>(instr # "h")>;
9490 def : BaseSTOPregister<asm, GPR32, WZR,
9491 !cast<Instruction>(instr # "s")>;
9492 def : BaseSTOPregister<asm, GPR64, XZR,
9493 !cast<Instruction>(instr # "d")>;
9494}
9495
9496//----------------------------------------------------------------------------
Tim Northover3b0846e2014-05-24 12:50:23 +00009497// Allow the size specifier tokens to be upper case, not just lower.
9498def : TokenAlias<".8B", ".8b">;
9499def : TokenAlias<".4H", ".4h">;
9500def : TokenAlias<".2S", ".2s">;
9501def : TokenAlias<".1D", ".1d">;
9502def : TokenAlias<".16B", ".16b">;
9503def : TokenAlias<".8H", ".8h">;
9504def : TokenAlias<".4S", ".4s">;
9505def : TokenAlias<".2D", ".2d">;
9506def : TokenAlias<".1Q", ".1q">;
Oliver Stannarde4c3d212015-12-08 12:16:10 +00009507def : TokenAlias<".2H", ".2h">;
Tim Northover3b0846e2014-05-24 12:50:23 +00009508def : TokenAlias<".B", ".b">;
9509def : TokenAlias<".H", ".h">;
9510def : TokenAlias<".S", ".s">;
9511def : TokenAlias<".D", ".d">;
9512def : TokenAlias<".Q", ".q">;