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