blob: 00658edefa52bbdd356681ee3c1cc4f7b959fca8 [file] [log] [blame]
Tim Northover00ed9962014-03-29 10:18:08 +00001//===- ARM64InstrFormats.td - ARM64 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 ARM64 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// ARM64 Instruction Format
25class ARM64Inst<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 = "ARM64";
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 : ARM64Inst<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> : ARM64Inst<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}
94def MovImm64ShifterOperand : AsmOperandClass {
95 let SuperClasses = [ShifterOperand];
96 let Name = "MovImm64Shifter";
97}
98
99// Shifter operand for arithmetic register shifted encodings.
100def ArithmeticShifterOperand : AsmOperandClass {
101 let SuperClasses = [ShifterOperand];
102 let Name = "ArithmeticShifter";
103}
104
105// Shifter operand for arithmetic shifted encodings for ADD/SUB instructions.
106def AddSubShifterOperand : AsmOperandClass {
107 let SuperClasses = [ArithmeticShifterOperand];
108 let Name = "AddSubShifter";
109}
110
111// Shifter operand for logical vector 128/64-bit shifted encodings.
112def LogicalVecShifterOperand : AsmOperandClass {
113 let SuperClasses = [ShifterOperand];
114 let Name = "LogicalVecShifter";
115}
116def LogicalVecHalfWordShifterOperand : AsmOperandClass {
117 let SuperClasses = [LogicalVecShifterOperand];
118 let Name = "LogicalVecHalfWordShifter";
119}
120
121// The "MSL" shifter on the vector MOVI instruction.
122def MoveVecShifterOperand : AsmOperandClass {
123 let SuperClasses = [ShifterOperand];
124 let Name = "MoveVecShifter";
125}
126
127// Extend operand for arithmetic encodings.
128def ExtendOperand : AsmOperandClass { let Name = "Extend"; }
129def ExtendOperand64 : AsmOperandClass {
130 let SuperClasses = [ExtendOperand];
131 let Name = "Extend64";
132}
133// 'extend' that's a lsl of a 64-bit register.
134def ExtendOperandLSL64 : AsmOperandClass {
135 let SuperClasses = [ExtendOperand];
136 let Name = "ExtendLSL64";
137}
138
139// 8-bit floating-point immediate encodings.
140def FPImmOperand : AsmOperandClass {
141 let Name = "FPImm";
142 let ParserMethod = "tryParseFPImm";
143}
144
145// 8-bit immediate for AdvSIMD where 64-bit values of the form:
146// aaaaaaaa bbbbbbbb cccccccc dddddddd eeeeeeee ffffffff gggggggg hhhhhhhh
147// are encoded as the eight bit value 'abcdefgh'.
148def SIMDImmType10Operand : AsmOperandClass { let Name = "SIMDImmType10"; }
149
150
151//===----------------------------------------------------------------------===//
152// Operand Definitions.
153//
154
155// ADR[P] instruction labels.
156def AdrpOperand : AsmOperandClass {
157 let Name = "AdrpLabel";
158 let ParserMethod = "tryParseAdrpLabel";
159}
160def adrplabel : Operand<i64> {
161 let EncoderMethod = "getAdrLabelOpValue";
162 let PrintMethod = "printAdrpLabel";
163 let ParserMatchClass = AdrpOperand;
164}
165
166def AdrOperand : AsmOperandClass {
167 let Name = "AdrLabel";
168 let ParserMethod = "tryParseAdrLabel";
169}
170def adrlabel : Operand<i64> {
171 let EncoderMethod = "getAdrLabelOpValue";
172 let ParserMatchClass = AdrOperand;
173}
174
175// simm9 predicate - True if the immediate is in the range [-256, 255].
176def SImm9Operand : AsmOperandClass {
177 let Name = "SImm9";
178 let DiagnosticType = "InvalidMemoryIndexedSImm9";
179}
180def simm9 : Operand<i64>, ImmLeaf<i64, [{ return Imm >= -256 && Imm < 256; }]> {
181 let ParserMatchClass = SImm9Operand;
182}
183
184// simm7s4 predicate - True if the immediate is a multiple of 4 in the range
185// [-256, 252].
186def SImm7s4Operand : AsmOperandClass {
187 let Name = "SImm7s4";
188 let DiagnosticType = "InvalidMemoryIndexed32SImm7";
189}
190def simm7s4 : Operand<i32> {
191 let ParserMatchClass = SImm7s4Operand;
192 let PrintMethod = "printImmScale4";
193}
194
195// simm7s8 predicate - True if the immediate is a multiple of 8 in the range
196// [-512, 504].
197def SImm7s8Operand : AsmOperandClass {
198 let Name = "SImm7s8";
199 let DiagnosticType = "InvalidMemoryIndexed64SImm7";
200}
201def simm7s8 : Operand<i32> {
202 let ParserMatchClass = SImm7s8Operand;
203 let PrintMethod = "printImmScale8";
204}
205
206// simm7s16 predicate - True if the immediate is a multiple of 16 in the range
207// [-1024, 1008].
208def SImm7s16Operand : AsmOperandClass {
209 let Name = "SImm7s16";
210 let DiagnosticType = "InvalidMemoryIndexed64SImm7";
211}
212def simm7s16 : Operand<i32> {
213 let ParserMatchClass = SImm7s16Operand;
214 let PrintMethod = "printImmScale16";
215}
216
217// imm0_65535 predicate - True if the immediate is in the range [0,65535].
218def Imm0_65535Operand : AsmOperandClass { let Name = "Imm0_65535"; }
219def imm0_65535 : Operand<i32>, ImmLeaf<i32, [{
220 return ((uint32_t)Imm) < 65536;
221}]> {
222 let ParserMatchClass = Imm0_65535Operand;
223}
224
225def Imm1_8Operand : AsmOperandClass {
226 let Name = "Imm1_8";
227 let DiagnosticType = "InvalidImm1_8";
228}
229def Imm1_16Operand : AsmOperandClass {
230 let Name = "Imm1_16";
231 let DiagnosticType = "InvalidImm1_16";
232}
233def Imm1_32Operand : AsmOperandClass {
234 let Name = "Imm1_32";
235 let DiagnosticType = "InvalidImm1_32";
236}
237def Imm1_64Operand : AsmOperandClass {
238 let Name = "Imm1_64";
239 let DiagnosticType = "InvalidImm1_64";
240}
241
242def MovZSymbolG3AsmOperand : AsmOperandClass {
243 let Name = "MovZSymbolG3";
244 let RenderMethod = "addImmOperands";
245}
246
247def movz_symbol_g3 : Operand<i32> {
248 let ParserMatchClass = MovZSymbolG3AsmOperand;
249}
250
251def MovZSymbolG2AsmOperand : AsmOperandClass {
252 let Name = "MovZSymbolG2";
253 let RenderMethod = "addImmOperands";
254}
255
256def movz_symbol_g2 : Operand<i32> {
257 let ParserMatchClass = MovZSymbolG2AsmOperand;
258}
259
260def MovZSymbolG1AsmOperand : AsmOperandClass {
261 let Name = "MovZSymbolG1";
262 let RenderMethod = "addImmOperands";
263}
264
265def movz_symbol_g1 : Operand<i32> {
266 let ParserMatchClass = MovZSymbolG1AsmOperand;
267}
268
269def MovZSymbolG0AsmOperand : AsmOperandClass {
270 let Name = "MovZSymbolG0";
271 let RenderMethod = "addImmOperands";
272}
273
274def movz_symbol_g0 : Operand<i32> {
275 let ParserMatchClass = MovZSymbolG0AsmOperand;
276}
277
278def MovKSymbolG2AsmOperand : AsmOperandClass {
279 let Name = "MovKSymbolG2";
280 let RenderMethod = "addImmOperands";
281}
282
283def movk_symbol_g2 : Operand<i32> {
284 let ParserMatchClass = MovKSymbolG2AsmOperand;
285}
286
287def MovKSymbolG1AsmOperand : AsmOperandClass {
288 let Name = "MovKSymbolG1";
289 let RenderMethod = "addImmOperands";
290}
291
292def movk_symbol_g1 : Operand<i32> {
293 let ParserMatchClass = MovKSymbolG1AsmOperand;
294}
295
296def MovKSymbolG0AsmOperand : AsmOperandClass {
297 let Name = "MovKSymbolG0";
298 let RenderMethod = "addImmOperands";
299}
300
301def movk_symbol_g0 : Operand<i32> {
302 let ParserMatchClass = MovKSymbolG0AsmOperand;
303}
304
305def fixedpoint32 : Operand<i32> {
306 let EncoderMethod = "getFixedPointScaleOpValue";
307 let DecoderMethod = "DecodeFixedPointScaleImm";
308 let ParserMatchClass = Imm1_32Operand;
309}
310def fixedpoint64 : Operand<i64> {
311 let EncoderMethod = "getFixedPointScaleOpValue";
312 let DecoderMethod = "DecodeFixedPointScaleImm";
313 let ParserMatchClass = Imm1_64Operand;
314}
315
316def vecshiftR8 : Operand<i32>, ImmLeaf<i32, [{
317 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 9);
318}]> {
319 let EncoderMethod = "getVecShiftR8OpValue";
320 let DecoderMethod = "DecodeVecShiftR8Imm";
321 let ParserMatchClass = Imm1_8Operand;
322}
323def vecshiftR16 : Operand<i32>, ImmLeaf<i32, [{
324 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 17);
325}]> {
326 let EncoderMethod = "getVecShiftR16OpValue";
327 let DecoderMethod = "DecodeVecShiftR16Imm";
328 let ParserMatchClass = Imm1_16Operand;
329}
330def vecshiftR16Narrow : Operand<i32>, ImmLeaf<i32, [{
331 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 9);
332}]> {
333 let EncoderMethod = "getVecShiftR16OpValue";
334 let DecoderMethod = "DecodeVecShiftR16ImmNarrow";
335 let ParserMatchClass = Imm1_8Operand;
336}
337def vecshiftR32 : Operand<i32>, ImmLeaf<i32, [{
338 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 33);
339}]> {
340 let EncoderMethod = "getVecShiftR32OpValue";
341 let DecoderMethod = "DecodeVecShiftR32Imm";
342 let ParserMatchClass = Imm1_32Operand;
343}
344def vecshiftR32Narrow : Operand<i32>, ImmLeaf<i32, [{
345 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 17);
346}]> {
347 let EncoderMethod = "getVecShiftR32OpValue";
348 let DecoderMethod = "DecodeVecShiftR32ImmNarrow";
349 let ParserMatchClass = Imm1_16Operand;
350}
351def vecshiftR64 : Operand<i32>, ImmLeaf<i32, [{
352 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 65);
353}]> {
354 let EncoderMethod = "getVecShiftR64OpValue";
355 let DecoderMethod = "DecodeVecShiftR64Imm";
356 let ParserMatchClass = Imm1_64Operand;
357}
358def vecshiftR64Narrow : Operand<i32>, ImmLeaf<i32, [{
359 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 33);
360}]> {
361 let EncoderMethod = "getVecShiftR64OpValue";
362 let DecoderMethod = "DecodeVecShiftR64ImmNarrow";
363 let ParserMatchClass = Imm1_32Operand;
364}
365
366def Imm0_7Operand : AsmOperandClass { let Name = "Imm0_7"; }
367def Imm0_15Operand : AsmOperandClass { let Name = "Imm0_15"; }
368def Imm0_31Operand : AsmOperandClass { let Name = "Imm0_31"; }
369def Imm0_63Operand : AsmOperandClass { let Name = "Imm0_63"; }
370
371def vecshiftL8 : Operand<i32>, ImmLeaf<i32, [{
372 return (((uint32_t)Imm) < 8);
373}]> {
374 let EncoderMethod = "getVecShiftL8OpValue";
375 let DecoderMethod = "DecodeVecShiftL8Imm";
376 let ParserMatchClass = Imm0_7Operand;
377}
378def vecshiftL16 : Operand<i32>, ImmLeaf<i32, [{
379 return (((uint32_t)Imm) < 16);
380}]> {
381 let EncoderMethod = "getVecShiftL16OpValue";
382 let DecoderMethod = "DecodeVecShiftL16Imm";
383 let ParserMatchClass = Imm0_15Operand;
384}
385def vecshiftL32 : Operand<i32>, ImmLeaf<i32, [{
386 return (((uint32_t)Imm) < 32);
387}]> {
388 let EncoderMethod = "getVecShiftL32OpValue";
389 let DecoderMethod = "DecodeVecShiftL32Imm";
390 let ParserMatchClass = Imm0_31Operand;
391}
392def vecshiftL64 : Operand<i32>, ImmLeaf<i32, [{
393 return (((uint32_t)Imm) < 64);
394}]> {
395 let EncoderMethod = "getVecShiftL64OpValue";
396 let DecoderMethod = "DecodeVecShiftL64Imm";
397 let ParserMatchClass = Imm0_63Operand;
398}
399
400
401// Crazy immediate formats used by 32-bit and 64-bit logical immediate
402// instructions for splatting repeating bit patterns across the immediate.
403def logical_imm32_XFORM : SDNodeXForm<imm, [{
404 uint64_t enc = ARM64_AM::encodeLogicalImmediate(N->getZExtValue(), 32);
405 return CurDAG->getTargetConstant(enc, MVT::i32);
406}]>;
407def logical_imm64_XFORM : SDNodeXForm<imm, [{
408 uint64_t enc = ARM64_AM::encodeLogicalImmediate(N->getZExtValue(), 64);
409 return CurDAG->getTargetConstant(enc, MVT::i32);
410}]>;
411
412def LogicalImm32Operand : AsmOperandClass { let Name = "LogicalImm32"; }
413def LogicalImm64Operand : AsmOperandClass { let Name = "LogicalImm64"; }
414def logical_imm32 : Operand<i32>, PatLeaf<(imm), [{
415 return ARM64_AM::isLogicalImmediate(N->getZExtValue(), 32);
416}], logical_imm32_XFORM> {
417 let PrintMethod = "printLogicalImm32";
418 let ParserMatchClass = LogicalImm32Operand;
419}
420def logical_imm64 : Operand<i64>, PatLeaf<(imm), [{
421 return ARM64_AM::isLogicalImmediate(N->getZExtValue(), 64);
422}], logical_imm64_XFORM> {
423 let PrintMethod = "printLogicalImm64";
424 let ParserMatchClass = LogicalImm64Operand;
425}
426
427// imm0_255 predicate - True if the immediate is in the range [0,255].
428def Imm0_255Operand : AsmOperandClass { let Name = "Imm0_255"; }
429def imm0_255 : Operand<i32>, ImmLeaf<i32, [{
430 return ((uint32_t)Imm) < 256;
431}]> {
432 let ParserMatchClass = Imm0_255Operand;
433}
434
435// imm0_127 predicate - True if the immediate is in the range [0,127]
436def Imm0_127Operand : AsmOperandClass { let Name = "Imm0_127"; }
437def imm0_127 : Operand<i32>, ImmLeaf<i32, [{
438 return ((uint32_t)Imm) < 128;
439}]> {
440 let ParserMatchClass = Imm0_127Operand;
441}
442
Tim Northover2ad88d32014-04-03 09:26:16 +0000443// NOTE: These imm0_N operands have to be of type i64 because i64 is the size
444// for all shift-amounts.
445
Tim Northover00ed9962014-03-29 10:18:08 +0000446// imm0_63 predicate - True if the immediate is in the range [0,63]
Tim Northover00ed9962014-03-29 10:18:08 +0000447def imm0_63 : Operand<i64>, ImmLeaf<i64, [{
448 return ((uint64_t)Imm) < 64;
449}]> {
450 let ParserMatchClass = Imm0_63Operand;
451}
452
Tim Northover2ad88d32014-04-03 09:26:16 +0000453// imm0_31 predicate - True if the immediate is in the range [0,31]
454def imm0_31 : Operand<i64>, ImmLeaf<i64, [{
Tim Northover00ed9962014-03-29 10:18:08 +0000455 return ((uint64_t)Imm) < 32;
456}]> {
457 let ParserMatchClass = Imm0_31Operand;
458}
459
Tim Northover2ad88d32014-04-03 09:26:16 +0000460// imm0_15 predicate - True if the immediate is in the range [0,15]
461def imm0_15 : Operand<i64>, ImmLeaf<i64, [{
Tim Northover00ed9962014-03-29 10:18:08 +0000462 return ((uint64_t)Imm) < 16;
463}]> {
464 let ParserMatchClass = Imm0_15Operand;
465}
466
Tim Northover00ed9962014-03-29 10:18:08 +0000467// imm0_7 predicate - True if the immediate is in the range [0,7]
Tim Northover2ad88d32014-04-03 09:26:16 +0000468def imm0_7 : Operand<i64>, ImmLeaf<i64, [{
469 return ((uint64_t)Imm) < 8;
Tim Northover00ed9962014-03-29 10:18:08 +0000470}]> {
471 let ParserMatchClass = Imm0_7Operand;
472}
473
474// An arithmetic shifter operand:
475// {7-6} - shift type: 00 = lsl, 01 = lsr, 10 = asr
476// {5-0} - imm6
477def arith_shift : Operand<i32> {
478 let PrintMethod = "printShifter";
479 let ParserMatchClass = ArithmeticShifterOperand;
480}
481
482class arith_shifted_reg<ValueType Ty, RegisterClass regclass>
483 : Operand<Ty>,
484 ComplexPattern<Ty, 2, "SelectArithShiftedRegister", []> {
485 let PrintMethod = "printShiftedRegister";
486 let MIOperandInfo = (ops regclass, arith_shift);
487}
488
489def arith_shifted_reg32 : arith_shifted_reg<i32, GPR32>;
490def arith_shifted_reg64 : arith_shifted_reg<i64, GPR64>;
491
492// An arithmetic shifter operand:
493// {7-6} - shift type: 00 = lsl, 01 = lsr, 10 = asr, 11 = ror
494// {5-0} - imm6
495def logical_shift : Operand<i32> {
496 let PrintMethod = "printShifter";
497 let ParserMatchClass = ShifterOperand;
498}
499
500class logical_shifted_reg<ValueType Ty, RegisterClass regclass>
501 : Operand<Ty>,
502 ComplexPattern<Ty, 2, "SelectLogicalShiftedRegister", []> {
503 let PrintMethod = "printShiftedRegister";
504 let MIOperandInfo = (ops regclass, logical_shift);
505}
506
507def logical_shifted_reg32 : logical_shifted_reg<i32, GPR32>;
508def logical_shifted_reg64 : logical_shifted_reg<i64, GPR64>;
509
510// A logical vector shifter operand:
511// {7-6} - shift type: 00 = lsl
512// {5-0} - imm6: #0, #8, #16, or #24
513def logical_vec_shift : Operand<i32> {
514 let PrintMethod = "printShifter";
515 let EncoderMethod = "getVecShifterOpValue";
516 let ParserMatchClass = LogicalVecShifterOperand;
517}
518
519// A logical vector half-word shifter operand:
520// {7-6} - shift type: 00 = lsl
521// {5-0} - imm6: #0 or #8
522def logical_vec_hw_shift : Operand<i32> {
523 let PrintMethod = "printShifter";
524 let EncoderMethod = "getVecShifterOpValue";
525 let ParserMatchClass = LogicalVecHalfWordShifterOperand;
526}
527
528// A vector move shifter operand:
529// {0} - imm1: #8 or #16
530def move_vec_shift : Operand<i32> {
531 let PrintMethod = "printShifter";
532 let EncoderMethod = "getMoveVecShifterOpValue";
533 let ParserMatchClass = MoveVecShifterOperand;
534}
535
536// An ADD/SUB immediate shifter operand:
537// {7-6} - shift type: 00 = lsl
538// {5-0} - imm6: #0 or #12
539def addsub_shift : Operand<i32> {
540 let ParserMatchClass = AddSubShifterOperand;
541}
542
543class addsub_shifted_imm<ValueType Ty>
544 : Operand<Ty>, ComplexPattern<Ty, 2, "SelectArithImmed", [imm]> {
545 let PrintMethod = "printAddSubImm";
546 let EncoderMethod = "getAddSubImmOpValue";
547 let MIOperandInfo = (ops i32imm, addsub_shift);
548}
549
550def addsub_shifted_imm32 : addsub_shifted_imm<i32>;
551def addsub_shifted_imm64 : addsub_shifted_imm<i64>;
552
553class neg_addsub_shifted_imm<ValueType Ty>
554 : Operand<Ty>, ComplexPattern<Ty, 2, "SelectNegArithImmed", [imm]> {
555 let PrintMethod = "printAddSubImm";
556 let EncoderMethod = "getAddSubImmOpValue";
557 let MIOperandInfo = (ops i32imm, addsub_shift);
558}
559
560def neg_addsub_shifted_imm32 : neg_addsub_shifted_imm<i32>;
561def neg_addsub_shifted_imm64 : neg_addsub_shifted_imm<i64>;
562
563// An extend operand:
564// {5-3} - extend type
565// {2-0} - imm3
566def arith_extend : Operand<i32> {
567 let PrintMethod = "printExtend";
568 let ParserMatchClass = ExtendOperand;
569}
570def arith_extend64 : Operand<i32> {
571 let PrintMethod = "printExtend";
572 let ParserMatchClass = ExtendOperand64;
573}
574
575// 'extend' that's a lsl of a 64-bit register.
576def arith_extendlsl64 : Operand<i32> {
577 let PrintMethod = "printExtend";
578 let ParserMatchClass = ExtendOperandLSL64;
579}
580
581class arith_extended_reg32<ValueType Ty> : Operand<Ty>,
582 ComplexPattern<Ty, 2, "SelectArithExtendedRegister", []> {
583 let PrintMethod = "printExtendedRegister";
584 let MIOperandInfo = (ops GPR32, arith_extend);
585}
586
587class arith_extended_reg32to64<ValueType Ty> : Operand<Ty>,
588 ComplexPattern<Ty, 2, "SelectArithExtendedRegister", []> {
589 let PrintMethod = "printExtendedRegister";
590 let MIOperandInfo = (ops GPR32, arith_extend64);
591}
592
593// Floating-point immediate.
594def fpimm32 : Operand<f32>,
595 PatLeaf<(f32 fpimm), [{
596 return ARM64_AM::getFP32Imm(N->getValueAPF()) != -1;
597 }], SDNodeXForm<fpimm, [{
598 APFloat InVal = N->getValueAPF();
599 uint32_t enc = ARM64_AM::getFP32Imm(InVal);
600 return CurDAG->getTargetConstant(enc, MVT::i32);
601 }]>> {
602 let ParserMatchClass = FPImmOperand;
603 let PrintMethod = "printFPImmOperand";
604}
605def fpimm64 : Operand<f64>,
606 PatLeaf<(f64 fpimm), [{
607 return ARM64_AM::getFP64Imm(N->getValueAPF()) != -1;
608 }], SDNodeXForm<fpimm, [{
609 APFloat InVal = N->getValueAPF();
610 uint32_t enc = ARM64_AM::getFP64Imm(InVal);
611 return CurDAG->getTargetConstant(enc, MVT::i32);
612 }]>> {
613 let ParserMatchClass = FPImmOperand;
614 let PrintMethod = "printFPImmOperand";
615}
616
617def fpimm8 : Operand<i32> {
618 let ParserMatchClass = FPImmOperand;
619 let PrintMethod = "printFPImmOperand";
620}
621
622def fpimm0 : PatLeaf<(fpimm), [{
623 return N->isExactlyValue(+0.0);
624}]>;
625
626// 8-bit immediate for AdvSIMD where 64-bit values of the form:
627// aaaaaaaa bbbbbbbb cccccccc dddddddd eeeeeeee ffffffff gggggggg hhhhhhhh
628// are encoded as the eight bit value 'abcdefgh'.
629def simdimmtype10 : Operand<i32>,
630 PatLeaf<(f64 fpimm), [{
631 return ARM64_AM::isAdvSIMDModImmType10(N->getValueAPF()
632 .bitcastToAPInt()
633 .getZExtValue());
634 }], SDNodeXForm<fpimm, [{
635 APFloat InVal = N->getValueAPF();
636 uint32_t enc = ARM64_AM::encodeAdvSIMDModImmType10(N->getValueAPF()
637 .bitcastToAPInt()
638 .getZExtValue());
639 return CurDAG->getTargetConstant(enc, MVT::i32);
640 }]>> {
641 let ParserMatchClass = SIMDImmType10Operand;
642 let PrintMethod = "printSIMDType10Operand";
643}
644
645
646//---
647// Sytem management
648//---
649
650// Base encoding for system instruction operands.
651let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in
652class BaseSystemI<bit L, dag oops, dag iops, string asm, string operands>
653 : I<oops, iops, asm, operands, "", []> {
654 let Inst{31-22} = 0b1101010100;
655 let Inst{21} = L;
656}
657
658// System instructions which do not have an Rt register.
659class SimpleSystemI<bit L, dag iops, string asm, string operands>
660 : BaseSystemI<L, (outs), iops, asm, operands> {
661 let Inst{4-0} = 0b11111;
662}
663
664// System instructions which have an Rt register.
665class RtSystemI<bit L, dag oops, dag iops, string asm, string operands>
666 : BaseSystemI<L, oops, iops, asm, operands>,
667 Sched<[WriteSys]> {
668 bits<5> Rt;
669 let Inst{4-0} = Rt;
670}
671
672// Hint instructions that take both a CRm and a 3-bit immediate.
673class HintI<string mnemonic>
674 : SimpleSystemI<0, (ins imm0_127:$imm), mnemonic#" $imm", "">,
675 Sched<[WriteHint]> {
676 bits <7> imm;
677 let Inst{20-12} = 0b000110010;
678 let Inst{11-5} = imm;
679}
680
681// System instructions taking a single literal operand which encodes into
682// CRm. op2 differentiates the opcodes.
683def BarrierAsmOperand : AsmOperandClass {
684 let Name = "Barrier";
685 let ParserMethod = "tryParseBarrierOperand";
686}
687def barrier_op : Operand<i32> {
688 let PrintMethod = "printBarrierOption";
689 let ParserMatchClass = BarrierAsmOperand;
690}
691class CRmSystemI<Operand crmtype, bits<3> opc, string asm>
692 : SimpleSystemI<0, (ins crmtype:$CRm), asm, "\t$CRm">,
693 Sched<[WriteBarrier]> {
694 bits<4> CRm;
695 let Inst{20-12} = 0b000110011;
696 let Inst{11-8} = CRm;
697 let Inst{7-5} = opc;
698}
699
Bradley Smith08c391c2014-04-09 14:42:36 +0000700// MRS/MSR system instructions. These have different operand classes because
701// a different subset of registers can be accessed through each instruction.
702def MRSSystemRegisterOperand : AsmOperandClass {
703 let Name = "MRSSystemRegister";
Bradley Smithe8b41662014-04-09 14:43:06 +0000704 let ParserMethod = "tryParseSysReg";
Tim Northover00ed9962014-03-29 10:18:08 +0000705}
706// concatenation of 1, op0, op1, CRn, CRm, op2. 16-bit immediate.
Bradley Smith08c391c2014-04-09 14:42:36 +0000707def mrs_sysreg_op : Operand<i32> {
708 let ParserMatchClass = MRSSystemRegisterOperand;
709 let DecoderMethod = "DecodeMRSSystemRegister";
710 let PrintMethod = "printMRSSystemRegister";
Tim Northover00ed9962014-03-29 10:18:08 +0000711}
712
Bradley Smith08c391c2014-04-09 14:42:36 +0000713def MSRSystemRegisterOperand : AsmOperandClass {
714 let Name = "MSRSystemRegister";
Bradley Smithe8b41662014-04-09 14:43:06 +0000715 let ParserMethod = "tryParseSysReg";
Bradley Smith08c391c2014-04-09 14:42:36 +0000716}
717def msr_sysreg_op : Operand<i32> {
718 let ParserMatchClass = MSRSystemRegisterOperand;
719 let DecoderMethod = "DecodeMSRSystemRegister";
720 let PrintMethod = "printMSRSystemRegister";
721}
722
723class MRSI : RtSystemI<1, (outs GPR64:$Rt), (ins mrs_sysreg_op:$systemreg),
Tim Northover00ed9962014-03-29 10:18:08 +0000724 "mrs", "\t$Rt, $systemreg"> {
725 bits<15> systemreg;
726 let Inst{20} = 1;
727 let Inst{19-5} = systemreg;
728}
729
730// FIXME: Some of these def CPSR, others don't. Best way to model that?
731// Explicitly modeling each of the system register as a register class
732// would do it, but feels like overkill at this point.
Bradley Smith08c391c2014-04-09 14:42:36 +0000733class MSRI : RtSystemI<0, (outs), (ins msr_sysreg_op:$systemreg, GPR64:$Rt),
Tim Northover00ed9962014-03-29 10:18:08 +0000734 "msr", "\t$systemreg, $Rt"> {
735 bits<15> systemreg;
736 let Inst{20} = 1;
737 let Inst{19-5} = systemreg;
738}
739
740def SystemCPSRFieldOperand : AsmOperandClass {
741 let Name = "SystemCPSRField";
Bradley Smithe8b41662014-04-09 14:43:06 +0000742 let ParserMethod = "tryParseSysReg";
Tim Northover00ed9962014-03-29 10:18:08 +0000743}
744def cpsrfield_op : Operand<i32> {
745 let ParserMatchClass = SystemCPSRFieldOperand;
746 let PrintMethod = "printSystemCPSRField";
747}
748
749let Defs = [CPSR] in
750class MSRcpsrI : SimpleSystemI<0, (ins cpsrfield_op:$cpsr_field, imm0_15:$imm),
751 "msr", "\t$cpsr_field, $imm">,
752 Sched<[WriteSys]> {
753 bits<6> cpsrfield;
754 bits<4> imm;
755 let Inst{20-19} = 0b00;
756 let Inst{18-16} = cpsrfield{5-3};
757 let Inst{15-12} = 0b0100;
758 let Inst{11-8} = imm;
759 let Inst{7-5} = cpsrfield{2-0};
760
761 let DecoderMethod = "DecodeSystemCPSRInstruction";
762}
763
764// SYS and SYSL generic system instructions.
765def SysCRAsmOperand : AsmOperandClass {
766 let Name = "SysCR";
767 let ParserMethod = "tryParseSysCROperand";
768}
769
770def sys_cr_op : Operand<i32> {
771 let PrintMethod = "printSysCROperand";
772 let ParserMatchClass = SysCRAsmOperand;
773}
774
775class SystemI<bit L, string asm>
776 : SimpleSystemI<L,
777 (ins imm0_7:$op1, sys_cr_op:$Cn, sys_cr_op:$Cm, imm0_7:$op2),
778 asm, "\t$op1, $Cn, $Cm, $op2">,
779 Sched<[WriteSys]> {
780 bits<3> op1;
781 bits<4> Cn;
782 bits<4> Cm;
783 bits<3> op2;
784 let Inst{20-19} = 0b01;
785 let Inst{18-16} = op1;
786 let Inst{15-12} = Cn;
787 let Inst{11-8} = Cm;
788 let Inst{7-5} = op2;
789}
790
791class SystemXtI<bit L, string asm>
792 : RtSystemI<L, (outs),
793 (ins imm0_7:$op1, sys_cr_op:$Cn, sys_cr_op:$Cm, imm0_7:$op2, GPR64:$Rt),
794 asm, "\t$op1, $Cn, $Cm, $op2, $Rt"> {
795 bits<3> op1;
796 bits<4> Cn;
797 bits<4> Cm;
798 bits<3> op2;
799 let Inst{20-19} = 0b01;
800 let Inst{18-16} = op1;
801 let Inst{15-12} = Cn;
802 let Inst{11-8} = Cm;
803 let Inst{7-5} = op2;
804}
805
806class SystemLXtI<bit L, string asm>
807 : RtSystemI<L, (outs),
808 (ins GPR64:$Rt, imm0_7:$op1, sys_cr_op:$Cn, sys_cr_op:$Cm, imm0_7:$op2),
809 asm, "\t$Rt, $op1, $Cn, $Cm, $op2"> {
810 bits<3> op1;
811 bits<4> Cn;
812 bits<4> Cm;
813 bits<3> op2;
814 let Inst{20-19} = 0b01;
815 let Inst{18-16} = op1;
816 let Inst{15-12} = Cn;
817 let Inst{11-8} = Cm;
818 let Inst{7-5} = op2;
819}
820
821
822// Branch (register) instructions:
823//
824// case opc of
825// 0001 blr
826// 0000 br
827// 0101 dret
828// 0100 eret
829// 0010 ret
830// otherwise UNDEFINED
831class BaseBranchReg<bits<4> opc, dag oops, dag iops, string asm,
832 string operands, list<dag> pattern>
833 : I<oops, iops, asm, operands, "", pattern>, Sched<[WriteBrReg]> {
834 let Inst{31-25} = 0b1101011;
835 let Inst{24-21} = opc;
836 let Inst{20-16} = 0b11111;
837 let Inst{15-10} = 0b000000;
838 let Inst{4-0} = 0b00000;
839}
840
841class BranchReg<bits<4> opc, string asm, list<dag> pattern>
842 : BaseBranchReg<opc, (outs), (ins GPR64:$Rn), asm, "\t$Rn", pattern> {
843 bits<5> Rn;
844 let Inst{9-5} = Rn;
845}
846
847let mayLoad = 0, mayStore = 0, hasSideEffects = 1, isReturn = 1 in
848class SpecialReturn<bits<4> opc, string asm>
849 : BaseBranchReg<opc, (outs), (ins), asm, "", []> {
850 let Inst{9-5} = 0b11111;
851}
852
853//---
854// Conditional branch instruction.
855//---
856// Branch condition code.
857// 4-bit immediate. Pretty-printed as .<cc>
858def dotCcode : Operand<i32> {
859 let PrintMethod = "printDotCondCode";
860}
861
862// Conditional branch target. 19-bit immediate. The low two bits of the target
863// offset are implied zero and so are not part of the immediate.
864def BranchTarget19Operand : AsmOperandClass {
865 let Name = "BranchTarget19";
866}
867def am_brcond : Operand<OtherVT> {
868 let EncoderMethod = "getCondBranchTargetOpValue";
869 let DecoderMethod = "DecodeCondBranchTarget";
870 let PrintMethod = "printAlignedBranchTarget";
871 let ParserMatchClass = BranchTarget19Operand;
872}
873
874class BranchCond : I<(outs), (ins dotCcode:$cond, am_brcond:$target),
875 "b", "$cond\t$target", "",
876 [(ARM64brcond bb:$target, imm:$cond, CPSR)]>,
877 Sched<[WriteBr]> {
878 let isBranch = 1;
879 let isTerminator = 1;
880 let Uses = [CPSR];
881
882 bits<4> cond;
883 bits<19> target;
884 let Inst{31-24} = 0b01010100;
885 let Inst{23-5} = target;
886 let Inst{4} = 0;
887 let Inst{3-0} = cond;
888}
889
890//---
891// Compare-and-branch instructions.
892//---
893class BaseCmpBranch<RegisterClass regtype, bit op, string asm, SDNode node>
894 : I<(outs), (ins regtype:$Rt, am_brcond:$target),
895 asm, "\t$Rt, $target", "",
896 [(node regtype:$Rt, bb:$target)]>,
897 Sched<[WriteBr]> {
898 let isBranch = 1;
899 let isTerminator = 1;
900
901 bits<5> Rt;
902 bits<19> target;
903 let Inst{30-25} = 0b011010;
904 let Inst{24} = op;
905 let Inst{23-5} = target;
906 let Inst{4-0} = Rt;
907}
908
909multiclass CmpBranch<bit op, string asm, SDNode node> {
910 def W : BaseCmpBranch<GPR32, op, asm, node> {
911 let Inst{31} = 0;
912 }
913 def X : BaseCmpBranch<GPR64, op, asm, node> {
914 let Inst{31} = 1;
915 }
916}
917
918//---
919// Test-bit-and-branch instructions.
920//---
921// Test-and-branch target. 14-bit sign-extended immediate. The low two bits of
922// the target offset are implied zero and so are not part of the immediate.
923def BranchTarget14Operand : AsmOperandClass {
924 let Name = "BranchTarget14";
925}
926def am_tbrcond : Operand<OtherVT> {
927 let EncoderMethod = "getTestBranchTargetOpValue";
928 let PrintMethod = "printAlignedBranchTarget";
929 let ParserMatchClass = BranchTarget14Operand;
930}
931
932class TestBranch<bit op, string asm, SDNode node>
933 : I<(outs), (ins GPR64:$Rt, imm0_63:$bit_off, am_tbrcond:$target),
934 asm, "\t$Rt, $bit_off, $target", "",
935 [(node GPR64:$Rt, imm0_63:$bit_off, bb:$target)]>,
936 Sched<[WriteBr]> {
937 let isBranch = 1;
938 let isTerminator = 1;
939
940 bits<5> Rt;
941 bits<6> bit_off;
942 bits<14> target;
943
944 let Inst{31} = bit_off{5};
945 let Inst{30-25} = 0b011011;
946 let Inst{24} = op;
947 let Inst{23-19} = bit_off{4-0};
948 let Inst{18-5} = target;
949 let Inst{4-0} = Rt;
950
951 let DecoderMethod = "DecodeTestAndBranch";
952}
953
954//---
955// Unconditional branch (immediate) instructions.
956//---
957def BranchTarget26Operand : AsmOperandClass {
958 let Name = "BranchTarget26";
959}
960def am_b_target : Operand<OtherVT> {
961 let EncoderMethod = "getBranchTargetOpValue";
962 let PrintMethod = "printAlignedBranchTarget";
963 let ParserMatchClass = BranchTarget26Operand;
964}
965def am_bl_target : Operand<i64> {
966 let EncoderMethod = "getBranchTargetOpValue";
967 let PrintMethod = "printAlignedBranchTarget";
968 let ParserMatchClass = BranchTarget26Operand;
969}
970
971class BImm<bit op, dag iops, string asm, list<dag> pattern>
972 : I<(outs), iops, asm, "\t$addr", "", pattern>, Sched<[WriteBr]> {
973 bits<26> addr;
974 let Inst{31} = op;
975 let Inst{30-26} = 0b00101;
976 let Inst{25-0} = addr;
977
978 let DecoderMethod = "DecodeUnconditionalBranch";
979}
980
981class BranchImm<bit op, string asm, list<dag> pattern>
982 : BImm<op, (ins am_b_target:$addr), asm, pattern>;
983class CallImm<bit op, string asm, list<dag> pattern>
984 : BImm<op, (ins am_bl_target:$addr), asm, pattern>;
985
986//---
987// Basic one-operand data processing instructions.
988//---
989
990let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
991class BaseOneOperandData<bits<3> opc, RegisterClass regtype, string asm,
992 SDPatternOperator node>
993 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm, "\t$Rd, $Rn", "",
994 [(set regtype:$Rd, (node regtype:$Rn))]>,
995 Sched<[WriteI]> {
996 bits<5> Rd;
997 bits<5> Rn;
998
999 let Inst{30-13} = 0b101101011000000000;
1000 let Inst{12-10} = opc;
1001 let Inst{9-5} = Rn;
1002 let Inst{4-0} = Rd;
1003}
1004
1005let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
1006multiclass OneOperandData<bits<3> opc, string asm,
1007 SDPatternOperator node = null_frag> {
1008 def Wr : BaseOneOperandData<opc, GPR32, asm, node> {
1009 let Inst{31} = 0;
1010 }
1011
1012 def Xr : BaseOneOperandData<opc, GPR64, asm, node> {
1013 let Inst{31} = 1;
1014 }
1015}
1016
1017class OneWRegData<bits<3> opc, string asm, SDPatternOperator node>
1018 : BaseOneOperandData<opc, GPR32, asm, node> {
1019 let Inst{31} = 0;
1020}
1021
1022class OneXRegData<bits<3> opc, string asm, SDPatternOperator node>
1023 : BaseOneOperandData<opc, GPR64, asm, node> {
1024 let Inst{31} = 1;
1025}
1026
1027//---
1028// Basic two-operand data processing instructions.
1029//---
1030class BaseBaseAddSubCarry<bit isSub, RegisterClass regtype, string asm,
1031 list<dag> pattern>
1032 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm),
1033 asm, "\t$Rd, $Rn, $Rm", "", pattern>,
1034 Sched<[WriteI]> {
1035 let Uses = [CPSR];
1036 bits<5> Rd;
1037 bits<5> Rn;
1038 bits<5> Rm;
1039 let Inst{30} = isSub;
1040 let Inst{28-21} = 0b11010000;
1041 let Inst{20-16} = Rm;
1042 let Inst{15-10} = 0;
1043 let Inst{9-5} = Rn;
1044 let Inst{4-0} = Rd;
1045}
1046
1047class BaseAddSubCarry<bit isSub, RegisterClass regtype, string asm,
1048 SDNode OpNode>
1049 : BaseBaseAddSubCarry<isSub, regtype, asm,
1050 [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm, CPSR))]>;
1051
1052class BaseAddSubCarrySetFlags<bit isSub, RegisterClass regtype, string asm,
1053 SDNode OpNode>
1054 : BaseBaseAddSubCarry<isSub, regtype, asm,
1055 [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm, CPSR)),
1056 (implicit CPSR)]> {
1057 let Defs = [CPSR];
1058}
1059
1060multiclass AddSubCarry<bit isSub, string asm, string asm_setflags,
1061 SDNode OpNode, SDNode OpNode_setflags> {
1062 def Wr : BaseAddSubCarry<isSub, GPR32, asm, OpNode> {
1063 let Inst{31} = 0;
1064 let Inst{29} = 0;
1065 }
1066 def Xr : BaseAddSubCarry<isSub, GPR64, asm, OpNode> {
1067 let Inst{31} = 1;
1068 let Inst{29} = 0;
1069 }
1070
1071 // Sets flags.
1072 def SWr : BaseAddSubCarrySetFlags<isSub, GPR32, asm_setflags,
1073 OpNode_setflags> {
1074 let Inst{31} = 0;
1075 let Inst{29} = 1;
1076 }
1077 def SXr : BaseAddSubCarrySetFlags<isSub, GPR64, asm_setflags,
1078 OpNode_setflags> {
1079 let Inst{31} = 1;
1080 let Inst{29} = 1;
1081 }
1082}
1083
1084class BaseTwoOperand<bits<4> opc, RegisterClass regtype, string asm,
1085 SDPatternOperator OpNode>
1086 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm),
1087 asm, "\t$Rd, $Rn, $Rm", "",
1088 [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm))]> {
1089 bits<5> Rd;
1090 bits<5> Rn;
1091 bits<5> Rm;
1092 let Inst{30-21} = 0b0011010110;
1093 let Inst{20-16} = Rm;
1094 let Inst{15-14} = 0b00;
1095 let Inst{13-10} = opc;
1096 let Inst{9-5} = Rn;
1097 let Inst{4-0} = Rd;
1098}
1099
1100class BaseDiv<bit isSigned, RegisterClass regtype, string asm,
1101 SDPatternOperator OpNode>
1102 : BaseTwoOperand<{0,0,1,?}, regtype, asm, OpNode> {
1103 let Inst{10} = isSigned;
1104}
1105
1106multiclass Div<bit isSigned, string asm, SDPatternOperator OpNode> {
1107 def Wr : BaseDiv<isSigned, GPR32, asm, OpNode>,
1108 Sched<[WriteID32]> {
1109 let Inst{31} = 0;
1110 }
1111 def Xr : BaseDiv<isSigned, GPR64, asm, OpNode>,
1112 Sched<[WriteID64]> {
1113 let Inst{31} = 1;
1114 }
1115}
1116
Tim Northover2ad88d32014-04-03 09:26:16 +00001117class BaseShift<bits<2> shift_type, RegisterClass regtype, string asm,
1118 SDPatternOperator OpNode = null_frag>
Tim Northover00ed9962014-03-29 10:18:08 +00001119 : BaseTwoOperand<{1,0,?,?}, regtype, asm, OpNode>,
1120 Sched<[WriteIS]> {
1121 let Inst{11-10} = shift_type;
1122}
1123
1124multiclass Shift<bits<2> shift_type, string asm, SDNode OpNode> {
Tim Northover2ad88d32014-04-03 09:26:16 +00001125 def Wr : BaseShift<shift_type, GPR32, asm> {
Tim Northover00ed9962014-03-29 10:18:08 +00001126 let Inst{31} = 0;
1127 }
1128
1129 def Xr : BaseShift<shift_type, GPR64, asm, OpNode> {
1130 let Inst{31} = 1;
1131 }
Tim Northover2ad88d32014-04-03 09:26:16 +00001132
1133 def : Pat<(i32 (OpNode GPR32:$Rn, i64:$Rm)),
1134 (!cast<Instruction>(NAME # "Wr") GPR32:$Rn,
1135 (EXTRACT_SUBREG i64:$Rm, sub_32))>;
1136
1137 def : Pat<(i32 (OpNode GPR32:$Rn, (i64 (zext GPR32:$Rm)))),
1138 (!cast<Instruction>(NAME # "Wr") GPR32:$Rn, GPR32:$Rm)>;
1139
1140 def : Pat<(i32 (OpNode GPR32:$Rn, (i64 (anyext GPR32:$Rm)))),
1141 (!cast<Instruction>(NAME # "Wr") GPR32:$Rn, GPR32:$Rm)>;
1142
1143 def : Pat<(i32 (OpNode GPR32:$Rn, (i64 (sext GPR32:$Rm)))),
1144 (!cast<Instruction>(NAME # "Wr") GPR32:$Rn, GPR32:$Rm)>;
Tim Northover00ed9962014-03-29 10:18:08 +00001145}
1146
1147class ShiftAlias<string asm, Instruction inst, RegisterClass regtype>
1148 : InstAlias<asm#" $dst, $src1, $src2",
1149 (inst regtype:$dst, regtype:$src1, regtype:$src2)>;
1150
1151class BaseMulAccum<bit isSub, bits<3> opc, RegisterClass multype,
1152 RegisterClass addtype, string asm,
1153 list<dag> pattern>
1154 : I<(outs addtype:$Rd), (ins multype:$Rn, multype:$Rm, addtype:$Ra),
1155 asm, "\t$Rd, $Rn, $Rm, $Ra", "", pattern> {
1156 bits<5> Rd;
1157 bits<5> Rn;
1158 bits<5> Rm;
1159 bits<5> Ra;
1160 let Inst{30-24} = 0b0011011;
1161 let Inst{23-21} = opc;
1162 let Inst{20-16} = Rm;
1163 let Inst{15} = isSub;
1164 let Inst{14-10} = Ra;
1165 let Inst{9-5} = Rn;
1166 let Inst{4-0} = Rd;
1167}
1168
1169multiclass MulAccum<bit isSub, string asm, SDNode AccNode> {
1170 def Wrrr : BaseMulAccum<isSub, 0b000, GPR32, GPR32, asm,
1171 [(set GPR32:$Rd, (AccNode GPR32:$Ra, (mul GPR32:$Rn, GPR32:$Rm)))]>,
1172 Sched<[WriteIM32]> {
1173 let Inst{31} = 0;
1174 }
1175
1176 def Xrrr : BaseMulAccum<isSub, 0b000, GPR64, GPR64, asm,
1177 [(set GPR64:$Rd, (AccNode GPR64:$Ra, (mul GPR64:$Rn, GPR64:$Rm)))]>,
1178 Sched<[WriteIM64]> {
1179 let Inst{31} = 1;
1180 }
1181}
1182
1183class WideMulAccum<bit isSub, bits<3> opc, string asm,
1184 SDNode AccNode, SDNode ExtNode>
1185 : BaseMulAccum<isSub, opc, GPR32, GPR64, asm,
1186 [(set GPR64:$Rd, (AccNode GPR64:$Ra,
1187 (mul (ExtNode GPR32:$Rn), (ExtNode GPR32:$Rm))))]>,
1188 Sched<[WriteIM32]> {
1189 let Inst{31} = 1;
1190}
1191
1192class MulHi<bits<3> opc, string asm, SDNode OpNode>
1193 : I<(outs GPR64:$Rd), (ins GPR64:$Rn, GPR64:$Rm),
1194 asm, "\t$Rd, $Rn, $Rm", "",
1195 [(set GPR64:$Rd, (OpNode GPR64:$Rn, GPR64:$Rm))]>,
1196 Sched<[WriteIM64]> {
1197 bits<5> Rd;
1198 bits<5> Rn;
1199 bits<5> Rm;
1200 let Inst{31-24} = 0b10011011;
1201 let Inst{23-21} = opc;
1202 let Inst{20-16} = Rm;
Bradley Smith8f906a32014-04-09 14:43:15 +00001203 let Inst{15} = 0;
Tim Northover00ed9962014-03-29 10:18:08 +00001204 let Inst{9-5} = Rn;
1205 let Inst{4-0} = Rd;
Bradley Smith8f906a32014-04-09 14:43:15 +00001206
1207 // The Ra field of SMULH and UMULH is unused: it should be assembled as 31
1208 // (i.e. all bits 1) but is ignored by the processor.
1209 let PostEncoderMethod = "fixMulHigh";
Tim Northover00ed9962014-03-29 10:18:08 +00001210}
1211
1212class MulAccumWAlias<string asm, Instruction inst>
1213 : InstAlias<asm#" $dst, $src1, $src2",
1214 (inst GPR32:$dst, GPR32:$src1, GPR32:$src2, WZR)>;
1215class MulAccumXAlias<string asm, Instruction inst>
1216 : InstAlias<asm#" $dst, $src1, $src2",
1217 (inst GPR64:$dst, GPR64:$src1, GPR64:$src2, XZR)>;
1218class WideMulAccumAlias<string asm, Instruction inst>
1219 : InstAlias<asm#" $dst, $src1, $src2",
1220 (inst GPR64:$dst, GPR32:$src1, GPR32:$src2, XZR)>;
1221
1222class BaseCRC32<bit sf, bits<2> sz, bit C, RegisterClass StreamReg,
1223 SDPatternOperator OpNode, string asm>
1224 : I<(outs GPR32:$Rd), (ins GPR32:$Rn, StreamReg:$Rm),
1225 asm, "\t$Rd, $Rn, $Rm", "",
1226 [(set GPR32:$Rd, (OpNode GPR32:$Rn, StreamReg:$Rm))]>,
1227 Sched<[WriteISReg]> {
1228 bits<5> Rd;
1229 bits<5> Rn;
1230 bits<5> Rm;
1231
1232 let Inst{31} = sf;
1233 let Inst{30-21} = 0b0011010110;
1234 let Inst{20-16} = Rm;
1235 let Inst{15-13} = 0b010;
1236 let Inst{12} = C;
1237 let Inst{11-10} = sz;
1238 let Inst{9-5} = Rn;
1239 let Inst{4-0} = Rd;
1240}
1241
1242//---
1243// Address generation.
1244//---
1245
1246class ADRI<bit page, string asm, Operand adr, list<dag> pattern>
1247 : I<(outs GPR64:$Xd), (ins adr:$label), asm, "\t$Xd, $label", "",
1248 pattern>,
1249 Sched<[WriteI]> {
1250 bits<5> Xd;
1251 bits<21> label;
1252 let Inst{31} = page;
1253 let Inst{30-29} = label{1-0};
1254 let Inst{28-24} = 0b10000;
1255 let Inst{23-5} = label{20-2};
1256 let Inst{4-0} = Xd;
1257
1258 let DecoderMethod = "DecodeAdrInstruction";
1259}
1260
1261//---
1262// Move immediate.
1263//---
1264
1265def movimm32_imm : Operand<i32> {
1266 let ParserMatchClass = Imm0_65535Operand;
1267 let EncoderMethod = "getMoveWideImmOpValue";
1268}
1269def movimm32_shift : Operand<i32> {
1270 let PrintMethod = "printShifter";
1271 let ParserMatchClass = MovImm32ShifterOperand;
1272}
1273def movimm64_shift : Operand<i32> {
1274 let PrintMethod = "printShifter";
1275 let ParserMatchClass = MovImm64ShifterOperand;
1276}
1277let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
1278class BaseMoveImmediate<bits<2> opc, RegisterClass regtype, Operand shifter,
1279 string asm>
1280 : I<(outs regtype:$Rd), (ins movimm32_imm:$imm, shifter:$shift),
1281 asm, "\t$Rd, $imm$shift", "", []>,
1282 Sched<[WriteImm]> {
1283 bits<5> Rd;
1284 bits<16> imm;
1285 bits<6> shift;
1286 let Inst{30-29} = opc;
1287 let Inst{28-23} = 0b100101;
1288 let Inst{22-21} = shift{5-4};
1289 let Inst{20-5} = imm;
1290 let Inst{4-0} = Rd;
1291
1292 let DecoderMethod = "DecodeMoveImmInstruction";
1293}
1294
1295multiclass MoveImmediate<bits<2> opc, string asm> {
1296 def Wi : BaseMoveImmediate<opc, GPR32, movimm32_shift, asm> {
1297 let Inst{31} = 0;
1298 }
1299
1300 def Xi : BaseMoveImmediate<opc, GPR64, movimm64_shift, asm> {
1301 let Inst{31} = 1;
1302 }
1303}
1304
1305let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
1306class BaseInsertImmediate<bits<2> opc, RegisterClass regtype, Operand shifter,
1307 string asm>
1308 : I<(outs regtype:$Rd),
1309 (ins regtype:$src, movimm32_imm:$imm, shifter:$shift),
1310 asm, "\t$Rd, $imm$shift", "$src = $Rd", []>,
1311 Sched<[WriteI]> {
1312 bits<5> Rd;
1313 bits<16> imm;
1314 bits<6> shift;
1315 let Inst{30-29} = opc;
1316 let Inst{28-23} = 0b100101;
1317 let Inst{22-21} = shift{5-4};
1318 let Inst{20-5} = imm;
1319 let Inst{4-0} = Rd;
1320
1321 let DecoderMethod = "DecodeMoveImmInstruction";
1322}
1323
1324multiclass InsertImmediate<bits<2> opc, string asm> {
1325 def Wi : BaseInsertImmediate<opc, GPR32, movimm32_shift, asm> {
1326 let Inst{31} = 0;
1327 }
1328
1329 def Xi : BaseInsertImmediate<opc, GPR64, movimm64_shift, asm> {
1330 let Inst{31} = 1;
1331 }
1332}
1333
1334//---
1335// Add/Subtract
1336//---
1337
1338class BaseAddSubImm<bit isSub, bit setFlags, RegisterClass dstRegtype,
1339 RegisterClass srcRegtype, addsub_shifted_imm immtype,
1340 string asm, SDPatternOperator OpNode>
1341 : I<(outs dstRegtype:$Rd), (ins srcRegtype:$Rn, immtype:$imm),
1342 asm, "\t$Rd, $Rn, $imm", "",
1343 [(set dstRegtype:$Rd, (OpNode srcRegtype:$Rn, immtype:$imm))]>,
1344 Sched<[WriteI]> {
1345 bits<5> Rd;
1346 bits<5> Rn;
1347 bits<14> imm;
1348 let Inst{30} = isSub;
1349 let Inst{29} = setFlags;
1350 let Inst{28-24} = 0b10001;
1351 let Inst{23-22} = imm{13-12}; // '00' => lsl #0, '01' => lsl #12
1352 let Inst{21-10} = imm{11-0};
1353 let Inst{9-5} = Rn;
1354 let Inst{4-0} = Rd;
1355 let DecoderMethod = "DecodeBaseAddSubImm";
1356}
1357
1358class BaseAddSubRegPseudo<RegisterClass regtype,
1359 SDPatternOperator OpNode>
1360 : Pseudo<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm),
1361 [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm))]>,
1362 Sched<[WriteI]>;
1363
1364class BaseAddSubSReg<bit isSub, bit setFlags, RegisterClass regtype,
1365 arith_shifted_reg shifted_regtype, string asm,
1366 SDPatternOperator OpNode>
1367 : I<(outs regtype:$Rd), (ins regtype:$Rn, shifted_regtype:$Rm),
1368 asm, "\t$Rd, $Rn, $Rm", "",
1369 [(set regtype:$Rd, (OpNode regtype:$Rn, shifted_regtype:$Rm))]>,
1370 Sched<[WriteISReg]> {
1371 // The operands are in order to match the 'addr' MI operands, so we
1372 // don't need an encoder method and by-name matching. Just use the default
1373 // in-order handling. Since we're using by-order, make sure the names
1374 // do not match.
1375 bits<5> dst;
1376 bits<5> src1;
1377 bits<5> src2;
1378 bits<8> shift;
1379 let Inst{30} = isSub;
1380 let Inst{29} = setFlags;
1381 let Inst{28-24} = 0b01011;
1382 let Inst{23-22} = shift{7-6};
1383 let Inst{21} = 0;
1384 let Inst{20-16} = src2;
1385 let Inst{15-10} = shift{5-0};
1386 let Inst{9-5} = src1;
1387 let Inst{4-0} = dst;
1388
1389 let DecoderMethod = "DecodeThreeAddrSRegInstruction";
1390}
1391
1392class BaseAddSubEReg<bit isSub, bit setFlags, RegisterClass dstRegtype,
1393 RegisterClass src1Regtype, Operand src2Regtype,
1394 string asm, SDPatternOperator OpNode>
1395 : I<(outs dstRegtype:$R1),
1396 (ins src1Regtype:$R2, src2Regtype:$R3),
1397 asm, "\t$R1, $R2, $R3", "",
1398 [(set dstRegtype:$R1, (OpNode src1Regtype:$R2, src2Regtype:$R3))]>,
1399 Sched<[WriteIEReg]> {
1400 bits<5> Rd;
1401 bits<5> Rn;
1402 bits<5> Rm;
1403 bits<6> ext;
1404 let Inst{30} = isSub;
1405 let Inst{29} = setFlags;
1406 let Inst{28-24} = 0b01011;
1407 let Inst{23-21} = 0b001;
1408 let Inst{20-16} = Rm;
1409 let Inst{15-13} = ext{5-3};
1410 let Inst{12-10} = ext{2-0};
1411 let Inst{9-5} = Rn;
1412 let Inst{4-0} = Rd;
1413
1414 let DecoderMethod = "DecodeAddSubERegInstruction";
1415}
1416
1417let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
1418class BaseAddSubEReg64<bit isSub, bit setFlags, RegisterClass dstRegtype,
1419 RegisterClass src1Regtype, RegisterClass src2Regtype,
1420 Operand ext_op, string asm>
1421 : I<(outs dstRegtype:$Rd),
1422 (ins src1Regtype:$Rn, src2Regtype:$Rm, ext_op:$ext),
1423 asm, "\t$Rd, $Rn, $Rm$ext", "", []>,
1424 Sched<[WriteIEReg]> {
1425 bits<5> Rd;
1426 bits<5> Rn;
1427 bits<5> Rm;
1428 bits<6> ext;
1429 let Inst{30} = isSub;
1430 let Inst{29} = setFlags;
1431 let Inst{28-24} = 0b01011;
1432 let Inst{23-21} = 0b001;
1433 let Inst{20-16} = Rm;
1434 let Inst{15} = ext{5};
1435 let Inst{12-10} = ext{2-0};
1436 let Inst{9-5} = Rn;
1437 let Inst{4-0} = Rd;
1438
1439 let DecoderMethod = "DecodeAddSubERegInstruction";
1440}
1441
1442// Aliases for register+register add/subtract.
1443class AddSubRegAlias<string asm, Instruction inst, RegisterClass dstRegtype,
1444 RegisterClass src1Regtype, RegisterClass src2Regtype,
1445 int shiftExt>
1446 : InstAlias<asm#" $dst, $src1, $src2",
1447 (inst dstRegtype:$dst, src1Regtype:$src1, src2Regtype:$src2,
1448 shiftExt)>;
1449
1450multiclass AddSub<bit isSub, string mnemonic,
1451 SDPatternOperator OpNode = null_frag> {
1452 let hasSideEffects = 0 in {
1453 // Add/Subtract immediate
1454 def Wri : BaseAddSubImm<isSub, 0, GPR32sp, GPR32sp, addsub_shifted_imm32,
1455 mnemonic, OpNode> {
1456 let Inst{31} = 0;
1457 }
1458 def Xri : BaseAddSubImm<isSub, 0, GPR64sp, GPR64sp, addsub_shifted_imm64,
1459 mnemonic, OpNode> {
1460 let Inst{31} = 1;
1461 }
1462
1463 // Add/Subtract register - Only used for CodeGen
1464 def Wrr : BaseAddSubRegPseudo<GPR32, OpNode>;
1465 def Xrr : BaseAddSubRegPseudo<GPR64, OpNode>;
1466
1467 // Add/Subtract shifted register
1468 def Wrs : BaseAddSubSReg<isSub, 0, GPR32, arith_shifted_reg32, mnemonic,
1469 OpNode> {
1470 let Inst{31} = 0;
1471 }
1472 def Xrs : BaseAddSubSReg<isSub, 0, GPR64, arith_shifted_reg64, mnemonic,
1473 OpNode> {
1474 let Inst{31} = 1;
1475 }
1476 }
1477
1478 // Add/Subtract extended register
1479 let AddedComplexity = 1, hasSideEffects = 0 in {
1480 def Wrx : BaseAddSubEReg<isSub, 0, GPR32sp, GPR32sp,
1481 arith_extended_reg32<i32>, mnemonic, OpNode> {
1482 let Inst{31} = 0;
1483 }
1484 def Xrx : BaseAddSubEReg<isSub, 0, GPR64sp, GPR64sp,
1485 arith_extended_reg32to64<i64>, mnemonic, OpNode> {
1486 let Inst{31} = 1;
1487 }
1488 }
1489
1490 def Xrx64 : BaseAddSubEReg64<isSub, 0, GPR64sp, GPR64sp, GPR64,
1491 arith_extendlsl64, mnemonic> {
1492 // UXTX and SXTX only.
1493 let Inst{14-13} = 0b11;
1494 let Inst{31} = 1;
1495 }
1496
1497 // Register/register aliases with no shift when SP is not used.
1498 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrs"),
1499 GPR32, GPR32, GPR32, 0>;
1500 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Xrs"),
1501 GPR64, GPR64, GPR64, 0>;
1502
1503 // Register/register aliases with no shift when either the destination or
1504 // first source register is SP. This relies on the shifted register aliases
1505 // above matching first in the case when SP is not used.
1506 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrx"),
1507 GPR32sp, GPR32sp, GPR32, 16>; // UXTW #0
1508 def : AddSubRegAlias<mnemonic,
1509 !cast<Instruction>(NAME#"Xrx64"),
1510 GPR64sp, GPR64sp, GPR64, 24>; // UXTX #0
1511}
1512
1513multiclass AddSubS<bit isSub, string mnemonic, SDNode OpNode> {
1514 let isCompare = 1, Defs = [CPSR] in {
1515 // Add/Subtract immediate
1516 def Wri : BaseAddSubImm<isSub, 1, GPR32, GPR32sp, addsub_shifted_imm32,
1517 mnemonic, OpNode> {
1518 let Inst{31} = 0;
1519 }
1520 def Xri : BaseAddSubImm<isSub, 1, GPR64, GPR64sp, addsub_shifted_imm64,
1521 mnemonic, OpNode> {
1522 let Inst{31} = 1;
1523 }
1524
1525 // Add/Subtract register
1526 def Wrr : BaseAddSubRegPseudo<GPR32, OpNode>;
1527 def Xrr : BaseAddSubRegPseudo<GPR64, OpNode>;
1528
1529 // Add/Subtract shifted register
1530 def Wrs : BaseAddSubSReg<isSub, 1, GPR32, arith_shifted_reg32, mnemonic,
1531 OpNode> {
1532 let Inst{31} = 0;
1533 }
1534 def Xrs : BaseAddSubSReg<isSub, 1, GPR64, arith_shifted_reg64, mnemonic,
1535 OpNode> {
1536 let Inst{31} = 1;
1537 }
1538
1539 // Add/Subtract extended register
1540 let AddedComplexity = 1 in {
1541 def Wrx : BaseAddSubEReg<isSub, 1, GPR32, GPR32sp,
1542 arith_extended_reg32<i32>, mnemonic, OpNode> {
1543 let Inst{31} = 0;
1544 }
1545 def Xrx : BaseAddSubEReg<isSub, 1, GPR64, GPR64sp,
1546 arith_extended_reg32<i64>, mnemonic, OpNode> {
1547 let Inst{31} = 1;
1548 }
1549 }
1550
1551 def Xrx64 : BaseAddSubEReg64<isSub, 1, GPR64, GPR64sp, GPR64,
1552 arith_extendlsl64, mnemonic> {
1553 // UXTX and SXTX only.
1554 let Inst{14-13} = 0b11;
1555 let Inst{31} = 1;
1556 }
1557 } // Defs = [CPSR]
1558
1559 // Register/register aliases with no shift when SP is not used.
1560 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrs"),
1561 GPR32, GPR32, GPR32, 0>;
1562 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Xrs"),
1563 GPR64, GPR64, GPR64, 0>;
1564
1565 // Register/register aliases with no shift when the first source register
1566 // is SP. This relies on the shifted register aliases above matching first
1567 // in the case when SP is not used.
1568 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrx"),
1569 GPR32, GPR32sp, GPR32, 16>; // UXTW #0
1570 def : AddSubRegAlias<mnemonic,
1571 !cast<Instruction>(NAME#"Xrx64"),
1572 GPR64, GPR64sp, GPR64, 24>; // UXTX #0
1573}
1574
1575//---
1576// Extract
1577//---
1578def SDTA64EXTR : SDTypeProfile<1, 3, [SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>,
Tim Northover2ad88d32014-04-03 09:26:16 +00001579 SDTCisPtrTy<3>]>;
Tim Northover00ed9962014-03-29 10:18:08 +00001580def ARM64Extr : SDNode<"ARM64ISD::EXTR", SDTA64EXTR>;
1581
1582class BaseExtractImm<RegisterClass regtype, Operand imm_type, string asm,
1583 list<dag> patterns>
1584 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, imm_type:$imm),
1585 asm, "\t$Rd, $Rn, $Rm, $imm", "", patterns>,
1586 Sched<[WriteExtr, ReadExtrHi]> {
1587 bits<5> Rd;
1588 bits<5> Rn;
1589 bits<5> Rm;
1590 bits<6> imm;
1591
1592 let Inst{30-23} = 0b00100111;
1593 let Inst{21} = 0;
1594 let Inst{20-16} = Rm;
1595 let Inst{15-10} = imm;
1596 let Inst{9-5} = Rn;
1597 let Inst{4-0} = Rd;
1598}
1599
1600multiclass ExtractImm<string asm> {
1601 def Wrri : BaseExtractImm<GPR32, imm0_31, asm,
1602 [(set GPR32:$Rd,
1603 (ARM64Extr GPR32:$Rn, GPR32:$Rm, imm0_31:$imm))]> {
1604 let Inst{31} = 0;
1605 let Inst{22} = 0;
1606 }
1607 def Xrri : BaseExtractImm<GPR64, imm0_63, asm,
1608 [(set GPR64:$Rd,
1609 (ARM64Extr GPR64:$Rn, GPR64:$Rm, imm0_63:$imm))]> {
1610
1611 let Inst{31} = 1;
1612 let Inst{22} = 1;
1613 }
1614}
1615
1616//---
1617// Bitfield
1618//---
1619
1620let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
1621class BaseBitfieldImm<bits<2> opc,
1622 RegisterClass regtype, Operand imm_type, string asm>
1623 : I<(outs regtype:$Rd), (ins regtype:$Rn, imm_type:$immr, imm_type:$imms),
1624 asm, "\t$Rd, $Rn, $immr, $imms", "", []>,
1625 Sched<[WriteIS]> {
1626 bits<5> Rd;
1627 bits<5> Rn;
1628 bits<6> immr;
1629 bits<6> imms;
1630
1631 let Inst{30-29} = opc;
1632 let Inst{28-23} = 0b100110;
1633 let Inst{21-16} = immr;
1634 let Inst{15-10} = imms;
1635 let Inst{9-5} = Rn;
1636 let Inst{4-0} = Rd;
1637}
1638
1639multiclass BitfieldImm<bits<2> opc, string asm> {
1640 def Wri : BaseBitfieldImm<opc, GPR32, imm0_31, asm> {
1641 let Inst{31} = 0;
1642 let Inst{22} = 0;
1643 }
1644 def Xri : BaseBitfieldImm<opc, GPR64, imm0_63, asm> {
1645 let Inst{31} = 1;
1646 let Inst{22} = 1;
1647 }
1648}
1649
1650let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
1651class BaseBitfieldImmWith2RegArgs<bits<2> opc,
1652 RegisterClass regtype, Operand imm_type, string asm>
1653 : I<(outs regtype:$Rd), (ins regtype:$src, regtype:$Rn, imm_type:$immr,
1654 imm_type:$imms),
1655 asm, "\t$Rd, $Rn, $immr, $imms", "$src = $Rd", []>,
1656 Sched<[WriteIS]> {
1657 bits<5> Rd;
1658 bits<5> Rn;
1659 bits<6> immr;
1660 bits<6> imms;
1661
1662 let Inst{30-29} = opc;
1663 let Inst{28-23} = 0b100110;
1664 let Inst{21-16} = immr;
1665 let Inst{15-10} = imms;
1666 let Inst{9-5} = Rn;
1667 let Inst{4-0} = Rd;
1668}
1669
1670multiclass BitfieldImmWith2RegArgs<bits<2> opc, string asm> {
1671 def Wri : BaseBitfieldImmWith2RegArgs<opc, GPR32, imm0_31, asm> {
1672 let Inst{31} = 0;
1673 let Inst{22} = 0;
1674 }
1675 def Xri : BaseBitfieldImmWith2RegArgs<opc, GPR64, imm0_63, asm> {
1676 let Inst{31} = 1;
1677 let Inst{22} = 1;
1678 }
1679}
1680
1681//---
1682// Logical
1683//---
1684
1685// Logical (immediate)
1686class BaseLogicalImm<bits<2> opc, RegisterClass dregtype,
1687 RegisterClass sregtype, Operand imm_type, string asm,
1688 list<dag> pattern>
1689 : I<(outs dregtype:$Rd), (ins sregtype:$Rn, imm_type:$imm),
1690 asm, "\t$Rd, $Rn, $imm", "", pattern>,
1691 Sched<[WriteI]> {
1692 bits<5> Rd;
1693 bits<5> Rn;
1694 bits<13> imm;
1695 let Inst{30-29} = opc;
1696 let Inst{28-23} = 0b100100;
1697 let Inst{22} = imm{12};
1698 let Inst{21-16} = imm{11-6};
1699 let Inst{15-10} = imm{5-0};
1700 let Inst{9-5} = Rn;
1701 let Inst{4-0} = Rd;
1702
1703 let DecoderMethod = "DecodeLogicalImmInstruction";
1704}
1705
1706// Logical (shifted register)
1707class BaseLogicalSReg<bits<2> opc, bit N, RegisterClass regtype,
1708 logical_shifted_reg shifted_regtype, string asm,
1709 list<dag> pattern>
1710 : I<(outs regtype:$Rd), (ins regtype:$Rn, shifted_regtype:$Rm),
1711 asm, "\t$Rd, $Rn, $Rm", "", pattern>,
1712 Sched<[WriteISReg]> {
1713 // The operands are in order to match the 'addr' MI operands, so we
1714 // don't need an encoder method and by-name matching. Just use the default
1715 // in-order handling. Since we're using by-order, make sure the names
1716 // do not match.
1717 bits<5> dst;
1718 bits<5> src1;
1719 bits<5> src2;
1720 bits<8> shift;
1721 let Inst{30-29} = opc;
1722 let Inst{28-24} = 0b01010;
1723 let Inst{23-22} = shift{7-6};
1724 let Inst{21} = N;
1725 let Inst{20-16} = src2;
1726 let Inst{15-10} = shift{5-0};
1727 let Inst{9-5} = src1;
1728 let Inst{4-0} = dst;
1729
1730 let DecoderMethod = "DecodeThreeAddrSRegInstruction";
1731}
1732
1733// Aliases for register+register logical instructions.
1734class LogicalRegAlias<string asm, Instruction inst, RegisterClass regtype>
1735 : InstAlias<asm#" $dst, $src1, $src2",
1736 (inst regtype:$dst, regtype:$src1, regtype:$src2, 0)>;
1737
1738let AddedComplexity = 6 in
1739multiclass LogicalImm<bits<2> opc, string mnemonic, SDNode OpNode> {
1740 def Wri : BaseLogicalImm<opc, GPR32sp, GPR32, logical_imm32, mnemonic,
1741 [(set GPR32sp:$Rd, (OpNode GPR32:$Rn,
1742 logical_imm32:$imm))]> {
1743 let Inst{31} = 0;
1744 let Inst{22} = 0; // 64-bit version has an additional bit of immediate.
1745 }
1746 def Xri : BaseLogicalImm<opc, GPR64sp, GPR64, logical_imm64, mnemonic,
1747 [(set GPR64sp:$Rd, (OpNode GPR64:$Rn,
1748 logical_imm64:$imm))]> {
1749 let Inst{31} = 1;
1750 }
1751}
1752
1753multiclass LogicalImmS<bits<2> opc, string mnemonic, SDNode OpNode> {
1754 let isCompare = 1, Defs = [CPSR] in {
1755 def Wri : BaseLogicalImm<opc, GPR32, GPR32, logical_imm32, mnemonic,
1756 [(set GPR32:$Rd, (OpNode GPR32:$Rn, logical_imm32:$imm))]> {
1757 let Inst{31} = 0;
1758 let Inst{22} = 0; // 64-bit version has an additional bit of immediate.
1759 }
1760 def Xri : BaseLogicalImm<opc, GPR64, GPR64, logical_imm64, mnemonic,
1761 [(set GPR64:$Rd, (OpNode GPR64:$Rn, logical_imm64:$imm))]> {
1762 let Inst{31} = 1;
1763 }
1764 } // end Defs = [CPSR]
1765}
1766
1767class BaseLogicalRegPseudo<RegisterClass regtype, SDPatternOperator OpNode>
1768 : Pseudo<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm),
1769 [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm))]>,
1770 Sched<[WriteI]>;
1771
1772// Split from LogicalImm as not all instructions have both.
1773multiclass LogicalReg<bits<2> opc, bit N, string mnemonic,
1774 SDPatternOperator OpNode> {
1775 def Wrr : BaseLogicalRegPseudo<GPR32, OpNode>;
1776 def Xrr : BaseLogicalRegPseudo<GPR64, OpNode>;
1777
1778 def Wrs : BaseLogicalSReg<opc, N, GPR32, logical_shifted_reg32, mnemonic,
1779 [(set GPR32:$Rd, (OpNode GPR32:$Rn,
1780 logical_shifted_reg32:$Rm))]> {
1781 let Inst{31} = 0;
1782 }
1783 def Xrs : BaseLogicalSReg<opc, N, GPR64, logical_shifted_reg64, mnemonic,
1784 [(set GPR64:$Rd, (OpNode GPR64:$Rn,
1785 logical_shifted_reg64:$Rm))]> {
1786 let Inst{31} = 1;
1787 }
1788
1789 def : LogicalRegAlias<mnemonic,
1790 !cast<Instruction>(NAME#"Wrs"), GPR32>;
1791 def : LogicalRegAlias<mnemonic,
1792 !cast<Instruction>(NAME#"Xrs"), GPR64>;
1793}
1794
1795// Split from LogicalReg to allow setting CPSR Defs
1796multiclass LogicalRegS<bits<2> opc, bit N, string mnemonic> {
1797 let Defs = [CPSR], mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
1798 def Wrs : BaseLogicalSReg<opc, N, GPR32, logical_shifted_reg32, mnemonic, []>{
1799 let Inst{31} = 0;
1800 }
1801 def Xrs : BaseLogicalSReg<opc, N, GPR64, logical_shifted_reg64, mnemonic, []>{
1802 let Inst{31} = 1;
1803 }
1804 } // Defs = [CPSR]
1805
1806 def : LogicalRegAlias<mnemonic,
1807 !cast<Instruction>(NAME#"Wrs"), GPR32>;
1808 def : LogicalRegAlias<mnemonic,
1809 !cast<Instruction>(NAME#"Xrs"), GPR64>;
1810}
1811
1812//---
1813// Conditionally set flags
1814//---
1815
1816// Condition code.
1817// 4-bit immediate. Pretty-printed as <cc>
1818def ccode : Operand<i32> {
1819 let PrintMethod = "printCondCode";
1820}
1821
1822let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
1823class BaseCondSetFlagsImm<bit op, RegisterClass regtype, string asm>
1824 : I<(outs), (ins regtype:$Rn, imm0_31:$imm, imm0_15:$nzcv, ccode:$cond),
1825 asm, "\t$Rn, $imm, $nzcv, $cond", "", []>,
1826 Sched<[WriteI]> {
1827 let Uses = [CPSR];
1828 let Defs = [CPSR];
1829
1830 bits<5> Rn;
1831 bits<5> imm;
1832 bits<4> nzcv;
1833 bits<4> cond;
1834
1835 let Inst{30} = op;
1836 let Inst{29-21} = 0b111010010;
1837 let Inst{20-16} = imm;
1838 let Inst{15-12} = cond;
1839 let Inst{11-10} = 0b10;
1840 let Inst{9-5} = Rn;
1841 let Inst{4} = 0b0;
1842 let Inst{3-0} = nzcv;
1843}
1844
1845multiclass CondSetFlagsImm<bit op, string asm> {
1846 def Wi : BaseCondSetFlagsImm<op, GPR32, asm> {
1847 let Inst{31} = 0;
1848 }
1849 def Xi : BaseCondSetFlagsImm<op, GPR64, asm> {
1850 let Inst{31} = 1;
1851 }
1852}
1853
1854let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
1855class BaseCondSetFlagsReg<bit op, RegisterClass regtype, string asm>
1856 : I<(outs), (ins regtype:$Rn, regtype:$Rm, imm0_15:$nzcv, ccode:$cond),
1857 asm, "\t$Rn, $Rm, $nzcv, $cond", "", []>,
1858 Sched<[WriteI]> {
1859 let Uses = [CPSR];
1860 let Defs = [CPSR];
1861
1862 bits<5> Rn;
1863 bits<5> Rm;
1864 bits<4> nzcv;
1865 bits<4> cond;
1866
1867 let Inst{30} = op;
1868 let Inst{29-21} = 0b111010010;
1869 let Inst{20-16} = Rm;
1870 let Inst{15-12} = cond;
1871 let Inst{11-10} = 0b00;
1872 let Inst{9-5} = Rn;
1873 let Inst{4} = 0b0;
1874 let Inst{3-0} = nzcv;
1875}
1876
1877multiclass CondSetFlagsReg<bit op, string asm> {
1878 def Wr : BaseCondSetFlagsReg<op, GPR32, asm> {
1879 let Inst{31} = 0;
1880 }
1881 def Xr : BaseCondSetFlagsReg<op, GPR64, asm> {
1882 let Inst{31} = 1;
1883 }
1884}
1885
1886//---
1887// Conditional select
1888//---
1889
1890class BaseCondSelect<bit op, bits<2> op2, RegisterClass regtype, string asm>
1891 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, ccode:$cond),
1892 asm, "\t$Rd, $Rn, $Rm, $cond", "",
1893 [(set regtype:$Rd,
1894 (ARM64csel regtype:$Rn, regtype:$Rm, (i32 imm:$cond), CPSR))]>,
1895 Sched<[WriteI]> {
1896 let Uses = [CPSR];
1897
1898 bits<5> Rd;
1899 bits<5> Rn;
1900 bits<5> Rm;
1901 bits<4> cond;
1902
1903 let Inst{30} = op;
1904 let Inst{29-21} = 0b011010100;
1905 let Inst{20-16} = Rm;
1906 let Inst{15-12} = cond;
1907 let Inst{11-10} = op2;
1908 let Inst{9-5} = Rn;
1909 let Inst{4-0} = Rd;
1910}
1911
1912multiclass CondSelect<bit op, bits<2> op2, string asm> {
1913 def Wr : BaseCondSelect<op, op2, GPR32, asm> {
1914 let Inst{31} = 0;
1915 }
1916 def Xr : BaseCondSelect<op, op2, GPR64, asm> {
1917 let Inst{31} = 1;
1918 }
1919}
1920
1921class BaseCondSelectOp<bit op, bits<2> op2, RegisterClass regtype, string asm,
1922 PatFrag frag>
1923 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, ccode:$cond),
1924 asm, "\t$Rd, $Rn, $Rm, $cond", "",
1925 [(set regtype:$Rd,
1926 (ARM64csel regtype:$Rn, (frag regtype:$Rm),
1927 (i32 imm:$cond), CPSR))]>,
1928 Sched<[WriteI]> {
1929 let Uses = [CPSR];
1930
1931 bits<5> Rd;
1932 bits<5> Rn;
1933 bits<5> Rm;
1934 bits<4> cond;
1935
1936 let Inst{30} = op;
1937 let Inst{29-21} = 0b011010100;
1938 let Inst{20-16} = Rm;
1939 let Inst{15-12} = cond;
1940 let Inst{11-10} = op2;
1941 let Inst{9-5} = Rn;
1942 let Inst{4-0} = Rd;
1943}
1944
1945multiclass CondSelectOp<bit op, bits<2> op2, string asm, PatFrag frag> {
1946 def Wr : BaseCondSelectOp<op, op2, GPR32, asm, frag> {
1947 let Inst{31} = 0;
1948 }
1949 def Xr : BaseCondSelectOp<op, op2, GPR64, asm, frag> {
1950 let Inst{31} = 1;
1951 }
1952}
1953
1954//---
1955// Special Mask Value
1956//---
1957def maski8_or_more : Operand<i32>,
1958 ImmLeaf<i32, [{ return (Imm & 0xff) == 0xff; }]> {
1959}
1960def maski16_or_more : Operand<i32>,
1961 ImmLeaf<i32, [{ return (Imm & 0xffff) == 0xffff; }]> {
1962}
1963
1964
1965//---
1966// Load/store
1967//---
1968
1969// (unsigned immediate)
1970// Indexed for 8-bit registers. offset is in range [0,4095].
1971def MemoryIndexed8Operand : AsmOperandClass {
1972 let Name = "MemoryIndexed8";
1973 let DiagnosticType = "InvalidMemoryIndexed8";
1974}
1975def am_indexed8 : Operand<i64>,
1976 ComplexPattern<i64, 2, "SelectAddrModeIndexed8", []> {
1977 let PrintMethod = "printAMIndexed8";
1978 let EncoderMethod
1979 = "getAMIndexed8OpValue<ARM64::fixup_arm64_ldst_imm12_scale1>";
1980 let ParserMatchClass = MemoryIndexed8Operand;
1981 let MIOperandInfo = (ops GPR64sp:$base, i64imm:$offset);
1982}
1983
1984// Indexed for 16-bit registers. offset is multiple of 2 in range [0,8190],
1985// stored as immval/2 (the 12-bit literal that encodes directly into the insn).
1986def MemoryIndexed16Operand : AsmOperandClass {
1987 let Name = "MemoryIndexed16";
1988 let DiagnosticType = "InvalidMemoryIndexed16";
1989}
1990def am_indexed16 : Operand<i64>,
1991 ComplexPattern<i64, 2, "SelectAddrModeIndexed16", []> {
1992 let PrintMethod = "printAMIndexed16";
1993 let EncoderMethod
1994 = "getAMIndexed8OpValue<ARM64::fixup_arm64_ldst_imm12_scale2>";
1995 let ParserMatchClass = MemoryIndexed16Operand;
1996 let MIOperandInfo = (ops GPR64sp:$base, i64imm:$offset);
1997}
1998
1999// Indexed for 32-bit registers. offset is multiple of 4 in range [0,16380],
2000// stored as immval/4 (the 12-bit literal that encodes directly into the insn).
2001def MemoryIndexed32Operand : AsmOperandClass {
2002 let Name = "MemoryIndexed32";
2003 let DiagnosticType = "InvalidMemoryIndexed32";
2004}
2005def am_indexed32 : Operand<i64>,
2006 ComplexPattern<i64, 2, "SelectAddrModeIndexed32", []> {
2007 let PrintMethod = "printAMIndexed32";
2008 let EncoderMethod
2009 = "getAMIndexed8OpValue<ARM64::fixup_arm64_ldst_imm12_scale4>";
2010 let ParserMatchClass = MemoryIndexed32Operand;
2011 let MIOperandInfo = (ops GPR64sp:$base, i64imm:$offset);
2012}
2013
2014// Indexed for 64-bit registers. offset is multiple of 8 in range [0,32760],
2015// stored as immval/8 (the 12-bit literal that encodes directly into the insn).
2016def MemoryIndexed64Operand : AsmOperandClass {
2017 let Name = "MemoryIndexed64";
2018 let DiagnosticType = "InvalidMemoryIndexed64";
2019}
2020def am_indexed64 : Operand<i64>,
2021 ComplexPattern<i64, 2, "SelectAddrModeIndexed64", []> {
2022 let PrintMethod = "printAMIndexed64";
2023 let EncoderMethod
2024 = "getAMIndexed8OpValue<ARM64::fixup_arm64_ldst_imm12_scale8>";
2025 let ParserMatchClass = MemoryIndexed64Operand;
2026 let MIOperandInfo = (ops GPR64sp:$base, i64imm:$offset);
2027}
2028
2029// Indexed for 128-bit registers. offset is multiple of 16 in range [0,65520],
2030// stored as immval/16 (the 12-bit literal that encodes directly into the insn).
2031def MemoryIndexed128Operand : AsmOperandClass {
2032 let Name = "MemoryIndexed128";
2033 let DiagnosticType = "InvalidMemoryIndexed128";
2034}
2035def am_indexed128 : Operand<i64>,
2036 ComplexPattern<i64, 2, "SelectAddrModeIndexed128", []> {
2037 let PrintMethod = "printAMIndexed128";
2038 let EncoderMethod
2039 = "getAMIndexed8OpValue<ARM64::fixup_arm64_ldst_imm12_scale16>";
2040 let ParserMatchClass = MemoryIndexed128Operand;
2041 let MIOperandInfo = (ops GPR64sp:$base, i64imm:$offset);
2042}
2043
2044// No offset.
2045def MemoryNoIndexOperand : AsmOperandClass { let Name = "MemoryNoIndex"; }
2046def am_noindex : Operand<i64>,
2047 ComplexPattern<i64, 1, "SelectAddrModeNoIndex", []> {
2048 let PrintMethod = "printAMNoIndex";
2049 let ParserMatchClass = MemoryNoIndexOperand;
2050 let MIOperandInfo = (ops GPR64sp:$base);
2051}
2052
2053class BaseLoadStoreUI<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops,
2054 string asm, list<dag> pattern>
2055 : I<oops, iops, asm, "\t$Rt, $addr", "", pattern> {
2056 bits<5> dst;
2057
2058 bits<17> addr;
2059 bits<5> base = addr{4-0};
2060 bits<12> offset = addr{16-5};
2061
2062 let Inst{31-30} = sz;
2063 let Inst{29-27} = 0b111;
2064 let Inst{26} = V;
2065 let Inst{25-24} = 0b01;
2066 let Inst{23-22} = opc;
2067 let Inst{21-10} = offset;
2068 let Inst{9-5} = base;
2069 let Inst{4-0} = dst;
2070
2071 let DecoderMethod = "DecodeUnsignedLdStInstruction";
2072}
2073
2074let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
2075class LoadUI<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2076 Operand indextype, string asm, list<dag> pattern>
2077 : BaseLoadStoreUI<sz, V, opc,
2078 (outs regtype:$Rt), (ins indextype:$addr), asm, pattern>,
2079 Sched<[WriteLD]>;
2080
2081let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
2082class StoreUI<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2083 Operand indextype, string asm, list<dag> pattern>
2084 : BaseLoadStoreUI<sz, V, opc,
2085 (outs), (ins regtype:$Rt, indextype:$addr), asm, pattern>,
2086 Sched<[WriteST]>;
2087
2088def PrefetchOperand : AsmOperandClass {
2089 let Name = "Prefetch";
2090 let ParserMethod = "tryParsePrefetch";
2091}
2092def prfop : Operand<i32> {
2093 let PrintMethod = "printPrefetchOp";
2094 let ParserMatchClass = PrefetchOperand;
2095}
2096
2097let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in
2098class PrefetchUI<bits<2> sz, bit V, bits<2> opc, string asm, list<dag> pat>
2099 : BaseLoadStoreUI<sz, V, opc,
2100 (outs), (ins prfop:$Rt, am_indexed64:$addr), asm, pat>,
2101 Sched<[WriteLD]>;
2102
2103//---
2104// Load literal
2105//---
2106
2107let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
2108class LoadLiteral<bits<2> opc, bit V, RegisterClass regtype, string asm>
2109 : I<(outs regtype:$Rt), (ins am_brcond:$label),
2110 asm, "\t$Rt, $label", "", []>,
2111 Sched<[WriteLD]> {
2112 bits<5> Rt;
2113 bits<19> label;
2114 let Inst{31-30} = opc;
2115 let Inst{29-27} = 0b011;
2116 let Inst{26} = V;
2117 let Inst{25-24} = 0b00;
2118 let Inst{23-5} = label;
2119 let Inst{4-0} = Rt;
2120}
2121
2122let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in
2123class PrefetchLiteral<bits<2> opc, bit V, string asm, list<dag> pat>
2124 : I<(outs), (ins prfop:$Rt, am_brcond:$label),
2125 asm, "\t$Rt, $label", "", pat>,
2126 Sched<[WriteLD]> {
2127 bits<5> Rt;
2128 bits<19> label;
2129 let Inst{31-30} = opc;
2130 let Inst{29-27} = 0b011;
2131 let Inst{26} = V;
2132 let Inst{25-24} = 0b00;
2133 let Inst{23-5} = label;
2134 let Inst{4-0} = Rt;
2135}
2136
2137//---
2138// Load/store register offset
2139//---
2140
2141class MemROAsmOperand<int sz> : AsmOperandClass {
2142 let Name = "MemoryRegisterOffset"#sz;
2143}
2144
2145def MemROAsmOperand8 : MemROAsmOperand<8>;
2146def MemROAsmOperand16 : MemROAsmOperand<16>;
2147def MemROAsmOperand32 : MemROAsmOperand<32>;
2148def MemROAsmOperand64 : MemROAsmOperand<64>;
2149def MemROAsmOperand128 : MemROAsmOperand<128>;
2150
2151class ro_indexed<int sz> : Operand<i64> { // ComplexPattern<...>
2152 let PrintMethod = "printMemoryRegOffset"#sz;
2153 let MIOperandInfo = (ops GPR64sp:$base, GPR64:$offset, i32imm:$extend);
2154}
2155
2156def ro_indexed8 : ro_indexed<8>, ComplexPattern<i64, 3, "SelectAddrModeRO8", []> {
2157 let ParserMatchClass = MemROAsmOperand8;
2158}
2159
2160def ro_indexed16 : ro_indexed<16>, ComplexPattern<i64, 3, "SelectAddrModeRO16", []> {
2161 let ParserMatchClass = MemROAsmOperand16;
2162}
2163
2164def ro_indexed32 : ro_indexed<32>, ComplexPattern<i64, 3, "SelectAddrModeRO32", []> {
2165 let ParserMatchClass = MemROAsmOperand32;
2166}
2167
2168def ro_indexed64 : ro_indexed<64>, ComplexPattern<i64, 3, "SelectAddrModeRO64", []> {
2169 let ParserMatchClass = MemROAsmOperand64;
2170}
2171
2172def ro_indexed128 : ro_indexed<128>, ComplexPattern<i64, 3, "SelectAddrModeRO128", []> {
2173 let ParserMatchClass = MemROAsmOperand128;
2174}
2175
2176class LoadStore8RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2177 string asm, dag ins, dag outs, list<dag> pat>
2178 : I<ins, outs, asm, "\t$Rt, $addr", "", pat> {
2179 // The operands are in order to match the 'addr' MI operands, so we
2180 // don't need an encoder method and by-name matching. Just use the default
2181 // in-order handling. Since we're using by-order, make sure the names
2182 // do not match.
2183 bits<5> dst;
2184 bits<5> base;
2185 bits<5> offset;
2186 bits<4> extend;
2187 let Inst{31-30} = sz;
2188 let Inst{29-27} = 0b111;
2189 let Inst{26} = V;
2190 let Inst{25-24} = 0b00;
2191 let Inst{23-22} = opc;
2192 let Inst{21} = 1;
2193 let Inst{20-16} = offset;
2194 let Inst{15-13} = extend{3-1};
2195
2196 let Inst{12} = extend{0};
2197 let Inst{11-10} = 0b10;
2198 let Inst{9-5} = base;
2199 let Inst{4-0} = dst;
2200
2201 let DecoderMethod = "DecodeRegOffsetLdStInstruction";
2202}
2203
2204class Load8RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2205 string asm, list<dag> pat>
2206 : LoadStore8RO<sz, V, opc, regtype, asm,
2207 (outs regtype:$Rt), (ins ro_indexed8:$addr), pat>,
2208 Sched<[WriteLDIdx, ReadAdrBase]>;
2209
2210class Store8RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2211 string asm, list<dag> pat>
2212 : LoadStore8RO<sz, V, opc, regtype, asm,
2213 (outs), (ins regtype:$Rt, ro_indexed8:$addr), pat>,
2214 Sched<[WriteSTIdx, ReadAdrBase]>;
2215
2216class LoadStore16RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2217 string asm, dag ins, dag outs, list<dag> pat>
2218 : I<ins, outs, asm, "\t$Rt, $addr", "", pat> {
2219 // The operands are in order to match the 'addr' MI operands, so we
2220 // don't need an encoder method and by-name matching. Just use the default
2221 // in-order handling. Since we're using by-order, make sure the names
2222 // do not match.
2223 bits<5> dst;
2224 bits<5> base;
2225 bits<5> offset;
2226 bits<4> extend;
2227 let Inst{31-30} = sz;
2228 let Inst{29-27} = 0b111;
2229 let Inst{26} = V;
2230 let Inst{25-24} = 0b00;
2231 let Inst{23-22} = opc;
2232 let Inst{21} = 1;
2233 let Inst{20-16} = offset;
2234 let Inst{15-13} = extend{3-1};
2235
2236 let Inst{12} = extend{0};
2237 let Inst{11-10} = 0b10;
2238 let Inst{9-5} = base;
2239 let Inst{4-0} = dst;
2240
2241 let DecoderMethod = "DecodeRegOffsetLdStInstruction";
2242}
2243
2244class Load16RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2245 string asm, list<dag> pat>
2246 : LoadStore16RO<sz, V, opc, regtype, asm,
2247 (outs regtype:$Rt), (ins ro_indexed16:$addr), pat>,
2248 Sched<[WriteLDIdx, ReadAdrBase]>;
2249
2250class Store16RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2251 string asm, list<dag> pat>
2252 : LoadStore16RO<sz, V, opc, regtype, asm,
2253 (outs), (ins regtype:$Rt, ro_indexed16:$addr), pat>,
2254 Sched<[WriteSTIdx, ReadAdrBase]>;
2255
2256class LoadStore32RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2257 string asm, dag ins, dag outs, list<dag> pat>
2258 : I<ins, outs, asm, "\t$Rt, $addr", "", pat> {
2259 // The operands are in order to match the 'addr' MI operands, so we
2260 // don't need an encoder method and by-name matching. Just use the default
2261 // in-order handling. Since we're using by-order, make sure the names
2262 // do not match.
2263 bits<5> dst;
2264 bits<5> base;
2265 bits<5> offset;
2266 bits<4> extend;
2267 let Inst{31-30} = sz;
2268 let Inst{29-27} = 0b111;
2269 let Inst{26} = V;
2270 let Inst{25-24} = 0b00;
2271 let Inst{23-22} = opc;
2272 let Inst{21} = 1;
2273 let Inst{20-16} = offset;
2274 let Inst{15-13} = extend{3-1};
2275
2276 let Inst{12} = extend{0};
2277 let Inst{11-10} = 0b10;
2278 let Inst{9-5} = base;
2279 let Inst{4-0} = dst;
2280
2281 let DecoderMethod = "DecodeRegOffsetLdStInstruction";
2282}
2283
2284class Load32RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2285 string asm, list<dag> pat>
2286 : LoadStore32RO<sz, V, opc, regtype, asm,
2287 (outs regtype:$Rt), (ins ro_indexed32:$addr), pat>,
2288 Sched<[WriteLDIdx, ReadAdrBase]>;
2289
2290class Store32RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2291 string asm, list<dag> pat>
2292 : LoadStore32RO<sz, V, opc, regtype, asm,
2293 (outs), (ins regtype:$Rt, ro_indexed32:$addr), pat>,
2294 Sched<[WriteSTIdx, ReadAdrBase]>;
2295
2296class LoadStore64RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2297 string asm, dag ins, dag outs, list<dag> pat>
2298 : I<ins, outs, asm, "\t$Rt, $addr", "", pat> {
2299 // The operands are in order to match the 'addr' MI operands, so we
2300 // don't need an encoder method and by-name matching. Just use the default
2301 // in-order handling. Since we're using by-order, make sure the names
2302 // do not match.
2303 bits<5> dst;
2304 bits<5> base;
2305 bits<5> offset;
2306 bits<4> extend;
2307 let Inst{31-30} = sz;
2308 let Inst{29-27} = 0b111;
2309 let Inst{26} = V;
2310 let Inst{25-24} = 0b00;
2311 let Inst{23-22} = opc;
2312 let Inst{21} = 1;
2313 let Inst{20-16} = offset;
2314 let Inst{15-13} = extend{3-1};
2315
2316 let Inst{12} = extend{0};
2317 let Inst{11-10} = 0b10;
2318 let Inst{9-5} = base;
2319 let Inst{4-0} = dst;
2320
2321 let DecoderMethod = "DecodeRegOffsetLdStInstruction";
2322}
2323
2324let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
2325class Load64RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2326 string asm, list<dag> pat>
2327 : LoadStore64RO<sz, V, opc, regtype, asm,
2328 (outs regtype:$Rt), (ins ro_indexed64:$addr), pat>,
2329 Sched<[WriteLDIdx, ReadAdrBase]>;
2330
2331let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
2332class Store64RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2333 string asm, list<dag> pat>
2334 : LoadStore64RO<sz, V, opc, regtype, asm,
2335 (outs), (ins regtype:$Rt, ro_indexed64:$addr), pat>,
2336 Sched<[WriteSTIdx, ReadAdrBase]>;
2337
2338
2339class LoadStore128RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2340 string asm, dag ins, dag outs, list<dag> pat>
2341 : I<ins, outs, asm, "\t$Rt, $addr", "", pat> {
2342 // The operands are in order to match the 'addr' MI operands, so we
2343 // don't need an encoder method and by-name matching. Just use the default
2344 // in-order handling. Since we're using by-order, make sure the names
2345 // do not match.
2346 bits<5> dst;
2347 bits<5> base;
2348 bits<5> offset;
2349 bits<4> extend;
2350 let Inst{31-30} = sz;
2351 let Inst{29-27} = 0b111;
2352 let Inst{26} = V;
2353 let Inst{25-24} = 0b00;
2354 let Inst{23-22} = opc;
2355 let Inst{21} = 1;
2356 let Inst{20-16} = offset;
2357 let Inst{15-13} = extend{3-1};
2358
2359 let Inst{12} = extend{0};
2360 let Inst{11-10} = 0b10;
2361 let Inst{9-5} = base;
2362 let Inst{4-0} = dst;
2363
2364 let DecoderMethod = "DecodeRegOffsetLdStInstruction";
2365}
2366
2367let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
2368class Load128RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2369 string asm, list<dag> pat>
2370 : LoadStore128RO<sz, V, opc, regtype, asm,
2371 (outs regtype:$Rt), (ins ro_indexed128:$addr), pat>,
2372 Sched<[WriteLDIdx, ReadAdrBase]>;
2373
2374let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
2375class Store128RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2376 string asm, list<dag> pat>
2377 : LoadStore128RO<sz, V, opc, regtype, asm,
2378 (outs), (ins regtype:$Rt, ro_indexed128:$addr), pat>,
2379 Sched<[WriteSTIdx, ReadAdrBase]>;
2380
2381let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in
2382class PrefetchRO<bits<2> sz, bit V, bits<2> opc, string asm, list<dag> pat>
2383 : I<(outs), (ins prfop:$Rt, ro_indexed64:$addr), asm,
2384 "\t$Rt, $addr", "", pat>,
2385 Sched<[WriteLD]> {
2386 // The operands are in order to match the 'addr' MI operands, so we
2387 // don't need an encoder method and by-name matching. Just use the default
2388 // in-order handling. Since we're using by-order, make sure the names
2389 // do not match.
2390 bits<5> dst;
2391 bits<5> base;
2392 bits<5> offset;
2393 bits<4> extend;
2394 let Inst{31-30} = sz;
2395 let Inst{29-27} = 0b111;
2396 let Inst{26} = V;
2397 let Inst{25-24} = 0b00;
2398 let Inst{23-22} = opc;
2399 let Inst{21} = 1;
2400 let Inst{20-16} = offset;
2401 let Inst{15-13} = extend{3-1};
2402
2403 let Inst{12} = extend{0};
2404 let Inst{11-10} = 0b10;
2405 let Inst{9-5} = base;
2406 let Inst{4-0} = dst;
2407
2408 let DecoderMethod = "DecodeRegOffsetLdStInstruction";
2409}
2410
2411//---
2412// Load/store unscaled immediate
2413//---
2414
2415def MemoryUnscaledOperand : AsmOperandClass {
2416 let Name = "MemoryUnscaled";
2417 let DiagnosticType = "InvalidMemoryIndexedSImm9";
2418}
2419class am_unscaled_operand : Operand<i64> {
2420 let PrintMethod = "printAMUnscaled";
2421 let ParserMatchClass = MemoryUnscaledOperand;
2422 let MIOperandInfo = (ops GPR64sp:$base, i64imm:$offset);
2423}
2424def am_unscaled : am_unscaled_operand;
2425def am_unscaled8 : am_unscaled_operand,
2426 ComplexPattern<i64, 2, "SelectAddrModeUnscaled8", []>;
2427def am_unscaled16 : am_unscaled_operand,
2428 ComplexPattern<i64, 2, "SelectAddrModeUnscaled16", []>;
2429def am_unscaled32 : am_unscaled_operand,
2430 ComplexPattern<i64, 2, "SelectAddrModeUnscaled32", []>;
2431def am_unscaled64 : am_unscaled_operand,
2432 ComplexPattern<i64, 2, "SelectAddrModeUnscaled64", []>;
2433def am_unscaled128 : am_unscaled_operand,
2434 ComplexPattern<i64, 2, "SelectAddrModeUnscaled128", []>;
2435
2436class BaseLoadStoreUnscale<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops,
2437 string asm, list<dag> pattern>
2438 : I<oops, iops, asm, "\t$Rt, $addr", "", pattern> {
2439 // The operands are in order to match the 'addr' MI operands, so we
2440 // don't need an encoder method and by-name matching. Just use the default
2441 // in-order handling. Since we're using by-order, make sure the names
2442 // do not match.
2443 bits<5> dst;
2444 bits<5> base;
2445 bits<9> offset;
2446 let Inst{31-30} = sz;
2447 let Inst{29-27} = 0b111;
2448 let Inst{26} = V;
2449 let Inst{25-24} = 0b00;
2450 let Inst{23-22} = opc;
2451 let Inst{21} = 0;
2452 let Inst{20-12} = offset;
2453 let Inst{11-10} = 0b00;
2454 let Inst{9-5} = base;
2455 let Inst{4-0} = dst;
2456
2457 let DecoderMethod = "DecodeSignedLdStInstruction";
2458}
2459
2460let AddedComplexity = 1 in // try this before LoadUI
2461class LoadUnscaled<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2462 Operand amtype, string asm, list<dag> pattern>
2463 : BaseLoadStoreUnscale<sz, V, opc, (outs regtype:$Rt),
2464 (ins amtype:$addr), asm, pattern>,
2465 Sched<[WriteLD]>;
2466
2467let AddedComplexity = 1 in // try this before StoreUI
2468class StoreUnscaled<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2469 Operand amtype, string asm, list<dag> pattern>
2470 : BaseLoadStoreUnscale<sz, V, opc, (outs),
2471 (ins regtype:$Rt, amtype:$addr), asm, pattern>,
2472 Sched<[WriteST]>;
2473
2474let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in
2475class PrefetchUnscaled<bits<2> sz, bit V, bits<2> opc, string asm, list<dag> pat>
2476 : BaseLoadStoreUnscale<sz, V, opc, (outs),
2477 (ins prfop:$Rt, am_unscaled:$addr), asm, pat>,
2478 Sched<[WriteLD]>;
2479
2480//---
2481// Load/store unscaled immediate, unprivileged
2482//---
2483
2484class BaseLoadStoreUnprivileged<bits<2> sz, bit V, bits<2> opc,
2485 dag oops, dag iops, string asm>
2486 : I<oops, iops, asm, "\t$Rt, $addr", "", []> {
2487 // The operands are in order to match the 'addr' MI operands, so we
2488 // don't need an encoder method and by-name matching. Just use the default
2489 // in-order handling. Since we're using by-order, make sure the names
2490 // do not match.
2491 bits<5> dst;
2492 bits<5> base;
2493 bits<9> offset;
2494 let Inst{31-30} = sz;
2495 let Inst{29-27} = 0b111;
2496 let Inst{26} = V;
2497 let Inst{25-24} = 0b00;
2498 let Inst{23-22} = opc;
2499 let Inst{21} = 0;
2500 let Inst{20-12} = offset;
2501 let Inst{11-10} = 0b10;
2502 let Inst{9-5} = base;
2503 let Inst{4-0} = dst;
2504
2505 let DecoderMethod = "DecodeSignedLdStInstruction";
2506}
2507
2508let mayStore = 0, mayLoad = 1, hasSideEffects = 0 in {
2509class LoadUnprivileged<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2510 string asm>
2511 : BaseLoadStoreUnprivileged<sz, V, opc,
2512 (outs regtype:$Rt), (ins am_unscaled:$addr), asm>,
2513 Sched<[WriteLD]>;
2514}
2515
2516let mayStore = 1, mayLoad = 0, hasSideEffects = 0 in {
2517class StoreUnprivileged<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2518 string asm>
2519 : BaseLoadStoreUnprivileged<sz, V, opc,
2520 (outs), (ins regtype:$Rt, am_unscaled:$addr), asm>,
2521 Sched<[WriteST]>;
2522}
2523
2524//---
2525// Load/store pre-indexed
2526//---
2527
2528class BaseLoadStorePreIdx<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops,
2529 string asm, string cstr>
2530 : I<oops, iops, asm, "\t$Rt, $addr!", cstr, []> {
2531 // The operands are in order to match the 'addr' MI operands, so we
2532 // don't need an encoder method and by-name matching. Just use the default
2533 // in-order handling.
2534 bits<5> dst;
2535 bits<5> base;
2536 bits<9> offset;
2537 let Inst{31-30} = sz;
2538 let Inst{29-27} = 0b111;
2539 let Inst{26} = V;
2540 let Inst{25-24} = 0;
2541 let Inst{23-22} = opc;
2542 let Inst{21} = 0;
2543 let Inst{20-12} = offset;
2544 let Inst{11-10} = 0b11;
2545 let Inst{9-5} = base;
2546 let Inst{4-0} = dst;
2547
2548 let DecoderMethod = "DecodeSignedLdStInstruction";
2549}
2550
2551let hasSideEffects = 0 in {
2552let mayStore = 0, mayLoad = 1 in
2553// FIXME: Modeling the write-back of these instructions for isel is tricky.
2554// we need the complex addressing mode for the memory reference, but
2555// we also need the write-back specified as a tied operand to the
2556// base register. That combination does not play nicely with
2557// the asm matcher and friends.
2558class LoadPreIdx<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2559 string asm>
2560 : BaseLoadStorePreIdx<sz, V, opc,
2561 (outs regtype:$Rt/*, GPR64sp:$wback*/),
2562 (ins am_unscaled:$addr), asm, ""/*"$addr.base = $wback"*/>,
2563 Sched<[WriteLD, WriteAdr]>;
2564
2565let mayStore = 1, mayLoad = 0 in
2566class StorePreIdx<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2567 string asm>
2568 : BaseLoadStorePreIdx<sz, V, opc,
2569 (outs/* GPR64sp:$wback*/),
2570 (ins regtype:$Rt, am_unscaled:$addr),
2571 asm, ""/*"$addr.base = $wback"*/>,
2572 Sched<[WriteAdr, WriteST]>;
2573} // hasSideEffects = 0
2574
2575// ISel pseudo-instructions which have the tied operands. When the MC lowering
2576// logic finally gets smart enough to strip off tied operands that are just
2577// for isel convenience, we can get rid of these pseudos and just reference
2578// the real instructions directly.
2579//
2580// Ironically, also because of the writeback operands, we can't put the
2581// matcher pattern directly on the instruction, but need to define it
2582// separately.
2583//
2584// Loads aren't matched with patterns here at all, but rather in C++
2585// custom lowering.
2586let mayStore = 0, mayLoad = 1, hasSideEffects = 0 in {
2587class LoadPreIdxPseudo<RegisterClass regtype>
2588 : Pseudo<(outs regtype:$Rt, GPR64sp:$wback),
2589 (ins am_noindex:$addr, simm9:$offset), [],
2590 "$addr.base = $wback,@earlyclobber $wback">,
2591 Sched<[WriteLD, WriteAdr]>;
2592class LoadPostIdxPseudo<RegisterClass regtype>
2593 : Pseudo<(outs regtype:$Rt, GPR64sp:$wback),
2594 (ins am_noindex:$addr, simm9:$offset), [],
2595 "$addr.base = $wback,@earlyclobber $wback">,
2596 Sched<[WriteLD, WriteI]>;
2597}
2598multiclass StorePreIdxPseudo<RegisterClass regtype, ValueType Ty,
2599 SDPatternOperator OpNode> {
2600 let mayStore = 1, mayLoad = 0, hasSideEffects = 0 in
2601 def _isel: Pseudo<(outs GPR64sp:$wback),
2602 (ins regtype:$Rt, am_noindex:$addr, simm9:$offset), [],
2603 "$addr.base = $wback,@earlyclobber $wback">,
2604 Sched<[WriteAdr, WriteST]>;
2605
2606 def : Pat<(OpNode (Ty regtype:$Rt), am_noindex:$addr, simm9:$offset),
2607 (!cast<Instruction>(NAME#_isel) regtype:$Rt, am_noindex:$addr,
2608 simm9:$offset)>;
2609}
2610
2611//---
2612// Load/store post-indexed
2613//---
2614
2615// (pre-index) load/stores.
2616class BaseLoadStorePostIdx<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops,
2617 string asm, string cstr>
2618 : I<oops, iops, asm, "\t$Rt, $addr, $idx", cstr, []> {
2619 // The operands are in order to match the 'addr' MI operands, so we
2620 // don't need an encoder method and by-name matching. Just use the default
2621 // in-order handling.
2622 bits<5> dst;
2623 bits<5> base;
2624 bits<9> offset;
2625 let Inst{31-30} = sz;
2626 let Inst{29-27} = 0b111;
2627 let Inst{26} = V;
2628 let Inst{25-24} = 0b00;
2629 let Inst{23-22} = opc;
2630 let Inst{21} = 0b0;
2631 let Inst{20-12} = offset;
2632 let Inst{11-10} = 0b01;
2633 let Inst{9-5} = base;
2634 let Inst{4-0} = dst;
2635
2636 let DecoderMethod = "DecodeSignedLdStInstruction";
2637}
2638
2639let hasSideEffects = 0 in {
2640let mayStore = 0, mayLoad = 1 in
2641// FIXME: Modeling the write-back of these instructions for isel is tricky.
2642// we need the complex addressing mode for the memory reference, but
2643// we also need the write-back specified as a tied operand to the
2644// base register. That combination does not play nicely with
2645// the asm matcher and friends.
2646class LoadPostIdx<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2647 string asm>
2648 : BaseLoadStorePostIdx<sz, V, opc,
2649 (outs regtype:$Rt/*, GPR64sp:$wback*/),
2650 (ins am_noindex:$addr, simm9:$idx),
2651 asm, ""/*"$addr.base = $wback"*/>,
2652 Sched<[WriteLD, WriteI]>;
2653
2654let mayStore = 1, mayLoad = 0 in
2655class StorePostIdx<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2656 string asm>
2657 : BaseLoadStorePostIdx<sz, V, opc,
2658 (outs/* GPR64sp:$wback*/),
2659 (ins regtype:$Rt, am_noindex:$addr, simm9:$idx),
2660 asm, ""/*"$addr.base = $wback"*/>,
2661 Sched<[WriteAdr, WriteST, ReadAdrBase]>;
2662} // hasSideEffects = 0
2663
2664// ISel pseudo-instructions which have the tied operands. When the MC lowering
2665// logic finally gets smart enough to strip off tied operands that are just
2666// for isel convenience, we can get rid of these pseudos and just reference
2667// the real instructions directly.
2668//
2669// Ironically, also because of the writeback operands, we can't put the
2670// matcher pattern directly on the instruction, but need to define it
2671// separately.
2672multiclass StorePostIdxPseudo<RegisterClass regtype, ValueType Ty,
2673 SDPatternOperator OpNode, Instruction Insn> {
2674 let mayStore = 1, mayLoad = 0, hasSideEffects = 0 in
2675 def _isel: Pseudo<(outs GPR64sp:$wback),
2676 (ins regtype:$Rt, am_noindex:$addr, simm9:$idx), [],
2677 "$addr.base = $wback,@earlyclobber $wback">,
2678 PseudoInstExpansion<(Insn regtype:$Rt, am_noindex:$addr, simm9:$idx)>,
2679 Sched<[WriteAdr, WriteST, ReadAdrBase]>;
2680
2681 def : Pat<(OpNode (Ty regtype:$Rt), am_noindex:$addr, simm9:$idx),
2682 (!cast<Instruction>(NAME#_isel) regtype:$Rt, am_noindex:$addr,
2683 simm9:$idx)>;
2684}
2685
2686//---
2687// Load/store pair
2688//---
2689
2690// (indexed, offset)
2691
2692class BaseLoadStorePairOffset<bits<2> opc, bit V, bit L, dag oops, dag iops,
2693 string asm>
2694 : I<oops, iops, asm, "\t$Rt, $Rt2, $addr", "", []> {
2695 // The operands are in order to match the 'addr' MI operands, so we
2696 // don't need an encoder method and by-name matching. Just use the default
2697 // in-order handling. Since we're using by-order, make sure the names
2698 // do not match.
2699 bits<5> dst;
2700 bits<5> dst2;
2701 bits<5> base;
2702 bits<7> offset;
2703 let Inst{31-30} = opc;
2704 let Inst{29-27} = 0b101;
2705 let Inst{26} = V;
2706 let Inst{25-23} = 0b010;
2707 let Inst{22} = L;
2708 let Inst{21-15} = offset;
2709 let Inst{14-10} = dst2;
2710 let Inst{9-5} = base;
2711 let Inst{4-0} = dst;
2712
2713 let DecoderMethod = "DecodePairLdStInstruction";
2714}
2715
2716let hasSideEffects = 0 in {
2717let mayStore = 0, mayLoad = 1 in
2718class LoadPairOffset<bits<2> opc, bit V, RegisterClass regtype,
2719 Operand indextype, string asm>
2720 : BaseLoadStorePairOffset<opc, V, 1,
2721 (outs regtype:$Rt, regtype:$Rt2),
2722 (ins indextype:$addr), asm>,
2723 Sched<[WriteLD, WriteLDHi]>;
2724
2725let mayLoad = 0, mayStore = 1 in
2726class StorePairOffset<bits<2> opc, bit V, RegisterClass regtype,
2727 Operand indextype, string asm>
2728 : BaseLoadStorePairOffset<opc, V, 0, (outs),
2729 (ins regtype:$Rt, regtype:$Rt2, indextype:$addr),
2730 asm>,
2731 Sched<[WriteSTP]>;
2732} // hasSideEffects = 0
2733
2734// (pre-indexed)
2735
2736def MemoryIndexed32SImm7 : AsmOperandClass {
2737 let Name = "MemoryIndexed32SImm7";
2738 let DiagnosticType = "InvalidMemoryIndexed32SImm7";
2739}
2740def am_indexed32simm7 : Operand<i32> { // ComplexPattern<...>
2741 let PrintMethod = "printAMIndexed32";
2742 let ParserMatchClass = MemoryIndexed32SImm7;
2743 let MIOperandInfo = (ops GPR64sp:$base, i32imm:$offset);
2744}
2745
2746def MemoryIndexed64SImm7 : AsmOperandClass {
2747 let Name = "MemoryIndexed64SImm7";
2748 let DiagnosticType = "InvalidMemoryIndexed64SImm7";
2749}
2750def am_indexed64simm7 : Operand<i32> { // ComplexPattern<...>
2751 let PrintMethod = "printAMIndexed64";
2752 let ParserMatchClass = MemoryIndexed64SImm7;
2753 let MIOperandInfo = (ops GPR64sp:$base, i32imm:$offset);
2754}
2755
2756def MemoryIndexed128SImm7 : AsmOperandClass {
2757 let Name = "MemoryIndexed128SImm7";
2758 let DiagnosticType = "InvalidMemoryIndexed128SImm7";
2759}
2760def am_indexed128simm7 : Operand<i32> { // ComplexPattern<...>
2761 let PrintMethod = "printAMIndexed128";
2762 let ParserMatchClass = MemoryIndexed128SImm7;
2763 let MIOperandInfo = (ops GPR64sp:$base, i32imm:$offset);
2764}
2765
2766class BaseLoadStorePairPreIdx<bits<2> opc, bit V, bit L, dag oops, dag iops,
2767 string asm>
2768 : I<oops, iops, asm, "\t$Rt, $Rt2, $addr!", "", []> {
2769 // The operands are in order to match the 'addr' MI operands, so we
2770 // don't need an encoder method and by-name matching. Just use the default
2771 // in-order handling. Since we're using by-order, make sure the names
2772 // do not match.
2773 bits<5> dst;
2774 bits<5> dst2;
2775 bits<5> base;
2776 bits<7> offset;
2777 let Inst{31-30} = opc;
2778 let Inst{29-27} = 0b101;
2779 let Inst{26} = V;
2780 let Inst{25-23} = 0b011;
2781 let Inst{22} = L;
2782 let Inst{21-15} = offset;
2783 let Inst{14-10} = dst2;
2784 let Inst{9-5} = base;
2785 let Inst{4-0} = dst;
2786
2787 let DecoderMethod = "DecodePairLdStInstruction";
2788}
2789
2790let hasSideEffects = 0 in {
2791let mayStore = 0, mayLoad = 1 in
2792class LoadPairPreIdx<bits<2> opc, bit V, RegisterClass regtype,
2793 Operand addrmode, string asm>
2794 : BaseLoadStorePairPreIdx<opc, V, 1,
2795 (outs regtype:$Rt, regtype:$Rt2),
2796 (ins addrmode:$addr), asm>,
2797 Sched<[WriteLD, WriteLDHi, WriteAdr]>;
2798
2799let mayStore = 1, mayLoad = 0 in
2800class StorePairPreIdx<bits<2> opc, bit V, RegisterClass regtype,
2801 Operand addrmode, string asm>
2802 : BaseLoadStorePairPreIdx<opc, V, 0, (outs),
2803 (ins regtype:$Rt, regtype:$Rt2, addrmode:$addr),
2804 asm>,
2805 Sched<[WriteAdr, WriteSTP]>;
2806} // hasSideEffects = 0
2807
2808// (post-indexed)
2809
2810class BaseLoadStorePairPostIdx<bits<2> opc, bit V, bit L, dag oops, dag iops,
2811 string asm>
2812 : I<oops, iops, asm, "\t$Rt, $Rt2, $addr, $idx", "", []> {
2813 // The operands are in order to match the 'addr' MI operands, so we
2814 // don't need an encoder method and by-name matching. Just use the default
2815 // in-order handling. Since we're using by-order, make sure the names
2816 // do not match.
2817 bits<5> dst;
2818 bits<5> dst2;
2819 bits<5> base;
2820 bits<7> offset;
2821 let Inst{31-30} = opc;
2822 let Inst{29-27} = 0b101;
2823 let Inst{26} = V;
2824 let Inst{25-23} = 0b001;
2825 let Inst{22} = L;
2826 let Inst{21-15} = offset;
2827 let Inst{14-10} = dst2;
2828 let Inst{9-5} = base;
2829 let Inst{4-0} = dst;
2830
2831 let DecoderMethod = "DecodePairLdStInstruction";
2832}
2833
2834let hasSideEffects = 0 in {
2835let mayStore = 0, mayLoad = 1 in
2836class LoadPairPostIdx<bits<2> opc, bit V, RegisterClass regtype,
2837 Operand idxtype, string asm>
2838 : BaseLoadStorePairPostIdx<opc, V, 1,
2839 (outs regtype:$Rt, regtype:$Rt2),
2840 (ins am_noindex:$addr, idxtype:$idx), asm>,
2841 Sched<[WriteLD, WriteLDHi, WriteAdr]>;
2842
2843let mayStore = 1, mayLoad = 0 in
2844class StorePairPostIdx<bits<2> opc, bit V, RegisterClass regtype,
2845 Operand idxtype, string asm>
2846 : BaseLoadStorePairPostIdx<opc, V, 0, (outs),
2847 (ins regtype:$Rt, regtype:$Rt2,
2848 am_noindex:$addr, idxtype:$idx),
2849 asm>,
2850 Sched<[WriteAdr, WriteSTP]>;
2851} // hasSideEffects = 0
2852
2853// (no-allocate)
2854
2855class BaseLoadStorePairNoAlloc<bits<2> opc, bit V, bit L, dag oops, dag iops,
2856 string asm>
2857 : I<oops, iops, asm, "\t$Rt, $Rt2, $addr", "", []> {
2858 // The operands are in order to match the 'addr' MI operands, so we
2859 // don't need an encoder method and by-name matching. Just use the default
2860 // in-order handling. Since we're using by-order, make sure the names
2861 // do not match.
2862 bits<5> dst;
2863 bits<5> dst2;
2864 bits<5> base;
2865 bits<7> offset;
2866 let Inst{31-30} = opc;
2867 let Inst{29-27} = 0b101;
2868 let Inst{26} = V;
2869 let Inst{25-23} = 0b000;
2870 let Inst{22} = L;
2871 let Inst{21-15} = offset;
2872 let Inst{14-10} = dst2;
2873 let Inst{9-5} = base;
2874 let Inst{4-0} = dst;
2875
2876 let DecoderMethod = "DecodePairLdStInstruction";
2877}
2878
2879let hasSideEffects = 0 in {
2880let mayStore = 0, mayLoad = 1 in
2881class LoadPairNoAlloc<bits<2> opc, bit V, RegisterClass regtype,
2882 Operand indextype, string asm>
2883 : BaseLoadStorePairNoAlloc<opc, V, 1,
2884 (outs regtype:$Rt, regtype:$Rt2),
2885 (ins indextype:$addr), asm>,
2886 Sched<[WriteLD, WriteLDHi]>;
2887
2888let mayStore = 1, mayLoad = 0 in
2889class StorePairNoAlloc<bits<2> opc, bit V, RegisterClass regtype,
2890 Operand indextype, string asm>
2891 : BaseLoadStorePairNoAlloc<opc, V, 0, (outs),
2892 (ins regtype:$Rt, regtype:$Rt2, indextype:$addr),
2893 asm>,
2894 Sched<[WriteSTP]>;
2895} // hasSideEffects = 0
2896
2897//---
2898// Load/store exclusive
2899//---
2900
2901// True exclusive operations write to and/or read from the system's exclusive
2902// monitors, which as far as a compiler is concerned can be modelled as a
2903// random shared memory address. Hence LoadExclusive mayStore.
Bradley Smithbc35b1f2014-04-09 14:43:01 +00002904//
2905// Since these instructions have the undefined register bits set to 1 in
2906// their canonical form, we need a post encoder method to set those bits
2907// to 1 when encoding these instructions. We do this using the
2908// fixLoadStoreExclusive function. This function has template parameters:
2909//
2910// fixLoadStoreExclusive<int hasRs, int hasRt2>
2911//
2912// hasRs indicates that the instruction uses the Rs field, so we won't set
2913// it to 1 (and the same for Rt2). We don't need template parameters for
2914// the other register fields since Rt and Rn are always used.
2915//
Tim Northover00ed9962014-03-29 10:18:08 +00002916let hasSideEffects = 1, mayLoad = 1, mayStore = 1 in
2917class BaseLoadStoreExclusive<bits<2> sz, bit o2, bit L, bit o1, bit o0,
2918 dag oops, dag iops, string asm, string operands>
2919 : I<oops, iops, asm, operands, "", []> {
2920 let Inst{31-30} = sz;
2921 let Inst{29-24} = 0b001000;
2922 let Inst{23} = o2;
2923 let Inst{22} = L;
2924 let Inst{21} = o1;
2925 let Inst{15} = o0;
2926
2927 let DecoderMethod = "DecodeExclusiveLdStInstruction";
2928}
2929
2930// Neither Rs nor Rt2 operands.
2931class LoadStoreExclusiveSimple<bits<2> sz, bit o2, bit L, bit o1, bit o0,
2932 dag oops, dag iops, string asm, string operands>
2933 : BaseLoadStoreExclusive<sz, o2, L, o1, o0, oops, iops, asm, operands> {
2934 bits<5> reg;
2935 bits<5> base;
Tim Northover00ed9962014-03-29 10:18:08 +00002936 let Inst{9-5} = base;
2937 let Inst{4-0} = reg;
Bradley Smithbc35b1f2014-04-09 14:43:01 +00002938
2939 let PostEncoderMethod = "fixLoadStoreExclusive<0,0>";
Tim Northover00ed9962014-03-29 10:18:08 +00002940}
2941
2942// Simple load acquires don't set the exclusive monitor
2943let mayLoad = 1, mayStore = 0 in
2944class LoadAcquire<bits<2> sz, bit o2, bit L, bit o1, bit o0,
2945 RegisterClass regtype, string asm>
2946 : LoadStoreExclusiveSimple<sz, o2, L, o1, o0, (outs regtype:$Rt),
2947 (ins am_noindex:$addr), asm, "\t$Rt, $addr">,
2948 Sched<[WriteLD]>;
2949
2950class LoadExclusive<bits<2> sz, bit o2, bit L, bit o1, bit o0,
2951 RegisterClass regtype, string asm>
2952 : LoadStoreExclusiveSimple<sz, o2, L, o1, o0, (outs regtype:$Rt),
2953 (ins am_noindex:$addr), asm, "\t$Rt, $addr">,
2954 Sched<[WriteLD]>;
2955
2956class LoadExclusivePair<bits<2> sz, bit o2, bit L, bit o1, bit o0,
2957 RegisterClass regtype, string asm>
2958 : BaseLoadStoreExclusive<sz, o2, L, o1, o0,
2959 (outs regtype:$Rt, regtype:$Rt2),
2960 (ins am_noindex:$addr), asm,
2961 "\t$Rt, $Rt2, $addr">,
2962 Sched<[WriteLD, WriteLDHi]> {
2963 bits<5> dst1;
2964 bits<5> dst2;
2965 bits<5> base;
Tim Northover00ed9962014-03-29 10:18:08 +00002966 let Inst{14-10} = dst2;
2967 let Inst{9-5} = base;
2968 let Inst{4-0} = dst1;
Bradley Smithbc35b1f2014-04-09 14:43:01 +00002969
2970 let PostEncoderMethod = "fixLoadStoreExclusive<0,1>";
Tim Northover00ed9962014-03-29 10:18:08 +00002971}
2972
2973// Simple store release operations do not check the exclusive monitor.
2974let mayLoad = 0, mayStore = 1 in
2975class StoreRelease<bits<2> sz, bit o2, bit L, bit o1, bit o0,
2976 RegisterClass regtype, string asm>
2977 : LoadStoreExclusiveSimple<sz, o2, L, o1, o0, (outs),
2978 (ins regtype:$Rt, am_noindex:$addr),
2979 asm, "\t$Rt, $addr">,
2980 Sched<[WriteST]>;
2981
2982let mayLoad = 1, mayStore = 1 in
2983class StoreExclusive<bits<2> sz, bit o2, bit L, bit o1, bit o0,
2984 RegisterClass regtype, string asm>
2985 : BaseLoadStoreExclusive<sz, o2, L, o1, o0, (outs GPR32:$Ws),
2986 (ins regtype:$Rt, am_noindex:$addr),
2987 asm, "\t$Ws, $Rt, $addr">,
2988 Sched<[WriteSTX]> {
2989 bits<5> status;
2990 bits<5> reg;
2991 bits<5> base;
2992 let Inst{20-16} = status;
Tim Northover00ed9962014-03-29 10:18:08 +00002993 let Inst{9-5} = base;
2994 let Inst{4-0} = reg;
2995
2996 let Constraints = "@earlyclobber $Ws";
Bradley Smithbc35b1f2014-04-09 14:43:01 +00002997 let PostEncoderMethod = "fixLoadStoreExclusive<1,0>";
Tim Northover00ed9962014-03-29 10:18:08 +00002998}
2999
3000class StoreExclusivePair<bits<2> sz, bit o2, bit L, bit o1, bit o0,
3001 RegisterClass regtype, string asm>
3002 : BaseLoadStoreExclusive<sz, o2, L, o1, o0,
3003 (outs GPR32:$Ws),
3004 (ins regtype:$Rt, regtype:$Rt2, am_noindex:$addr),
3005 asm, "\t$Ws, $Rt, $Rt2, $addr">,
3006 Sched<[WriteSTX]> {
3007 bits<5> status;
3008 bits<5> dst1;
3009 bits<5> dst2;
3010 bits<5> base;
3011 let Inst{20-16} = status;
3012 let Inst{14-10} = dst2;
3013 let Inst{9-5} = base;
3014 let Inst{4-0} = dst1;
3015
3016 let Constraints = "@earlyclobber $Ws";
3017}
3018
3019//---
3020// Exception generation
3021//---
3022
3023let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in
3024class ExceptionGeneration<bits<3> op1, bits<2> ll, string asm>
3025 : I<(outs), (ins imm0_65535:$imm), asm, "\t$imm", "", []>,
3026 Sched<[WriteSys]> {
3027 bits<16> imm;
3028 let Inst{31-24} = 0b11010100;
3029 let Inst{23-21} = op1;
3030 let Inst{20-5} = imm;
3031 let Inst{4-2} = 0b000;
3032 let Inst{1-0} = ll;
3033}
3034
3035//---
3036// Floating point to integer conversion
3037//---
3038
3039class BaseFPToIntegerUnscaled<bits<2> type, bits<2> rmode, bits<3> opcode,
3040 RegisterClass srcType, RegisterClass dstType,
3041 string asm, list<dag> pattern>
3042 : I<(outs dstType:$Rd), (ins srcType:$Rn),
3043 asm, "\t$Rd, $Rn", "", pattern>,
3044 Sched<[WriteFCvt]> {
3045 bits<5> Rd;
3046 bits<5> Rn;
3047 let Inst{30} = 0;
3048 let Inst{28-24} = 0b11110;
3049 let Inst{23-22} = type;
3050 let Inst{21} = 1;
3051 let Inst{20-19} = rmode;
3052 let Inst{18-16} = opcode;
3053 let Inst{15-10} = 0;
3054 let Inst{9-5} = Rn;
3055 let Inst{4-0} = Rd;
3056}
3057
3058let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
3059class BaseFPToInteger<bits<2> type, bits<2> rmode, bits<3> opcode,
3060 RegisterClass srcType, RegisterClass dstType,
3061 Operand immType, string asm>
3062 : I<(outs dstType:$Rd), (ins srcType:$Rn, immType:$scale),
3063 asm, "\t$Rd, $Rn, $scale", "", []>,
3064 Sched<[WriteFCvt]> {
3065 bits<5> Rd;
3066 bits<5> Rn;
3067 bits<6> scale;
3068 let Inst{30} = 0;
3069 let Inst{28-24} = 0b11110;
3070 let Inst{23-22} = type;
3071 let Inst{21} = 0;
3072 let Inst{20-19} = rmode;
3073 let Inst{18-16} = opcode;
3074 let Inst{15-10} = scale;
3075 let Inst{9-5} = Rn;
3076 let Inst{4-0} = Rd;
3077}
3078
3079multiclass FPToInteger<bits<2> rmode, bits<3> opcode, string asm, SDPatternOperator OpN> {
3080 // Unscaled single-precision to 32-bit
3081 def UWSr : BaseFPToIntegerUnscaled<0b00, rmode, opcode, FPR32, GPR32, asm,
3082 [(set GPR32:$Rd, (OpN FPR32:$Rn))]> {
3083 let Inst{31} = 0; // 32-bit GPR flag
3084 }
3085
3086 // Unscaled single-precision to 64-bit
3087 def UXSr : BaseFPToIntegerUnscaled<0b00, rmode, opcode, FPR32, GPR64, asm,
3088 [(set GPR64:$Rd, (OpN FPR32:$Rn))]> {
3089 let Inst{31} = 1; // 64-bit GPR flag
3090 }
3091
3092 // Unscaled double-precision to 32-bit
3093 def UWDr : BaseFPToIntegerUnscaled<0b01, rmode, opcode, FPR64, GPR32, asm,
3094 [(set GPR32:$Rd, (OpN (f64 FPR64:$Rn)))]> {
3095 let Inst{31} = 0; // 32-bit GPR flag
3096 }
3097
3098 // Unscaled double-precision to 64-bit
3099 def UXDr : BaseFPToIntegerUnscaled<0b01, rmode, opcode, FPR64, GPR64, asm,
3100 [(set GPR64:$Rd, (OpN (f64 FPR64:$Rn)))]> {
3101 let Inst{31} = 1; // 64-bit GPR flag
3102 }
3103
3104 // Scaled single-precision to 32-bit
3105 def SWSri : BaseFPToInteger<0b00, rmode, opcode, FPR32, GPR32,
3106 fixedpoint32, asm> {
3107 let Inst{31} = 0; // 32-bit GPR flag
3108 }
3109
3110 // Scaled single-precision to 64-bit
3111 def SXSri : BaseFPToInteger<0b00, rmode, opcode, FPR32, GPR64,
3112 fixedpoint64, asm> {
3113 let Inst{31} = 1; // 64-bit GPR flag
3114 }
3115
3116 // Scaled double-precision to 32-bit
3117 def SWDri : BaseFPToInteger<0b01, rmode, opcode, FPR64, GPR32,
3118 fixedpoint32, asm> {
3119 let Inst{31} = 0; // 32-bit GPR flag
3120 }
3121
3122 // Scaled double-precision to 64-bit
3123 def SXDri : BaseFPToInteger<0b01, rmode, opcode, FPR64, GPR64,
3124 fixedpoint64, asm> {
3125 let Inst{31} = 1; // 64-bit GPR flag
3126 }
3127}
3128
3129//---
3130// Integer to floating point conversion
3131//---
3132
3133let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
3134class BaseIntegerToFP<bit isUnsigned,
3135 RegisterClass srcType, RegisterClass dstType,
3136 Operand immType, string asm>
3137 : I<(outs dstType:$Rd), (ins srcType:$Rn, immType:$scale),
3138 asm, "\t$Rd, $Rn, $scale", "", []>,
3139 Sched<[WriteFCvt]> {
3140 bits<5> Rd;
3141 bits<5> Rn;
3142 bits<6> scale;
3143 let Inst{30-23} = 0b00111100;
3144 let Inst{21-17} = 0b00001;
3145 let Inst{16} = isUnsigned;
3146 let Inst{15-10} = scale;
3147 let Inst{9-5} = Rn;
3148 let Inst{4-0} = Rd;
3149}
3150
3151class BaseIntegerToFPUnscaled<bit isUnsigned,
3152 RegisterClass srcType, RegisterClass dstType,
3153 ValueType dvt, string asm, SDNode node>
3154 : I<(outs dstType:$Rd), (ins srcType:$Rn),
3155 asm, "\t$Rd, $Rn", "", [(set (dvt dstType:$Rd), (node srcType:$Rn))]>,
3156 Sched<[WriteFCvt]> {
3157 bits<5> Rd;
3158 bits<5> Rn;
3159 bits<6> scale;
3160 let Inst{30-23} = 0b00111100;
3161 let Inst{21-17} = 0b10001;
3162 let Inst{16} = isUnsigned;
3163 let Inst{15-10} = 0b000000;
3164 let Inst{9-5} = Rn;
3165 let Inst{4-0} = Rd;
3166}
3167
3168multiclass IntegerToFP<bit isUnsigned, string asm, SDNode node> {
3169 // Unscaled
3170 def UWSri: BaseIntegerToFPUnscaled<isUnsigned, GPR32, FPR32, f32, asm, node> {
3171 let Inst{31} = 0; // 32-bit GPR flag
3172 let Inst{22} = 0; // 32-bit FPR flag
3173 }
3174
3175 def UWDri: BaseIntegerToFPUnscaled<isUnsigned, GPR32, FPR64, f64, asm, node> {
3176 let Inst{31} = 0; // 32-bit GPR flag
3177 let Inst{22} = 1; // 64-bit FPR flag
3178 }
3179
3180 def UXSri: BaseIntegerToFPUnscaled<isUnsigned, GPR64, FPR32, f32, asm, node> {
3181 let Inst{31} = 1; // 64-bit GPR flag
3182 let Inst{22} = 0; // 32-bit FPR flag
3183 }
3184
3185 def UXDri: BaseIntegerToFPUnscaled<isUnsigned, GPR64, FPR64, f64, asm, node> {
3186 let Inst{31} = 1; // 64-bit GPR flag
3187 let Inst{22} = 1; // 64-bit FPR flag
3188 }
3189
3190 // Scaled
3191 def SWSri: BaseIntegerToFP<isUnsigned, GPR32, FPR32, fixedpoint32, asm> {
3192 let Inst{31} = 0; // 32-bit GPR flag
3193 let Inst{22} = 0; // 32-bit FPR flag
3194 }
3195
3196 def SWDri: BaseIntegerToFP<isUnsigned, GPR32, FPR64, fixedpoint32, asm> {
3197 let Inst{31} = 0; // 32-bit GPR flag
3198 let Inst{22} = 1; // 64-bit FPR flag
3199 }
3200
3201 def SXSri: BaseIntegerToFP<isUnsigned, GPR64, FPR32, fixedpoint64, asm> {
3202 let Inst{31} = 1; // 64-bit GPR flag
3203 let Inst{22} = 0; // 32-bit FPR flag
3204 }
3205
3206 def SXDri: BaseIntegerToFP<isUnsigned, GPR64, FPR64, fixedpoint64, asm> {
3207 let Inst{31} = 1; // 64-bit GPR flag
3208 let Inst{22} = 1; // 64-bit FPR flag
3209 }
3210}
3211
3212//---
3213// Unscaled integer <-> floating point conversion (i.e. FMOV)
3214//---
3215
3216let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
3217class BaseUnscaledConversion<bits<2> rmode, bits<3> opcode,
3218 RegisterClass srcType, RegisterClass dstType,
3219 string asm>
3220 : I<(outs dstType:$Rd), (ins srcType:$Rn), asm, "\t$Rd, $Rn", "",
3221 // We use COPY_TO_REGCLASS for these bitconvert operations.
3222 // copyPhysReg() expands the resultant COPY instructions after
3223 // regalloc is done. This gives greater freedom for the allocator
3224 // and related passes (coalescing, copy propagation, et. al.) to
3225 // be more effective.
3226 [/*(set (dvt dstType:$Rd), (bitconvert (svt srcType:$Rn)))*/]>,
3227 Sched<[WriteFCopy]> {
3228 bits<5> Rd;
3229 bits<5> Rn;
3230 let Inst{30-23} = 0b00111100;
3231 let Inst{21} = 1;
3232 let Inst{20-19} = rmode;
3233 let Inst{18-16} = opcode;
3234 let Inst{15-10} = 0b000000;
3235 let Inst{9-5} = Rn;
3236 let Inst{4-0} = Rd;
3237}
3238
3239let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
3240class BaseUnscaledConversionToHigh<bits<2> rmode, bits<3> opcode,
3241 RegisterClass srcType, RegisterOperand dstType, string asm>
3242 : I<(outs dstType:$Rd), (ins srcType:$Rn), asm, "\t$Rd[1], $Rn", "", []>,
3243 Sched<[WriteFCopy]> {
3244 bits<5> Rd;
3245 bits<5> Rn;
3246 let Inst{30-23} = 0b00111101;
3247 let Inst{21} = 1;
3248 let Inst{20-19} = rmode;
3249 let Inst{18-16} = opcode;
3250 let Inst{15-10} = 0b000000;
3251 let Inst{9-5} = Rn;
3252 let Inst{4-0} = Rd;
3253}
3254
3255let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
3256class BaseUnscaledConversionFromHigh<bits<2> rmode, bits<3> opcode,
3257 RegisterOperand srcType, RegisterClass dstType, string asm>
3258 : I<(outs dstType:$Rd), (ins srcType:$Rn), asm, "\t$Rd, $Rn[1]", "", []>,
3259 Sched<[WriteFCopy]> {
3260 bits<5> Rd;
3261 bits<5> Rn;
3262 let Inst{30-23} = 0b00111101;
3263 let Inst{21} = 1;
3264 let Inst{20-19} = rmode;
3265 let Inst{18-16} = opcode;
3266 let Inst{15-10} = 0b000000;
3267 let Inst{9-5} = Rn;
3268 let Inst{4-0} = Rd;
3269}
3270
3271
3272
3273multiclass UnscaledConversion<string asm> {
3274 def WSr : BaseUnscaledConversion<0b00, 0b111, GPR32, FPR32, asm> {
3275 let Inst{31} = 0; // 32-bit GPR flag
3276 let Inst{22} = 0; // 32-bit FPR flag
3277 }
3278
3279 def XDr : BaseUnscaledConversion<0b00, 0b111, GPR64, FPR64, asm> {
3280 let Inst{31} = 1; // 64-bit GPR flag
3281 let Inst{22} = 1; // 64-bit FPR flag
3282 }
3283
3284 def SWr : BaseUnscaledConversion<0b00, 0b110, FPR32, GPR32, asm> {
3285 let Inst{31} = 0; // 32-bit GPR flag
3286 let Inst{22} = 0; // 32-bit FPR flag
3287 }
3288
3289 def DXr : BaseUnscaledConversion<0b00, 0b110, FPR64, GPR64, asm> {
3290 let Inst{31} = 1; // 64-bit GPR flag
3291 let Inst{22} = 1; // 64-bit FPR flag
3292 }
3293
3294 def XDHighr : BaseUnscaledConversionToHigh<0b01, 0b111, GPR64, V128,
3295 asm#".d"> {
3296 let Inst{31} = 1;
3297 let Inst{22} = 0;
3298 }
3299
3300 def DXHighr : BaseUnscaledConversionFromHigh<0b01, 0b110, V128, GPR64,
3301 asm#".d"> {
3302 let Inst{31} = 1;
3303 let Inst{22} = 0;
3304 }
3305
3306 def : InstAlias<asm#"$Vd.d[1], $Rn",
3307 (!cast<Instruction>(NAME#XDHighr) V128:$Vd, GPR64:$Rn), 0>;
3308 def : InstAlias<asm#"$Rd, $Vn.d[1]",
3309 (!cast<Instruction>(NAME#DXHighr) GPR64:$Rd, V128:$Vn), 0>;
3310}
3311
3312//---
3313// Floating point conversion
3314//---
3315
3316class BaseFPConversion<bits<2> type, bits<2> opcode, RegisterClass dstType,
3317 RegisterClass srcType, string asm, list<dag> pattern>
3318 : I<(outs dstType:$Rd), (ins srcType:$Rn), asm, "\t$Rd, $Rn", "", pattern>,
3319 Sched<[WriteFCvt]> {
3320 bits<5> Rd;
3321 bits<5> Rn;
3322 let Inst{31-24} = 0b00011110;
3323 let Inst{23-22} = type;
3324 let Inst{21-17} = 0b10001;
3325 let Inst{16-15} = opcode;
3326 let Inst{14-10} = 0b10000;
3327 let Inst{9-5} = Rn;
3328 let Inst{4-0} = Rd;
3329}
3330
3331multiclass FPConversion<string asm> {
3332 // Double-precision to Half-precision
3333 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
3334 def HDr : BaseFPConversion<0b01, 0b11, FPR16, FPR64, asm, []>;
3335
3336 // Double-precision to Single-precision
3337 def SDr : BaseFPConversion<0b01, 0b00, FPR32, FPR64, asm,
3338 [(set FPR32:$Rd, (fround FPR64:$Rn))]>;
3339
3340 // Half-precision to Double-precision
3341 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
3342 def DHr : BaseFPConversion<0b11, 0b01, FPR64, FPR16, asm, []>;
3343
3344 // Half-precision to Single-precision
3345 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
3346 def SHr : BaseFPConversion<0b11, 0b00, FPR32, FPR16, asm, []>;
3347
3348 // Single-precision to Double-precision
3349 def DSr : BaseFPConversion<0b00, 0b01, FPR64, FPR32, asm,
3350 [(set FPR64:$Rd, (fextend FPR32:$Rn))]>;
3351
3352 // Single-precision to Half-precision
3353 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
3354 def HSr : BaseFPConversion<0b00, 0b11, FPR16, FPR32, asm, []>;
3355}
3356
3357//---
3358// Single operand floating point data processing
3359//---
3360
3361let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
3362class BaseSingleOperandFPData<bits<4> opcode, RegisterClass regtype,
3363 ValueType vt, string asm, SDPatternOperator node>
3364 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm, "\t$Rd, $Rn", "",
3365 [(set (vt regtype:$Rd), (node (vt regtype:$Rn)))]>,
3366 Sched<[WriteF]> {
3367 bits<5> Rd;
3368 bits<5> Rn;
3369 let Inst{31-23} = 0b000111100;
3370 let Inst{21-19} = 0b100;
3371 let Inst{18-15} = opcode;
3372 let Inst{14-10} = 0b10000;
3373 let Inst{9-5} = Rn;
3374 let Inst{4-0} = Rd;
3375}
3376
3377multiclass SingleOperandFPData<bits<4> opcode, string asm,
3378 SDPatternOperator node = null_frag> {
3379 def Sr : BaseSingleOperandFPData<opcode, FPR32, f32, asm, node> {
3380 let Inst{22} = 0; // 32-bit size flag
3381 }
3382
3383 def Dr : BaseSingleOperandFPData<opcode, FPR64, f64, asm, node> {
3384 let Inst{22} = 1; // 64-bit size flag
3385 }
3386}
3387
3388//---
3389// Two operand floating point data processing
3390//---
3391
3392let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
3393class BaseTwoOperandFPData<bits<4> opcode, RegisterClass regtype,
3394 string asm, list<dag> pat>
3395 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm),
3396 asm, "\t$Rd, $Rn, $Rm", "", pat>,
3397 Sched<[WriteF]> {
3398 bits<5> Rd;
3399 bits<5> Rn;
3400 bits<5> Rm;
3401 let Inst{31-23} = 0b000111100;
3402 let Inst{21} = 1;
3403 let Inst{20-16} = Rm;
3404 let Inst{15-12} = opcode;
3405 let Inst{11-10} = 0b10;
3406 let Inst{9-5} = Rn;
3407 let Inst{4-0} = Rd;
3408}
3409
3410multiclass TwoOperandFPData<bits<4> opcode, string asm,
3411 SDPatternOperator node = null_frag> {
3412 def Srr : BaseTwoOperandFPData<opcode, FPR32, asm,
3413 [(set (f32 FPR32:$Rd),
3414 (node (f32 FPR32:$Rn), (f32 FPR32:$Rm)))]> {
3415 let Inst{22} = 0; // 32-bit size flag
3416 }
3417
3418 def Drr : BaseTwoOperandFPData<opcode, FPR64, asm,
3419 [(set (f64 FPR64:$Rd),
3420 (node (f64 FPR64:$Rn), (f64 FPR64:$Rm)))]> {
3421 let Inst{22} = 1; // 64-bit size flag
3422 }
3423}
3424
3425multiclass TwoOperandFPDataNeg<bits<4> opcode, string asm, SDNode node> {
3426 def Srr : BaseTwoOperandFPData<opcode, FPR32, asm,
3427 [(set FPR32:$Rd, (fneg (node FPR32:$Rn, (f32 FPR32:$Rm))))]> {
3428 let Inst{22} = 0; // 32-bit size flag
3429 }
3430
3431 def Drr : BaseTwoOperandFPData<opcode, FPR64, asm,
3432 [(set FPR64:$Rd, (fneg (node FPR64:$Rn, (f64 FPR64:$Rm))))]> {
3433 let Inst{22} = 1; // 64-bit size flag
3434 }
3435}
3436
3437
3438//---
3439// Three operand floating point data processing
3440//---
3441
3442class BaseThreeOperandFPData<bit isNegated, bit isSub,
3443 RegisterClass regtype, string asm, list<dag> pat>
3444 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, regtype: $Ra),
3445 asm, "\t$Rd, $Rn, $Rm, $Ra", "", pat>,
3446 Sched<[WriteFMul]> {
3447 bits<5> Rd;
3448 bits<5> Rn;
3449 bits<5> Rm;
3450 bits<5> Ra;
3451 let Inst{31-23} = 0b000111110;
3452 let Inst{21} = isNegated;
3453 let Inst{20-16} = Rm;
3454 let Inst{15} = isSub;
3455 let Inst{14-10} = Ra;
3456 let Inst{9-5} = Rn;
3457 let Inst{4-0} = Rd;
3458}
3459
3460multiclass ThreeOperandFPData<bit isNegated, bit isSub,string asm,
3461 SDPatternOperator node> {
3462 def Srrr : BaseThreeOperandFPData<isNegated, isSub, FPR32, asm,
3463 [(set FPR32:$Rd,
3464 (node (f32 FPR32:$Rn), (f32 FPR32:$Rm), (f32 FPR32:$Ra)))]> {
3465 let Inst{22} = 0; // 32-bit size flag
3466 }
3467
3468 def Drrr : BaseThreeOperandFPData<isNegated, isSub, FPR64, asm,
3469 [(set FPR64:$Rd,
3470 (node (f64 FPR64:$Rn), (f64 FPR64:$Rm), (f64 FPR64:$Ra)))]> {
3471 let Inst{22} = 1; // 64-bit size flag
3472 }
3473}
3474
3475//---
3476// Floating point data comparisons
3477//---
3478
3479let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
3480class BaseOneOperandFPComparison<bit signalAllNans,
3481 RegisterClass regtype, string asm,
3482 list<dag> pat>
3483 : I<(outs), (ins regtype:$Rn), asm, "\t$Rn, #0.0", "", pat>,
3484 Sched<[WriteFCmp]> {
3485 bits<5> Rn;
3486 let Inst{31-23} = 0b000111100;
3487 let Inst{21} = 1;
3488
3489 let Inst{20-16} = 0b00000;
3490 let Inst{15-10} = 0b001000;
3491 let Inst{9-5} = Rn;
3492 let Inst{4} = signalAllNans;
3493 let Inst{3-0} = 0b1000;
3494}
3495
3496let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
3497class BaseTwoOperandFPComparison<bit signalAllNans, RegisterClass regtype,
3498 string asm, list<dag> pat>
3499 : I<(outs), (ins regtype:$Rn, regtype:$Rm), asm, "\t$Rn, $Rm", "", pat>,
3500 Sched<[WriteFCmp]> {
3501 bits<5> Rm;
3502 bits<5> Rn;
3503 let Inst{31-23} = 0b000111100;
3504 let Inst{21} = 1;
3505 let Inst{20-16} = Rm;
3506 let Inst{15-10} = 0b001000;
3507 let Inst{9-5} = Rn;
3508 let Inst{4} = signalAllNans;
3509 let Inst{3-0} = 0b0000;
3510}
3511
3512multiclass FPComparison<bit signalAllNans, string asm,
3513 SDPatternOperator OpNode = null_frag> {
3514 let Defs = [CPSR] in {
3515 def Srr : BaseTwoOperandFPComparison<signalAllNans, FPR32, asm,
3516 [(OpNode FPR32:$Rn, (f32 FPR32:$Rm)), (implicit CPSR)]> {
3517 let Inst{22} = 0;
3518 }
3519
3520 def Sri : BaseOneOperandFPComparison<signalAllNans, FPR32, asm,
3521 [(OpNode (f32 FPR32:$Rn), fpimm0), (implicit CPSR)]> {
3522 let Inst{22} = 0;
3523 }
3524
3525 def Drr : BaseTwoOperandFPComparison<signalAllNans, FPR64, asm,
3526 [(OpNode FPR64:$Rn, (f64 FPR64:$Rm)), (implicit CPSR)]> {
3527 let Inst{22} = 1;
3528 }
3529
3530 def Dri : BaseOneOperandFPComparison<signalAllNans, FPR64, asm,
3531 [(OpNode (f64 FPR64:$Rn), fpimm0), (implicit CPSR)]> {
3532 let Inst{22} = 1;
3533 }
3534 } // Defs = [CPSR]
3535}
3536
3537//---
3538// Floating point conditional comparisons
3539//---
3540
3541let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
3542class BaseFPCondComparison<bit signalAllNans,
3543 RegisterClass regtype, string asm>
3544 : I<(outs), (ins regtype:$Rn, regtype:$Rm, imm0_15:$nzcv, ccode:$cond),
3545 asm, "\t$Rn, $Rm, $nzcv, $cond", "", []>,
3546 Sched<[WriteFCmp]> {
3547 bits<5> Rn;
3548 bits<5> Rm;
3549 bits<4> nzcv;
3550 bits<4> cond;
3551
3552 let Inst{31-23} = 0b000111100;
3553 let Inst{21} = 1;
3554 let Inst{20-16} = Rm;
3555 let Inst{15-12} = cond;
3556 let Inst{11-10} = 0b01;
3557 let Inst{9-5} = Rn;
3558 let Inst{4} = signalAllNans;
3559 let Inst{3-0} = nzcv;
3560}
3561
3562multiclass FPCondComparison<bit signalAllNans, string asm> {
3563 let Defs = [CPSR], Uses = [CPSR] in {
3564 def Srr : BaseFPCondComparison<signalAllNans, FPR32, asm> {
3565 let Inst{22} = 0;
3566 }
3567
3568 def Drr : BaseFPCondComparison<signalAllNans, FPR64, asm> {
3569 let Inst{22} = 1;
3570 }
3571 } // Defs = [CPSR], Uses = [CPSR]
3572}
3573
3574//---
3575// Floating point conditional select
3576//---
3577
3578class BaseFPCondSelect<RegisterClass regtype, ValueType vt, string asm>
3579 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, ccode:$cond),
3580 asm, "\t$Rd, $Rn, $Rm, $cond", "",
3581 [(set regtype:$Rd,
3582 (ARM64csel (vt regtype:$Rn), regtype:$Rm,
3583 (i32 imm:$cond), CPSR))]>,
3584 Sched<[WriteF]> {
3585 bits<5> Rd;
3586 bits<5> Rn;
3587 bits<5> Rm;
3588 bits<4> cond;
3589
3590 let Inst{31-23} = 0b000111100;
3591 let Inst{21} = 1;
3592 let Inst{20-16} = Rm;
3593 let Inst{15-12} = cond;
3594 let Inst{11-10} = 0b11;
3595 let Inst{9-5} = Rn;
3596 let Inst{4-0} = Rd;
3597}
3598
3599multiclass FPCondSelect<string asm> {
3600 let Uses = [CPSR] in {
3601 def Srrr : BaseFPCondSelect<FPR32, f32, asm> {
3602 let Inst{22} = 0;
3603 }
3604
3605 def Drrr : BaseFPCondSelect<FPR64, f64, asm> {
3606 let Inst{22} = 1;
3607 }
3608 } // Uses = [CPSR]
3609}
3610
3611//---
3612// Floating move immediate
3613//---
3614
3615class BaseFPMoveImmediate<RegisterClass regtype, Operand fpimmtype, string asm>
3616 : I<(outs regtype:$Rd), (ins fpimmtype:$imm), asm, "\t$Rd, $imm", "",
3617 [(set regtype:$Rd, fpimmtype:$imm)]>,
3618 Sched<[WriteFImm]> {
3619 bits<5> Rd;
3620 bits<8> imm;
3621 let Inst{31-23} = 0b000111100;
3622 let Inst{21} = 1;
3623 let Inst{20-13} = imm;
3624 let Inst{12-5} = 0b10000000;
3625 let Inst{4-0} = Rd;
3626}
3627
3628multiclass FPMoveImmediate<string asm> {
3629 def Si : BaseFPMoveImmediate<FPR32, fpimm32, asm> {
3630 let Inst{22} = 0;
3631 }
3632
3633 def Di : BaseFPMoveImmediate<FPR64, fpimm64, asm> {
3634 let Inst{22} = 1;
3635 }
3636}
3637
3638//----------------------------------------------------------------------------
3639// AdvSIMD
3640//----------------------------------------------------------------------------
3641
3642def VectorIndexBOperand : AsmOperandClass { let Name = "VectorIndexB"; }
3643def VectorIndexHOperand : AsmOperandClass { let Name = "VectorIndexH"; }
3644def VectorIndexSOperand : AsmOperandClass { let Name = "VectorIndexS"; }
3645def VectorIndexDOperand : AsmOperandClass { let Name = "VectorIndexD"; }
3646def VectorIndexB : Operand<i64>, ImmLeaf<i64, [{
3647 return ((uint64_t)Imm) < 16;
3648}]> {
3649 let ParserMatchClass = VectorIndexBOperand;
3650 let PrintMethod = "printVectorIndex";
3651 let MIOperandInfo = (ops i64imm);
3652}
3653def VectorIndexH : Operand<i64>, ImmLeaf<i64, [{
3654 return ((uint64_t)Imm) < 8;
3655}]> {
3656 let ParserMatchClass = VectorIndexHOperand;
3657 let PrintMethod = "printVectorIndex";
3658 let MIOperandInfo = (ops i64imm);
3659}
3660def VectorIndexS : Operand<i64>, ImmLeaf<i64, [{
3661 return ((uint64_t)Imm) < 4;
3662}]> {
3663 let ParserMatchClass = VectorIndexSOperand;
3664 let PrintMethod = "printVectorIndex";
3665 let MIOperandInfo = (ops i64imm);
3666}
3667def VectorIndexD : Operand<i64>, ImmLeaf<i64, [{
3668 return ((uint64_t)Imm) < 2;
3669}]> {
3670 let ParserMatchClass = VectorIndexDOperand;
3671 let PrintMethod = "printVectorIndex";
3672 let MIOperandInfo = (ops i64imm);
3673}
3674
3675//----------------------------------------------------------------------------
3676// AdvSIMD three register vector instructions
3677//----------------------------------------------------------------------------
3678
3679let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
3680class BaseSIMDThreeSameVector<bit Q, bit U, bits<2> size, bits<5> opcode,
3681 RegisterOperand regtype, string asm, string kind,
3682 list<dag> pattern>
3683 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), asm,
3684 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind #
3685 "|" # kind # "\t$Rd, $Rn, $Rm|}", "", pattern>,
3686 Sched<[WriteV]> {
3687 bits<5> Rd;
3688 bits<5> Rn;
3689 bits<5> Rm;
3690 let Inst{31} = 0;
3691 let Inst{30} = Q;
3692 let Inst{29} = U;
3693 let Inst{28-24} = 0b01110;
3694 let Inst{23-22} = size;
3695 let Inst{21} = 1;
3696 let Inst{20-16} = Rm;
3697 let Inst{15-11} = opcode;
3698 let Inst{10} = 1;
3699 let Inst{9-5} = Rn;
3700 let Inst{4-0} = Rd;
3701}
3702
3703let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
3704class BaseSIMDThreeSameVectorTied<bit Q, bit U, bits<2> size, bits<5> opcode,
3705 RegisterOperand regtype, string asm, string kind,
3706 list<dag> pattern>
3707 : I<(outs regtype:$dst), (ins regtype:$Rd, regtype:$Rn, regtype:$Rm), asm,
3708 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind #
3709 "|" # kind # "\t$Rd, $Rn, $Rm}", "$Rd = $dst", pattern>,
3710 Sched<[WriteV]> {
3711 bits<5> Rd;
3712 bits<5> Rn;
3713 bits<5> Rm;
3714 let Inst{31} = 0;
3715 let Inst{30} = Q;
3716 let Inst{29} = U;
3717 let Inst{28-24} = 0b01110;
3718 let Inst{23-22} = size;
3719 let Inst{21} = 1;
3720 let Inst{20-16} = Rm;
3721 let Inst{15-11} = opcode;
3722 let Inst{10} = 1;
3723 let Inst{9-5} = Rn;
3724 let Inst{4-0} = Rd;
3725}
3726
3727// All operand sizes distinguished in the encoding.
3728multiclass SIMDThreeSameVector<bit U, bits<5> opc, string asm,
3729 SDPatternOperator OpNode> {
3730 def v8i8 : BaseSIMDThreeSameVector<0, U, 0b00, opc, V64,
3731 asm, ".8b",
3732 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
3733 def v16i8 : BaseSIMDThreeSameVector<1, U, 0b00, opc, V128,
3734 asm, ".16b",
3735 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn), (v16i8 V128:$Rm)))]>;
3736 def v4i16 : BaseSIMDThreeSameVector<0, U, 0b01, opc, V64,
3737 asm, ".4h",
3738 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>;
3739 def v8i16 : BaseSIMDThreeSameVector<1, U, 0b01, opc, V128,
3740 asm, ".8h",
3741 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>;
3742 def v2i32 : BaseSIMDThreeSameVector<0, U, 0b10, opc, V64,
3743 asm, ".2s",
3744 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>;
3745 def v4i32 : BaseSIMDThreeSameVector<1, U, 0b10, opc, V128,
3746 asm, ".4s",
3747 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>;
3748 def v2i64 : BaseSIMDThreeSameVector<1, U, 0b11, opc, V128,
3749 asm, ".2d",
3750 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn), (v2i64 V128:$Rm)))]>;
3751}
3752
3753// As above, but D sized elements unsupported.
3754multiclass SIMDThreeSameVectorBHS<bit U, bits<5> opc, string asm,
3755 SDPatternOperator OpNode> {
3756 def v8i8 : BaseSIMDThreeSameVector<0, U, 0b00, opc, V64,
3757 asm, ".8b",
3758 [(set V64:$Rd, (v8i8 (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm))))]>;
3759 def v16i8 : BaseSIMDThreeSameVector<1, U, 0b00, opc, V128,
3760 asm, ".16b",
3761 [(set V128:$Rd, (v16i8 (OpNode (v16i8 V128:$Rn), (v16i8 V128:$Rm))))]>;
3762 def v4i16 : BaseSIMDThreeSameVector<0, U, 0b01, opc, V64,
3763 asm, ".4h",
3764 [(set V64:$Rd, (v4i16 (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm))))]>;
3765 def v8i16 : BaseSIMDThreeSameVector<1, U, 0b01, opc, V128,
3766 asm, ".8h",
3767 [(set V128:$Rd, (v8i16 (OpNode (v8i16 V128:$Rn), (v8i16 V128:$Rm))))]>;
3768 def v2i32 : BaseSIMDThreeSameVector<0, U, 0b10, opc, V64,
3769 asm, ".2s",
3770 [(set V64:$Rd, (v2i32 (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm))))]>;
3771 def v4i32 : BaseSIMDThreeSameVector<1, U, 0b10, opc, V128,
3772 asm, ".4s",
3773 [(set V128:$Rd, (v4i32 (OpNode (v4i32 V128:$Rn), (v4i32 V128:$Rm))))]>;
3774}
3775
3776multiclass SIMDThreeSameVectorBHSTied<bit U, bits<5> opc, string asm,
3777 SDPatternOperator OpNode> {
3778 def v8i8 : BaseSIMDThreeSameVectorTied<0, U, 0b00, opc, V64,
3779 asm, ".8b",
3780 [(set (v8i8 V64:$dst),
3781 (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
3782 def v16i8 : BaseSIMDThreeSameVectorTied<1, U, 0b00, opc, V128,
3783 asm, ".16b",
3784 [(set (v16i8 V128:$dst),
3785 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn), (v16i8 V128:$Rm)))]>;
3786 def v4i16 : BaseSIMDThreeSameVectorTied<0, U, 0b01, opc, V64,
3787 asm, ".4h",
3788 [(set (v4i16 V64:$dst),
3789 (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>;
3790 def v8i16 : BaseSIMDThreeSameVectorTied<1, U, 0b01, opc, V128,
3791 asm, ".8h",
3792 [(set (v8i16 V128:$dst),
3793 (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>;
3794 def v2i32 : BaseSIMDThreeSameVectorTied<0, U, 0b10, opc, V64,
3795 asm, ".2s",
3796 [(set (v2i32 V64:$dst),
3797 (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>;
3798 def v4i32 : BaseSIMDThreeSameVectorTied<1, U, 0b10, opc, V128,
3799 asm, ".4s",
3800 [(set (v4i32 V128:$dst),
3801 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>;
3802}
3803
3804// As above, but only B sized elements supported.
3805multiclass SIMDThreeSameVectorB<bit U, bits<5> opc, string asm,
3806 SDPatternOperator OpNode> {
3807 def v8i8 : BaseSIMDThreeSameVector<0, U, 0b00, opc, V64,
3808 asm, ".8b",
3809 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
3810 def v16i8 : BaseSIMDThreeSameVector<1, U, 0b00, opc, V128,
3811 asm, ".16b",
3812 [(set (v16i8 V128:$Rd),
3813 (OpNode (v16i8 V128:$Rn), (v16i8 V128:$Rm)))]>;
3814}
3815
3816// As above, but only S and D sized floating point elements supported.
3817multiclass SIMDThreeSameVectorFP<bit U, bit S, bits<5> opc,
3818 string asm, SDPatternOperator OpNode> {
3819 def v2f32 : BaseSIMDThreeSameVector<0, U, {S,0}, opc, V64,
3820 asm, ".2s",
3821 [(set (v2f32 V64:$Rd), (OpNode (v2f32 V64:$Rn), (v2f32 V64:$Rm)))]>;
3822 def v4f32 : BaseSIMDThreeSameVector<1, U, {S,0}, opc, V128,
3823 asm, ".4s",
3824 [(set (v4f32 V128:$Rd), (OpNode (v4f32 V128:$Rn), (v4f32 V128:$Rm)))]>;
3825 def v2f64 : BaseSIMDThreeSameVector<1, U, {S,1}, opc, V128,
3826 asm, ".2d",
3827 [(set (v2f64 V128:$Rd), (OpNode (v2f64 V128:$Rn), (v2f64 V128:$Rm)))]>;
3828}
3829
3830multiclass SIMDThreeSameVectorFPCmp<bit U, bit S, bits<5> opc,
3831 string asm,
3832 SDPatternOperator OpNode> {
3833 def v2f32 : BaseSIMDThreeSameVector<0, U, {S,0}, opc, V64,
3834 asm, ".2s",
3835 [(set (v2i32 V64:$Rd), (OpNode (v2f32 V64:$Rn), (v2f32 V64:$Rm)))]>;
3836 def v4f32 : BaseSIMDThreeSameVector<1, U, {S,0}, opc, V128,
3837 asm, ".4s",
3838 [(set (v4i32 V128:$Rd), (OpNode (v4f32 V128:$Rn), (v4f32 V128:$Rm)))]>;
3839 def v2f64 : BaseSIMDThreeSameVector<1, U, {S,1}, opc, V128,
3840 asm, ".2d",
3841 [(set (v2i64 V128:$Rd), (OpNode (v2f64 V128:$Rn), (v2f64 V128:$Rm)))]>;
3842}
3843
3844multiclass SIMDThreeSameVectorFPTied<bit U, bit S, bits<5> opc,
3845 string asm, SDPatternOperator OpNode> {
3846 def v2f32 : BaseSIMDThreeSameVectorTied<0, U, {S,0}, opc, V64,
3847 asm, ".2s",
3848 [(set (v2f32 V64:$dst),
3849 (OpNode (v2f32 V64:$Rd), (v2f32 V64:$Rn), (v2f32 V64:$Rm)))]>;
3850 def v4f32 : BaseSIMDThreeSameVectorTied<1, U, {S,0}, opc, V128,
3851 asm, ".4s",
3852 [(set (v4f32 V128:$dst),
3853 (OpNode (v4f32 V128:$Rd), (v4f32 V128:$Rn), (v4f32 V128:$Rm)))]>;
3854 def v2f64 : BaseSIMDThreeSameVectorTied<1, U, {S,1}, opc, V128,
3855 asm, ".2d",
3856 [(set (v2f64 V128:$dst),
3857 (OpNode (v2f64 V128:$Rd), (v2f64 V128:$Rn), (v2f64 V128:$Rm)))]>;
3858}
3859
3860// As above, but D and B sized elements unsupported.
3861multiclass SIMDThreeSameVectorHS<bit U, bits<5> opc, string asm,
3862 SDPatternOperator OpNode> {
3863 def v4i16 : BaseSIMDThreeSameVector<0, U, 0b01, opc, V64,
3864 asm, ".4h",
3865 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>;
3866 def v8i16 : BaseSIMDThreeSameVector<1, U, 0b01, opc, V128,
3867 asm, ".8h",
3868 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>;
3869 def v2i32 : BaseSIMDThreeSameVector<0, U, 0b10, opc, V64,
3870 asm, ".2s",
3871 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>;
3872 def v4i32 : BaseSIMDThreeSameVector<1, U, 0b10, opc, V128,
3873 asm, ".4s",
3874 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>;
3875}
3876
3877// Logical three vector ops share opcode bits, and only use B sized elements.
3878multiclass SIMDLogicalThreeVector<bit U, bits<2> size, string asm,
3879 SDPatternOperator OpNode = null_frag> {
3880 def v8i8 : BaseSIMDThreeSameVector<0, U, size, 0b00011, V64,
3881 asm, ".8b",
3882 [(set (v8i8 V64:$Rd), (OpNode V64:$Rn, V64:$Rm))]>;
3883 def v16i8 : BaseSIMDThreeSameVector<1, U, size, 0b00011, V128,
3884 asm, ".16b",
3885 [(set (v16i8 V128:$Rd), (OpNode V128:$Rn, V128:$Rm))]>;
3886
3887 def : Pat<(v4i16 (OpNode V64:$LHS, V64:$RHS)),
3888 (!cast<Instruction>(NAME#"v8i8") V64:$LHS, V64:$RHS)>;
3889 def : Pat<(v2i32 (OpNode V64:$LHS, V64:$RHS)),
3890 (!cast<Instruction>(NAME#"v8i8") V64:$LHS, V64:$RHS)>;
3891 def : Pat<(v1i64 (OpNode V64:$LHS, V64:$RHS)),
3892 (!cast<Instruction>(NAME#"v8i8") V64:$LHS, V64:$RHS)>;
3893
3894 def : Pat<(v8i16 (OpNode V128:$LHS, V128:$RHS)),
3895 (!cast<Instruction>(NAME#"v16i8") V128:$LHS, V128:$RHS)>;
3896 def : Pat<(v4i32 (OpNode V128:$LHS, V128:$RHS)),
3897 (!cast<Instruction>(NAME#"v16i8") V128:$LHS, V128:$RHS)>;
3898 def : Pat<(v2i64 (OpNode V128:$LHS, V128:$RHS)),
3899 (!cast<Instruction>(NAME#"v16i8") V128:$LHS, V128:$RHS)>;
3900}
3901
3902multiclass SIMDLogicalThreeVectorTied<bit U, bits<2> size,
3903 string asm, SDPatternOperator OpNode> {
3904 def v8i8 : BaseSIMDThreeSameVectorTied<0, U, size, 0b00011, V64,
3905 asm, ".8b",
3906 [(set (v8i8 V64:$dst),
3907 (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
3908 def v16i8 : BaseSIMDThreeSameVectorTied<1, U, size, 0b00011, V128,
3909 asm, ".16b",
3910 [(set (v16i8 V128:$dst),
3911 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn),
3912 (v16i8 V128:$Rm)))]>;
3913
3914 def : Pat<(v4i16 (OpNode (v4i16 V64:$LHS), (v4i16 V64:$MHS),
3915 (v4i16 V64:$RHS))),
3916 (!cast<Instruction>(NAME#"v8i8")
3917 V64:$LHS, V64:$MHS, V64:$RHS)>;
3918 def : Pat<(v2i32 (OpNode (v2i32 V64:$LHS), (v2i32 V64:$MHS),
3919 (v2i32 V64:$RHS))),
3920 (!cast<Instruction>(NAME#"v8i8")
3921 V64:$LHS, V64:$MHS, V64:$RHS)>;
3922 def : Pat<(v1i64 (OpNode (v1i64 V64:$LHS), (v1i64 V64:$MHS),
3923 (v1i64 V64:$RHS))),
3924 (!cast<Instruction>(NAME#"v8i8")
3925 V64:$LHS, V64:$MHS, V64:$RHS)>;
3926
3927 def : Pat<(v8i16 (OpNode (v8i16 V128:$LHS), (v8i16 V128:$MHS),
3928 (v8i16 V128:$RHS))),
3929 (!cast<Instruction>(NAME#"v16i8")
3930 V128:$LHS, V128:$MHS, V128:$RHS)>;
3931 def : Pat<(v4i32 (OpNode (v4i32 V128:$LHS), (v4i32 V128:$MHS),
3932 (v4i32 V128:$RHS))),
3933 (!cast<Instruction>(NAME#"v16i8")
3934 V128:$LHS, V128:$MHS, V128:$RHS)>;
3935 def : Pat<(v2i64 (OpNode (v2i64 V128:$LHS), (v2i64 V128:$MHS),
3936 (v2i64 V128:$RHS))),
3937 (!cast<Instruction>(NAME#"v16i8")
3938 V128:$LHS, V128:$MHS, V128:$RHS)>;
3939}
3940
3941
3942//----------------------------------------------------------------------------
3943// AdvSIMD two register vector instructions.
3944//----------------------------------------------------------------------------
3945
3946let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
3947class BaseSIMDTwoSameVector<bit Q, bit U, bits<2> size, bits<5> opcode,
3948 RegisterOperand regtype, string asm, string dstkind,
3949 string srckind, list<dag> pattern>
3950 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm,
3951 "{\t$Rd" # dstkind # ", $Rn" # srckind #
3952 "|" # dstkind # "\t$Rd, $Rn}", "", pattern>,
3953 Sched<[WriteV]> {
3954 bits<5> Rd;
3955 bits<5> Rn;
3956 let Inst{31} = 0;
3957 let Inst{30} = Q;
3958 let Inst{29} = U;
3959 let Inst{28-24} = 0b01110;
3960 let Inst{23-22} = size;
3961 let Inst{21-17} = 0b10000;
3962 let Inst{16-12} = opcode;
3963 let Inst{11-10} = 0b10;
3964 let Inst{9-5} = Rn;
3965 let Inst{4-0} = Rd;
3966}
3967
3968let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
3969class BaseSIMDTwoSameVectorTied<bit Q, bit U, bits<2> size, bits<5> opcode,
3970 RegisterOperand regtype, string asm, string dstkind,
3971 string srckind, list<dag> pattern>
3972 : I<(outs regtype:$dst), (ins regtype:$Rd, regtype:$Rn), asm,
3973 "{\t$Rd" # dstkind # ", $Rn" # srckind #
3974 "|" # dstkind # "\t$Rd, $Rn}", "$Rd = $dst", pattern>,
3975 Sched<[WriteV]> {
3976 bits<5> Rd;
3977 bits<5> Rn;
3978 let Inst{31} = 0;
3979 let Inst{30} = Q;
3980 let Inst{29} = U;
3981 let Inst{28-24} = 0b01110;
3982 let Inst{23-22} = size;
3983 let Inst{21-17} = 0b10000;
3984 let Inst{16-12} = opcode;
3985 let Inst{11-10} = 0b10;
3986 let Inst{9-5} = Rn;
3987 let Inst{4-0} = Rd;
3988}
3989
3990// Supports B, H, and S element sizes.
3991multiclass SIMDTwoVectorBHS<bit U, bits<5> opc, string asm,
3992 SDPatternOperator OpNode> {
3993 def v8i8 : BaseSIMDTwoSameVector<0, U, 0b00, opc, V64,
3994 asm, ".8b", ".8b",
3995 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>;
3996 def v16i8 : BaseSIMDTwoSameVector<1, U, 0b00, opc, V128,
3997 asm, ".16b", ".16b",
3998 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>;
3999 def v4i16 : BaseSIMDTwoSameVector<0, U, 0b01, opc, V64,
4000 asm, ".4h", ".4h",
4001 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>;
4002 def v8i16 : BaseSIMDTwoSameVector<1, U, 0b01, opc, V128,
4003 asm, ".8h", ".8h",
4004 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>;
4005 def v2i32 : BaseSIMDTwoSameVector<0, U, 0b10, opc, V64,
4006 asm, ".2s", ".2s",
4007 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>;
4008 def v4i32 : BaseSIMDTwoSameVector<1, U, 0b10, opc, V128,
4009 asm, ".4s", ".4s",
4010 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>;
4011}
4012
4013class BaseSIMDVectorLShiftLongBySize<bit Q, bits<2> size,
4014 RegisterOperand regtype, string asm, string dstkind,
4015 string srckind, string amount>
4016 : I<(outs V128:$Rd), (ins regtype:$Rn), asm,
4017 "{\t$Rd" # dstkind # ", $Rn" # srckind # ", #" # amount #
4018 "|" # dstkind # "\t$Rd, $Rn, #" # amount # "}", "", []>,
4019 Sched<[WriteV]> {
4020 bits<5> Rd;
4021 bits<5> Rn;
4022 let Inst{31} = 0;
4023 let Inst{30} = Q;
4024 let Inst{29-24} = 0b101110;
4025 let Inst{23-22} = size;
4026 let Inst{21-10} = 0b100001001110;
4027 let Inst{9-5} = Rn;
4028 let Inst{4-0} = Rd;
4029}
4030
4031multiclass SIMDVectorLShiftLongBySizeBHS {
4032 let neverHasSideEffects = 1 in {
4033 def v8i8 : BaseSIMDVectorLShiftLongBySize<0, 0b00, V64,
4034 "shll", ".8h", ".8b", "8">;
4035 def v16i8 : BaseSIMDVectorLShiftLongBySize<1, 0b00, V128,
4036 "shll2", ".8h", ".16b", "8">;
4037 def v4i16 : BaseSIMDVectorLShiftLongBySize<0, 0b01, V64,
4038 "shll", ".4s", ".4h", "16">;
4039 def v8i16 : BaseSIMDVectorLShiftLongBySize<1, 0b01, V128,
4040 "shll2", ".4s", ".8h", "16">;
4041 def v2i32 : BaseSIMDVectorLShiftLongBySize<0, 0b10, V64,
4042 "shll", ".2d", ".2s", "32">;
4043 def v4i32 : BaseSIMDVectorLShiftLongBySize<1, 0b10, V128,
4044 "shll2", ".2d", ".4s", "32">;
4045 }
4046}
4047
4048// Supports all element sizes.
4049multiclass SIMDLongTwoVector<bit U, bits<5> opc, string asm,
4050 SDPatternOperator OpNode> {
4051 def v8i8_v4i16 : BaseSIMDTwoSameVector<0, U, 0b00, opc, V64,
4052 asm, ".4h", ".8b",
4053 [(set (v4i16 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>;
4054 def v16i8_v8i16 : BaseSIMDTwoSameVector<1, U, 0b00, opc, V128,
4055 asm, ".8h", ".16b",
4056 [(set (v8i16 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>;
4057 def v4i16_v2i32 : BaseSIMDTwoSameVector<0, U, 0b01, opc, V64,
4058 asm, ".2s", ".4h",
4059 [(set (v2i32 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>;
4060 def v8i16_v4i32 : BaseSIMDTwoSameVector<1, U, 0b01, opc, V128,
4061 asm, ".4s", ".8h",
4062 [(set (v4i32 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>;
4063 def v2i32_v1i64 : BaseSIMDTwoSameVector<0, U, 0b10, opc, V64,
4064 asm, ".1d", ".2s",
4065 [(set (v1i64 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>;
4066 def v4i32_v2i64 : BaseSIMDTwoSameVector<1, U, 0b10, opc, V128,
4067 asm, ".2d", ".4s",
4068 [(set (v2i64 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>;
4069}
4070
4071multiclass SIMDLongTwoVectorTied<bit U, bits<5> opc, string asm,
4072 SDPatternOperator OpNode> {
4073 def v8i8_v4i16 : BaseSIMDTwoSameVectorTied<0, U, 0b00, opc, V64,
4074 asm, ".4h", ".8b",
4075 [(set (v4i16 V64:$dst), (OpNode (v4i16 V64:$Rd),
4076 (v8i8 V64:$Rn)))]>;
4077 def v16i8_v8i16 : BaseSIMDTwoSameVectorTied<1, U, 0b00, opc, V128,
4078 asm, ".8h", ".16b",
4079 [(set (v8i16 V128:$dst), (OpNode (v8i16 V128:$Rd),
4080 (v16i8 V128:$Rn)))]>;
4081 def v4i16_v2i32 : BaseSIMDTwoSameVectorTied<0, U, 0b01, opc, V64,
4082 asm, ".2s", ".4h",
4083 [(set (v2i32 V64:$dst), (OpNode (v2i32 V64:$Rd),
4084 (v4i16 V64:$Rn)))]>;
4085 def v8i16_v4i32 : BaseSIMDTwoSameVectorTied<1, U, 0b01, opc, V128,
4086 asm, ".4s", ".8h",
4087 [(set (v4i32 V128:$dst), (OpNode (v4i32 V128:$Rd),
4088 (v8i16 V128:$Rn)))]>;
4089 def v2i32_v1i64 : BaseSIMDTwoSameVectorTied<0, U, 0b10, opc, V64,
4090 asm, ".1d", ".2s",
4091 [(set (v1i64 V64:$dst), (OpNode (v1i64 V64:$Rd),
4092 (v2i32 V64:$Rn)))]>;
4093 def v4i32_v2i64 : BaseSIMDTwoSameVectorTied<1, U, 0b10, opc, V128,
4094 asm, ".2d", ".4s",
4095 [(set (v2i64 V128:$dst), (OpNode (v2i64 V128:$Rd),
4096 (v4i32 V128:$Rn)))]>;
4097}
4098
4099// Supports all element sizes, except 1xD.
4100multiclass SIMDTwoVectorBHSDTied<bit U, bits<5> opc, string asm,
4101 SDPatternOperator OpNode> {
4102 def v8i8 : BaseSIMDTwoSameVectorTied<0, U, 0b00, opc, V64,
4103 asm, ".8b", ".8b",
4104 [(set (v8i8 V64:$dst), (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn)))]>;
4105 def v16i8 : BaseSIMDTwoSameVectorTied<1, U, 0b00, opc, V128,
4106 asm, ".16b", ".16b",
4107 [(set (v16i8 V128:$dst), (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn)))]>;
4108 def v4i16 : BaseSIMDTwoSameVectorTied<0, U, 0b01, opc, V64,
4109 asm, ".4h", ".4h",
4110 [(set (v4i16 V64:$dst), (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn)))]>;
4111 def v8i16 : BaseSIMDTwoSameVectorTied<1, U, 0b01, opc, V128,
4112 asm, ".8h", ".8h",
4113 [(set (v8i16 V128:$dst), (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn)))]>;
4114 def v2i32 : BaseSIMDTwoSameVectorTied<0, U, 0b10, opc, V64,
4115 asm, ".2s", ".2s",
4116 [(set (v2i32 V64:$dst), (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn)))]>;
4117 def v4i32 : BaseSIMDTwoSameVectorTied<1, U, 0b10, opc, V128,
4118 asm, ".4s", ".4s",
4119 [(set (v4i32 V128:$dst), (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn)))]>;
4120 def v2i64 : BaseSIMDTwoSameVectorTied<1, U, 0b11, opc, V128,
4121 asm, ".2d", ".2d",
4122 [(set (v2i64 V128:$dst), (OpNode (v2i64 V128:$Rd), (v2i64 V128:$Rn)))]>;
4123}
4124
4125multiclass SIMDTwoVectorBHSD<bit U, bits<5> opc, string asm,
4126 SDPatternOperator OpNode = null_frag> {
4127 def v8i8 : BaseSIMDTwoSameVector<0, U, 0b00, opc, V64,
4128 asm, ".8b", ".8b",
4129 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>;
4130 def v16i8 : BaseSIMDTwoSameVector<1, U, 0b00, opc, V128,
4131 asm, ".16b", ".16b",
4132 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>;
4133 def v4i16 : BaseSIMDTwoSameVector<0, U, 0b01, opc, V64,
4134 asm, ".4h", ".4h",
4135 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>;
4136 def v8i16 : BaseSIMDTwoSameVector<1, U, 0b01, opc, V128,
4137 asm, ".8h", ".8h",
4138 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>;
4139 def v2i32 : BaseSIMDTwoSameVector<0, U, 0b10, opc, V64,
4140 asm, ".2s", ".2s",
4141 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>;
4142 def v4i32 : BaseSIMDTwoSameVector<1, U, 0b10, opc, V128,
4143 asm, ".4s", ".4s",
4144 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>;
4145 def v2i64 : BaseSIMDTwoSameVector<1, U, 0b11, opc, V128,
4146 asm, ".2d", ".2d",
4147 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn)))]>;
4148}
4149
4150
4151// Supports only B element sizes.
4152multiclass SIMDTwoVectorB<bit U, bits<2> size, bits<5> opc, string asm,
4153 SDPatternOperator OpNode> {
4154 def v8i8 : BaseSIMDTwoSameVector<0, U, size, opc, V64,
4155 asm, ".8b", ".8b",
4156 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>;
4157 def v16i8 : BaseSIMDTwoSameVector<1, U, size, opc, V128,
4158 asm, ".16b", ".16b",
4159 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>;
4160
4161}
4162
4163// Supports only B and H element sizes.
4164multiclass SIMDTwoVectorBH<bit U, bits<5> opc, string asm,
4165 SDPatternOperator OpNode> {
4166 def v8i8 : BaseSIMDTwoSameVector<0, U, 0b00, opc, V64,
4167 asm, ".8b", ".8b",
4168 [(set (v8i8 V64:$Rd), (OpNode V64:$Rn))]>;
4169 def v16i8 : BaseSIMDTwoSameVector<1, U, 0b00, opc, V128,
4170 asm, ".16b", ".16b",
4171 [(set (v16i8 V128:$Rd), (OpNode V128:$Rn))]>;
4172 def v4i16 : BaseSIMDTwoSameVector<0, U, 0b01, opc, V64,
4173 asm, ".4h", ".4h",
4174 [(set (v4i16 V64:$Rd), (OpNode V64:$Rn))]>;
4175 def v8i16 : BaseSIMDTwoSameVector<1, U, 0b01, opc, V128,
4176 asm, ".8h", ".8h",
4177 [(set (v8i16 V128:$Rd), (OpNode V128:$Rn))]>;
4178}
4179
4180// Supports only S and D element sizes, uses high bit of the size field
4181// as an extra opcode bit.
4182multiclass SIMDTwoVectorFP<bit U, bit S, bits<5> opc, string asm,
4183 SDPatternOperator OpNode> {
4184 def v2f32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, V64,
4185 asm, ".2s", ".2s",
4186 [(set (v2f32 V64:$Rd), (OpNode (v2f32 V64:$Rn)))]>;
4187 def v4f32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, V128,
4188 asm, ".4s", ".4s",
4189 [(set (v4f32 V128:$Rd), (OpNode (v4f32 V128:$Rn)))]>;
4190 def v2f64 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, V128,
4191 asm, ".2d", ".2d",
4192 [(set (v2f64 V128:$Rd), (OpNode (v2f64 V128:$Rn)))]>;
4193}
4194
4195// Supports only S element size.
4196multiclass SIMDTwoVectorS<bit U, bit S, bits<5> opc, string asm,
4197 SDPatternOperator OpNode> {
4198 def v2i32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, V64,
4199 asm, ".2s", ".2s",
4200 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>;
4201 def v4i32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, V128,
4202 asm, ".4s", ".4s",
4203 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>;
4204}
4205
4206
4207multiclass SIMDTwoVectorFPToInt<bit U, bit S, bits<5> opc, string asm,
4208 SDPatternOperator OpNode> {
4209 def v2f32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, V64,
4210 asm, ".2s", ".2s",
4211 [(set (v2i32 V64:$Rd), (OpNode (v2f32 V64:$Rn)))]>;
4212 def v4f32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, V128,
4213 asm, ".4s", ".4s",
4214 [(set (v4i32 V128:$Rd), (OpNode (v4f32 V128:$Rn)))]>;
4215 def v2f64 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, V128,
4216 asm, ".2d", ".2d",
4217 [(set (v2i64 V128:$Rd), (OpNode (v2f64 V128:$Rn)))]>;
4218}
4219
4220multiclass SIMDTwoVectorIntToFP<bit U, bit S, bits<5> opc, string asm,
4221 SDPatternOperator OpNode> {
4222 def v2f32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, V64,
4223 asm, ".2s", ".2s",
4224 [(set (v2f32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>;
4225 def v4f32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, V128,
4226 asm, ".4s", ".4s",
4227 [(set (v4f32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>;
4228 def v2f64 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, V128,
4229 asm, ".2d", ".2d",
4230 [(set (v2f64 V128:$Rd), (OpNode (v2i64 V128:$Rn)))]>;
4231}
4232
4233
4234class BaseSIMDMixedTwoVector<bit Q, bit U, bits<2> size, bits<5> opcode,
4235 RegisterOperand inreg, RegisterOperand outreg,
4236 string asm, string outkind, string inkind,
4237 list<dag> pattern>
4238 : I<(outs outreg:$Rd), (ins inreg:$Rn), asm,
4239 "{\t$Rd" # outkind # ", $Rn" # inkind #
4240 "|" # outkind # "\t$Rd, $Rn}", "", pattern>,
4241 Sched<[WriteV]> {
4242 bits<5> Rd;
4243 bits<5> Rn;
4244 let Inst{31} = 0;
4245 let Inst{30} = Q;
4246 let Inst{29} = U;
4247 let Inst{28-24} = 0b01110;
4248 let Inst{23-22} = size;
4249 let Inst{21-17} = 0b10000;
4250 let Inst{16-12} = opcode;
4251 let Inst{11-10} = 0b10;
4252 let Inst{9-5} = Rn;
4253 let Inst{4-0} = Rd;
4254}
4255
4256class BaseSIMDMixedTwoVectorTied<bit Q, bit U, bits<2> size, bits<5> opcode,
4257 RegisterOperand inreg, RegisterOperand outreg,
4258 string asm, string outkind, string inkind,
4259 list<dag> pattern>
4260 : I<(outs outreg:$dst), (ins outreg:$Rd, inreg:$Rn), asm,
4261 "{\t$Rd" # outkind # ", $Rn" # inkind #
4262 "|" # outkind # "\t$Rd, $Rn}", "$Rd = $dst", pattern>,
4263 Sched<[WriteV]> {
4264 bits<5> Rd;
4265 bits<5> Rn;
4266 let Inst{31} = 0;
4267 let Inst{30} = Q;
4268 let Inst{29} = U;
4269 let Inst{28-24} = 0b01110;
4270 let Inst{23-22} = size;
4271 let Inst{21-17} = 0b10000;
4272 let Inst{16-12} = opcode;
4273 let Inst{11-10} = 0b10;
4274 let Inst{9-5} = Rn;
4275 let Inst{4-0} = Rd;
4276}
4277
4278multiclass SIMDMixedTwoVector<bit U, bits<5> opc, string asm,
4279 SDPatternOperator OpNode> {
4280 def v8i8 : BaseSIMDMixedTwoVector<0, U, 0b00, opc, V128, V64,
4281 asm, ".8b", ".8h",
4282 [(set (v8i8 V64:$Rd), (OpNode (v8i16 V128:$Rn)))]>;
4283 def v16i8 : BaseSIMDMixedTwoVectorTied<1, U, 0b00, opc, V128, V128,
4284 asm#"2", ".16b", ".8h", []>;
4285 def v4i16 : BaseSIMDMixedTwoVector<0, U, 0b01, opc, V128, V64,
4286 asm, ".4h", ".4s",
4287 [(set (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn)))]>;
4288 def v8i16 : BaseSIMDMixedTwoVectorTied<1, U, 0b01, opc, V128, V128,
4289 asm#"2", ".8h", ".4s", []>;
4290 def v2i32 : BaseSIMDMixedTwoVector<0, U, 0b10, opc, V128, V64,
4291 asm, ".2s", ".2d",
4292 [(set (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn)))]>;
4293 def v4i32 : BaseSIMDMixedTwoVectorTied<1, U, 0b10, opc, V128, V128,
4294 asm#"2", ".4s", ".2d", []>;
4295
4296 def : Pat<(concat_vectors (v8i8 V64:$Rd), (OpNode (v8i16 V128:$Rn))),
4297 (!cast<Instruction>(NAME # "v16i8")
4298 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>;
4299 def : Pat<(concat_vectors (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn))),
4300 (!cast<Instruction>(NAME # "v8i16")
4301 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>;
4302 def : Pat<(concat_vectors (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn))),
4303 (!cast<Instruction>(NAME # "v4i32")
4304 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>;
4305}
4306
4307class BaseSIMDCmpTwoVector<bit Q, bit U, bits<2> size, bits<5> opcode,
4308 RegisterOperand regtype, string asm, string kind,
4309 ValueType dty, ValueType sty, SDNode OpNode>
4310 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm,
4311 "{\t$Rd" # kind # ", $Rn" # kind # ", #0" #
4312 "|" # kind # "\t$Rd, $Rn, #0}", "",
4313 [(set (dty regtype:$Rd), (OpNode (sty regtype:$Rn)))]>,
4314 Sched<[WriteV]> {
4315 bits<5> Rd;
4316 bits<5> Rn;
4317 let Inst{31} = 0;
4318 let Inst{30} = Q;
4319 let Inst{29} = U;
4320 let Inst{28-24} = 0b01110;
4321 let Inst{23-22} = size;
4322 let Inst{21-17} = 0b10000;
4323 let Inst{16-12} = opcode;
4324 let Inst{11-10} = 0b10;
4325 let Inst{9-5} = Rn;
4326 let Inst{4-0} = Rd;
4327}
4328
4329// Comparisons support all element sizes, except 1xD.
4330multiclass SIMDCmpTwoVector<bit U, bits<5> opc, string asm,
4331 SDNode OpNode> {
4332 def v8i8rz : BaseSIMDCmpTwoVector<0, U, 0b00, opc, V64,
4333 asm, ".8b",
4334 v8i8, v8i8, OpNode>;
4335 def v16i8rz : BaseSIMDCmpTwoVector<1, U, 0b00, opc, V128,
4336 asm, ".16b",
4337 v16i8, v16i8, OpNode>;
4338 def v4i16rz : BaseSIMDCmpTwoVector<0, U, 0b01, opc, V64,
4339 asm, ".4h",
4340 v4i16, v4i16, OpNode>;
4341 def v8i16rz : BaseSIMDCmpTwoVector<1, U, 0b01, opc, V128,
4342 asm, ".8h",
4343 v8i16, v8i16, OpNode>;
4344 def v2i32rz : BaseSIMDCmpTwoVector<0, U, 0b10, opc, V64,
4345 asm, ".2s",
4346 v2i32, v2i32, OpNode>;
4347 def v4i32rz : BaseSIMDCmpTwoVector<1, U, 0b10, opc, V128,
4348 asm, ".4s",
4349 v4i32, v4i32, OpNode>;
4350 def v2i64rz : BaseSIMDCmpTwoVector<1, U, 0b11, opc, V128,
4351 asm, ".2d",
4352 v2i64, v2i64, OpNode>;
4353}
4354
4355// FP Comparisons support only S and D element sizes.
4356multiclass SIMDFPCmpTwoVector<bit U, bit S, bits<5> opc,
4357 string asm, SDNode OpNode> {
4358 def v2i32rz : BaseSIMDCmpTwoVector<0, U, {S,0}, opc, V64,
4359 asm, ".2s",
4360 v2i32, v2f32, OpNode>;
4361 def v4i32rz : BaseSIMDCmpTwoVector<1, U, {S,0}, opc, V128,
4362 asm, ".4s",
4363 v4i32, v4f32, OpNode>;
4364 def v2i64rz : BaseSIMDCmpTwoVector<1, U, {S,1}, opc, V128,
4365 asm, ".2d",
4366 v2i64, v2f64, OpNode>;
4367}
4368
4369let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
4370class BaseSIMDFPCvtTwoVector<bit Q, bit U, bits<2> size, bits<5> opcode,
4371 RegisterOperand outtype, RegisterOperand intype,
4372 string asm, string VdTy, string VnTy,
4373 list<dag> pattern>
4374 : I<(outs outtype:$Rd), (ins intype:$Rn), asm,
4375 !strconcat("\t$Rd", VdTy, ", $Rn", VnTy), "", pattern>,
4376 Sched<[WriteV]> {
4377 bits<5> Rd;
4378 bits<5> Rn;
4379 let Inst{31} = 0;
4380 let Inst{30} = Q;
4381 let Inst{29} = U;
4382 let Inst{28-24} = 0b01110;
4383 let Inst{23-22} = size;
4384 let Inst{21-17} = 0b10000;
4385 let Inst{16-12} = opcode;
4386 let Inst{11-10} = 0b10;
4387 let Inst{9-5} = Rn;
4388 let Inst{4-0} = Rd;
4389}
4390
4391class BaseSIMDFPCvtTwoVectorTied<bit Q, bit U, bits<2> size, bits<5> opcode,
4392 RegisterOperand outtype, RegisterOperand intype,
4393 string asm, string VdTy, string VnTy,
4394 list<dag> pattern>
4395 : I<(outs outtype:$dst), (ins outtype:$Rd, intype:$Rn), asm,
4396 !strconcat("\t$Rd", VdTy, ", $Rn", VnTy), "$Rd = $dst", pattern>,
4397 Sched<[WriteV]> {
4398 bits<5> Rd;
4399 bits<5> Rn;
4400 let Inst{31} = 0;
4401 let Inst{30} = Q;
4402 let Inst{29} = U;
4403 let Inst{28-24} = 0b01110;
4404 let Inst{23-22} = size;
4405 let Inst{21-17} = 0b10000;
4406 let Inst{16-12} = opcode;
4407 let Inst{11-10} = 0b10;
4408 let Inst{9-5} = Rn;
4409 let Inst{4-0} = Rd;
4410}
4411
4412multiclass SIMDFPWidenTwoVector<bit U, bit S, bits<5> opc, string asm> {
4413 def v4i16 : BaseSIMDFPCvtTwoVector<0, U, {S,0}, opc, V128, V64,
4414 asm, ".4s", ".4h", []>;
4415 def v8i16 : BaseSIMDFPCvtTwoVector<1, U, {S,0}, opc, V128, V128,
4416 asm#"2", ".4s", ".8h", []>;
4417 def v2i32 : BaseSIMDFPCvtTwoVector<0, U, {S,1}, opc, V128, V64,
4418 asm, ".2d", ".2s", []>;
4419 def v4i32 : BaseSIMDFPCvtTwoVector<1, U, {S,1}, opc, V128, V128,
4420 asm#"2", ".2d", ".4s", []>;
4421}
4422
4423multiclass SIMDFPNarrowTwoVector<bit U, bit S, bits<5> opc, string asm> {
4424 def v4i16 : BaseSIMDFPCvtTwoVector<0, U, {S,0}, opc, V64, V128,
4425 asm, ".4h", ".4s", []>;
4426 def v8i16 : BaseSIMDFPCvtTwoVectorTied<1, U, {S,0}, opc, V128, V128,
4427 asm#"2", ".8h", ".4s", []>;
4428 def v2i32 : BaseSIMDFPCvtTwoVector<0, U, {S,1}, opc, V64, V128,
4429 asm, ".2s", ".2d", []>;
4430 def v4i32 : BaseSIMDFPCvtTwoVectorTied<1, U, {S,1}, opc, V128, V128,
4431 asm#"2", ".4s", ".2d", []>;
4432}
4433
4434multiclass SIMDFPInexactCvtTwoVector<bit U, bit S, bits<5> opc, string asm,
4435 Intrinsic OpNode> {
4436 def v2f32 : BaseSIMDFPCvtTwoVector<0, U, {S,1}, opc, V64, V128,
4437 asm, ".2s", ".2d",
4438 [(set (v2f32 V64:$Rd), (OpNode (v2f64 V128:$Rn)))]>;
4439 def v4f32 : BaseSIMDFPCvtTwoVectorTied<1, U, {S,1}, opc, V128, V128,
4440 asm#"2", ".4s", ".2d", []>;
4441
4442 def : Pat<(concat_vectors (v2f32 V64:$Rd), (OpNode (v2f64 V128:$Rn))),
4443 (!cast<Instruction>(NAME # "v4f32")
4444 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>;
4445}
4446
4447//----------------------------------------------------------------------------
4448// AdvSIMD three register different-size vector instructions.
4449//----------------------------------------------------------------------------
4450
4451let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
4452class BaseSIMDDifferentThreeVector<bit U, bits<3> size, bits<4> opcode,
4453 RegisterOperand outtype, RegisterOperand intype1,
4454 RegisterOperand intype2, string asm,
4455 string outkind, string inkind1, string inkind2,
4456 list<dag> pattern>
4457 : I<(outs outtype:$Rd), (ins intype1:$Rn, intype2:$Rm), asm,
4458 "{\t$Rd" # outkind # ", $Rn" # inkind1 # ", $Rm" # inkind2 #
4459 "|" # outkind # "\t$Rd, $Rn, $Rm}", "", pattern>,
4460 Sched<[WriteV]> {
4461 bits<5> Rd;
4462 bits<5> Rn;
4463 bits<5> Rm;
4464 let Inst{31} = 0;
4465 let Inst{30} = size{0};
4466 let Inst{29} = U;
4467 let Inst{28-24} = 0b01110;
4468 let Inst{23-22} = size{2-1};
4469 let Inst{21} = 1;
4470 let Inst{20-16} = Rm;
4471 let Inst{15-12} = opcode;
4472 let Inst{11-10} = 0b00;
4473 let Inst{9-5} = Rn;
4474 let Inst{4-0} = Rd;
4475}
4476
4477let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
4478class BaseSIMDDifferentThreeVectorTied<bit U, bits<3> size, bits<4> opcode,
4479 RegisterOperand outtype, RegisterOperand intype1,
4480 RegisterOperand intype2, string asm,
4481 string outkind, string inkind1, string inkind2,
4482 list<dag> pattern>
4483 : I<(outs outtype:$dst), (ins outtype:$Rd, intype1:$Rn, intype2:$Rm), asm,
4484 "{\t$Rd" # outkind # ", $Rn" # inkind1 # ", $Rm" # inkind2 #
4485 "|" # outkind # "\t$Rd, $Rn, $Rm}", "$Rd = $dst", pattern>,
4486 Sched<[WriteV]> {
4487 bits<5> Rd;
4488 bits<5> Rn;
4489 bits<5> Rm;
4490 let Inst{31} = 0;
4491 let Inst{30} = size{0};
4492 let Inst{29} = U;
4493 let Inst{28-24} = 0b01110;
4494 let Inst{23-22} = size{2-1};
4495 let Inst{21} = 1;
4496 let Inst{20-16} = Rm;
4497 let Inst{15-12} = opcode;
4498 let Inst{11-10} = 0b00;
4499 let Inst{9-5} = Rn;
4500 let Inst{4-0} = Rd;
4501}
4502
4503// FIXME: TableGen doesn't know how to deal with expanded types that also
4504// change the element count (in this case, placing the results in
4505// the high elements of the result register rather than the low
4506// elements). Until that's fixed, we can't code-gen those.
4507multiclass SIMDNarrowThreeVectorBHS<bit U, bits<4> opc, string asm,
4508 Intrinsic IntOp> {
4509 def v8i16_v8i8 : BaseSIMDDifferentThreeVector<U, 0b000, opc,
4510 V64, V128, V128,
4511 asm, ".8b", ".8h", ".8h",
4512 [(set (v8i8 V64:$Rd), (IntOp (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>;
4513 def v8i16_v16i8 : BaseSIMDDifferentThreeVectorTied<U, 0b001, opc,
4514 V128, V128, V128,
4515 asm#"2", ".16b", ".8h", ".8h",
4516 []>;
4517 def v4i32_v4i16 : BaseSIMDDifferentThreeVector<U, 0b010, opc,
4518 V64, V128, V128,
4519 asm, ".4h", ".4s", ".4s",
4520 [(set (v4i16 V64:$Rd), (IntOp (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>;
4521 def v4i32_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc,
4522 V128, V128, V128,
4523 asm#"2", ".8h", ".4s", ".4s",
4524 []>;
4525 def v2i64_v2i32 : BaseSIMDDifferentThreeVector<U, 0b100, opc,
4526 V64, V128, V128,
4527 asm, ".2s", ".2d", ".2d",
4528 [(set (v2i32 V64:$Rd), (IntOp (v2i64 V128:$Rn), (v2i64 V128:$Rm)))]>;
4529 def v2i64_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc,
4530 V128, V128, V128,
4531 asm#"2", ".4s", ".2d", ".2d",
4532 []>;
4533
4534
4535 // Patterns for the '2' variants involve INSERT_SUBREG, which you can't put in
4536 // a version attached to an instruction.
4537 def : Pat<(concat_vectors (v8i8 V64:$Rd), (IntOp (v8i16 V128:$Rn),
4538 (v8i16 V128:$Rm))),
4539 (!cast<Instruction>(NAME # "v8i16_v16i8")
4540 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub),
4541 V128:$Rn, V128:$Rm)>;
4542 def : Pat<(concat_vectors (v4i16 V64:$Rd), (IntOp (v4i32 V128:$Rn),
4543 (v4i32 V128:$Rm))),
4544 (!cast<Instruction>(NAME # "v4i32_v8i16")
4545 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub),
4546 V128:$Rn, V128:$Rm)>;
4547 def : Pat<(concat_vectors (v2i32 V64:$Rd), (IntOp (v2i64 V128:$Rn),
4548 (v2i64 V128:$Rm))),
4549 (!cast<Instruction>(NAME # "v2i64_v4i32")
4550 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub),
4551 V128:$Rn, V128:$Rm)>;
4552}
4553
4554multiclass SIMDDifferentThreeVectorBD<bit U, bits<4> opc, string asm,
4555 Intrinsic IntOp> {
4556 def v8i8 : BaseSIMDDifferentThreeVector<U, 0b000, opc,
4557 V128, V64, V64,
4558 asm, ".8h", ".8b", ".8b",
4559 [(set (v8i16 V128:$Rd), (IntOp (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
4560 def v16i8 : BaseSIMDDifferentThreeVector<U, 0b001, opc,
4561 V128, V128, V128,
4562 asm#"2", ".8h", ".16b", ".16b", []>;
4563 def v1i64 : BaseSIMDDifferentThreeVector<U, 0b110, opc,
4564 V128, V64, V64,
4565 asm, ".1q", ".1d", ".1d", []>;
4566 def v2i64 : BaseSIMDDifferentThreeVector<U, 0b111, opc,
4567 V128, V128, V128,
4568 asm#"2", ".1q", ".2d", ".2d", []>;
4569
4570 def : Pat<(v8i16 (IntOp (v8i8 (extract_high_v16i8 V128:$Rn)),
4571 (v8i8 (extract_high_v16i8 V128:$Rm)))),
4572 (!cast<Instruction>(NAME#"v16i8") V128:$Rn, V128:$Rm)>;
4573}
4574
4575multiclass SIMDLongThreeVectorHS<bit U, bits<4> opc, string asm,
4576 SDPatternOperator OpNode> {
4577 def v4i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b010, opc,
4578 V128, V64, V64,
4579 asm, ".4s", ".4h", ".4h",
4580 [(set (v4i32 V128:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>;
4581 def v8i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b011, opc,
4582 V128, V128, V128,
4583 asm#"2", ".4s", ".8h", ".8h",
4584 [(set (v4i32 V128:$Rd), (OpNode (extract_high_v8i16 V128:$Rn),
4585 (extract_high_v8i16 V128:$Rm)))]>;
4586 def v2i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b100, opc,
4587 V128, V64, V64,
4588 asm, ".2d", ".2s", ".2s",
4589 [(set (v2i64 V128:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>;
4590 def v4i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b101, opc,
4591 V128, V128, V128,
4592 asm#"2", ".2d", ".4s", ".4s",
4593 [(set (v2i64 V128:$Rd), (OpNode (extract_high_v4i32 V128:$Rn),
4594 (extract_high_v4i32 V128:$Rm)))]>;
4595}
4596
4597multiclass SIMDLongThreeVectorBHSabdl<bit U, bits<4> opc, string asm,
4598 SDPatternOperator OpNode = null_frag> {
4599 def v8i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b000, opc,
4600 V128, V64, V64,
4601 asm, ".8h", ".8b", ".8b",
4602 [(set (v8i16 V128:$Rd),
4603 (zext (v8i8 (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))))]>;
4604 def v16i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b001, opc,
4605 V128, V128, V128,
4606 asm#"2", ".8h", ".16b", ".16b",
4607 [(set (v8i16 V128:$Rd),
4608 (zext (v8i8 (OpNode (extract_high_v16i8 V128:$Rn),
4609 (extract_high_v16i8 V128:$Rm)))))]>;
4610 def v4i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b010, opc,
4611 V128, V64, V64,
4612 asm, ".4s", ".4h", ".4h",
4613 [(set (v4i32 V128:$Rd),
4614 (zext (v4i16 (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))))]>;
4615 def v8i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b011, opc,
4616 V128, V128, V128,
4617 asm#"2", ".4s", ".8h", ".8h",
4618 [(set (v4i32 V128:$Rd),
4619 (zext (v4i16 (OpNode (extract_high_v8i16 V128:$Rn),
4620 (extract_high_v8i16 V128:$Rm)))))]>;
4621 def v2i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b100, opc,
4622 V128, V64, V64,
4623 asm, ".2d", ".2s", ".2s",
4624 [(set (v2i64 V128:$Rd),
4625 (zext (v2i32 (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))))]>;
4626 def v4i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b101, opc,
4627 V128, V128, V128,
4628 asm#"2", ".2d", ".4s", ".4s",
4629 [(set (v2i64 V128:$Rd),
4630 (zext (v2i32 (OpNode (extract_high_v4i32 V128:$Rn),
4631 (extract_high_v4i32 V128:$Rm)))))]>;
4632}
4633
4634multiclass SIMDLongThreeVectorTiedBHSabal<bit U, bits<4> opc,
4635 string asm,
4636 SDPatternOperator OpNode> {
4637 def v8i8_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b000, opc,
4638 V128, V64, V64,
4639 asm, ".8h", ".8b", ".8b",
4640 [(set (v8i16 V128:$dst),
4641 (add (v8i16 V128:$Rd),
4642 (zext (v8i8 (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm))))))]>;
4643 def v16i8_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b001, opc,
4644 V128, V128, V128,
4645 asm#"2", ".8h", ".16b", ".16b",
4646 [(set (v8i16 V128:$dst),
4647 (add (v8i16 V128:$Rd),
4648 (zext (v8i8 (OpNode (extract_high_v16i8 V128:$Rn),
4649 (extract_high_v16i8 V128:$Rm))))))]>;
4650 def v4i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b010, opc,
4651 V128, V64, V64,
4652 asm, ".4s", ".4h", ".4h",
4653 [(set (v4i32 V128:$dst),
4654 (add (v4i32 V128:$Rd),
4655 (zext (v4i16 (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm))))))]>;
4656 def v8i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc,
4657 V128, V128, V128,
4658 asm#"2", ".4s", ".8h", ".8h",
4659 [(set (v4i32 V128:$dst),
4660 (add (v4i32 V128:$Rd),
4661 (zext (v4i16 (OpNode (extract_high_v8i16 V128:$Rn),
4662 (extract_high_v8i16 V128:$Rm))))))]>;
4663 def v2i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b100, opc,
4664 V128, V64, V64,
4665 asm, ".2d", ".2s", ".2s",
4666 [(set (v2i64 V128:$dst),
4667 (add (v2i64 V128:$Rd),
4668 (zext (v2i32 (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm))))))]>;
4669 def v4i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc,
4670 V128, V128, V128,
4671 asm#"2", ".2d", ".4s", ".4s",
4672 [(set (v2i64 V128:$dst),
4673 (add (v2i64 V128:$Rd),
4674 (zext (v2i32 (OpNode (extract_high_v4i32 V128:$Rn),
4675 (extract_high_v4i32 V128:$Rm))))))]>;
4676}
4677
4678multiclass SIMDLongThreeVectorBHS<bit U, bits<4> opc, string asm,
4679 SDPatternOperator OpNode = null_frag> {
4680 def v8i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b000, opc,
4681 V128, V64, V64,
4682 asm, ".8h", ".8b", ".8b",
4683 [(set (v8i16 V128:$Rd), (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
4684 def v16i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b001, opc,
4685 V128, V128, V128,
4686 asm#"2", ".8h", ".16b", ".16b",
4687 [(set (v8i16 V128:$Rd), (OpNode (extract_high_v16i8 V128:$Rn),
4688 (extract_high_v16i8 V128:$Rm)))]>;
4689 def v4i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b010, opc,
4690 V128, V64, V64,
4691 asm, ".4s", ".4h", ".4h",
4692 [(set (v4i32 V128:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>;
4693 def v8i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b011, opc,
4694 V128, V128, V128,
4695 asm#"2", ".4s", ".8h", ".8h",
4696 [(set (v4i32 V128:$Rd), (OpNode (extract_high_v8i16 V128:$Rn),
4697 (extract_high_v8i16 V128:$Rm)))]>;
4698 def v2i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b100, opc,
4699 V128, V64, V64,
4700 asm, ".2d", ".2s", ".2s",
4701 [(set (v2i64 V128:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>;
4702 def v4i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b101, opc,
4703 V128, V128, V128,
4704 asm#"2", ".2d", ".4s", ".4s",
4705 [(set (v2i64 V128:$Rd), (OpNode (extract_high_v4i32 V128:$Rn),
4706 (extract_high_v4i32 V128:$Rm)))]>;
4707}
4708
4709multiclass SIMDLongThreeVectorTiedBHS<bit U, bits<4> opc,
4710 string asm,
4711 SDPatternOperator OpNode> {
4712 def v8i8_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b000, opc,
4713 V128, V64, V64,
4714 asm, ".8h", ".8b", ".8b",
4715 [(set (v8i16 V128:$dst),
4716 (OpNode (v8i16 V128:$Rd), (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
4717 def v16i8_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b001, opc,
4718 V128, V128, V128,
4719 asm#"2", ".8h", ".16b", ".16b",
4720 [(set (v8i16 V128:$dst),
4721 (OpNode (v8i16 V128:$Rd),
4722 (extract_high_v16i8 V128:$Rn),
4723 (extract_high_v16i8 V128:$Rm)))]>;
4724 def v4i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b010, opc,
4725 V128, V64, V64,
4726 asm, ".4s", ".4h", ".4h",
4727 [(set (v4i32 V128:$dst),
4728 (OpNode (v4i32 V128:$Rd), (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>;
4729 def v8i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc,
4730 V128, V128, V128,
4731 asm#"2", ".4s", ".8h", ".8h",
4732 [(set (v4i32 V128:$dst),
4733 (OpNode (v4i32 V128:$Rd),
4734 (extract_high_v8i16 V128:$Rn),
4735 (extract_high_v8i16 V128:$Rm)))]>;
4736 def v2i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b100, opc,
4737 V128, V64, V64,
4738 asm, ".2d", ".2s", ".2s",
4739 [(set (v2i64 V128:$dst),
4740 (OpNode (v2i64 V128:$Rd), (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>;
4741 def v4i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc,
4742 V128, V128, V128,
4743 asm#"2", ".2d", ".4s", ".4s",
4744 [(set (v2i64 V128:$dst),
4745 (OpNode (v2i64 V128:$Rd),
4746 (extract_high_v4i32 V128:$Rn),
4747 (extract_high_v4i32 V128:$Rm)))]>;
4748}
4749
4750multiclass SIMDLongThreeVectorSQDMLXTiedHS<bit U, bits<4> opc, string asm,
4751 SDPatternOperator Accum> {
4752 def v4i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b010, opc,
4753 V128, V64, V64,
4754 asm, ".4s", ".4h", ".4h",
4755 [(set (v4i32 V128:$dst),
4756 (Accum (v4i32 V128:$Rd),
4757 (v4i32 (int_arm64_neon_sqdmull (v4i16 V64:$Rn),
4758 (v4i16 V64:$Rm)))))]>;
4759 def v8i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc,
4760 V128, V128, V128,
4761 asm#"2", ".4s", ".8h", ".8h",
4762 [(set (v4i32 V128:$dst),
4763 (Accum (v4i32 V128:$Rd),
4764 (v4i32 (int_arm64_neon_sqdmull (extract_high_v8i16 V128:$Rn),
4765 (extract_high_v8i16 V128:$Rm)))))]>;
4766 def v2i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b100, opc,
4767 V128, V64, V64,
4768 asm, ".2d", ".2s", ".2s",
4769 [(set (v2i64 V128:$dst),
4770 (Accum (v2i64 V128:$Rd),
4771 (v2i64 (int_arm64_neon_sqdmull (v2i32 V64:$Rn),
4772 (v2i32 V64:$Rm)))))]>;
4773 def v4i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc,
4774 V128, V128, V128,
4775 asm#"2", ".2d", ".4s", ".4s",
4776 [(set (v2i64 V128:$dst),
4777 (Accum (v2i64 V128:$Rd),
4778 (v2i64 (int_arm64_neon_sqdmull (extract_high_v4i32 V128:$Rn),
4779 (extract_high_v4i32 V128:$Rm)))))]>;
4780}
4781
4782multiclass SIMDWideThreeVectorBHS<bit U, bits<4> opc, string asm,
4783 SDPatternOperator OpNode> {
4784 def v8i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b000, opc,
4785 V128, V128, V64,
4786 asm, ".8h", ".8h", ".8b",
4787 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (v8i8 V64:$Rm)))]>;
4788 def v16i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b001, opc,
4789 V128, V128, V128,
4790 asm#"2", ".8h", ".8h", ".16b",
4791 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn),
4792 (extract_high_v16i8 V128:$Rm)))]>;
4793 def v4i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b010, opc,
4794 V128, V128, V64,
4795 asm, ".4s", ".4s", ".4h",
4796 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (v4i16 V64:$Rm)))]>;
4797 def v8i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b011, opc,
4798 V128, V128, V128,
4799 asm#"2", ".4s", ".4s", ".8h",
4800 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn),
4801 (extract_high_v8i16 V128:$Rm)))]>;
4802 def v2i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b100, opc,
4803 V128, V128, V64,
4804 asm, ".2d", ".2d", ".2s",
4805 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn), (v2i32 V64:$Rm)))]>;
4806 def v4i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b101, opc,
4807 V128, V128, V128,
4808 asm#"2", ".2d", ".2d", ".4s",
4809 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn),
4810 (extract_high_v4i32 V128:$Rm)))]>;
4811}
4812
4813//----------------------------------------------------------------------------
4814// AdvSIMD bitwise extract from vector
4815//----------------------------------------------------------------------------
4816
4817class BaseSIMDBitwiseExtract<bit size, RegisterOperand regtype, ValueType vty,
4818 string asm, string kind>
4819 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, i32imm:$imm), asm,
4820 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind # ", $imm" #
4821 "|" # kind # "\t$Rd, $Rn, $Rm, $imm}", "",
4822 [(set (vty regtype:$Rd),
4823 (ARM64ext regtype:$Rn, regtype:$Rm, (i32 imm:$imm)))]>,
4824 Sched<[WriteV]> {
4825 bits<5> Rd;
4826 bits<5> Rn;
4827 bits<5> Rm;
4828 bits<4> imm;
4829 let Inst{31} = 0;
4830 let Inst{30} = size;
4831 let Inst{29-21} = 0b101110000;
4832 let Inst{20-16} = Rm;
4833 let Inst{15} = 0;
4834 let Inst{14-11} = imm;
4835 let Inst{10} = 0;
4836 let Inst{9-5} = Rn;
4837 let Inst{4-0} = Rd;
4838}
4839
4840
4841multiclass SIMDBitwiseExtract<string asm> {
4842 def v8i8 : BaseSIMDBitwiseExtract<0, V64, v8i8, asm, ".8b">;
4843 def v16i8 : BaseSIMDBitwiseExtract<1, V128, v16i8, asm, ".16b">;
4844}
4845
4846//----------------------------------------------------------------------------
4847// AdvSIMD zip vector
4848//----------------------------------------------------------------------------
4849
4850class BaseSIMDZipVector<bits<3> size, bits<3> opc, RegisterOperand regtype,
4851 string asm, string kind, SDNode OpNode, ValueType valty>
4852 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), asm,
4853 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind #
4854 "|" # kind # "\t$Rd, $Rn, $Rm}", "",
4855 [(set (valty regtype:$Rd), (OpNode regtype:$Rn, regtype:$Rm))]>,
4856 Sched<[WriteV]> {
4857 bits<5> Rd;
4858 bits<5> Rn;
4859 bits<5> Rm;
4860 let Inst{31} = 0;
4861 let Inst{30} = size{0};
4862 let Inst{29-24} = 0b001110;
4863 let Inst{23-22} = size{2-1};
4864 let Inst{21} = 0;
4865 let Inst{20-16} = Rm;
4866 let Inst{15} = 0;
4867 let Inst{14-12} = opc;
4868 let Inst{11-10} = 0b10;
4869 let Inst{9-5} = Rn;
4870 let Inst{4-0} = Rd;
4871}
4872
4873multiclass SIMDZipVector<bits<3>opc, string asm,
4874 SDNode OpNode> {
4875 def v8i8 : BaseSIMDZipVector<0b000, opc, V64,
4876 asm, ".8b", OpNode, v8i8>;
4877 def v16i8 : BaseSIMDZipVector<0b001, opc, V128,
4878 asm, ".16b", OpNode, v16i8>;
4879 def v4i16 : BaseSIMDZipVector<0b010, opc, V64,
4880 asm, ".4h", OpNode, v4i16>;
4881 def v8i16 : BaseSIMDZipVector<0b011, opc, V128,
4882 asm, ".8h", OpNode, v8i16>;
4883 def v2i32 : BaseSIMDZipVector<0b100, opc, V64,
4884 asm, ".2s", OpNode, v2i32>;
4885 def v4i32 : BaseSIMDZipVector<0b101, opc, V128,
4886 asm, ".4s", OpNode, v4i32>;
4887 def v2i64 : BaseSIMDZipVector<0b111, opc, V128,
4888 asm, ".2d", OpNode, v2i64>;
4889
4890 def : Pat<(v2f32 (OpNode V64:$Rn, V64:$Rm)),
4891 (!cast<Instruction>(NAME#"v2i32") V64:$Rn, V64:$Rm)>;
4892 def : Pat<(v4f32 (OpNode V128:$Rn, V128:$Rm)),
4893 (!cast<Instruction>(NAME#"v4i32") V128:$Rn, V128:$Rm)>;
4894 def : Pat<(v2f64 (OpNode V128:$Rn, V128:$Rm)),
4895 (!cast<Instruction>(NAME#"v2i64") V128:$Rn, V128:$Rm)>;
4896}
4897
4898//----------------------------------------------------------------------------
4899// AdvSIMD three register scalar instructions
4900//----------------------------------------------------------------------------
4901
4902let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
4903class BaseSIMDThreeScalar<bit U, bits<2> size, bits<5> opcode,
4904 RegisterClass regtype, string asm,
4905 list<dag> pattern>
4906 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), asm,
4907 "\t$Rd, $Rn, $Rm", "", pattern>,
4908 Sched<[WriteV]> {
4909 bits<5> Rd;
4910 bits<5> Rn;
4911 bits<5> Rm;
4912 let Inst{31-30} = 0b01;
4913 let Inst{29} = U;
4914 let Inst{28-24} = 0b11110;
4915 let Inst{23-22} = size;
4916 let Inst{21} = 1;
4917 let Inst{20-16} = Rm;
4918 let Inst{15-11} = opcode;
4919 let Inst{10} = 1;
4920 let Inst{9-5} = Rn;
4921 let Inst{4-0} = Rd;
4922}
4923
4924multiclass SIMDThreeScalarD<bit U, bits<5> opc, string asm,
4925 SDPatternOperator OpNode> {
4926 def v1i64 : BaseSIMDThreeScalar<U, 0b11, opc, FPR64, asm,
4927 [(set (v1i64 FPR64:$Rd), (OpNode (v1i64 FPR64:$Rn), (v1i64 FPR64:$Rm)))]>;
4928}
4929
4930multiclass SIMDThreeScalarBHSD<bit U, bits<5> opc, string asm,
4931 SDPatternOperator OpNode> {
4932 def v1i64 : BaseSIMDThreeScalar<U, 0b11, opc, FPR64, asm,
4933 [(set (v1i64 FPR64:$Rd), (OpNode (v1i64 FPR64:$Rn), (v1i64 FPR64:$Rm)))]>;
4934 def v1i32 : BaseSIMDThreeScalar<U, 0b10, opc, FPR32, asm, []>;
4935 def v1i16 : BaseSIMDThreeScalar<U, 0b01, opc, FPR16, asm, []>;
4936 def v1i8 : BaseSIMDThreeScalar<U, 0b00, opc, FPR8 , asm, []>;
4937
4938 def : Pat<(i64 (OpNode (i64 FPR64:$Rn), (i64 FPR64:$Rm))),
4939 (!cast<Instruction>(NAME#"v1i64") FPR64:$Rn, FPR64:$Rm)>;
4940 def : Pat<(i32 (OpNode (i32 FPR32:$Rn), (i32 FPR32:$Rm))),
4941 (!cast<Instruction>(NAME#"v1i32") FPR32:$Rn, FPR32:$Rm)>;
4942}
4943
4944multiclass SIMDThreeScalarHS<bit U, bits<5> opc, string asm,
4945 SDPatternOperator OpNode> {
4946 def v1i32 : BaseSIMDThreeScalar<U, 0b10, opc, FPR32, asm,
4947 [(set FPR32:$Rd, (OpNode FPR32:$Rn, FPR32:$Rm))]>;
4948 def v1i16 : BaseSIMDThreeScalar<U, 0b01, opc, FPR16, asm, []>;
4949}
4950
4951multiclass SIMDThreeScalarSD<bit U, bit S, bits<5> opc, string asm,
4952 SDPatternOperator OpNode = null_frag> {
4953 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
4954 def #NAME#64 : BaseSIMDThreeScalar<U, {S,1}, opc, FPR64, asm,
4955 [(set (f64 FPR64:$Rd), (OpNode (f64 FPR64:$Rn), (f64 FPR64:$Rm)))]>;
4956 def #NAME#32 : BaseSIMDThreeScalar<U, {S,0}, opc, FPR32, asm,
4957 [(set FPR32:$Rd, (OpNode FPR32:$Rn, FPR32:$Rm))]>;
4958 }
4959
4960 def : Pat<(v1f64 (OpNode (v1f64 FPR64:$Rn), (v1f64 FPR64:$Rm))),
4961 (!cast<Instruction>(NAME # "64") FPR64:$Rn, FPR64:$Rm)>;
4962}
4963
4964multiclass SIMDThreeScalarFPCmp<bit U, bit S, bits<5> opc, string asm,
4965 SDPatternOperator OpNode = null_frag> {
4966 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
4967 def #NAME#64 : BaseSIMDThreeScalar<U, {S,1}, opc, FPR64, asm,
4968 [(set (i64 FPR64:$Rd), (OpNode (f64 FPR64:$Rn), (f64 FPR64:$Rm)))]>;
4969 def #NAME#32 : BaseSIMDThreeScalar<U, {S,0}, opc, FPR32, asm,
4970 [(set (i32 FPR32:$Rd), (OpNode (f32 FPR32:$Rn), (f32 FPR32:$Rm)))]>;
4971 }
4972
4973 def : Pat<(v1i64 (OpNode (v1f64 FPR64:$Rn), (v1f64 FPR64:$Rm))),
4974 (!cast<Instruction>(NAME # "64") FPR64:$Rn, FPR64:$Rm)>;
4975}
4976
4977class BaseSIMDThreeScalarMixed<bit U, bits<2> size, bits<5> opcode,
4978 dag oops, dag iops, string asm, string cstr, list<dag> pat>
4979 : I<oops, iops, asm,
4980 "\t$Rd, $Rn, $Rm", cstr, pat>,
4981 Sched<[WriteV]> {
4982 bits<5> Rd;
4983 bits<5> Rn;
4984 bits<5> Rm;
4985 let Inst{31-30} = 0b01;
4986 let Inst{29} = U;
4987 let Inst{28-24} = 0b11110;
4988 let Inst{23-22} = size;
4989 let Inst{21} = 1;
4990 let Inst{20-16} = Rm;
4991 let Inst{15-11} = opcode;
4992 let Inst{10} = 0;
4993 let Inst{9-5} = Rn;
4994 let Inst{4-0} = Rd;
4995}
4996
4997let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
4998multiclass SIMDThreeScalarMixedHS<bit U, bits<5> opc, string asm,
4999 SDPatternOperator OpNode = null_frag> {
5000 def i16 : BaseSIMDThreeScalarMixed<U, 0b01, opc,
5001 (outs FPR32:$Rd),
5002 (ins FPR16:$Rn, FPR16:$Rm), asm, "", []>;
5003 def i32 : BaseSIMDThreeScalarMixed<U, 0b10, opc,
5004 (outs FPR64:$Rd),
5005 (ins FPR32:$Rn, FPR32:$Rm), asm, "",
5006 [(set (i64 FPR64:$Rd), (OpNode (i32 FPR32:$Rn), (i32 FPR32:$Rm)))]>;
5007}
5008
5009let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5010multiclass SIMDThreeScalarMixedTiedHS<bit U, bits<5> opc, string asm,
5011 SDPatternOperator OpNode = null_frag> {
5012 def i16 : BaseSIMDThreeScalarMixed<U, 0b01, opc,
5013 (outs FPR32:$dst),
5014 (ins FPR32:$Rd, FPR16:$Rn, FPR16:$Rm),
5015 asm, "$Rd = $dst", []>;
5016 def i32 : BaseSIMDThreeScalarMixed<U, 0b10, opc,
5017 (outs FPR64:$dst),
5018 (ins FPR64:$Rd, FPR32:$Rn, FPR32:$Rm),
5019 asm, "$Rd = $dst",
5020 [(set (i64 FPR64:$dst),
5021 (OpNode (i64 FPR64:$Rd), (i32 FPR32:$Rn), (i32 FPR32:$Rm)))]>;
5022}
5023
5024//----------------------------------------------------------------------------
5025// AdvSIMD two register scalar instructions
5026//----------------------------------------------------------------------------
5027
5028let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5029class BaseSIMDTwoScalar<bit U, bits<2> size, bits<5> opcode,
5030 RegisterClass regtype, RegisterClass regtype2,
5031 string asm, list<dag> pat>
5032 : I<(outs regtype:$Rd), (ins regtype2:$Rn), asm,
5033 "\t$Rd, $Rn", "", pat>,
5034 Sched<[WriteV]> {
5035 bits<5> Rd;
5036 bits<5> Rn;
5037 let Inst{31-30} = 0b01;
5038 let Inst{29} = U;
5039 let Inst{28-24} = 0b11110;
5040 let Inst{23-22} = size;
5041 let Inst{21-17} = 0b10000;
5042 let Inst{16-12} = opcode;
5043 let Inst{11-10} = 0b10;
5044 let Inst{9-5} = Rn;
5045 let Inst{4-0} = Rd;
5046}
5047
5048let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5049class BaseSIMDTwoScalarTied<bit U, bits<2> size, bits<5> opcode,
5050 RegisterClass regtype, RegisterClass regtype2,
5051 string asm, list<dag> pat>
5052 : I<(outs regtype:$dst), (ins regtype:$Rd, regtype2:$Rn), asm,
5053 "\t$Rd, $Rn", "$Rd = $dst", pat>,
5054 Sched<[WriteV]> {
5055 bits<5> Rd;
5056 bits<5> Rn;
5057 let Inst{31-30} = 0b01;
5058 let Inst{29} = U;
5059 let Inst{28-24} = 0b11110;
5060 let Inst{23-22} = size;
5061 let Inst{21-17} = 0b10000;
5062 let Inst{16-12} = opcode;
5063 let Inst{11-10} = 0b10;
5064 let Inst{9-5} = Rn;
5065 let Inst{4-0} = Rd;
5066}
5067
5068
5069let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5070class BaseSIMDCmpTwoScalar<bit U, bits<2> size, bits<5> opcode,
5071 RegisterClass regtype, string asm>
5072 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm,
5073 "\t$Rd, $Rn, #0", "", []>,
5074 Sched<[WriteV]> {
5075 bits<5> Rd;
5076 bits<5> Rn;
5077 let Inst{31-30} = 0b01;
5078 let Inst{29} = U;
5079 let Inst{28-24} = 0b11110;
5080 let Inst{23-22} = size;
5081 let Inst{21-17} = 0b10000;
5082 let Inst{16-12} = opcode;
5083 let Inst{11-10} = 0b10;
5084 let Inst{9-5} = Rn;
5085 let Inst{4-0} = Rd;
5086}
5087
5088class SIMDInexactCvtTwoScalar<bits<5> opcode, string asm>
5089 : I<(outs FPR32:$Rd), (ins FPR64:$Rn), asm, "\t$Rd, $Rn", "",
5090 [(set (f32 FPR32:$Rd), (int_arm64_sisd_fcvtxn (f64 FPR64:$Rn)))]>,
5091 Sched<[WriteV]> {
5092 bits<5> Rd;
5093 bits<5> Rn;
5094 let Inst{31-17} = 0b011111100110000;
5095 let Inst{16-12} = opcode;
5096 let Inst{11-10} = 0b10;
5097 let Inst{9-5} = Rn;
5098 let Inst{4-0} = Rd;
5099}
5100
5101multiclass SIMDCmpTwoScalarD<bit U, bits<5> opc, string asm,
5102 SDPatternOperator OpNode> {
5103 def v1i64rz : BaseSIMDCmpTwoScalar<U, 0b11, opc, FPR64, asm>;
5104
5105 def : Pat<(v1i64 (OpNode FPR64:$Rn)),
5106 (!cast<Instruction>(NAME # v1i64rz) FPR64:$Rn)>;
5107}
5108
5109multiclass SIMDCmpTwoScalarSD<bit U, bit S, bits<5> opc, string asm,
5110 SDPatternOperator OpNode> {
5111 def v1i64rz : BaseSIMDCmpTwoScalar<U, {S,1}, opc, FPR64, asm>;
5112 def v1i32rz : BaseSIMDCmpTwoScalar<U, {S,0}, opc, FPR32, asm>;
5113
5114 def : Pat<(v1i64 (OpNode (v1f64 FPR64:$Rn))),
5115 (!cast<Instruction>(NAME # v1i64rz) FPR64:$Rn)>;
5116}
5117
5118multiclass SIMDTwoScalarD<bit U, bits<5> opc, string asm,
5119 SDPatternOperator OpNode = null_frag> {
5120 def v1i64 : BaseSIMDTwoScalar<U, 0b11, opc, FPR64, FPR64, asm,
5121 [(set (v1i64 FPR64:$Rd), (OpNode (v1i64 FPR64:$Rn)))]>;
Tim Northoverf4810362014-03-31 15:46:17 +00005122
5123 def : Pat<(i64 (OpNode (i64 FPR64:$Rn))),
5124 (!cast<Instruction>(NAME # "v1i64") FPR64:$Rn)>;
Tim Northover00ed9962014-03-29 10:18:08 +00005125}
5126
5127multiclass SIMDTwoScalarSD<bit U, bit S, bits<5> opc, string asm> {
5128 def v1i64 : BaseSIMDTwoScalar<U, {S,1}, opc, FPR64, FPR64, asm,[]>;
5129 def v1i32 : BaseSIMDTwoScalar<U, {S,0}, opc, FPR32, FPR32, asm,[]>;
5130}
5131
5132multiclass SIMDTwoScalarCVTSD<bit U, bit S, bits<5> opc, string asm,
5133 SDPatternOperator OpNode> {
5134 def v1i64 : BaseSIMDTwoScalar<U, {S,1}, opc, FPR64, FPR64, asm,
5135 [(set FPR64:$Rd, (OpNode (f64 FPR64:$Rn)))]>;
5136 def v1i32 : BaseSIMDTwoScalar<U, {S,0}, opc, FPR32, FPR32, asm,
5137 [(set FPR32:$Rd, (OpNode (f32 FPR32:$Rn)))]>;
5138}
5139
5140multiclass SIMDTwoScalarBHSD<bit U, bits<5> opc, string asm,
5141 SDPatternOperator OpNode = null_frag> {
5142 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
5143 def v1i64 : BaseSIMDTwoScalar<U, 0b11, opc, FPR64, FPR64, asm,
5144 [(set (i64 FPR64:$Rd), (OpNode (i64 FPR64:$Rn)))]>;
5145 def v1i32 : BaseSIMDTwoScalar<U, 0b10, opc, FPR32, FPR32, asm,
5146 [(set (i32 FPR32:$Rd), (OpNode (i32 FPR32:$Rn)))]>;
5147 def v1i16 : BaseSIMDTwoScalar<U, 0b01, opc, FPR16, FPR16, asm, []>;
5148 def v1i8 : BaseSIMDTwoScalar<U, 0b00, opc, FPR8 , FPR8 , asm, []>;
5149 }
5150
5151 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rn))),
5152 (!cast<Instruction>(NAME # v1i64) FPR64:$Rn)>;
5153}
5154
Tim Northover00ed9962014-03-29 10:18:08 +00005155multiclass SIMDTwoScalarBHSDTied<bit U, bits<5> opc, string asm,
5156 Intrinsic OpNode> {
Tim Northover903814c2014-03-31 15:46:26 +00005157 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
5158 def v1i64 : BaseSIMDTwoScalarTied<U, 0b11, opc, FPR64, FPR64, asm,
5159 [(set (i64 FPR64:$dst), (OpNode (i64 FPR64:$Rd), (i64 FPR64:$Rn)))]>;
5160 def v1i32 : BaseSIMDTwoScalarTied<U, 0b10, opc, FPR32, FPR32, asm,
5161 [(set (i32 FPR32:$dst), (OpNode (i32 FPR32:$Rd), (i32 FPR32:$Rn)))]>;
5162 def v1i16 : BaseSIMDTwoScalarTied<U, 0b01, opc, FPR16, FPR16, asm, []>;
5163 def v1i8 : BaseSIMDTwoScalarTied<U, 0b00, opc, FPR8 , FPR8 , asm, []>;
5164 }
5165
5166 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rd), (v1i64 FPR64:$Rn))),
5167 (!cast<Instruction>(NAME # v1i64) FPR64:$Rd, FPR64:$Rn)>;
Tim Northover00ed9962014-03-29 10:18:08 +00005168}
5169
5170
5171
5172let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5173multiclass SIMDTwoScalarMixedBHS<bit U, bits<5> opc, string asm,
5174 SDPatternOperator OpNode = null_frag> {
5175 def v1i32 : BaseSIMDTwoScalar<U, 0b10, opc, FPR32, FPR64, asm,
5176 [(set (i32 FPR32:$Rd), (OpNode (i64 FPR64:$Rn)))]>;
5177 def v1i16 : BaseSIMDTwoScalar<U, 0b01, opc, FPR16, FPR32, asm, []>;
5178 def v1i8 : BaseSIMDTwoScalar<U, 0b00, opc, FPR8 , FPR16, asm, []>;
5179}
5180
5181//----------------------------------------------------------------------------
5182// AdvSIMD scalar pairwise instructions
5183//----------------------------------------------------------------------------
5184
5185let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5186class BaseSIMDPairwiseScalar<bit U, bits<2> size, bits<5> opcode,
5187 RegisterOperand regtype, RegisterOperand vectype,
5188 string asm, string kind>
5189 : I<(outs regtype:$Rd), (ins vectype:$Rn), asm,
5190 "{\t$Rd, $Rn" # kind # "|" # kind # "\t$Rd, $Rn}", "", []>,
5191 Sched<[WriteV]> {
5192 bits<5> Rd;
5193 bits<5> Rn;
5194 let Inst{31-30} = 0b01;
5195 let Inst{29} = U;
5196 let Inst{28-24} = 0b11110;
5197 let Inst{23-22} = size;
5198 let Inst{21-17} = 0b11000;
5199 let Inst{16-12} = opcode;
5200 let Inst{11-10} = 0b10;
5201 let Inst{9-5} = Rn;
5202 let Inst{4-0} = Rd;
5203}
5204
5205multiclass SIMDPairwiseScalarD<bit U, bits<5> opc, string asm> {
5206 def v2i64p : BaseSIMDPairwiseScalar<U, 0b11, opc, FPR64Op, V128,
5207 asm, ".2d">;
5208}
5209
5210multiclass SIMDPairwiseScalarSD<bit U, bit S, bits<5> opc, string asm> {
5211 def v2i32p : BaseSIMDPairwiseScalar<U, {S,0}, opc, FPR32Op, V64,
5212 asm, ".2s">;
5213 def v2i64p : BaseSIMDPairwiseScalar<U, {S,1}, opc, FPR64Op, V128,
5214 asm, ".2d">;
5215}
5216
5217//----------------------------------------------------------------------------
5218// AdvSIMD across lanes instructions
5219//----------------------------------------------------------------------------
5220
5221let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5222class BaseSIMDAcrossLanes<bit Q, bit U, bits<2> size, bits<5> opcode,
5223 RegisterClass regtype, RegisterOperand vectype,
5224 string asm, string kind, list<dag> pattern>
5225 : I<(outs regtype:$Rd), (ins vectype:$Rn), asm,
5226 "{\t$Rd, $Rn" # kind # "|" # kind # "\t$Rd, $Rn}", "", pattern>,
5227 Sched<[WriteV]> {
5228 bits<5> Rd;
5229 bits<5> Rn;
5230 let Inst{31} = 0;
5231 let Inst{30} = Q;
5232 let Inst{29} = U;
5233 let Inst{28-24} = 0b01110;
5234 let Inst{23-22} = size;
5235 let Inst{21-17} = 0b11000;
5236 let Inst{16-12} = opcode;
5237 let Inst{11-10} = 0b10;
5238 let Inst{9-5} = Rn;
5239 let Inst{4-0} = Rd;
5240}
5241
5242multiclass SIMDAcrossLanesBHS<bit U, bits<5> opcode,
5243 string asm> {
5244 def v8i8v : BaseSIMDAcrossLanes<0, U, 0b00, opcode, FPR8, V64,
5245 asm, ".8b", []>;
5246 def v16i8v : BaseSIMDAcrossLanes<1, U, 0b00, opcode, FPR8, V128,
5247 asm, ".16b", []>;
5248 def v4i16v : BaseSIMDAcrossLanes<0, U, 0b01, opcode, FPR16, V64,
5249 asm, ".4h", []>;
5250 def v8i16v : BaseSIMDAcrossLanes<1, U, 0b01, opcode, FPR16, V128,
5251 asm, ".8h", []>;
5252 def v4i32v : BaseSIMDAcrossLanes<1, U, 0b10, opcode, FPR32, V128,
5253 asm, ".4s", []>;
5254}
5255
5256multiclass SIMDAcrossLanesHSD<bit U, bits<5> opcode, string asm> {
5257 def v8i8v : BaseSIMDAcrossLanes<0, U, 0b00, opcode, FPR16, V64,
5258 asm, ".8b", []>;
5259 def v16i8v : BaseSIMDAcrossLanes<1, U, 0b00, opcode, FPR16, V128,
5260 asm, ".16b", []>;
5261 def v4i16v : BaseSIMDAcrossLanes<0, U, 0b01, opcode, FPR32, V64,
5262 asm, ".4h", []>;
5263 def v8i16v : BaseSIMDAcrossLanes<1, U, 0b01, opcode, FPR32, V128,
5264 asm, ".8h", []>;
5265 def v4i32v : BaseSIMDAcrossLanes<1, U, 0b10, opcode, FPR64, V128,
5266 asm, ".4s", []>;
5267}
5268
5269multiclass SIMDAcrossLanesS<bits<5> opcode, bit sz1, string asm,
5270 Intrinsic intOp> {
5271 def v4i32v : BaseSIMDAcrossLanes<1, 1, {sz1, 0}, opcode, FPR32, V128,
5272 asm, ".4s",
5273 [(set FPR32:$Rd, (intOp (v4f32 V128:$Rn)))]>;
5274}
5275
5276//----------------------------------------------------------------------------
5277// AdvSIMD INS/DUP instructions
5278//----------------------------------------------------------------------------
5279
5280// FIXME: There has got to be a better way to factor these. ugh.
5281
5282class BaseSIMDInsDup<bit Q, bit op, dag outs, dag ins, string asm,
5283 string operands, string constraints, list<dag> pattern>
5284 : I<outs, ins, asm, operands, constraints, pattern>,
5285 Sched<[WriteV]> {
5286 bits<5> Rd;
5287 bits<5> Rn;
5288 let Inst{31} = 0;
5289 let Inst{30} = Q;
5290 let Inst{29} = op;
5291 let Inst{28-21} = 0b01110000;
5292 let Inst{15} = 0;
5293 let Inst{10} = 1;
5294 let Inst{9-5} = Rn;
5295 let Inst{4-0} = Rd;
5296}
5297
5298class SIMDDupFromMain<bit Q, bits<5> imm5, string size, ValueType vectype,
5299 RegisterOperand vecreg, RegisterClass regtype>
5300 : BaseSIMDInsDup<Q, 0, (outs vecreg:$Rd), (ins regtype:$Rn), "dup",
5301 "{\t$Rd" # size # ", $Rn" #
5302 "|" # size # "\t$Rd, $Rn}", "",
5303 [(set (vectype vecreg:$Rd), (ARM64dup regtype:$Rn))]> {
5304 let Inst{20-16} = imm5;
5305 let Inst{14-11} = 0b0001;
5306}
5307
5308class SIMDDupFromElement<bit Q, string dstkind, string srckind,
5309 ValueType vectype, ValueType insreg,
5310 RegisterOperand vecreg, Operand idxtype,
5311 ValueType elttype, SDNode OpNode>
5312 : BaseSIMDInsDup<Q, 0, (outs vecreg:$Rd), (ins V128:$Rn, idxtype:$idx), "dup",
5313 "{\t$Rd" # dstkind # ", $Rn" # srckind # "$idx" #
5314 "|" # dstkind # "\t$Rd, $Rn$idx}", "",
5315 [(set (vectype vecreg:$Rd),
5316 (OpNode (insreg V128:$Rn), idxtype:$idx))]> {
5317 let Inst{14-11} = 0b0000;
5318}
5319
5320class SIMDDup64FromElement
5321 : SIMDDupFromElement<1, ".2d", ".d", v2i64, v2i64, V128,
5322 VectorIndexD, i64, ARM64duplane64> {
5323 bits<1> idx;
5324 let Inst{20} = idx;
5325 let Inst{19-16} = 0b1000;
5326}
5327
5328class SIMDDup32FromElement<bit Q, string size, ValueType vectype,
5329 RegisterOperand vecreg>
5330 : SIMDDupFromElement<Q, size, ".s", vectype, v4i32, vecreg,
5331 VectorIndexS, i64, ARM64duplane32> {
5332 bits<2> idx;
5333 let Inst{20-19} = idx;
5334 let Inst{18-16} = 0b100;
5335}
5336
5337class SIMDDup16FromElement<bit Q, string size, ValueType vectype,
5338 RegisterOperand vecreg>
5339 : SIMDDupFromElement<Q, size, ".h", vectype, v8i16, vecreg,
5340 VectorIndexH, i64, ARM64duplane16> {
5341 bits<3> idx;
5342 let Inst{20-18} = idx;
5343 let Inst{17-16} = 0b10;
5344}
5345
5346class SIMDDup8FromElement<bit Q, string size, ValueType vectype,
5347 RegisterOperand vecreg>
5348 : SIMDDupFromElement<Q, size, ".b", vectype, v16i8, vecreg,
5349 VectorIndexB, i64, ARM64duplane8> {
5350 bits<4> idx;
5351 let Inst{20-17} = idx;
5352 let Inst{16} = 1;
5353}
5354
5355class BaseSIMDMov<bit Q, string size, bits<4> imm4, RegisterClass regtype,
5356 Operand idxtype, string asm, list<dag> pattern>
5357 : BaseSIMDInsDup<Q, 0, (outs regtype:$Rd), (ins V128:$Rn, idxtype:$idx), asm,
5358 "{\t$Rd, $Rn" # size # "$idx" #
5359 "|" # size # "\t$Rd, $Rn$idx}", "", pattern> {
5360 let Inst{14-11} = imm4;
5361}
5362
5363class SIMDSMov<bit Q, string size, RegisterClass regtype,
5364 Operand idxtype>
5365 : BaseSIMDMov<Q, size, 0b0101, regtype, idxtype, "smov", []>;
5366class SIMDUMov<bit Q, string size, ValueType vectype, RegisterClass regtype,
5367 Operand idxtype>
5368 : BaseSIMDMov<Q, size, 0b0111, regtype, idxtype, "umov",
5369 [(set regtype:$Rd, (vector_extract (vectype V128:$Rn), idxtype:$idx))]>;
5370
5371class SIMDMovAlias<string asm, string size, Instruction inst,
5372 RegisterClass regtype, Operand idxtype>
5373 : InstAlias<asm#"{\t$dst, $src"#size#"$idx" #
5374 "|" # size # "\t$dst, $src$idx}",
5375 (inst regtype:$dst, V128:$src, idxtype:$idx)>;
5376
5377multiclass SMov {
5378 def vi8to32 : SIMDSMov<0, ".b", GPR32, VectorIndexB> {
5379 bits<4> idx;
5380 let Inst{20-17} = idx;
5381 let Inst{16} = 1;
5382 }
5383 def vi8to64 : SIMDSMov<1, ".b", GPR64, VectorIndexB> {
5384 bits<4> idx;
5385 let Inst{20-17} = idx;
5386 let Inst{16} = 1;
5387 }
5388 def vi16to32 : SIMDSMov<0, ".h", GPR32, VectorIndexH> {
5389 bits<3> idx;
5390 let Inst{20-18} = idx;
5391 let Inst{17-16} = 0b10;
5392 }
5393 def vi16to64 : SIMDSMov<1, ".h", GPR64, VectorIndexH> {
5394 bits<3> idx;
5395 let Inst{20-18} = idx;
5396 let Inst{17-16} = 0b10;
5397 }
5398 def vi32to64 : SIMDSMov<1, ".s", GPR64, VectorIndexS> {
5399 bits<2> idx;
5400 let Inst{20-19} = idx;
5401 let Inst{18-16} = 0b100;
5402 }
5403}
5404
5405multiclass UMov {
5406 def vi8 : SIMDUMov<0, ".b", v16i8, GPR32, VectorIndexB> {
5407 bits<4> idx;
5408 let Inst{20-17} = idx;
5409 let Inst{16} = 1;
5410 }
5411 def vi16 : SIMDUMov<0, ".h", v8i16, GPR32, VectorIndexH> {
5412 bits<3> idx;
5413 let Inst{20-18} = idx;
5414 let Inst{17-16} = 0b10;
5415 }
5416 def vi32 : SIMDUMov<0, ".s", v4i32, GPR32, VectorIndexS> {
5417 bits<2> idx;
5418 let Inst{20-19} = idx;
5419 let Inst{18-16} = 0b100;
5420 }
5421 def vi64 : SIMDUMov<1, ".d", v2i64, GPR64, VectorIndexD> {
5422 bits<1> idx;
5423 let Inst{20} = idx;
5424 let Inst{19-16} = 0b1000;
5425 }
5426 def : SIMDMovAlias<"mov", ".s",
5427 !cast<Instruction>(NAME#"vi32"),
5428 GPR32, VectorIndexS>;
5429 def : SIMDMovAlias<"mov", ".d",
5430 !cast<Instruction>(NAME#"vi64"),
5431 GPR64, VectorIndexD>;
5432}
5433
5434class SIMDInsFromMain<string size, ValueType vectype,
5435 RegisterClass regtype, Operand idxtype>
5436 : BaseSIMDInsDup<1, 0, (outs V128:$dst),
5437 (ins V128:$Rd, idxtype:$idx, regtype:$Rn), "ins",
5438 "{\t$Rd" # size # "$idx, $Rn" #
5439 "|" # size # "\t$Rd$idx, $Rn}",
5440 "$Rd = $dst",
5441 [(set V128:$dst,
5442 (vector_insert (vectype V128:$Rd), regtype:$Rn, idxtype:$idx))]> {
5443 let Inst{14-11} = 0b0011;
5444}
5445
5446class SIMDInsFromElement<string size, ValueType vectype,
5447 ValueType elttype, Operand idxtype>
5448 : BaseSIMDInsDup<1, 1, (outs V128:$dst),
5449 (ins V128:$Rd, idxtype:$idx, V128:$Rn, idxtype:$idx2), "ins",
5450 "{\t$Rd" # size # "$idx, $Rn" # size # "$idx2" #
5451 "|" # size # "\t$Rd$idx, $Rn$idx2}",
5452 "$Rd = $dst",
5453 [(set V128:$dst,
5454 (vector_insert
5455 (vectype V128:$Rd),
5456 (elttype (vector_extract (vectype V128:$Rn), idxtype:$idx2)),
5457 idxtype:$idx))]>;
5458
5459class SIMDInsMainMovAlias<string size, Instruction inst,
5460 RegisterClass regtype, Operand idxtype>
5461 : InstAlias<"mov" # "{\t$dst" # size # "$idx, $src" #
5462 "|" # size #"\t$dst$idx, $src}",
5463 (inst V128:$dst, idxtype:$idx, regtype:$src)>;
5464class SIMDInsElementMovAlias<string size, Instruction inst,
5465 Operand idxtype>
5466 : InstAlias<"mov" # "{\t$dst" # size # "$idx, $src" # size # "$idx2" #
5467 # "|" # size #" $dst$idx, $src$idx2}",
5468 (inst V128:$dst, idxtype:$idx, V128:$src, idxtype:$idx2)>;
5469
5470
5471multiclass SIMDIns {
5472 def vi8gpr : SIMDInsFromMain<".b", v16i8, GPR32, VectorIndexB> {
5473 bits<4> idx;
5474 let Inst{20-17} = idx;
5475 let Inst{16} = 1;
5476 }
5477 def vi16gpr : SIMDInsFromMain<".h", v8i16, GPR32, VectorIndexH> {
5478 bits<3> idx;
5479 let Inst{20-18} = idx;
5480 let Inst{17-16} = 0b10;
5481 }
5482 def vi32gpr : SIMDInsFromMain<".s", v4i32, GPR32, VectorIndexS> {
5483 bits<2> idx;
5484 let Inst{20-19} = idx;
5485 let Inst{18-16} = 0b100;
5486 }
5487 def vi64gpr : SIMDInsFromMain<".d", v2i64, GPR64, VectorIndexD> {
5488 bits<1> idx;
5489 let Inst{20} = idx;
5490 let Inst{19-16} = 0b1000;
5491 }
5492
5493 def vi8lane : SIMDInsFromElement<".b", v16i8, i32, VectorIndexB> {
5494 bits<4> idx;
5495 bits<4> idx2;
5496 let Inst{20-17} = idx;
5497 let Inst{16} = 1;
5498 let Inst{14-11} = idx2;
5499 }
5500 def vi16lane : SIMDInsFromElement<".h", v8i16, i32, VectorIndexH> {
5501 bits<3> idx;
5502 bits<3> idx2;
5503 let Inst{20-18} = idx;
5504 let Inst{17-16} = 0b10;
5505 let Inst{14-12} = idx2;
5506 let Inst{11} = 0;
5507 }
5508 def vi32lane : SIMDInsFromElement<".s", v4i32, i32, VectorIndexS> {
5509 bits<2> idx;
5510 bits<2> idx2;
5511 let Inst{20-19} = idx;
5512 let Inst{18-16} = 0b100;
5513 let Inst{14-13} = idx2;
5514 let Inst{12-11} = 0;
5515 }
5516 def vi64lane : SIMDInsFromElement<".d", v2i64, i64, VectorIndexD> {
5517 bits<1> idx;
5518 bits<1> idx2;
5519 let Inst{20} = idx;
5520 let Inst{19-16} = 0b1000;
5521 let Inst{14} = idx2;
5522 let Inst{13-11} = 0;
5523 }
5524
5525 // For all forms of the INS instruction, the "mov" mnemonic is the
5526 // preferred alias. Why they didn't just call the instruction "mov" in
5527 // the first place is a very good question indeed...
5528 def : SIMDInsMainMovAlias<".b", !cast<Instruction>(NAME#"vi8gpr"),
5529 GPR32, VectorIndexB>;
5530 def : SIMDInsMainMovAlias<".h", !cast<Instruction>(NAME#"vi16gpr"),
5531 GPR32, VectorIndexH>;
5532 def : SIMDInsMainMovAlias<".s", !cast<Instruction>(NAME#"vi32gpr"),
5533 GPR32, VectorIndexS>;
5534 def : SIMDInsMainMovAlias<".d", !cast<Instruction>(NAME#"vi64gpr"),
5535 GPR64, VectorIndexD>;
5536
5537 def : SIMDInsElementMovAlias<".b", !cast<Instruction>(NAME#"vi8lane"),
5538 VectorIndexB>;
5539 def : SIMDInsElementMovAlias<".h", !cast<Instruction>(NAME#"vi16lane"),
5540 VectorIndexH>;
5541 def : SIMDInsElementMovAlias<".s", !cast<Instruction>(NAME#"vi32lane"),
5542 VectorIndexS>;
5543 def : SIMDInsElementMovAlias<".d", !cast<Instruction>(NAME#"vi64lane"),
5544 VectorIndexD>;
5545}
5546
5547//----------------------------------------------------------------------------
5548// AdvSIMD TBL/TBX
5549//----------------------------------------------------------------------------
5550
5551let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
5552class BaseSIMDTableLookup<bit Q, bits<2> len, bit op, RegisterOperand vectype,
5553 RegisterOperand listtype, string asm, string kind>
5554 : I<(outs vectype:$Vd), (ins listtype:$Vn, vectype:$Vm), asm,
5555 "\t$Vd" # kind # ", $Vn, $Vm" # kind, "", []>,
5556 Sched<[WriteV]> {
5557 bits<5> Vd;
5558 bits<5> Vn;
5559 bits<5> Vm;
5560 let Inst{31} = 0;
5561 let Inst{30} = Q;
5562 let Inst{29-21} = 0b001110000;
5563 let Inst{20-16} = Vm;
5564 let Inst{15} = 0;
5565 let Inst{14-13} = len;
5566 let Inst{12} = op;
5567 let Inst{11-10} = 0b00;
5568 let Inst{9-5} = Vn;
5569 let Inst{4-0} = Vd;
5570}
5571
5572let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
5573class BaseSIMDTableLookupTied<bit Q, bits<2> len, bit op, RegisterOperand vectype,
5574 RegisterOperand listtype, string asm, string kind>
5575 : I<(outs vectype:$dst), (ins vectype:$Vd, listtype:$Vn, vectype:$Vm), asm,
5576 "\t$Vd" # kind # ", $Vn, $Vm" # kind, "$Vd = $dst", []>,
5577 Sched<[WriteV]> {
5578 bits<5> Vd;
5579 bits<5> Vn;
5580 bits<5> Vm;
5581 let Inst{31} = 0;
5582 let Inst{30} = Q;
5583 let Inst{29-21} = 0b001110000;
5584 let Inst{20-16} = Vm;
5585 let Inst{15} = 0;
5586 let Inst{14-13} = len;
5587 let Inst{12} = op;
5588 let Inst{11-10} = 0b00;
5589 let Inst{9-5} = Vn;
5590 let Inst{4-0} = Vd;
5591}
5592
5593class SIMDTableLookupAlias<string asm, Instruction inst,
5594 RegisterOperand vectype, RegisterOperand listtype>
5595 : InstAlias<!strconcat(asm, "\t$dst, $lst, $index"),
5596 (inst vectype:$dst, listtype:$lst, vectype:$index), 0>;
5597
5598multiclass SIMDTableLookup<bit op, string asm> {
5599 def v8i8One : BaseSIMDTableLookup<0, 0b00, op, V64, VecListOne16b,
5600 asm, ".8b">;
5601 def v8i8Two : BaseSIMDTableLookup<0, 0b01, op, V64, VecListTwo16b,
5602 asm, ".8b">;
5603 def v8i8Three : BaseSIMDTableLookup<0, 0b10, op, V64, VecListThree16b,
5604 asm, ".8b">;
5605 def v8i8Four : BaseSIMDTableLookup<0, 0b11, op, V64, VecListFour16b,
5606 asm, ".8b">;
5607 def v16i8One : BaseSIMDTableLookup<1, 0b00, op, V128, VecListOne16b,
5608 asm, ".16b">;
5609 def v16i8Two : BaseSIMDTableLookup<1, 0b01, op, V128, VecListTwo16b,
5610 asm, ".16b">;
5611 def v16i8Three: BaseSIMDTableLookup<1, 0b10, op, V128, VecListThree16b,
5612 asm, ".16b">;
5613 def v16i8Four : BaseSIMDTableLookup<1, 0b11, op, V128, VecListFour16b,
5614 asm, ".16b">;
5615
5616 def : SIMDTableLookupAlias<asm # ".8b",
5617 !cast<Instruction>(NAME#"v8i8One"),
5618 V64, VecListOne128>;
5619 def : SIMDTableLookupAlias<asm # ".8b",
5620 !cast<Instruction>(NAME#"v8i8Two"),
5621 V64, VecListTwo128>;
5622 def : SIMDTableLookupAlias<asm # ".8b",
5623 !cast<Instruction>(NAME#"v8i8Three"),
5624 V64, VecListThree128>;
5625 def : SIMDTableLookupAlias<asm # ".8b",
5626 !cast<Instruction>(NAME#"v8i8Four"),
5627 V64, VecListFour128>;
5628 def : SIMDTableLookupAlias<asm # ".16b",
5629 !cast<Instruction>(NAME#"v16i8One"),
5630 V128, VecListOne128>;
5631 def : SIMDTableLookupAlias<asm # ".16b",
5632 !cast<Instruction>(NAME#"v16i8Two"),
5633 V128, VecListTwo128>;
5634 def : SIMDTableLookupAlias<asm # ".16b",
5635 !cast<Instruction>(NAME#"v16i8Three"),
5636 V128, VecListThree128>;
5637 def : SIMDTableLookupAlias<asm # ".16b",
5638 !cast<Instruction>(NAME#"v16i8Four"),
5639 V128, VecListFour128>;
5640}
5641
5642multiclass SIMDTableLookupTied<bit op, string asm> {
5643 def v8i8One : BaseSIMDTableLookupTied<0, 0b00, op, V64, VecListOne16b,
5644 asm, ".8b">;
5645 def v8i8Two : BaseSIMDTableLookupTied<0, 0b01, op, V64, VecListTwo16b,
5646 asm, ".8b">;
5647 def v8i8Three : BaseSIMDTableLookupTied<0, 0b10, op, V64, VecListThree16b,
5648 asm, ".8b">;
5649 def v8i8Four : BaseSIMDTableLookupTied<0, 0b11, op, V64, VecListFour16b,
5650 asm, ".8b">;
5651 def v16i8One : BaseSIMDTableLookupTied<1, 0b00, op, V128, VecListOne16b,
5652 asm, ".16b">;
5653 def v16i8Two : BaseSIMDTableLookupTied<1, 0b01, op, V128, VecListTwo16b,
5654 asm, ".16b">;
5655 def v16i8Three: BaseSIMDTableLookupTied<1, 0b10, op, V128, VecListThree16b,
5656 asm, ".16b">;
5657 def v16i8Four : BaseSIMDTableLookupTied<1, 0b11, op, V128, VecListFour16b,
5658 asm, ".16b">;
5659
5660 def : SIMDTableLookupAlias<asm # ".8b",
5661 !cast<Instruction>(NAME#"v8i8One"),
5662 V64, VecListOne128>;
5663 def : SIMDTableLookupAlias<asm # ".8b",
5664 !cast<Instruction>(NAME#"v8i8Two"),
5665 V64, VecListTwo128>;
5666 def : SIMDTableLookupAlias<asm # ".8b",
5667 !cast<Instruction>(NAME#"v8i8Three"),
5668 V64, VecListThree128>;
5669 def : SIMDTableLookupAlias<asm # ".8b",
5670 !cast<Instruction>(NAME#"v8i8Four"),
5671 V64, VecListFour128>;
5672 def : SIMDTableLookupAlias<asm # ".16b",
5673 !cast<Instruction>(NAME#"v16i8One"),
5674 V128, VecListOne128>;
5675 def : SIMDTableLookupAlias<asm # ".16b",
5676 !cast<Instruction>(NAME#"v16i8Two"),
5677 V128, VecListTwo128>;
5678 def : SIMDTableLookupAlias<asm # ".16b",
5679 !cast<Instruction>(NAME#"v16i8Three"),
5680 V128, VecListThree128>;
5681 def : SIMDTableLookupAlias<asm # ".16b",
5682 !cast<Instruction>(NAME#"v16i8Four"),
5683 V128, VecListFour128>;
5684}
5685
5686
5687//----------------------------------------------------------------------------
5688// AdvSIMD scalar CPY
5689//----------------------------------------------------------------------------
5690let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5691class BaseSIMDScalarCPY<RegisterClass regtype, RegisterOperand vectype,
5692 string kind, Operand idxtype>
5693 : I<(outs regtype:$dst), (ins vectype:$src, idxtype:$idx), "mov",
5694 "{\t$dst, $src" # kind # "$idx" #
5695 "|\t$dst, $src$idx}", "", []>,
5696 Sched<[WriteV]> {
5697 bits<5> dst;
5698 bits<5> src;
5699 let Inst{31-21} = 0b01011110000;
5700 let Inst{15-10} = 0b000001;
5701 let Inst{9-5} = src;
5702 let Inst{4-0} = dst;
5703}
5704
5705class SIMDScalarCPYAlias<string asm, string size, Instruction inst,
5706 RegisterClass regtype, RegisterOperand vectype, Operand idxtype>
5707 : InstAlias<asm # "{\t$dst, $src" # size # "$index" #
5708 # "|\t$dst, $src$index}",
5709 (inst regtype:$dst, vectype:$src, idxtype:$index)>;
5710
5711
5712multiclass SIMDScalarCPY<string asm> {
5713 def i8 : BaseSIMDScalarCPY<FPR8, V128, ".b", VectorIndexB> {
5714 bits<4> idx;
5715 let Inst{20-17} = idx;
5716 let Inst{16} = 1;
5717 }
5718 def i16 : BaseSIMDScalarCPY<FPR16, V128, ".h", VectorIndexH> {
5719 bits<3> idx;
5720 let Inst{20-18} = idx;
5721 let Inst{17-16} = 0b10;
5722 }
5723 def i32 : BaseSIMDScalarCPY<FPR32, V128, ".s", VectorIndexS> {
5724 bits<2> idx;
5725 let Inst{20-19} = idx;
5726 let Inst{18-16} = 0b100;
5727 }
5728 def i64 : BaseSIMDScalarCPY<FPR64, V128, ".d", VectorIndexD> {
5729 bits<1> idx;
5730 let Inst{20} = idx;
5731 let Inst{19-16} = 0b1000;
5732 }
5733
5734 // 'DUP' mnemonic aliases.
5735 def : SIMDScalarCPYAlias<"dup", ".b",
5736 !cast<Instruction>(NAME#"i8"),
5737 FPR8, V128, VectorIndexB>;
5738 def : SIMDScalarCPYAlias<"dup", ".h",
5739 !cast<Instruction>(NAME#"i16"),
5740 FPR16, V128, VectorIndexH>;
5741 def : SIMDScalarCPYAlias<"dup", ".s",
5742 !cast<Instruction>(NAME#"i32"),
5743 FPR32, V128, VectorIndexS>;
5744 def : SIMDScalarCPYAlias<"dup", ".d",
5745 !cast<Instruction>(NAME#"i64"),
5746 FPR64, V128, VectorIndexD>;
5747}
5748
5749//----------------------------------------------------------------------------
5750// AdvSIMD modified immediate instructions
5751//----------------------------------------------------------------------------
5752
5753class BaseSIMDModifiedImm<bit Q, bit op, dag oops, dag iops,
5754 string asm, string op_string,
5755 string cstr, list<dag> pattern>
5756 : I<oops, iops, asm, op_string, cstr, pattern>,
5757 Sched<[WriteV]> {
5758 bits<5> Rd;
5759 bits<8> imm8;
5760 let Inst{31} = 0;
5761 let Inst{30} = Q;
5762 let Inst{29} = op;
5763 let Inst{28-19} = 0b0111100000;
5764 let Inst{18-16} = imm8{7-5};
5765 let Inst{11-10} = 0b01;
5766 let Inst{9-5} = imm8{4-0};
5767 let Inst{4-0} = Rd;
5768}
5769
5770class BaseSIMDModifiedImmVector<bit Q, bit op, RegisterOperand vectype,
5771 Operand immtype, dag opt_shift_iop,
5772 string opt_shift, string asm, string kind,
5773 list<dag> pattern>
5774 : BaseSIMDModifiedImm<Q, op, (outs vectype:$Rd),
5775 !con((ins immtype:$imm8), opt_shift_iop), asm,
5776 "{\t$Rd" # kind # ", $imm8" # opt_shift #
5777 "|" # kind # "\t$Rd, $imm8" # opt_shift # "}",
5778 "", pattern> {
5779 let DecoderMethod = "DecodeModImmInstruction";
5780}
5781
5782class BaseSIMDModifiedImmVectorTied<bit Q, bit op, RegisterOperand vectype,
5783 Operand immtype, dag opt_shift_iop,
5784 string opt_shift, string asm, string kind,
5785 list<dag> pattern>
5786 : BaseSIMDModifiedImm<Q, op, (outs vectype:$dst),
5787 !con((ins vectype:$Rd, immtype:$imm8), opt_shift_iop),
5788 asm, "{\t$Rd" # kind # ", $imm8" # opt_shift #
5789 "|" # kind # "\t$Rd, $imm8" # opt_shift # "}",
5790 "$Rd = $dst", pattern> {
5791 let DecoderMethod = "DecodeModImmTiedInstruction";
5792}
5793
5794class BaseSIMDModifiedImmVectorShift<bit Q, bit op, bits<2> b15_b12,
5795 RegisterOperand vectype, string asm,
5796 string kind, list<dag> pattern>
5797 : BaseSIMDModifiedImmVector<Q, op, vectype, imm0_255,
5798 (ins logical_vec_shift:$shift),
5799 "$shift", asm, kind, pattern> {
5800 bits<2> shift;
5801 let Inst{15} = b15_b12{1};
5802 let Inst{14-13} = shift;
5803 let Inst{12} = b15_b12{0};
5804}
5805
5806class BaseSIMDModifiedImmVectorShiftTied<bit Q, bit op, bits<2> b15_b12,
5807 RegisterOperand vectype, string asm,
5808 string kind, list<dag> pattern>
5809 : BaseSIMDModifiedImmVectorTied<Q, op, vectype, imm0_255,
5810 (ins logical_vec_shift:$shift),
5811 "$shift", asm, kind, pattern> {
5812 bits<2> shift;
5813 let Inst{15} = b15_b12{1};
5814 let Inst{14-13} = shift;
5815 let Inst{12} = b15_b12{0};
5816}
5817
5818
5819class BaseSIMDModifiedImmVectorShiftHalf<bit Q, bit op, bits<2> b15_b12,
5820 RegisterOperand vectype, string asm,
5821 string kind, list<dag> pattern>
5822 : BaseSIMDModifiedImmVector<Q, op, vectype, imm0_255,
5823 (ins logical_vec_hw_shift:$shift),
5824 "$shift", asm, kind, pattern> {
5825 bits<2> shift;
5826 let Inst{15} = b15_b12{1};
5827 let Inst{14} = 0;
5828 let Inst{13} = shift{0};
5829 let Inst{12} = b15_b12{0};
5830}
5831
5832class BaseSIMDModifiedImmVectorShiftHalfTied<bit Q, bit op, bits<2> b15_b12,
5833 RegisterOperand vectype, string asm,
5834 string kind, list<dag> pattern>
5835 : BaseSIMDModifiedImmVectorTied<Q, op, vectype, imm0_255,
5836 (ins logical_vec_hw_shift:$shift),
5837 "$shift", asm, kind, pattern> {
5838 bits<2> shift;
5839 let Inst{15} = b15_b12{1};
5840 let Inst{14} = 0;
5841 let Inst{13} = shift{0};
5842 let Inst{12} = b15_b12{0};
5843}
5844
5845multiclass SIMDModifiedImmVectorShift<bit op, bits<2> hw_cmode, bits<2> w_cmode,
5846 string asm> {
5847 def v4i16 : BaseSIMDModifiedImmVectorShiftHalf<0, op, hw_cmode, V64,
5848 asm, ".4h", []>;
5849 def v8i16 : BaseSIMDModifiedImmVectorShiftHalf<1, op, hw_cmode, V128,
5850 asm, ".8h", []>;
5851
5852 def v2i32 : BaseSIMDModifiedImmVectorShift<0, op, w_cmode, V64,
5853 asm, ".2s", []>;
5854 def v4i32 : BaseSIMDModifiedImmVectorShift<1, op, w_cmode, V128,
5855 asm, ".4s", []>;
5856}
5857
5858multiclass SIMDModifiedImmVectorShiftTied<bit op, bits<2> hw_cmode,
5859 bits<2> w_cmode, string asm,
5860 SDNode OpNode> {
5861 def v4i16 : BaseSIMDModifiedImmVectorShiftHalfTied<0, op, hw_cmode, V64,
5862 asm, ".4h",
5863 [(set (v4i16 V64:$dst), (OpNode V64:$Rd,
5864 imm0_255:$imm8,
5865 (i32 imm:$shift)))]>;
5866 def v8i16 : BaseSIMDModifiedImmVectorShiftHalfTied<1, op, hw_cmode, V128,
5867 asm, ".8h",
5868 [(set (v8i16 V128:$dst), (OpNode V128:$Rd,
5869 imm0_255:$imm8,
5870 (i32 imm:$shift)))]>;
5871
5872 def v2i32 : BaseSIMDModifiedImmVectorShiftTied<0, op, w_cmode, V64,
5873 asm, ".2s",
5874 [(set (v2i32 V64:$dst), (OpNode V64:$Rd,
5875 imm0_255:$imm8,
5876 (i32 imm:$shift)))]>;
5877 def v4i32 : BaseSIMDModifiedImmVectorShiftTied<1, op, w_cmode, V128,
5878 asm, ".4s",
5879 [(set (v4i32 V128:$dst), (OpNode V128:$Rd,
5880 imm0_255:$imm8,
5881 (i32 imm:$shift)))]>;
5882}
5883
5884class SIMDModifiedImmMoveMSL<bit Q, bit op, bits<4> cmode,
5885 RegisterOperand vectype, string asm,
5886 string kind, list<dag> pattern>
5887 : BaseSIMDModifiedImmVector<Q, op, vectype, imm0_255,
5888 (ins move_vec_shift:$shift),
5889 "$shift", asm, kind, pattern> {
5890 bits<1> shift;
5891 let Inst{15-13} = cmode{3-1};
5892 let Inst{12} = shift;
5893}
5894
5895class SIMDModifiedImmVectorNoShift<bit Q, bit op, bits<4> cmode,
5896 RegisterOperand vectype,
5897 Operand imm_type, string asm,
5898 string kind, list<dag> pattern>
5899 : BaseSIMDModifiedImmVector<Q, op, vectype, imm_type, (ins), "",
5900 asm, kind, pattern> {
5901 let Inst{15-12} = cmode;
5902}
5903
5904class SIMDModifiedImmScalarNoShift<bit Q, bit op, bits<4> cmode, string asm,
5905 list<dag> pattern>
5906 : BaseSIMDModifiedImm<Q, op, (outs FPR64:$Rd), (ins simdimmtype10:$imm8), asm,
5907 "\t$Rd, $imm8", "", pattern> {
5908 let Inst{15-12} = cmode;
5909 let DecoderMethod = "DecodeModImmInstruction";
5910}
5911
5912//----------------------------------------------------------------------------
5913// AdvSIMD indexed element
5914//----------------------------------------------------------------------------
5915
5916let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5917class BaseSIMDIndexed<bit Q, bit U, bit Scalar, bits<2> size, bits<4> opc,
5918 RegisterOperand dst_reg, RegisterOperand lhs_reg,
5919 RegisterOperand rhs_reg, Operand vec_idx, string asm,
5920 string apple_kind, string dst_kind, string lhs_kind,
5921 string rhs_kind, list<dag> pattern>
5922 : I<(outs dst_reg:$Rd), (ins lhs_reg:$Rn, rhs_reg:$Rm, vec_idx:$idx),
5923 asm,
5924 "{\t$Rd" # dst_kind # ", $Rn" # lhs_kind # ", $Rm" # rhs_kind # "$idx" #
5925 "|" # apple_kind # "\t$Rd, $Rn, $Rm$idx}", "", pattern>,
5926 Sched<[WriteV]> {
5927 bits<5> Rd;
5928 bits<5> Rn;
5929 bits<5> Rm;
5930
5931 let Inst{31} = 0;
5932 let Inst{30} = Q;
5933 let Inst{29} = U;
5934 let Inst{28} = Scalar;
5935 let Inst{27-24} = 0b1111;
5936 let Inst{23-22} = size;
5937 // Bit 21 must be set by the derived class.
5938 let Inst{20-16} = Rm;
5939 let Inst{15-12} = opc;
5940 // Bit 11 must be set by the derived class.
5941 let Inst{10} = 0;
5942 let Inst{9-5} = Rn;
5943 let Inst{4-0} = Rd;
5944}
5945
5946let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5947class BaseSIMDIndexedTied<bit Q, bit U, bit Scalar, bits<2> size, bits<4> opc,
5948 RegisterOperand dst_reg, RegisterOperand lhs_reg,
5949 RegisterOperand rhs_reg, Operand vec_idx, string asm,
5950 string apple_kind, string dst_kind, string lhs_kind,
5951 string rhs_kind, list<dag> pattern>
5952 : I<(outs dst_reg:$dst),
5953 (ins dst_reg:$Rd, lhs_reg:$Rn, rhs_reg:$Rm, vec_idx:$idx), asm,
5954 "{\t$Rd" # dst_kind # ", $Rn" # lhs_kind # ", $Rm" # rhs_kind # "$idx" #
5955 "|" # apple_kind # "\t$Rd, $Rn, $Rm$idx}", "$Rd = $dst", pattern>,
5956 Sched<[WriteV]> {
5957 bits<5> Rd;
5958 bits<5> Rn;
5959 bits<5> Rm;
5960
5961 let Inst{31} = 0;
5962 let Inst{30} = Q;
5963 let Inst{29} = U;
5964 let Inst{28} = Scalar;
5965 let Inst{27-24} = 0b1111;
5966 let Inst{23-22} = size;
5967 // Bit 21 must be set by the derived class.
5968 let Inst{20-16} = Rm;
5969 let Inst{15-12} = opc;
5970 // Bit 11 must be set by the derived class.
5971 let Inst{10} = 0;
5972 let Inst{9-5} = Rn;
5973 let Inst{4-0} = Rd;
5974}
5975
5976multiclass SIMDFPIndexedSD<bit U, bits<4> opc, string asm,
5977 SDPatternOperator OpNode> {
5978 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc,
5979 V64, V64,
5980 V128, VectorIndexS,
5981 asm, ".2s", ".2s", ".2s", ".s",
5982 [(set (v2f32 V64:$Rd),
5983 (OpNode (v2f32 V64:$Rn),
5984 (v2f32 (ARM64duplane32 (v4f32 V128:$Rm), VectorIndexS:$idx))))]> {
5985 bits<2> idx;
5986 let Inst{11} = idx{1};
5987 let Inst{21} = idx{0};
5988 }
5989
5990 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc,
5991 V128, V128,
5992 V128, VectorIndexS,
5993 asm, ".4s", ".4s", ".4s", ".s",
5994 [(set (v4f32 V128:$Rd),
5995 (OpNode (v4f32 V128:$Rn),
5996 (v4f32 (ARM64duplane32 (v4f32 V128:$Rm), VectorIndexS:$idx))))]> {
5997 bits<2> idx;
5998 let Inst{11} = idx{1};
5999 let Inst{21} = idx{0};
6000 }
6001
6002 def v2i64_indexed : BaseSIMDIndexed<1, U, 0, 0b11, opc,
6003 V128, V128,
6004 V128, VectorIndexD,
6005 asm, ".2d", ".2d", ".2d", ".d",
6006 [(set (v2f64 V128:$Rd),
6007 (OpNode (v2f64 V128:$Rn),
6008 (v2f64 (ARM64duplane64 (v2f64 V128:$Rm), VectorIndexD:$idx))))]> {
6009 bits<1> idx;
6010 let Inst{11} = idx{0};
6011 let Inst{21} = 0;
6012 }
6013
6014 def v1i32_indexed : BaseSIMDIndexed<1, U, 1, 0b10, opc,
6015 FPR32Op, FPR32Op, V128, VectorIndexS,
6016 asm, ".s", "", "", ".s",
6017 [(set (f32 FPR32Op:$Rd),
6018 (OpNode (f32 FPR32Op:$Rn),
6019 (f32 (vector_extract (v4f32 V128:$Rm),
6020 VectorIndexS:$idx))))]> {
6021 bits<2> idx;
6022 let Inst{11} = idx{1};
6023 let Inst{21} = idx{0};
6024 }
6025
6026 def v1i64_indexed : BaseSIMDIndexed<1, U, 1, 0b11, opc,
6027 FPR64Op, FPR64Op, V128, VectorIndexD,
6028 asm, ".d", "", "", ".d",
6029 [(set (f64 FPR64Op:$Rd),
6030 (OpNode (f64 FPR64Op:$Rn),
6031 (f64 (vector_extract (v2f64 V128:$Rm),
6032 VectorIndexD:$idx))))]> {
6033 bits<1> idx;
6034 let Inst{11} = idx{0};
6035 let Inst{21} = 0;
6036 }
6037}
6038
6039multiclass SIMDFPIndexedSDTiedPatterns<string INST, SDPatternOperator OpNode> {
6040 // 2 variants for the .2s version: DUPLANE from 128-bit and DUP scalar.
6041 def : Pat<(v2f32 (OpNode (v2f32 V64:$Rd), (v2f32 V64:$Rn),
6042 (ARM64duplane32 (v4f32 V128:$Rm),
6043 VectorIndexS:$idx))),
6044 (!cast<Instruction>(INST # v2i32_indexed)
6045 V64:$Rd, V64:$Rn, V128:$Rm, VectorIndexS:$idx)>;
6046 def : Pat<(v2f32 (OpNode (v2f32 V64:$Rd), (v2f32 V64:$Rn),
6047 (ARM64dup (f32 FPR32Op:$Rm)))),
6048 (!cast<Instruction>(INST # "v2i32_indexed") V64:$Rd, V64:$Rn,
6049 (SUBREG_TO_REG (i32 0), FPR32Op:$Rm, ssub), (i64 0))>;
6050
6051
6052 // 2 variants for the .4s version: DUPLANE from 128-bit and DUP scalar.
6053 def : Pat<(v4f32 (OpNode (v4f32 V128:$Rd), (v4f32 V128:$Rn),
6054 (ARM64duplane32 (v4f32 V128:$Rm),
6055 VectorIndexS:$idx))),
6056 (!cast<Instruction>(INST # "v4i32_indexed")
6057 V128:$Rd, V128:$Rn, V128:$Rm, VectorIndexS:$idx)>;
6058 def : Pat<(v4f32 (OpNode (v4f32 V128:$Rd), (v4f32 V128:$Rn),
6059 (ARM64dup (f32 FPR32Op:$Rm)))),
6060 (!cast<Instruction>(INST # "v4i32_indexed") V128:$Rd, V128:$Rn,
6061 (SUBREG_TO_REG (i32 0), FPR32Op:$Rm, ssub), (i64 0))>;
6062
6063 // 2 variants for the .2d version: DUPLANE from 128-bit and DUP scalar.
6064 def : Pat<(v2f64 (OpNode (v2f64 V128:$Rd), (v2f64 V128:$Rn),
6065 (ARM64duplane64 (v2f64 V128:$Rm),
6066 VectorIndexD:$idx))),
6067 (!cast<Instruction>(INST # "v2i64_indexed")
6068 V128:$Rd, V128:$Rn, V128:$Rm, VectorIndexS:$idx)>;
6069 def : Pat<(v2f64 (OpNode (v2f64 V128:$Rd), (v2f64 V128:$Rn),
6070 (ARM64dup (f64 FPR64Op:$Rm)))),
6071 (!cast<Instruction>(INST # "v2i64_indexed") V128:$Rd, V128:$Rn,
6072 (SUBREG_TO_REG (i32 0), FPR64Op:$Rm, dsub), (i64 0))>;
6073
6074 // 2 variants for 32-bit scalar version: extract from .2s or from .4s
6075 def : Pat<(f32 (OpNode (f32 FPR32:$Rd), (f32 FPR32:$Rn),
6076 (vector_extract (v4f32 V128:$Rm), VectorIndexS:$idx))),
6077 (!cast<Instruction>(INST # "v1i32_indexed") FPR32:$Rd, FPR32:$Rn,
6078 V128:$Rm, VectorIndexS:$idx)>;
6079 def : Pat<(f32 (OpNode (f32 FPR32:$Rd), (f32 FPR32:$Rn),
6080 (vector_extract (v2f32 V64:$Rm), VectorIndexS:$idx))),
6081 (!cast<Instruction>(INST # "v1i32_indexed") FPR32:$Rd, FPR32:$Rn,
6082 (SUBREG_TO_REG (i32 0), V64:$Rm, dsub), VectorIndexS:$idx)>;
6083
6084 // 1 variant for 64-bit scalar version: extract from .1d or from .2d
6085 def : Pat<(f64 (OpNode (f64 FPR64:$Rd), (f64 FPR64:$Rn),
6086 (vector_extract (v2f64 V128:$Rm), VectorIndexD:$idx))),
6087 (!cast<Instruction>(INST # "v1i64_indexed") FPR64:$Rd, FPR64:$Rn,
6088 V128:$Rm, VectorIndexD:$idx)>;
6089}
6090
6091multiclass SIMDFPIndexedSDTied<bit U, bits<4> opc, string asm> {
6092 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc, V64, V64,
6093 V128, VectorIndexS,
6094 asm, ".2s", ".2s", ".2s", ".s", []> {
6095 bits<2> idx;
6096 let Inst{11} = idx{1};
6097 let Inst{21} = idx{0};
6098 }
6099
6100 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc,
6101 V128, V128,
6102 V128, VectorIndexS,
6103 asm, ".4s", ".4s", ".4s", ".s", []> {
6104 bits<2> idx;
6105 let Inst{11} = idx{1};
6106 let Inst{21} = idx{0};
6107 }
6108
6109 def v2i64_indexed : BaseSIMDIndexedTied<1, U, 0, 0b11, opc,
6110 V128, V128,
6111 V128, VectorIndexD,
6112 asm, ".2d", ".2d", ".2d", ".d", []> {
6113 bits<1> idx;
6114 let Inst{11} = idx{0};
6115 let Inst{21} = 0;
6116 }
6117
6118
6119 def v1i32_indexed : BaseSIMDIndexedTied<1, U, 1, 0b10, opc,
6120 FPR32Op, FPR32Op, V128, VectorIndexS,
6121 asm, ".s", "", "", ".s", []> {
6122 bits<2> idx;
6123 let Inst{11} = idx{1};
6124 let Inst{21} = idx{0};
6125 }
6126
6127 def v1i64_indexed : BaseSIMDIndexedTied<1, U, 1, 0b11, opc,
6128 FPR64Op, FPR64Op, V128, VectorIndexD,
6129 asm, ".d", "", "", ".d", []> {
6130 bits<1> idx;
6131 let Inst{11} = idx{0};
6132 let Inst{21} = 0;
6133 }
6134}
6135
6136multiclass SIMDIndexedHS<bit U, bits<4> opc, string asm,
6137 SDPatternOperator OpNode> {
6138 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc, V64, V64,
6139 V128_lo, VectorIndexH,
6140 asm, ".4h", ".4h", ".4h", ".h",
6141 [(set (v4i16 V64:$Rd),
6142 (OpNode (v4i16 V64:$Rn),
6143 (v4i16 (ARM64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
6144 bits<3> idx;
6145 let Inst{11} = idx{2};
6146 let Inst{21} = idx{1};
6147 let Inst{20} = idx{0};
6148 }
6149
6150 def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc,
6151 V128, V128,
6152 V128_lo, VectorIndexH,
6153 asm, ".8h", ".8h", ".8h", ".h",
6154 [(set (v8i16 V128:$Rd),
6155 (OpNode (v8i16 V128:$Rn),
6156 (v8i16 (ARM64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
6157 bits<3> idx;
6158 let Inst{11} = idx{2};
6159 let Inst{21} = idx{1};
6160 let Inst{20} = idx{0};
6161 }
6162
6163 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc,
6164 V64, V64,
6165 V128, VectorIndexS,
6166 asm, ".2s", ".2s", ".2s", ".s",
6167 [(set (v2i32 V64:$Rd),
6168 (OpNode (v2i32 V64:$Rn),
6169 (v2i32 (ARM64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
6170 bits<2> idx;
6171 let Inst{11} = idx{1};
6172 let Inst{21} = idx{0};
6173 }
6174
6175 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc,
6176 V128, V128,
6177 V128, VectorIndexS,
6178 asm, ".4s", ".4s", ".4s", ".s",
6179 [(set (v4i32 V128:$Rd),
6180 (OpNode (v4i32 V128:$Rn),
6181 (v4i32 (ARM64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
6182 bits<2> idx;
6183 let Inst{11} = idx{1};
6184 let Inst{21} = idx{0};
6185 }
6186
6187 def v1i16_indexed : BaseSIMDIndexed<1, U, 1, 0b01, opc,
6188 FPR16Op, FPR16Op, V128_lo, VectorIndexH,
6189 asm, ".h", "", "", ".h", []> {
6190 bits<3> idx;
6191 let Inst{11} = idx{2};
6192 let Inst{21} = idx{1};
6193 let Inst{20} = idx{0};
6194 }
6195
6196 def v1i32_indexed : BaseSIMDIndexed<1, U, 1, 0b10, opc,
6197 FPR32Op, FPR32Op, V128, VectorIndexS,
6198 asm, ".s", "", "", ".s",
6199 [(set (i32 FPR32Op:$Rd),
6200 (OpNode FPR32Op:$Rn,
6201 (i32 (vector_extract (v4i32 V128:$Rm),
6202 VectorIndexS:$idx))))]> {
6203 bits<2> idx;
6204 let Inst{11} = idx{1};
6205 let Inst{21} = idx{0};
6206 }
6207}
6208
6209multiclass SIMDVectorIndexedHS<bit U, bits<4> opc, string asm,
6210 SDPatternOperator OpNode> {
6211 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc,
6212 V64, V64,
6213 V128_lo, VectorIndexH,
6214 asm, ".4h", ".4h", ".4h", ".h",
6215 [(set (v4i16 V64:$Rd),
6216 (OpNode (v4i16 V64:$Rn),
6217 (v4i16 (ARM64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
6218 bits<3> idx;
6219 let Inst{11} = idx{2};
6220 let Inst{21} = idx{1};
6221 let Inst{20} = idx{0};
6222 }
6223
6224 def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc,
6225 V128, V128,
6226 V128_lo, VectorIndexH,
6227 asm, ".8h", ".8h", ".8h", ".h",
6228 [(set (v8i16 V128:$Rd),
6229 (OpNode (v8i16 V128:$Rn),
6230 (v8i16 (ARM64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
6231 bits<3> idx;
6232 let Inst{11} = idx{2};
6233 let Inst{21} = idx{1};
6234 let Inst{20} = idx{0};
6235 }
6236
6237 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc,
6238 V64, V64,
6239 V128, VectorIndexS,
6240 asm, ".2s", ".2s", ".2s", ".s",
6241 [(set (v2i32 V64:$Rd),
6242 (OpNode (v2i32 V64:$Rn),
6243 (v2i32 (ARM64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
6244 bits<2> idx;
6245 let Inst{11} = idx{1};
6246 let Inst{21} = idx{0};
6247 }
6248
6249 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc,
6250 V128, V128,
6251 V128, VectorIndexS,
6252 asm, ".4s", ".4s", ".4s", ".s",
6253 [(set (v4i32 V128:$Rd),
6254 (OpNode (v4i32 V128:$Rn),
6255 (v4i32 (ARM64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
6256 bits<2> idx;
6257 let Inst{11} = idx{1};
6258 let Inst{21} = idx{0};
6259 }
6260}
6261
6262multiclass SIMDVectorIndexedHSTied<bit U, bits<4> opc, string asm,
6263 SDPatternOperator OpNode> {
6264 def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc, V64, V64,
6265 V128_lo, VectorIndexH,
6266 asm, ".4h", ".4h", ".4h", ".h",
6267 [(set (v4i16 V64:$dst),
6268 (OpNode (v4i16 V64:$Rd),(v4i16 V64:$Rn),
6269 (v4i16 (ARM64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
6270 bits<3> idx;
6271 let Inst{11} = idx{2};
6272 let Inst{21} = idx{1};
6273 let Inst{20} = idx{0};
6274 }
6275
6276 def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc,
6277 V128, V128,
6278 V128_lo, VectorIndexH,
6279 asm, ".8h", ".8h", ".8h", ".h",
6280 [(set (v8i16 V128:$dst),
6281 (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn),
6282 (v8i16 (ARM64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
6283 bits<3> idx;
6284 let Inst{11} = idx{2};
6285 let Inst{21} = idx{1};
6286 let Inst{20} = idx{0};
6287 }
6288
6289 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc,
6290 V64, V64,
6291 V128, VectorIndexS,
6292 asm, ".2s", ".2s", ".2s", ".s",
6293 [(set (v2i32 V64:$dst),
6294 (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn),
6295 (v2i32 (ARM64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
6296 bits<2> idx;
6297 let Inst{11} = idx{1};
6298 let Inst{21} = idx{0};
6299 }
6300
6301 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc,
6302 V128, V128,
6303 V128, VectorIndexS,
6304 asm, ".4s", ".4s", ".4s", ".s",
6305 [(set (v4i32 V128:$dst),
6306 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn),
6307 (v4i32 (ARM64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
6308 bits<2> idx;
6309 let Inst{11} = idx{1};
6310 let Inst{21} = idx{0};
6311 }
6312}
6313
6314multiclass SIMDIndexedLongSD<bit U, bits<4> opc, string asm,
6315 SDPatternOperator OpNode> {
6316 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc,
6317 V128, V64,
6318 V128_lo, VectorIndexH,
6319 asm, ".4s", ".4s", ".4h", ".h",
6320 [(set (v4i32 V128:$Rd),
6321 (OpNode (v4i16 V64:$Rn),
6322 (v4i16 (ARM64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
6323 bits<3> idx;
6324 let Inst{11} = idx{2};
6325 let Inst{21} = idx{1};
6326 let Inst{20} = idx{0};
6327 }
6328
6329 def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc,
6330 V128, V128,
6331 V128_lo, VectorIndexH,
6332 asm#"2", ".4s", ".4s", ".8h", ".h",
6333 [(set (v4i32 V128:$Rd),
6334 (OpNode (extract_high_v8i16 V128:$Rn),
6335 (extract_high_v8i16 (ARM64duplane16 (v8i16 V128_lo:$Rm),
6336 VectorIndexH:$idx))))]> {
6337
6338 bits<3> idx;
6339 let Inst{11} = idx{2};
6340 let Inst{21} = idx{1};
6341 let Inst{20} = idx{0};
6342 }
6343
6344 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc,
6345 V128, V64,
6346 V128, VectorIndexS,
6347 asm, ".2d", ".2d", ".2s", ".s",
6348 [(set (v2i64 V128:$Rd),
6349 (OpNode (v2i32 V64:$Rn),
6350 (v2i32 (ARM64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
6351 bits<2> idx;
6352 let Inst{11} = idx{1};
6353 let Inst{21} = idx{0};
6354 }
6355
6356 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc,
6357 V128, V128,
6358 V128, VectorIndexS,
6359 asm#"2", ".2d", ".2d", ".4s", ".s",
6360 [(set (v2i64 V128:$Rd),
6361 (OpNode (extract_high_v4i32 V128:$Rn),
6362 (extract_high_v4i32 (ARM64duplane32 (v4i32 V128:$Rm),
6363 VectorIndexS:$idx))))]> {
6364 bits<2> idx;
6365 let Inst{11} = idx{1};
6366 let Inst{21} = idx{0};
6367 }
6368
6369 def v1i32_indexed : BaseSIMDIndexed<1, U, 1, 0b01, opc,
6370 FPR32Op, FPR16Op, V128_lo, VectorIndexH,
6371 asm, ".h", "", "", ".h", []> {
6372 bits<3> idx;
6373 let Inst{11} = idx{2};
6374 let Inst{21} = idx{1};
6375 let Inst{20} = idx{0};
6376 }
6377
6378 def v1i64_indexed : BaseSIMDIndexed<1, U, 1, 0b10, opc,
6379 FPR64Op, FPR32Op, V128, VectorIndexS,
6380 asm, ".s", "", "", ".s", []> {
6381 bits<2> idx;
6382 let Inst{11} = idx{1};
6383 let Inst{21} = idx{0};
6384 }
6385}
6386
6387multiclass SIMDIndexedLongSQDMLXSDTied<bit U, bits<4> opc, string asm,
6388 SDPatternOperator Accum> {
6389 def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc,
6390 V128, V64,
6391 V128_lo, VectorIndexH,
6392 asm, ".4s", ".4s", ".4h", ".h",
6393 [(set (v4i32 V128:$dst),
6394 (Accum (v4i32 V128:$Rd),
6395 (v4i32 (int_arm64_neon_sqdmull
6396 (v4i16 V64:$Rn),
6397 (v4i16 (ARM64duplane16 (v8i16 V128_lo:$Rm),
6398 VectorIndexH:$idx))))))]> {
6399 bits<3> idx;
6400 let Inst{11} = idx{2};
6401 let Inst{21} = idx{1};
6402 let Inst{20} = idx{0};
6403 }
6404
6405 // FIXME: it would be nice to use the scalar (v1i32) instruction here, but an
6406 // intermediate EXTRACT_SUBREG would be untyped.
6407 def : Pat<(i32 (Accum (i32 FPR32Op:$Rd),
6408 (i32 (vector_extract (v4i32
6409 (int_arm64_neon_sqdmull (v4i16 V64:$Rn),
6410 (v4i16 (ARM64duplane16 (v8i16 V128_lo:$Rm),
6411 VectorIndexH:$idx)))),
6412 (i64 0))))),
6413 (EXTRACT_SUBREG
6414 (!cast<Instruction>(NAME # v4i16_indexed)
6415 (SUBREG_TO_REG (i32 0), FPR32Op:$Rd, ssub), V64:$Rn,
6416 V128_lo:$Rm, VectorIndexH:$idx),
6417 ssub)>;
6418
6419 def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc,
6420 V128, V128,
6421 V128_lo, VectorIndexH,
6422 asm#"2", ".4s", ".4s", ".8h", ".h",
6423 [(set (v4i32 V128:$dst),
6424 (Accum (v4i32 V128:$Rd),
6425 (v4i32 (int_arm64_neon_sqdmull
6426 (extract_high_v8i16 V128:$Rn),
6427 (extract_high_v8i16
6428 (ARM64duplane16 (v8i16 V128_lo:$Rm),
6429 VectorIndexH:$idx))))))]> {
6430 bits<3> idx;
6431 let Inst{11} = idx{2};
6432 let Inst{21} = idx{1};
6433 let Inst{20} = idx{0};
6434 }
6435
6436 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc,
6437 V128, V64,
6438 V128, VectorIndexS,
6439 asm, ".2d", ".2d", ".2s", ".s",
6440 [(set (v2i64 V128:$dst),
6441 (Accum (v2i64 V128:$Rd),
6442 (v2i64 (int_arm64_neon_sqdmull
6443 (v2i32 V64:$Rn),
6444 (v2i32 (ARM64duplane32 (v4i32 V128:$Rm),
6445 VectorIndexS:$idx))))))]> {
6446 bits<2> idx;
6447 let Inst{11} = idx{1};
6448 let Inst{21} = idx{0};
6449 }
6450
6451 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc,
6452 V128, V128,
6453 V128, VectorIndexS,
6454 asm#"2", ".2d", ".2d", ".4s", ".s",
6455 [(set (v2i64 V128:$dst),
6456 (Accum (v2i64 V128:$Rd),
6457 (v2i64 (int_arm64_neon_sqdmull
6458 (extract_high_v4i32 V128:$Rn),
6459 (extract_high_v4i32
6460 (ARM64duplane32 (v4i32 V128:$Rm),
6461 VectorIndexS:$idx))))))]> {
6462 bits<2> idx;
6463 let Inst{11} = idx{1};
6464 let Inst{21} = idx{0};
6465 }
6466
6467 def v1i32_indexed : BaseSIMDIndexedTied<1, U, 1, 0b01, opc,
6468 FPR32Op, FPR16Op, V128_lo, VectorIndexH,
6469 asm, ".h", "", "", ".h", []> {
6470 bits<3> idx;
6471 let Inst{11} = idx{2};
6472 let Inst{21} = idx{1};
6473 let Inst{20} = idx{0};
6474 }
6475
6476
6477 def v1i64_indexed : BaseSIMDIndexedTied<1, U, 1, 0b10, opc,
6478 FPR64Op, FPR32Op, V128, VectorIndexS,
6479 asm, ".s", "", "", ".s",
6480 [(set (i64 FPR64Op:$dst),
6481 (Accum (i64 FPR64Op:$Rd),
6482 (i64 (int_arm64_neon_sqdmulls_scalar
6483 (i32 FPR32Op:$Rn),
6484 (i32 (vector_extract (v4i32 V128:$Rm),
6485 VectorIndexS:$idx))))))]> {
6486
6487 bits<2> idx;
6488 let Inst{11} = idx{1};
6489 let Inst{21} = idx{0};
6490 }
6491}
6492
6493multiclass SIMDVectorIndexedLongSD<bit U, bits<4> opc, string asm,
6494 SDPatternOperator OpNode> {
6495 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
6496 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc,
6497 V128, V64,
6498 V128_lo, VectorIndexH,
6499 asm, ".4s", ".4s", ".4h", ".h",
6500 [(set (v4i32 V128:$Rd),
6501 (OpNode (v4i16 V64:$Rn),
6502 (v4i16 (ARM64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
6503 bits<3> idx;
6504 let Inst{11} = idx{2};
6505 let Inst{21} = idx{1};
6506 let Inst{20} = idx{0};
6507 }
6508
6509 def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc,
6510 V128, V128,
6511 V128_lo, VectorIndexH,
6512 asm#"2", ".4s", ".4s", ".8h", ".h",
6513 [(set (v4i32 V128:$Rd),
6514 (OpNode (extract_high_v8i16 V128:$Rn),
6515 (extract_high_v8i16 (ARM64duplane16 (v8i16 V128_lo:$Rm),
6516 VectorIndexH:$idx))))]> {
6517
6518 bits<3> idx;
6519 let Inst{11} = idx{2};
6520 let Inst{21} = idx{1};
6521 let Inst{20} = idx{0};
6522 }
6523
6524 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc,
6525 V128, V64,
6526 V128, VectorIndexS,
6527 asm, ".2d", ".2d", ".2s", ".s",
6528 [(set (v2i64 V128:$Rd),
6529 (OpNode (v2i32 V64:$Rn),
6530 (v2i32 (ARM64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
6531 bits<2> idx;
6532 let Inst{11} = idx{1};
6533 let Inst{21} = idx{0};
6534 }
6535
6536 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc,
6537 V128, V128,
6538 V128, VectorIndexS,
6539 asm#"2", ".2d", ".2d", ".4s", ".s",
6540 [(set (v2i64 V128:$Rd),
6541 (OpNode (extract_high_v4i32 V128:$Rn),
6542 (extract_high_v4i32 (ARM64duplane32 (v4i32 V128:$Rm),
6543 VectorIndexS:$idx))))]> {
6544 bits<2> idx;
6545 let Inst{11} = idx{1};
6546 let Inst{21} = idx{0};
6547 }
6548 }
6549}
6550
6551multiclass SIMDVectorIndexedLongSDTied<bit U, bits<4> opc, string asm,
6552 SDPatternOperator OpNode> {
6553 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
6554 def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc,
6555 V128, V64,
6556 V128_lo, VectorIndexH,
6557 asm, ".4s", ".4s", ".4h", ".h",
6558 [(set (v4i32 V128:$dst),
6559 (OpNode (v4i32 V128:$Rd), (v4i16 V64:$Rn),
6560 (v4i16 (ARM64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
6561 bits<3> idx;
6562 let Inst{11} = idx{2};
6563 let Inst{21} = idx{1};
6564 let Inst{20} = idx{0};
6565 }
6566
6567 def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc,
6568 V128, V128,
6569 V128_lo, VectorIndexH,
6570 asm#"2", ".4s", ".4s", ".8h", ".h",
6571 [(set (v4i32 V128:$dst),
6572 (OpNode (v4i32 V128:$Rd),
6573 (extract_high_v8i16 V128:$Rn),
6574 (extract_high_v8i16 (ARM64duplane16 (v8i16 V128_lo:$Rm),
6575 VectorIndexH:$idx))))]> {
6576 bits<3> idx;
6577 let Inst{11} = idx{2};
6578 let Inst{21} = idx{1};
6579 let Inst{20} = idx{0};
6580 }
6581
6582 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc,
6583 V128, V64,
6584 V128, VectorIndexS,
6585 asm, ".2d", ".2d", ".2s", ".s",
6586 [(set (v2i64 V128:$dst),
6587 (OpNode (v2i64 V128:$Rd), (v2i32 V64:$Rn),
6588 (v2i32 (ARM64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
6589 bits<2> idx;
6590 let Inst{11} = idx{1};
6591 let Inst{21} = idx{0};
6592 }
6593
6594 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc,
6595 V128, V128,
6596 V128, VectorIndexS,
6597 asm#"2", ".2d", ".2d", ".4s", ".s",
6598 [(set (v2i64 V128:$dst),
6599 (OpNode (v2i64 V128:$Rd),
6600 (extract_high_v4i32 V128:$Rn),
6601 (extract_high_v4i32 (ARM64duplane32 (v4i32 V128:$Rm),
6602 VectorIndexS:$idx))))]> {
6603 bits<2> idx;
6604 let Inst{11} = idx{1};
6605 let Inst{21} = idx{0};
6606 }
6607 }
6608}
6609
6610//----------------------------------------------------------------------------
6611// AdvSIMD scalar shift by immediate
6612//----------------------------------------------------------------------------
6613
6614let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
6615class BaseSIMDScalarShift<bit U, bits<5> opc, bits<7> fixed_imm,
6616 RegisterClass regtype1, RegisterClass regtype2,
6617 Operand immtype, string asm, list<dag> pattern>
6618 : I<(outs regtype1:$Rd), (ins regtype2:$Rn, immtype:$imm),
6619 asm, "\t$Rd, $Rn, $imm", "", pattern>,
6620 Sched<[WriteV]> {
6621 bits<5> Rd;
6622 bits<5> Rn;
6623 bits<7> imm;
6624 let Inst{31-30} = 0b01;
6625 let Inst{29} = U;
6626 let Inst{28-23} = 0b111110;
6627 let Inst{22-16} = fixed_imm;
6628 let Inst{15-11} = opc;
6629 let Inst{10} = 1;
6630 let Inst{9-5} = Rn;
6631 let Inst{4-0} = Rd;
6632}
6633
6634let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
6635class BaseSIMDScalarShiftTied<bit U, bits<5> opc, bits<7> fixed_imm,
6636 RegisterClass regtype1, RegisterClass regtype2,
6637 Operand immtype, string asm, list<dag> pattern>
6638 : I<(outs regtype1:$dst), (ins regtype1:$Rd, regtype2:$Rn, immtype:$imm),
6639 asm, "\t$Rd, $Rn, $imm", "$Rd = $dst", pattern>,
6640 Sched<[WriteV]> {
6641 bits<5> Rd;
6642 bits<5> Rn;
6643 bits<7> imm;
6644 let Inst{31-30} = 0b01;
6645 let Inst{29} = U;
6646 let Inst{28-23} = 0b111110;
6647 let Inst{22-16} = fixed_imm;
6648 let Inst{15-11} = opc;
6649 let Inst{10} = 1;
6650 let Inst{9-5} = Rn;
6651 let Inst{4-0} = Rd;
6652}
6653
6654
6655multiclass SIMDScalarRShiftSD<bit U, bits<5> opc, string asm> {
6656 def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?},
6657 FPR32, FPR32, vecshiftR32, asm, []> {
6658 let Inst{20-16} = imm{4-0};
6659 }
6660
6661 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?},
6662 FPR64, FPR64, vecshiftR64, asm, []> {
6663 let Inst{21-16} = imm{5-0};
6664 }
6665}
6666
6667multiclass SIMDScalarRShiftD<bit U, bits<5> opc, string asm,
6668 SDPatternOperator OpNode> {
6669 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?},
6670 FPR64, FPR64, vecshiftR64, asm,
Tim Northover5081cd02014-03-31 15:46:46 +00006671 [(set (i64 FPR64:$Rd),
6672 (OpNode (i64 FPR64:$Rn), (i32 vecshiftR64:$imm)))]> {
Tim Northover00ed9962014-03-29 10:18:08 +00006673 let Inst{21-16} = imm{5-0};
6674 }
Tim Northover5081cd02014-03-31 15:46:46 +00006675
6676 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rn), (i32 vecshiftR64:$imm))),
6677 (!cast<Instruction>(NAME # "d") FPR64:$Rn, vecshiftR64:$imm)>;
Tim Northover00ed9962014-03-29 10:18:08 +00006678}
6679
Tim Northover00ed9962014-03-29 10:18:08 +00006680multiclass SIMDScalarRShiftDTied<bit U, bits<5> opc, string asm,
6681 SDPatternOperator OpNode = null_frag> {
6682 def d : BaseSIMDScalarShiftTied<U, opc, {1,?,?,?,?,?,?},
6683 FPR64, FPR64, vecshiftR64, asm,
Tim Northover5081cd02014-03-31 15:46:46 +00006684 [(set (i64 FPR64:$dst), (OpNode (i64 FPR64:$Rd), (i64 FPR64:$Rn),
6685 (i32 vecshiftR64:$imm)))]> {
Tim Northover00ed9962014-03-29 10:18:08 +00006686 let Inst{21-16} = imm{5-0};
6687 }
Tim Northover5081cd02014-03-31 15:46:46 +00006688
6689 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rd), (v1i64 FPR64:$Rn),
6690 (i32 vecshiftR64:$imm))),
6691 (!cast<Instruction>(NAME # "d") FPR64:$Rd, FPR64:$Rn,
6692 vecshiftR64:$imm)>;
Tim Northover00ed9962014-03-29 10:18:08 +00006693}
6694
6695multiclass SIMDScalarLShiftD<bit U, bits<5> opc, string asm,
6696 SDPatternOperator OpNode> {
6697 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?},
6698 FPR64, FPR64, vecshiftL64, asm,
6699 [(set (v1i64 FPR64:$Rd),
6700 (OpNode (v1i64 FPR64:$Rn), (i32 vecshiftL64:$imm)))]> {
6701 let Inst{21-16} = imm{5-0};
6702 }
6703}
6704
6705let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
6706multiclass SIMDScalarLShiftDTied<bit U, bits<5> opc, string asm> {
6707 def d : BaseSIMDScalarShiftTied<U, opc, {1,?,?,?,?,?,?},
6708 FPR64, FPR64, vecshiftL64, asm, []> {
6709 let Inst{21-16} = imm{5-0};
6710 }
6711}
6712
6713let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
6714multiclass SIMDScalarRShiftBHS<bit U, bits<5> opc, string asm,
6715 SDPatternOperator OpNode = null_frag> {
6716 def b : BaseSIMDScalarShift<U, opc, {0,0,0,1,?,?,?},
6717 FPR8, FPR16, vecshiftR8, asm, []> {
6718 let Inst{18-16} = imm{2-0};
6719 }
6720
6721 def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?},
6722 FPR16, FPR32, vecshiftR16, asm, []> {
6723 let Inst{19-16} = imm{3-0};
6724 }
6725
6726 def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?},
6727 FPR32, FPR64, vecshiftR32, asm,
6728 [(set (i32 FPR32:$Rd), (OpNode (i64 FPR64:$Rn), vecshiftR32:$imm))]> {
6729 let Inst{20-16} = imm{4-0};
6730 }
6731}
6732
6733multiclass SIMDScalarLShiftBHSD<bit U, bits<5> opc, string asm,
6734 SDPatternOperator OpNode> {
6735 def b : BaseSIMDScalarShift<U, opc, {0,0,0,1,?,?,?},
6736 FPR8, FPR8, vecshiftL8, asm, []> {
6737 let Inst{18-16} = imm{2-0};
6738 }
6739
6740 def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?},
6741 FPR16, FPR16, vecshiftL16, asm, []> {
6742 let Inst{19-16} = imm{3-0};
6743 }
6744
6745 def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?},
6746 FPR32, FPR32, vecshiftL32, asm,
6747 [(set (i32 FPR32:$Rd), (OpNode (i32 FPR32:$Rn), (i32 vecshiftL32:$imm)))]> {
6748 let Inst{20-16} = imm{4-0};
6749 }
6750
6751 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?},
6752 FPR64, FPR64, vecshiftL64, asm,
6753 [(set (v1i64 FPR64:$Rd), (OpNode (v1i64 FPR64:$Rn),
6754 (i32 vecshiftL64:$imm)))]> {
6755 let Inst{21-16} = imm{5-0};
6756 }
6757}
6758
6759multiclass SIMDScalarRShiftBHSD<bit U, bits<5> opc, string asm> {
6760 def b : BaseSIMDScalarShift<U, opc, {0,0,0,1,?,?,?},
6761 FPR8, FPR8, vecshiftR8, asm, []> {
6762 let Inst{18-16} = imm{2-0};
6763 }
6764
6765 def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?},
6766 FPR16, FPR16, vecshiftR16, asm, []> {
6767 let Inst{19-16} = imm{3-0};
6768 }
6769
6770 def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?},
6771 FPR32, FPR32, vecshiftR32, asm, []> {
6772 let Inst{20-16} = imm{4-0};
6773 }
6774
6775 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?},
6776 FPR64, FPR64, vecshiftR64, asm, []> {
6777 let Inst{21-16} = imm{5-0};
6778 }
6779}
6780
6781//----------------------------------------------------------------------------
6782// AdvSIMD vector x indexed element
6783//----------------------------------------------------------------------------
6784
6785let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
6786class BaseSIMDVectorShift<bit Q, bit U, bits<5> opc, bits<7> fixed_imm,
6787 RegisterOperand dst_reg, RegisterOperand src_reg,
6788 Operand immtype,
6789 string asm, string dst_kind, string src_kind,
6790 list<dag> pattern>
6791 : I<(outs dst_reg:$Rd), (ins src_reg:$Rn, immtype:$imm),
6792 asm, "{\t$Rd" # dst_kind # ", $Rn" # src_kind # ", $imm" #
6793 "|" # dst_kind # "\t$Rd, $Rn, $imm}", "", pattern>,
6794 Sched<[WriteV]> {
6795 bits<5> Rd;
6796 bits<5> Rn;
6797 let Inst{31} = 0;
6798 let Inst{30} = Q;
6799 let Inst{29} = U;
6800 let Inst{28-23} = 0b011110;
6801 let Inst{22-16} = fixed_imm;
6802 let Inst{15-11} = opc;
6803 let Inst{10} = 1;
6804 let Inst{9-5} = Rn;
6805 let Inst{4-0} = Rd;
6806}
6807
6808let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
6809class BaseSIMDVectorShiftTied<bit Q, bit U, bits<5> opc, bits<7> fixed_imm,
6810 RegisterOperand vectype1, RegisterOperand vectype2,
6811 Operand immtype,
6812 string asm, string dst_kind, string src_kind,
6813 list<dag> pattern>
6814 : I<(outs vectype1:$dst), (ins vectype1:$Rd, vectype2:$Rn, immtype:$imm),
6815 asm, "{\t$Rd" # dst_kind # ", $Rn" # src_kind # ", $imm" #
6816 "|" # dst_kind # "\t$Rd, $Rn, $imm}", "$Rd = $dst", pattern>,
6817 Sched<[WriteV]> {
6818 bits<5> Rd;
6819 bits<5> Rn;
6820 let Inst{31} = 0;
6821 let Inst{30} = Q;
6822 let Inst{29} = U;
6823 let Inst{28-23} = 0b011110;
6824 let Inst{22-16} = fixed_imm;
6825 let Inst{15-11} = opc;
6826 let Inst{10} = 1;
6827 let Inst{9-5} = Rn;
6828 let Inst{4-0} = Rd;
6829}
6830
6831multiclass SIMDVectorRShiftSD<bit U, bits<5> opc, string asm,
6832 Intrinsic OpNode> {
6833 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?},
6834 V64, V64, vecshiftR32,
6835 asm, ".2s", ".2s",
6836 [(set (v2i32 V64:$Rd), (OpNode (v2f32 V64:$Rn), (i32 imm:$imm)))]> {
6837 bits<5> imm;
6838 let Inst{20-16} = imm;
6839 }
6840
6841 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?},
6842 V128, V128, vecshiftR32,
6843 asm, ".4s", ".4s",
6844 [(set (v4i32 V128:$Rd), (OpNode (v4f32 V128:$Rn), (i32 imm:$imm)))]> {
6845 bits<5> imm;
6846 let Inst{20-16} = imm;
6847 }
6848
6849 def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?},
6850 V128, V128, vecshiftR64,
6851 asm, ".2d", ".2d",
6852 [(set (v2i64 V128:$Rd), (OpNode (v2f64 V128:$Rn), (i32 imm:$imm)))]> {
6853 bits<6> imm;
6854 let Inst{21-16} = imm;
6855 }
6856}
6857
6858multiclass SIMDVectorRShiftSDToFP<bit U, bits<5> opc, string asm,
6859 Intrinsic OpNode> {
6860 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?},
6861 V64, V64, vecshiftR32,
6862 asm, ".2s", ".2s",
6863 [(set (v2f32 V64:$Rd), (OpNode (v2i32 V64:$Rn), (i32 imm:$imm)))]> {
6864 bits<5> imm;
6865 let Inst{20-16} = imm;
6866 }
6867
6868 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?},
6869 V128, V128, vecshiftR32,
6870 asm, ".4s", ".4s",
6871 [(set (v4f32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (i32 imm:$imm)))]> {
6872 bits<5> imm;
6873 let Inst{20-16} = imm;
6874 }
6875
6876 def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?},
6877 V128, V128, vecshiftR64,
6878 asm, ".2d", ".2d",
6879 [(set (v2f64 V128:$Rd), (OpNode (v2i64 V128:$Rn), (i32 imm:$imm)))]> {
6880 bits<6> imm;
6881 let Inst{21-16} = imm;
6882 }
6883}
6884
6885multiclass SIMDVectorRShiftNarrowBHS<bit U, bits<5> opc, string asm,
6886 SDPatternOperator OpNode> {
6887 def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?},
6888 V64, V128, vecshiftR16Narrow,
6889 asm, ".8b", ".8h",
6890 [(set (v8i8 V64:$Rd), (OpNode (v8i16 V128:$Rn), vecshiftR16Narrow:$imm))]> {
6891 bits<3> imm;
6892 let Inst{18-16} = imm;
6893 }
6894
6895 def v16i8_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,0,1,?,?,?},
6896 V128, V128, vecshiftR16Narrow,
6897 asm#"2", ".16b", ".8h", []> {
6898 bits<3> imm;
6899 let Inst{18-16} = imm;
6900 let hasSideEffects = 0;
6901 }
6902
6903 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?},
6904 V64, V128, vecshiftR32Narrow,
6905 asm, ".4h", ".4s",
6906 [(set (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn), vecshiftR32Narrow:$imm))]> {
6907 bits<4> imm;
6908 let Inst{19-16} = imm;
6909 }
6910
6911 def v8i16_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,1,?,?,?,?},
6912 V128, V128, vecshiftR32Narrow,
6913 asm#"2", ".8h", ".4s", []> {
6914 bits<4> imm;
6915 let Inst{19-16} = imm;
6916 let hasSideEffects = 0;
6917 }
6918
6919 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?},
6920 V64, V128, vecshiftR64Narrow,
6921 asm, ".2s", ".2d",
6922 [(set (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn), vecshiftR64Narrow:$imm))]> {
6923 bits<5> imm;
6924 let Inst{20-16} = imm;
6925 }
6926
6927 def v4i32_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,1,?,?,?,?,?},
6928 V128, V128, vecshiftR64Narrow,
6929 asm#"2", ".4s", ".2d", []> {
6930 bits<5> imm;
6931 let Inst{20-16} = imm;
6932 let hasSideEffects = 0;
6933 }
6934
6935 // TableGen doesn't like patters w/ INSERT_SUBREG on the instructions
6936 // themselves, so put them here instead.
6937
6938 // Patterns involving what's effectively an insert high and a normal
6939 // intrinsic, represented by CONCAT_VECTORS.
6940 def : Pat<(concat_vectors (v8i8 V64:$Rd),(OpNode (v8i16 V128:$Rn),
6941 vecshiftR16Narrow:$imm)),
6942 (!cast<Instruction>(NAME # "v16i8_shift")
6943 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub),
6944 V128:$Rn, vecshiftR16Narrow:$imm)>;
6945 def : Pat<(concat_vectors (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn),
6946 vecshiftR32Narrow:$imm)),
6947 (!cast<Instruction>(NAME # "v8i16_shift")
6948 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub),
6949 V128:$Rn, vecshiftR32Narrow:$imm)>;
6950 def : Pat<(concat_vectors (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn),
6951 vecshiftR64Narrow:$imm)),
6952 (!cast<Instruction>(NAME # "v4i32_shift")
6953 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub),
6954 V128:$Rn, vecshiftR64Narrow:$imm)>;
6955}
6956
6957multiclass SIMDVectorLShiftBHSD<bit U, bits<5> opc, string asm,
6958 SDPatternOperator OpNode> {
6959 def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?},
6960 V64, V64, vecshiftL8,
6961 asm, ".8b", ".8b",
6962 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn),
6963 (i32 vecshiftL8:$imm)))]> {
6964 bits<3> imm;
6965 let Inst{18-16} = imm;
6966 }
6967
6968 def v16i8_shift : BaseSIMDVectorShift<1, U, opc, {0,0,0,1,?,?,?},
6969 V128, V128, vecshiftL8,
6970 asm, ".16b", ".16b",
6971 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn),
6972 (i32 vecshiftL8:$imm)))]> {
6973 bits<3> imm;
6974 let Inst{18-16} = imm;
6975 }
6976
6977 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?},
6978 V64, V64, vecshiftL16,
6979 asm, ".4h", ".4h",
6980 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn),
6981 (i32 vecshiftL16:$imm)))]> {
6982 bits<4> imm;
6983 let Inst{19-16} = imm;
6984 }
6985
6986 def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?},
6987 V128, V128, vecshiftL16,
6988 asm, ".8h", ".8h",
6989 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn),
6990 (i32 vecshiftL16:$imm)))]> {
6991 bits<4> imm;
6992 let Inst{19-16} = imm;
6993 }
6994
6995 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?},
6996 V64, V64, vecshiftL32,
6997 asm, ".2s", ".2s",
6998 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn),
6999 (i32 vecshiftL32:$imm)))]> {
7000 bits<5> imm;
7001 let Inst{20-16} = imm;
7002 }
7003
7004 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?},
7005 V128, V128, vecshiftL32,
7006 asm, ".4s", ".4s",
7007 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn),
7008 (i32 vecshiftL32:$imm)))]> {
7009 bits<5> imm;
7010 let Inst{20-16} = imm;
7011 }
7012
7013 def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?},
7014 V128, V128, vecshiftL64,
7015 asm, ".2d", ".2d",
7016 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn),
7017 (i32 vecshiftL64:$imm)))]> {
7018 bits<6> imm;
7019 let Inst{21-16} = imm;
7020 }
7021}
7022
7023multiclass SIMDVectorRShiftBHSD<bit U, bits<5> opc, string asm,
7024 SDPatternOperator OpNode> {
7025 def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?},
7026 V64, V64, vecshiftR8,
7027 asm, ".8b", ".8b",
7028 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn),
7029 (i32 vecshiftR8:$imm)))]> {
7030 bits<3> imm;
7031 let Inst{18-16} = imm;
7032 }
7033
7034 def v16i8_shift : BaseSIMDVectorShift<1, U, opc, {0,0,0,1,?,?,?},
7035 V128, V128, vecshiftR8,
7036 asm, ".16b", ".16b",
7037 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn),
7038 (i32 vecshiftR8:$imm)))]> {
7039 bits<3> imm;
7040 let Inst{18-16} = imm;
7041 }
7042
7043 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?},
7044 V64, V64, vecshiftR16,
7045 asm, ".4h", ".4h",
7046 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn),
7047 (i32 vecshiftR16:$imm)))]> {
7048 bits<4> imm;
7049 let Inst{19-16} = imm;
7050 }
7051
7052 def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?},
7053 V128, V128, vecshiftR16,
7054 asm, ".8h", ".8h",
7055 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn),
7056 (i32 vecshiftR16:$imm)))]> {
7057 bits<4> imm;
7058 let Inst{19-16} = imm;
7059 }
7060
7061 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?},
7062 V64, V64, vecshiftR32,
7063 asm, ".2s", ".2s",
7064 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn),
7065 (i32 vecshiftR32:$imm)))]> {
7066 bits<5> imm;
7067 let Inst{20-16} = imm;
7068 }
7069
7070 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?},
7071 V128, V128, vecshiftR32,
7072 asm, ".4s", ".4s",
7073 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn),
7074 (i32 vecshiftR32:$imm)))]> {
7075 bits<5> imm;
7076 let Inst{20-16} = imm;
7077 }
7078
7079 def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?},
7080 V128, V128, vecshiftR64,
7081 asm, ".2d", ".2d",
7082 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn),
7083 (i32 vecshiftR64:$imm)))]> {
7084 bits<6> imm;
7085 let Inst{21-16} = imm;
7086 }
7087}
7088
7089let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
7090multiclass SIMDVectorRShiftBHSDTied<bit U, bits<5> opc, string asm,
7091 SDPatternOperator OpNode = null_frag> {
7092 def v8i8_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,0,1,?,?,?},
7093 V64, V64, vecshiftR8, asm, ".8b", ".8b",
7094 [(set (v8i8 V64:$dst),
7095 (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn),
7096 (i32 vecshiftR8:$imm)))]> {
7097 bits<3> imm;
7098 let Inst{18-16} = imm;
7099 }
7100
7101 def v16i8_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,0,1,?,?,?},
7102 V128, V128, vecshiftR8, asm, ".16b", ".16b",
7103 [(set (v16i8 V128:$dst),
7104 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn),
7105 (i32 vecshiftR8:$imm)))]> {
7106 bits<3> imm;
7107 let Inst{18-16} = imm;
7108 }
7109
7110 def v4i16_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,1,?,?,?,?},
7111 V64, V64, vecshiftR16, asm, ".4h", ".4h",
7112 [(set (v4i16 V64:$dst),
7113 (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn),
7114 (i32 vecshiftR16:$imm)))]> {
7115 bits<4> imm;
7116 let Inst{19-16} = imm;
7117 }
7118
7119 def v8i16_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,1,?,?,?,?},
7120 V128, V128, vecshiftR16, asm, ".8h", ".8h",
7121 [(set (v8i16 V128:$dst),
7122 (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn),
7123 (i32 vecshiftR16:$imm)))]> {
7124 bits<4> imm;
7125 let Inst{19-16} = imm;
7126 }
7127
7128 def v2i32_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,1,?,?,?,?,?},
7129 V64, V64, vecshiftR32, asm, ".2s", ".2s",
7130 [(set (v2i32 V64:$dst),
7131 (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn),
7132 (i32 vecshiftR32:$imm)))]> {
7133 bits<5> imm;
7134 let Inst{20-16} = imm;
7135 }
7136
7137 def v4i32_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,1,?,?,?,?,?},
7138 V128, V128, vecshiftR32, asm, ".4s", ".4s",
7139 [(set (v4i32 V128:$dst),
7140 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn),
7141 (i32 vecshiftR32:$imm)))]> {
7142 bits<5> imm;
7143 let Inst{20-16} = imm;
7144 }
7145
7146 def v2i64_shift : BaseSIMDVectorShiftTied<1, U, opc, {1,?,?,?,?,?,?},
7147 V128, V128, vecshiftR64,
7148 asm, ".2d", ".2d", [(set (v2i64 V128:$dst),
7149 (OpNode (v2i64 V128:$Rd), (v2i64 V128:$Rn),
7150 (i32 vecshiftR64:$imm)))]> {
7151 bits<6> imm;
7152 let Inst{21-16} = imm;
7153 }
7154}
7155
7156multiclass SIMDVectorLShiftBHSDTied<bit U, bits<5> opc, string asm,
7157 SDPatternOperator OpNode = null_frag> {
7158 def v8i8_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,0,1,?,?,?},
7159 V64, V64, vecshiftL8,
7160 asm, ".8b", ".8b",
7161 [(set (v8i8 V64:$dst),
7162 (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn),
7163 (i32 vecshiftL8:$imm)))]> {
7164 bits<3> imm;
7165 let Inst{18-16} = imm;
7166 }
7167
7168 def v16i8_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,0,1,?,?,?},
7169 V128, V128, vecshiftL8,
7170 asm, ".16b", ".16b",
7171 [(set (v16i8 V128:$dst),
7172 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn),
7173 (i32 vecshiftL8:$imm)))]> {
7174 bits<3> imm;
7175 let Inst{18-16} = imm;
7176 }
7177
7178 def v4i16_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,1,?,?,?,?},
7179 V64, V64, vecshiftL16,
7180 asm, ".4h", ".4h",
7181 [(set (v4i16 V64:$dst),
7182 (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn),
7183 (i32 vecshiftL16:$imm)))]> {
7184 bits<4> imm;
7185 let Inst{19-16} = imm;
7186 }
7187
7188 def v8i16_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,1,?,?,?,?},
7189 V128, V128, vecshiftL16,
7190 asm, ".8h", ".8h",
7191 [(set (v8i16 V128:$dst),
7192 (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn),
7193 (i32 vecshiftL16:$imm)))]> {
7194 bits<4> imm;
7195 let Inst{19-16} = imm;
7196 }
7197
7198 def v2i32_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,1,?,?,?,?,?},
7199 V64, V64, vecshiftL32,
7200 asm, ".2s", ".2s",
7201 [(set (v2i32 V64:$dst),
7202 (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn),
7203 (i32 vecshiftL32:$imm)))]> {
7204 bits<5> imm;
7205 let Inst{20-16} = imm;
7206 }
7207
7208 def v4i32_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,1,?,?,?,?,?},
7209 V128, V128, vecshiftL32,
7210 asm, ".4s", ".4s",
7211 [(set (v4i32 V128:$dst),
7212 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn),
7213 (i32 vecshiftL32:$imm)))]> {
7214 bits<5> imm;
7215 let Inst{20-16} = imm;
7216 }
7217
7218 def v2i64_shift : BaseSIMDVectorShiftTied<1, U, opc, {1,?,?,?,?,?,?},
7219 V128, V128, vecshiftL64,
7220 asm, ".2d", ".2d",
7221 [(set (v2i64 V128:$dst),
7222 (OpNode (v2i64 V128:$Rd), (v2i64 V128:$Rn),
7223 (i32 vecshiftL64:$imm)))]> {
7224 bits<6> imm;
7225 let Inst{21-16} = imm;
7226 }
7227}
7228
7229multiclass SIMDVectorLShiftLongBHSD<bit U, bits<5> opc, string asm,
7230 SDPatternOperator OpNode> {
7231 def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?},
7232 V128, V64, vecshiftL8, asm, ".8h", ".8b",
7233 [(set (v8i16 V128:$Rd), (OpNode (v8i8 V64:$Rn), vecshiftL8:$imm))]> {
7234 bits<3> imm;
7235 let Inst{18-16} = imm;
7236 }
7237
7238 def v16i8_shift : BaseSIMDVectorShift<1, U, opc, {0,0,0,1,?,?,?},
7239 V128, V128, vecshiftL8,
7240 asm#"2", ".8h", ".16b",
7241 [(set (v8i16 V128:$Rd),
7242 (OpNode (extract_high_v16i8 V128:$Rn), vecshiftL8:$imm))]> {
7243 bits<3> imm;
7244 let Inst{18-16} = imm;
7245 }
7246
7247 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?},
7248 V128, V64, vecshiftL16, asm, ".4s", ".4h",
7249 [(set (v4i32 V128:$Rd), (OpNode (v4i16 V64:$Rn), vecshiftL16:$imm))]> {
7250 bits<4> imm;
7251 let Inst{19-16} = imm;
7252 }
7253
7254 def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?},
7255 V128, V128, vecshiftL16,
7256 asm#"2", ".4s", ".8h",
7257 [(set (v4i32 V128:$Rd),
7258 (OpNode (extract_high_v8i16 V128:$Rn), vecshiftL16:$imm))]> {
7259
7260 bits<4> imm;
7261 let Inst{19-16} = imm;
7262 }
7263
7264 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?},
7265 V128, V64, vecshiftL32, asm, ".2d", ".2s",
7266 [(set (v2i64 V128:$Rd), (OpNode (v2i32 V64:$Rn), vecshiftL32:$imm))]> {
7267 bits<5> imm;
7268 let Inst{20-16} = imm;
7269 }
7270
7271 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?},
7272 V128, V128, vecshiftL32,
7273 asm#"2", ".2d", ".4s",
7274 [(set (v2i64 V128:$Rd),
7275 (OpNode (extract_high_v4i32 V128:$Rn), vecshiftL32:$imm))]> {
7276 bits<5> imm;
7277 let Inst{20-16} = imm;
7278 }
7279}
7280
7281
7282//---
7283// Vector load/store
7284//---
7285// SIMD ldX/stX no-index memory references don't allow the optional
7286// ", #0" constant and handle post-indexing explicitly, so we use
7287// a more specialized parse method for them. Otherwise, it's the same as
7288// the general am_noindex handling.
7289def MemorySIMDNoIndexOperand : AsmOperandClass {
7290 let Name = "MemorySIMDNoIndex";
7291 let ParserMethod = "tryParseNoIndexMemory";
7292}
7293def am_simdnoindex : Operand<i64>,
7294 ComplexPattern<i64, 1, "SelectAddrModeNoIndex", []> {
7295 let PrintMethod = "printAMNoIndex";
7296 let ParserMatchClass = MemorySIMDNoIndexOperand;
7297 let MIOperandInfo = (ops GPR64sp:$base);
7298 let DecoderMethod = "DecodeGPR64spRegisterClass";
7299}
7300
7301class BaseSIMDLdSt<bit Q, bit L, bits<4> opcode, bits<2> size,
7302 string asm, dag oops, dag iops, list<dag> pattern>
7303 : I<oops, iops, asm, "\t$Vt, $vaddr", "", pattern> {
7304 bits<5> Vt;
7305 bits<5> vaddr;
7306 let Inst{31} = 0;
7307 let Inst{30} = Q;
7308 let Inst{29-23} = 0b0011000;
7309 let Inst{22} = L;
7310 let Inst{21-16} = 0b000000;
7311 let Inst{15-12} = opcode;
7312 let Inst{11-10} = size;
7313 let Inst{9-5} = vaddr;
7314 let Inst{4-0} = Vt;
7315}
7316
7317class BaseSIMDLdStPost<bit Q, bit L, bits<4> opcode, bits<2> size,
7318 string asm, dag oops, dag iops>
7319 : I<oops, iops, asm, "\t$Vt, $vaddr, $Xm", "", []> {
7320 bits<5> Vt;
7321 bits<5> vaddr;
7322 bits<5> Xm;
7323 let Inst{31} = 0;
7324 let Inst{30} = Q;
7325 let Inst{29-23} = 0b0011001;
7326 let Inst{22} = L;
7327 let Inst{21} = 0;
7328 let Inst{20-16} = Xm;
7329 let Inst{15-12} = opcode;
7330 let Inst{11-10} = size;
7331 let Inst{9-5} = vaddr;
7332 let Inst{4-0} = Vt;
7333 let DecoderMethod = "DecodeSIMDLdStPost";
7334}
7335
7336// The immediate form of AdvSIMD post-indexed addressing is encoded with
7337// register post-index addressing from the zero register.
7338multiclass SIMDLdStAliases<string asm, string layout, string Count,
7339 int Offset, int Size> {
7340 // E.g. "ld1 { v0.8b, v1.8b }, [x1], #16"
7341 // "ld1\t$Vt, $vaddr, #16"
7342 // may get mapped to
7343 // (LD1Twov8b_POST VecListTwo8b:$Vt, am_simdnoindex:$vaddr, XZR)
7344 def : InstAlias<asm # "\t$Vt, $vaddr, #" # Offset,
7345 (!cast<Instruction>(NAME # Count # "v" # layout # "_POST")
7346 !cast<RegisterOperand>("VecList" # Count # layout):$Vt,
7347 am_simdnoindex:$vaddr, XZR), 1>;
7348
7349 // E.g. "ld1.8b { v0, v1 }, [x1], #16"
7350 // "ld1.8b\t$Vt, $vaddr, #16"
7351 // may get mapped to
7352 // (LD1Twov8b_POST VecListTwo64:$Vt, am_simdnoindex:$vaddr, XZR)
7353 def : InstAlias<asm # "." # layout # "\t$Vt, $vaddr, #" # Offset,
7354 (!cast<Instruction>(NAME # Count # "v" # layout # "_POST")
7355 !cast<RegisterOperand>("VecList" # Count # Size):$Vt,
7356 am_simdnoindex:$vaddr, XZR), 0>;
7357
7358 // E.g. "ld1.8b { v0, v1 }, [x1]"
7359 // "ld1\t$Vt, $vaddr"
7360 // may get mapped to
7361 // (LD1Twov8b VecListTwo64:$Vt, am_simdnoindex:$vaddr)
7362 def : InstAlias<asm # "." # layout # "\t$Vt, $vaddr",
7363 (!cast<Instruction>(NAME # Count # "v" # layout)
7364 !cast<RegisterOperand>("VecList" # Count # Size):$Vt,
7365 am_simdnoindex:$vaddr), 0>;
7366
7367 // E.g. "ld1.8b { v0, v1 }, [x1], x2"
7368 // "ld1\t$Vt, $vaddr, $Xm"
7369 // may get mapped to
7370 // (LD1Twov8b_POST VecListTwo64:$Vt, am_simdnoindex:$vaddr, GPR64pi8:$Xm)
7371 def : InstAlias<asm # "." # layout # "\t$Vt, $vaddr, $Xm",
7372 (!cast<Instruction>(NAME # Count # "v" # layout # "_POST")
7373 !cast<RegisterOperand>("VecList" # Count # Size):$Vt,
7374 am_simdnoindex:$vaddr,
7375 !cast<RegisterOperand>("GPR64pi" # Offset):$Xm), 0>;
7376}
7377
7378multiclass BaseSIMDLdN<string Count, string asm, string veclist, int Offset128,
7379 int Offset64, bits<4> opcode> {
7380 let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in {
7381 def v16b: BaseSIMDLdSt<1, 1, opcode, 0b00, asm,
7382 (outs !cast<RegisterOperand>(veclist # "16b"):$Vt),
7383 (ins am_simdnoindex:$vaddr), []>;
7384 def v8h : BaseSIMDLdSt<1, 1, opcode, 0b01, asm,
7385 (outs !cast<RegisterOperand>(veclist # "8h"):$Vt),
7386 (ins am_simdnoindex:$vaddr), []>;
7387 def v4s : BaseSIMDLdSt<1, 1, opcode, 0b10, asm,
7388 (outs !cast<RegisterOperand>(veclist # "4s"):$Vt),
7389 (ins am_simdnoindex:$vaddr), []>;
7390 def v2d : BaseSIMDLdSt<1, 1, opcode, 0b11, asm,
7391 (outs !cast<RegisterOperand>(veclist # "2d"):$Vt),
7392 (ins am_simdnoindex:$vaddr), []>;
7393 def v8b : BaseSIMDLdSt<0, 1, opcode, 0b00, asm,
7394 (outs !cast<RegisterOperand>(veclist # "8b"):$Vt),
7395 (ins am_simdnoindex:$vaddr), []>;
7396 def v4h : BaseSIMDLdSt<0, 1, opcode, 0b01, asm,
7397 (outs !cast<RegisterOperand>(veclist # "4h"):$Vt),
7398 (ins am_simdnoindex:$vaddr), []>;
7399 def v2s : BaseSIMDLdSt<0, 1, opcode, 0b10, asm,
7400 (outs !cast<RegisterOperand>(veclist # "2s"):$Vt),
7401 (ins am_simdnoindex:$vaddr), []>;
7402
7403
7404 def v16b_POST: BaseSIMDLdStPost<1, 1, opcode, 0b00, asm,
7405 (outs !cast<RegisterOperand>(veclist # "16b"):$Vt),
7406 (ins am_simdnoindex:$vaddr,
7407 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
7408 def v8h_POST : BaseSIMDLdStPost<1, 1, opcode, 0b01, asm,
7409 (outs !cast<RegisterOperand>(veclist # "8h"):$Vt),
7410 (ins am_simdnoindex:$vaddr,
7411 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
7412 def v4s_POST : BaseSIMDLdStPost<1, 1, opcode, 0b10, asm,
7413 (outs !cast<RegisterOperand>(veclist # "4s"):$Vt),
7414 (ins am_simdnoindex:$vaddr,
7415 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
7416 def v2d_POST : BaseSIMDLdStPost<1, 1, opcode, 0b11, asm,
7417 (outs !cast<RegisterOperand>(veclist # "2d"):$Vt),
7418 (ins am_simdnoindex:$vaddr,
7419 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
7420 def v8b_POST : BaseSIMDLdStPost<0, 1, opcode, 0b00, asm,
7421 (outs !cast<RegisterOperand>(veclist # "8b"):$Vt),
7422 (ins am_simdnoindex:$vaddr,
7423 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
7424 def v4h_POST : BaseSIMDLdStPost<0, 1, opcode, 0b01, asm,
7425 (outs !cast<RegisterOperand>(veclist # "4h"):$Vt),
7426 (ins am_simdnoindex:$vaddr,
7427 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
7428 def v2s_POST : BaseSIMDLdStPost<0, 1, opcode, 0b10, asm,
7429 (outs !cast<RegisterOperand>(veclist # "2s"):$Vt),
7430 (ins am_simdnoindex:$vaddr,
7431 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
7432 }
7433
7434 defm : SIMDLdStAliases<asm, "16b", Count, Offset128, 128>;
7435 defm : SIMDLdStAliases<asm, "8h", Count, Offset128, 128>;
7436 defm : SIMDLdStAliases<asm, "4s", Count, Offset128, 128>;
7437 defm : SIMDLdStAliases<asm, "2d", Count, Offset128, 128>;
7438 defm : SIMDLdStAliases<asm, "8b", Count, Offset64, 64>;
7439 defm : SIMDLdStAliases<asm, "4h", Count, Offset64, 64>;
7440 defm : SIMDLdStAliases<asm, "2s", Count, Offset64, 64>;
7441}
7442
7443// Only ld1/st1 has a v1d version.
7444multiclass BaseSIMDStN<string Count, string asm, string veclist, int Offset128,
7445 int Offset64, bits<4> opcode> {
7446 let hasSideEffects = 0, mayStore = 1, mayLoad = 0 in {
7447 def v16b : BaseSIMDLdSt<1, 0, opcode, 0b00, asm, (outs),
7448 (ins !cast<RegisterOperand>(veclist # "16b"):$Vt,
7449 am_simdnoindex:$vaddr), []>;
7450 def v8h : BaseSIMDLdSt<1, 0, opcode, 0b01, asm, (outs),
7451 (ins !cast<RegisterOperand>(veclist # "8h"):$Vt,
7452 am_simdnoindex:$vaddr), []>;
7453 def v4s : BaseSIMDLdSt<1, 0, opcode, 0b10, asm, (outs),
7454 (ins !cast<RegisterOperand>(veclist # "4s"):$Vt,
7455 am_simdnoindex:$vaddr), []>;
7456 def v2d : BaseSIMDLdSt<1, 0, opcode, 0b11, asm, (outs),
7457 (ins !cast<RegisterOperand>(veclist # "2d"):$Vt,
7458 am_simdnoindex:$vaddr), []>;
7459 def v8b : BaseSIMDLdSt<0, 0, opcode, 0b00, asm, (outs),
7460 (ins !cast<RegisterOperand>(veclist # "8b"):$Vt,
7461 am_simdnoindex:$vaddr), []>;
7462 def v4h : BaseSIMDLdSt<0, 0, opcode, 0b01, asm, (outs),
7463 (ins !cast<RegisterOperand>(veclist # "4h"):$Vt,
7464 am_simdnoindex:$vaddr), []>;
7465 def v2s : BaseSIMDLdSt<0, 0, opcode, 0b10, asm, (outs),
7466 (ins !cast<RegisterOperand>(veclist # "2s"):$Vt,
7467 am_simdnoindex:$vaddr), []>;
7468
7469 def v16b_POST : BaseSIMDLdStPost<1, 0, opcode, 0b00, asm, (outs),
7470 (ins !cast<RegisterOperand>(veclist # "16b"):$Vt,
7471 am_simdnoindex:$vaddr,
7472 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
7473 def v8h_POST : BaseSIMDLdStPost<1, 0, opcode, 0b01, asm, (outs),
7474 (ins !cast<RegisterOperand>(veclist # "8h"):$Vt,
7475 am_simdnoindex:$vaddr,
7476 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
7477 def v4s_POST : BaseSIMDLdStPost<1, 0, opcode, 0b10, asm, (outs),
7478 (ins !cast<RegisterOperand>(veclist # "4s"):$Vt,
7479 am_simdnoindex:$vaddr,
7480 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
7481 def v2d_POST : BaseSIMDLdStPost<1, 0, opcode, 0b11, asm, (outs),
7482 (ins !cast<RegisterOperand>(veclist # "2d"):$Vt,
7483 am_simdnoindex:$vaddr,
7484 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
7485 def v8b_POST : BaseSIMDLdStPost<0, 0, opcode, 0b00, asm, (outs),
7486 (ins !cast<RegisterOperand>(veclist # "8b"):$Vt,
7487 am_simdnoindex:$vaddr,
7488 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
7489 def v4h_POST : BaseSIMDLdStPost<0, 0, opcode, 0b01, asm, (outs),
7490 (ins !cast<RegisterOperand>(veclist # "4h"):$Vt,
7491 am_simdnoindex:$vaddr,
7492 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
7493 def v2s_POST : BaseSIMDLdStPost<0, 0, opcode, 0b10, asm, (outs),
7494 (ins !cast<RegisterOperand>(veclist # "2s"):$Vt,
7495 am_simdnoindex:$vaddr,
7496 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
7497 }
7498
7499 defm : SIMDLdStAliases<asm, "16b", Count, Offset128, 128>;
7500 defm : SIMDLdStAliases<asm, "8h", Count, Offset128, 128>;
7501 defm : SIMDLdStAliases<asm, "4s", Count, Offset128, 128>;
7502 defm : SIMDLdStAliases<asm, "2d", Count, Offset128, 128>;
7503 defm : SIMDLdStAliases<asm, "8b", Count, Offset64, 64>;
7504 defm : SIMDLdStAliases<asm, "4h", Count, Offset64, 64>;
7505 defm : SIMDLdStAliases<asm, "2s", Count, Offset64, 64>;
7506}
7507
7508multiclass BaseSIMDLd1<string Count, string asm, string veclist,
7509 int Offset128, int Offset64, bits<4> opcode>
7510 : BaseSIMDLdN<Count, asm, veclist, Offset128, Offset64, opcode> {
7511
7512 // LD1 instructions have extra "1d" variants.
7513 let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in {
7514 def v1d : BaseSIMDLdSt<0, 1, opcode, 0b11, asm,
7515 (outs !cast<RegisterOperand>(veclist # "1d"):$Vt),
7516 (ins am_simdnoindex:$vaddr), []>;
7517
7518 def v1d_POST : BaseSIMDLdStPost<0, 1, opcode, 0b11, asm,
7519 (outs !cast<RegisterOperand>(veclist # "1d"):$Vt),
7520 (ins am_simdnoindex:$vaddr,
7521 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
7522 }
7523
7524 defm : SIMDLdStAliases<asm, "1d", Count, Offset64, 64>;
7525}
7526
7527multiclass BaseSIMDSt1<string Count, string asm, string veclist,
7528 int Offset128, int Offset64, bits<4> opcode>
7529 : BaseSIMDStN<Count, asm, veclist, Offset128, Offset64, opcode> {
7530
7531 // ST1 instructions have extra "1d" variants.
7532 let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in {
7533 def v1d : BaseSIMDLdSt<0, 0, opcode, 0b11, asm, (outs),
7534 (ins !cast<RegisterOperand>(veclist # "1d"):$Vt,
7535 am_simdnoindex:$vaddr), []>;
7536
7537 def v1d_POST : BaseSIMDLdStPost<0, 0, opcode, 0b11, asm, (outs),
7538 (ins !cast<RegisterOperand>(veclist # "1d"):$Vt,
7539 am_simdnoindex:$vaddr,
7540 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
7541 }
7542
7543 defm : SIMDLdStAliases<asm, "1d", Count, Offset64, 64>;
7544}
7545
7546multiclass SIMDLd1Multiple<string asm> {
7547 defm One : BaseSIMDLd1<"One", asm, "VecListOne", 16, 8, 0b0111>;
7548 defm Two : BaseSIMDLd1<"Two", asm, "VecListTwo", 32, 16, 0b1010>;
7549 defm Three : BaseSIMDLd1<"Three", asm, "VecListThree", 48, 24, 0b0110>;
7550 defm Four : BaseSIMDLd1<"Four", asm, "VecListFour", 64, 32, 0b0010>;
7551}
7552
7553multiclass SIMDSt1Multiple<string asm> {
7554 defm One : BaseSIMDSt1<"One", asm, "VecListOne", 16, 8, 0b0111>;
7555 defm Two : BaseSIMDSt1<"Two", asm, "VecListTwo", 32, 16, 0b1010>;
7556 defm Three : BaseSIMDSt1<"Three", asm, "VecListThree", 48, 24, 0b0110>;
7557 defm Four : BaseSIMDSt1<"Four", asm, "VecListFour", 64, 32, 0b0010>;
7558}
7559
7560multiclass SIMDLd2Multiple<string asm> {
7561 defm Two : BaseSIMDLdN<"Two", asm, "VecListTwo", 32, 16, 0b1000>;
7562}
7563
7564multiclass SIMDSt2Multiple<string asm> {
7565 defm Two : BaseSIMDStN<"Two", asm, "VecListTwo", 32, 16, 0b1000>;
7566}
7567
7568multiclass SIMDLd3Multiple<string asm> {
7569 defm Three : BaseSIMDLdN<"Three", asm, "VecListThree", 48, 24, 0b0100>;
7570}
7571
7572multiclass SIMDSt3Multiple<string asm> {
7573 defm Three : BaseSIMDStN<"Three", asm, "VecListThree", 48, 24, 0b0100>;
7574}
7575
7576multiclass SIMDLd4Multiple<string asm> {
7577 defm Four : BaseSIMDLdN<"Four", asm, "VecListFour", 64, 32, 0b0000>;
7578}
7579
7580multiclass SIMDSt4Multiple<string asm> {
7581 defm Four : BaseSIMDStN<"Four", asm, "VecListFour", 64, 32, 0b0000>;
7582}
7583
7584//---
7585// AdvSIMD Load/store single-element
7586//---
7587
7588class BaseSIMDLdStSingle<bit L, bit R, bits<3> opcode,
7589 string asm, string operands, dag oops, dag iops,
7590 list<dag> pattern>
7591 : I<oops, iops, asm, operands, "", pattern> {
7592 bits<5> Vt;
7593 bits<5> vaddr;
7594 let Inst{31} = 0;
7595 let Inst{29-24} = 0b001101;
7596 let Inst{22} = L;
7597 let Inst{21} = R;
7598 let Inst{15-13} = opcode;
7599 let Inst{9-5} = vaddr;
7600 let Inst{4-0} = Vt;
7601 let DecoderMethod = "DecodeSIMDLdStSingle";
7602}
7603
7604class BaseSIMDLdStSingleTied<bit L, bit R, bits<3> opcode,
7605 string asm, string operands, dag oops, dag iops,
7606 list<dag> pattern>
7607 : I<oops, iops, asm, operands, "$Vt = $dst", pattern> {
7608 bits<5> Vt;
7609 bits<5> vaddr;
7610 let Inst{31} = 0;
7611 let Inst{29-24} = 0b001101;
7612 let Inst{22} = L;
7613 let Inst{21} = R;
7614 let Inst{15-13} = opcode;
7615 let Inst{9-5} = vaddr;
7616 let Inst{4-0} = Vt;
7617 let DecoderMethod = "DecodeSIMDLdStSingleTied";
7618}
7619
7620
7621let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
7622class BaseSIMDLdR<bit Q, bit R, bits<3> opcode, bit S, bits<2> size, string asm,
7623 Operand listtype>
7624 : BaseSIMDLdStSingle<1, R, opcode, asm, "\t$Vt, $vaddr",
7625 (outs listtype:$Vt), (ins am_simdnoindex:$vaddr), []> {
7626 let Inst{30} = Q;
7627 let Inst{23} = 0;
7628 let Inst{20-16} = 0b00000;
7629 let Inst{12} = S;
7630 let Inst{11-10} = size;
7631}
7632let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
7633class BaseSIMDLdRPost<bit Q, bit R, bits<3> opcode, bit S, bits<2> size,
7634 string asm, Operand listtype, Operand GPR64pi>
7635 : BaseSIMDLdStSingle<1, R, opcode, asm, "\t$Vt, $vaddr, $Xm",
7636 (outs listtype:$Vt),
7637 (ins am_simdnoindex:$vaddr, GPR64pi:$Xm), []> {
7638 bits<5> Xm;
7639 let Inst{30} = Q;
7640 let Inst{23} = 1;
7641 let Inst{20-16} = Xm;
7642 let Inst{12} = S;
7643 let Inst{11-10} = size;
7644}
7645
7646multiclass SIMDLdrAliases<string asm, string layout, string Count,
7647 int Offset, int Size> {
7648 // E.g. "ld1r { v0.8b }, [x1], #1"
7649 // "ld1r.8b\t$Vt, $vaddr, #1"
7650 // may get mapped to
7651 // (LD1Rv8b_POST VecListOne8b:$Vt, am_simdnoindex:$vaddr, XZR)
7652 def : InstAlias<asm # "\t$Vt, $vaddr, #" # Offset,
7653 (!cast<Instruction>(NAME # "v" # layout # "_POST")
7654 !cast<RegisterOperand>("VecList" # Count # layout):$Vt,
7655 am_simdnoindex:$vaddr, XZR), 1>;
7656
7657 // E.g. "ld1r.8b { v0 }, [x1], #1"
7658 // "ld1r.8b\t$Vt, $vaddr, #1"
7659 // may get mapped to
7660 // (LD1Rv8b_POST VecListOne64:$Vt, am_simdnoindex:$vaddr, XZR)
7661 def : InstAlias<asm # "." # layout # "\t$Vt, $vaddr, #" # Offset,
7662 (!cast<Instruction>(NAME # "v" # layout # "_POST")
7663 !cast<RegisterOperand>("VecList" # Count # Size):$Vt,
7664 am_simdnoindex:$vaddr, XZR), 0>;
7665
7666 // E.g. "ld1r.8b { v0 }, [x1]"
7667 // "ld1r.8b\t$Vt, $vaddr"
7668 // may get mapped to
7669 // (LD1Rv8b VecListOne64:$Vt, am_simdnoindex:$vaddr)
7670 def : InstAlias<asm # "." # layout # "\t$Vt, $vaddr",
7671 (!cast<Instruction>(NAME # "v" # layout)
7672 !cast<RegisterOperand>("VecList" # Count # Size):$Vt,
7673 am_simdnoindex:$vaddr), 0>;
7674
7675 // E.g. "ld1r.8b { v0 }, [x1], x2"
7676 // "ld1r.8b\t$Vt, $vaddr, $Xm"
7677 // may get mapped to
7678 // (LD1Rv8b_POST VecListOne64:$Vt, am_simdnoindex:$vaddr, GPR64pi1:$Xm)
7679 def : InstAlias<asm # "." # layout # "\t$Vt, $vaddr, $Xm",
7680 (!cast<Instruction>(NAME # "v" # layout # "_POST")
7681 !cast<RegisterOperand>("VecList" # Count # Size):$Vt,
7682 am_simdnoindex:$vaddr,
7683 !cast<RegisterOperand>("GPR64pi" # Offset):$Xm), 0>;
7684}
7685
7686multiclass SIMDLdR<bit R, bits<3> opcode, bit S, string asm, string Count,
7687 int Offset1, int Offset2, int Offset4, int Offset8> {
7688 def v8b : BaseSIMDLdR<0, R, opcode, S, 0b00, asm,
7689 !cast<Operand>("VecList" # Count # "8b")>;
7690 def v16b: BaseSIMDLdR<1, R, opcode, S, 0b00, asm,
7691 !cast<Operand>("VecList" # Count #"16b")>;
7692 def v4h : BaseSIMDLdR<0, R, opcode, S, 0b01, asm,
7693 !cast<Operand>("VecList" # Count #"4h")>;
7694 def v8h : BaseSIMDLdR<1, R, opcode, S, 0b01, asm,
7695 !cast<Operand>("VecList" # Count #"8h")>;
7696 def v2s : BaseSIMDLdR<0, R, opcode, S, 0b10, asm,
7697 !cast<Operand>("VecList" # Count #"2s")>;
7698 def v4s : BaseSIMDLdR<1, R, opcode, S, 0b10, asm,
7699 !cast<Operand>("VecList" # Count #"4s")>;
7700 def v1d : BaseSIMDLdR<0, R, opcode, S, 0b11, asm,
7701 !cast<Operand>("VecList" # Count #"1d")>;
7702 def v2d : BaseSIMDLdR<1, R, opcode, S, 0b11, asm,
7703 !cast<Operand>("VecList" # Count #"2d")>;
7704
7705 def v8b_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b00, asm,
7706 !cast<Operand>("VecList" # Count # "8b"),
7707 !cast<Operand>("GPR64pi" # Offset1)>;
7708 def v16b_POST: BaseSIMDLdRPost<1, R, opcode, S, 0b00, asm,
7709 !cast<Operand>("VecList" # Count # "16b"),
7710 !cast<Operand>("GPR64pi" # Offset1)>;
7711 def v4h_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b01, asm,
7712 !cast<Operand>("VecList" # Count # "4h"),
7713 !cast<Operand>("GPR64pi" # Offset2)>;
7714 def v8h_POST : BaseSIMDLdRPost<1, R, opcode, S, 0b01, asm,
7715 !cast<Operand>("VecList" # Count # "8h"),
7716 !cast<Operand>("GPR64pi" # Offset2)>;
7717 def v2s_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b10, asm,
7718 !cast<Operand>("VecList" # Count # "2s"),
7719 !cast<Operand>("GPR64pi" # Offset4)>;
7720 def v4s_POST : BaseSIMDLdRPost<1, R, opcode, S, 0b10, asm,
7721 !cast<Operand>("VecList" # Count # "4s"),
7722 !cast<Operand>("GPR64pi" # Offset4)>;
7723 def v1d_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b11, asm,
7724 !cast<Operand>("VecList" # Count # "1d"),
7725 !cast<Operand>("GPR64pi" # Offset8)>;
7726 def v2d_POST : BaseSIMDLdRPost<1, R, opcode, S, 0b11, asm,
7727 !cast<Operand>("VecList" # Count # "2d"),
7728 !cast<Operand>("GPR64pi" # Offset8)>;
7729
7730 defm : SIMDLdrAliases<asm, "8b", Count, Offset1, 64>;
7731 defm : SIMDLdrAliases<asm, "16b", Count, Offset1, 128>;
7732 defm : SIMDLdrAliases<asm, "4h", Count, Offset2, 64>;
7733 defm : SIMDLdrAliases<asm, "8h", Count, Offset2, 128>;
7734 defm : SIMDLdrAliases<asm, "2s", Count, Offset4, 64>;
7735 defm : SIMDLdrAliases<asm, "4s", Count, Offset4, 128>;
7736 defm : SIMDLdrAliases<asm, "1d", Count, Offset8, 64>;
7737 defm : SIMDLdrAliases<asm, "2d", Count, Offset8, 128>;
7738}
7739
7740class SIMDLdStSingleB<bit L, bit R, bits<3> opcode, string asm,
7741 dag oops, dag iops, list<dag> pattern>
7742 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, $vaddr", oops, iops,
7743 pattern> {
7744 // idx encoded in Q:S:size fields.
7745 bits<4> idx;
7746 let Inst{30} = idx{3};
7747 let Inst{23} = 0;
7748 let Inst{20-16} = 0b00000;
7749 let Inst{12} = idx{2};
7750 let Inst{11-10} = idx{1-0};
7751}
7752class SIMDLdStSingleBTied<bit L, bit R, bits<3> opcode, string asm,
7753 dag oops, dag iops, list<dag> pattern>
7754 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, $vaddr", oops, iops,
7755 pattern> {
7756 // idx encoded in Q:S:size fields.
7757 bits<4> idx;
7758 let Inst{30} = idx{3};
7759 let Inst{23} = 0;
7760 let Inst{20-16} = 0b00000;
7761 let Inst{12} = idx{2};
7762 let Inst{11-10} = idx{1-0};
7763}
7764class SIMDLdStSingleBPost<bit L, bit R, bits<3> opcode, string asm,
7765 dag oops, dag iops>
7766 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, $vaddr, $Xm",
7767 oops, iops, []> {
7768 // idx encoded in Q:S:size fields.
7769 bits<4> idx;
7770 bits<5> Xm;
7771 let Inst{30} = idx{3};
7772 let Inst{23} = 1;
7773 let Inst{20-16} = Xm;
7774 let Inst{12} = idx{2};
7775 let Inst{11-10} = idx{1-0};
7776}
7777class SIMDLdStSingleBTiedPost<bit L, bit R, bits<3> opcode, string asm,
7778 dag oops, dag iops>
7779 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, $vaddr, $Xm",
7780 oops, iops, []> {
7781 // idx encoded in Q:S:size fields.
7782 bits<4> idx;
7783 bits<5> Xm;
7784 let Inst{30} = idx{3};
7785 let Inst{23} = 1;
7786 let Inst{20-16} = Xm;
7787 let Inst{12} = idx{2};
7788 let Inst{11-10} = idx{1-0};
7789}
7790
7791class SIMDLdStSingleH<bit L, bit R, bits<3> opcode, bit size, string asm,
7792 dag oops, dag iops, list<dag> pattern>
7793 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, $vaddr", oops, iops,
7794 pattern> {
7795 // idx encoded in Q:S:size<1> fields.
7796 bits<3> idx;
7797 let Inst{30} = idx{2};
7798 let Inst{23} = 0;
7799 let Inst{20-16} = 0b00000;
7800 let Inst{12} = idx{1};
7801 let Inst{11} = idx{0};
7802 let Inst{10} = size;
7803}
7804class SIMDLdStSingleHTied<bit L, bit R, bits<3> opcode, bit size, string asm,
7805 dag oops, dag iops, list<dag> pattern>
7806 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, $vaddr", oops, iops,
7807 pattern> {
7808 // idx encoded in Q:S:size<1> fields.
7809 bits<3> idx;
7810 let Inst{30} = idx{2};
7811 let Inst{23} = 0;
7812 let Inst{20-16} = 0b00000;
7813 let Inst{12} = idx{1};
7814 let Inst{11} = idx{0};
7815 let Inst{10} = size;
7816}
7817
7818class SIMDLdStSingleHPost<bit L, bit R, bits<3> opcode, bit size, string asm,
7819 dag oops, dag iops>
7820 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, $vaddr, $Xm",
7821 oops, iops, []> {
7822 // idx encoded in Q:S:size<1> fields.
7823 bits<3> idx;
7824 bits<5> Xm;
7825 let Inst{30} = idx{2};
7826 let Inst{23} = 1;
7827 let Inst{20-16} = Xm;
7828 let Inst{12} = idx{1};
7829 let Inst{11} = idx{0};
7830 let Inst{10} = size;
7831}
7832class SIMDLdStSingleHTiedPost<bit L, bit R, bits<3> opcode, bit size, string asm,
7833 dag oops, dag iops>
7834 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, $vaddr, $Xm",
7835 oops, iops, []> {
7836 // idx encoded in Q:S:size<1> fields.
7837 bits<3> idx;
7838 bits<5> Xm;
7839 let Inst{30} = idx{2};
7840 let Inst{23} = 1;
7841 let Inst{20-16} = Xm;
7842 let Inst{12} = idx{1};
7843 let Inst{11} = idx{0};
7844 let Inst{10} = size;
7845}
7846class SIMDLdStSingleS<bit L, bit R, bits<3> opcode, bits<2> size, string asm,
7847 dag oops, dag iops, list<dag> pattern>
7848 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, $vaddr", oops, iops,
7849 pattern> {
7850 // idx encoded in Q:S fields.
7851 bits<2> idx;
7852 let Inst{30} = idx{1};
7853 let Inst{23} = 0;
7854 let Inst{20-16} = 0b00000;
7855 let Inst{12} = idx{0};
7856 let Inst{11-10} = size;
7857}
7858class SIMDLdStSingleSTied<bit L, bit R, bits<3> opcode, bits<2> size, string asm,
7859 dag oops, dag iops, list<dag> pattern>
7860 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, $vaddr", oops, iops,
7861 pattern> {
7862 // idx encoded in Q:S fields.
7863 bits<2> idx;
7864 let Inst{30} = idx{1};
7865 let Inst{23} = 0;
7866 let Inst{20-16} = 0b00000;
7867 let Inst{12} = idx{0};
7868 let Inst{11-10} = size;
7869}
7870class SIMDLdStSingleSPost<bit L, bit R, bits<3> opcode, bits<2> size,
7871 string asm, dag oops, dag iops>
7872 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, $vaddr, $Xm",
7873 oops, iops, []> {
7874 // idx encoded in Q:S fields.
7875 bits<2> idx;
7876 bits<5> Xm;
7877 let Inst{30} = idx{1};
7878 let Inst{23} = 1;
7879 let Inst{20-16} = Xm;
7880 let Inst{12} = idx{0};
7881 let Inst{11-10} = size;
7882}
7883class SIMDLdStSingleSTiedPost<bit L, bit R, bits<3> opcode, bits<2> size,
7884 string asm, dag oops, dag iops>
7885 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, $vaddr, $Xm",
7886 oops, iops, []> {
7887 // idx encoded in Q:S fields.
7888 bits<2> idx;
7889 bits<5> Xm;
7890 let Inst{30} = idx{1};
7891 let Inst{23} = 1;
7892 let Inst{20-16} = Xm;
7893 let Inst{12} = idx{0};
7894 let Inst{11-10} = size;
7895}
7896class SIMDLdStSingleD<bit L, bit R, bits<3> opcode, bits<2> size, string asm,
7897 dag oops, dag iops, list<dag> pattern>
7898 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, $vaddr", oops, iops,
7899 pattern> {
7900 // idx encoded in Q field.
7901 bits<1> idx;
7902 let Inst{30} = idx;
7903 let Inst{23} = 0;
7904 let Inst{20-16} = 0b00000;
7905 let Inst{12} = 0;
7906 let Inst{11-10} = size;
7907}
7908class SIMDLdStSingleDTied<bit L, bit R, bits<3> opcode, bits<2> size, string asm,
7909 dag oops, dag iops, list<dag> pattern>
7910 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, $vaddr", oops, iops,
7911 pattern> {
7912 // idx encoded in Q field.
7913 bits<1> idx;
7914 let Inst{30} = idx;
7915 let Inst{23} = 0;
7916 let Inst{20-16} = 0b00000;
7917 let Inst{12} = 0;
7918 let Inst{11-10} = size;
7919}
7920class SIMDLdStSingleDPost<bit L, bit R, bits<3> opcode, bits<2> size,
7921 string asm, dag oops, dag iops>
7922 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, $vaddr, $Xm",
7923 oops, iops, []> {
7924 // idx encoded in Q field.
7925 bits<1> idx;
7926 bits<5> Xm;
7927 let Inst{30} = idx;
7928 let Inst{23} = 1;
7929 let Inst{20-16} = Xm;
7930 let Inst{12} = 0;
7931 let Inst{11-10} = size;
7932}
7933class SIMDLdStSingleDTiedPost<bit L, bit R, bits<3> opcode, bits<2> size,
7934 string asm, dag oops, dag iops>
7935 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, $vaddr, $Xm",
7936 oops, iops, []> {
7937 // idx encoded in Q field.
7938 bits<1> idx;
7939 bits<5> Xm;
7940 let Inst{30} = idx;
7941 let Inst{23} = 1;
7942 let Inst{20-16} = Xm;
7943 let Inst{12} = 0;
7944 let Inst{11-10} = size;
7945}
7946
7947let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
7948multiclass SIMDLdSingleBTied<bit R, bits<3> opcode, string asm,
7949 RegisterOperand listtype,
7950 RegisterOperand GPR64pi> {
7951 def i8 : SIMDLdStSingleBTied<1, R, opcode, asm,
7952 (outs listtype:$dst),
7953 (ins listtype:$Vt, VectorIndexB:$idx,
7954 am_simdnoindex:$vaddr), []>;
7955
7956 def i8_POST : SIMDLdStSingleBTiedPost<1, R, opcode, asm,
7957 (outs listtype:$dst),
7958 (ins listtype:$Vt, VectorIndexB:$idx,
7959 am_simdnoindex:$vaddr, GPR64pi:$Xm)>;
7960}
7961let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
7962multiclass SIMDLdSingleHTied<bit R, bits<3> opcode, bit size, string asm,
7963 RegisterOperand listtype,
7964 RegisterOperand GPR64pi> {
7965 def i16 : SIMDLdStSingleHTied<1, R, opcode, size, asm,
7966 (outs listtype:$dst),
7967 (ins listtype:$Vt, VectorIndexH:$idx,
7968 am_simdnoindex:$vaddr), []>;
7969
7970 def i16_POST : SIMDLdStSingleHTiedPost<1, R, opcode, size, asm,
7971 (outs listtype:$dst),
7972 (ins listtype:$Vt, VectorIndexH:$idx,
7973 am_simdnoindex:$vaddr, GPR64pi:$Xm)>;
7974}
7975let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
7976multiclass SIMDLdSingleSTied<bit R, bits<3> opcode, bits<2> size,string asm,
7977 RegisterOperand listtype,
7978 RegisterOperand GPR64pi> {
7979 def i32 : SIMDLdStSingleSTied<1, R, opcode, size, asm,
7980 (outs listtype:$dst),
7981 (ins listtype:$Vt, VectorIndexS:$idx,
7982 am_simdnoindex:$vaddr), []>;
7983
7984 def i32_POST : SIMDLdStSingleSTiedPost<1, R, opcode, size, asm,
7985 (outs listtype:$dst),
7986 (ins listtype:$Vt, VectorIndexS:$idx,
7987 am_simdnoindex:$vaddr, GPR64pi:$Xm)>;
7988}
7989let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
7990multiclass SIMDLdSingleDTied<bit R, bits<3> opcode, bits<2> size, string asm,
Tim Northoverff179ba2014-04-01 10:37:09 +00007991 RegisterOperand listtype, RegisterOperand GPR64pi> {
Tim Northover00ed9962014-03-29 10:18:08 +00007992 def i64 : SIMDLdStSingleDTied<1, R, opcode, size, asm,
7993 (outs listtype:$dst),
7994 (ins listtype:$Vt, VectorIndexD:$idx,
7995 am_simdnoindex:$vaddr), []>;
7996
7997 def i64_POST : SIMDLdStSingleDTiedPost<1, R, opcode, size, asm,
7998 (outs listtype:$dst),
7999 (ins listtype:$Vt, VectorIndexD:$idx,
8000 am_simdnoindex:$vaddr, GPR64pi:$Xm)>;
8001}
8002let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
8003multiclass SIMDStSingleB<bit R, bits<3> opcode, string asm,
Tim Northoverff179ba2014-04-01 10:37:09 +00008004 RegisterOperand listtype, RegisterOperand GPR64pi> {
Tim Northover00ed9962014-03-29 10:18:08 +00008005 def i8 : SIMDLdStSingleB<0, R, opcode, asm,
8006 (outs), (ins listtype:$Vt, VectorIndexB:$idx,
Tim Northoverff179ba2014-04-01 10:37:09 +00008007 am_simdnoindex:$vaddr), []>;
Tim Northover00ed9962014-03-29 10:18:08 +00008008
8009 def i8_POST : SIMDLdStSingleBPost<0, R, opcode, asm,
8010 (outs), (ins listtype:$Vt, VectorIndexB:$idx,
8011 am_simdnoindex:$vaddr, GPR64pi:$Xm)>;
8012}
8013let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
8014multiclass SIMDStSingleH<bit R, bits<3> opcode, bit size, string asm,
Tim Northoverff179ba2014-04-01 10:37:09 +00008015 RegisterOperand listtype, RegisterOperand GPR64pi> {
Tim Northover00ed9962014-03-29 10:18:08 +00008016 def i16 : SIMDLdStSingleH<0, R, opcode, size, asm,
8017 (outs), (ins listtype:$Vt, VectorIndexH:$idx,
Tim Northoverff179ba2014-04-01 10:37:09 +00008018 am_simdnoindex:$vaddr), []>;
Tim Northover00ed9962014-03-29 10:18:08 +00008019
8020 def i16_POST : SIMDLdStSingleHPost<0, R, opcode, size, asm,
8021 (outs), (ins listtype:$Vt, VectorIndexH:$idx,
8022 am_simdnoindex:$vaddr, GPR64pi:$Xm)>;
8023}
8024let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
8025multiclass SIMDStSingleS<bit R, bits<3> opcode, bits<2> size,string asm,
Tim Northoverff179ba2014-04-01 10:37:09 +00008026 RegisterOperand listtype, RegisterOperand GPR64pi> {
Tim Northover00ed9962014-03-29 10:18:08 +00008027 def i32 : SIMDLdStSingleS<0, R, opcode, size, asm,
8028 (outs), (ins listtype:$Vt, VectorIndexS:$idx,
Tim Northoverff179ba2014-04-01 10:37:09 +00008029 am_simdnoindex:$vaddr), []>;
Tim Northover00ed9962014-03-29 10:18:08 +00008030
8031 def i32_POST : SIMDLdStSingleSPost<0, R, opcode, size, asm,
8032 (outs), (ins listtype:$Vt, VectorIndexS:$idx,
8033 am_simdnoindex:$vaddr, GPR64pi:$Xm)>;
8034}
8035let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
8036multiclass SIMDStSingleD<bit R, bits<3> opcode, bits<2> size, string asm,
Tim Northoverff179ba2014-04-01 10:37:09 +00008037 RegisterOperand listtype, RegisterOperand GPR64pi> {
Tim Northover00ed9962014-03-29 10:18:08 +00008038 def i64 : SIMDLdStSingleD<0, R, opcode, size, asm,
8039 (outs), (ins listtype:$Vt, VectorIndexD:$idx,
Tim Northoverff179ba2014-04-01 10:37:09 +00008040 am_simdnoindex:$vaddr), []>;
Tim Northover00ed9962014-03-29 10:18:08 +00008041
8042 def i64_POST : SIMDLdStSingleDPost<0, R, opcode, size, asm,
8043 (outs), (ins listtype:$Vt, VectorIndexD:$idx,
8044 am_simdnoindex:$vaddr, GPR64pi:$Xm)>;
8045}
8046
8047multiclass SIMDLdStSingleAliases<string asm, string layout, string Type,
8048 string Count, int Offset, Operand idxtype> {
8049 // E.g. "ld1 { v0.8b }[0], [x1], #1"
8050 // "ld1\t$Vt, $vaddr, #1"
8051 // may get mapped to
8052 // (LD1Rv8b_POST VecListOne8b:$Vt, am_simdnoindex:$vaddr, XZR)
8053 def : InstAlias<asm # "\t$Vt$idx, $vaddr, #" # Offset,
8054 (!cast<Instruction>(NAME # Type # "_POST")
8055 !cast<RegisterOperand>("VecList" # Count # layout):$Vt,
8056 idxtype:$idx, am_simdnoindex:$vaddr, XZR), 1>;
8057
8058 // E.g. "ld1.8b { v0 }[0], [x1], #1"
8059 // "ld1.8b\t$Vt, $vaddr, #1"
8060 // may get mapped to
8061 // (LD1Rv8b_POST VecListOne64:$Vt, am_simdnoindex:$vaddr, XZR)
8062 def : InstAlias<asm # "." # layout # "\t$Vt$idx, $vaddr, #" # Offset,
8063 (!cast<Instruction>(NAME # Type # "_POST")
8064 !cast<RegisterOperand>("VecList" # Count # "128"):$Vt,
8065 idxtype:$idx, am_simdnoindex:$vaddr, XZR), 0>;
8066
8067 // E.g. "ld1.8b { v0 }[0], [x1]"
8068 // "ld1.8b\t$Vt, $vaddr"
8069 // may get mapped to
8070 // (LD1Rv8b VecListOne64:$Vt, am_simdnoindex:$vaddr)
8071 def : InstAlias<asm # "." # layout # "\t$Vt$idx, $vaddr",
8072 (!cast<Instruction>(NAME # Type)
8073 !cast<RegisterOperand>("VecList" # Count # "128"):$Vt,
8074 idxtype:$idx, am_simdnoindex:$vaddr), 0>;
8075
8076 // E.g. "ld1.8b { v0 }[0], [x1], x2"
8077 // "ld1.8b\t$Vt, $vaddr, $Xm"
8078 // may get mapped to
8079 // (LD1Rv8b_POST VecListOne64:$Vt, am_simdnoindex:$vaddr, GPR64pi1:$Xm)
8080 def : InstAlias<asm # "." # layout # "\t$Vt$idx, $vaddr, $Xm",
8081 (!cast<Instruction>(NAME # Type # "_POST")
8082 !cast<RegisterOperand>("VecList" # Count # "128"):$Vt,
8083 idxtype:$idx, am_simdnoindex:$vaddr,
8084 !cast<RegisterOperand>("GPR64pi" # Offset):$Xm), 0>;
8085}
8086
8087multiclass SIMDLdSt1SingleAliases<string asm> {
8088 defm : SIMDLdStSingleAliases<asm, "b", "i8", "One", 1, VectorIndexB>;
8089 defm : SIMDLdStSingleAliases<asm, "h", "i16", "One", 2, VectorIndexH>;
8090 defm : SIMDLdStSingleAliases<asm, "s", "i32", "One", 4, VectorIndexS>;
8091 defm : SIMDLdStSingleAliases<asm, "d", "i64", "One", 8, VectorIndexD>;
8092}
8093
8094multiclass SIMDLdSt2SingleAliases<string asm> {
8095 defm : SIMDLdStSingleAliases<asm, "b", "i8", "Two", 2, VectorIndexB>;
8096 defm : SIMDLdStSingleAliases<asm, "h", "i16", "Two", 4, VectorIndexH>;
8097 defm : SIMDLdStSingleAliases<asm, "s", "i32", "Two", 8, VectorIndexS>;
8098 defm : SIMDLdStSingleAliases<asm, "d", "i64", "Two", 16, VectorIndexD>;
8099}
8100
8101multiclass SIMDLdSt3SingleAliases<string asm> {
8102 defm : SIMDLdStSingleAliases<asm, "b", "i8", "Three", 3, VectorIndexB>;
8103 defm : SIMDLdStSingleAliases<asm, "h", "i16", "Three", 6, VectorIndexH>;
8104 defm : SIMDLdStSingleAliases<asm, "s", "i32", "Three", 12, VectorIndexS>;
8105 defm : SIMDLdStSingleAliases<asm, "d", "i64", "Three", 24, VectorIndexD>;
8106}
8107
8108multiclass SIMDLdSt4SingleAliases<string asm> {
8109 defm : SIMDLdStSingleAliases<asm, "b", "i8", "Four", 4, VectorIndexB>;
8110 defm : SIMDLdStSingleAliases<asm, "h", "i16", "Four", 8, VectorIndexH>;
8111 defm : SIMDLdStSingleAliases<asm, "s", "i32", "Four", 16, VectorIndexS>;
8112 defm : SIMDLdStSingleAliases<asm, "d", "i64", "Four", 32, VectorIndexD>;
8113}
8114
8115//----------------------------------------------------------------------------
8116// Crypto extensions
8117//----------------------------------------------------------------------------
8118
8119let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
8120class AESBase<bits<4> opc, string asm, dag outs, dag ins, string cstr,
8121 list<dag> pat>
8122 : I<outs, ins, asm, "{\t$Rd.16b, $Rn.16b|.16b\t$Rd, $Rn}", cstr, pat>,
8123 Sched<[WriteV]>{
8124 bits<5> Rd;
8125 bits<5> Rn;
8126 let Inst{31-16} = 0b0100111000101000;
8127 let Inst{15-12} = opc;
8128 let Inst{11-10} = 0b10;
8129 let Inst{9-5} = Rn;
8130 let Inst{4-0} = Rd;
8131}
8132
8133class AESInst<bits<4> opc, string asm, Intrinsic OpNode>
8134 : AESBase<opc, asm, (outs V128:$Rd), (ins V128:$Rn), "",
8135 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>;
8136
8137class AESTiedInst<bits<4> opc, string asm, Intrinsic OpNode>
8138 : AESBase<opc, asm, (outs V128:$dst), (ins V128:$Rd, V128:$Rn),
8139 "$Rd = $dst",
8140 [(set (v16i8 V128:$dst),
8141 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn)))]>;
8142
8143let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
8144class SHA3OpTiedInst<bits<3> opc, string asm, string dst_lhs_kind,
8145 dag oops, dag iops, list<dag> pat>
8146 : I<oops, iops, asm,
8147 "{\t$Rd" # dst_lhs_kind # ", $Rn" # dst_lhs_kind # ", $Rm.4s" #
8148 "|.4s\t$Rd, $Rn, $Rm}", "$Rd = $dst", pat>,
8149 Sched<[WriteV]>{
8150 bits<5> Rd;
8151 bits<5> Rn;
8152 bits<5> Rm;
8153 let Inst{31-21} = 0b01011110000;
8154 let Inst{20-16} = Rm;
8155 let Inst{15} = 0;
8156 let Inst{14-12} = opc;
8157 let Inst{11-10} = 0b00;
8158 let Inst{9-5} = Rn;
8159 let Inst{4-0} = Rd;
8160}
8161
8162class SHATiedInstQSV<bits<3> opc, string asm, Intrinsic OpNode>
8163 : SHA3OpTiedInst<opc, asm, "", (outs FPR128:$dst),
8164 (ins FPR128:$Rd, FPR32:$Rn, V128:$Rm),
8165 [(set (v4i32 FPR128:$dst),
8166 (OpNode (v4i32 FPR128:$Rd), (i32 FPR32:$Rn),
8167 (v4i32 V128:$Rm)))]>;
8168
8169class SHATiedInstVVV<bits<3> opc, string asm, Intrinsic OpNode>
8170 : SHA3OpTiedInst<opc, asm, ".4s", (outs V128:$dst),
8171 (ins V128:$Rd, V128:$Rn, V128:$Rm),
8172 [(set (v4i32 V128:$dst),
8173 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn),
8174 (v4i32 V128:$Rm)))]>;
8175
8176class SHATiedInstQQV<bits<3> opc, string asm, Intrinsic OpNode>
8177 : SHA3OpTiedInst<opc, asm, "", (outs FPR128:$dst),
8178 (ins FPR128:$Rd, FPR128:$Rn, V128:$Rm),
8179 [(set (v4i32 FPR128:$dst),
8180 (OpNode (v4i32 FPR128:$Rd), (v4i32 FPR128:$Rn),
8181 (v4i32 V128:$Rm)))]>;
8182
8183let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
8184class SHA2OpInst<bits<4> opc, string asm, string kind,
8185 string cstr, dag oops, dag iops,
8186 list<dag> pat>
8187 : I<oops, iops, asm, "{\t$Rd" # kind # ", $Rn" # kind #
8188 "|" # kind # "\t$Rd, $Rn}", cstr, pat>,
8189 Sched<[WriteV]>{
8190 bits<5> Rd;
8191 bits<5> Rn;
8192 let Inst{31-16} = 0b0101111000101000;
8193 let Inst{15-12} = opc;
8194 let Inst{11-10} = 0b10;
8195 let Inst{9-5} = Rn;
8196 let Inst{4-0} = Rd;
8197}
8198
8199class SHATiedInstVV<bits<4> opc, string asm, Intrinsic OpNode>
8200 : SHA2OpInst<opc, asm, ".4s", "$Rd = $dst", (outs V128:$dst),
8201 (ins V128:$Rd, V128:$Rn),
8202 [(set (v4i32 V128:$dst),
8203 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn)))]>;
8204
8205class SHAInstSS<bits<4> opc, string asm, Intrinsic OpNode>
8206 : SHA2OpInst<opc, asm, "", "", (outs FPR32:$Rd), (ins FPR32:$Rn),
8207 [(set (i32 FPR32:$Rd), (OpNode (i32 FPR32:$Rn)))]>;
8208
8209// Allow the size specifier tokens to be upper case, not just lower.
8210def : TokenAlias<".8B", ".8b">;
8211def : TokenAlias<".4H", ".4h">;
8212def : TokenAlias<".2S", ".2s">;
8213def : TokenAlias<".1D", ".1d">;
8214def : TokenAlias<".16B", ".16b">;
8215def : TokenAlias<".8H", ".8h">;
8216def : TokenAlias<".4S", ".4s">;
8217def : TokenAlias<".2D", ".2d">;
Bradley Smith6d7af172014-04-09 14:42:01 +00008218def : TokenAlias<".1Q", ".1q">;
Tim Northover00ed9962014-03-29 10:18:08 +00008219def : TokenAlias<".B", ".b">;
8220def : TokenAlias<".H", ".h">;
8221def : TokenAlias<".S", ".s">;
8222def : TokenAlias<".D", ".d">;
Bradley Smith6d7af172014-04-09 14:42:01 +00008223def : TokenAlias<".Q", ".q">;