blob: f4ad842f242576acf649ebec988a24590494e1aa [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;
Bradley Smith0243aa32014-04-09 14:43:20 +00003047 let Inst{30-29} = 0b00;
Tim Northover00ed9962014-03-29 10:18:08 +00003048 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
Bradley Smith0243aa32014-04-09 14:43:20 +00003079multiclass FPToIntegerUnscaled<bits<2> rmode, bits<3> opcode, string asm,
3080 SDPatternOperator OpN> {
Tim Northover00ed9962014-03-29 10:18:08 +00003081 // Unscaled single-precision to 32-bit
3082 def UWSr : BaseFPToIntegerUnscaled<0b00, rmode, opcode, FPR32, GPR32, asm,
3083 [(set GPR32:$Rd, (OpN FPR32:$Rn))]> {
3084 let Inst{31} = 0; // 32-bit GPR flag
3085 }
3086
3087 // Unscaled single-precision to 64-bit
3088 def UXSr : BaseFPToIntegerUnscaled<0b00, rmode, opcode, FPR32, GPR64, asm,
3089 [(set GPR64:$Rd, (OpN FPR32:$Rn))]> {
3090 let Inst{31} = 1; // 64-bit GPR flag
3091 }
3092
3093 // Unscaled double-precision to 32-bit
3094 def UWDr : BaseFPToIntegerUnscaled<0b01, rmode, opcode, FPR64, GPR32, asm,
3095 [(set GPR32:$Rd, (OpN (f64 FPR64:$Rn)))]> {
3096 let Inst{31} = 0; // 32-bit GPR flag
3097 }
3098
3099 // Unscaled double-precision to 64-bit
3100 def UXDr : BaseFPToIntegerUnscaled<0b01, rmode, opcode, FPR64, GPR64, asm,
3101 [(set GPR64:$Rd, (OpN (f64 FPR64:$Rn)))]> {
3102 let Inst{31} = 1; // 64-bit GPR flag
3103 }
Bradley Smith0243aa32014-04-09 14:43:20 +00003104}
Tim Northover00ed9962014-03-29 10:18:08 +00003105
Bradley Smith0243aa32014-04-09 14:43:20 +00003106multiclass FPToIntegerScaled<bits<2> rmode, bits<3> opcode, string asm,
3107 SDPatternOperator OpN> {
Tim Northover00ed9962014-03-29 10:18:08 +00003108 // Scaled single-precision to 32-bit
3109 def SWSri : BaseFPToInteger<0b00, rmode, opcode, FPR32, GPR32,
3110 fixedpoint32, asm> {
3111 let Inst{31} = 0; // 32-bit GPR flag
3112 }
3113
3114 // Scaled single-precision to 64-bit
3115 def SXSri : BaseFPToInteger<0b00, rmode, opcode, FPR32, GPR64,
3116 fixedpoint64, asm> {
3117 let Inst{31} = 1; // 64-bit GPR flag
3118 }
3119
3120 // Scaled double-precision to 32-bit
3121 def SWDri : BaseFPToInteger<0b01, rmode, opcode, FPR64, GPR32,
3122 fixedpoint32, asm> {
3123 let Inst{31} = 0; // 32-bit GPR flag
3124 }
3125
3126 // Scaled double-precision to 64-bit
3127 def SXDri : BaseFPToInteger<0b01, rmode, opcode, FPR64, GPR64,
3128 fixedpoint64, asm> {
3129 let Inst{31} = 1; // 64-bit GPR flag
3130 }
3131}
3132
3133//---
3134// Integer to floating point conversion
3135//---
3136
3137let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
3138class BaseIntegerToFP<bit isUnsigned,
3139 RegisterClass srcType, RegisterClass dstType,
3140 Operand immType, string asm>
3141 : I<(outs dstType:$Rd), (ins srcType:$Rn, immType:$scale),
3142 asm, "\t$Rd, $Rn, $scale", "", []>,
3143 Sched<[WriteFCvt]> {
3144 bits<5> Rd;
3145 bits<5> Rn;
3146 bits<6> scale;
3147 let Inst{30-23} = 0b00111100;
3148 let Inst{21-17} = 0b00001;
3149 let Inst{16} = isUnsigned;
3150 let Inst{15-10} = scale;
3151 let Inst{9-5} = Rn;
3152 let Inst{4-0} = Rd;
3153}
3154
3155class BaseIntegerToFPUnscaled<bit isUnsigned,
3156 RegisterClass srcType, RegisterClass dstType,
3157 ValueType dvt, string asm, SDNode node>
3158 : I<(outs dstType:$Rd), (ins srcType:$Rn),
3159 asm, "\t$Rd, $Rn", "", [(set (dvt dstType:$Rd), (node srcType:$Rn))]>,
3160 Sched<[WriteFCvt]> {
3161 bits<5> Rd;
3162 bits<5> Rn;
3163 bits<6> scale;
3164 let Inst{30-23} = 0b00111100;
3165 let Inst{21-17} = 0b10001;
3166 let Inst{16} = isUnsigned;
3167 let Inst{15-10} = 0b000000;
3168 let Inst{9-5} = Rn;
3169 let Inst{4-0} = Rd;
3170}
3171
3172multiclass IntegerToFP<bit isUnsigned, string asm, SDNode node> {
3173 // Unscaled
3174 def UWSri: BaseIntegerToFPUnscaled<isUnsigned, GPR32, FPR32, f32, asm, node> {
3175 let Inst{31} = 0; // 32-bit GPR flag
3176 let Inst{22} = 0; // 32-bit FPR flag
3177 }
3178
3179 def UWDri: BaseIntegerToFPUnscaled<isUnsigned, GPR32, FPR64, f64, asm, node> {
3180 let Inst{31} = 0; // 32-bit GPR flag
3181 let Inst{22} = 1; // 64-bit FPR flag
3182 }
3183
3184 def UXSri: BaseIntegerToFPUnscaled<isUnsigned, GPR64, FPR32, f32, asm, node> {
3185 let Inst{31} = 1; // 64-bit GPR flag
3186 let Inst{22} = 0; // 32-bit FPR flag
3187 }
3188
3189 def UXDri: BaseIntegerToFPUnscaled<isUnsigned, GPR64, FPR64, f64, asm, node> {
3190 let Inst{31} = 1; // 64-bit GPR flag
3191 let Inst{22} = 1; // 64-bit FPR flag
3192 }
3193
3194 // Scaled
3195 def SWSri: BaseIntegerToFP<isUnsigned, GPR32, FPR32, fixedpoint32, asm> {
3196 let Inst{31} = 0; // 32-bit GPR flag
3197 let Inst{22} = 0; // 32-bit FPR flag
3198 }
3199
3200 def SWDri: BaseIntegerToFP<isUnsigned, GPR32, FPR64, fixedpoint32, asm> {
3201 let Inst{31} = 0; // 32-bit GPR flag
3202 let Inst{22} = 1; // 64-bit FPR flag
3203 }
3204
3205 def SXSri: BaseIntegerToFP<isUnsigned, GPR64, FPR32, fixedpoint64, asm> {
3206 let Inst{31} = 1; // 64-bit GPR flag
3207 let Inst{22} = 0; // 32-bit FPR flag
3208 }
3209
3210 def SXDri: BaseIntegerToFP<isUnsigned, GPR64, FPR64, fixedpoint64, asm> {
3211 let Inst{31} = 1; // 64-bit GPR flag
3212 let Inst{22} = 1; // 64-bit FPR flag
3213 }
3214}
3215
3216//---
3217// Unscaled integer <-> floating point conversion (i.e. FMOV)
3218//---
3219
3220let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
3221class BaseUnscaledConversion<bits<2> rmode, bits<3> opcode,
3222 RegisterClass srcType, RegisterClass dstType,
3223 string asm>
3224 : I<(outs dstType:$Rd), (ins srcType:$Rn), asm, "\t$Rd, $Rn", "",
3225 // We use COPY_TO_REGCLASS for these bitconvert operations.
3226 // copyPhysReg() expands the resultant COPY instructions after
3227 // regalloc is done. This gives greater freedom for the allocator
3228 // and related passes (coalescing, copy propagation, et. al.) to
3229 // be more effective.
3230 [/*(set (dvt dstType:$Rd), (bitconvert (svt srcType:$Rn)))*/]>,
3231 Sched<[WriteFCopy]> {
3232 bits<5> Rd;
3233 bits<5> Rn;
3234 let Inst{30-23} = 0b00111100;
3235 let Inst{21} = 1;
3236 let Inst{20-19} = rmode;
3237 let Inst{18-16} = opcode;
3238 let Inst{15-10} = 0b000000;
3239 let Inst{9-5} = Rn;
3240 let Inst{4-0} = Rd;
3241}
3242
3243let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
3244class BaseUnscaledConversionToHigh<bits<2> rmode, bits<3> opcode,
3245 RegisterClass srcType, RegisterOperand dstType, string asm>
3246 : I<(outs dstType:$Rd), (ins srcType:$Rn), asm, "\t$Rd[1], $Rn", "", []>,
3247 Sched<[WriteFCopy]> {
3248 bits<5> Rd;
3249 bits<5> Rn;
3250 let Inst{30-23} = 0b00111101;
3251 let Inst{21} = 1;
3252 let Inst{20-19} = rmode;
3253 let Inst{18-16} = opcode;
3254 let Inst{15-10} = 0b000000;
3255 let Inst{9-5} = Rn;
3256 let Inst{4-0} = Rd;
3257}
3258
3259let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
3260class BaseUnscaledConversionFromHigh<bits<2> rmode, bits<3> opcode,
3261 RegisterOperand srcType, RegisterClass dstType, string asm>
3262 : I<(outs dstType:$Rd), (ins srcType:$Rn), asm, "\t$Rd, $Rn[1]", "", []>,
3263 Sched<[WriteFCopy]> {
3264 bits<5> Rd;
3265 bits<5> Rn;
3266 let Inst{30-23} = 0b00111101;
3267 let Inst{21} = 1;
3268 let Inst{20-19} = rmode;
3269 let Inst{18-16} = opcode;
3270 let Inst{15-10} = 0b000000;
3271 let Inst{9-5} = Rn;
3272 let Inst{4-0} = Rd;
3273}
3274
3275
3276
3277multiclass UnscaledConversion<string asm> {
3278 def WSr : BaseUnscaledConversion<0b00, 0b111, GPR32, FPR32, asm> {
3279 let Inst{31} = 0; // 32-bit GPR flag
3280 let Inst{22} = 0; // 32-bit FPR flag
3281 }
3282
3283 def XDr : BaseUnscaledConversion<0b00, 0b111, GPR64, FPR64, asm> {
3284 let Inst{31} = 1; // 64-bit GPR flag
3285 let Inst{22} = 1; // 64-bit FPR flag
3286 }
3287
3288 def SWr : BaseUnscaledConversion<0b00, 0b110, FPR32, GPR32, asm> {
3289 let Inst{31} = 0; // 32-bit GPR flag
3290 let Inst{22} = 0; // 32-bit FPR flag
3291 }
3292
3293 def DXr : BaseUnscaledConversion<0b00, 0b110, FPR64, GPR64, asm> {
3294 let Inst{31} = 1; // 64-bit GPR flag
3295 let Inst{22} = 1; // 64-bit FPR flag
3296 }
3297
3298 def XDHighr : BaseUnscaledConversionToHigh<0b01, 0b111, GPR64, V128,
3299 asm#".d"> {
3300 let Inst{31} = 1;
3301 let Inst{22} = 0;
3302 }
3303
3304 def DXHighr : BaseUnscaledConversionFromHigh<0b01, 0b110, V128, GPR64,
3305 asm#".d"> {
3306 let Inst{31} = 1;
3307 let Inst{22} = 0;
3308 }
3309
3310 def : InstAlias<asm#"$Vd.d[1], $Rn",
3311 (!cast<Instruction>(NAME#XDHighr) V128:$Vd, GPR64:$Rn), 0>;
3312 def : InstAlias<asm#"$Rd, $Vn.d[1]",
3313 (!cast<Instruction>(NAME#DXHighr) GPR64:$Rd, V128:$Vn), 0>;
3314}
3315
3316//---
3317// Floating point conversion
3318//---
3319
3320class BaseFPConversion<bits<2> type, bits<2> opcode, RegisterClass dstType,
3321 RegisterClass srcType, string asm, list<dag> pattern>
3322 : I<(outs dstType:$Rd), (ins srcType:$Rn), asm, "\t$Rd, $Rn", "", pattern>,
3323 Sched<[WriteFCvt]> {
3324 bits<5> Rd;
3325 bits<5> Rn;
3326 let Inst{31-24} = 0b00011110;
3327 let Inst{23-22} = type;
3328 let Inst{21-17} = 0b10001;
3329 let Inst{16-15} = opcode;
3330 let Inst{14-10} = 0b10000;
3331 let Inst{9-5} = Rn;
3332 let Inst{4-0} = Rd;
3333}
3334
3335multiclass FPConversion<string asm> {
3336 // Double-precision to Half-precision
3337 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
3338 def HDr : BaseFPConversion<0b01, 0b11, FPR16, FPR64, asm, []>;
3339
3340 // Double-precision to Single-precision
3341 def SDr : BaseFPConversion<0b01, 0b00, FPR32, FPR64, asm,
3342 [(set FPR32:$Rd, (fround FPR64:$Rn))]>;
3343
3344 // Half-precision to Double-precision
3345 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
3346 def DHr : BaseFPConversion<0b11, 0b01, FPR64, FPR16, asm, []>;
3347
3348 // Half-precision to Single-precision
3349 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
3350 def SHr : BaseFPConversion<0b11, 0b00, FPR32, FPR16, asm, []>;
3351
3352 // Single-precision to Double-precision
3353 def DSr : BaseFPConversion<0b00, 0b01, FPR64, FPR32, asm,
3354 [(set FPR64:$Rd, (fextend FPR32:$Rn))]>;
3355
3356 // Single-precision to Half-precision
3357 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
3358 def HSr : BaseFPConversion<0b00, 0b11, FPR16, FPR32, asm, []>;
3359}
3360
3361//---
3362// Single operand floating point data processing
3363//---
3364
3365let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
3366class BaseSingleOperandFPData<bits<4> opcode, RegisterClass regtype,
3367 ValueType vt, string asm, SDPatternOperator node>
3368 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm, "\t$Rd, $Rn", "",
3369 [(set (vt regtype:$Rd), (node (vt regtype:$Rn)))]>,
3370 Sched<[WriteF]> {
3371 bits<5> Rd;
3372 bits<5> Rn;
3373 let Inst{31-23} = 0b000111100;
3374 let Inst{21-19} = 0b100;
3375 let Inst{18-15} = opcode;
3376 let Inst{14-10} = 0b10000;
3377 let Inst{9-5} = Rn;
3378 let Inst{4-0} = Rd;
3379}
3380
3381multiclass SingleOperandFPData<bits<4> opcode, string asm,
3382 SDPatternOperator node = null_frag> {
3383 def Sr : BaseSingleOperandFPData<opcode, FPR32, f32, asm, node> {
3384 let Inst{22} = 0; // 32-bit size flag
3385 }
3386
3387 def Dr : BaseSingleOperandFPData<opcode, FPR64, f64, asm, node> {
3388 let Inst{22} = 1; // 64-bit size flag
3389 }
3390}
3391
3392//---
3393// Two operand floating point data processing
3394//---
3395
3396let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
3397class BaseTwoOperandFPData<bits<4> opcode, RegisterClass regtype,
3398 string asm, list<dag> pat>
3399 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm),
3400 asm, "\t$Rd, $Rn, $Rm", "", pat>,
3401 Sched<[WriteF]> {
3402 bits<5> Rd;
3403 bits<5> Rn;
3404 bits<5> Rm;
3405 let Inst{31-23} = 0b000111100;
3406 let Inst{21} = 1;
3407 let Inst{20-16} = Rm;
3408 let Inst{15-12} = opcode;
3409 let Inst{11-10} = 0b10;
3410 let Inst{9-5} = Rn;
3411 let Inst{4-0} = Rd;
3412}
3413
3414multiclass TwoOperandFPData<bits<4> opcode, string asm,
3415 SDPatternOperator node = null_frag> {
3416 def Srr : BaseTwoOperandFPData<opcode, FPR32, asm,
3417 [(set (f32 FPR32:$Rd),
3418 (node (f32 FPR32:$Rn), (f32 FPR32:$Rm)))]> {
3419 let Inst{22} = 0; // 32-bit size flag
3420 }
3421
3422 def Drr : BaseTwoOperandFPData<opcode, FPR64, asm,
3423 [(set (f64 FPR64:$Rd),
3424 (node (f64 FPR64:$Rn), (f64 FPR64:$Rm)))]> {
3425 let Inst{22} = 1; // 64-bit size flag
3426 }
3427}
3428
3429multiclass TwoOperandFPDataNeg<bits<4> opcode, string asm, SDNode node> {
3430 def Srr : BaseTwoOperandFPData<opcode, FPR32, asm,
3431 [(set FPR32:$Rd, (fneg (node FPR32:$Rn, (f32 FPR32:$Rm))))]> {
3432 let Inst{22} = 0; // 32-bit size flag
3433 }
3434
3435 def Drr : BaseTwoOperandFPData<opcode, FPR64, asm,
3436 [(set FPR64:$Rd, (fneg (node FPR64:$Rn, (f64 FPR64:$Rm))))]> {
3437 let Inst{22} = 1; // 64-bit size flag
3438 }
3439}
3440
3441
3442//---
3443// Three operand floating point data processing
3444//---
3445
3446class BaseThreeOperandFPData<bit isNegated, bit isSub,
3447 RegisterClass regtype, string asm, list<dag> pat>
3448 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, regtype: $Ra),
3449 asm, "\t$Rd, $Rn, $Rm, $Ra", "", pat>,
3450 Sched<[WriteFMul]> {
3451 bits<5> Rd;
3452 bits<5> Rn;
3453 bits<5> Rm;
3454 bits<5> Ra;
3455 let Inst{31-23} = 0b000111110;
3456 let Inst{21} = isNegated;
3457 let Inst{20-16} = Rm;
3458 let Inst{15} = isSub;
3459 let Inst{14-10} = Ra;
3460 let Inst{9-5} = Rn;
3461 let Inst{4-0} = Rd;
3462}
3463
3464multiclass ThreeOperandFPData<bit isNegated, bit isSub,string asm,
3465 SDPatternOperator node> {
3466 def Srrr : BaseThreeOperandFPData<isNegated, isSub, FPR32, asm,
3467 [(set FPR32:$Rd,
3468 (node (f32 FPR32:$Rn), (f32 FPR32:$Rm), (f32 FPR32:$Ra)))]> {
3469 let Inst{22} = 0; // 32-bit size flag
3470 }
3471
3472 def Drrr : BaseThreeOperandFPData<isNegated, isSub, FPR64, asm,
3473 [(set FPR64:$Rd,
3474 (node (f64 FPR64:$Rn), (f64 FPR64:$Rm), (f64 FPR64:$Ra)))]> {
3475 let Inst{22} = 1; // 64-bit size flag
3476 }
3477}
3478
3479//---
3480// Floating point data comparisons
3481//---
3482
3483let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
3484class BaseOneOperandFPComparison<bit signalAllNans,
3485 RegisterClass regtype, string asm,
3486 list<dag> pat>
3487 : I<(outs), (ins regtype:$Rn), asm, "\t$Rn, #0.0", "", pat>,
3488 Sched<[WriteFCmp]> {
3489 bits<5> Rn;
3490 let Inst{31-23} = 0b000111100;
3491 let Inst{21} = 1;
3492
3493 let Inst{20-16} = 0b00000;
3494 let Inst{15-10} = 0b001000;
3495 let Inst{9-5} = Rn;
3496 let Inst{4} = signalAllNans;
3497 let Inst{3-0} = 0b1000;
3498}
3499
3500let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
3501class BaseTwoOperandFPComparison<bit signalAllNans, RegisterClass regtype,
3502 string asm, list<dag> pat>
3503 : I<(outs), (ins regtype:$Rn, regtype:$Rm), asm, "\t$Rn, $Rm", "", pat>,
3504 Sched<[WriteFCmp]> {
3505 bits<5> Rm;
3506 bits<5> Rn;
3507 let Inst{31-23} = 0b000111100;
3508 let Inst{21} = 1;
3509 let Inst{20-16} = Rm;
3510 let Inst{15-10} = 0b001000;
3511 let Inst{9-5} = Rn;
3512 let Inst{4} = signalAllNans;
3513 let Inst{3-0} = 0b0000;
3514}
3515
3516multiclass FPComparison<bit signalAllNans, string asm,
3517 SDPatternOperator OpNode = null_frag> {
3518 let Defs = [CPSR] in {
3519 def Srr : BaseTwoOperandFPComparison<signalAllNans, FPR32, asm,
3520 [(OpNode FPR32:$Rn, (f32 FPR32:$Rm)), (implicit CPSR)]> {
3521 let Inst{22} = 0;
3522 }
3523
3524 def Sri : BaseOneOperandFPComparison<signalAllNans, FPR32, asm,
3525 [(OpNode (f32 FPR32:$Rn), fpimm0), (implicit CPSR)]> {
3526 let Inst{22} = 0;
3527 }
3528
3529 def Drr : BaseTwoOperandFPComparison<signalAllNans, FPR64, asm,
3530 [(OpNode FPR64:$Rn, (f64 FPR64:$Rm)), (implicit CPSR)]> {
3531 let Inst{22} = 1;
3532 }
3533
3534 def Dri : BaseOneOperandFPComparison<signalAllNans, FPR64, asm,
3535 [(OpNode (f64 FPR64:$Rn), fpimm0), (implicit CPSR)]> {
3536 let Inst{22} = 1;
3537 }
3538 } // Defs = [CPSR]
3539}
3540
3541//---
3542// Floating point conditional comparisons
3543//---
3544
3545let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
3546class BaseFPCondComparison<bit signalAllNans,
3547 RegisterClass regtype, string asm>
3548 : I<(outs), (ins regtype:$Rn, regtype:$Rm, imm0_15:$nzcv, ccode:$cond),
3549 asm, "\t$Rn, $Rm, $nzcv, $cond", "", []>,
3550 Sched<[WriteFCmp]> {
3551 bits<5> Rn;
3552 bits<5> Rm;
3553 bits<4> nzcv;
3554 bits<4> cond;
3555
3556 let Inst{31-23} = 0b000111100;
3557 let Inst{21} = 1;
3558 let Inst{20-16} = Rm;
3559 let Inst{15-12} = cond;
3560 let Inst{11-10} = 0b01;
3561 let Inst{9-5} = Rn;
3562 let Inst{4} = signalAllNans;
3563 let Inst{3-0} = nzcv;
3564}
3565
3566multiclass FPCondComparison<bit signalAllNans, string asm> {
3567 let Defs = [CPSR], Uses = [CPSR] in {
3568 def Srr : BaseFPCondComparison<signalAllNans, FPR32, asm> {
3569 let Inst{22} = 0;
3570 }
3571
3572 def Drr : BaseFPCondComparison<signalAllNans, FPR64, asm> {
3573 let Inst{22} = 1;
3574 }
3575 } // Defs = [CPSR], Uses = [CPSR]
3576}
3577
3578//---
3579// Floating point conditional select
3580//---
3581
3582class BaseFPCondSelect<RegisterClass regtype, ValueType vt, string asm>
3583 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, ccode:$cond),
3584 asm, "\t$Rd, $Rn, $Rm, $cond", "",
3585 [(set regtype:$Rd,
3586 (ARM64csel (vt regtype:$Rn), regtype:$Rm,
3587 (i32 imm:$cond), CPSR))]>,
3588 Sched<[WriteF]> {
3589 bits<5> Rd;
3590 bits<5> Rn;
3591 bits<5> Rm;
3592 bits<4> cond;
3593
3594 let Inst{31-23} = 0b000111100;
3595 let Inst{21} = 1;
3596 let Inst{20-16} = Rm;
3597 let Inst{15-12} = cond;
3598 let Inst{11-10} = 0b11;
3599 let Inst{9-5} = Rn;
3600 let Inst{4-0} = Rd;
3601}
3602
3603multiclass FPCondSelect<string asm> {
3604 let Uses = [CPSR] in {
3605 def Srrr : BaseFPCondSelect<FPR32, f32, asm> {
3606 let Inst{22} = 0;
3607 }
3608
3609 def Drrr : BaseFPCondSelect<FPR64, f64, asm> {
3610 let Inst{22} = 1;
3611 }
3612 } // Uses = [CPSR]
3613}
3614
3615//---
3616// Floating move immediate
3617//---
3618
3619class BaseFPMoveImmediate<RegisterClass regtype, Operand fpimmtype, string asm>
3620 : I<(outs regtype:$Rd), (ins fpimmtype:$imm), asm, "\t$Rd, $imm", "",
3621 [(set regtype:$Rd, fpimmtype:$imm)]>,
3622 Sched<[WriteFImm]> {
3623 bits<5> Rd;
3624 bits<8> imm;
3625 let Inst{31-23} = 0b000111100;
3626 let Inst{21} = 1;
3627 let Inst{20-13} = imm;
3628 let Inst{12-5} = 0b10000000;
3629 let Inst{4-0} = Rd;
3630}
3631
3632multiclass FPMoveImmediate<string asm> {
3633 def Si : BaseFPMoveImmediate<FPR32, fpimm32, asm> {
3634 let Inst{22} = 0;
3635 }
3636
3637 def Di : BaseFPMoveImmediate<FPR64, fpimm64, asm> {
3638 let Inst{22} = 1;
3639 }
3640}
3641
3642//----------------------------------------------------------------------------
3643// AdvSIMD
3644//----------------------------------------------------------------------------
3645
3646def VectorIndexBOperand : AsmOperandClass { let Name = "VectorIndexB"; }
3647def VectorIndexHOperand : AsmOperandClass { let Name = "VectorIndexH"; }
3648def VectorIndexSOperand : AsmOperandClass { let Name = "VectorIndexS"; }
3649def VectorIndexDOperand : AsmOperandClass { let Name = "VectorIndexD"; }
3650def VectorIndexB : Operand<i64>, ImmLeaf<i64, [{
3651 return ((uint64_t)Imm) < 16;
3652}]> {
3653 let ParserMatchClass = VectorIndexBOperand;
3654 let PrintMethod = "printVectorIndex";
3655 let MIOperandInfo = (ops i64imm);
3656}
3657def VectorIndexH : Operand<i64>, ImmLeaf<i64, [{
3658 return ((uint64_t)Imm) < 8;
3659}]> {
3660 let ParserMatchClass = VectorIndexHOperand;
3661 let PrintMethod = "printVectorIndex";
3662 let MIOperandInfo = (ops i64imm);
3663}
3664def VectorIndexS : Operand<i64>, ImmLeaf<i64, [{
3665 return ((uint64_t)Imm) < 4;
3666}]> {
3667 let ParserMatchClass = VectorIndexSOperand;
3668 let PrintMethod = "printVectorIndex";
3669 let MIOperandInfo = (ops i64imm);
3670}
3671def VectorIndexD : Operand<i64>, ImmLeaf<i64, [{
3672 return ((uint64_t)Imm) < 2;
3673}]> {
3674 let ParserMatchClass = VectorIndexDOperand;
3675 let PrintMethod = "printVectorIndex";
3676 let MIOperandInfo = (ops i64imm);
3677}
3678
3679//----------------------------------------------------------------------------
3680// AdvSIMD three register vector instructions
3681//----------------------------------------------------------------------------
3682
3683let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
3684class BaseSIMDThreeSameVector<bit Q, bit U, bits<2> size, bits<5> opcode,
3685 RegisterOperand regtype, string asm, string kind,
3686 list<dag> pattern>
3687 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), asm,
3688 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind #
3689 "|" # kind # "\t$Rd, $Rn, $Rm|}", "", pattern>,
3690 Sched<[WriteV]> {
3691 bits<5> Rd;
3692 bits<5> Rn;
3693 bits<5> Rm;
3694 let Inst{31} = 0;
3695 let Inst{30} = Q;
3696 let Inst{29} = U;
3697 let Inst{28-24} = 0b01110;
3698 let Inst{23-22} = size;
3699 let Inst{21} = 1;
3700 let Inst{20-16} = Rm;
3701 let Inst{15-11} = opcode;
3702 let Inst{10} = 1;
3703 let Inst{9-5} = Rn;
3704 let Inst{4-0} = Rd;
3705}
3706
3707let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
3708class BaseSIMDThreeSameVectorTied<bit Q, bit U, bits<2> size, bits<5> opcode,
3709 RegisterOperand regtype, string asm, string kind,
3710 list<dag> pattern>
3711 : I<(outs regtype:$dst), (ins regtype:$Rd, regtype:$Rn, regtype:$Rm), asm,
3712 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind #
3713 "|" # kind # "\t$Rd, $Rn, $Rm}", "$Rd = $dst", pattern>,
3714 Sched<[WriteV]> {
3715 bits<5> Rd;
3716 bits<5> Rn;
3717 bits<5> Rm;
3718 let Inst{31} = 0;
3719 let Inst{30} = Q;
3720 let Inst{29} = U;
3721 let Inst{28-24} = 0b01110;
3722 let Inst{23-22} = size;
3723 let Inst{21} = 1;
3724 let Inst{20-16} = Rm;
3725 let Inst{15-11} = opcode;
3726 let Inst{10} = 1;
3727 let Inst{9-5} = Rn;
3728 let Inst{4-0} = Rd;
3729}
3730
3731// All operand sizes distinguished in the encoding.
3732multiclass SIMDThreeSameVector<bit U, bits<5> opc, string asm,
3733 SDPatternOperator OpNode> {
3734 def v8i8 : BaseSIMDThreeSameVector<0, U, 0b00, opc, V64,
3735 asm, ".8b",
3736 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
3737 def v16i8 : BaseSIMDThreeSameVector<1, U, 0b00, opc, V128,
3738 asm, ".16b",
3739 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn), (v16i8 V128:$Rm)))]>;
3740 def v4i16 : BaseSIMDThreeSameVector<0, U, 0b01, opc, V64,
3741 asm, ".4h",
3742 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>;
3743 def v8i16 : BaseSIMDThreeSameVector<1, U, 0b01, opc, V128,
3744 asm, ".8h",
3745 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>;
3746 def v2i32 : BaseSIMDThreeSameVector<0, U, 0b10, opc, V64,
3747 asm, ".2s",
3748 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>;
3749 def v4i32 : BaseSIMDThreeSameVector<1, U, 0b10, opc, V128,
3750 asm, ".4s",
3751 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>;
3752 def v2i64 : BaseSIMDThreeSameVector<1, U, 0b11, opc, V128,
3753 asm, ".2d",
3754 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn), (v2i64 V128:$Rm)))]>;
3755}
3756
3757// As above, but D sized elements unsupported.
3758multiclass SIMDThreeSameVectorBHS<bit U, bits<5> opc, string asm,
3759 SDPatternOperator OpNode> {
3760 def v8i8 : BaseSIMDThreeSameVector<0, U, 0b00, opc, V64,
3761 asm, ".8b",
3762 [(set V64:$Rd, (v8i8 (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm))))]>;
3763 def v16i8 : BaseSIMDThreeSameVector<1, U, 0b00, opc, V128,
3764 asm, ".16b",
3765 [(set V128:$Rd, (v16i8 (OpNode (v16i8 V128:$Rn), (v16i8 V128:$Rm))))]>;
3766 def v4i16 : BaseSIMDThreeSameVector<0, U, 0b01, opc, V64,
3767 asm, ".4h",
3768 [(set V64:$Rd, (v4i16 (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm))))]>;
3769 def v8i16 : BaseSIMDThreeSameVector<1, U, 0b01, opc, V128,
3770 asm, ".8h",
3771 [(set V128:$Rd, (v8i16 (OpNode (v8i16 V128:$Rn), (v8i16 V128:$Rm))))]>;
3772 def v2i32 : BaseSIMDThreeSameVector<0, U, 0b10, opc, V64,
3773 asm, ".2s",
3774 [(set V64:$Rd, (v2i32 (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm))))]>;
3775 def v4i32 : BaseSIMDThreeSameVector<1, U, 0b10, opc, V128,
3776 asm, ".4s",
3777 [(set V128:$Rd, (v4i32 (OpNode (v4i32 V128:$Rn), (v4i32 V128:$Rm))))]>;
3778}
3779
3780multiclass SIMDThreeSameVectorBHSTied<bit U, bits<5> opc, string asm,
3781 SDPatternOperator OpNode> {
3782 def v8i8 : BaseSIMDThreeSameVectorTied<0, U, 0b00, opc, V64,
3783 asm, ".8b",
3784 [(set (v8i8 V64:$dst),
3785 (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
3786 def v16i8 : BaseSIMDThreeSameVectorTied<1, U, 0b00, opc, V128,
3787 asm, ".16b",
3788 [(set (v16i8 V128:$dst),
3789 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn), (v16i8 V128:$Rm)))]>;
3790 def v4i16 : BaseSIMDThreeSameVectorTied<0, U, 0b01, opc, V64,
3791 asm, ".4h",
3792 [(set (v4i16 V64:$dst),
3793 (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>;
3794 def v8i16 : BaseSIMDThreeSameVectorTied<1, U, 0b01, opc, V128,
3795 asm, ".8h",
3796 [(set (v8i16 V128:$dst),
3797 (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>;
3798 def v2i32 : BaseSIMDThreeSameVectorTied<0, U, 0b10, opc, V64,
3799 asm, ".2s",
3800 [(set (v2i32 V64:$dst),
3801 (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>;
3802 def v4i32 : BaseSIMDThreeSameVectorTied<1, U, 0b10, opc, V128,
3803 asm, ".4s",
3804 [(set (v4i32 V128:$dst),
3805 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>;
3806}
3807
3808// As above, but only B sized elements supported.
3809multiclass SIMDThreeSameVectorB<bit U, bits<5> opc, string asm,
3810 SDPatternOperator OpNode> {
3811 def v8i8 : BaseSIMDThreeSameVector<0, U, 0b00, opc, V64,
3812 asm, ".8b",
3813 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
3814 def v16i8 : BaseSIMDThreeSameVector<1, U, 0b00, opc, V128,
3815 asm, ".16b",
3816 [(set (v16i8 V128:$Rd),
3817 (OpNode (v16i8 V128:$Rn), (v16i8 V128:$Rm)))]>;
3818}
3819
3820// As above, but only S and D sized floating point elements supported.
3821multiclass SIMDThreeSameVectorFP<bit U, bit S, bits<5> opc,
3822 string asm, SDPatternOperator OpNode> {
3823 def v2f32 : BaseSIMDThreeSameVector<0, U, {S,0}, opc, V64,
3824 asm, ".2s",
3825 [(set (v2f32 V64:$Rd), (OpNode (v2f32 V64:$Rn), (v2f32 V64:$Rm)))]>;
3826 def v4f32 : BaseSIMDThreeSameVector<1, U, {S,0}, opc, V128,
3827 asm, ".4s",
3828 [(set (v4f32 V128:$Rd), (OpNode (v4f32 V128:$Rn), (v4f32 V128:$Rm)))]>;
3829 def v2f64 : BaseSIMDThreeSameVector<1, U, {S,1}, opc, V128,
3830 asm, ".2d",
3831 [(set (v2f64 V128:$Rd), (OpNode (v2f64 V128:$Rn), (v2f64 V128:$Rm)))]>;
3832}
3833
3834multiclass SIMDThreeSameVectorFPCmp<bit U, bit S, bits<5> opc,
3835 string asm,
3836 SDPatternOperator OpNode> {
3837 def v2f32 : BaseSIMDThreeSameVector<0, U, {S,0}, opc, V64,
3838 asm, ".2s",
3839 [(set (v2i32 V64:$Rd), (OpNode (v2f32 V64:$Rn), (v2f32 V64:$Rm)))]>;
3840 def v4f32 : BaseSIMDThreeSameVector<1, U, {S,0}, opc, V128,
3841 asm, ".4s",
3842 [(set (v4i32 V128:$Rd), (OpNode (v4f32 V128:$Rn), (v4f32 V128:$Rm)))]>;
3843 def v2f64 : BaseSIMDThreeSameVector<1, U, {S,1}, opc, V128,
3844 asm, ".2d",
3845 [(set (v2i64 V128:$Rd), (OpNode (v2f64 V128:$Rn), (v2f64 V128:$Rm)))]>;
3846}
3847
3848multiclass SIMDThreeSameVectorFPTied<bit U, bit S, bits<5> opc,
3849 string asm, SDPatternOperator OpNode> {
3850 def v2f32 : BaseSIMDThreeSameVectorTied<0, U, {S,0}, opc, V64,
3851 asm, ".2s",
3852 [(set (v2f32 V64:$dst),
3853 (OpNode (v2f32 V64:$Rd), (v2f32 V64:$Rn), (v2f32 V64:$Rm)))]>;
3854 def v4f32 : BaseSIMDThreeSameVectorTied<1, U, {S,0}, opc, V128,
3855 asm, ".4s",
3856 [(set (v4f32 V128:$dst),
3857 (OpNode (v4f32 V128:$Rd), (v4f32 V128:$Rn), (v4f32 V128:$Rm)))]>;
3858 def v2f64 : BaseSIMDThreeSameVectorTied<1, U, {S,1}, opc, V128,
3859 asm, ".2d",
3860 [(set (v2f64 V128:$dst),
3861 (OpNode (v2f64 V128:$Rd), (v2f64 V128:$Rn), (v2f64 V128:$Rm)))]>;
3862}
3863
3864// As above, but D and B sized elements unsupported.
3865multiclass SIMDThreeSameVectorHS<bit U, bits<5> opc, string asm,
3866 SDPatternOperator OpNode> {
3867 def v4i16 : BaseSIMDThreeSameVector<0, U, 0b01, opc, V64,
3868 asm, ".4h",
3869 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>;
3870 def v8i16 : BaseSIMDThreeSameVector<1, U, 0b01, opc, V128,
3871 asm, ".8h",
3872 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>;
3873 def v2i32 : BaseSIMDThreeSameVector<0, U, 0b10, opc, V64,
3874 asm, ".2s",
3875 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>;
3876 def v4i32 : BaseSIMDThreeSameVector<1, U, 0b10, opc, V128,
3877 asm, ".4s",
3878 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>;
3879}
3880
3881// Logical three vector ops share opcode bits, and only use B sized elements.
3882multiclass SIMDLogicalThreeVector<bit U, bits<2> size, string asm,
3883 SDPatternOperator OpNode = null_frag> {
3884 def v8i8 : BaseSIMDThreeSameVector<0, U, size, 0b00011, V64,
3885 asm, ".8b",
3886 [(set (v8i8 V64:$Rd), (OpNode V64:$Rn, V64:$Rm))]>;
3887 def v16i8 : BaseSIMDThreeSameVector<1, U, size, 0b00011, V128,
3888 asm, ".16b",
3889 [(set (v16i8 V128:$Rd), (OpNode V128:$Rn, V128:$Rm))]>;
3890
3891 def : Pat<(v4i16 (OpNode V64:$LHS, V64:$RHS)),
3892 (!cast<Instruction>(NAME#"v8i8") V64:$LHS, V64:$RHS)>;
3893 def : Pat<(v2i32 (OpNode V64:$LHS, V64:$RHS)),
3894 (!cast<Instruction>(NAME#"v8i8") V64:$LHS, V64:$RHS)>;
3895 def : Pat<(v1i64 (OpNode V64:$LHS, V64:$RHS)),
3896 (!cast<Instruction>(NAME#"v8i8") V64:$LHS, V64:$RHS)>;
3897
3898 def : Pat<(v8i16 (OpNode V128:$LHS, V128:$RHS)),
3899 (!cast<Instruction>(NAME#"v16i8") V128:$LHS, V128:$RHS)>;
3900 def : Pat<(v4i32 (OpNode V128:$LHS, V128:$RHS)),
3901 (!cast<Instruction>(NAME#"v16i8") V128:$LHS, V128:$RHS)>;
3902 def : Pat<(v2i64 (OpNode V128:$LHS, V128:$RHS)),
3903 (!cast<Instruction>(NAME#"v16i8") V128:$LHS, V128:$RHS)>;
3904}
3905
3906multiclass SIMDLogicalThreeVectorTied<bit U, bits<2> size,
3907 string asm, SDPatternOperator OpNode> {
3908 def v8i8 : BaseSIMDThreeSameVectorTied<0, U, size, 0b00011, V64,
3909 asm, ".8b",
3910 [(set (v8i8 V64:$dst),
3911 (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
3912 def v16i8 : BaseSIMDThreeSameVectorTied<1, U, size, 0b00011, V128,
3913 asm, ".16b",
3914 [(set (v16i8 V128:$dst),
3915 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn),
3916 (v16i8 V128:$Rm)))]>;
3917
3918 def : Pat<(v4i16 (OpNode (v4i16 V64:$LHS), (v4i16 V64:$MHS),
3919 (v4i16 V64:$RHS))),
3920 (!cast<Instruction>(NAME#"v8i8")
3921 V64:$LHS, V64:$MHS, V64:$RHS)>;
3922 def : Pat<(v2i32 (OpNode (v2i32 V64:$LHS), (v2i32 V64:$MHS),
3923 (v2i32 V64:$RHS))),
3924 (!cast<Instruction>(NAME#"v8i8")
3925 V64:$LHS, V64:$MHS, V64:$RHS)>;
3926 def : Pat<(v1i64 (OpNode (v1i64 V64:$LHS), (v1i64 V64:$MHS),
3927 (v1i64 V64:$RHS))),
3928 (!cast<Instruction>(NAME#"v8i8")
3929 V64:$LHS, V64:$MHS, V64:$RHS)>;
3930
3931 def : Pat<(v8i16 (OpNode (v8i16 V128:$LHS), (v8i16 V128:$MHS),
3932 (v8i16 V128:$RHS))),
3933 (!cast<Instruction>(NAME#"v16i8")
3934 V128:$LHS, V128:$MHS, V128:$RHS)>;
3935 def : Pat<(v4i32 (OpNode (v4i32 V128:$LHS), (v4i32 V128:$MHS),
3936 (v4i32 V128:$RHS))),
3937 (!cast<Instruction>(NAME#"v16i8")
3938 V128:$LHS, V128:$MHS, V128:$RHS)>;
3939 def : Pat<(v2i64 (OpNode (v2i64 V128:$LHS), (v2i64 V128:$MHS),
3940 (v2i64 V128:$RHS))),
3941 (!cast<Instruction>(NAME#"v16i8")
3942 V128:$LHS, V128:$MHS, V128:$RHS)>;
3943}
3944
3945
3946//----------------------------------------------------------------------------
3947// AdvSIMD two register vector instructions.
3948//----------------------------------------------------------------------------
3949
3950let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
3951class BaseSIMDTwoSameVector<bit Q, bit U, bits<2> size, bits<5> opcode,
3952 RegisterOperand regtype, string asm, string dstkind,
3953 string srckind, list<dag> pattern>
3954 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm,
3955 "{\t$Rd" # dstkind # ", $Rn" # srckind #
3956 "|" # dstkind # "\t$Rd, $Rn}", "", pattern>,
3957 Sched<[WriteV]> {
3958 bits<5> Rd;
3959 bits<5> Rn;
3960 let Inst{31} = 0;
3961 let Inst{30} = Q;
3962 let Inst{29} = U;
3963 let Inst{28-24} = 0b01110;
3964 let Inst{23-22} = size;
3965 let Inst{21-17} = 0b10000;
3966 let Inst{16-12} = opcode;
3967 let Inst{11-10} = 0b10;
3968 let Inst{9-5} = Rn;
3969 let Inst{4-0} = Rd;
3970}
3971
3972let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
3973class BaseSIMDTwoSameVectorTied<bit Q, bit U, bits<2> size, bits<5> opcode,
3974 RegisterOperand regtype, string asm, string dstkind,
3975 string srckind, list<dag> pattern>
3976 : I<(outs regtype:$dst), (ins regtype:$Rd, regtype:$Rn), asm,
3977 "{\t$Rd" # dstkind # ", $Rn" # srckind #
3978 "|" # dstkind # "\t$Rd, $Rn}", "$Rd = $dst", pattern>,
3979 Sched<[WriteV]> {
3980 bits<5> Rd;
3981 bits<5> Rn;
3982 let Inst{31} = 0;
3983 let Inst{30} = Q;
3984 let Inst{29} = U;
3985 let Inst{28-24} = 0b01110;
3986 let Inst{23-22} = size;
3987 let Inst{21-17} = 0b10000;
3988 let Inst{16-12} = opcode;
3989 let Inst{11-10} = 0b10;
3990 let Inst{9-5} = Rn;
3991 let Inst{4-0} = Rd;
3992}
3993
3994// Supports B, H, and S element sizes.
3995multiclass SIMDTwoVectorBHS<bit U, bits<5> opc, string asm,
3996 SDPatternOperator OpNode> {
3997 def v8i8 : BaseSIMDTwoSameVector<0, U, 0b00, opc, V64,
3998 asm, ".8b", ".8b",
3999 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>;
4000 def v16i8 : BaseSIMDTwoSameVector<1, U, 0b00, opc, V128,
4001 asm, ".16b", ".16b",
4002 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>;
4003 def v4i16 : BaseSIMDTwoSameVector<0, U, 0b01, opc, V64,
4004 asm, ".4h", ".4h",
4005 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>;
4006 def v8i16 : BaseSIMDTwoSameVector<1, U, 0b01, opc, V128,
4007 asm, ".8h", ".8h",
4008 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>;
4009 def v2i32 : BaseSIMDTwoSameVector<0, U, 0b10, opc, V64,
4010 asm, ".2s", ".2s",
4011 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>;
4012 def v4i32 : BaseSIMDTwoSameVector<1, U, 0b10, opc, V128,
4013 asm, ".4s", ".4s",
4014 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>;
4015}
4016
4017class BaseSIMDVectorLShiftLongBySize<bit Q, bits<2> size,
4018 RegisterOperand regtype, string asm, string dstkind,
4019 string srckind, string amount>
4020 : I<(outs V128:$Rd), (ins regtype:$Rn), asm,
4021 "{\t$Rd" # dstkind # ", $Rn" # srckind # ", #" # amount #
4022 "|" # dstkind # "\t$Rd, $Rn, #" # amount # "}", "", []>,
4023 Sched<[WriteV]> {
4024 bits<5> Rd;
4025 bits<5> Rn;
4026 let Inst{31} = 0;
4027 let Inst{30} = Q;
4028 let Inst{29-24} = 0b101110;
4029 let Inst{23-22} = size;
4030 let Inst{21-10} = 0b100001001110;
4031 let Inst{9-5} = Rn;
4032 let Inst{4-0} = Rd;
4033}
4034
4035multiclass SIMDVectorLShiftLongBySizeBHS {
4036 let neverHasSideEffects = 1 in {
4037 def v8i8 : BaseSIMDVectorLShiftLongBySize<0, 0b00, V64,
4038 "shll", ".8h", ".8b", "8">;
4039 def v16i8 : BaseSIMDVectorLShiftLongBySize<1, 0b00, V128,
4040 "shll2", ".8h", ".16b", "8">;
4041 def v4i16 : BaseSIMDVectorLShiftLongBySize<0, 0b01, V64,
4042 "shll", ".4s", ".4h", "16">;
4043 def v8i16 : BaseSIMDVectorLShiftLongBySize<1, 0b01, V128,
4044 "shll2", ".4s", ".8h", "16">;
4045 def v2i32 : BaseSIMDVectorLShiftLongBySize<0, 0b10, V64,
4046 "shll", ".2d", ".2s", "32">;
4047 def v4i32 : BaseSIMDVectorLShiftLongBySize<1, 0b10, V128,
4048 "shll2", ".2d", ".4s", "32">;
4049 }
4050}
4051
4052// Supports all element sizes.
4053multiclass SIMDLongTwoVector<bit U, bits<5> opc, string asm,
4054 SDPatternOperator OpNode> {
4055 def v8i8_v4i16 : BaseSIMDTwoSameVector<0, U, 0b00, opc, V64,
4056 asm, ".4h", ".8b",
4057 [(set (v4i16 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>;
4058 def v16i8_v8i16 : BaseSIMDTwoSameVector<1, U, 0b00, opc, V128,
4059 asm, ".8h", ".16b",
4060 [(set (v8i16 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>;
4061 def v4i16_v2i32 : BaseSIMDTwoSameVector<0, U, 0b01, opc, V64,
4062 asm, ".2s", ".4h",
4063 [(set (v2i32 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>;
4064 def v8i16_v4i32 : BaseSIMDTwoSameVector<1, U, 0b01, opc, V128,
4065 asm, ".4s", ".8h",
4066 [(set (v4i32 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>;
4067 def v2i32_v1i64 : BaseSIMDTwoSameVector<0, U, 0b10, opc, V64,
4068 asm, ".1d", ".2s",
4069 [(set (v1i64 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>;
4070 def v4i32_v2i64 : BaseSIMDTwoSameVector<1, U, 0b10, opc, V128,
4071 asm, ".2d", ".4s",
4072 [(set (v2i64 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>;
4073}
4074
4075multiclass SIMDLongTwoVectorTied<bit U, bits<5> opc, string asm,
4076 SDPatternOperator OpNode> {
4077 def v8i8_v4i16 : BaseSIMDTwoSameVectorTied<0, U, 0b00, opc, V64,
4078 asm, ".4h", ".8b",
4079 [(set (v4i16 V64:$dst), (OpNode (v4i16 V64:$Rd),
4080 (v8i8 V64:$Rn)))]>;
4081 def v16i8_v8i16 : BaseSIMDTwoSameVectorTied<1, U, 0b00, opc, V128,
4082 asm, ".8h", ".16b",
4083 [(set (v8i16 V128:$dst), (OpNode (v8i16 V128:$Rd),
4084 (v16i8 V128:$Rn)))]>;
4085 def v4i16_v2i32 : BaseSIMDTwoSameVectorTied<0, U, 0b01, opc, V64,
4086 asm, ".2s", ".4h",
4087 [(set (v2i32 V64:$dst), (OpNode (v2i32 V64:$Rd),
4088 (v4i16 V64:$Rn)))]>;
4089 def v8i16_v4i32 : BaseSIMDTwoSameVectorTied<1, U, 0b01, opc, V128,
4090 asm, ".4s", ".8h",
4091 [(set (v4i32 V128:$dst), (OpNode (v4i32 V128:$Rd),
4092 (v8i16 V128:$Rn)))]>;
4093 def v2i32_v1i64 : BaseSIMDTwoSameVectorTied<0, U, 0b10, opc, V64,
4094 asm, ".1d", ".2s",
4095 [(set (v1i64 V64:$dst), (OpNode (v1i64 V64:$Rd),
4096 (v2i32 V64:$Rn)))]>;
4097 def v4i32_v2i64 : BaseSIMDTwoSameVectorTied<1, U, 0b10, opc, V128,
4098 asm, ".2d", ".4s",
4099 [(set (v2i64 V128:$dst), (OpNode (v2i64 V128:$Rd),
4100 (v4i32 V128:$Rn)))]>;
4101}
4102
4103// Supports all element sizes, except 1xD.
4104multiclass SIMDTwoVectorBHSDTied<bit U, bits<5> opc, string asm,
4105 SDPatternOperator OpNode> {
4106 def v8i8 : BaseSIMDTwoSameVectorTied<0, U, 0b00, opc, V64,
4107 asm, ".8b", ".8b",
4108 [(set (v8i8 V64:$dst), (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn)))]>;
4109 def v16i8 : BaseSIMDTwoSameVectorTied<1, U, 0b00, opc, V128,
4110 asm, ".16b", ".16b",
4111 [(set (v16i8 V128:$dst), (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn)))]>;
4112 def v4i16 : BaseSIMDTwoSameVectorTied<0, U, 0b01, opc, V64,
4113 asm, ".4h", ".4h",
4114 [(set (v4i16 V64:$dst), (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn)))]>;
4115 def v8i16 : BaseSIMDTwoSameVectorTied<1, U, 0b01, opc, V128,
4116 asm, ".8h", ".8h",
4117 [(set (v8i16 V128:$dst), (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn)))]>;
4118 def v2i32 : BaseSIMDTwoSameVectorTied<0, U, 0b10, opc, V64,
4119 asm, ".2s", ".2s",
4120 [(set (v2i32 V64:$dst), (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn)))]>;
4121 def v4i32 : BaseSIMDTwoSameVectorTied<1, U, 0b10, opc, V128,
4122 asm, ".4s", ".4s",
4123 [(set (v4i32 V128:$dst), (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn)))]>;
4124 def v2i64 : BaseSIMDTwoSameVectorTied<1, U, 0b11, opc, V128,
4125 asm, ".2d", ".2d",
4126 [(set (v2i64 V128:$dst), (OpNode (v2i64 V128:$Rd), (v2i64 V128:$Rn)))]>;
4127}
4128
4129multiclass SIMDTwoVectorBHSD<bit U, bits<5> opc, string asm,
4130 SDPatternOperator OpNode = null_frag> {
4131 def v8i8 : BaseSIMDTwoSameVector<0, U, 0b00, opc, V64,
4132 asm, ".8b", ".8b",
4133 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>;
4134 def v16i8 : BaseSIMDTwoSameVector<1, U, 0b00, opc, V128,
4135 asm, ".16b", ".16b",
4136 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>;
4137 def v4i16 : BaseSIMDTwoSameVector<0, U, 0b01, opc, V64,
4138 asm, ".4h", ".4h",
4139 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>;
4140 def v8i16 : BaseSIMDTwoSameVector<1, U, 0b01, opc, V128,
4141 asm, ".8h", ".8h",
4142 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>;
4143 def v2i32 : BaseSIMDTwoSameVector<0, U, 0b10, opc, V64,
4144 asm, ".2s", ".2s",
4145 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>;
4146 def v4i32 : BaseSIMDTwoSameVector<1, U, 0b10, opc, V128,
4147 asm, ".4s", ".4s",
4148 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>;
4149 def v2i64 : BaseSIMDTwoSameVector<1, U, 0b11, opc, V128,
4150 asm, ".2d", ".2d",
4151 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn)))]>;
4152}
4153
4154
4155// Supports only B element sizes.
4156multiclass SIMDTwoVectorB<bit U, bits<2> size, bits<5> opc, string asm,
4157 SDPatternOperator OpNode> {
4158 def v8i8 : BaseSIMDTwoSameVector<0, U, size, opc, V64,
4159 asm, ".8b", ".8b",
4160 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>;
4161 def v16i8 : BaseSIMDTwoSameVector<1, U, size, opc, V128,
4162 asm, ".16b", ".16b",
4163 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>;
4164
4165}
4166
4167// Supports only B and H element sizes.
4168multiclass SIMDTwoVectorBH<bit U, bits<5> opc, string asm,
4169 SDPatternOperator OpNode> {
4170 def v8i8 : BaseSIMDTwoSameVector<0, U, 0b00, opc, V64,
4171 asm, ".8b", ".8b",
4172 [(set (v8i8 V64:$Rd), (OpNode V64:$Rn))]>;
4173 def v16i8 : BaseSIMDTwoSameVector<1, U, 0b00, opc, V128,
4174 asm, ".16b", ".16b",
4175 [(set (v16i8 V128:$Rd), (OpNode V128:$Rn))]>;
4176 def v4i16 : BaseSIMDTwoSameVector<0, U, 0b01, opc, V64,
4177 asm, ".4h", ".4h",
4178 [(set (v4i16 V64:$Rd), (OpNode V64:$Rn))]>;
4179 def v8i16 : BaseSIMDTwoSameVector<1, U, 0b01, opc, V128,
4180 asm, ".8h", ".8h",
4181 [(set (v8i16 V128:$Rd), (OpNode V128:$Rn))]>;
4182}
4183
4184// Supports only S and D element sizes, uses high bit of the size field
4185// as an extra opcode bit.
4186multiclass SIMDTwoVectorFP<bit U, bit S, bits<5> opc, string asm,
4187 SDPatternOperator OpNode> {
4188 def v2f32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, V64,
4189 asm, ".2s", ".2s",
4190 [(set (v2f32 V64:$Rd), (OpNode (v2f32 V64:$Rn)))]>;
4191 def v4f32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, V128,
4192 asm, ".4s", ".4s",
4193 [(set (v4f32 V128:$Rd), (OpNode (v4f32 V128:$Rn)))]>;
4194 def v2f64 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, V128,
4195 asm, ".2d", ".2d",
4196 [(set (v2f64 V128:$Rd), (OpNode (v2f64 V128:$Rn)))]>;
4197}
4198
4199// Supports only S element size.
4200multiclass SIMDTwoVectorS<bit U, bit S, bits<5> opc, string asm,
4201 SDPatternOperator OpNode> {
4202 def v2i32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, V64,
4203 asm, ".2s", ".2s",
4204 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>;
4205 def v4i32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, V128,
4206 asm, ".4s", ".4s",
4207 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>;
4208}
4209
4210
4211multiclass SIMDTwoVectorFPToInt<bit U, bit S, bits<5> opc, string asm,
4212 SDPatternOperator OpNode> {
4213 def v2f32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, V64,
4214 asm, ".2s", ".2s",
4215 [(set (v2i32 V64:$Rd), (OpNode (v2f32 V64:$Rn)))]>;
4216 def v4f32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, V128,
4217 asm, ".4s", ".4s",
4218 [(set (v4i32 V128:$Rd), (OpNode (v4f32 V128:$Rn)))]>;
4219 def v2f64 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, V128,
4220 asm, ".2d", ".2d",
4221 [(set (v2i64 V128:$Rd), (OpNode (v2f64 V128:$Rn)))]>;
4222}
4223
4224multiclass SIMDTwoVectorIntToFP<bit U, bit S, bits<5> opc, string asm,
4225 SDPatternOperator OpNode> {
4226 def v2f32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, V64,
4227 asm, ".2s", ".2s",
4228 [(set (v2f32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>;
4229 def v4f32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, V128,
4230 asm, ".4s", ".4s",
4231 [(set (v4f32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>;
4232 def v2f64 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, V128,
4233 asm, ".2d", ".2d",
4234 [(set (v2f64 V128:$Rd), (OpNode (v2i64 V128:$Rn)))]>;
4235}
4236
4237
4238class BaseSIMDMixedTwoVector<bit Q, bit U, bits<2> size, bits<5> opcode,
4239 RegisterOperand inreg, RegisterOperand outreg,
4240 string asm, string outkind, string inkind,
4241 list<dag> pattern>
4242 : I<(outs outreg:$Rd), (ins inreg:$Rn), asm,
4243 "{\t$Rd" # outkind # ", $Rn" # inkind #
4244 "|" # outkind # "\t$Rd, $Rn}", "", pattern>,
4245 Sched<[WriteV]> {
4246 bits<5> Rd;
4247 bits<5> Rn;
4248 let Inst{31} = 0;
4249 let Inst{30} = Q;
4250 let Inst{29} = U;
4251 let Inst{28-24} = 0b01110;
4252 let Inst{23-22} = size;
4253 let Inst{21-17} = 0b10000;
4254 let Inst{16-12} = opcode;
4255 let Inst{11-10} = 0b10;
4256 let Inst{9-5} = Rn;
4257 let Inst{4-0} = Rd;
4258}
4259
4260class BaseSIMDMixedTwoVectorTied<bit Q, bit U, bits<2> size, bits<5> opcode,
4261 RegisterOperand inreg, RegisterOperand outreg,
4262 string asm, string outkind, string inkind,
4263 list<dag> pattern>
4264 : I<(outs outreg:$dst), (ins outreg:$Rd, inreg:$Rn), asm,
4265 "{\t$Rd" # outkind # ", $Rn" # inkind #
4266 "|" # outkind # "\t$Rd, $Rn}", "$Rd = $dst", pattern>,
4267 Sched<[WriteV]> {
4268 bits<5> Rd;
4269 bits<5> Rn;
4270 let Inst{31} = 0;
4271 let Inst{30} = Q;
4272 let Inst{29} = U;
4273 let Inst{28-24} = 0b01110;
4274 let Inst{23-22} = size;
4275 let Inst{21-17} = 0b10000;
4276 let Inst{16-12} = opcode;
4277 let Inst{11-10} = 0b10;
4278 let Inst{9-5} = Rn;
4279 let Inst{4-0} = Rd;
4280}
4281
4282multiclass SIMDMixedTwoVector<bit U, bits<5> opc, string asm,
4283 SDPatternOperator OpNode> {
4284 def v8i8 : BaseSIMDMixedTwoVector<0, U, 0b00, opc, V128, V64,
4285 asm, ".8b", ".8h",
4286 [(set (v8i8 V64:$Rd), (OpNode (v8i16 V128:$Rn)))]>;
4287 def v16i8 : BaseSIMDMixedTwoVectorTied<1, U, 0b00, opc, V128, V128,
4288 asm#"2", ".16b", ".8h", []>;
4289 def v4i16 : BaseSIMDMixedTwoVector<0, U, 0b01, opc, V128, V64,
4290 asm, ".4h", ".4s",
4291 [(set (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn)))]>;
4292 def v8i16 : BaseSIMDMixedTwoVectorTied<1, U, 0b01, opc, V128, V128,
4293 asm#"2", ".8h", ".4s", []>;
4294 def v2i32 : BaseSIMDMixedTwoVector<0, U, 0b10, opc, V128, V64,
4295 asm, ".2s", ".2d",
4296 [(set (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn)))]>;
4297 def v4i32 : BaseSIMDMixedTwoVectorTied<1, U, 0b10, opc, V128, V128,
4298 asm#"2", ".4s", ".2d", []>;
4299
4300 def : Pat<(concat_vectors (v8i8 V64:$Rd), (OpNode (v8i16 V128:$Rn))),
4301 (!cast<Instruction>(NAME # "v16i8")
4302 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>;
4303 def : Pat<(concat_vectors (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn))),
4304 (!cast<Instruction>(NAME # "v8i16")
4305 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>;
4306 def : Pat<(concat_vectors (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn))),
4307 (!cast<Instruction>(NAME # "v4i32")
4308 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>;
4309}
4310
4311class BaseSIMDCmpTwoVector<bit Q, bit U, bits<2> size, bits<5> opcode,
4312 RegisterOperand regtype, string asm, string kind,
4313 ValueType dty, ValueType sty, SDNode OpNode>
4314 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm,
4315 "{\t$Rd" # kind # ", $Rn" # kind # ", #0" #
4316 "|" # kind # "\t$Rd, $Rn, #0}", "",
4317 [(set (dty regtype:$Rd), (OpNode (sty regtype:$Rn)))]>,
4318 Sched<[WriteV]> {
4319 bits<5> Rd;
4320 bits<5> Rn;
4321 let Inst{31} = 0;
4322 let Inst{30} = Q;
4323 let Inst{29} = U;
4324 let Inst{28-24} = 0b01110;
4325 let Inst{23-22} = size;
4326 let Inst{21-17} = 0b10000;
4327 let Inst{16-12} = opcode;
4328 let Inst{11-10} = 0b10;
4329 let Inst{9-5} = Rn;
4330 let Inst{4-0} = Rd;
4331}
4332
4333// Comparisons support all element sizes, except 1xD.
4334multiclass SIMDCmpTwoVector<bit U, bits<5> opc, string asm,
4335 SDNode OpNode> {
4336 def v8i8rz : BaseSIMDCmpTwoVector<0, U, 0b00, opc, V64,
4337 asm, ".8b",
4338 v8i8, v8i8, OpNode>;
4339 def v16i8rz : BaseSIMDCmpTwoVector<1, U, 0b00, opc, V128,
4340 asm, ".16b",
4341 v16i8, v16i8, OpNode>;
4342 def v4i16rz : BaseSIMDCmpTwoVector<0, U, 0b01, opc, V64,
4343 asm, ".4h",
4344 v4i16, v4i16, OpNode>;
4345 def v8i16rz : BaseSIMDCmpTwoVector<1, U, 0b01, opc, V128,
4346 asm, ".8h",
4347 v8i16, v8i16, OpNode>;
4348 def v2i32rz : BaseSIMDCmpTwoVector<0, U, 0b10, opc, V64,
4349 asm, ".2s",
4350 v2i32, v2i32, OpNode>;
4351 def v4i32rz : BaseSIMDCmpTwoVector<1, U, 0b10, opc, V128,
4352 asm, ".4s",
4353 v4i32, v4i32, OpNode>;
4354 def v2i64rz : BaseSIMDCmpTwoVector<1, U, 0b11, opc, V128,
4355 asm, ".2d",
4356 v2i64, v2i64, OpNode>;
4357}
4358
4359// FP Comparisons support only S and D element sizes.
4360multiclass SIMDFPCmpTwoVector<bit U, bit S, bits<5> opc,
4361 string asm, SDNode OpNode> {
4362 def v2i32rz : BaseSIMDCmpTwoVector<0, U, {S,0}, opc, V64,
4363 asm, ".2s",
4364 v2i32, v2f32, OpNode>;
4365 def v4i32rz : BaseSIMDCmpTwoVector<1, U, {S,0}, opc, V128,
4366 asm, ".4s",
4367 v4i32, v4f32, OpNode>;
4368 def v2i64rz : BaseSIMDCmpTwoVector<1, U, {S,1}, opc, V128,
4369 asm, ".2d",
4370 v2i64, v2f64, OpNode>;
4371}
4372
4373let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
4374class BaseSIMDFPCvtTwoVector<bit Q, bit U, bits<2> size, bits<5> opcode,
4375 RegisterOperand outtype, RegisterOperand intype,
4376 string asm, string VdTy, string VnTy,
4377 list<dag> pattern>
4378 : I<(outs outtype:$Rd), (ins intype:$Rn), asm,
4379 !strconcat("\t$Rd", VdTy, ", $Rn", VnTy), "", pattern>,
4380 Sched<[WriteV]> {
4381 bits<5> Rd;
4382 bits<5> Rn;
4383 let Inst{31} = 0;
4384 let Inst{30} = Q;
4385 let Inst{29} = U;
4386 let Inst{28-24} = 0b01110;
4387 let Inst{23-22} = size;
4388 let Inst{21-17} = 0b10000;
4389 let Inst{16-12} = opcode;
4390 let Inst{11-10} = 0b10;
4391 let Inst{9-5} = Rn;
4392 let Inst{4-0} = Rd;
4393}
4394
4395class BaseSIMDFPCvtTwoVectorTied<bit Q, bit U, bits<2> size, bits<5> opcode,
4396 RegisterOperand outtype, RegisterOperand intype,
4397 string asm, string VdTy, string VnTy,
4398 list<dag> pattern>
4399 : I<(outs outtype:$dst), (ins outtype:$Rd, intype:$Rn), asm,
4400 !strconcat("\t$Rd", VdTy, ", $Rn", VnTy), "$Rd = $dst", pattern>,
4401 Sched<[WriteV]> {
4402 bits<5> Rd;
4403 bits<5> Rn;
4404 let Inst{31} = 0;
4405 let Inst{30} = Q;
4406 let Inst{29} = U;
4407 let Inst{28-24} = 0b01110;
4408 let Inst{23-22} = size;
4409 let Inst{21-17} = 0b10000;
4410 let Inst{16-12} = opcode;
4411 let Inst{11-10} = 0b10;
4412 let Inst{9-5} = Rn;
4413 let Inst{4-0} = Rd;
4414}
4415
4416multiclass SIMDFPWidenTwoVector<bit U, bit S, bits<5> opc, string asm> {
4417 def v4i16 : BaseSIMDFPCvtTwoVector<0, U, {S,0}, opc, V128, V64,
4418 asm, ".4s", ".4h", []>;
4419 def v8i16 : BaseSIMDFPCvtTwoVector<1, U, {S,0}, opc, V128, V128,
4420 asm#"2", ".4s", ".8h", []>;
4421 def v2i32 : BaseSIMDFPCvtTwoVector<0, U, {S,1}, opc, V128, V64,
4422 asm, ".2d", ".2s", []>;
4423 def v4i32 : BaseSIMDFPCvtTwoVector<1, U, {S,1}, opc, V128, V128,
4424 asm#"2", ".2d", ".4s", []>;
4425}
4426
4427multiclass SIMDFPNarrowTwoVector<bit U, bit S, bits<5> opc, string asm> {
4428 def v4i16 : BaseSIMDFPCvtTwoVector<0, U, {S,0}, opc, V64, V128,
4429 asm, ".4h", ".4s", []>;
4430 def v8i16 : BaseSIMDFPCvtTwoVectorTied<1, U, {S,0}, opc, V128, V128,
4431 asm#"2", ".8h", ".4s", []>;
4432 def v2i32 : BaseSIMDFPCvtTwoVector<0, U, {S,1}, opc, V64, V128,
4433 asm, ".2s", ".2d", []>;
4434 def v4i32 : BaseSIMDFPCvtTwoVectorTied<1, U, {S,1}, opc, V128, V128,
4435 asm#"2", ".4s", ".2d", []>;
4436}
4437
4438multiclass SIMDFPInexactCvtTwoVector<bit U, bit S, bits<5> opc, string asm,
4439 Intrinsic OpNode> {
4440 def v2f32 : BaseSIMDFPCvtTwoVector<0, U, {S,1}, opc, V64, V128,
4441 asm, ".2s", ".2d",
4442 [(set (v2f32 V64:$Rd), (OpNode (v2f64 V128:$Rn)))]>;
4443 def v4f32 : BaseSIMDFPCvtTwoVectorTied<1, U, {S,1}, opc, V128, V128,
4444 asm#"2", ".4s", ".2d", []>;
4445
4446 def : Pat<(concat_vectors (v2f32 V64:$Rd), (OpNode (v2f64 V128:$Rn))),
4447 (!cast<Instruction>(NAME # "v4f32")
4448 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>;
4449}
4450
4451//----------------------------------------------------------------------------
4452// AdvSIMD three register different-size vector instructions.
4453//----------------------------------------------------------------------------
4454
4455let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
4456class BaseSIMDDifferentThreeVector<bit U, bits<3> size, bits<4> opcode,
4457 RegisterOperand outtype, RegisterOperand intype1,
4458 RegisterOperand intype2, string asm,
4459 string outkind, string inkind1, string inkind2,
4460 list<dag> pattern>
4461 : I<(outs outtype:$Rd), (ins intype1:$Rn, intype2:$Rm), asm,
4462 "{\t$Rd" # outkind # ", $Rn" # inkind1 # ", $Rm" # inkind2 #
4463 "|" # outkind # "\t$Rd, $Rn, $Rm}", "", pattern>,
4464 Sched<[WriteV]> {
4465 bits<5> Rd;
4466 bits<5> Rn;
4467 bits<5> Rm;
4468 let Inst{31} = 0;
4469 let Inst{30} = size{0};
4470 let Inst{29} = U;
4471 let Inst{28-24} = 0b01110;
4472 let Inst{23-22} = size{2-1};
4473 let Inst{21} = 1;
4474 let Inst{20-16} = Rm;
4475 let Inst{15-12} = opcode;
4476 let Inst{11-10} = 0b00;
4477 let Inst{9-5} = Rn;
4478 let Inst{4-0} = Rd;
4479}
4480
4481let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
4482class BaseSIMDDifferentThreeVectorTied<bit U, bits<3> size, bits<4> opcode,
4483 RegisterOperand outtype, RegisterOperand intype1,
4484 RegisterOperand intype2, string asm,
4485 string outkind, string inkind1, string inkind2,
4486 list<dag> pattern>
4487 : I<(outs outtype:$dst), (ins outtype:$Rd, intype1:$Rn, intype2:$Rm), asm,
4488 "{\t$Rd" # outkind # ", $Rn" # inkind1 # ", $Rm" # inkind2 #
4489 "|" # outkind # "\t$Rd, $Rn, $Rm}", "$Rd = $dst", pattern>,
4490 Sched<[WriteV]> {
4491 bits<5> Rd;
4492 bits<5> Rn;
4493 bits<5> Rm;
4494 let Inst{31} = 0;
4495 let Inst{30} = size{0};
4496 let Inst{29} = U;
4497 let Inst{28-24} = 0b01110;
4498 let Inst{23-22} = size{2-1};
4499 let Inst{21} = 1;
4500 let Inst{20-16} = Rm;
4501 let Inst{15-12} = opcode;
4502 let Inst{11-10} = 0b00;
4503 let Inst{9-5} = Rn;
4504 let Inst{4-0} = Rd;
4505}
4506
4507// FIXME: TableGen doesn't know how to deal with expanded types that also
4508// change the element count (in this case, placing the results in
4509// the high elements of the result register rather than the low
4510// elements). Until that's fixed, we can't code-gen those.
4511multiclass SIMDNarrowThreeVectorBHS<bit U, bits<4> opc, string asm,
4512 Intrinsic IntOp> {
4513 def v8i16_v8i8 : BaseSIMDDifferentThreeVector<U, 0b000, opc,
4514 V64, V128, V128,
4515 asm, ".8b", ".8h", ".8h",
4516 [(set (v8i8 V64:$Rd), (IntOp (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>;
4517 def v8i16_v16i8 : BaseSIMDDifferentThreeVectorTied<U, 0b001, opc,
4518 V128, V128, V128,
4519 asm#"2", ".16b", ".8h", ".8h",
4520 []>;
4521 def v4i32_v4i16 : BaseSIMDDifferentThreeVector<U, 0b010, opc,
4522 V64, V128, V128,
4523 asm, ".4h", ".4s", ".4s",
4524 [(set (v4i16 V64:$Rd), (IntOp (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>;
4525 def v4i32_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc,
4526 V128, V128, V128,
4527 asm#"2", ".8h", ".4s", ".4s",
4528 []>;
4529 def v2i64_v2i32 : BaseSIMDDifferentThreeVector<U, 0b100, opc,
4530 V64, V128, V128,
4531 asm, ".2s", ".2d", ".2d",
4532 [(set (v2i32 V64:$Rd), (IntOp (v2i64 V128:$Rn), (v2i64 V128:$Rm)))]>;
4533 def v2i64_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc,
4534 V128, V128, V128,
4535 asm#"2", ".4s", ".2d", ".2d",
4536 []>;
4537
4538
4539 // Patterns for the '2' variants involve INSERT_SUBREG, which you can't put in
4540 // a version attached to an instruction.
4541 def : Pat<(concat_vectors (v8i8 V64:$Rd), (IntOp (v8i16 V128:$Rn),
4542 (v8i16 V128:$Rm))),
4543 (!cast<Instruction>(NAME # "v8i16_v16i8")
4544 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub),
4545 V128:$Rn, V128:$Rm)>;
4546 def : Pat<(concat_vectors (v4i16 V64:$Rd), (IntOp (v4i32 V128:$Rn),
4547 (v4i32 V128:$Rm))),
4548 (!cast<Instruction>(NAME # "v4i32_v8i16")
4549 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub),
4550 V128:$Rn, V128:$Rm)>;
4551 def : Pat<(concat_vectors (v2i32 V64:$Rd), (IntOp (v2i64 V128:$Rn),
4552 (v2i64 V128:$Rm))),
4553 (!cast<Instruction>(NAME # "v2i64_v4i32")
4554 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub),
4555 V128:$Rn, V128:$Rm)>;
4556}
4557
4558multiclass SIMDDifferentThreeVectorBD<bit U, bits<4> opc, string asm,
4559 Intrinsic IntOp> {
4560 def v8i8 : BaseSIMDDifferentThreeVector<U, 0b000, opc,
4561 V128, V64, V64,
4562 asm, ".8h", ".8b", ".8b",
4563 [(set (v8i16 V128:$Rd), (IntOp (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
4564 def v16i8 : BaseSIMDDifferentThreeVector<U, 0b001, opc,
4565 V128, V128, V128,
4566 asm#"2", ".8h", ".16b", ".16b", []>;
4567 def v1i64 : BaseSIMDDifferentThreeVector<U, 0b110, opc,
4568 V128, V64, V64,
4569 asm, ".1q", ".1d", ".1d", []>;
4570 def v2i64 : BaseSIMDDifferentThreeVector<U, 0b111, opc,
4571 V128, V128, V128,
4572 asm#"2", ".1q", ".2d", ".2d", []>;
4573
4574 def : Pat<(v8i16 (IntOp (v8i8 (extract_high_v16i8 V128:$Rn)),
4575 (v8i8 (extract_high_v16i8 V128:$Rm)))),
4576 (!cast<Instruction>(NAME#"v16i8") V128:$Rn, V128:$Rm)>;
4577}
4578
4579multiclass SIMDLongThreeVectorHS<bit U, bits<4> opc, string asm,
4580 SDPatternOperator OpNode> {
4581 def v4i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b010, opc,
4582 V128, V64, V64,
4583 asm, ".4s", ".4h", ".4h",
4584 [(set (v4i32 V128:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>;
4585 def v8i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b011, opc,
4586 V128, V128, V128,
4587 asm#"2", ".4s", ".8h", ".8h",
4588 [(set (v4i32 V128:$Rd), (OpNode (extract_high_v8i16 V128:$Rn),
4589 (extract_high_v8i16 V128:$Rm)))]>;
4590 def v2i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b100, opc,
4591 V128, V64, V64,
4592 asm, ".2d", ".2s", ".2s",
4593 [(set (v2i64 V128:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>;
4594 def v4i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b101, opc,
4595 V128, V128, V128,
4596 asm#"2", ".2d", ".4s", ".4s",
4597 [(set (v2i64 V128:$Rd), (OpNode (extract_high_v4i32 V128:$Rn),
4598 (extract_high_v4i32 V128:$Rm)))]>;
4599}
4600
4601multiclass SIMDLongThreeVectorBHSabdl<bit U, bits<4> opc, string asm,
4602 SDPatternOperator OpNode = null_frag> {
4603 def v8i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b000, opc,
4604 V128, V64, V64,
4605 asm, ".8h", ".8b", ".8b",
4606 [(set (v8i16 V128:$Rd),
4607 (zext (v8i8 (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))))]>;
4608 def v16i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b001, opc,
4609 V128, V128, V128,
4610 asm#"2", ".8h", ".16b", ".16b",
4611 [(set (v8i16 V128:$Rd),
4612 (zext (v8i8 (OpNode (extract_high_v16i8 V128:$Rn),
4613 (extract_high_v16i8 V128:$Rm)))))]>;
4614 def v4i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b010, opc,
4615 V128, V64, V64,
4616 asm, ".4s", ".4h", ".4h",
4617 [(set (v4i32 V128:$Rd),
4618 (zext (v4i16 (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))))]>;
4619 def v8i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b011, opc,
4620 V128, V128, V128,
4621 asm#"2", ".4s", ".8h", ".8h",
4622 [(set (v4i32 V128:$Rd),
4623 (zext (v4i16 (OpNode (extract_high_v8i16 V128:$Rn),
4624 (extract_high_v8i16 V128:$Rm)))))]>;
4625 def v2i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b100, opc,
4626 V128, V64, V64,
4627 asm, ".2d", ".2s", ".2s",
4628 [(set (v2i64 V128:$Rd),
4629 (zext (v2i32 (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))))]>;
4630 def v4i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b101, opc,
4631 V128, V128, V128,
4632 asm#"2", ".2d", ".4s", ".4s",
4633 [(set (v2i64 V128:$Rd),
4634 (zext (v2i32 (OpNode (extract_high_v4i32 V128:$Rn),
4635 (extract_high_v4i32 V128:$Rm)))))]>;
4636}
4637
4638multiclass SIMDLongThreeVectorTiedBHSabal<bit U, bits<4> opc,
4639 string asm,
4640 SDPatternOperator OpNode> {
4641 def v8i8_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b000, opc,
4642 V128, V64, V64,
4643 asm, ".8h", ".8b", ".8b",
4644 [(set (v8i16 V128:$dst),
4645 (add (v8i16 V128:$Rd),
4646 (zext (v8i8 (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm))))))]>;
4647 def v16i8_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b001, opc,
4648 V128, V128, V128,
4649 asm#"2", ".8h", ".16b", ".16b",
4650 [(set (v8i16 V128:$dst),
4651 (add (v8i16 V128:$Rd),
4652 (zext (v8i8 (OpNode (extract_high_v16i8 V128:$Rn),
4653 (extract_high_v16i8 V128:$Rm))))))]>;
4654 def v4i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b010, opc,
4655 V128, V64, V64,
4656 asm, ".4s", ".4h", ".4h",
4657 [(set (v4i32 V128:$dst),
4658 (add (v4i32 V128:$Rd),
4659 (zext (v4i16 (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm))))))]>;
4660 def v8i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc,
4661 V128, V128, V128,
4662 asm#"2", ".4s", ".8h", ".8h",
4663 [(set (v4i32 V128:$dst),
4664 (add (v4i32 V128:$Rd),
4665 (zext (v4i16 (OpNode (extract_high_v8i16 V128:$Rn),
4666 (extract_high_v8i16 V128:$Rm))))))]>;
4667 def v2i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b100, opc,
4668 V128, V64, V64,
4669 asm, ".2d", ".2s", ".2s",
4670 [(set (v2i64 V128:$dst),
4671 (add (v2i64 V128:$Rd),
4672 (zext (v2i32 (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm))))))]>;
4673 def v4i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc,
4674 V128, V128, V128,
4675 asm#"2", ".2d", ".4s", ".4s",
4676 [(set (v2i64 V128:$dst),
4677 (add (v2i64 V128:$Rd),
4678 (zext (v2i32 (OpNode (extract_high_v4i32 V128:$Rn),
4679 (extract_high_v4i32 V128:$Rm))))))]>;
4680}
4681
4682multiclass SIMDLongThreeVectorBHS<bit U, bits<4> opc, string asm,
4683 SDPatternOperator OpNode = null_frag> {
4684 def v8i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b000, opc,
4685 V128, V64, V64,
4686 asm, ".8h", ".8b", ".8b",
4687 [(set (v8i16 V128:$Rd), (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
4688 def v16i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b001, opc,
4689 V128, V128, V128,
4690 asm#"2", ".8h", ".16b", ".16b",
4691 [(set (v8i16 V128:$Rd), (OpNode (extract_high_v16i8 V128:$Rn),
4692 (extract_high_v16i8 V128:$Rm)))]>;
4693 def v4i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b010, opc,
4694 V128, V64, V64,
4695 asm, ".4s", ".4h", ".4h",
4696 [(set (v4i32 V128:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>;
4697 def v8i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b011, opc,
4698 V128, V128, V128,
4699 asm#"2", ".4s", ".8h", ".8h",
4700 [(set (v4i32 V128:$Rd), (OpNode (extract_high_v8i16 V128:$Rn),
4701 (extract_high_v8i16 V128:$Rm)))]>;
4702 def v2i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b100, opc,
4703 V128, V64, V64,
4704 asm, ".2d", ".2s", ".2s",
4705 [(set (v2i64 V128:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>;
4706 def v4i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b101, opc,
4707 V128, V128, V128,
4708 asm#"2", ".2d", ".4s", ".4s",
4709 [(set (v2i64 V128:$Rd), (OpNode (extract_high_v4i32 V128:$Rn),
4710 (extract_high_v4i32 V128:$Rm)))]>;
4711}
4712
4713multiclass SIMDLongThreeVectorTiedBHS<bit U, bits<4> opc,
4714 string asm,
4715 SDPatternOperator OpNode> {
4716 def v8i8_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b000, opc,
4717 V128, V64, V64,
4718 asm, ".8h", ".8b", ".8b",
4719 [(set (v8i16 V128:$dst),
4720 (OpNode (v8i16 V128:$Rd), (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
4721 def v16i8_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b001, opc,
4722 V128, V128, V128,
4723 asm#"2", ".8h", ".16b", ".16b",
4724 [(set (v8i16 V128:$dst),
4725 (OpNode (v8i16 V128:$Rd),
4726 (extract_high_v16i8 V128:$Rn),
4727 (extract_high_v16i8 V128:$Rm)))]>;
4728 def v4i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b010, opc,
4729 V128, V64, V64,
4730 asm, ".4s", ".4h", ".4h",
4731 [(set (v4i32 V128:$dst),
4732 (OpNode (v4i32 V128:$Rd), (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>;
4733 def v8i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc,
4734 V128, V128, V128,
4735 asm#"2", ".4s", ".8h", ".8h",
4736 [(set (v4i32 V128:$dst),
4737 (OpNode (v4i32 V128:$Rd),
4738 (extract_high_v8i16 V128:$Rn),
4739 (extract_high_v8i16 V128:$Rm)))]>;
4740 def v2i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b100, opc,
4741 V128, V64, V64,
4742 asm, ".2d", ".2s", ".2s",
4743 [(set (v2i64 V128:$dst),
4744 (OpNode (v2i64 V128:$Rd), (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>;
4745 def v4i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc,
4746 V128, V128, V128,
4747 asm#"2", ".2d", ".4s", ".4s",
4748 [(set (v2i64 V128:$dst),
4749 (OpNode (v2i64 V128:$Rd),
4750 (extract_high_v4i32 V128:$Rn),
4751 (extract_high_v4i32 V128:$Rm)))]>;
4752}
4753
4754multiclass SIMDLongThreeVectorSQDMLXTiedHS<bit U, bits<4> opc, string asm,
4755 SDPatternOperator Accum> {
4756 def v4i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b010, opc,
4757 V128, V64, V64,
4758 asm, ".4s", ".4h", ".4h",
4759 [(set (v4i32 V128:$dst),
4760 (Accum (v4i32 V128:$Rd),
4761 (v4i32 (int_arm64_neon_sqdmull (v4i16 V64:$Rn),
4762 (v4i16 V64:$Rm)))))]>;
4763 def v8i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc,
4764 V128, V128, V128,
4765 asm#"2", ".4s", ".8h", ".8h",
4766 [(set (v4i32 V128:$dst),
4767 (Accum (v4i32 V128:$Rd),
4768 (v4i32 (int_arm64_neon_sqdmull (extract_high_v8i16 V128:$Rn),
4769 (extract_high_v8i16 V128:$Rm)))))]>;
4770 def v2i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b100, opc,
4771 V128, V64, V64,
4772 asm, ".2d", ".2s", ".2s",
4773 [(set (v2i64 V128:$dst),
4774 (Accum (v2i64 V128:$Rd),
4775 (v2i64 (int_arm64_neon_sqdmull (v2i32 V64:$Rn),
4776 (v2i32 V64:$Rm)))))]>;
4777 def v4i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc,
4778 V128, V128, V128,
4779 asm#"2", ".2d", ".4s", ".4s",
4780 [(set (v2i64 V128:$dst),
4781 (Accum (v2i64 V128:$Rd),
4782 (v2i64 (int_arm64_neon_sqdmull (extract_high_v4i32 V128:$Rn),
4783 (extract_high_v4i32 V128:$Rm)))))]>;
4784}
4785
4786multiclass SIMDWideThreeVectorBHS<bit U, bits<4> opc, string asm,
4787 SDPatternOperator OpNode> {
4788 def v8i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b000, opc,
4789 V128, V128, V64,
4790 asm, ".8h", ".8h", ".8b",
4791 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (v8i8 V64:$Rm)))]>;
4792 def v16i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b001, opc,
4793 V128, V128, V128,
4794 asm#"2", ".8h", ".8h", ".16b",
4795 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn),
4796 (extract_high_v16i8 V128:$Rm)))]>;
4797 def v4i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b010, opc,
4798 V128, V128, V64,
4799 asm, ".4s", ".4s", ".4h",
4800 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (v4i16 V64:$Rm)))]>;
4801 def v8i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b011, opc,
4802 V128, V128, V128,
4803 asm#"2", ".4s", ".4s", ".8h",
4804 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn),
4805 (extract_high_v8i16 V128:$Rm)))]>;
4806 def v2i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b100, opc,
4807 V128, V128, V64,
4808 asm, ".2d", ".2d", ".2s",
4809 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn), (v2i32 V64:$Rm)))]>;
4810 def v4i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b101, opc,
4811 V128, V128, V128,
4812 asm#"2", ".2d", ".2d", ".4s",
4813 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn),
4814 (extract_high_v4i32 V128:$Rm)))]>;
4815}
4816
4817//----------------------------------------------------------------------------
4818// AdvSIMD bitwise extract from vector
4819//----------------------------------------------------------------------------
4820
4821class BaseSIMDBitwiseExtract<bit size, RegisterOperand regtype, ValueType vty,
4822 string asm, string kind>
4823 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, i32imm:$imm), asm,
4824 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind # ", $imm" #
4825 "|" # kind # "\t$Rd, $Rn, $Rm, $imm}", "",
4826 [(set (vty regtype:$Rd),
4827 (ARM64ext regtype:$Rn, regtype:$Rm, (i32 imm:$imm)))]>,
4828 Sched<[WriteV]> {
4829 bits<5> Rd;
4830 bits<5> Rn;
4831 bits<5> Rm;
4832 bits<4> imm;
4833 let Inst{31} = 0;
4834 let Inst{30} = size;
4835 let Inst{29-21} = 0b101110000;
4836 let Inst{20-16} = Rm;
4837 let Inst{15} = 0;
4838 let Inst{14-11} = imm;
4839 let Inst{10} = 0;
4840 let Inst{9-5} = Rn;
4841 let Inst{4-0} = Rd;
4842}
4843
4844
4845multiclass SIMDBitwiseExtract<string asm> {
4846 def v8i8 : BaseSIMDBitwiseExtract<0, V64, v8i8, asm, ".8b">;
4847 def v16i8 : BaseSIMDBitwiseExtract<1, V128, v16i8, asm, ".16b">;
4848}
4849
4850//----------------------------------------------------------------------------
4851// AdvSIMD zip vector
4852//----------------------------------------------------------------------------
4853
4854class BaseSIMDZipVector<bits<3> size, bits<3> opc, RegisterOperand regtype,
4855 string asm, string kind, SDNode OpNode, ValueType valty>
4856 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), asm,
4857 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind #
4858 "|" # kind # "\t$Rd, $Rn, $Rm}", "",
4859 [(set (valty regtype:$Rd), (OpNode regtype:$Rn, regtype:$Rm))]>,
4860 Sched<[WriteV]> {
4861 bits<5> Rd;
4862 bits<5> Rn;
4863 bits<5> Rm;
4864 let Inst{31} = 0;
4865 let Inst{30} = size{0};
4866 let Inst{29-24} = 0b001110;
4867 let Inst{23-22} = size{2-1};
4868 let Inst{21} = 0;
4869 let Inst{20-16} = Rm;
4870 let Inst{15} = 0;
4871 let Inst{14-12} = opc;
4872 let Inst{11-10} = 0b10;
4873 let Inst{9-5} = Rn;
4874 let Inst{4-0} = Rd;
4875}
4876
4877multiclass SIMDZipVector<bits<3>opc, string asm,
4878 SDNode OpNode> {
4879 def v8i8 : BaseSIMDZipVector<0b000, opc, V64,
4880 asm, ".8b", OpNode, v8i8>;
4881 def v16i8 : BaseSIMDZipVector<0b001, opc, V128,
4882 asm, ".16b", OpNode, v16i8>;
4883 def v4i16 : BaseSIMDZipVector<0b010, opc, V64,
4884 asm, ".4h", OpNode, v4i16>;
4885 def v8i16 : BaseSIMDZipVector<0b011, opc, V128,
4886 asm, ".8h", OpNode, v8i16>;
4887 def v2i32 : BaseSIMDZipVector<0b100, opc, V64,
4888 asm, ".2s", OpNode, v2i32>;
4889 def v4i32 : BaseSIMDZipVector<0b101, opc, V128,
4890 asm, ".4s", OpNode, v4i32>;
4891 def v2i64 : BaseSIMDZipVector<0b111, opc, V128,
4892 asm, ".2d", OpNode, v2i64>;
4893
4894 def : Pat<(v2f32 (OpNode V64:$Rn, V64:$Rm)),
4895 (!cast<Instruction>(NAME#"v2i32") V64:$Rn, V64:$Rm)>;
4896 def : Pat<(v4f32 (OpNode V128:$Rn, V128:$Rm)),
4897 (!cast<Instruction>(NAME#"v4i32") V128:$Rn, V128:$Rm)>;
4898 def : Pat<(v2f64 (OpNode V128:$Rn, V128:$Rm)),
4899 (!cast<Instruction>(NAME#"v2i64") V128:$Rn, V128:$Rm)>;
4900}
4901
4902//----------------------------------------------------------------------------
4903// AdvSIMD three register scalar instructions
4904//----------------------------------------------------------------------------
4905
4906let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
4907class BaseSIMDThreeScalar<bit U, bits<2> size, bits<5> opcode,
4908 RegisterClass regtype, string asm,
4909 list<dag> pattern>
4910 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), asm,
4911 "\t$Rd, $Rn, $Rm", "", pattern>,
4912 Sched<[WriteV]> {
4913 bits<5> Rd;
4914 bits<5> Rn;
4915 bits<5> Rm;
4916 let Inst{31-30} = 0b01;
4917 let Inst{29} = U;
4918 let Inst{28-24} = 0b11110;
4919 let Inst{23-22} = size;
4920 let Inst{21} = 1;
4921 let Inst{20-16} = Rm;
4922 let Inst{15-11} = opcode;
4923 let Inst{10} = 1;
4924 let Inst{9-5} = Rn;
4925 let Inst{4-0} = Rd;
4926}
4927
4928multiclass SIMDThreeScalarD<bit U, bits<5> opc, string asm,
4929 SDPatternOperator OpNode> {
4930 def v1i64 : BaseSIMDThreeScalar<U, 0b11, opc, FPR64, asm,
4931 [(set (v1i64 FPR64:$Rd), (OpNode (v1i64 FPR64:$Rn), (v1i64 FPR64:$Rm)))]>;
4932}
4933
4934multiclass SIMDThreeScalarBHSD<bit U, bits<5> opc, string asm,
4935 SDPatternOperator OpNode> {
4936 def v1i64 : BaseSIMDThreeScalar<U, 0b11, opc, FPR64, asm,
4937 [(set (v1i64 FPR64:$Rd), (OpNode (v1i64 FPR64:$Rn), (v1i64 FPR64:$Rm)))]>;
4938 def v1i32 : BaseSIMDThreeScalar<U, 0b10, opc, FPR32, asm, []>;
4939 def v1i16 : BaseSIMDThreeScalar<U, 0b01, opc, FPR16, asm, []>;
4940 def v1i8 : BaseSIMDThreeScalar<U, 0b00, opc, FPR8 , asm, []>;
4941
4942 def : Pat<(i64 (OpNode (i64 FPR64:$Rn), (i64 FPR64:$Rm))),
4943 (!cast<Instruction>(NAME#"v1i64") FPR64:$Rn, FPR64:$Rm)>;
4944 def : Pat<(i32 (OpNode (i32 FPR32:$Rn), (i32 FPR32:$Rm))),
4945 (!cast<Instruction>(NAME#"v1i32") FPR32:$Rn, FPR32:$Rm)>;
4946}
4947
4948multiclass SIMDThreeScalarHS<bit U, bits<5> opc, string asm,
4949 SDPatternOperator OpNode> {
4950 def v1i32 : BaseSIMDThreeScalar<U, 0b10, opc, FPR32, asm,
4951 [(set FPR32:$Rd, (OpNode FPR32:$Rn, FPR32:$Rm))]>;
4952 def v1i16 : BaseSIMDThreeScalar<U, 0b01, opc, FPR16, asm, []>;
4953}
4954
4955multiclass SIMDThreeScalarSD<bit U, bit S, bits<5> opc, string asm,
4956 SDPatternOperator OpNode = null_frag> {
4957 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
4958 def #NAME#64 : BaseSIMDThreeScalar<U, {S,1}, opc, FPR64, asm,
4959 [(set (f64 FPR64:$Rd), (OpNode (f64 FPR64:$Rn), (f64 FPR64:$Rm)))]>;
4960 def #NAME#32 : BaseSIMDThreeScalar<U, {S,0}, opc, FPR32, asm,
4961 [(set FPR32:$Rd, (OpNode FPR32:$Rn, FPR32:$Rm))]>;
4962 }
4963
4964 def : Pat<(v1f64 (OpNode (v1f64 FPR64:$Rn), (v1f64 FPR64:$Rm))),
4965 (!cast<Instruction>(NAME # "64") FPR64:$Rn, FPR64:$Rm)>;
4966}
4967
4968multiclass SIMDThreeScalarFPCmp<bit U, bit S, bits<5> opc, string asm,
4969 SDPatternOperator OpNode = null_frag> {
4970 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
4971 def #NAME#64 : BaseSIMDThreeScalar<U, {S,1}, opc, FPR64, asm,
4972 [(set (i64 FPR64:$Rd), (OpNode (f64 FPR64:$Rn), (f64 FPR64:$Rm)))]>;
4973 def #NAME#32 : BaseSIMDThreeScalar<U, {S,0}, opc, FPR32, asm,
4974 [(set (i32 FPR32:$Rd), (OpNode (f32 FPR32:$Rn), (f32 FPR32:$Rm)))]>;
4975 }
4976
4977 def : Pat<(v1i64 (OpNode (v1f64 FPR64:$Rn), (v1f64 FPR64:$Rm))),
4978 (!cast<Instruction>(NAME # "64") FPR64:$Rn, FPR64:$Rm)>;
4979}
4980
4981class BaseSIMDThreeScalarMixed<bit U, bits<2> size, bits<5> opcode,
4982 dag oops, dag iops, string asm, string cstr, list<dag> pat>
4983 : I<oops, iops, asm,
4984 "\t$Rd, $Rn, $Rm", cstr, pat>,
4985 Sched<[WriteV]> {
4986 bits<5> Rd;
4987 bits<5> Rn;
4988 bits<5> Rm;
4989 let Inst{31-30} = 0b01;
4990 let Inst{29} = U;
4991 let Inst{28-24} = 0b11110;
4992 let Inst{23-22} = size;
4993 let Inst{21} = 1;
4994 let Inst{20-16} = Rm;
4995 let Inst{15-11} = opcode;
4996 let Inst{10} = 0;
4997 let Inst{9-5} = Rn;
4998 let Inst{4-0} = Rd;
4999}
5000
5001let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5002multiclass SIMDThreeScalarMixedHS<bit U, bits<5> opc, string asm,
5003 SDPatternOperator OpNode = null_frag> {
5004 def i16 : BaseSIMDThreeScalarMixed<U, 0b01, opc,
5005 (outs FPR32:$Rd),
5006 (ins FPR16:$Rn, FPR16:$Rm), asm, "", []>;
5007 def i32 : BaseSIMDThreeScalarMixed<U, 0b10, opc,
5008 (outs FPR64:$Rd),
5009 (ins FPR32:$Rn, FPR32:$Rm), asm, "",
5010 [(set (i64 FPR64:$Rd), (OpNode (i32 FPR32:$Rn), (i32 FPR32:$Rm)))]>;
5011}
5012
5013let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5014multiclass SIMDThreeScalarMixedTiedHS<bit U, bits<5> opc, string asm,
5015 SDPatternOperator OpNode = null_frag> {
5016 def i16 : BaseSIMDThreeScalarMixed<U, 0b01, opc,
5017 (outs FPR32:$dst),
5018 (ins FPR32:$Rd, FPR16:$Rn, FPR16:$Rm),
5019 asm, "$Rd = $dst", []>;
5020 def i32 : BaseSIMDThreeScalarMixed<U, 0b10, opc,
5021 (outs FPR64:$dst),
5022 (ins FPR64:$Rd, FPR32:$Rn, FPR32:$Rm),
5023 asm, "$Rd = $dst",
5024 [(set (i64 FPR64:$dst),
5025 (OpNode (i64 FPR64:$Rd), (i32 FPR32:$Rn), (i32 FPR32:$Rm)))]>;
5026}
5027
5028//----------------------------------------------------------------------------
5029// AdvSIMD two register scalar instructions
5030//----------------------------------------------------------------------------
5031
5032let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5033class BaseSIMDTwoScalar<bit U, bits<2> size, bits<5> opcode,
5034 RegisterClass regtype, RegisterClass regtype2,
5035 string asm, list<dag> pat>
5036 : I<(outs regtype:$Rd), (ins regtype2:$Rn), asm,
5037 "\t$Rd, $Rn", "", pat>,
5038 Sched<[WriteV]> {
5039 bits<5> Rd;
5040 bits<5> Rn;
5041 let Inst{31-30} = 0b01;
5042 let Inst{29} = U;
5043 let Inst{28-24} = 0b11110;
5044 let Inst{23-22} = size;
5045 let Inst{21-17} = 0b10000;
5046 let Inst{16-12} = opcode;
5047 let Inst{11-10} = 0b10;
5048 let Inst{9-5} = Rn;
5049 let Inst{4-0} = Rd;
5050}
5051
5052let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5053class BaseSIMDTwoScalarTied<bit U, bits<2> size, bits<5> opcode,
5054 RegisterClass regtype, RegisterClass regtype2,
5055 string asm, list<dag> pat>
5056 : I<(outs regtype:$dst), (ins regtype:$Rd, regtype2:$Rn), asm,
5057 "\t$Rd, $Rn", "$Rd = $dst", pat>,
5058 Sched<[WriteV]> {
5059 bits<5> Rd;
5060 bits<5> Rn;
5061 let Inst{31-30} = 0b01;
5062 let Inst{29} = U;
5063 let Inst{28-24} = 0b11110;
5064 let Inst{23-22} = size;
5065 let Inst{21-17} = 0b10000;
5066 let Inst{16-12} = opcode;
5067 let Inst{11-10} = 0b10;
5068 let Inst{9-5} = Rn;
5069 let Inst{4-0} = Rd;
5070}
5071
5072
5073let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5074class BaseSIMDCmpTwoScalar<bit U, bits<2> size, bits<5> opcode,
5075 RegisterClass regtype, string asm>
5076 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm,
5077 "\t$Rd, $Rn, #0", "", []>,
5078 Sched<[WriteV]> {
5079 bits<5> Rd;
5080 bits<5> Rn;
5081 let Inst{31-30} = 0b01;
5082 let Inst{29} = U;
5083 let Inst{28-24} = 0b11110;
5084 let Inst{23-22} = size;
5085 let Inst{21-17} = 0b10000;
5086 let Inst{16-12} = opcode;
5087 let Inst{11-10} = 0b10;
5088 let Inst{9-5} = Rn;
5089 let Inst{4-0} = Rd;
5090}
5091
5092class SIMDInexactCvtTwoScalar<bits<5> opcode, string asm>
5093 : I<(outs FPR32:$Rd), (ins FPR64:$Rn), asm, "\t$Rd, $Rn", "",
5094 [(set (f32 FPR32:$Rd), (int_arm64_sisd_fcvtxn (f64 FPR64:$Rn)))]>,
5095 Sched<[WriteV]> {
5096 bits<5> Rd;
5097 bits<5> Rn;
5098 let Inst{31-17} = 0b011111100110000;
5099 let Inst{16-12} = opcode;
5100 let Inst{11-10} = 0b10;
5101 let Inst{9-5} = Rn;
5102 let Inst{4-0} = Rd;
5103}
5104
5105multiclass SIMDCmpTwoScalarD<bit U, bits<5> opc, string asm,
5106 SDPatternOperator OpNode> {
5107 def v1i64rz : BaseSIMDCmpTwoScalar<U, 0b11, opc, FPR64, asm>;
5108
5109 def : Pat<(v1i64 (OpNode FPR64:$Rn)),
5110 (!cast<Instruction>(NAME # v1i64rz) FPR64:$Rn)>;
5111}
5112
5113multiclass SIMDCmpTwoScalarSD<bit U, bit S, bits<5> opc, string asm,
5114 SDPatternOperator OpNode> {
5115 def v1i64rz : BaseSIMDCmpTwoScalar<U, {S,1}, opc, FPR64, asm>;
5116 def v1i32rz : BaseSIMDCmpTwoScalar<U, {S,0}, opc, FPR32, asm>;
5117
5118 def : Pat<(v1i64 (OpNode (v1f64 FPR64:$Rn))),
5119 (!cast<Instruction>(NAME # v1i64rz) FPR64:$Rn)>;
5120}
5121
5122multiclass SIMDTwoScalarD<bit U, bits<5> opc, string asm,
5123 SDPatternOperator OpNode = null_frag> {
5124 def v1i64 : BaseSIMDTwoScalar<U, 0b11, opc, FPR64, FPR64, asm,
5125 [(set (v1i64 FPR64:$Rd), (OpNode (v1i64 FPR64:$Rn)))]>;
Tim Northoverf4810362014-03-31 15:46:17 +00005126
5127 def : Pat<(i64 (OpNode (i64 FPR64:$Rn))),
5128 (!cast<Instruction>(NAME # "v1i64") FPR64:$Rn)>;
Tim Northover00ed9962014-03-29 10:18:08 +00005129}
5130
5131multiclass SIMDTwoScalarSD<bit U, bit S, bits<5> opc, string asm> {
5132 def v1i64 : BaseSIMDTwoScalar<U, {S,1}, opc, FPR64, FPR64, asm,[]>;
5133 def v1i32 : BaseSIMDTwoScalar<U, {S,0}, opc, FPR32, FPR32, asm,[]>;
5134}
5135
5136multiclass SIMDTwoScalarCVTSD<bit U, bit S, bits<5> opc, string asm,
5137 SDPatternOperator OpNode> {
5138 def v1i64 : BaseSIMDTwoScalar<U, {S,1}, opc, FPR64, FPR64, asm,
5139 [(set FPR64:$Rd, (OpNode (f64 FPR64:$Rn)))]>;
5140 def v1i32 : BaseSIMDTwoScalar<U, {S,0}, opc, FPR32, FPR32, asm,
5141 [(set FPR32:$Rd, (OpNode (f32 FPR32:$Rn)))]>;
5142}
5143
5144multiclass SIMDTwoScalarBHSD<bit U, bits<5> opc, string asm,
5145 SDPatternOperator OpNode = null_frag> {
5146 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
5147 def v1i64 : BaseSIMDTwoScalar<U, 0b11, opc, FPR64, FPR64, asm,
5148 [(set (i64 FPR64:$Rd), (OpNode (i64 FPR64:$Rn)))]>;
5149 def v1i32 : BaseSIMDTwoScalar<U, 0b10, opc, FPR32, FPR32, asm,
5150 [(set (i32 FPR32:$Rd), (OpNode (i32 FPR32:$Rn)))]>;
5151 def v1i16 : BaseSIMDTwoScalar<U, 0b01, opc, FPR16, FPR16, asm, []>;
5152 def v1i8 : BaseSIMDTwoScalar<U, 0b00, opc, FPR8 , FPR8 , asm, []>;
5153 }
5154
5155 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rn))),
5156 (!cast<Instruction>(NAME # v1i64) FPR64:$Rn)>;
5157}
5158
Tim Northover00ed9962014-03-29 10:18:08 +00005159multiclass SIMDTwoScalarBHSDTied<bit U, bits<5> opc, string asm,
5160 Intrinsic OpNode> {
Tim Northover903814c2014-03-31 15:46:26 +00005161 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
5162 def v1i64 : BaseSIMDTwoScalarTied<U, 0b11, opc, FPR64, FPR64, asm,
5163 [(set (i64 FPR64:$dst), (OpNode (i64 FPR64:$Rd), (i64 FPR64:$Rn)))]>;
5164 def v1i32 : BaseSIMDTwoScalarTied<U, 0b10, opc, FPR32, FPR32, asm,
5165 [(set (i32 FPR32:$dst), (OpNode (i32 FPR32:$Rd), (i32 FPR32:$Rn)))]>;
5166 def v1i16 : BaseSIMDTwoScalarTied<U, 0b01, opc, FPR16, FPR16, asm, []>;
5167 def v1i8 : BaseSIMDTwoScalarTied<U, 0b00, opc, FPR8 , FPR8 , asm, []>;
5168 }
5169
5170 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rd), (v1i64 FPR64:$Rn))),
5171 (!cast<Instruction>(NAME # v1i64) FPR64:$Rd, FPR64:$Rn)>;
Tim Northover00ed9962014-03-29 10:18:08 +00005172}
5173
5174
5175
5176let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5177multiclass SIMDTwoScalarMixedBHS<bit U, bits<5> opc, string asm,
5178 SDPatternOperator OpNode = null_frag> {
5179 def v1i32 : BaseSIMDTwoScalar<U, 0b10, opc, FPR32, FPR64, asm,
5180 [(set (i32 FPR32:$Rd), (OpNode (i64 FPR64:$Rn)))]>;
5181 def v1i16 : BaseSIMDTwoScalar<U, 0b01, opc, FPR16, FPR32, asm, []>;
5182 def v1i8 : BaseSIMDTwoScalar<U, 0b00, opc, FPR8 , FPR16, asm, []>;
5183}
5184
5185//----------------------------------------------------------------------------
5186// AdvSIMD scalar pairwise instructions
5187//----------------------------------------------------------------------------
5188
5189let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5190class BaseSIMDPairwiseScalar<bit U, bits<2> size, bits<5> opcode,
5191 RegisterOperand regtype, RegisterOperand vectype,
5192 string asm, string kind>
5193 : I<(outs regtype:$Rd), (ins vectype:$Rn), asm,
5194 "{\t$Rd, $Rn" # kind # "|" # kind # "\t$Rd, $Rn}", "", []>,
5195 Sched<[WriteV]> {
5196 bits<5> Rd;
5197 bits<5> Rn;
5198 let Inst{31-30} = 0b01;
5199 let Inst{29} = U;
5200 let Inst{28-24} = 0b11110;
5201 let Inst{23-22} = size;
5202 let Inst{21-17} = 0b11000;
5203 let Inst{16-12} = opcode;
5204 let Inst{11-10} = 0b10;
5205 let Inst{9-5} = Rn;
5206 let Inst{4-0} = Rd;
5207}
5208
5209multiclass SIMDPairwiseScalarD<bit U, bits<5> opc, string asm> {
5210 def v2i64p : BaseSIMDPairwiseScalar<U, 0b11, opc, FPR64Op, V128,
5211 asm, ".2d">;
5212}
5213
5214multiclass SIMDPairwiseScalarSD<bit U, bit S, bits<5> opc, string asm> {
5215 def v2i32p : BaseSIMDPairwiseScalar<U, {S,0}, opc, FPR32Op, V64,
5216 asm, ".2s">;
5217 def v2i64p : BaseSIMDPairwiseScalar<U, {S,1}, opc, FPR64Op, V128,
5218 asm, ".2d">;
5219}
5220
5221//----------------------------------------------------------------------------
5222// AdvSIMD across lanes instructions
5223//----------------------------------------------------------------------------
5224
5225let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5226class BaseSIMDAcrossLanes<bit Q, bit U, bits<2> size, bits<5> opcode,
5227 RegisterClass regtype, RegisterOperand vectype,
5228 string asm, string kind, list<dag> pattern>
5229 : I<(outs regtype:$Rd), (ins vectype:$Rn), asm,
5230 "{\t$Rd, $Rn" # kind # "|" # kind # "\t$Rd, $Rn}", "", pattern>,
5231 Sched<[WriteV]> {
5232 bits<5> Rd;
5233 bits<5> Rn;
5234 let Inst{31} = 0;
5235 let Inst{30} = Q;
5236 let Inst{29} = U;
5237 let Inst{28-24} = 0b01110;
5238 let Inst{23-22} = size;
5239 let Inst{21-17} = 0b11000;
5240 let Inst{16-12} = opcode;
5241 let Inst{11-10} = 0b10;
5242 let Inst{9-5} = Rn;
5243 let Inst{4-0} = Rd;
5244}
5245
5246multiclass SIMDAcrossLanesBHS<bit U, bits<5> opcode,
5247 string asm> {
5248 def v8i8v : BaseSIMDAcrossLanes<0, U, 0b00, opcode, FPR8, V64,
5249 asm, ".8b", []>;
5250 def v16i8v : BaseSIMDAcrossLanes<1, U, 0b00, opcode, FPR8, V128,
5251 asm, ".16b", []>;
5252 def v4i16v : BaseSIMDAcrossLanes<0, U, 0b01, opcode, FPR16, V64,
5253 asm, ".4h", []>;
5254 def v8i16v : BaseSIMDAcrossLanes<1, U, 0b01, opcode, FPR16, V128,
5255 asm, ".8h", []>;
5256 def v4i32v : BaseSIMDAcrossLanes<1, U, 0b10, opcode, FPR32, V128,
5257 asm, ".4s", []>;
5258}
5259
5260multiclass SIMDAcrossLanesHSD<bit U, bits<5> opcode, string asm> {
5261 def v8i8v : BaseSIMDAcrossLanes<0, U, 0b00, opcode, FPR16, V64,
5262 asm, ".8b", []>;
5263 def v16i8v : BaseSIMDAcrossLanes<1, U, 0b00, opcode, FPR16, V128,
5264 asm, ".16b", []>;
5265 def v4i16v : BaseSIMDAcrossLanes<0, U, 0b01, opcode, FPR32, V64,
5266 asm, ".4h", []>;
5267 def v8i16v : BaseSIMDAcrossLanes<1, U, 0b01, opcode, FPR32, V128,
5268 asm, ".8h", []>;
5269 def v4i32v : BaseSIMDAcrossLanes<1, U, 0b10, opcode, FPR64, V128,
5270 asm, ".4s", []>;
5271}
5272
5273multiclass SIMDAcrossLanesS<bits<5> opcode, bit sz1, string asm,
5274 Intrinsic intOp> {
5275 def v4i32v : BaseSIMDAcrossLanes<1, 1, {sz1, 0}, opcode, FPR32, V128,
5276 asm, ".4s",
5277 [(set FPR32:$Rd, (intOp (v4f32 V128:$Rn)))]>;
5278}
5279
5280//----------------------------------------------------------------------------
5281// AdvSIMD INS/DUP instructions
5282//----------------------------------------------------------------------------
5283
5284// FIXME: There has got to be a better way to factor these. ugh.
5285
5286class BaseSIMDInsDup<bit Q, bit op, dag outs, dag ins, string asm,
5287 string operands, string constraints, list<dag> pattern>
5288 : I<outs, ins, asm, operands, constraints, pattern>,
5289 Sched<[WriteV]> {
5290 bits<5> Rd;
5291 bits<5> Rn;
5292 let Inst{31} = 0;
5293 let Inst{30} = Q;
5294 let Inst{29} = op;
5295 let Inst{28-21} = 0b01110000;
5296 let Inst{15} = 0;
5297 let Inst{10} = 1;
5298 let Inst{9-5} = Rn;
5299 let Inst{4-0} = Rd;
5300}
5301
5302class SIMDDupFromMain<bit Q, bits<5> imm5, string size, ValueType vectype,
5303 RegisterOperand vecreg, RegisterClass regtype>
5304 : BaseSIMDInsDup<Q, 0, (outs vecreg:$Rd), (ins regtype:$Rn), "dup",
5305 "{\t$Rd" # size # ", $Rn" #
5306 "|" # size # "\t$Rd, $Rn}", "",
5307 [(set (vectype vecreg:$Rd), (ARM64dup regtype:$Rn))]> {
5308 let Inst{20-16} = imm5;
5309 let Inst{14-11} = 0b0001;
5310}
5311
5312class SIMDDupFromElement<bit Q, string dstkind, string srckind,
5313 ValueType vectype, ValueType insreg,
5314 RegisterOperand vecreg, Operand idxtype,
5315 ValueType elttype, SDNode OpNode>
5316 : BaseSIMDInsDup<Q, 0, (outs vecreg:$Rd), (ins V128:$Rn, idxtype:$idx), "dup",
5317 "{\t$Rd" # dstkind # ", $Rn" # srckind # "$idx" #
5318 "|" # dstkind # "\t$Rd, $Rn$idx}", "",
5319 [(set (vectype vecreg:$Rd),
5320 (OpNode (insreg V128:$Rn), idxtype:$idx))]> {
5321 let Inst{14-11} = 0b0000;
5322}
5323
5324class SIMDDup64FromElement
5325 : SIMDDupFromElement<1, ".2d", ".d", v2i64, v2i64, V128,
5326 VectorIndexD, i64, ARM64duplane64> {
5327 bits<1> idx;
5328 let Inst{20} = idx;
5329 let Inst{19-16} = 0b1000;
5330}
5331
5332class SIMDDup32FromElement<bit Q, string size, ValueType vectype,
5333 RegisterOperand vecreg>
5334 : SIMDDupFromElement<Q, size, ".s", vectype, v4i32, vecreg,
5335 VectorIndexS, i64, ARM64duplane32> {
5336 bits<2> idx;
5337 let Inst{20-19} = idx;
5338 let Inst{18-16} = 0b100;
5339}
5340
5341class SIMDDup16FromElement<bit Q, string size, ValueType vectype,
5342 RegisterOperand vecreg>
5343 : SIMDDupFromElement<Q, size, ".h", vectype, v8i16, vecreg,
5344 VectorIndexH, i64, ARM64duplane16> {
5345 bits<3> idx;
5346 let Inst{20-18} = idx;
5347 let Inst{17-16} = 0b10;
5348}
5349
5350class SIMDDup8FromElement<bit Q, string size, ValueType vectype,
5351 RegisterOperand vecreg>
5352 : SIMDDupFromElement<Q, size, ".b", vectype, v16i8, vecreg,
5353 VectorIndexB, i64, ARM64duplane8> {
5354 bits<4> idx;
5355 let Inst{20-17} = idx;
5356 let Inst{16} = 1;
5357}
5358
5359class BaseSIMDMov<bit Q, string size, bits<4> imm4, RegisterClass regtype,
5360 Operand idxtype, string asm, list<dag> pattern>
5361 : BaseSIMDInsDup<Q, 0, (outs regtype:$Rd), (ins V128:$Rn, idxtype:$idx), asm,
5362 "{\t$Rd, $Rn" # size # "$idx" #
5363 "|" # size # "\t$Rd, $Rn$idx}", "", pattern> {
5364 let Inst{14-11} = imm4;
5365}
5366
5367class SIMDSMov<bit Q, string size, RegisterClass regtype,
5368 Operand idxtype>
5369 : BaseSIMDMov<Q, size, 0b0101, regtype, idxtype, "smov", []>;
5370class SIMDUMov<bit Q, string size, ValueType vectype, RegisterClass regtype,
5371 Operand idxtype>
5372 : BaseSIMDMov<Q, size, 0b0111, regtype, idxtype, "umov",
5373 [(set regtype:$Rd, (vector_extract (vectype V128:$Rn), idxtype:$idx))]>;
5374
5375class SIMDMovAlias<string asm, string size, Instruction inst,
5376 RegisterClass regtype, Operand idxtype>
5377 : InstAlias<asm#"{\t$dst, $src"#size#"$idx" #
5378 "|" # size # "\t$dst, $src$idx}",
5379 (inst regtype:$dst, V128:$src, idxtype:$idx)>;
5380
5381multiclass SMov {
5382 def vi8to32 : SIMDSMov<0, ".b", GPR32, VectorIndexB> {
5383 bits<4> idx;
5384 let Inst{20-17} = idx;
5385 let Inst{16} = 1;
5386 }
5387 def vi8to64 : SIMDSMov<1, ".b", GPR64, VectorIndexB> {
5388 bits<4> idx;
5389 let Inst{20-17} = idx;
5390 let Inst{16} = 1;
5391 }
5392 def vi16to32 : SIMDSMov<0, ".h", GPR32, VectorIndexH> {
5393 bits<3> idx;
5394 let Inst{20-18} = idx;
5395 let Inst{17-16} = 0b10;
5396 }
5397 def vi16to64 : SIMDSMov<1, ".h", GPR64, VectorIndexH> {
5398 bits<3> idx;
5399 let Inst{20-18} = idx;
5400 let Inst{17-16} = 0b10;
5401 }
5402 def vi32to64 : SIMDSMov<1, ".s", GPR64, VectorIndexS> {
5403 bits<2> idx;
5404 let Inst{20-19} = idx;
5405 let Inst{18-16} = 0b100;
5406 }
5407}
5408
5409multiclass UMov {
5410 def vi8 : SIMDUMov<0, ".b", v16i8, GPR32, VectorIndexB> {
5411 bits<4> idx;
5412 let Inst{20-17} = idx;
5413 let Inst{16} = 1;
5414 }
5415 def vi16 : SIMDUMov<0, ".h", v8i16, GPR32, VectorIndexH> {
5416 bits<3> idx;
5417 let Inst{20-18} = idx;
5418 let Inst{17-16} = 0b10;
5419 }
5420 def vi32 : SIMDUMov<0, ".s", v4i32, GPR32, VectorIndexS> {
5421 bits<2> idx;
5422 let Inst{20-19} = idx;
5423 let Inst{18-16} = 0b100;
5424 }
5425 def vi64 : SIMDUMov<1, ".d", v2i64, GPR64, VectorIndexD> {
5426 bits<1> idx;
5427 let Inst{20} = idx;
5428 let Inst{19-16} = 0b1000;
5429 }
5430 def : SIMDMovAlias<"mov", ".s",
5431 !cast<Instruction>(NAME#"vi32"),
5432 GPR32, VectorIndexS>;
5433 def : SIMDMovAlias<"mov", ".d",
5434 !cast<Instruction>(NAME#"vi64"),
5435 GPR64, VectorIndexD>;
5436}
5437
5438class SIMDInsFromMain<string size, ValueType vectype,
5439 RegisterClass regtype, Operand idxtype>
5440 : BaseSIMDInsDup<1, 0, (outs V128:$dst),
5441 (ins V128:$Rd, idxtype:$idx, regtype:$Rn), "ins",
5442 "{\t$Rd" # size # "$idx, $Rn" #
5443 "|" # size # "\t$Rd$idx, $Rn}",
5444 "$Rd = $dst",
5445 [(set V128:$dst,
5446 (vector_insert (vectype V128:$Rd), regtype:$Rn, idxtype:$idx))]> {
5447 let Inst{14-11} = 0b0011;
5448}
5449
5450class SIMDInsFromElement<string size, ValueType vectype,
5451 ValueType elttype, Operand idxtype>
5452 : BaseSIMDInsDup<1, 1, (outs V128:$dst),
5453 (ins V128:$Rd, idxtype:$idx, V128:$Rn, idxtype:$idx2), "ins",
5454 "{\t$Rd" # size # "$idx, $Rn" # size # "$idx2" #
5455 "|" # size # "\t$Rd$idx, $Rn$idx2}",
5456 "$Rd = $dst",
5457 [(set V128:$dst,
5458 (vector_insert
5459 (vectype V128:$Rd),
5460 (elttype (vector_extract (vectype V128:$Rn), idxtype:$idx2)),
5461 idxtype:$idx))]>;
5462
5463class SIMDInsMainMovAlias<string size, Instruction inst,
5464 RegisterClass regtype, Operand idxtype>
5465 : InstAlias<"mov" # "{\t$dst" # size # "$idx, $src" #
5466 "|" # size #"\t$dst$idx, $src}",
5467 (inst V128:$dst, idxtype:$idx, regtype:$src)>;
5468class SIMDInsElementMovAlias<string size, Instruction inst,
5469 Operand idxtype>
5470 : InstAlias<"mov" # "{\t$dst" # size # "$idx, $src" # size # "$idx2" #
5471 # "|" # size #" $dst$idx, $src$idx2}",
5472 (inst V128:$dst, idxtype:$idx, V128:$src, idxtype:$idx2)>;
5473
5474
5475multiclass SIMDIns {
5476 def vi8gpr : SIMDInsFromMain<".b", v16i8, GPR32, VectorIndexB> {
5477 bits<4> idx;
5478 let Inst{20-17} = idx;
5479 let Inst{16} = 1;
5480 }
5481 def vi16gpr : SIMDInsFromMain<".h", v8i16, GPR32, VectorIndexH> {
5482 bits<3> idx;
5483 let Inst{20-18} = idx;
5484 let Inst{17-16} = 0b10;
5485 }
5486 def vi32gpr : SIMDInsFromMain<".s", v4i32, GPR32, VectorIndexS> {
5487 bits<2> idx;
5488 let Inst{20-19} = idx;
5489 let Inst{18-16} = 0b100;
5490 }
5491 def vi64gpr : SIMDInsFromMain<".d", v2i64, GPR64, VectorIndexD> {
5492 bits<1> idx;
5493 let Inst{20} = idx;
5494 let Inst{19-16} = 0b1000;
5495 }
5496
5497 def vi8lane : SIMDInsFromElement<".b", v16i8, i32, VectorIndexB> {
5498 bits<4> idx;
5499 bits<4> idx2;
5500 let Inst{20-17} = idx;
5501 let Inst{16} = 1;
5502 let Inst{14-11} = idx2;
5503 }
5504 def vi16lane : SIMDInsFromElement<".h", v8i16, i32, VectorIndexH> {
5505 bits<3> idx;
5506 bits<3> idx2;
5507 let Inst{20-18} = idx;
5508 let Inst{17-16} = 0b10;
5509 let Inst{14-12} = idx2;
5510 let Inst{11} = 0;
5511 }
5512 def vi32lane : SIMDInsFromElement<".s", v4i32, i32, VectorIndexS> {
5513 bits<2> idx;
5514 bits<2> idx2;
5515 let Inst{20-19} = idx;
5516 let Inst{18-16} = 0b100;
5517 let Inst{14-13} = idx2;
5518 let Inst{12-11} = 0;
5519 }
5520 def vi64lane : SIMDInsFromElement<".d", v2i64, i64, VectorIndexD> {
5521 bits<1> idx;
5522 bits<1> idx2;
5523 let Inst{20} = idx;
5524 let Inst{19-16} = 0b1000;
5525 let Inst{14} = idx2;
5526 let Inst{13-11} = 0;
5527 }
5528
5529 // For all forms of the INS instruction, the "mov" mnemonic is the
5530 // preferred alias. Why they didn't just call the instruction "mov" in
5531 // the first place is a very good question indeed...
5532 def : SIMDInsMainMovAlias<".b", !cast<Instruction>(NAME#"vi8gpr"),
5533 GPR32, VectorIndexB>;
5534 def : SIMDInsMainMovAlias<".h", !cast<Instruction>(NAME#"vi16gpr"),
5535 GPR32, VectorIndexH>;
5536 def : SIMDInsMainMovAlias<".s", !cast<Instruction>(NAME#"vi32gpr"),
5537 GPR32, VectorIndexS>;
5538 def : SIMDInsMainMovAlias<".d", !cast<Instruction>(NAME#"vi64gpr"),
5539 GPR64, VectorIndexD>;
5540
5541 def : SIMDInsElementMovAlias<".b", !cast<Instruction>(NAME#"vi8lane"),
5542 VectorIndexB>;
5543 def : SIMDInsElementMovAlias<".h", !cast<Instruction>(NAME#"vi16lane"),
5544 VectorIndexH>;
5545 def : SIMDInsElementMovAlias<".s", !cast<Instruction>(NAME#"vi32lane"),
5546 VectorIndexS>;
5547 def : SIMDInsElementMovAlias<".d", !cast<Instruction>(NAME#"vi64lane"),
5548 VectorIndexD>;
5549}
5550
5551//----------------------------------------------------------------------------
5552// AdvSIMD TBL/TBX
5553//----------------------------------------------------------------------------
5554
5555let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
5556class BaseSIMDTableLookup<bit Q, bits<2> len, bit op, RegisterOperand vectype,
5557 RegisterOperand listtype, string asm, string kind>
5558 : I<(outs vectype:$Vd), (ins listtype:$Vn, vectype:$Vm), asm,
5559 "\t$Vd" # kind # ", $Vn, $Vm" # kind, "", []>,
5560 Sched<[WriteV]> {
5561 bits<5> Vd;
5562 bits<5> Vn;
5563 bits<5> Vm;
5564 let Inst{31} = 0;
5565 let Inst{30} = Q;
5566 let Inst{29-21} = 0b001110000;
5567 let Inst{20-16} = Vm;
5568 let Inst{15} = 0;
5569 let Inst{14-13} = len;
5570 let Inst{12} = op;
5571 let Inst{11-10} = 0b00;
5572 let Inst{9-5} = Vn;
5573 let Inst{4-0} = Vd;
5574}
5575
5576let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
5577class BaseSIMDTableLookupTied<bit Q, bits<2> len, bit op, RegisterOperand vectype,
5578 RegisterOperand listtype, string asm, string kind>
5579 : I<(outs vectype:$dst), (ins vectype:$Vd, listtype:$Vn, vectype:$Vm), asm,
5580 "\t$Vd" # kind # ", $Vn, $Vm" # kind, "$Vd = $dst", []>,
5581 Sched<[WriteV]> {
5582 bits<5> Vd;
5583 bits<5> Vn;
5584 bits<5> Vm;
5585 let Inst{31} = 0;
5586 let Inst{30} = Q;
5587 let Inst{29-21} = 0b001110000;
5588 let Inst{20-16} = Vm;
5589 let Inst{15} = 0;
5590 let Inst{14-13} = len;
5591 let Inst{12} = op;
5592 let Inst{11-10} = 0b00;
5593 let Inst{9-5} = Vn;
5594 let Inst{4-0} = Vd;
5595}
5596
5597class SIMDTableLookupAlias<string asm, Instruction inst,
5598 RegisterOperand vectype, RegisterOperand listtype>
5599 : InstAlias<!strconcat(asm, "\t$dst, $lst, $index"),
5600 (inst vectype:$dst, listtype:$lst, vectype:$index), 0>;
5601
5602multiclass SIMDTableLookup<bit op, string asm> {
5603 def v8i8One : BaseSIMDTableLookup<0, 0b00, op, V64, VecListOne16b,
5604 asm, ".8b">;
5605 def v8i8Two : BaseSIMDTableLookup<0, 0b01, op, V64, VecListTwo16b,
5606 asm, ".8b">;
5607 def v8i8Three : BaseSIMDTableLookup<0, 0b10, op, V64, VecListThree16b,
5608 asm, ".8b">;
5609 def v8i8Four : BaseSIMDTableLookup<0, 0b11, op, V64, VecListFour16b,
5610 asm, ".8b">;
5611 def v16i8One : BaseSIMDTableLookup<1, 0b00, op, V128, VecListOne16b,
5612 asm, ".16b">;
5613 def v16i8Two : BaseSIMDTableLookup<1, 0b01, op, V128, VecListTwo16b,
5614 asm, ".16b">;
5615 def v16i8Three: BaseSIMDTableLookup<1, 0b10, op, V128, VecListThree16b,
5616 asm, ".16b">;
5617 def v16i8Four : BaseSIMDTableLookup<1, 0b11, op, V128, VecListFour16b,
5618 asm, ".16b">;
5619
5620 def : SIMDTableLookupAlias<asm # ".8b",
5621 !cast<Instruction>(NAME#"v8i8One"),
5622 V64, VecListOne128>;
5623 def : SIMDTableLookupAlias<asm # ".8b",
5624 !cast<Instruction>(NAME#"v8i8Two"),
5625 V64, VecListTwo128>;
5626 def : SIMDTableLookupAlias<asm # ".8b",
5627 !cast<Instruction>(NAME#"v8i8Three"),
5628 V64, VecListThree128>;
5629 def : SIMDTableLookupAlias<asm # ".8b",
5630 !cast<Instruction>(NAME#"v8i8Four"),
5631 V64, VecListFour128>;
5632 def : SIMDTableLookupAlias<asm # ".16b",
5633 !cast<Instruction>(NAME#"v16i8One"),
5634 V128, VecListOne128>;
5635 def : SIMDTableLookupAlias<asm # ".16b",
5636 !cast<Instruction>(NAME#"v16i8Two"),
5637 V128, VecListTwo128>;
5638 def : SIMDTableLookupAlias<asm # ".16b",
5639 !cast<Instruction>(NAME#"v16i8Three"),
5640 V128, VecListThree128>;
5641 def : SIMDTableLookupAlias<asm # ".16b",
5642 !cast<Instruction>(NAME#"v16i8Four"),
5643 V128, VecListFour128>;
5644}
5645
5646multiclass SIMDTableLookupTied<bit op, string asm> {
5647 def v8i8One : BaseSIMDTableLookupTied<0, 0b00, op, V64, VecListOne16b,
5648 asm, ".8b">;
5649 def v8i8Two : BaseSIMDTableLookupTied<0, 0b01, op, V64, VecListTwo16b,
5650 asm, ".8b">;
5651 def v8i8Three : BaseSIMDTableLookupTied<0, 0b10, op, V64, VecListThree16b,
5652 asm, ".8b">;
5653 def v8i8Four : BaseSIMDTableLookupTied<0, 0b11, op, V64, VecListFour16b,
5654 asm, ".8b">;
5655 def v16i8One : BaseSIMDTableLookupTied<1, 0b00, op, V128, VecListOne16b,
5656 asm, ".16b">;
5657 def v16i8Two : BaseSIMDTableLookupTied<1, 0b01, op, V128, VecListTwo16b,
5658 asm, ".16b">;
5659 def v16i8Three: BaseSIMDTableLookupTied<1, 0b10, op, V128, VecListThree16b,
5660 asm, ".16b">;
5661 def v16i8Four : BaseSIMDTableLookupTied<1, 0b11, op, V128, VecListFour16b,
5662 asm, ".16b">;
5663
5664 def : SIMDTableLookupAlias<asm # ".8b",
5665 !cast<Instruction>(NAME#"v8i8One"),
5666 V64, VecListOne128>;
5667 def : SIMDTableLookupAlias<asm # ".8b",
5668 !cast<Instruction>(NAME#"v8i8Two"),
5669 V64, VecListTwo128>;
5670 def : SIMDTableLookupAlias<asm # ".8b",
5671 !cast<Instruction>(NAME#"v8i8Three"),
5672 V64, VecListThree128>;
5673 def : SIMDTableLookupAlias<asm # ".8b",
5674 !cast<Instruction>(NAME#"v8i8Four"),
5675 V64, VecListFour128>;
5676 def : SIMDTableLookupAlias<asm # ".16b",
5677 !cast<Instruction>(NAME#"v16i8One"),
5678 V128, VecListOne128>;
5679 def : SIMDTableLookupAlias<asm # ".16b",
5680 !cast<Instruction>(NAME#"v16i8Two"),
5681 V128, VecListTwo128>;
5682 def : SIMDTableLookupAlias<asm # ".16b",
5683 !cast<Instruction>(NAME#"v16i8Three"),
5684 V128, VecListThree128>;
5685 def : SIMDTableLookupAlias<asm # ".16b",
5686 !cast<Instruction>(NAME#"v16i8Four"),
5687 V128, VecListFour128>;
5688}
5689
5690
5691//----------------------------------------------------------------------------
5692// AdvSIMD scalar CPY
5693//----------------------------------------------------------------------------
5694let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5695class BaseSIMDScalarCPY<RegisterClass regtype, RegisterOperand vectype,
5696 string kind, Operand idxtype>
5697 : I<(outs regtype:$dst), (ins vectype:$src, idxtype:$idx), "mov",
5698 "{\t$dst, $src" # kind # "$idx" #
5699 "|\t$dst, $src$idx}", "", []>,
5700 Sched<[WriteV]> {
5701 bits<5> dst;
5702 bits<5> src;
5703 let Inst{31-21} = 0b01011110000;
5704 let Inst{15-10} = 0b000001;
5705 let Inst{9-5} = src;
5706 let Inst{4-0} = dst;
5707}
5708
5709class SIMDScalarCPYAlias<string asm, string size, Instruction inst,
5710 RegisterClass regtype, RegisterOperand vectype, Operand idxtype>
5711 : InstAlias<asm # "{\t$dst, $src" # size # "$index" #
5712 # "|\t$dst, $src$index}",
5713 (inst regtype:$dst, vectype:$src, idxtype:$index)>;
5714
5715
5716multiclass SIMDScalarCPY<string asm> {
5717 def i8 : BaseSIMDScalarCPY<FPR8, V128, ".b", VectorIndexB> {
5718 bits<4> idx;
5719 let Inst{20-17} = idx;
5720 let Inst{16} = 1;
5721 }
5722 def i16 : BaseSIMDScalarCPY<FPR16, V128, ".h", VectorIndexH> {
5723 bits<3> idx;
5724 let Inst{20-18} = idx;
5725 let Inst{17-16} = 0b10;
5726 }
5727 def i32 : BaseSIMDScalarCPY<FPR32, V128, ".s", VectorIndexS> {
5728 bits<2> idx;
5729 let Inst{20-19} = idx;
5730 let Inst{18-16} = 0b100;
5731 }
5732 def i64 : BaseSIMDScalarCPY<FPR64, V128, ".d", VectorIndexD> {
5733 bits<1> idx;
5734 let Inst{20} = idx;
5735 let Inst{19-16} = 0b1000;
5736 }
5737
5738 // 'DUP' mnemonic aliases.
5739 def : SIMDScalarCPYAlias<"dup", ".b",
5740 !cast<Instruction>(NAME#"i8"),
5741 FPR8, V128, VectorIndexB>;
5742 def : SIMDScalarCPYAlias<"dup", ".h",
5743 !cast<Instruction>(NAME#"i16"),
5744 FPR16, V128, VectorIndexH>;
5745 def : SIMDScalarCPYAlias<"dup", ".s",
5746 !cast<Instruction>(NAME#"i32"),
5747 FPR32, V128, VectorIndexS>;
5748 def : SIMDScalarCPYAlias<"dup", ".d",
5749 !cast<Instruction>(NAME#"i64"),
5750 FPR64, V128, VectorIndexD>;
5751}
5752
5753//----------------------------------------------------------------------------
5754// AdvSIMD modified immediate instructions
5755//----------------------------------------------------------------------------
5756
5757class BaseSIMDModifiedImm<bit Q, bit op, dag oops, dag iops,
5758 string asm, string op_string,
5759 string cstr, list<dag> pattern>
5760 : I<oops, iops, asm, op_string, cstr, pattern>,
5761 Sched<[WriteV]> {
5762 bits<5> Rd;
5763 bits<8> imm8;
5764 let Inst{31} = 0;
5765 let Inst{30} = Q;
5766 let Inst{29} = op;
5767 let Inst{28-19} = 0b0111100000;
5768 let Inst{18-16} = imm8{7-5};
5769 let Inst{11-10} = 0b01;
5770 let Inst{9-5} = imm8{4-0};
5771 let Inst{4-0} = Rd;
5772}
5773
5774class BaseSIMDModifiedImmVector<bit Q, bit op, RegisterOperand vectype,
5775 Operand immtype, dag opt_shift_iop,
5776 string opt_shift, string asm, string kind,
5777 list<dag> pattern>
5778 : BaseSIMDModifiedImm<Q, op, (outs vectype:$Rd),
5779 !con((ins immtype:$imm8), opt_shift_iop), asm,
5780 "{\t$Rd" # kind # ", $imm8" # opt_shift #
5781 "|" # kind # "\t$Rd, $imm8" # opt_shift # "}",
5782 "", pattern> {
5783 let DecoderMethod = "DecodeModImmInstruction";
5784}
5785
5786class BaseSIMDModifiedImmVectorTied<bit Q, bit op, RegisterOperand vectype,
5787 Operand immtype, dag opt_shift_iop,
5788 string opt_shift, string asm, string kind,
5789 list<dag> pattern>
5790 : BaseSIMDModifiedImm<Q, op, (outs vectype:$dst),
5791 !con((ins vectype:$Rd, immtype:$imm8), opt_shift_iop),
5792 asm, "{\t$Rd" # kind # ", $imm8" # opt_shift #
5793 "|" # kind # "\t$Rd, $imm8" # opt_shift # "}",
5794 "$Rd = $dst", pattern> {
5795 let DecoderMethod = "DecodeModImmTiedInstruction";
5796}
5797
5798class BaseSIMDModifiedImmVectorShift<bit Q, bit op, bits<2> b15_b12,
5799 RegisterOperand vectype, string asm,
5800 string kind, list<dag> pattern>
5801 : BaseSIMDModifiedImmVector<Q, op, vectype, imm0_255,
5802 (ins logical_vec_shift:$shift),
5803 "$shift", asm, kind, pattern> {
5804 bits<2> shift;
5805 let Inst{15} = b15_b12{1};
5806 let Inst{14-13} = shift;
5807 let Inst{12} = b15_b12{0};
5808}
5809
5810class BaseSIMDModifiedImmVectorShiftTied<bit Q, bit op, bits<2> b15_b12,
5811 RegisterOperand vectype, string asm,
5812 string kind, list<dag> pattern>
5813 : BaseSIMDModifiedImmVectorTied<Q, op, vectype, imm0_255,
5814 (ins logical_vec_shift:$shift),
5815 "$shift", asm, kind, pattern> {
5816 bits<2> shift;
5817 let Inst{15} = b15_b12{1};
5818 let Inst{14-13} = shift;
5819 let Inst{12} = b15_b12{0};
5820}
5821
5822
5823class BaseSIMDModifiedImmVectorShiftHalf<bit Q, bit op, bits<2> b15_b12,
5824 RegisterOperand vectype, string asm,
5825 string kind, list<dag> pattern>
5826 : BaseSIMDModifiedImmVector<Q, op, vectype, imm0_255,
5827 (ins logical_vec_hw_shift:$shift),
5828 "$shift", asm, kind, pattern> {
5829 bits<2> shift;
5830 let Inst{15} = b15_b12{1};
5831 let Inst{14} = 0;
5832 let Inst{13} = shift{0};
5833 let Inst{12} = b15_b12{0};
5834}
5835
5836class BaseSIMDModifiedImmVectorShiftHalfTied<bit Q, bit op, bits<2> b15_b12,
5837 RegisterOperand vectype, string asm,
5838 string kind, list<dag> pattern>
5839 : BaseSIMDModifiedImmVectorTied<Q, op, vectype, imm0_255,
5840 (ins logical_vec_hw_shift:$shift),
5841 "$shift", asm, kind, pattern> {
5842 bits<2> shift;
5843 let Inst{15} = b15_b12{1};
5844 let Inst{14} = 0;
5845 let Inst{13} = shift{0};
5846 let Inst{12} = b15_b12{0};
5847}
5848
5849multiclass SIMDModifiedImmVectorShift<bit op, bits<2> hw_cmode, bits<2> w_cmode,
5850 string asm> {
5851 def v4i16 : BaseSIMDModifiedImmVectorShiftHalf<0, op, hw_cmode, V64,
5852 asm, ".4h", []>;
5853 def v8i16 : BaseSIMDModifiedImmVectorShiftHalf<1, op, hw_cmode, V128,
5854 asm, ".8h", []>;
5855
5856 def v2i32 : BaseSIMDModifiedImmVectorShift<0, op, w_cmode, V64,
5857 asm, ".2s", []>;
5858 def v4i32 : BaseSIMDModifiedImmVectorShift<1, op, w_cmode, V128,
5859 asm, ".4s", []>;
5860}
5861
5862multiclass SIMDModifiedImmVectorShiftTied<bit op, bits<2> hw_cmode,
5863 bits<2> w_cmode, string asm,
5864 SDNode OpNode> {
5865 def v4i16 : BaseSIMDModifiedImmVectorShiftHalfTied<0, op, hw_cmode, V64,
5866 asm, ".4h",
5867 [(set (v4i16 V64:$dst), (OpNode V64:$Rd,
5868 imm0_255:$imm8,
5869 (i32 imm:$shift)))]>;
5870 def v8i16 : BaseSIMDModifiedImmVectorShiftHalfTied<1, op, hw_cmode, V128,
5871 asm, ".8h",
5872 [(set (v8i16 V128:$dst), (OpNode V128:$Rd,
5873 imm0_255:$imm8,
5874 (i32 imm:$shift)))]>;
5875
5876 def v2i32 : BaseSIMDModifiedImmVectorShiftTied<0, op, w_cmode, V64,
5877 asm, ".2s",
5878 [(set (v2i32 V64:$dst), (OpNode V64:$Rd,
5879 imm0_255:$imm8,
5880 (i32 imm:$shift)))]>;
5881 def v4i32 : BaseSIMDModifiedImmVectorShiftTied<1, op, w_cmode, V128,
5882 asm, ".4s",
5883 [(set (v4i32 V128:$dst), (OpNode V128:$Rd,
5884 imm0_255:$imm8,
5885 (i32 imm:$shift)))]>;
5886}
5887
5888class SIMDModifiedImmMoveMSL<bit Q, bit op, bits<4> cmode,
5889 RegisterOperand vectype, string asm,
5890 string kind, list<dag> pattern>
5891 : BaseSIMDModifiedImmVector<Q, op, vectype, imm0_255,
5892 (ins move_vec_shift:$shift),
5893 "$shift", asm, kind, pattern> {
5894 bits<1> shift;
5895 let Inst{15-13} = cmode{3-1};
5896 let Inst{12} = shift;
5897}
5898
5899class SIMDModifiedImmVectorNoShift<bit Q, bit op, bits<4> cmode,
5900 RegisterOperand vectype,
5901 Operand imm_type, string asm,
5902 string kind, list<dag> pattern>
5903 : BaseSIMDModifiedImmVector<Q, op, vectype, imm_type, (ins), "",
5904 asm, kind, pattern> {
5905 let Inst{15-12} = cmode;
5906}
5907
5908class SIMDModifiedImmScalarNoShift<bit Q, bit op, bits<4> cmode, string asm,
5909 list<dag> pattern>
5910 : BaseSIMDModifiedImm<Q, op, (outs FPR64:$Rd), (ins simdimmtype10:$imm8), asm,
5911 "\t$Rd, $imm8", "", pattern> {
5912 let Inst{15-12} = cmode;
5913 let DecoderMethod = "DecodeModImmInstruction";
5914}
5915
5916//----------------------------------------------------------------------------
5917// AdvSIMD indexed element
5918//----------------------------------------------------------------------------
5919
5920let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5921class BaseSIMDIndexed<bit Q, bit U, bit Scalar, bits<2> size, bits<4> opc,
5922 RegisterOperand dst_reg, RegisterOperand lhs_reg,
5923 RegisterOperand rhs_reg, Operand vec_idx, string asm,
5924 string apple_kind, string dst_kind, string lhs_kind,
5925 string rhs_kind, list<dag> pattern>
5926 : I<(outs dst_reg:$Rd), (ins lhs_reg:$Rn, rhs_reg:$Rm, vec_idx:$idx),
5927 asm,
5928 "{\t$Rd" # dst_kind # ", $Rn" # lhs_kind # ", $Rm" # rhs_kind # "$idx" #
5929 "|" # apple_kind # "\t$Rd, $Rn, $Rm$idx}", "", pattern>,
5930 Sched<[WriteV]> {
5931 bits<5> Rd;
5932 bits<5> Rn;
5933 bits<5> Rm;
5934
5935 let Inst{31} = 0;
5936 let Inst{30} = Q;
5937 let Inst{29} = U;
5938 let Inst{28} = Scalar;
5939 let Inst{27-24} = 0b1111;
5940 let Inst{23-22} = size;
5941 // Bit 21 must be set by the derived class.
5942 let Inst{20-16} = Rm;
5943 let Inst{15-12} = opc;
5944 // Bit 11 must be set by the derived class.
5945 let Inst{10} = 0;
5946 let Inst{9-5} = Rn;
5947 let Inst{4-0} = Rd;
5948}
5949
5950let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5951class BaseSIMDIndexedTied<bit Q, bit U, bit Scalar, bits<2> size, bits<4> opc,
5952 RegisterOperand dst_reg, RegisterOperand lhs_reg,
5953 RegisterOperand rhs_reg, Operand vec_idx, string asm,
5954 string apple_kind, string dst_kind, string lhs_kind,
5955 string rhs_kind, list<dag> pattern>
5956 : I<(outs dst_reg:$dst),
5957 (ins dst_reg:$Rd, lhs_reg:$Rn, rhs_reg:$Rm, vec_idx:$idx), asm,
5958 "{\t$Rd" # dst_kind # ", $Rn" # lhs_kind # ", $Rm" # rhs_kind # "$idx" #
5959 "|" # apple_kind # "\t$Rd, $Rn, $Rm$idx}", "$Rd = $dst", pattern>,
5960 Sched<[WriteV]> {
5961 bits<5> Rd;
5962 bits<5> Rn;
5963 bits<5> Rm;
5964
5965 let Inst{31} = 0;
5966 let Inst{30} = Q;
5967 let Inst{29} = U;
5968 let Inst{28} = Scalar;
5969 let Inst{27-24} = 0b1111;
5970 let Inst{23-22} = size;
5971 // Bit 21 must be set by the derived class.
5972 let Inst{20-16} = Rm;
5973 let Inst{15-12} = opc;
5974 // Bit 11 must be set by the derived class.
5975 let Inst{10} = 0;
5976 let Inst{9-5} = Rn;
5977 let Inst{4-0} = Rd;
5978}
5979
5980multiclass SIMDFPIndexedSD<bit U, bits<4> opc, string asm,
5981 SDPatternOperator OpNode> {
5982 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc,
5983 V64, V64,
5984 V128, VectorIndexS,
5985 asm, ".2s", ".2s", ".2s", ".s",
5986 [(set (v2f32 V64:$Rd),
5987 (OpNode (v2f32 V64:$Rn),
5988 (v2f32 (ARM64duplane32 (v4f32 V128:$Rm), VectorIndexS:$idx))))]> {
5989 bits<2> idx;
5990 let Inst{11} = idx{1};
5991 let Inst{21} = idx{0};
5992 }
5993
5994 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc,
5995 V128, V128,
5996 V128, VectorIndexS,
5997 asm, ".4s", ".4s", ".4s", ".s",
5998 [(set (v4f32 V128:$Rd),
5999 (OpNode (v4f32 V128:$Rn),
6000 (v4f32 (ARM64duplane32 (v4f32 V128:$Rm), VectorIndexS:$idx))))]> {
6001 bits<2> idx;
6002 let Inst{11} = idx{1};
6003 let Inst{21} = idx{0};
6004 }
6005
6006 def v2i64_indexed : BaseSIMDIndexed<1, U, 0, 0b11, opc,
6007 V128, V128,
6008 V128, VectorIndexD,
6009 asm, ".2d", ".2d", ".2d", ".d",
6010 [(set (v2f64 V128:$Rd),
6011 (OpNode (v2f64 V128:$Rn),
6012 (v2f64 (ARM64duplane64 (v2f64 V128:$Rm), VectorIndexD:$idx))))]> {
6013 bits<1> idx;
6014 let Inst{11} = idx{0};
6015 let Inst{21} = 0;
6016 }
6017
6018 def v1i32_indexed : BaseSIMDIndexed<1, U, 1, 0b10, opc,
6019 FPR32Op, FPR32Op, V128, VectorIndexS,
6020 asm, ".s", "", "", ".s",
6021 [(set (f32 FPR32Op:$Rd),
6022 (OpNode (f32 FPR32Op:$Rn),
6023 (f32 (vector_extract (v4f32 V128:$Rm),
6024 VectorIndexS:$idx))))]> {
6025 bits<2> idx;
6026 let Inst{11} = idx{1};
6027 let Inst{21} = idx{0};
6028 }
6029
6030 def v1i64_indexed : BaseSIMDIndexed<1, U, 1, 0b11, opc,
6031 FPR64Op, FPR64Op, V128, VectorIndexD,
6032 asm, ".d", "", "", ".d",
6033 [(set (f64 FPR64Op:$Rd),
6034 (OpNode (f64 FPR64Op:$Rn),
6035 (f64 (vector_extract (v2f64 V128:$Rm),
6036 VectorIndexD:$idx))))]> {
6037 bits<1> idx;
6038 let Inst{11} = idx{0};
6039 let Inst{21} = 0;
6040 }
6041}
6042
6043multiclass SIMDFPIndexedSDTiedPatterns<string INST, SDPatternOperator OpNode> {
6044 // 2 variants for the .2s version: DUPLANE from 128-bit and DUP scalar.
6045 def : Pat<(v2f32 (OpNode (v2f32 V64:$Rd), (v2f32 V64:$Rn),
6046 (ARM64duplane32 (v4f32 V128:$Rm),
6047 VectorIndexS:$idx))),
6048 (!cast<Instruction>(INST # v2i32_indexed)
6049 V64:$Rd, V64:$Rn, V128:$Rm, VectorIndexS:$idx)>;
6050 def : Pat<(v2f32 (OpNode (v2f32 V64:$Rd), (v2f32 V64:$Rn),
6051 (ARM64dup (f32 FPR32Op:$Rm)))),
6052 (!cast<Instruction>(INST # "v2i32_indexed") V64:$Rd, V64:$Rn,
6053 (SUBREG_TO_REG (i32 0), FPR32Op:$Rm, ssub), (i64 0))>;
6054
6055
6056 // 2 variants for the .4s version: DUPLANE from 128-bit and DUP scalar.
6057 def : Pat<(v4f32 (OpNode (v4f32 V128:$Rd), (v4f32 V128:$Rn),
6058 (ARM64duplane32 (v4f32 V128:$Rm),
6059 VectorIndexS:$idx))),
6060 (!cast<Instruction>(INST # "v4i32_indexed")
6061 V128:$Rd, V128:$Rn, V128:$Rm, VectorIndexS:$idx)>;
6062 def : Pat<(v4f32 (OpNode (v4f32 V128:$Rd), (v4f32 V128:$Rn),
6063 (ARM64dup (f32 FPR32Op:$Rm)))),
6064 (!cast<Instruction>(INST # "v4i32_indexed") V128:$Rd, V128:$Rn,
6065 (SUBREG_TO_REG (i32 0), FPR32Op:$Rm, ssub), (i64 0))>;
6066
6067 // 2 variants for the .2d version: DUPLANE from 128-bit and DUP scalar.
6068 def : Pat<(v2f64 (OpNode (v2f64 V128:$Rd), (v2f64 V128:$Rn),
6069 (ARM64duplane64 (v2f64 V128:$Rm),
6070 VectorIndexD:$idx))),
6071 (!cast<Instruction>(INST # "v2i64_indexed")
6072 V128:$Rd, V128:$Rn, V128:$Rm, VectorIndexS:$idx)>;
6073 def : Pat<(v2f64 (OpNode (v2f64 V128:$Rd), (v2f64 V128:$Rn),
6074 (ARM64dup (f64 FPR64Op:$Rm)))),
6075 (!cast<Instruction>(INST # "v2i64_indexed") V128:$Rd, V128:$Rn,
6076 (SUBREG_TO_REG (i32 0), FPR64Op:$Rm, dsub), (i64 0))>;
6077
6078 // 2 variants for 32-bit scalar version: extract from .2s or from .4s
6079 def : Pat<(f32 (OpNode (f32 FPR32:$Rd), (f32 FPR32:$Rn),
6080 (vector_extract (v4f32 V128:$Rm), VectorIndexS:$idx))),
6081 (!cast<Instruction>(INST # "v1i32_indexed") FPR32:$Rd, FPR32:$Rn,
6082 V128:$Rm, VectorIndexS:$idx)>;
6083 def : Pat<(f32 (OpNode (f32 FPR32:$Rd), (f32 FPR32:$Rn),
6084 (vector_extract (v2f32 V64:$Rm), VectorIndexS:$idx))),
6085 (!cast<Instruction>(INST # "v1i32_indexed") FPR32:$Rd, FPR32:$Rn,
6086 (SUBREG_TO_REG (i32 0), V64:$Rm, dsub), VectorIndexS:$idx)>;
6087
6088 // 1 variant for 64-bit scalar version: extract from .1d or from .2d
6089 def : Pat<(f64 (OpNode (f64 FPR64:$Rd), (f64 FPR64:$Rn),
6090 (vector_extract (v2f64 V128:$Rm), VectorIndexD:$idx))),
6091 (!cast<Instruction>(INST # "v1i64_indexed") FPR64:$Rd, FPR64:$Rn,
6092 V128:$Rm, VectorIndexD:$idx)>;
6093}
6094
6095multiclass SIMDFPIndexedSDTied<bit U, bits<4> opc, string asm> {
6096 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc, V64, V64,
6097 V128, VectorIndexS,
6098 asm, ".2s", ".2s", ".2s", ".s", []> {
6099 bits<2> idx;
6100 let Inst{11} = idx{1};
6101 let Inst{21} = idx{0};
6102 }
6103
6104 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc,
6105 V128, V128,
6106 V128, VectorIndexS,
6107 asm, ".4s", ".4s", ".4s", ".s", []> {
6108 bits<2> idx;
6109 let Inst{11} = idx{1};
6110 let Inst{21} = idx{0};
6111 }
6112
6113 def v2i64_indexed : BaseSIMDIndexedTied<1, U, 0, 0b11, opc,
6114 V128, V128,
6115 V128, VectorIndexD,
6116 asm, ".2d", ".2d", ".2d", ".d", []> {
6117 bits<1> idx;
6118 let Inst{11} = idx{0};
6119 let Inst{21} = 0;
6120 }
6121
6122
6123 def v1i32_indexed : BaseSIMDIndexedTied<1, U, 1, 0b10, opc,
6124 FPR32Op, FPR32Op, V128, VectorIndexS,
6125 asm, ".s", "", "", ".s", []> {
6126 bits<2> idx;
6127 let Inst{11} = idx{1};
6128 let Inst{21} = idx{0};
6129 }
6130
6131 def v1i64_indexed : BaseSIMDIndexedTied<1, U, 1, 0b11, opc,
6132 FPR64Op, FPR64Op, V128, VectorIndexD,
6133 asm, ".d", "", "", ".d", []> {
6134 bits<1> idx;
6135 let Inst{11} = idx{0};
6136 let Inst{21} = 0;
6137 }
6138}
6139
6140multiclass SIMDIndexedHS<bit U, bits<4> opc, string asm,
6141 SDPatternOperator OpNode> {
6142 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc, V64, V64,
6143 V128_lo, VectorIndexH,
6144 asm, ".4h", ".4h", ".4h", ".h",
6145 [(set (v4i16 V64:$Rd),
6146 (OpNode (v4i16 V64:$Rn),
6147 (v4i16 (ARM64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
6148 bits<3> idx;
6149 let Inst{11} = idx{2};
6150 let Inst{21} = idx{1};
6151 let Inst{20} = idx{0};
6152 }
6153
6154 def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc,
6155 V128, V128,
6156 V128_lo, VectorIndexH,
6157 asm, ".8h", ".8h", ".8h", ".h",
6158 [(set (v8i16 V128:$Rd),
6159 (OpNode (v8i16 V128:$Rn),
6160 (v8i16 (ARM64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
6161 bits<3> idx;
6162 let Inst{11} = idx{2};
6163 let Inst{21} = idx{1};
6164 let Inst{20} = idx{0};
6165 }
6166
6167 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc,
6168 V64, V64,
6169 V128, VectorIndexS,
6170 asm, ".2s", ".2s", ".2s", ".s",
6171 [(set (v2i32 V64:$Rd),
6172 (OpNode (v2i32 V64:$Rn),
6173 (v2i32 (ARM64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
6174 bits<2> idx;
6175 let Inst{11} = idx{1};
6176 let Inst{21} = idx{0};
6177 }
6178
6179 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc,
6180 V128, V128,
6181 V128, VectorIndexS,
6182 asm, ".4s", ".4s", ".4s", ".s",
6183 [(set (v4i32 V128:$Rd),
6184 (OpNode (v4i32 V128:$Rn),
6185 (v4i32 (ARM64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
6186 bits<2> idx;
6187 let Inst{11} = idx{1};
6188 let Inst{21} = idx{0};
6189 }
6190
6191 def v1i16_indexed : BaseSIMDIndexed<1, U, 1, 0b01, opc,
6192 FPR16Op, FPR16Op, V128_lo, VectorIndexH,
6193 asm, ".h", "", "", ".h", []> {
6194 bits<3> idx;
6195 let Inst{11} = idx{2};
6196 let Inst{21} = idx{1};
6197 let Inst{20} = idx{0};
6198 }
6199
6200 def v1i32_indexed : BaseSIMDIndexed<1, U, 1, 0b10, opc,
6201 FPR32Op, FPR32Op, V128, VectorIndexS,
6202 asm, ".s", "", "", ".s",
6203 [(set (i32 FPR32Op:$Rd),
6204 (OpNode FPR32Op:$Rn,
6205 (i32 (vector_extract (v4i32 V128:$Rm),
6206 VectorIndexS:$idx))))]> {
6207 bits<2> idx;
6208 let Inst{11} = idx{1};
6209 let Inst{21} = idx{0};
6210 }
6211}
6212
6213multiclass SIMDVectorIndexedHS<bit U, bits<4> opc, string asm,
6214 SDPatternOperator OpNode> {
6215 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc,
6216 V64, V64,
6217 V128_lo, VectorIndexH,
6218 asm, ".4h", ".4h", ".4h", ".h",
6219 [(set (v4i16 V64:$Rd),
6220 (OpNode (v4i16 V64:$Rn),
6221 (v4i16 (ARM64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
6222 bits<3> idx;
6223 let Inst{11} = idx{2};
6224 let Inst{21} = idx{1};
6225 let Inst{20} = idx{0};
6226 }
6227
6228 def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc,
6229 V128, V128,
6230 V128_lo, VectorIndexH,
6231 asm, ".8h", ".8h", ".8h", ".h",
6232 [(set (v8i16 V128:$Rd),
6233 (OpNode (v8i16 V128:$Rn),
6234 (v8i16 (ARM64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
6235 bits<3> idx;
6236 let Inst{11} = idx{2};
6237 let Inst{21} = idx{1};
6238 let Inst{20} = idx{0};
6239 }
6240
6241 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc,
6242 V64, V64,
6243 V128, VectorIndexS,
6244 asm, ".2s", ".2s", ".2s", ".s",
6245 [(set (v2i32 V64:$Rd),
6246 (OpNode (v2i32 V64:$Rn),
6247 (v2i32 (ARM64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
6248 bits<2> idx;
6249 let Inst{11} = idx{1};
6250 let Inst{21} = idx{0};
6251 }
6252
6253 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc,
6254 V128, V128,
6255 V128, VectorIndexS,
6256 asm, ".4s", ".4s", ".4s", ".s",
6257 [(set (v4i32 V128:$Rd),
6258 (OpNode (v4i32 V128:$Rn),
6259 (v4i32 (ARM64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
6260 bits<2> idx;
6261 let Inst{11} = idx{1};
6262 let Inst{21} = idx{0};
6263 }
6264}
6265
6266multiclass SIMDVectorIndexedHSTied<bit U, bits<4> opc, string asm,
6267 SDPatternOperator OpNode> {
6268 def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc, V64, V64,
6269 V128_lo, VectorIndexH,
6270 asm, ".4h", ".4h", ".4h", ".h",
6271 [(set (v4i16 V64:$dst),
6272 (OpNode (v4i16 V64:$Rd),(v4i16 V64:$Rn),
6273 (v4i16 (ARM64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
6274 bits<3> idx;
6275 let Inst{11} = idx{2};
6276 let Inst{21} = idx{1};
6277 let Inst{20} = idx{0};
6278 }
6279
6280 def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc,
6281 V128, V128,
6282 V128_lo, VectorIndexH,
6283 asm, ".8h", ".8h", ".8h", ".h",
6284 [(set (v8i16 V128:$dst),
6285 (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn),
6286 (v8i16 (ARM64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
6287 bits<3> idx;
6288 let Inst{11} = idx{2};
6289 let Inst{21} = idx{1};
6290 let Inst{20} = idx{0};
6291 }
6292
6293 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc,
6294 V64, V64,
6295 V128, VectorIndexS,
6296 asm, ".2s", ".2s", ".2s", ".s",
6297 [(set (v2i32 V64:$dst),
6298 (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn),
6299 (v2i32 (ARM64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
6300 bits<2> idx;
6301 let Inst{11} = idx{1};
6302 let Inst{21} = idx{0};
6303 }
6304
6305 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc,
6306 V128, V128,
6307 V128, VectorIndexS,
6308 asm, ".4s", ".4s", ".4s", ".s",
6309 [(set (v4i32 V128:$dst),
6310 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn),
6311 (v4i32 (ARM64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
6312 bits<2> idx;
6313 let Inst{11} = idx{1};
6314 let Inst{21} = idx{0};
6315 }
6316}
6317
6318multiclass SIMDIndexedLongSD<bit U, bits<4> opc, string asm,
6319 SDPatternOperator OpNode> {
6320 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc,
6321 V128, V64,
6322 V128_lo, VectorIndexH,
6323 asm, ".4s", ".4s", ".4h", ".h",
6324 [(set (v4i32 V128:$Rd),
6325 (OpNode (v4i16 V64:$Rn),
6326 (v4i16 (ARM64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
6327 bits<3> idx;
6328 let Inst{11} = idx{2};
6329 let Inst{21} = idx{1};
6330 let Inst{20} = idx{0};
6331 }
6332
6333 def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc,
6334 V128, V128,
6335 V128_lo, VectorIndexH,
6336 asm#"2", ".4s", ".4s", ".8h", ".h",
6337 [(set (v4i32 V128:$Rd),
6338 (OpNode (extract_high_v8i16 V128:$Rn),
6339 (extract_high_v8i16 (ARM64duplane16 (v8i16 V128_lo:$Rm),
6340 VectorIndexH:$idx))))]> {
6341
6342 bits<3> idx;
6343 let Inst{11} = idx{2};
6344 let Inst{21} = idx{1};
6345 let Inst{20} = idx{0};
6346 }
6347
6348 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc,
6349 V128, V64,
6350 V128, VectorIndexS,
6351 asm, ".2d", ".2d", ".2s", ".s",
6352 [(set (v2i64 V128:$Rd),
6353 (OpNode (v2i32 V64:$Rn),
6354 (v2i32 (ARM64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
6355 bits<2> idx;
6356 let Inst{11} = idx{1};
6357 let Inst{21} = idx{0};
6358 }
6359
6360 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc,
6361 V128, V128,
6362 V128, VectorIndexS,
6363 asm#"2", ".2d", ".2d", ".4s", ".s",
6364 [(set (v2i64 V128:$Rd),
6365 (OpNode (extract_high_v4i32 V128:$Rn),
6366 (extract_high_v4i32 (ARM64duplane32 (v4i32 V128:$Rm),
6367 VectorIndexS:$idx))))]> {
6368 bits<2> idx;
6369 let Inst{11} = idx{1};
6370 let Inst{21} = idx{0};
6371 }
6372
6373 def v1i32_indexed : BaseSIMDIndexed<1, U, 1, 0b01, opc,
6374 FPR32Op, FPR16Op, V128_lo, VectorIndexH,
6375 asm, ".h", "", "", ".h", []> {
6376 bits<3> idx;
6377 let Inst{11} = idx{2};
6378 let Inst{21} = idx{1};
6379 let Inst{20} = idx{0};
6380 }
6381
6382 def v1i64_indexed : BaseSIMDIndexed<1, U, 1, 0b10, opc,
6383 FPR64Op, FPR32Op, V128, VectorIndexS,
6384 asm, ".s", "", "", ".s", []> {
6385 bits<2> idx;
6386 let Inst{11} = idx{1};
6387 let Inst{21} = idx{0};
6388 }
6389}
6390
6391multiclass SIMDIndexedLongSQDMLXSDTied<bit U, bits<4> opc, string asm,
6392 SDPatternOperator Accum> {
6393 def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc,
6394 V128, V64,
6395 V128_lo, VectorIndexH,
6396 asm, ".4s", ".4s", ".4h", ".h",
6397 [(set (v4i32 V128:$dst),
6398 (Accum (v4i32 V128:$Rd),
6399 (v4i32 (int_arm64_neon_sqdmull
6400 (v4i16 V64:$Rn),
6401 (v4i16 (ARM64duplane16 (v8i16 V128_lo:$Rm),
6402 VectorIndexH:$idx))))))]> {
6403 bits<3> idx;
6404 let Inst{11} = idx{2};
6405 let Inst{21} = idx{1};
6406 let Inst{20} = idx{0};
6407 }
6408
6409 // FIXME: it would be nice to use the scalar (v1i32) instruction here, but an
6410 // intermediate EXTRACT_SUBREG would be untyped.
6411 def : Pat<(i32 (Accum (i32 FPR32Op:$Rd),
6412 (i32 (vector_extract (v4i32
6413 (int_arm64_neon_sqdmull (v4i16 V64:$Rn),
6414 (v4i16 (ARM64duplane16 (v8i16 V128_lo:$Rm),
6415 VectorIndexH:$idx)))),
6416 (i64 0))))),
6417 (EXTRACT_SUBREG
6418 (!cast<Instruction>(NAME # v4i16_indexed)
6419 (SUBREG_TO_REG (i32 0), FPR32Op:$Rd, ssub), V64:$Rn,
6420 V128_lo:$Rm, VectorIndexH:$idx),
6421 ssub)>;
6422
6423 def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc,
6424 V128, V128,
6425 V128_lo, VectorIndexH,
6426 asm#"2", ".4s", ".4s", ".8h", ".h",
6427 [(set (v4i32 V128:$dst),
6428 (Accum (v4i32 V128:$Rd),
6429 (v4i32 (int_arm64_neon_sqdmull
6430 (extract_high_v8i16 V128:$Rn),
6431 (extract_high_v8i16
6432 (ARM64duplane16 (v8i16 V128_lo:$Rm),
6433 VectorIndexH:$idx))))))]> {
6434 bits<3> idx;
6435 let Inst{11} = idx{2};
6436 let Inst{21} = idx{1};
6437 let Inst{20} = idx{0};
6438 }
6439
6440 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc,
6441 V128, V64,
6442 V128, VectorIndexS,
6443 asm, ".2d", ".2d", ".2s", ".s",
6444 [(set (v2i64 V128:$dst),
6445 (Accum (v2i64 V128:$Rd),
6446 (v2i64 (int_arm64_neon_sqdmull
6447 (v2i32 V64:$Rn),
6448 (v2i32 (ARM64duplane32 (v4i32 V128:$Rm),
6449 VectorIndexS:$idx))))))]> {
6450 bits<2> idx;
6451 let Inst{11} = idx{1};
6452 let Inst{21} = idx{0};
6453 }
6454
6455 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc,
6456 V128, V128,
6457 V128, VectorIndexS,
6458 asm#"2", ".2d", ".2d", ".4s", ".s",
6459 [(set (v2i64 V128:$dst),
6460 (Accum (v2i64 V128:$Rd),
6461 (v2i64 (int_arm64_neon_sqdmull
6462 (extract_high_v4i32 V128:$Rn),
6463 (extract_high_v4i32
6464 (ARM64duplane32 (v4i32 V128:$Rm),
6465 VectorIndexS:$idx))))))]> {
6466 bits<2> idx;
6467 let Inst{11} = idx{1};
6468 let Inst{21} = idx{0};
6469 }
6470
6471 def v1i32_indexed : BaseSIMDIndexedTied<1, U, 1, 0b01, opc,
6472 FPR32Op, FPR16Op, V128_lo, VectorIndexH,
6473 asm, ".h", "", "", ".h", []> {
6474 bits<3> idx;
6475 let Inst{11} = idx{2};
6476 let Inst{21} = idx{1};
6477 let Inst{20} = idx{0};
6478 }
6479
6480
6481 def v1i64_indexed : BaseSIMDIndexedTied<1, U, 1, 0b10, opc,
6482 FPR64Op, FPR32Op, V128, VectorIndexS,
6483 asm, ".s", "", "", ".s",
6484 [(set (i64 FPR64Op:$dst),
6485 (Accum (i64 FPR64Op:$Rd),
6486 (i64 (int_arm64_neon_sqdmulls_scalar
6487 (i32 FPR32Op:$Rn),
6488 (i32 (vector_extract (v4i32 V128:$Rm),
6489 VectorIndexS:$idx))))))]> {
6490
6491 bits<2> idx;
6492 let Inst{11} = idx{1};
6493 let Inst{21} = idx{0};
6494 }
6495}
6496
6497multiclass SIMDVectorIndexedLongSD<bit U, bits<4> opc, string asm,
6498 SDPatternOperator OpNode> {
6499 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
6500 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc,
6501 V128, V64,
6502 V128_lo, VectorIndexH,
6503 asm, ".4s", ".4s", ".4h", ".h",
6504 [(set (v4i32 V128:$Rd),
6505 (OpNode (v4i16 V64:$Rn),
6506 (v4i16 (ARM64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
6507 bits<3> idx;
6508 let Inst{11} = idx{2};
6509 let Inst{21} = idx{1};
6510 let Inst{20} = idx{0};
6511 }
6512
6513 def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc,
6514 V128, V128,
6515 V128_lo, VectorIndexH,
6516 asm#"2", ".4s", ".4s", ".8h", ".h",
6517 [(set (v4i32 V128:$Rd),
6518 (OpNode (extract_high_v8i16 V128:$Rn),
6519 (extract_high_v8i16 (ARM64duplane16 (v8i16 V128_lo:$Rm),
6520 VectorIndexH:$idx))))]> {
6521
6522 bits<3> idx;
6523 let Inst{11} = idx{2};
6524 let Inst{21} = idx{1};
6525 let Inst{20} = idx{0};
6526 }
6527
6528 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc,
6529 V128, V64,
6530 V128, VectorIndexS,
6531 asm, ".2d", ".2d", ".2s", ".s",
6532 [(set (v2i64 V128:$Rd),
6533 (OpNode (v2i32 V64:$Rn),
6534 (v2i32 (ARM64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
6535 bits<2> idx;
6536 let Inst{11} = idx{1};
6537 let Inst{21} = idx{0};
6538 }
6539
6540 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc,
6541 V128, V128,
6542 V128, VectorIndexS,
6543 asm#"2", ".2d", ".2d", ".4s", ".s",
6544 [(set (v2i64 V128:$Rd),
6545 (OpNode (extract_high_v4i32 V128:$Rn),
6546 (extract_high_v4i32 (ARM64duplane32 (v4i32 V128:$Rm),
6547 VectorIndexS:$idx))))]> {
6548 bits<2> idx;
6549 let Inst{11} = idx{1};
6550 let Inst{21} = idx{0};
6551 }
6552 }
6553}
6554
6555multiclass SIMDVectorIndexedLongSDTied<bit U, bits<4> opc, string asm,
6556 SDPatternOperator OpNode> {
6557 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
6558 def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc,
6559 V128, V64,
6560 V128_lo, VectorIndexH,
6561 asm, ".4s", ".4s", ".4h", ".h",
6562 [(set (v4i32 V128:$dst),
6563 (OpNode (v4i32 V128:$Rd), (v4i16 V64:$Rn),
6564 (v4i16 (ARM64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
6565 bits<3> idx;
6566 let Inst{11} = idx{2};
6567 let Inst{21} = idx{1};
6568 let Inst{20} = idx{0};
6569 }
6570
6571 def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc,
6572 V128, V128,
6573 V128_lo, VectorIndexH,
6574 asm#"2", ".4s", ".4s", ".8h", ".h",
6575 [(set (v4i32 V128:$dst),
6576 (OpNode (v4i32 V128:$Rd),
6577 (extract_high_v8i16 V128:$Rn),
6578 (extract_high_v8i16 (ARM64duplane16 (v8i16 V128_lo:$Rm),
6579 VectorIndexH:$idx))))]> {
6580 bits<3> idx;
6581 let Inst{11} = idx{2};
6582 let Inst{21} = idx{1};
6583 let Inst{20} = idx{0};
6584 }
6585
6586 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc,
6587 V128, V64,
6588 V128, VectorIndexS,
6589 asm, ".2d", ".2d", ".2s", ".s",
6590 [(set (v2i64 V128:$dst),
6591 (OpNode (v2i64 V128:$Rd), (v2i32 V64:$Rn),
6592 (v2i32 (ARM64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
6593 bits<2> idx;
6594 let Inst{11} = idx{1};
6595 let Inst{21} = idx{0};
6596 }
6597
6598 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc,
6599 V128, V128,
6600 V128, VectorIndexS,
6601 asm#"2", ".2d", ".2d", ".4s", ".s",
6602 [(set (v2i64 V128:$dst),
6603 (OpNode (v2i64 V128:$Rd),
6604 (extract_high_v4i32 V128:$Rn),
6605 (extract_high_v4i32 (ARM64duplane32 (v4i32 V128:$Rm),
6606 VectorIndexS:$idx))))]> {
6607 bits<2> idx;
6608 let Inst{11} = idx{1};
6609 let Inst{21} = idx{0};
6610 }
6611 }
6612}
6613
6614//----------------------------------------------------------------------------
6615// AdvSIMD scalar shift by immediate
6616//----------------------------------------------------------------------------
6617
6618let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
6619class BaseSIMDScalarShift<bit U, bits<5> opc, bits<7> fixed_imm,
6620 RegisterClass regtype1, RegisterClass regtype2,
6621 Operand immtype, string asm, list<dag> pattern>
6622 : I<(outs regtype1:$Rd), (ins regtype2:$Rn, immtype:$imm),
6623 asm, "\t$Rd, $Rn, $imm", "", pattern>,
6624 Sched<[WriteV]> {
6625 bits<5> Rd;
6626 bits<5> Rn;
6627 bits<7> imm;
6628 let Inst{31-30} = 0b01;
6629 let Inst{29} = U;
6630 let Inst{28-23} = 0b111110;
6631 let Inst{22-16} = fixed_imm;
6632 let Inst{15-11} = opc;
6633 let Inst{10} = 1;
6634 let Inst{9-5} = Rn;
6635 let Inst{4-0} = Rd;
6636}
6637
6638let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
6639class BaseSIMDScalarShiftTied<bit U, bits<5> opc, bits<7> fixed_imm,
6640 RegisterClass regtype1, RegisterClass regtype2,
6641 Operand immtype, string asm, list<dag> pattern>
6642 : I<(outs regtype1:$dst), (ins regtype1:$Rd, regtype2:$Rn, immtype:$imm),
6643 asm, "\t$Rd, $Rn, $imm", "$Rd = $dst", pattern>,
6644 Sched<[WriteV]> {
6645 bits<5> Rd;
6646 bits<5> Rn;
6647 bits<7> imm;
6648 let Inst{31-30} = 0b01;
6649 let Inst{29} = U;
6650 let Inst{28-23} = 0b111110;
6651 let Inst{22-16} = fixed_imm;
6652 let Inst{15-11} = opc;
6653 let Inst{10} = 1;
6654 let Inst{9-5} = Rn;
6655 let Inst{4-0} = Rd;
6656}
6657
6658
6659multiclass SIMDScalarRShiftSD<bit U, bits<5> opc, string asm> {
6660 def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?},
6661 FPR32, FPR32, vecshiftR32, asm, []> {
6662 let Inst{20-16} = imm{4-0};
6663 }
6664
6665 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?},
6666 FPR64, FPR64, vecshiftR64, asm, []> {
6667 let Inst{21-16} = imm{5-0};
6668 }
6669}
6670
6671multiclass SIMDScalarRShiftD<bit U, bits<5> opc, string asm,
6672 SDPatternOperator OpNode> {
6673 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?},
6674 FPR64, FPR64, vecshiftR64, asm,
Tim Northover5081cd02014-03-31 15:46:46 +00006675 [(set (i64 FPR64:$Rd),
6676 (OpNode (i64 FPR64:$Rn), (i32 vecshiftR64:$imm)))]> {
Tim Northover00ed9962014-03-29 10:18:08 +00006677 let Inst{21-16} = imm{5-0};
6678 }
Tim Northover5081cd02014-03-31 15:46:46 +00006679
6680 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rn), (i32 vecshiftR64:$imm))),
6681 (!cast<Instruction>(NAME # "d") FPR64:$Rn, vecshiftR64:$imm)>;
Tim Northover00ed9962014-03-29 10:18:08 +00006682}
6683
Tim Northover00ed9962014-03-29 10:18:08 +00006684multiclass SIMDScalarRShiftDTied<bit U, bits<5> opc, string asm,
6685 SDPatternOperator OpNode = null_frag> {
6686 def d : BaseSIMDScalarShiftTied<U, opc, {1,?,?,?,?,?,?},
6687 FPR64, FPR64, vecshiftR64, asm,
Tim Northover5081cd02014-03-31 15:46:46 +00006688 [(set (i64 FPR64:$dst), (OpNode (i64 FPR64:$Rd), (i64 FPR64:$Rn),
6689 (i32 vecshiftR64:$imm)))]> {
Tim Northover00ed9962014-03-29 10:18:08 +00006690 let Inst{21-16} = imm{5-0};
6691 }
Tim Northover5081cd02014-03-31 15:46:46 +00006692
6693 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rd), (v1i64 FPR64:$Rn),
6694 (i32 vecshiftR64:$imm))),
6695 (!cast<Instruction>(NAME # "d") FPR64:$Rd, FPR64:$Rn,
6696 vecshiftR64:$imm)>;
Tim Northover00ed9962014-03-29 10:18:08 +00006697}
6698
6699multiclass SIMDScalarLShiftD<bit U, bits<5> opc, string asm,
6700 SDPatternOperator OpNode> {
6701 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?},
6702 FPR64, FPR64, vecshiftL64, asm,
6703 [(set (v1i64 FPR64:$Rd),
6704 (OpNode (v1i64 FPR64:$Rn), (i32 vecshiftL64:$imm)))]> {
6705 let Inst{21-16} = imm{5-0};
6706 }
6707}
6708
6709let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
6710multiclass SIMDScalarLShiftDTied<bit U, bits<5> opc, string asm> {
6711 def d : BaseSIMDScalarShiftTied<U, opc, {1,?,?,?,?,?,?},
6712 FPR64, FPR64, vecshiftL64, asm, []> {
6713 let Inst{21-16} = imm{5-0};
6714 }
6715}
6716
6717let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
6718multiclass SIMDScalarRShiftBHS<bit U, bits<5> opc, string asm,
6719 SDPatternOperator OpNode = null_frag> {
6720 def b : BaseSIMDScalarShift<U, opc, {0,0,0,1,?,?,?},
6721 FPR8, FPR16, vecshiftR8, asm, []> {
6722 let Inst{18-16} = imm{2-0};
6723 }
6724
6725 def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?},
6726 FPR16, FPR32, vecshiftR16, asm, []> {
6727 let Inst{19-16} = imm{3-0};
6728 }
6729
6730 def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?},
6731 FPR32, FPR64, vecshiftR32, asm,
6732 [(set (i32 FPR32:$Rd), (OpNode (i64 FPR64:$Rn), vecshiftR32:$imm))]> {
6733 let Inst{20-16} = imm{4-0};
6734 }
6735}
6736
6737multiclass SIMDScalarLShiftBHSD<bit U, bits<5> opc, string asm,
6738 SDPatternOperator OpNode> {
6739 def b : BaseSIMDScalarShift<U, opc, {0,0,0,1,?,?,?},
6740 FPR8, FPR8, vecshiftL8, asm, []> {
6741 let Inst{18-16} = imm{2-0};
6742 }
6743
6744 def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?},
6745 FPR16, FPR16, vecshiftL16, asm, []> {
6746 let Inst{19-16} = imm{3-0};
6747 }
6748
6749 def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?},
6750 FPR32, FPR32, vecshiftL32, asm,
6751 [(set (i32 FPR32:$Rd), (OpNode (i32 FPR32:$Rn), (i32 vecshiftL32:$imm)))]> {
6752 let Inst{20-16} = imm{4-0};
6753 }
6754
6755 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?},
6756 FPR64, FPR64, vecshiftL64, asm,
6757 [(set (v1i64 FPR64:$Rd), (OpNode (v1i64 FPR64:$Rn),
6758 (i32 vecshiftL64:$imm)))]> {
6759 let Inst{21-16} = imm{5-0};
6760 }
6761}
6762
6763multiclass SIMDScalarRShiftBHSD<bit U, bits<5> opc, string asm> {
6764 def b : BaseSIMDScalarShift<U, opc, {0,0,0,1,?,?,?},
6765 FPR8, FPR8, vecshiftR8, asm, []> {
6766 let Inst{18-16} = imm{2-0};
6767 }
6768
6769 def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?},
6770 FPR16, FPR16, vecshiftR16, asm, []> {
6771 let Inst{19-16} = imm{3-0};
6772 }
6773
6774 def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?},
6775 FPR32, FPR32, vecshiftR32, asm, []> {
6776 let Inst{20-16} = imm{4-0};
6777 }
6778
6779 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?},
6780 FPR64, FPR64, vecshiftR64, asm, []> {
6781 let Inst{21-16} = imm{5-0};
6782 }
6783}
6784
6785//----------------------------------------------------------------------------
6786// AdvSIMD vector x indexed element
6787//----------------------------------------------------------------------------
6788
6789let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
6790class BaseSIMDVectorShift<bit Q, bit U, bits<5> opc, bits<7> fixed_imm,
6791 RegisterOperand dst_reg, RegisterOperand src_reg,
6792 Operand immtype,
6793 string asm, string dst_kind, string src_kind,
6794 list<dag> pattern>
6795 : I<(outs dst_reg:$Rd), (ins src_reg:$Rn, immtype:$imm),
6796 asm, "{\t$Rd" # dst_kind # ", $Rn" # src_kind # ", $imm" #
6797 "|" # dst_kind # "\t$Rd, $Rn, $imm}", "", pattern>,
6798 Sched<[WriteV]> {
6799 bits<5> Rd;
6800 bits<5> Rn;
6801 let Inst{31} = 0;
6802 let Inst{30} = Q;
6803 let Inst{29} = U;
6804 let Inst{28-23} = 0b011110;
6805 let Inst{22-16} = fixed_imm;
6806 let Inst{15-11} = opc;
6807 let Inst{10} = 1;
6808 let Inst{9-5} = Rn;
6809 let Inst{4-0} = Rd;
6810}
6811
6812let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
6813class BaseSIMDVectorShiftTied<bit Q, bit U, bits<5> opc, bits<7> fixed_imm,
6814 RegisterOperand vectype1, RegisterOperand vectype2,
6815 Operand immtype,
6816 string asm, string dst_kind, string src_kind,
6817 list<dag> pattern>
6818 : I<(outs vectype1:$dst), (ins vectype1:$Rd, vectype2:$Rn, immtype:$imm),
6819 asm, "{\t$Rd" # dst_kind # ", $Rn" # src_kind # ", $imm" #
6820 "|" # dst_kind # "\t$Rd, $Rn, $imm}", "$Rd = $dst", pattern>,
6821 Sched<[WriteV]> {
6822 bits<5> Rd;
6823 bits<5> Rn;
6824 let Inst{31} = 0;
6825 let Inst{30} = Q;
6826 let Inst{29} = U;
6827 let Inst{28-23} = 0b011110;
6828 let Inst{22-16} = fixed_imm;
6829 let Inst{15-11} = opc;
6830 let Inst{10} = 1;
6831 let Inst{9-5} = Rn;
6832 let Inst{4-0} = Rd;
6833}
6834
6835multiclass SIMDVectorRShiftSD<bit U, bits<5> opc, string asm,
6836 Intrinsic OpNode> {
6837 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?},
6838 V64, V64, vecshiftR32,
6839 asm, ".2s", ".2s",
6840 [(set (v2i32 V64:$Rd), (OpNode (v2f32 V64:$Rn), (i32 imm:$imm)))]> {
6841 bits<5> imm;
6842 let Inst{20-16} = imm;
6843 }
6844
6845 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?},
6846 V128, V128, vecshiftR32,
6847 asm, ".4s", ".4s",
6848 [(set (v4i32 V128:$Rd), (OpNode (v4f32 V128:$Rn), (i32 imm:$imm)))]> {
6849 bits<5> imm;
6850 let Inst{20-16} = imm;
6851 }
6852
6853 def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?},
6854 V128, V128, vecshiftR64,
6855 asm, ".2d", ".2d",
6856 [(set (v2i64 V128:$Rd), (OpNode (v2f64 V128:$Rn), (i32 imm:$imm)))]> {
6857 bits<6> imm;
6858 let Inst{21-16} = imm;
6859 }
6860}
6861
6862multiclass SIMDVectorRShiftSDToFP<bit U, bits<5> opc, string asm,
6863 Intrinsic OpNode> {
6864 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?},
6865 V64, V64, vecshiftR32,
6866 asm, ".2s", ".2s",
6867 [(set (v2f32 V64:$Rd), (OpNode (v2i32 V64:$Rn), (i32 imm:$imm)))]> {
6868 bits<5> imm;
6869 let Inst{20-16} = imm;
6870 }
6871
6872 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?},
6873 V128, V128, vecshiftR32,
6874 asm, ".4s", ".4s",
6875 [(set (v4f32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (i32 imm:$imm)))]> {
6876 bits<5> imm;
6877 let Inst{20-16} = imm;
6878 }
6879
6880 def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?},
6881 V128, V128, vecshiftR64,
6882 asm, ".2d", ".2d",
6883 [(set (v2f64 V128:$Rd), (OpNode (v2i64 V128:$Rn), (i32 imm:$imm)))]> {
6884 bits<6> imm;
6885 let Inst{21-16} = imm;
6886 }
6887}
6888
6889multiclass SIMDVectorRShiftNarrowBHS<bit U, bits<5> opc, string asm,
6890 SDPatternOperator OpNode> {
6891 def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?},
6892 V64, V128, vecshiftR16Narrow,
6893 asm, ".8b", ".8h",
6894 [(set (v8i8 V64:$Rd), (OpNode (v8i16 V128:$Rn), vecshiftR16Narrow:$imm))]> {
6895 bits<3> imm;
6896 let Inst{18-16} = imm;
6897 }
6898
6899 def v16i8_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,0,1,?,?,?},
6900 V128, V128, vecshiftR16Narrow,
6901 asm#"2", ".16b", ".8h", []> {
6902 bits<3> imm;
6903 let Inst{18-16} = imm;
6904 let hasSideEffects = 0;
6905 }
6906
6907 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?},
6908 V64, V128, vecshiftR32Narrow,
6909 asm, ".4h", ".4s",
6910 [(set (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn), vecshiftR32Narrow:$imm))]> {
6911 bits<4> imm;
6912 let Inst{19-16} = imm;
6913 }
6914
6915 def v8i16_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,1,?,?,?,?},
6916 V128, V128, vecshiftR32Narrow,
6917 asm#"2", ".8h", ".4s", []> {
6918 bits<4> imm;
6919 let Inst{19-16} = imm;
6920 let hasSideEffects = 0;
6921 }
6922
6923 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?},
6924 V64, V128, vecshiftR64Narrow,
6925 asm, ".2s", ".2d",
6926 [(set (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn), vecshiftR64Narrow:$imm))]> {
6927 bits<5> imm;
6928 let Inst{20-16} = imm;
6929 }
6930
6931 def v4i32_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,1,?,?,?,?,?},
6932 V128, V128, vecshiftR64Narrow,
6933 asm#"2", ".4s", ".2d", []> {
6934 bits<5> imm;
6935 let Inst{20-16} = imm;
6936 let hasSideEffects = 0;
6937 }
6938
6939 // TableGen doesn't like patters w/ INSERT_SUBREG on the instructions
6940 // themselves, so put them here instead.
6941
6942 // Patterns involving what's effectively an insert high and a normal
6943 // intrinsic, represented by CONCAT_VECTORS.
6944 def : Pat<(concat_vectors (v8i8 V64:$Rd),(OpNode (v8i16 V128:$Rn),
6945 vecshiftR16Narrow:$imm)),
6946 (!cast<Instruction>(NAME # "v16i8_shift")
6947 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub),
6948 V128:$Rn, vecshiftR16Narrow:$imm)>;
6949 def : Pat<(concat_vectors (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn),
6950 vecshiftR32Narrow:$imm)),
6951 (!cast<Instruction>(NAME # "v8i16_shift")
6952 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub),
6953 V128:$Rn, vecshiftR32Narrow:$imm)>;
6954 def : Pat<(concat_vectors (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn),
6955 vecshiftR64Narrow:$imm)),
6956 (!cast<Instruction>(NAME # "v4i32_shift")
6957 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub),
6958 V128:$Rn, vecshiftR64Narrow:$imm)>;
6959}
6960
6961multiclass SIMDVectorLShiftBHSD<bit U, bits<5> opc, string asm,
6962 SDPatternOperator OpNode> {
6963 def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?},
6964 V64, V64, vecshiftL8,
6965 asm, ".8b", ".8b",
6966 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn),
6967 (i32 vecshiftL8:$imm)))]> {
6968 bits<3> imm;
6969 let Inst{18-16} = imm;
6970 }
6971
6972 def v16i8_shift : BaseSIMDVectorShift<1, U, opc, {0,0,0,1,?,?,?},
6973 V128, V128, vecshiftL8,
6974 asm, ".16b", ".16b",
6975 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn),
6976 (i32 vecshiftL8:$imm)))]> {
6977 bits<3> imm;
6978 let Inst{18-16} = imm;
6979 }
6980
6981 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?},
6982 V64, V64, vecshiftL16,
6983 asm, ".4h", ".4h",
6984 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn),
6985 (i32 vecshiftL16:$imm)))]> {
6986 bits<4> imm;
6987 let Inst{19-16} = imm;
6988 }
6989
6990 def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?},
6991 V128, V128, vecshiftL16,
6992 asm, ".8h", ".8h",
6993 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn),
6994 (i32 vecshiftL16:$imm)))]> {
6995 bits<4> imm;
6996 let Inst{19-16} = imm;
6997 }
6998
6999 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?},
7000 V64, V64, vecshiftL32,
7001 asm, ".2s", ".2s",
7002 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn),
7003 (i32 vecshiftL32:$imm)))]> {
7004 bits<5> imm;
7005 let Inst{20-16} = imm;
7006 }
7007
7008 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?},
7009 V128, V128, vecshiftL32,
7010 asm, ".4s", ".4s",
7011 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn),
7012 (i32 vecshiftL32:$imm)))]> {
7013 bits<5> imm;
7014 let Inst{20-16} = imm;
7015 }
7016
7017 def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?},
7018 V128, V128, vecshiftL64,
7019 asm, ".2d", ".2d",
7020 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn),
7021 (i32 vecshiftL64:$imm)))]> {
7022 bits<6> imm;
7023 let Inst{21-16} = imm;
7024 }
7025}
7026
7027multiclass SIMDVectorRShiftBHSD<bit U, bits<5> opc, string asm,
7028 SDPatternOperator OpNode> {
7029 def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?},
7030 V64, V64, vecshiftR8,
7031 asm, ".8b", ".8b",
7032 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn),
7033 (i32 vecshiftR8:$imm)))]> {
7034 bits<3> imm;
7035 let Inst{18-16} = imm;
7036 }
7037
7038 def v16i8_shift : BaseSIMDVectorShift<1, U, opc, {0,0,0,1,?,?,?},
7039 V128, V128, vecshiftR8,
7040 asm, ".16b", ".16b",
7041 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn),
7042 (i32 vecshiftR8:$imm)))]> {
7043 bits<3> imm;
7044 let Inst{18-16} = imm;
7045 }
7046
7047 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?},
7048 V64, V64, vecshiftR16,
7049 asm, ".4h", ".4h",
7050 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn),
7051 (i32 vecshiftR16:$imm)))]> {
7052 bits<4> imm;
7053 let Inst{19-16} = imm;
7054 }
7055
7056 def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?},
7057 V128, V128, vecshiftR16,
7058 asm, ".8h", ".8h",
7059 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn),
7060 (i32 vecshiftR16:$imm)))]> {
7061 bits<4> imm;
7062 let Inst{19-16} = imm;
7063 }
7064
7065 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?},
7066 V64, V64, vecshiftR32,
7067 asm, ".2s", ".2s",
7068 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn),
7069 (i32 vecshiftR32:$imm)))]> {
7070 bits<5> imm;
7071 let Inst{20-16} = imm;
7072 }
7073
7074 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?},
7075 V128, V128, vecshiftR32,
7076 asm, ".4s", ".4s",
7077 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn),
7078 (i32 vecshiftR32:$imm)))]> {
7079 bits<5> imm;
7080 let Inst{20-16} = imm;
7081 }
7082
7083 def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?},
7084 V128, V128, vecshiftR64,
7085 asm, ".2d", ".2d",
7086 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn),
7087 (i32 vecshiftR64:$imm)))]> {
7088 bits<6> imm;
7089 let Inst{21-16} = imm;
7090 }
7091}
7092
7093let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
7094multiclass SIMDVectorRShiftBHSDTied<bit U, bits<5> opc, string asm,
7095 SDPatternOperator OpNode = null_frag> {
7096 def v8i8_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,0,1,?,?,?},
7097 V64, V64, vecshiftR8, asm, ".8b", ".8b",
7098 [(set (v8i8 V64:$dst),
7099 (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn),
7100 (i32 vecshiftR8:$imm)))]> {
7101 bits<3> imm;
7102 let Inst{18-16} = imm;
7103 }
7104
7105 def v16i8_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,0,1,?,?,?},
7106 V128, V128, vecshiftR8, asm, ".16b", ".16b",
7107 [(set (v16i8 V128:$dst),
7108 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn),
7109 (i32 vecshiftR8:$imm)))]> {
7110 bits<3> imm;
7111 let Inst{18-16} = imm;
7112 }
7113
7114 def v4i16_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,1,?,?,?,?},
7115 V64, V64, vecshiftR16, asm, ".4h", ".4h",
7116 [(set (v4i16 V64:$dst),
7117 (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn),
7118 (i32 vecshiftR16:$imm)))]> {
7119 bits<4> imm;
7120 let Inst{19-16} = imm;
7121 }
7122
7123 def v8i16_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,1,?,?,?,?},
7124 V128, V128, vecshiftR16, asm, ".8h", ".8h",
7125 [(set (v8i16 V128:$dst),
7126 (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn),
7127 (i32 vecshiftR16:$imm)))]> {
7128 bits<4> imm;
7129 let Inst{19-16} = imm;
7130 }
7131
7132 def v2i32_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,1,?,?,?,?,?},
7133 V64, V64, vecshiftR32, asm, ".2s", ".2s",
7134 [(set (v2i32 V64:$dst),
7135 (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn),
7136 (i32 vecshiftR32:$imm)))]> {
7137 bits<5> imm;
7138 let Inst{20-16} = imm;
7139 }
7140
7141 def v4i32_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,1,?,?,?,?,?},
7142 V128, V128, vecshiftR32, asm, ".4s", ".4s",
7143 [(set (v4i32 V128:$dst),
7144 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn),
7145 (i32 vecshiftR32:$imm)))]> {
7146 bits<5> imm;
7147 let Inst{20-16} = imm;
7148 }
7149
7150 def v2i64_shift : BaseSIMDVectorShiftTied<1, U, opc, {1,?,?,?,?,?,?},
7151 V128, V128, vecshiftR64,
7152 asm, ".2d", ".2d", [(set (v2i64 V128:$dst),
7153 (OpNode (v2i64 V128:$Rd), (v2i64 V128:$Rn),
7154 (i32 vecshiftR64:$imm)))]> {
7155 bits<6> imm;
7156 let Inst{21-16} = imm;
7157 }
7158}
7159
7160multiclass SIMDVectorLShiftBHSDTied<bit U, bits<5> opc, string asm,
7161 SDPatternOperator OpNode = null_frag> {
7162 def v8i8_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,0,1,?,?,?},
7163 V64, V64, vecshiftL8,
7164 asm, ".8b", ".8b",
7165 [(set (v8i8 V64:$dst),
7166 (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn),
7167 (i32 vecshiftL8:$imm)))]> {
7168 bits<3> imm;
7169 let Inst{18-16} = imm;
7170 }
7171
7172 def v16i8_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,0,1,?,?,?},
7173 V128, V128, vecshiftL8,
7174 asm, ".16b", ".16b",
7175 [(set (v16i8 V128:$dst),
7176 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn),
7177 (i32 vecshiftL8:$imm)))]> {
7178 bits<3> imm;
7179 let Inst{18-16} = imm;
7180 }
7181
7182 def v4i16_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,1,?,?,?,?},
7183 V64, V64, vecshiftL16,
7184 asm, ".4h", ".4h",
7185 [(set (v4i16 V64:$dst),
7186 (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn),
7187 (i32 vecshiftL16:$imm)))]> {
7188 bits<4> imm;
7189 let Inst{19-16} = imm;
7190 }
7191
7192 def v8i16_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,1,?,?,?,?},
7193 V128, V128, vecshiftL16,
7194 asm, ".8h", ".8h",
7195 [(set (v8i16 V128:$dst),
7196 (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn),
7197 (i32 vecshiftL16:$imm)))]> {
7198 bits<4> imm;
7199 let Inst{19-16} = imm;
7200 }
7201
7202 def v2i32_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,1,?,?,?,?,?},
7203 V64, V64, vecshiftL32,
7204 asm, ".2s", ".2s",
7205 [(set (v2i32 V64:$dst),
7206 (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn),
7207 (i32 vecshiftL32:$imm)))]> {
7208 bits<5> imm;
7209 let Inst{20-16} = imm;
7210 }
7211
7212 def v4i32_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,1,?,?,?,?,?},
7213 V128, V128, vecshiftL32,
7214 asm, ".4s", ".4s",
7215 [(set (v4i32 V128:$dst),
7216 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn),
7217 (i32 vecshiftL32:$imm)))]> {
7218 bits<5> imm;
7219 let Inst{20-16} = imm;
7220 }
7221
7222 def v2i64_shift : BaseSIMDVectorShiftTied<1, U, opc, {1,?,?,?,?,?,?},
7223 V128, V128, vecshiftL64,
7224 asm, ".2d", ".2d",
7225 [(set (v2i64 V128:$dst),
7226 (OpNode (v2i64 V128:$Rd), (v2i64 V128:$Rn),
7227 (i32 vecshiftL64:$imm)))]> {
7228 bits<6> imm;
7229 let Inst{21-16} = imm;
7230 }
7231}
7232
7233multiclass SIMDVectorLShiftLongBHSD<bit U, bits<5> opc, string asm,
7234 SDPatternOperator OpNode> {
7235 def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?},
7236 V128, V64, vecshiftL8, asm, ".8h", ".8b",
7237 [(set (v8i16 V128:$Rd), (OpNode (v8i8 V64:$Rn), vecshiftL8:$imm))]> {
7238 bits<3> imm;
7239 let Inst{18-16} = imm;
7240 }
7241
7242 def v16i8_shift : BaseSIMDVectorShift<1, U, opc, {0,0,0,1,?,?,?},
7243 V128, V128, vecshiftL8,
7244 asm#"2", ".8h", ".16b",
7245 [(set (v8i16 V128:$Rd),
7246 (OpNode (extract_high_v16i8 V128:$Rn), vecshiftL8:$imm))]> {
7247 bits<3> imm;
7248 let Inst{18-16} = imm;
7249 }
7250
7251 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?},
7252 V128, V64, vecshiftL16, asm, ".4s", ".4h",
7253 [(set (v4i32 V128:$Rd), (OpNode (v4i16 V64:$Rn), vecshiftL16:$imm))]> {
7254 bits<4> imm;
7255 let Inst{19-16} = imm;
7256 }
7257
7258 def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?},
7259 V128, V128, vecshiftL16,
7260 asm#"2", ".4s", ".8h",
7261 [(set (v4i32 V128:$Rd),
7262 (OpNode (extract_high_v8i16 V128:$Rn), vecshiftL16:$imm))]> {
7263
7264 bits<4> imm;
7265 let Inst{19-16} = imm;
7266 }
7267
7268 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?},
7269 V128, V64, vecshiftL32, asm, ".2d", ".2s",
7270 [(set (v2i64 V128:$Rd), (OpNode (v2i32 V64:$Rn), vecshiftL32:$imm))]> {
7271 bits<5> imm;
7272 let Inst{20-16} = imm;
7273 }
7274
7275 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?},
7276 V128, V128, vecshiftL32,
7277 asm#"2", ".2d", ".4s",
7278 [(set (v2i64 V128:$Rd),
7279 (OpNode (extract_high_v4i32 V128:$Rn), vecshiftL32:$imm))]> {
7280 bits<5> imm;
7281 let Inst{20-16} = imm;
7282 }
7283}
7284
7285
7286//---
7287// Vector load/store
7288//---
7289// SIMD ldX/stX no-index memory references don't allow the optional
7290// ", #0" constant and handle post-indexing explicitly, so we use
7291// a more specialized parse method for them. Otherwise, it's the same as
7292// the general am_noindex handling.
7293def MemorySIMDNoIndexOperand : AsmOperandClass {
7294 let Name = "MemorySIMDNoIndex";
7295 let ParserMethod = "tryParseNoIndexMemory";
7296}
7297def am_simdnoindex : Operand<i64>,
7298 ComplexPattern<i64, 1, "SelectAddrModeNoIndex", []> {
7299 let PrintMethod = "printAMNoIndex";
7300 let ParserMatchClass = MemorySIMDNoIndexOperand;
7301 let MIOperandInfo = (ops GPR64sp:$base);
7302 let DecoderMethod = "DecodeGPR64spRegisterClass";
7303}
7304
7305class BaseSIMDLdSt<bit Q, bit L, bits<4> opcode, bits<2> size,
7306 string asm, dag oops, dag iops, list<dag> pattern>
7307 : I<oops, iops, asm, "\t$Vt, $vaddr", "", pattern> {
7308 bits<5> Vt;
7309 bits<5> vaddr;
7310 let Inst{31} = 0;
7311 let Inst{30} = Q;
7312 let Inst{29-23} = 0b0011000;
7313 let Inst{22} = L;
7314 let Inst{21-16} = 0b000000;
7315 let Inst{15-12} = opcode;
7316 let Inst{11-10} = size;
7317 let Inst{9-5} = vaddr;
7318 let Inst{4-0} = Vt;
7319}
7320
7321class BaseSIMDLdStPost<bit Q, bit L, bits<4> opcode, bits<2> size,
7322 string asm, dag oops, dag iops>
7323 : I<oops, iops, asm, "\t$Vt, $vaddr, $Xm", "", []> {
7324 bits<5> Vt;
7325 bits<5> vaddr;
7326 bits<5> Xm;
7327 let Inst{31} = 0;
7328 let Inst{30} = Q;
7329 let Inst{29-23} = 0b0011001;
7330 let Inst{22} = L;
7331 let Inst{21} = 0;
7332 let Inst{20-16} = Xm;
7333 let Inst{15-12} = opcode;
7334 let Inst{11-10} = size;
7335 let Inst{9-5} = vaddr;
7336 let Inst{4-0} = Vt;
7337 let DecoderMethod = "DecodeSIMDLdStPost";
7338}
7339
7340// The immediate form of AdvSIMD post-indexed addressing is encoded with
7341// register post-index addressing from the zero register.
7342multiclass SIMDLdStAliases<string asm, string layout, string Count,
7343 int Offset, int Size> {
7344 // E.g. "ld1 { v0.8b, v1.8b }, [x1], #16"
7345 // "ld1\t$Vt, $vaddr, #16"
7346 // may get mapped to
7347 // (LD1Twov8b_POST VecListTwo8b:$Vt, am_simdnoindex:$vaddr, XZR)
7348 def : InstAlias<asm # "\t$Vt, $vaddr, #" # Offset,
7349 (!cast<Instruction>(NAME # Count # "v" # layout # "_POST")
7350 !cast<RegisterOperand>("VecList" # Count # layout):$Vt,
7351 am_simdnoindex:$vaddr, XZR), 1>;
7352
7353 // E.g. "ld1.8b { v0, v1 }, [x1], #16"
7354 // "ld1.8b\t$Vt, $vaddr, #16"
7355 // may get mapped to
7356 // (LD1Twov8b_POST VecListTwo64:$Vt, am_simdnoindex:$vaddr, XZR)
7357 def : InstAlias<asm # "." # layout # "\t$Vt, $vaddr, #" # Offset,
7358 (!cast<Instruction>(NAME # Count # "v" # layout # "_POST")
7359 !cast<RegisterOperand>("VecList" # Count # Size):$Vt,
7360 am_simdnoindex:$vaddr, XZR), 0>;
7361
7362 // E.g. "ld1.8b { v0, v1 }, [x1]"
7363 // "ld1\t$Vt, $vaddr"
7364 // may get mapped to
7365 // (LD1Twov8b VecListTwo64:$Vt, am_simdnoindex:$vaddr)
7366 def : InstAlias<asm # "." # layout # "\t$Vt, $vaddr",
7367 (!cast<Instruction>(NAME # Count # "v" # layout)
7368 !cast<RegisterOperand>("VecList" # Count # Size):$Vt,
7369 am_simdnoindex:$vaddr), 0>;
7370
7371 // E.g. "ld1.8b { v0, v1 }, [x1], x2"
7372 // "ld1\t$Vt, $vaddr, $Xm"
7373 // may get mapped to
7374 // (LD1Twov8b_POST VecListTwo64:$Vt, am_simdnoindex:$vaddr, GPR64pi8:$Xm)
7375 def : InstAlias<asm # "." # layout # "\t$Vt, $vaddr, $Xm",
7376 (!cast<Instruction>(NAME # Count # "v" # layout # "_POST")
7377 !cast<RegisterOperand>("VecList" # Count # Size):$Vt,
7378 am_simdnoindex:$vaddr,
7379 !cast<RegisterOperand>("GPR64pi" # Offset):$Xm), 0>;
7380}
7381
7382multiclass BaseSIMDLdN<string Count, string asm, string veclist, int Offset128,
7383 int Offset64, bits<4> opcode> {
7384 let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in {
7385 def v16b: BaseSIMDLdSt<1, 1, opcode, 0b00, asm,
7386 (outs !cast<RegisterOperand>(veclist # "16b"):$Vt),
7387 (ins am_simdnoindex:$vaddr), []>;
7388 def v8h : BaseSIMDLdSt<1, 1, opcode, 0b01, asm,
7389 (outs !cast<RegisterOperand>(veclist # "8h"):$Vt),
7390 (ins am_simdnoindex:$vaddr), []>;
7391 def v4s : BaseSIMDLdSt<1, 1, opcode, 0b10, asm,
7392 (outs !cast<RegisterOperand>(veclist # "4s"):$Vt),
7393 (ins am_simdnoindex:$vaddr), []>;
7394 def v2d : BaseSIMDLdSt<1, 1, opcode, 0b11, asm,
7395 (outs !cast<RegisterOperand>(veclist # "2d"):$Vt),
7396 (ins am_simdnoindex:$vaddr), []>;
7397 def v8b : BaseSIMDLdSt<0, 1, opcode, 0b00, asm,
7398 (outs !cast<RegisterOperand>(veclist # "8b"):$Vt),
7399 (ins am_simdnoindex:$vaddr), []>;
7400 def v4h : BaseSIMDLdSt<0, 1, opcode, 0b01, asm,
7401 (outs !cast<RegisterOperand>(veclist # "4h"):$Vt),
7402 (ins am_simdnoindex:$vaddr), []>;
7403 def v2s : BaseSIMDLdSt<0, 1, opcode, 0b10, asm,
7404 (outs !cast<RegisterOperand>(veclist # "2s"):$Vt),
7405 (ins am_simdnoindex:$vaddr), []>;
7406
7407
7408 def v16b_POST: BaseSIMDLdStPost<1, 1, opcode, 0b00, asm,
7409 (outs !cast<RegisterOperand>(veclist # "16b"):$Vt),
7410 (ins am_simdnoindex:$vaddr,
7411 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
7412 def v8h_POST : BaseSIMDLdStPost<1, 1, opcode, 0b01, asm,
7413 (outs !cast<RegisterOperand>(veclist # "8h"):$Vt),
7414 (ins am_simdnoindex:$vaddr,
7415 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
7416 def v4s_POST : BaseSIMDLdStPost<1, 1, opcode, 0b10, asm,
7417 (outs !cast<RegisterOperand>(veclist # "4s"):$Vt),
7418 (ins am_simdnoindex:$vaddr,
7419 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
7420 def v2d_POST : BaseSIMDLdStPost<1, 1, opcode, 0b11, asm,
7421 (outs !cast<RegisterOperand>(veclist # "2d"):$Vt),
7422 (ins am_simdnoindex:$vaddr,
7423 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
7424 def v8b_POST : BaseSIMDLdStPost<0, 1, opcode, 0b00, asm,
7425 (outs !cast<RegisterOperand>(veclist # "8b"):$Vt),
7426 (ins am_simdnoindex:$vaddr,
7427 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
7428 def v4h_POST : BaseSIMDLdStPost<0, 1, opcode, 0b01, asm,
7429 (outs !cast<RegisterOperand>(veclist # "4h"):$Vt),
7430 (ins am_simdnoindex:$vaddr,
7431 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
7432 def v2s_POST : BaseSIMDLdStPost<0, 1, opcode, 0b10, asm,
7433 (outs !cast<RegisterOperand>(veclist # "2s"):$Vt),
7434 (ins am_simdnoindex:$vaddr,
7435 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
7436 }
7437
7438 defm : SIMDLdStAliases<asm, "16b", Count, Offset128, 128>;
7439 defm : SIMDLdStAliases<asm, "8h", Count, Offset128, 128>;
7440 defm : SIMDLdStAliases<asm, "4s", Count, Offset128, 128>;
7441 defm : SIMDLdStAliases<asm, "2d", Count, Offset128, 128>;
7442 defm : SIMDLdStAliases<asm, "8b", Count, Offset64, 64>;
7443 defm : SIMDLdStAliases<asm, "4h", Count, Offset64, 64>;
7444 defm : SIMDLdStAliases<asm, "2s", Count, Offset64, 64>;
7445}
7446
7447// Only ld1/st1 has a v1d version.
7448multiclass BaseSIMDStN<string Count, string asm, string veclist, int Offset128,
7449 int Offset64, bits<4> opcode> {
7450 let hasSideEffects = 0, mayStore = 1, mayLoad = 0 in {
7451 def v16b : BaseSIMDLdSt<1, 0, opcode, 0b00, asm, (outs),
7452 (ins !cast<RegisterOperand>(veclist # "16b"):$Vt,
7453 am_simdnoindex:$vaddr), []>;
7454 def v8h : BaseSIMDLdSt<1, 0, opcode, 0b01, asm, (outs),
7455 (ins !cast<RegisterOperand>(veclist # "8h"):$Vt,
7456 am_simdnoindex:$vaddr), []>;
7457 def v4s : BaseSIMDLdSt<1, 0, opcode, 0b10, asm, (outs),
7458 (ins !cast<RegisterOperand>(veclist # "4s"):$Vt,
7459 am_simdnoindex:$vaddr), []>;
7460 def v2d : BaseSIMDLdSt<1, 0, opcode, 0b11, asm, (outs),
7461 (ins !cast<RegisterOperand>(veclist # "2d"):$Vt,
7462 am_simdnoindex:$vaddr), []>;
7463 def v8b : BaseSIMDLdSt<0, 0, opcode, 0b00, asm, (outs),
7464 (ins !cast<RegisterOperand>(veclist # "8b"):$Vt,
7465 am_simdnoindex:$vaddr), []>;
7466 def v4h : BaseSIMDLdSt<0, 0, opcode, 0b01, asm, (outs),
7467 (ins !cast<RegisterOperand>(veclist # "4h"):$Vt,
7468 am_simdnoindex:$vaddr), []>;
7469 def v2s : BaseSIMDLdSt<0, 0, opcode, 0b10, asm, (outs),
7470 (ins !cast<RegisterOperand>(veclist # "2s"):$Vt,
7471 am_simdnoindex:$vaddr), []>;
7472
7473 def v16b_POST : BaseSIMDLdStPost<1, 0, opcode, 0b00, asm, (outs),
7474 (ins !cast<RegisterOperand>(veclist # "16b"):$Vt,
7475 am_simdnoindex:$vaddr,
7476 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
7477 def v8h_POST : BaseSIMDLdStPost<1, 0, opcode, 0b01, asm, (outs),
7478 (ins !cast<RegisterOperand>(veclist # "8h"):$Vt,
7479 am_simdnoindex:$vaddr,
7480 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
7481 def v4s_POST : BaseSIMDLdStPost<1, 0, opcode, 0b10, asm, (outs),
7482 (ins !cast<RegisterOperand>(veclist # "4s"):$Vt,
7483 am_simdnoindex:$vaddr,
7484 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
7485 def v2d_POST : BaseSIMDLdStPost<1, 0, opcode, 0b11, asm, (outs),
7486 (ins !cast<RegisterOperand>(veclist # "2d"):$Vt,
7487 am_simdnoindex:$vaddr,
7488 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
7489 def v8b_POST : BaseSIMDLdStPost<0, 0, opcode, 0b00, asm, (outs),
7490 (ins !cast<RegisterOperand>(veclist # "8b"):$Vt,
7491 am_simdnoindex:$vaddr,
7492 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
7493 def v4h_POST : BaseSIMDLdStPost<0, 0, opcode, 0b01, asm, (outs),
7494 (ins !cast<RegisterOperand>(veclist # "4h"):$Vt,
7495 am_simdnoindex:$vaddr,
7496 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
7497 def v2s_POST : BaseSIMDLdStPost<0, 0, opcode, 0b10, asm, (outs),
7498 (ins !cast<RegisterOperand>(veclist # "2s"):$Vt,
7499 am_simdnoindex:$vaddr,
7500 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
7501 }
7502
7503 defm : SIMDLdStAliases<asm, "16b", Count, Offset128, 128>;
7504 defm : SIMDLdStAliases<asm, "8h", Count, Offset128, 128>;
7505 defm : SIMDLdStAliases<asm, "4s", Count, Offset128, 128>;
7506 defm : SIMDLdStAliases<asm, "2d", Count, Offset128, 128>;
7507 defm : SIMDLdStAliases<asm, "8b", Count, Offset64, 64>;
7508 defm : SIMDLdStAliases<asm, "4h", Count, Offset64, 64>;
7509 defm : SIMDLdStAliases<asm, "2s", Count, Offset64, 64>;
7510}
7511
7512multiclass BaseSIMDLd1<string Count, string asm, string veclist,
7513 int Offset128, int Offset64, bits<4> opcode>
7514 : BaseSIMDLdN<Count, asm, veclist, Offset128, Offset64, opcode> {
7515
7516 // LD1 instructions have extra "1d" variants.
7517 let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in {
7518 def v1d : BaseSIMDLdSt<0, 1, opcode, 0b11, asm,
7519 (outs !cast<RegisterOperand>(veclist # "1d"):$Vt),
7520 (ins am_simdnoindex:$vaddr), []>;
7521
7522 def v1d_POST : BaseSIMDLdStPost<0, 1, opcode, 0b11, asm,
7523 (outs !cast<RegisterOperand>(veclist # "1d"):$Vt),
7524 (ins am_simdnoindex:$vaddr,
7525 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
7526 }
7527
7528 defm : SIMDLdStAliases<asm, "1d", Count, Offset64, 64>;
7529}
7530
7531multiclass BaseSIMDSt1<string Count, string asm, string veclist,
7532 int Offset128, int Offset64, bits<4> opcode>
7533 : BaseSIMDStN<Count, asm, veclist, Offset128, Offset64, opcode> {
7534
7535 // ST1 instructions have extra "1d" variants.
7536 let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in {
7537 def v1d : BaseSIMDLdSt<0, 0, opcode, 0b11, asm, (outs),
7538 (ins !cast<RegisterOperand>(veclist # "1d"):$Vt,
7539 am_simdnoindex:$vaddr), []>;
7540
7541 def v1d_POST : BaseSIMDLdStPost<0, 0, opcode, 0b11, asm, (outs),
7542 (ins !cast<RegisterOperand>(veclist # "1d"):$Vt,
7543 am_simdnoindex:$vaddr,
7544 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
7545 }
7546
7547 defm : SIMDLdStAliases<asm, "1d", Count, Offset64, 64>;
7548}
7549
7550multiclass SIMDLd1Multiple<string asm> {
7551 defm One : BaseSIMDLd1<"One", asm, "VecListOne", 16, 8, 0b0111>;
7552 defm Two : BaseSIMDLd1<"Two", asm, "VecListTwo", 32, 16, 0b1010>;
7553 defm Three : BaseSIMDLd1<"Three", asm, "VecListThree", 48, 24, 0b0110>;
7554 defm Four : BaseSIMDLd1<"Four", asm, "VecListFour", 64, 32, 0b0010>;
7555}
7556
7557multiclass SIMDSt1Multiple<string asm> {
7558 defm One : BaseSIMDSt1<"One", asm, "VecListOne", 16, 8, 0b0111>;
7559 defm Two : BaseSIMDSt1<"Two", asm, "VecListTwo", 32, 16, 0b1010>;
7560 defm Three : BaseSIMDSt1<"Three", asm, "VecListThree", 48, 24, 0b0110>;
7561 defm Four : BaseSIMDSt1<"Four", asm, "VecListFour", 64, 32, 0b0010>;
7562}
7563
7564multiclass SIMDLd2Multiple<string asm> {
7565 defm Two : BaseSIMDLdN<"Two", asm, "VecListTwo", 32, 16, 0b1000>;
7566}
7567
7568multiclass SIMDSt2Multiple<string asm> {
7569 defm Two : BaseSIMDStN<"Two", asm, "VecListTwo", 32, 16, 0b1000>;
7570}
7571
7572multiclass SIMDLd3Multiple<string asm> {
7573 defm Three : BaseSIMDLdN<"Three", asm, "VecListThree", 48, 24, 0b0100>;
7574}
7575
7576multiclass SIMDSt3Multiple<string asm> {
7577 defm Three : BaseSIMDStN<"Three", asm, "VecListThree", 48, 24, 0b0100>;
7578}
7579
7580multiclass SIMDLd4Multiple<string asm> {
7581 defm Four : BaseSIMDLdN<"Four", asm, "VecListFour", 64, 32, 0b0000>;
7582}
7583
7584multiclass SIMDSt4Multiple<string asm> {
7585 defm Four : BaseSIMDStN<"Four", asm, "VecListFour", 64, 32, 0b0000>;
7586}
7587
7588//---
7589// AdvSIMD Load/store single-element
7590//---
7591
7592class BaseSIMDLdStSingle<bit L, bit R, bits<3> opcode,
7593 string asm, string operands, dag oops, dag iops,
7594 list<dag> pattern>
7595 : I<oops, iops, asm, operands, "", pattern> {
7596 bits<5> Vt;
7597 bits<5> vaddr;
7598 let Inst{31} = 0;
7599 let Inst{29-24} = 0b001101;
7600 let Inst{22} = L;
7601 let Inst{21} = R;
7602 let Inst{15-13} = opcode;
7603 let Inst{9-5} = vaddr;
7604 let Inst{4-0} = Vt;
7605 let DecoderMethod = "DecodeSIMDLdStSingle";
7606}
7607
7608class BaseSIMDLdStSingleTied<bit L, bit R, bits<3> opcode,
7609 string asm, string operands, dag oops, dag iops,
7610 list<dag> pattern>
7611 : I<oops, iops, asm, operands, "$Vt = $dst", pattern> {
7612 bits<5> Vt;
7613 bits<5> vaddr;
7614 let Inst{31} = 0;
7615 let Inst{29-24} = 0b001101;
7616 let Inst{22} = L;
7617 let Inst{21} = R;
7618 let Inst{15-13} = opcode;
7619 let Inst{9-5} = vaddr;
7620 let Inst{4-0} = Vt;
7621 let DecoderMethod = "DecodeSIMDLdStSingleTied";
7622}
7623
7624
7625let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
7626class BaseSIMDLdR<bit Q, bit R, bits<3> opcode, bit S, bits<2> size, string asm,
7627 Operand listtype>
7628 : BaseSIMDLdStSingle<1, R, opcode, asm, "\t$Vt, $vaddr",
7629 (outs listtype:$Vt), (ins am_simdnoindex:$vaddr), []> {
7630 let Inst{30} = Q;
7631 let Inst{23} = 0;
7632 let Inst{20-16} = 0b00000;
7633 let Inst{12} = S;
7634 let Inst{11-10} = size;
7635}
7636let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
7637class BaseSIMDLdRPost<bit Q, bit R, bits<3> opcode, bit S, bits<2> size,
7638 string asm, Operand listtype, Operand GPR64pi>
7639 : BaseSIMDLdStSingle<1, R, opcode, asm, "\t$Vt, $vaddr, $Xm",
7640 (outs listtype:$Vt),
7641 (ins am_simdnoindex:$vaddr, GPR64pi:$Xm), []> {
7642 bits<5> Xm;
7643 let Inst{30} = Q;
7644 let Inst{23} = 1;
7645 let Inst{20-16} = Xm;
7646 let Inst{12} = S;
7647 let Inst{11-10} = size;
7648}
7649
7650multiclass SIMDLdrAliases<string asm, string layout, string Count,
7651 int Offset, int Size> {
7652 // E.g. "ld1r { v0.8b }, [x1], #1"
7653 // "ld1r.8b\t$Vt, $vaddr, #1"
7654 // may get mapped to
7655 // (LD1Rv8b_POST VecListOne8b:$Vt, am_simdnoindex:$vaddr, XZR)
7656 def : InstAlias<asm # "\t$Vt, $vaddr, #" # Offset,
7657 (!cast<Instruction>(NAME # "v" # layout # "_POST")
7658 !cast<RegisterOperand>("VecList" # Count # layout):$Vt,
7659 am_simdnoindex:$vaddr, XZR), 1>;
7660
7661 // E.g. "ld1r.8b { v0 }, [x1], #1"
7662 // "ld1r.8b\t$Vt, $vaddr, #1"
7663 // may get mapped to
7664 // (LD1Rv8b_POST VecListOne64:$Vt, am_simdnoindex:$vaddr, XZR)
7665 def : InstAlias<asm # "." # layout # "\t$Vt, $vaddr, #" # Offset,
7666 (!cast<Instruction>(NAME # "v" # layout # "_POST")
7667 !cast<RegisterOperand>("VecList" # Count # Size):$Vt,
7668 am_simdnoindex:$vaddr, XZR), 0>;
7669
7670 // E.g. "ld1r.8b { v0 }, [x1]"
7671 // "ld1r.8b\t$Vt, $vaddr"
7672 // may get mapped to
7673 // (LD1Rv8b VecListOne64:$Vt, am_simdnoindex:$vaddr)
7674 def : InstAlias<asm # "." # layout # "\t$Vt, $vaddr",
7675 (!cast<Instruction>(NAME # "v" # layout)
7676 !cast<RegisterOperand>("VecList" # Count # Size):$Vt,
7677 am_simdnoindex:$vaddr), 0>;
7678
7679 // E.g. "ld1r.8b { v0 }, [x1], x2"
7680 // "ld1r.8b\t$Vt, $vaddr, $Xm"
7681 // may get mapped to
7682 // (LD1Rv8b_POST VecListOne64:$Vt, am_simdnoindex:$vaddr, GPR64pi1:$Xm)
7683 def : InstAlias<asm # "." # layout # "\t$Vt, $vaddr, $Xm",
7684 (!cast<Instruction>(NAME # "v" # layout # "_POST")
7685 !cast<RegisterOperand>("VecList" # Count # Size):$Vt,
7686 am_simdnoindex:$vaddr,
7687 !cast<RegisterOperand>("GPR64pi" # Offset):$Xm), 0>;
7688}
7689
7690multiclass SIMDLdR<bit R, bits<3> opcode, bit S, string asm, string Count,
7691 int Offset1, int Offset2, int Offset4, int Offset8> {
7692 def v8b : BaseSIMDLdR<0, R, opcode, S, 0b00, asm,
7693 !cast<Operand>("VecList" # Count # "8b")>;
7694 def v16b: BaseSIMDLdR<1, R, opcode, S, 0b00, asm,
7695 !cast<Operand>("VecList" # Count #"16b")>;
7696 def v4h : BaseSIMDLdR<0, R, opcode, S, 0b01, asm,
7697 !cast<Operand>("VecList" # Count #"4h")>;
7698 def v8h : BaseSIMDLdR<1, R, opcode, S, 0b01, asm,
7699 !cast<Operand>("VecList" # Count #"8h")>;
7700 def v2s : BaseSIMDLdR<0, R, opcode, S, 0b10, asm,
7701 !cast<Operand>("VecList" # Count #"2s")>;
7702 def v4s : BaseSIMDLdR<1, R, opcode, S, 0b10, asm,
7703 !cast<Operand>("VecList" # Count #"4s")>;
7704 def v1d : BaseSIMDLdR<0, R, opcode, S, 0b11, asm,
7705 !cast<Operand>("VecList" # Count #"1d")>;
7706 def v2d : BaseSIMDLdR<1, R, opcode, S, 0b11, asm,
7707 !cast<Operand>("VecList" # Count #"2d")>;
7708
7709 def v8b_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b00, asm,
7710 !cast<Operand>("VecList" # Count # "8b"),
7711 !cast<Operand>("GPR64pi" # Offset1)>;
7712 def v16b_POST: BaseSIMDLdRPost<1, R, opcode, S, 0b00, asm,
7713 !cast<Operand>("VecList" # Count # "16b"),
7714 !cast<Operand>("GPR64pi" # Offset1)>;
7715 def v4h_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b01, asm,
7716 !cast<Operand>("VecList" # Count # "4h"),
7717 !cast<Operand>("GPR64pi" # Offset2)>;
7718 def v8h_POST : BaseSIMDLdRPost<1, R, opcode, S, 0b01, asm,
7719 !cast<Operand>("VecList" # Count # "8h"),
7720 !cast<Operand>("GPR64pi" # Offset2)>;
7721 def v2s_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b10, asm,
7722 !cast<Operand>("VecList" # Count # "2s"),
7723 !cast<Operand>("GPR64pi" # Offset4)>;
7724 def v4s_POST : BaseSIMDLdRPost<1, R, opcode, S, 0b10, asm,
7725 !cast<Operand>("VecList" # Count # "4s"),
7726 !cast<Operand>("GPR64pi" # Offset4)>;
7727 def v1d_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b11, asm,
7728 !cast<Operand>("VecList" # Count # "1d"),
7729 !cast<Operand>("GPR64pi" # Offset8)>;
7730 def v2d_POST : BaseSIMDLdRPost<1, R, opcode, S, 0b11, asm,
7731 !cast<Operand>("VecList" # Count # "2d"),
7732 !cast<Operand>("GPR64pi" # Offset8)>;
7733
7734 defm : SIMDLdrAliases<asm, "8b", Count, Offset1, 64>;
7735 defm : SIMDLdrAliases<asm, "16b", Count, Offset1, 128>;
7736 defm : SIMDLdrAliases<asm, "4h", Count, Offset2, 64>;
7737 defm : SIMDLdrAliases<asm, "8h", Count, Offset2, 128>;
7738 defm : SIMDLdrAliases<asm, "2s", Count, Offset4, 64>;
7739 defm : SIMDLdrAliases<asm, "4s", Count, Offset4, 128>;
7740 defm : SIMDLdrAliases<asm, "1d", Count, Offset8, 64>;
7741 defm : SIMDLdrAliases<asm, "2d", Count, Offset8, 128>;
7742}
7743
7744class SIMDLdStSingleB<bit L, bit R, bits<3> opcode, string asm,
7745 dag oops, dag iops, list<dag> pattern>
7746 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, $vaddr", oops, iops,
7747 pattern> {
7748 // idx encoded in Q:S:size fields.
7749 bits<4> idx;
7750 let Inst{30} = idx{3};
7751 let Inst{23} = 0;
7752 let Inst{20-16} = 0b00000;
7753 let Inst{12} = idx{2};
7754 let Inst{11-10} = idx{1-0};
7755}
7756class SIMDLdStSingleBTied<bit L, bit R, bits<3> opcode, string asm,
7757 dag oops, dag iops, list<dag> pattern>
7758 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, $vaddr", oops, iops,
7759 pattern> {
7760 // idx encoded in Q:S:size fields.
7761 bits<4> idx;
7762 let Inst{30} = idx{3};
7763 let Inst{23} = 0;
7764 let Inst{20-16} = 0b00000;
7765 let Inst{12} = idx{2};
7766 let Inst{11-10} = idx{1-0};
7767}
7768class SIMDLdStSingleBPost<bit L, bit R, bits<3> opcode, string asm,
7769 dag oops, dag iops>
7770 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, $vaddr, $Xm",
7771 oops, iops, []> {
7772 // idx encoded in Q:S:size fields.
7773 bits<4> idx;
7774 bits<5> Xm;
7775 let Inst{30} = idx{3};
7776 let Inst{23} = 1;
7777 let Inst{20-16} = Xm;
7778 let Inst{12} = idx{2};
7779 let Inst{11-10} = idx{1-0};
7780}
7781class SIMDLdStSingleBTiedPost<bit L, bit R, bits<3> opcode, string asm,
7782 dag oops, dag iops>
7783 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, $vaddr, $Xm",
7784 oops, iops, []> {
7785 // idx encoded in Q:S:size fields.
7786 bits<4> idx;
7787 bits<5> Xm;
7788 let Inst{30} = idx{3};
7789 let Inst{23} = 1;
7790 let Inst{20-16} = Xm;
7791 let Inst{12} = idx{2};
7792 let Inst{11-10} = idx{1-0};
7793}
7794
7795class SIMDLdStSingleH<bit L, bit R, bits<3> opcode, bit size, string asm,
7796 dag oops, dag iops, list<dag> pattern>
7797 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, $vaddr", oops, iops,
7798 pattern> {
7799 // idx encoded in Q:S:size<1> fields.
7800 bits<3> idx;
7801 let Inst{30} = idx{2};
7802 let Inst{23} = 0;
7803 let Inst{20-16} = 0b00000;
7804 let Inst{12} = idx{1};
7805 let Inst{11} = idx{0};
7806 let Inst{10} = size;
7807}
7808class SIMDLdStSingleHTied<bit L, bit R, bits<3> opcode, bit size, string asm,
7809 dag oops, dag iops, list<dag> pattern>
7810 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, $vaddr", oops, iops,
7811 pattern> {
7812 // idx encoded in Q:S:size<1> fields.
7813 bits<3> idx;
7814 let Inst{30} = idx{2};
7815 let Inst{23} = 0;
7816 let Inst{20-16} = 0b00000;
7817 let Inst{12} = idx{1};
7818 let Inst{11} = idx{0};
7819 let Inst{10} = size;
7820}
7821
7822class SIMDLdStSingleHPost<bit L, bit R, bits<3> opcode, bit size, string asm,
7823 dag oops, dag iops>
7824 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, $vaddr, $Xm",
7825 oops, iops, []> {
7826 // idx encoded in Q:S:size<1> fields.
7827 bits<3> idx;
7828 bits<5> Xm;
7829 let Inst{30} = idx{2};
7830 let Inst{23} = 1;
7831 let Inst{20-16} = Xm;
7832 let Inst{12} = idx{1};
7833 let Inst{11} = idx{0};
7834 let Inst{10} = size;
7835}
7836class SIMDLdStSingleHTiedPost<bit L, bit R, bits<3> opcode, bit size, string asm,
7837 dag oops, dag iops>
7838 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, $vaddr, $Xm",
7839 oops, iops, []> {
7840 // idx encoded in Q:S:size<1> fields.
7841 bits<3> idx;
7842 bits<5> Xm;
7843 let Inst{30} = idx{2};
7844 let Inst{23} = 1;
7845 let Inst{20-16} = Xm;
7846 let Inst{12} = idx{1};
7847 let Inst{11} = idx{0};
7848 let Inst{10} = size;
7849}
7850class SIMDLdStSingleS<bit L, bit R, bits<3> opcode, bits<2> size, string asm,
7851 dag oops, dag iops, list<dag> pattern>
7852 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, $vaddr", oops, iops,
7853 pattern> {
7854 // idx encoded in Q:S fields.
7855 bits<2> idx;
7856 let Inst{30} = idx{1};
7857 let Inst{23} = 0;
7858 let Inst{20-16} = 0b00000;
7859 let Inst{12} = idx{0};
7860 let Inst{11-10} = size;
7861}
7862class SIMDLdStSingleSTied<bit L, bit R, bits<3> opcode, bits<2> size, string asm,
7863 dag oops, dag iops, list<dag> pattern>
7864 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, $vaddr", oops, iops,
7865 pattern> {
7866 // idx encoded in Q:S fields.
7867 bits<2> idx;
7868 let Inst{30} = idx{1};
7869 let Inst{23} = 0;
7870 let Inst{20-16} = 0b00000;
7871 let Inst{12} = idx{0};
7872 let Inst{11-10} = size;
7873}
7874class SIMDLdStSingleSPost<bit L, bit R, bits<3> opcode, bits<2> size,
7875 string asm, dag oops, dag iops>
7876 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, $vaddr, $Xm",
7877 oops, iops, []> {
7878 // idx encoded in Q:S fields.
7879 bits<2> idx;
7880 bits<5> Xm;
7881 let Inst{30} = idx{1};
7882 let Inst{23} = 1;
7883 let Inst{20-16} = Xm;
7884 let Inst{12} = idx{0};
7885 let Inst{11-10} = size;
7886}
7887class SIMDLdStSingleSTiedPost<bit L, bit R, bits<3> opcode, bits<2> size,
7888 string asm, dag oops, dag iops>
7889 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, $vaddr, $Xm",
7890 oops, iops, []> {
7891 // idx encoded in Q:S fields.
7892 bits<2> idx;
7893 bits<5> Xm;
7894 let Inst{30} = idx{1};
7895 let Inst{23} = 1;
7896 let Inst{20-16} = Xm;
7897 let Inst{12} = idx{0};
7898 let Inst{11-10} = size;
7899}
7900class SIMDLdStSingleD<bit L, bit R, bits<3> opcode, bits<2> size, string asm,
7901 dag oops, dag iops, list<dag> pattern>
7902 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, $vaddr", oops, iops,
7903 pattern> {
7904 // idx encoded in Q field.
7905 bits<1> idx;
7906 let Inst{30} = idx;
7907 let Inst{23} = 0;
7908 let Inst{20-16} = 0b00000;
7909 let Inst{12} = 0;
7910 let Inst{11-10} = size;
7911}
7912class SIMDLdStSingleDTied<bit L, bit R, bits<3> opcode, bits<2> size, string asm,
7913 dag oops, dag iops, list<dag> pattern>
7914 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, $vaddr", oops, iops,
7915 pattern> {
7916 // idx encoded in Q field.
7917 bits<1> idx;
7918 let Inst{30} = idx;
7919 let Inst{23} = 0;
7920 let Inst{20-16} = 0b00000;
7921 let Inst{12} = 0;
7922 let Inst{11-10} = size;
7923}
7924class SIMDLdStSingleDPost<bit L, bit R, bits<3> opcode, bits<2> size,
7925 string asm, dag oops, dag iops>
7926 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, $vaddr, $Xm",
7927 oops, iops, []> {
7928 // idx encoded in Q field.
7929 bits<1> idx;
7930 bits<5> Xm;
7931 let Inst{30} = idx;
7932 let Inst{23} = 1;
7933 let Inst{20-16} = Xm;
7934 let Inst{12} = 0;
7935 let Inst{11-10} = size;
7936}
7937class SIMDLdStSingleDTiedPost<bit L, bit R, bits<3> opcode, bits<2> size,
7938 string asm, dag oops, dag iops>
7939 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, $vaddr, $Xm",
7940 oops, iops, []> {
7941 // idx encoded in Q field.
7942 bits<1> idx;
7943 bits<5> Xm;
7944 let Inst{30} = idx;
7945 let Inst{23} = 1;
7946 let Inst{20-16} = Xm;
7947 let Inst{12} = 0;
7948 let Inst{11-10} = size;
7949}
7950
7951let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
7952multiclass SIMDLdSingleBTied<bit R, bits<3> opcode, string asm,
7953 RegisterOperand listtype,
7954 RegisterOperand GPR64pi> {
7955 def i8 : SIMDLdStSingleBTied<1, R, opcode, asm,
7956 (outs listtype:$dst),
7957 (ins listtype:$Vt, VectorIndexB:$idx,
7958 am_simdnoindex:$vaddr), []>;
7959
7960 def i8_POST : SIMDLdStSingleBTiedPost<1, R, opcode, asm,
7961 (outs listtype:$dst),
7962 (ins listtype:$Vt, VectorIndexB:$idx,
7963 am_simdnoindex:$vaddr, GPR64pi:$Xm)>;
7964}
7965let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
7966multiclass SIMDLdSingleHTied<bit R, bits<3> opcode, bit size, string asm,
7967 RegisterOperand listtype,
7968 RegisterOperand GPR64pi> {
7969 def i16 : SIMDLdStSingleHTied<1, R, opcode, size, asm,
7970 (outs listtype:$dst),
7971 (ins listtype:$Vt, VectorIndexH:$idx,
7972 am_simdnoindex:$vaddr), []>;
7973
7974 def i16_POST : SIMDLdStSingleHTiedPost<1, R, opcode, size, asm,
7975 (outs listtype:$dst),
7976 (ins listtype:$Vt, VectorIndexH:$idx,
7977 am_simdnoindex:$vaddr, GPR64pi:$Xm)>;
7978}
7979let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
7980multiclass SIMDLdSingleSTied<bit R, bits<3> opcode, bits<2> size,string asm,
7981 RegisterOperand listtype,
7982 RegisterOperand GPR64pi> {
7983 def i32 : SIMDLdStSingleSTied<1, R, opcode, size, asm,
7984 (outs listtype:$dst),
7985 (ins listtype:$Vt, VectorIndexS:$idx,
7986 am_simdnoindex:$vaddr), []>;
7987
7988 def i32_POST : SIMDLdStSingleSTiedPost<1, R, opcode, size, asm,
7989 (outs listtype:$dst),
7990 (ins listtype:$Vt, VectorIndexS:$idx,
7991 am_simdnoindex:$vaddr, GPR64pi:$Xm)>;
7992}
7993let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
7994multiclass SIMDLdSingleDTied<bit R, bits<3> opcode, bits<2> size, string asm,
Tim Northoverff179ba2014-04-01 10:37:09 +00007995 RegisterOperand listtype, RegisterOperand GPR64pi> {
Tim Northover00ed9962014-03-29 10:18:08 +00007996 def i64 : SIMDLdStSingleDTied<1, R, opcode, size, asm,
7997 (outs listtype:$dst),
7998 (ins listtype:$Vt, VectorIndexD:$idx,
7999 am_simdnoindex:$vaddr), []>;
8000
8001 def i64_POST : SIMDLdStSingleDTiedPost<1, R, opcode, size, asm,
8002 (outs listtype:$dst),
8003 (ins listtype:$Vt, VectorIndexD:$idx,
8004 am_simdnoindex:$vaddr, GPR64pi:$Xm)>;
8005}
8006let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
8007multiclass SIMDStSingleB<bit R, bits<3> opcode, string asm,
Tim Northoverff179ba2014-04-01 10:37:09 +00008008 RegisterOperand listtype, RegisterOperand GPR64pi> {
Tim Northover00ed9962014-03-29 10:18:08 +00008009 def i8 : SIMDLdStSingleB<0, R, opcode, asm,
8010 (outs), (ins listtype:$Vt, VectorIndexB:$idx,
Tim Northoverff179ba2014-04-01 10:37:09 +00008011 am_simdnoindex:$vaddr), []>;
Tim Northover00ed9962014-03-29 10:18:08 +00008012
8013 def i8_POST : SIMDLdStSingleBPost<0, R, opcode, asm,
8014 (outs), (ins listtype:$Vt, VectorIndexB:$idx,
8015 am_simdnoindex:$vaddr, GPR64pi:$Xm)>;
8016}
8017let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
8018multiclass SIMDStSingleH<bit R, bits<3> opcode, bit size, string asm,
Tim Northoverff179ba2014-04-01 10:37:09 +00008019 RegisterOperand listtype, RegisterOperand GPR64pi> {
Tim Northover00ed9962014-03-29 10:18:08 +00008020 def i16 : SIMDLdStSingleH<0, R, opcode, size, asm,
8021 (outs), (ins listtype:$Vt, VectorIndexH:$idx,
Tim Northoverff179ba2014-04-01 10:37:09 +00008022 am_simdnoindex:$vaddr), []>;
Tim Northover00ed9962014-03-29 10:18:08 +00008023
8024 def i16_POST : SIMDLdStSingleHPost<0, R, opcode, size, asm,
8025 (outs), (ins listtype:$Vt, VectorIndexH:$idx,
8026 am_simdnoindex:$vaddr, GPR64pi:$Xm)>;
8027}
8028let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
8029multiclass SIMDStSingleS<bit R, bits<3> opcode, bits<2> size,string asm,
Tim Northoverff179ba2014-04-01 10:37:09 +00008030 RegisterOperand listtype, RegisterOperand GPR64pi> {
Tim Northover00ed9962014-03-29 10:18:08 +00008031 def i32 : SIMDLdStSingleS<0, R, opcode, size, asm,
8032 (outs), (ins listtype:$Vt, VectorIndexS:$idx,
Tim Northoverff179ba2014-04-01 10:37:09 +00008033 am_simdnoindex:$vaddr), []>;
Tim Northover00ed9962014-03-29 10:18:08 +00008034
8035 def i32_POST : SIMDLdStSingleSPost<0, R, opcode, size, asm,
8036 (outs), (ins listtype:$Vt, VectorIndexS:$idx,
8037 am_simdnoindex:$vaddr, GPR64pi:$Xm)>;
8038}
8039let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
8040multiclass SIMDStSingleD<bit R, bits<3> opcode, bits<2> size, string asm,
Tim Northoverff179ba2014-04-01 10:37:09 +00008041 RegisterOperand listtype, RegisterOperand GPR64pi> {
Tim Northover00ed9962014-03-29 10:18:08 +00008042 def i64 : SIMDLdStSingleD<0, R, opcode, size, asm,
8043 (outs), (ins listtype:$Vt, VectorIndexD:$idx,
Tim Northoverff179ba2014-04-01 10:37:09 +00008044 am_simdnoindex:$vaddr), []>;
Tim Northover00ed9962014-03-29 10:18:08 +00008045
8046 def i64_POST : SIMDLdStSingleDPost<0, R, opcode, size, asm,
8047 (outs), (ins listtype:$Vt, VectorIndexD:$idx,
8048 am_simdnoindex:$vaddr, GPR64pi:$Xm)>;
8049}
8050
8051multiclass SIMDLdStSingleAliases<string asm, string layout, string Type,
8052 string Count, int Offset, Operand idxtype> {
8053 // E.g. "ld1 { v0.8b }[0], [x1], #1"
8054 // "ld1\t$Vt, $vaddr, #1"
8055 // may get mapped to
8056 // (LD1Rv8b_POST VecListOne8b:$Vt, am_simdnoindex:$vaddr, XZR)
8057 def : InstAlias<asm # "\t$Vt$idx, $vaddr, #" # Offset,
8058 (!cast<Instruction>(NAME # Type # "_POST")
8059 !cast<RegisterOperand>("VecList" # Count # layout):$Vt,
8060 idxtype:$idx, am_simdnoindex:$vaddr, XZR), 1>;
8061
8062 // E.g. "ld1.8b { v0 }[0], [x1], #1"
8063 // "ld1.8b\t$Vt, $vaddr, #1"
8064 // may get mapped to
8065 // (LD1Rv8b_POST VecListOne64:$Vt, am_simdnoindex:$vaddr, XZR)
8066 def : InstAlias<asm # "." # layout # "\t$Vt$idx, $vaddr, #" # Offset,
8067 (!cast<Instruction>(NAME # Type # "_POST")
8068 !cast<RegisterOperand>("VecList" # Count # "128"):$Vt,
8069 idxtype:$idx, am_simdnoindex:$vaddr, XZR), 0>;
8070
8071 // E.g. "ld1.8b { v0 }[0], [x1]"
8072 // "ld1.8b\t$Vt, $vaddr"
8073 // may get mapped to
8074 // (LD1Rv8b VecListOne64:$Vt, am_simdnoindex:$vaddr)
8075 def : InstAlias<asm # "." # layout # "\t$Vt$idx, $vaddr",
8076 (!cast<Instruction>(NAME # Type)
8077 !cast<RegisterOperand>("VecList" # Count # "128"):$Vt,
8078 idxtype:$idx, am_simdnoindex:$vaddr), 0>;
8079
8080 // E.g. "ld1.8b { v0 }[0], [x1], x2"
8081 // "ld1.8b\t$Vt, $vaddr, $Xm"
8082 // may get mapped to
8083 // (LD1Rv8b_POST VecListOne64:$Vt, am_simdnoindex:$vaddr, GPR64pi1:$Xm)
8084 def : InstAlias<asm # "." # layout # "\t$Vt$idx, $vaddr, $Xm",
8085 (!cast<Instruction>(NAME # Type # "_POST")
8086 !cast<RegisterOperand>("VecList" # Count # "128"):$Vt,
8087 idxtype:$idx, am_simdnoindex:$vaddr,
8088 !cast<RegisterOperand>("GPR64pi" # Offset):$Xm), 0>;
8089}
8090
8091multiclass SIMDLdSt1SingleAliases<string asm> {
8092 defm : SIMDLdStSingleAliases<asm, "b", "i8", "One", 1, VectorIndexB>;
8093 defm : SIMDLdStSingleAliases<asm, "h", "i16", "One", 2, VectorIndexH>;
8094 defm : SIMDLdStSingleAliases<asm, "s", "i32", "One", 4, VectorIndexS>;
8095 defm : SIMDLdStSingleAliases<asm, "d", "i64", "One", 8, VectorIndexD>;
8096}
8097
8098multiclass SIMDLdSt2SingleAliases<string asm> {
8099 defm : SIMDLdStSingleAliases<asm, "b", "i8", "Two", 2, VectorIndexB>;
8100 defm : SIMDLdStSingleAliases<asm, "h", "i16", "Two", 4, VectorIndexH>;
8101 defm : SIMDLdStSingleAliases<asm, "s", "i32", "Two", 8, VectorIndexS>;
8102 defm : SIMDLdStSingleAliases<asm, "d", "i64", "Two", 16, VectorIndexD>;
8103}
8104
8105multiclass SIMDLdSt3SingleAliases<string asm> {
8106 defm : SIMDLdStSingleAliases<asm, "b", "i8", "Three", 3, VectorIndexB>;
8107 defm : SIMDLdStSingleAliases<asm, "h", "i16", "Three", 6, VectorIndexH>;
8108 defm : SIMDLdStSingleAliases<asm, "s", "i32", "Three", 12, VectorIndexS>;
8109 defm : SIMDLdStSingleAliases<asm, "d", "i64", "Three", 24, VectorIndexD>;
8110}
8111
8112multiclass SIMDLdSt4SingleAliases<string asm> {
8113 defm : SIMDLdStSingleAliases<asm, "b", "i8", "Four", 4, VectorIndexB>;
8114 defm : SIMDLdStSingleAliases<asm, "h", "i16", "Four", 8, VectorIndexH>;
8115 defm : SIMDLdStSingleAliases<asm, "s", "i32", "Four", 16, VectorIndexS>;
8116 defm : SIMDLdStSingleAliases<asm, "d", "i64", "Four", 32, VectorIndexD>;
8117}
8118
8119//----------------------------------------------------------------------------
8120// Crypto extensions
8121//----------------------------------------------------------------------------
8122
8123let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
8124class AESBase<bits<4> opc, string asm, dag outs, dag ins, string cstr,
8125 list<dag> pat>
8126 : I<outs, ins, asm, "{\t$Rd.16b, $Rn.16b|.16b\t$Rd, $Rn}", cstr, pat>,
8127 Sched<[WriteV]>{
8128 bits<5> Rd;
8129 bits<5> Rn;
8130 let Inst{31-16} = 0b0100111000101000;
8131 let Inst{15-12} = opc;
8132 let Inst{11-10} = 0b10;
8133 let Inst{9-5} = Rn;
8134 let Inst{4-0} = Rd;
8135}
8136
8137class AESInst<bits<4> opc, string asm, Intrinsic OpNode>
8138 : AESBase<opc, asm, (outs V128:$Rd), (ins V128:$Rn), "",
8139 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>;
8140
8141class AESTiedInst<bits<4> opc, string asm, Intrinsic OpNode>
8142 : AESBase<opc, asm, (outs V128:$dst), (ins V128:$Rd, V128:$Rn),
8143 "$Rd = $dst",
8144 [(set (v16i8 V128:$dst),
8145 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn)))]>;
8146
8147let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
8148class SHA3OpTiedInst<bits<3> opc, string asm, string dst_lhs_kind,
8149 dag oops, dag iops, list<dag> pat>
8150 : I<oops, iops, asm,
8151 "{\t$Rd" # dst_lhs_kind # ", $Rn" # dst_lhs_kind # ", $Rm.4s" #
8152 "|.4s\t$Rd, $Rn, $Rm}", "$Rd = $dst", pat>,
8153 Sched<[WriteV]>{
8154 bits<5> Rd;
8155 bits<5> Rn;
8156 bits<5> Rm;
8157 let Inst{31-21} = 0b01011110000;
8158 let Inst{20-16} = Rm;
8159 let Inst{15} = 0;
8160 let Inst{14-12} = opc;
8161 let Inst{11-10} = 0b00;
8162 let Inst{9-5} = Rn;
8163 let Inst{4-0} = Rd;
8164}
8165
8166class SHATiedInstQSV<bits<3> opc, string asm, Intrinsic OpNode>
8167 : SHA3OpTiedInst<opc, asm, "", (outs FPR128:$dst),
8168 (ins FPR128:$Rd, FPR32:$Rn, V128:$Rm),
8169 [(set (v4i32 FPR128:$dst),
8170 (OpNode (v4i32 FPR128:$Rd), (i32 FPR32:$Rn),
8171 (v4i32 V128:$Rm)))]>;
8172
8173class SHATiedInstVVV<bits<3> opc, string asm, Intrinsic OpNode>
8174 : SHA3OpTiedInst<opc, asm, ".4s", (outs V128:$dst),
8175 (ins V128:$Rd, V128:$Rn, V128:$Rm),
8176 [(set (v4i32 V128:$dst),
8177 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn),
8178 (v4i32 V128:$Rm)))]>;
8179
8180class SHATiedInstQQV<bits<3> opc, string asm, Intrinsic OpNode>
8181 : SHA3OpTiedInst<opc, asm, "", (outs FPR128:$dst),
8182 (ins FPR128:$Rd, FPR128:$Rn, V128:$Rm),
8183 [(set (v4i32 FPR128:$dst),
8184 (OpNode (v4i32 FPR128:$Rd), (v4i32 FPR128:$Rn),
8185 (v4i32 V128:$Rm)))]>;
8186
8187let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
8188class SHA2OpInst<bits<4> opc, string asm, string kind,
8189 string cstr, dag oops, dag iops,
8190 list<dag> pat>
8191 : I<oops, iops, asm, "{\t$Rd" # kind # ", $Rn" # kind #
8192 "|" # kind # "\t$Rd, $Rn}", cstr, pat>,
8193 Sched<[WriteV]>{
8194 bits<5> Rd;
8195 bits<5> Rn;
8196 let Inst{31-16} = 0b0101111000101000;
8197 let Inst{15-12} = opc;
8198 let Inst{11-10} = 0b10;
8199 let Inst{9-5} = Rn;
8200 let Inst{4-0} = Rd;
8201}
8202
8203class SHATiedInstVV<bits<4> opc, string asm, Intrinsic OpNode>
8204 : SHA2OpInst<opc, asm, ".4s", "$Rd = $dst", (outs V128:$dst),
8205 (ins V128:$Rd, V128:$Rn),
8206 [(set (v4i32 V128:$dst),
8207 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn)))]>;
8208
8209class SHAInstSS<bits<4> opc, string asm, Intrinsic OpNode>
8210 : SHA2OpInst<opc, asm, "", "", (outs FPR32:$Rd), (ins FPR32:$Rn),
8211 [(set (i32 FPR32:$Rd), (OpNode (i32 FPR32:$Rn)))]>;
8212
8213// Allow the size specifier tokens to be upper case, not just lower.
8214def : TokenAlias<".8B", ".8b">;
8215def : TokenAlias<".4H", ".4h">;
8216def : TokenAlias<".2S", ".2s">;
8217def : TokenAlias<".1D", ".1d">;
8218def : TokenAlias<".16B", ".16b">;
8219def : TokenAlias<".8H", ".8h">;
8220def : TokenAlias<".4S", ".4s">;
8221def : TokenAlias<".2D", ".2d">;
Bradley Smith6d7af172014-04-09 14:42:01 +00008222def : TokenAlias<".1Q", ".1q">;
Tim Northover00ed9962014-03-29 10:18:08 +00008223def : TokenAlias<".B", ".b">;
8224def : TokenAlias<".H", ".h">;
8225def : TokenAlias<".S", ".s">;
8226def : TokenAlias<".D", ".d">;
Bradley Smith6d7af172014-04-09 14:42:01 +00008227def : TokenAlias<".Q", ".q">;