llvm.org GIT mirror llvm / f1b1c4f
[ARM] Set up infrastructure for MVE vector instructions. This commit prepares the way to start adding the main collection of MVE instructions, which operate on the 128-bit vector registers. The most obvious thing that's needed, and the simplest, is to add the MQPR register class, which is like the existing QPR except that it has fewer registers in it. The more complicated part: MVE defines a system of vector predication, in which instructions operating on 128-bit vector registers can be constrained to operate on only a subset of the lanes, using a system of prefix instructions similar to the existing Thumb IT, in that you have one prefix instruction which designates up to 4 following instructions as subject to predication, and within that sequence, the predicate can be inverted by means of T/E suffixes ('Then' / 'Else'). To support instructions of this type, we've added two new Tablegen classes `vpred_n` and `vpred_r` for standard clusters of MC operands to add to a predicated instruction. Both include a flag indicating how the instruction is predicated at all (options are T, E and 'not predicated'), and an input register field for the register controlling the set of active lanes. They differ from each other in that `vpred_r` also includes an input operand for the previous value of the output register, for instructions that leave inactive lanes unchanged. `vpred_n` lacks that extra operand; it will be used for instructions that don't preserve inactive lanes in their output register (either because inactive lanes are zeroed, as the MVE load instructions do, or because the output register isn't a vector at all). This commit also adds the family of prefix instructions themselves (VPT / VPST), and all the machinery needed to work with them in assembly and disassembly (e.g. generating the 't' and 'e' mnemonic suffixes on disassembled instructions within a predicated block) I've added a couple of demo instructions that derive from the new Tablegen base classes and use those two operand clusters. The bulk of the vector instructions will come in followup commits small enough to be manageable. (One exception is that I've added the full version of `isMnemonicVPTPredicable` in the AsmParser, because it seemed pointless to carefully split it up.) Reviewers: dmgreen, samparker, SjoerdMeijer, t.p.northover Subscribers: javed.absar, kristof.beyls, hiraditya, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D62669 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@363258 91177308-0d34-0410-b5e6-96231b3b80d8 Simon Tatham 1 year, 1 month ago
18 changed file(s) with 1460 addition(s) and 97 deletion(s). Raw diff Collapse all Expand all
476476 return Opc == ARM::B || Opc == ARM::tB || Opc == ARM::t2B;
477477 }
478478
479 static inline bool isVPTOpcode(int Opc) {
480 return Opc == ARM::t2VPTv16i8 || Opc == ARM::t2VPTv16u8 ||
481 Opc == ARM::t2VPTv16s8 || Opc == ARM::t2VPTv8i16 ||
482 Opc == ARM::t2VPTv8u16 || Opc == ARM::t2VPTv8s16 ||
483 Opc == ARM::t2VPTv4i32 || Opc == ARM::t2VPTv4u32 ||
484 Opc == ARM::t2VPTv4s32 || Opc == ARM::t2VPTv4f32 ||
485 Opc == ARM::t2VPTv8f16 || Opc == ARM::t2VPTv16i8r ||
486 Opc == ARM::t2VPTv16u8r || Opc == ARM::t2VPTv16s8r ||
487 Opc == ARM::t2VPTv8i16r || Opc == ARM::t2VPTv8u16r ||
488 Opc == ARM::t2VPTv8s16r || Opc == ARM::t2VPTv4i32r ||
489 Opc == ARM::t2VPTv4u32r || Opc == ARM::t2VPTv4s32r ||
490 Opc == ARM::t2VPTv4f32r || Opc == ARM::t2VPTv8f16r ||
491 Opc == ARM::t2VPST;
492 }
493
479494 static inline
480495 bool isCondBranchOpcode(int Opc) {
481496 return Opc == ARM::Bcc || Opc == ARM::tBcc || Opc == ARM::t2Bcc;
183183 let PrintMethod = "printSBitModifierOperand";
184184 let ParserMatchClass = CCOutOperand;
185185 let DecoderMethod = "DecodeCCOutOperand";
186 }
187
188 // VPT predicate
189
190 def VPTPredNOperand : AsmOperandClass {
191 let Name = "VPTPredN";
192 let PredicateMethod = "isVPTPred";
193 }
194 def VPTPredROperand : AsmOperandClass {
195 let Name = "VPTPredR";
196 let PredicateMethod = "isVPTPred";
197 }
198 def undef_tied_input;
199
200 // Operand classes for the cluster of MC operands describing a
201 // VPT-predicated MVE instruction.
202 //
203 // There are two of these classes. Both of them have the same first
204 // two options:
205 //
206 // $cond (an integer) indicates the instruction's predication status:
207 // * ARMVCC::None means it's unpredicated
208 // * ARMVCC::Then means it's in a VPT block and appears with the T suffix
209 // * ARMVCC::Else means it's in a VPT block and appears with the E suffix.
210 // During code generation, unpredicated and predicated instructions
211 // are indicated by setting this parameter to 'None' or to 'Then'; the
212 // third value 'Else' is only used for assembly and disassembly.
213 //
214 // $cond_reg (type VCCR) gives the input predicate register. This is
215 // always either zero_reg or VPR, but needs to be modelled as an
216 // explicit operand so that it can be register-allocated and spilled
217 // when these operands are used in code generation).
218 //
219 // For 'vpred_r', there's an extra operand $inactive, which specifies
220 // the vector register which will supply any lanes of the output
221 // register that the predication mask prevents from being written by
222 // this instruction. It's always tied to the actual output register
223 // (i.e. must be allocated into the same physical reg), but again,
224 // code generation will need to model it as a separate input value.
225 //
226 // 'vpred_n' doesn't have that extra operand: it only has $cond and
227 // $cond_reg. This variant is used for any instruction that can't, or
228 // doesn't want to, tie $inactive to the output register. Sometimes
229 // that's because another input parameter is already tied to it (e.g.
230 // instructions that both read and write their Qd register even when
231 // unpredicated, either because they only partially overwrite it like
232 // a narrowing integer conversion, or simply because the instruction
233 // encoding doesn't have enough register fields to make the output
234 // independent of all inputs). It can also be because the instruction
235 // is defined to set disabled output lanes to zero rather than leaving
236 // them unchanged (vector loads), or because it doesn't output a
237 // vector register at all (stores, compares). In any of these
238 // situations it's unnecessary to have an extra operand tied to the
239 // output, and inconvenient to leave it there unused.
240
241 // Base class for both kinds of vpred.
242 class vpred_ops : OperandWithDefaultOps
243 !con((ops (i32 0), (i32 zero_reg)), extra_op)> {
244 let PrintMethod = "printVPTPredicateOperand";
245 let OperandNamespace = "ARM";
246 let MIOperandInfo = !con((ops i32imm:$cond, VCCR:$cond_reg), extra_mi);
247
248 // For convenience, we provide a string value that can be appended
249 // to the constraints string. It's empty for vpred_n, and for
250 // vpred_r it ties the $inactive operand to the output q-register
251 // (which by convention will be called $Qd).
252 string vpred_constraint;
253 }
254
255 def vpred_r : vpred_ops<(ops (v4i32 undef_tied_input)), (ops MQPR:$inactive)> {
256 let ParserMatchClass = VPTPredROperand;
257 let OperandType = "OPERAND_VPRED_R";
258 let DecoderMethod = "DecodeVpredROperand";
259 let vpred_constraint = ",$Qd = $vp.inactive";
260 }
261
262 def vpred_n : vpred_ops<(ops), (ops)> {
263 let ParserMatchClass = VPTPredNOperand;
264 let OperandType = "OPERAND_VPRED_N";
265 let vpred_constraint = "";
186266 }
187267
188268 // ARM special operands for disassembly only.
99 //
1010 //===----------------------------------------------------------------------===//
1111
12 // VPT condition mask
13 def vpt_mask : Operand {
14 let PrintMethod = "printVPTMask";
15 let ParserMatchClass = it_mask_asmoperand;
16 let EncoderMethod = "getVPTMaskOpValue";
17 let DecoderMethod = "DecodeVPTMaskOperand";
18 }
19
20 // VPT/VCMP restricted predicate for sign invariant types
21 def pred_restricted_i_asmoperand : AsmOperandClass {
22 let Name = "CondCodeRestrictedI";
23 let RenderMethod = "addITCondCodeOperands";
24 let PredicateMethod = "isITCondCodeRestrictedI";
25 let ParserMethod = "parseITCondCode";
26 }
27
28 // VPT/VCMP restricted predicate for signed types
29 def pred_restricted_s_asmoperand : AsmOperandClass {
30 let Name = "CondCodeRestrictedS";
31 let RenderMethod = "addITCondCodeOperands";
32 let PredicateMethod = "isITCondCodeRestrictedS";
33 let ParserMethod = "parseITCondCode";
34 }
35
36 // VPT/VCMP restricted predicate for unsigned types
37 def pred_restricted_u_asmoperand : AsmOperandClass {
38 let Name = "CondCodeRestrictedU";
39 let RenderMethod = "addITCondCodeOperands";
40 let PredicateMethod = "isITCondCodeRestrictedU";
41 let ParserMethod = "parseITCondCode";
42 }
43
44 // VPT/VCMP restricted predicate for floating point
45 def pred_restricted_fp_asmoperand : AsmOperandClass {
46 let Name = "CondCodeRestrictedFP";
47 let RenderMethod = "addITCondCodeOperands";
48 let PredicateMethod = "isITCondCodeRestrictedFP";
49 let ParserMethod = "parseITCondCode";
50 }
51
52 def pred_basic_i : Operand {
53 let PrintMethod = "printMandatoryRestrictedPredicateOperand";
54 let ParserMatchClass = pred_restricted_i_asmoperand;
55 let DecoderMethod = "DecodeRestrictedIPredicateOperand";
56 let EncoderMethod = "getRestrictedCondCodeOpValue";
57 }
58
59 def pred_basic_u : Operand {
60 let PrintMethod = "printMandatoryRestrictedPredicateOperand";
61 let ParserMatchClass = pred_restricted_u_asmoperand;
62 let DecoderMethod = "DecodeRestrictedUPredicateOperand";
63 let EncoderMethod = "getRestrictedCondCodeOpValue";
64 }
65
66 def pred_basic_s : Operand {
67 let PrintMethod = "printMandatoryRestrictedPredicateOperand";
68 let ParserMatchClass = pred_restricted_s_asmoperand;
69 let DecoderMethod = "DecodeRestrictedSPredicateOperand";
70 let EncoderMethod = "getRestrictedCondCodeOpValue";
71 }
72
73 def pred_basic_fp : Operand {
74 let PrintMethod = "printMandatoryRestrictedPredicateOperand";
75 let ParserMatchClass = pred_restricted_fp_asmoperand;
76 let DecoderMethod = "DecodeRestrictedFPPredicateOperand";
77 let EncoderMethod = "getRestrictedCondCodeOpValue";
78 }
79
80 class MVE_MI
81 string ops, string cstr, list pattern>
82 : Thumb2XI
83 pattern>,
84 Requires<[HasMVEInt]> {
85 let D = MVEDomain;
86 let DecoderNamespace = "MVE";
87 }
88
89 // MVE_p is used for most predicated instructions, to add the cluster
90 // of input operands that provides the VPT suffix (none, T or E) and
91 // the input predicate register.
92 class MVE_p
93 string suffix, string ops, vpred_ops vpred, string cstr,
94 list pattern=[]>
95 : MVE_MI
96 // If the instruction has a suffix, like vadd.f32, then the
97 // VPT predication suffix goes before the dot, so the full
98 // name has to be "vadd${vp}.f32".
99 !strconcat(iname, "${vp}",
100 !if(!eq(suffix, ""), "", !strconcat(".", suffix))),
101 ops, !strconcat(cstr, vpred.vpred_constraint), pattern> {
102 let Inst{31-29} = 0b111;
103 let Inst{27-26} = 0b11;
104 }
105
12106 class MVE_MI_with_pred
13107 string ops, string cstr, list pattern>
14108 : Thumb2I
127221 def t2UQRSHLL : t2MVEShiftDRegReg<"uqrshll", 0b0, 0b1>;
128222 def t2UQSHLL : t2MVEShiftDRegImm<"uqshll", 0b00, 0b1>;
129223 def t2URSHRL : t2MVEShiftDRegImm<"urshrl", 0b01, 0b1>;
224
225 // start of mve_rDest instructions
226
227 class MVE_rDest
228 string ops, string cstr, list pattern=[]>
229 // Always use vpred_n and not vpred_r: with the output register being
230 // a GPR and not a vector register, there can't be any question of
231 // what to put in its inactive lanes.
232 : MVE_p {
233
234 let Inst{25-23} = 0b101;
235 let Inst{11-9} = 0b111;
236 let Inst{4} = 0b0;
237 }
238
239 class t2VABAV size, list pattern=[]>
240 : MVE_rDest<(outs rGPR:$Rda), (ins rGPR:$Rda_src, MQPR:$Qn, MQPR:$Qm),
241 NoItinerary, "vabav", suffix, "$Rda, $Qn, $Qm", "$Rda = $Rda_src",
242 pattern> {
243 bits<4> Qm;
244 bits<4> Qn;
245 bits<4> Rda;
246
247 let Inst{28} = U;
248 let Inst{22} = 0b0;
249 let Inst{21-20} = size{1-0};
250 let Inst{19-17} = Qn{2-0};
251 let Inst{16} = 0b0;
252 let Inst{15-12} = Rda{3-0};
253 let Inst{8} = 0b1;
254 let Inst{7} = Qn{3};
255 let Inst{6} = 0b0;
256 let Inst{5} = Qm{3};
257 let Inst{3-1} = Qm{2-0};
258 let Inst{0} = 0b1;
259 }
260
261 def VABAVs8 : t2VABAV<"s8", 0b0, 0b00>;
262 def VABAVs16 : t2VABAV<"s16", 0b0, 0b01>;
263 def VABAVs32 : t2VABAV<"s32", 0b0, 0b10>;
264 def VABAVu8 : t2VABAV<"u8", 0b1, 0b00>;
265 def VABAVu16 : t2VABAV<"u16", 0b1, 0b01>;
266 def VABAVu32 : t2VABAV<"u32", 0b1, 0b10>;
267
268 // end of mve_rDest instructions
269
270 // start of mve_comp instructions
271
272 class MVE_comp
273 string cstr, list pattern=[]>
274 : MVE_p<(outs MQPR:$Qd), (ins MQPR:$Qn, MQPR:$Qm), itin, iname, suffix,
275 "$Qd, $Qn, $Qm", vpred_r, cstr, pattern> {
276 bits<4> Qd;
277 bits<4> Qn;
278 bits<4> Qm;
279
280 let Inst{22} = Qd{3};
281 let Inst{19-17} = Qn{2-0};
282 let Inst{16} = 0b0;
283 let Inst{15-13} = Qd{2-0};
284 let Inst{12} = 0b0;
285 let Inst{10-9} = 0b11;
286 let Inst{7} = Qn{3};
287 let Inst{5} = Qm{3};
288 let Inst{3-1} = Qm{2-0};
289 let Inst{0} = 0b0;
290 }
291
292 class VMINMAXNM
293 list pattern=[]>
294 : MVE_comp {
295
296 let Inst{28} = 0b1;
297 let Inst{25-24} = 0b11;
298 let Inst{23} = 0b0;
299 let Inst{21} = bit_21;
300 let Inst{20} = sz;
301 let Inst{11} = 0b1;
302 let Inst{8} = 0b1;
303 let Inst{6} = 0b1;
304 let Inst{4} = 0b1;
305
306 let Predicates = [HasMVEFloat];
307 }
308
309 def VMAXNMf32 : VMINMAXNM<"vmaxnm", "f32", 0b0, 0b0>;
310 def VMAXNMf16 : VMINMAXNM<"vmaxnm", "f16", 0b1, 0b0>;
311
312 def VMINNMf32 : VMINMAXNM<"vminnm", "f32", 0b0, 0b1>;
313 def VMINNMf16 : VMINMAXNM<"vminnm", "f16", 0b1, 0b1>;
314
315 // end of mve_comp instructions
316
317 class t2VPT size, dag iops, string asm, list pattern=[]>
318 : MVE_MI<(outs ), iops, NoItinerary, !strconcat("vpt", "${Mk}", ".", suffix), asm, "", pattern> {
319 bits<3> fc;
320 bits<4> Mk;
321 bits<3> Qn;
322
323 let Inst{31-23} = 0b111111100;
324 let Inst{22} = Mk{3};
325 let Inst{21-20} = size;
326 let Inst{19-17} = Qn{2-0};
327 let Inst{16} = 0b1;
328 let Inst{15-13} = Mk{2-0};
329 let Inst{12} = fc{2};
330 let Inst{11-8} = 0b1111;
331 let Inst{7} = fc{0};
332 let Inst{4} = 0b0;
333
334 let Defs = [VPR, P0];
335 }
336
337 class t2VPTt1 size, dag iops>
338 : t2VPT {
339 bits<4> Qm;
340 bits<4> Mk;
341
342 let Inst{6} = 0b0;
343 let Inst{5} = Qm{3};
344 let Inst{3-1} = Qm{2-0};
345 let Inst{0} = fc{1};
346 }
347
348 class t2VPTt1i size>
349 : t2VPTt1
350 (ins vpt_mask:$Mk, pred_basic_i:$fc, MQPR:$Qn, MQPR:$Qm)> {
351 let Inst{12} = 0b0;
352 let Inst{0} = 0b0;
353 }
354
355 def t2VPTv4i32 : t2VPTt1i<"i32", 0b10>;
356 def t2VPTv8i16 : t2VPTt1i<"i16", 0b01>;
357 def t2VPTv16i8 : t2VPTt1i<"i8", 0b00>;
358
359 class t2VPTt1u size>
360 : t2VPTt1
361 (ins vpt_mask:$Mk, pred_basic_u:$fc, MQPR:$Qn, MQPR:$Qm)> {
362 let Inst{12} = 0b0;
363 let Inst{0} = 0b1;
364 }
365
366 def t2VPTv4u32 : t2VPTt1u<"u32", 0b10>;
367 def t2VPTv8u16 : t2VPTt1u<"u16", 0b01>;
368 def t2VPTv16u8 : t2VPTt1u<"u8", 0b00>;
369
370 class t2VPTt1s size>
371 : t2VPTt1
372 (ins vpt_mask:$Mk, pred_basic_s:$fc, MQPR:$Qn, MQPR:$Qm)> {
373 let Inst{12} = 0b1;
374 }
375
376 def t2VPTv4s32 : t2VPTt1s<"s32", 0b10>;
377 def t2VPTv8s16 : t2VPTt1s<"s16", 0b01>;
378 def t2VPTv16s8 : t2VPTt1s<"s8", 0b00>;
379
380 class t2VPTt2 size, dag iops>
381 : t2VPT
382 "$fc, $Qn, $Rm"> {
383 bits<4> Rm;
384 bits<3> fc;
385 bits<4> Mk;
386
387 let Inst{6} = 0b1;
388 let Inst{5} = fc{1};
389 let Inst{3-0} = Rm{3-0};
390 }
391
392 class t2VPTt2i size>
393 : t2VPTt2
394 (ins vpt_mask:$Mk, pred_basic_i:$fc, MQPR:$Qn, GPRwithZR:$Rm)> {
395 let Inst{12} = 0b0;
396 let Inst{5} = 0b0;
397 }
398
399 def t2VPTv4i32r : t2VPTt2i<"i32", 0b10>;
400 def t2VPTv8i16r : t2VPTt2i<"i16", 0b01>;
401 def t2VPTv16i8r : t2VPTt2i<"i8", 0b00>;
402
403 class t2VPTt2u size>
404 : t2VPTt2
405 (ins vpt_mask:$Mk, pred_basic_u:$fc, MQPR:$Qn, GPRwithZR:$Rm)> {
406 let Inst{12} = 0b0;
407 let Inst{5} = 0b1;
408 }
409
410 def t2VPTv4u32r : t2VPTt2u<"u32", 0b10>;
411 def t2VPTv8u16r : t2VPTt2u<"u16", 0b01>;
412 def t2VPTv16u8r : t2VPTt2u<"u8", 0b00>;
413
414 class t2VPTt2s size>
415 : t2VPTt2
416 (ins vpt_mask:$Mk, pred_basic_s:$fc, MQPR:$Qn, GPRwithZR:$Rm)> {
417 let Inst{12} = 0b1;
418 }
419
420 def t2VPTv4s32r : t2VPTt2s<"s32", 0b10>;
421 def t2VPTv8s16r : t2VPTt2s<"s16", 0b01>;
422 def t2VPTv16s8r : t2VPTt2s<"s8", 0b00>;
423
424
425 class t2VPTf pattern=[]>
426 : MVE_MI<(outs ), iops, NoItinerary, !strconcat("vpt", "${Mk}", ".", suffix), asm,
427 "", pattern> {
428 bits<3> fc;
429 bits<4> Mk;
430 bits<3> Qn;
431
432 let Inst{31-29} = 0b111;
433 let Inst{28} = size;
434 let Inst{27-23} = 0b11100;
435 let Inst{22} = Mk{3};
436 let Inst{21-20} = 0b11;
437 let Inst{19-17} = Qn{2-0};
438 let Inst{16} = 0b1;
439 let Inst{15-13} = Mk{2-0};
440 let Inst{12} = fc{2};
441 let Inst{11-8} = 0b1111;
442 let Inst{7} = fc{0};
443 let Inst{4} = 0b0;
444
445 let Defs = [P0];
446 let Predicates = [HasMVEFloat];
447 }
448
449 class t2VPTft1
450 : t2VPTf
451 "$fc, $Qn, $Qm"> {
452 bits<3> fc;
453 bits<4> Qm;
454
455 let Inst{6} = 0b0;
456 let Inst{5} = Qm{3};
457 let Inst{3-1} = Qm{2-0};
458 let Inst{0} = fc{1};
459 }
460
461 def t2VPTv4f32 : t2VPTft1<"f32", 0b0>;
462 def t2VPTv8f16 : t2VPTft1<"f16", 0b1>;
463
464 class t2VPTft2
465 : t2VPTf
466 "$fc, $Qn, $Rm"> {
467 bits<3> fc;
468 bits<4> Rm;
469
470 let Inst{6} = 0b1;
471 let Inst{5} = fc{1};
472 let Inst{3-0} = Rm{3-0};
473 }
474
475 def t2VPTv4f32r : t2VPTft2<"f32", 0b0>;
476 def t2VPTv8f16r : t2VPTft2<"f16", 0b1>;
477
478 def t2VPST : MVE_MI<(outs ), (ins vpt_mask:$Mk), NoItinerary,
479 !strconcat("vpst", "${Mk}"), "", "", []> {
480 bits<4> Mk;
481
482 let Inst{31-23} = 0b111111100;
483 let Inst{22} = Mk{3};
484 let Inst{21-16} = 0b110001;
485 let Inst{15-13} = Mk{2-0};
486 let Inst{12-0} = 0b0111101001101;
487 let Unpredictable{12} = 0b1;
488 let Unpredictable{7} = 0b1;
489 let Unpredictable{5} = 0b1;
490
491 let Defs = [P0];
492 }
158158 assert(RBGPR.covers(*TRI.getRegClass(ARM::tcGPRRegClassID)) &&
159159 "Subclass not added?");
160160 assert(RBGPR.covers(*TRI.getRegClass(ARM::tGPR_and_tcGPRRegClassID)) &&
161 "Subclass not added?");
162 assert(RBGPR.covers(*TRI.getRegClass(ARM::tGPREven_and_tGPR_and_tcGPRRegClassID)) &&
163 "Subclass not added?");
164 assert(RBGPR.covers(*TRI.getRegClass(ARM::tGPROdd_and_tcGPRRegClassID)) &&
161165 "Subclass not added?");
162166 assert(RBGPR.getSize() == 32 && "GPRs should hold up to 32-bit");
163167
434434 def QPR : RegisterClass<"ARM", [v16i8, v8i16, v4i32, v2i64, v4f32, v2f64, v8f16], 128,
435435 (sequence "Q%u", 0, 15)> {
436436 // Allocate non-VFP2 aliases Q8-Q15 first.
437 let AltOrders = [(rotl QPR, 8)];
438 let AltOrderSelect = [{ return 1; }];
437 let AltOrders = [(rotl QPR, 8), (trunc QPR, 8)];
438 let AltOrderSelect = [{
439 return 1 + MF.getSubtarget().hasMVEIntegerOps();
440 }];
439441 let DiagnosticString = "operand must be a register in range [q0, q15]";
440442 }
441443
450452 128, (trunc QPR, 4)> {
451453 let DiagnosticString = "operand must be a register in range [q0, q3]";
452454 }
455
456 // MVE 128-bit vector register class. This class is only really needed for
457 // parsing assembly, since we still have to truncate the register set in the QPR
458 // class anyway.
459 def MQPR : RegisterClass<"ARM", [v16i8, v8i16, v4i32, v2i64, v4f32, v2f64, v8f16],
460 128, (trunc QPR, 8)>;
453461
454462 // Pseudo-registers representing odd-even pairs of D registers. The even-odd
455463 // pairs are already represented by the Q registers.
6868
6969 using namespace llvm;
7070
71 namespace llvm {
72 extern const MCInstrDesc ARMInsts[];
73 } // end namespace llvm
74
7175 namespace {
7276
7377 enum class ImplicitItModeTy { Always, Never, ARMOnly, ThumbOnly };
354358 ITState.Mask = Mask;
355359 ITState.CurPosition = 0;
356360 ITState.IsExplicit = true;
361 }
362
363 struct {
364 unsigned Mask : 4;
365 unsigned CurPosition;
366 } VPTState;
367 bool inVPTBlock() { return VPTState.CurPosition != ~0U; }
368 void forwardVPTPosition() {
369 if (!inVPTBlock()) return;
370 unsigned TZ = countTrailingZeros(VPTState.Mask);
371 if (++VPTState.CurPosition == 5 - TZ)
372 VPTState.CurPosition = ~0U;
357373 }
358374
359375 void Note(SMLoc L, const Twine &Msg, SMRange Range = None) {
414430 bool parseDirectiveAlign(SMLoc L);
415431 bool parseDirectiveThumbSet(SMLoc L);
416432
417 StringRef splitMnemonic(StringRef Mnemonic, unsigned &PredicationCode,
418 bool &CarrySetting, unsigned &ProcessorIMod,
419 StringRef &ITMask);
420 void getMnemonicAcceptInfo(StringRef Mnemonic, StringRef FullInst,
421 bool &CanAcceptCarrySet,
422 bool &CanAcceptPredicationCode);
433 bool isMnemonicVPTPredicable(StringRef Mnemonic, StringRef ExtraToken);
434 StringRef splitMnemonic(StringRef Mnemonic, StringRef ExtraToken,
435 unsigned &PredicationCode,
436 unsigned &VPTPredicationCode, bool &CarrySetting,
437 unsigned &ProcessorIMod, StringRef &ITMask);
438 void getMnemonicAcceptInfo(StringRef Mnemonic, StringRef ExtraToken,
439 StringRef FullInst, bool &CanAcceptCarrySet,
440 bool &CanAcceptPredicationCode,
441 bool &CanAcceptVPTPredicationCode);
423442
424443 void tryConvertingToTwoOperandForm(StringRef Mnemonic, bool CarrySetting,
425444 OperandVector &Operands);
473492 }
474493 bool hasV8_1MMainline() const {
475494 return getSTI().getFeatureBits()[ARM::HasV8_1MMainlineOps];
495 }
496 bool hasMVE() const {
497 return getSTI().getFeatureBits()[ARM::HasMVEIntegerOps];
498 }
499 bool hasMVEFloat() const {
500 return getSTI().getFeatureBits()[ARM::HasMVEFloatOps];
476501 }
477502 bool has8MSecExt() const {
478503 return getSTI().getFeatureBits()[ARM::Feature8MSecExt];
556581 bool processInstruction(MCInst &Inst, const OperandVector &Ops, MCStreamer &Out);
557582 bool shouldOmitCCOutOperand(StringRef Mnemonic, OperandVector &Operands);
558583 bool shouldOmitPredicateOperand(StringRef Mnemonic, OperandVector &Operands);
584 bool shouldOmitVectorPredicateOperand(StringRef Mnemonic, OperandVector &Operands);
559585 bool isITBlockTerminator(MCInst &Inst) const;
560586 void fixupGNULDRDAlias(StringRef Mnemonic, OperandVector &Operands);
561587 bool validateLDRDSTRD(MCInst &Inst, const OperandVector &Operands,
592618 // Not in an ITBlock to start with.
593619 ITState.CurPosition = ~0U;
594620
621 VPTState.CurPosition = ~0U;
622
595623 NextSymbolIsThumb = false;
596624 }
597625
637665 class ARMOperand : public MCParsedAsmOperand {
638666 enum KindTy {
639667 k_CondCode,
668 k_VPTPred,
640669 k_CCOut,
641670 k_ITCondMask,
642671 k_CoprocNum,
679708 ARMCC::CondCodes Val;
680709 };
681710
711 struct VCCOp {
712 ARMVCC::VPTCodes Val;
713 };
714
682715 struct CopOp {
683716 unsigned Val;
684717 };
795828
796829 union {
797830 struct CCOp CC;
831 struct VCCOp VCC;
798832 struct CopOp Cop;
799833 struct CoprocOptionOp CoprocOption;
800834 struct MBOptOp MBOpt;
843877 return CC.Val;
844878 }
845879
880 ARMVCC::VPTCodes getVPTPred() const {
881 assert(isVPTPred() && "Invalid access!");
882 return VCC.Val;
883 }
884
846885 unsigned getCoproc() const {
847886 assert((Kind == k_CoprocNum || Kind == k_CoprocReg) && "Invalid access!");
848887 return Cop.Val;
916955 bool isCoprocReg() const { return Kind == k_CoprocReg; }
917956 bool isCoprocOption() const { return Kind == k_CoprocOption; }
918957 bool isCondCode() const { return Kind == k_CondCode; }
958 bool isVPTPred() const { return Kind == k_VPTPred; }
919959 bool isCCOut() const { return Kind == k_CCOut; }
920960 bool isITMask() const { return Kind == k_ITCondMask; }
921961 bool isITCondCode() const { return Kind == k_CondCode; }
18541894 return VectorList.Count == 4 && VectorList.LaneIndex <= 1;
18551895 }
18561896
1897 bool isVectorIndex() const { return Kind == k_VectorIndex; }
1898
18571899 bool isVectorIndex8() const {
18581900 if (Kind != k_VectorIndex) return false;
18591901 return VectorIndex.Val < 8;
20512093
20522094 bool isITCondCodeNoAL() const {
20532095 if (!isITCondCode()) return false;
2054 auto CC = (ARMCC::CondCodes) getCondCode();
2096 ARMCC::CondCodes CC = getCondCode();
20552097 return CC != ARMCC::AL;
2098 }
2099
2100 bool isITCondCodeRestrictedI() const {
2101 if (!isITCondCode())
2102 return false;
2103 ARMCC::CondCodes CC = getCondCode();
2104 return CC == ARMCC::EQ || CC == ARMCC::NE;
2105 }
2106
2107 bool isITCondCodeRestrictedS() const {
2108 if (!isITCondCode())
2109 return false;
2110 ARMCC::CondCodes CC = getCondCode();
2111 return CC == ARMCC::LT || CC == ARMCC::GT || CC == ARMCC::LE ||
2112 CC == ARMCC::GE;
2113 }
2114
2115 bool isITCondCodeRestrictedU() const {
2116 if (!isITCondCode())
2117 return false;
2118 ARMCC::CondCodes CC = getCondCode();
2119 return CC == ARMCC::HS || CC == ARMCC::HI;
2120 }
2121
2122 bool isITCondCodeRestrictedFP() const {
2123 if (!isITCondCode())
2124 return false;
2125 ARMCC::CondCodes CC = getCondCode();
2126 return CC == ARMCC::EQ || CC == ARMCC::NE || CC == ARMCC::LT ||
2127 CC == ARMCC::GT || CC == ARMCC::LE || CC == ARMCC::GE;
20562128 }
20572129
20582130 void addExpr(MCInst &Inst, const MCExpr *Expr) const {
20792151 assert(N == 2 && "Invalid number of operands!");
20802152 Inst.addOperand(MCOperand::createImm(unsigned(getCondCode())));
20812153 unsigned RegNum = getCondCode() == ARMCC::AL ? 0: ARM::CPSR;
2154 Inst.addOperand(MCOperand::createReg(RegNum));
2155 }
2156
2157 void addVPTPredNOperands(MCInst &Inst, unsigned N) const {
2158 assert(N == 2 && "Invalid number of operands!");
2159 Inst.addOperand(MCOperand::createImm(unsigned(getVPTPred())));
2160 unsigned RegNum = getVPTPred() == ARMVCC::None ? 0: ARM::P0;
2161 Inst.addOperand(MCOperand::createReg(RegNum));
2162 }
2163
2164 void addVPTPredROperands(MCInst &Inst, unsigned N) const {
2165 assert(N == 3 && "Invalid number of operands!");
2166 addVPTPredNOperands(Inst, N-1);
2167 unsigned RegNum;
2168 if (getVPTPred() == ARMVCC::None) {
2169 RegNum = 0;
2170 } else {
2171 unsigned NextOpIndex = Inst.getNumOperands();
2172 const MCInstrDesc &MCID = ARMInsts[Inst.getOpcode()];
2173 int TiedOp = MCID.getOperandConstraint(NextOpIndex, MCOI::TIED_TO);
2174 assert(TiedOp >= 0 &&
2175 "Inactive register in vpred_r is not tied to an output!");
2176 RegNum = Inst.getOperand(TiedOp).getReg();
2177 }
20822178 Inst.addOperand(MCOperand::createReg(RegNum));
20832179 }
20842180
28122908 Inst.addOperand(MCOperand::createImm(Imm));
28132909 }
28142910
2911 void addPowerTwoOperands(MCInst &Inst, unsigned N) const {
2912 assert(N == 1 && "Invalid number of operands!");
2913 const MCConstantExpr *CE = dyn_cast(getImm());
2914 Inst.addOperand(MCOperand::createImm(CE->getValue()));
2915 }
2916
28152917 void addMSRMaskOperands(MCInst &Inst, unsigned N) const {
28162918 assert(N == 1 && "Invalid number of operands!");
28172919 Inst.addOperand(MCOperand::createImm(unsigned(getMSRMask())));
30213123 SMLoc S) {
30223124 auto Op = make_unique(k_CondCode);
30233125 Op->CC.Val = CC;
3126 Op->StartLoc = S;
3127 Op->EndLoc = S;
3128 return Op;
3129 }
3130
3131 static std::unique_ptr CreateVPTPred(ARMVCC::VPTCodes CC,
3132 SMLoc S) {
3133 auto Op = make_unique(k_VPTPred);
3134 Op->VCC.Val = CC;
30243135 Op->StartLoc = S;
30253136 Op->EndLoc = S;
30263137 return Op;
33413452 switch (Kind) {
33423453 case k_CondCode:
33433454 OS << "";
3455 break;
3456 case k_VPTPred:
3457 OS << "";
33443458 break;
33453459 case k_CCOut:
33463460 OS << "";
57745888 // FIXME: Would be nice to autogen this.
57755889 // FIXME: This is a bit of a maze of special cases.
57765890 StringRef ARMAsmParser::splitMnemonic(StringRef Mnemonic,
5891 StringRef ExtraToken,
57775892 unsigned &PredicationCode,
5893 unsigned &VPTPredicationCode,
57785894 bool &CarrySetting,
57795895 unsigned &ProcessorIMod,
57805896 StringRef &ITMask) {
57815897 PredicationCode = ARMCC::AL;
5898 VPTPredicationCode = ARMVCC::None;
57825899 CarrySetting = false;
57835900 ProcessorIMod = 0;
57845901
58565973 }
58575974 }
58585975
5976 if (isMnemonicVPTPredicable(Mnemonic, ExtraToken)) {
5977 unsigned CC = ARMVectorCondCodeFromString(Mnemonic.substr(Mnemonic.size()-1));
5978 if (CC != ~0U) {
5979 Mnemonic = Mnemonic.slice(0, Mnemonic.size()-1);
5980 VPTPredicationCode = CC;
5981 }
5982 return Mnemonic;
5983 }
5984
58595985 // The "it" instruction has the condition mask on the end of the mnemonic.
58605986 if (Mnemonic.startswith("it")) {
58615987 ITMask = Mnemonic.slice(2, Mnemonic.size());
58625988 Mnemonic = Mnemonic.slice(0, 2);
58635989 }
58645990
5991 if (Mnemonic.startswith("vpst")) {
5992 ITMask = Mnemonic.slice(4, Mnemonic.size());
5993 Mnemonic = Mnemonic.slice(0, 4);
5994 }
5995 else if (Mnemonic.startswith("vpt")) {
5996 ITMask = Mnemonic.slice(3, Mnemonic.size());
5997 Mnemonic = Mnemonic.slice(0, 3);
5998 }
5999
58656000 return Mnemonic;
58666001 }
58676002
58696004 /// inclusion of carry set or predication code operands.
58706005 //
58716006 // FIXME: It would be nice to autogen this.
5872 void ARMAsmParser::getMnemonicAcceptInfo(StringRef Mnemonic, StringRef FullInst,
6007 void ARMAsmParser::getMnemonicAcceptInfo(StringRef Mnemonic,
6008 StringRef ExtraToken,
6009 StringRef FullInst,
58736010 bool &CanAcceptCarrySet,
5874 bool &CanAcceptPredicationCode) {
6011 bool &CanAcceptPredicationCode,
6012 bool &CanAcceptVPTPredicationCode) {
6013 CanAcceptVPTPredicationCode = isMnemonicVPTPredicable(Mnemonic, ExtraToken);
6014
58756015 CanAcceptCarrySet =
58766016 Mnemonic == "and" || Mnemonic == "lsl" || Mnemonic == "lsr" ||
58776017 Mnemonic == "rrx" || Mnemonic == "ror" || Mnemonic == "sub" ||
59056045 Mnemonic == "dls" || Mnemonic == "le" || Mnemonic == "csel" ||
59066046 Mnemonic == "csinc" || Mnemonic == "csinv" || Mnemonic == "csneg" ||
59076047 Mnemonic == "cinc" || Mnemonic == "cinv" || Mnemonic == "cneg" ||
5908 Mnemonic == "cset" || Mnemonic == "csetm") {
6048 Mnemonic == "cset" || Mnemonic == "csetm" ||
6049 Mnemonic.startswith("vpt") || Mnemonic.startswith("vpst")) {
59096050 // These mnemonics are never predicable
59106051 CanAcceptPredicationCode = false;
59116052 } else if (!isThumb()) {
61576298 return false;
61586299 }
61596300
6301 bool ARMAsmParser::shouldOmitVectorPredicateOperand(StringRef Mnemonic,
6302 OperandVector &Operands) {
6303 if (!hasMVE() || Operands.size() < 3)
6304 return true;
6305
6306 for (auto &Operand : Operands) {
6307 // We check the larger class QPR instead of just the legal class
6308 // MQPR, to more accurately report errors when using Q registers
6309 // outside of the allowed range.
6310 if (static_cast(*Operand).isVectorIndex() ||
6311 (Operand->isReg() &&
6312 (ARMMCRegisterClasses[ARM::QPRRegClassID].contains(
6313 Operand->getReg()))))
6314 return false;
6315 }
6316 return true;
6317 }
6318
61606319 static bool isDataTypeToken(StringRef Tok) {
61616320 return Tok == ".8" || Tok == ".16" || Tok == ".32" || Tok == ".64" ||
61626321 Tok == ".i8" || Tok == ".i16" || Tok == ".i32" || Tok == ".i64" ||
62486407 // Create the leading tokens for the mnemonic, split by '.' characters.
62496408 size_t Start = 0, Next = Name.find('.');
62506409 StringRef Mnemonic = Name.slice(Start, Next);
6410 StringRef ExtraToken = Name.slice(Next, Name.find(' ', Next + 1));
62516411
62526412 // Split out the predication code and carry setting flag from the mnemonic.
62536413 unsigned PredicationCode;
6414 unsigned VPTPredicationCode;
62546415 unsigned ProcessorIMod;
62556416 bool CarrySetting;
62566417 StringRef ITMask;
6257 Mnemonic = splitMnemonic(Mnemonic, PredicationCode, CarrySetting,
6258 ProcessorIMod, ITMask);
6418 Mnemonic = splitMnemonic(Mnemonic, ExtraToken, PredicationCode, VPTPredicationCode,
6419 CarrySetting, ProcessorIMod, ITMask);
62596420
62606421 // In Thumb1, only the branch (B) instruction can be predicated.
62616422 if (isThumbOne() && PredicationCode != ARMCC::AL && Mnemonic != "b") {
62646425
62656426 Operands.push_back(ARMOperand::CreateToken(Mnemonic, NameLoc));
62666427
6267 // Handle the mask for IT instructions. In ARMOperand and MCOperand,
6268 // this is stored in a format independent of the condition code: the
6269 // lowest set bit indicates the end of the encoding, and above that,
6270 // a 1 bit indicates 'else', and an 0 indicates 'then'. E.g.
6428 // Handle the mask for IT and VPT instructions. In ARMOperand and
6429 // MCOperand, this is stored in a format independent of the
6430 // condition code: the lowest set bit indicates the end of the
6431 // encoding, and above that, a 1 bit indicates 'else', and an 0
6432 // indicates 'then'. E.g.
62716433 // IT -> 1000
62726434 // ITx -> x100 (ITT -> 0100, ITE -> 1100)
62736435 // ITxy -> xy10 (e.g. ITET -> 1010)
62746436 // ITxyz -> xyz1 (e.g. ITEET -> 1101)
6275 if (Mnemonic == "it") {
6276 SMLoc Loc = SMLoc::getFromPointer(NameLoc.getPointer() + 2);
6437 if (Mnemonic == "it" || Mnemonic.startswith("vpt") ||
6438 Mnemonic.startswith("vpst")) {
6439 SMLoc Loc = Mnemonic == "it" ? SMLoc::getFromPointer(NameLoc.getPointer() + 2) :
6440 Mnemonic == "vpt" ? SMLoc::getFromPointer(NameLoc.getPointer() + 3) :
6441 SMLoc::getFromPointer(NameLoc.getPointer() + 4);
62776442 if (ITMask.size() > 3) {
6278 return Error(Loc, "too many conditions on IT instruction");
6443 if (Mnemonic == "it")
6444 return Error(Loc, "too many conditions on IT instruction");
6445 return Error(Loc, "too many conditions on VPT instruction");
62796446 }
62806447 unsigned Mask = 8;
62816448 for (unsigned i = ITMask.size(); i != 0; --i) {
63006467 // ConditionCode operands to match the mnemonic "as written" and then we let
63016468 // the matcher deal with finding the right instruction or generating an
63026469 // appropriate error.
6303 bool CanAcceptCarrySet, CanAcceptPredicationCode;
6304 getMnemonicAcceptInfo(Mnemonic, Name, CanAcceptCarrySet, CanAcceptPredicationCode);
6470 bool CanAcceptCarrySet, CanAcceptPredicationCode, CanAcceptVPTPredicationCode;
6471 getMnemonicAcceptInfo(Mnemonic, ExtraToken, Name, CanAcceptCarrySet,
6472 CanAcceptPredicationCode, CanAcceptVPTPredicationCode);
63056473
63066474 // If we had a carry-set on an instruction that can't do that, issue an
63076475 // error.
63166484 "' is not predicable, but condition code specified");
63176485 }
63186486
6487 // If we had a VPT predication code on an instruction that can't do that, issue an
6488 // error.
6489 if (!CanAcceptVPTPredicationCode && VPTPredicationCode != ARMVCC::None) {
6490 return Error(NameLoc, "instruction '" + Mnemonic +
6491 "' is not VPT predicable, but VPT code T/E is specified");
6492 }
6493
63196494 // Add the carry setting operand, if necessary.
63206495 if (CanAcceptCarrySet) {
63216496 SMLoc Loc = SMLoc::getFromPointer(NameLoc.getPointer() + Mnemonic.size());
63286503 SMLoc Loc = SMLoc::getFromPointer(NameLoc.getPointer() + Mnemonic.size() +
63296504 CarrySetting);
63306505 Operands.push_back(ARMOperand::CreateCondCode(
6331 ARMCC::CondCodes(PredicationCode), Loc));
6506 ARMCC::CondCodes(PredicationCode), Loc));
6507 }
6508
6509 // Add the VPT predication code operand, if necessary.
6510 if (CanAcceptVPTPredicationCode) {
6511 SMLoc Loc = SMLoc::getFromPointer(NameLoc.getPointer() + Mnemonic.size() +
6512 CarrySetting);
6513 Operands.push_back(ARMOperand::CreateVPTPred(
6514 ARMVCC::VPTCodes(VPTPredicationCode), Loc));
63326515 }
63336516
63346517 // Add the processor imod operand, if necessary.
63446527 while (Next != StringRef::npos) {
63456528 Start = Next;
63466529 Next = Name.find('.', Start + 1);
6347 StringRef ExtraToken = Name.slice(Start, Next);
6530 ExtraToken = Name.slice(Start, Next);
63486531
63496532 // Some NEON instructions have an optional datatype suffix that is
63506533 // completely ignored. Check for that.
64006583
64016584 // Some instructions have the same mnemonic, but don't always
64026585 // have a predicate. Distinguish them here and delete the
6403 // predicate if needed.
6586 // appropriate predicate if needed. This could be either the scalar
6587 // predication code or the vector predication code.
64046588 if (PredicationCode == ARMCC::AL &&
64056589 shouldOmitPredicateOperand(Mnemonic, Operands))
64066590 Operands.erase(Operands.begin() + 1);
64076591
6408 // ARM mode 'blx' need special handling, as the register operand version
6409 // is predicable, but the label operand version is not. So, we can't rely
6410 // on the Mnemonic based checking to correctly figure out when to put
6411 // a k_CondCode operand in the list. If we're trying to match the label
6412 // version, remove the k_CondCode operand here.
6413 if (!isThumb() && Mnemonic == "blx" && Operands.size() == 3 &&
6414 static_cast(*Operands[2]).isImm())
6415 Operands.erase(Operands.begin() + 1);
6416
6417 // Adjust operands of ldrexd/strexd to MCK_GPRPair.
6418 // ldrexd/strexd require even/odd GPR pair. To enforce this constraint,
6419 // a single GPRPair reg operand is used in the .td file to replace the two
6420 // GPRs. However, when parsing from asm, the two GRPs cannot be automatically
6421 // expressed as a GPRPair, so we have to manually merge them.
6422 // FIXME: We would really like to be able to tablegen'erate this.
6423 if (!isThumb() && Operands.size() > 4 &&
6424 (Mnemonic == "ldrexd" || Mnemonic == "strexd" || Mnemonic == "ldaexd" ||
6425 Mnemonic == "stlexd")) {
6426 bool isLoad = (Mnemonic == "ldrexd" || Mnemonic == "ldaexd");
6427 unsigned Idx = isLoad ? 2 : 3;
6428 ARMOperand &Op1 = static_cast(*Operands[Idx]);
6429 ARMOperand &Op2 = static_cast(*Operands[Idx + 1]);
6430
6431 const MCRegisterClass& MRC = MRI->getRegClass(ARM::GPRRegClassID);
6432 // Adjust only if Op1 and Op2 are GPRs.
6433 if (Op1.isReg() && Op2.isReg() && MRC.contains(Op1.getReg()) &&
6434 MRC.contains(Op2.getReg())) {
6435 unsigned Reg1 = Op1.getReg();
6436 unsigned Reg2 = Op2.getReg();
6437 unsigned Rt = MRI->getEncodingValue(Reg1);
6438 unsigned Rt2 = MRI->getEncodingValue(Reg2);
6439
6440 // Rt2 must be Rt + 1 and Rt must be even.
6441 if (Rt + 1 != Rt2 || (Rt & 1)) {
6442 return Error(Op2.getStartLoc(),
6443 isLoad ? "destination operands must be sequential"
6444 : "source operands must be sequential");
6592
6593 if (hasMVE()) {
6594 if (CanAcceptVPTPredicationCode) {
6595 // For all other instructions, make sure only one of the two
6596 // predication operands is left behind, depending on whether we should
6597 // use the vector predication.
6598 if (shouldOmitVectorPredicateOperand(Mnemonic, Operands)) {
6599 if (CanAcceptPredicationCode)
6600 Operands.erase(Operands.begin() + 2);
6601 else
6602 Operands.erase(Operands.begin() + 1);
6603 } else if (CanAcceptPredicationCode && PredicationCode == ARMCC::AL) {
6604 Operands.erase(Operands.begin() + 1);
64456605 }
6446 unsigned NewReg = MRI->getMatchingSuperReg(Reg1, ARM::gsub_0,
6447 &(MRI->getRegClass(ARM::GPRPairRegClassID)));
6448 Operands[Idx] =
6449 ARMOperand::CreateReg(NewReg, Op1.getStartLoc(), Op2.getEndLoc());
6450 Operands.erase(Operands.begin() + Idx + 1);
6451 }
6606 }
6607 }
6608
6609 if (VPTPredicationCode != ARMVCC::None) {
6610 bool usedVPTPredicationCode = false;
6611 for (unsigned I = 1; I < Operands.size(); ++I)
6612 if (static_cast(*Operands[I]).isVPTPred())
6613 usedVPTPredicationCode = true;
6614 if (!usedVPTPredicationCode) {
6615 // If we have a VPT predication code and we haven't just turned it
6616 // into an operand, then it was a mistake for splitMnemonic to
6617 // separate it from the rest of the mnemonic in the first place,
6618 // and this may lead to wrong disassembly (e.g. scalar floating
6619 // point VCMPE is actually a different instruction from VCMP, so
6620 // we mustn't treat them the same). In that situation, glue it
6621 // back on.
6622 Mnemonic = Name.slice(0, Mnemonic.size() + 1);
6623 Operands.erase(Operands.begin());
6624 Operands.insert(Operands.begin(),
6625 ARMOperand::CreateToken(Mnemonic, NameLoc));
6626 }
6627 }
6628
6629 // ARM mode 'blx' need special handling, as the register operand version
6630 // is predicable, but the label operand version is not. So, we can't rely
6631 // on the Mnemonic based checking to correctly figure out when to put
6632 // a k_CondCode operand in the list. If we're trying to match the label
6633 // version, remove the k_CondCode operand here.
6634 if (!isThumb() && Mnemonic == "blx" && Operands.size() == 3 &&
6635 static_cast(*Operands[2]).isImm())
6636 Operands.erase(Operands.begin() + 1);
6637
6638 // Adjust operands of ldrexd/strexd to MCK_GPRPair.
6639 // ldrexd/strexd require even/odd GPR pair. To enforce this constraint,
6640 // a single GPRPair reg operand is used in the .td file to replace the two
6641 // GPRs. However, when parsing from asm, the two GRPs cannot be
6642 // automatically
6643 // expressed as a GPRPair, so we have to manually merge them.
6644 // FIXME: We would really like to be able to tablegen'erate this.
6645 if (!isThumb() && Operands.size() > 4 &&
6646 (Mnemonic == "ldrexd" || Mnemonic == "strexd" || Mnemonic == "ldaexd" ||
6647 Mnemonic == "stlexd")) {
6648 bool isLoad = (Mnemonic == "ldrexd" || Mnemonic == "ldaexd");
6649 unsigned Idx = isLoad ? 2 : 3;
6650 ARMOperand &Op1 = static_cast(*Operands[Idx]);
6651 ARMOperand &Op2 = static_cast(*Operands[Idx + 1]);
6652
6653 const MCRegisterClass &MRC = MRI->getRegClass(ARM::GPRRegClassID);
6654 // Adjust only if Op1 and Op2 are GPRs.
6655 if (Op1.isReg() && Op2.isReg() && MRC.contains(Op1.getReg()) &&
6656 MRC.contains(Op2.getReg())) {
6657 unsigned Reg1 = Op1.getReg();
6658 unsigned Reg2 = Op2.getReg();
6659 unsigned Rt = MRI->getEncodingValue(Reg1);
6660 unsigned Rt2 = MRI->getEncodingValue(Reg2);
6661
6662 // Rt2 must be Rt + 1 and Rt must be even.
6663 if (Rt + 1 != Rt2 || (Rt & 1)) {
6664 return Error(Op2.getStartLoc(),
6665 isLoad ? "destination operands must be sequential"
6666 : "source operands must be sequential");
6667 }
6668 unsigned NewReg = MRI->getMatchingSuperReg(
6669 Reg1, ARM::gsub_0, &(MRI->getRegClass(ARM::GPRPairRegClassID)));
6670 Operands[Idx] =
6671 ARMOperand::CreateReg(NewReg, Op1.getStartLoc(), Op2.getEndLoc());
6672 Operands.erase(Operands.begin() + Idx + 1);
6673 }
64526674 }
64536675
64546676 // GNU Assembler extension (compatibility).
66096831 return false;
66106832 }
66116833
6834 static int findFirstVectorPredOperandIdx(const MCInstrDesc &MCID) {
6835 for (unsigned i = 0; i < MCID.NumOperands; ++i) {
6836 if (ARM::isVpred(MCID.OpInfo[i].OperandType))
6837 return i;
6838 }
6839 return -1;
6840 }
6841
6842 static bool isVectorPredicable(const MCInstrDesc &MCID) {
6843 return findFirstVectorPredOperandIdx(MCID) != -1;
6844 }
66126845
66136846 // FIXME: We would really like to be able to tablegen'erate this.
66146847 bool ARMAsmParser::validateInstruction(MCInst &Inst,
66666899 if (inExplicitITBlock() && !lastInITBlock() && isITBlockTerminator(Inst)) {
66676900 return Error(Loc, "instruction must be outside of IT block or the last instruction in an IT block");
66686901 }
6902
6903 if (inVPTBlock() && !instIsBreakpoint(Inst)) {
6904 unsigned Bit = extractITMaskBit(VPTState.Mask, VPTState.CurPosition);
6905 if (!isVectorPredicable(MCID))
6906 return Error(Loc, "instruction in VPT block must be predicable");
6907 unsigned Pred = Inst.getOperand(findFirstVectorPredOperandIdx(MCID)).getImm();
6908 unsigned VPTPred = Bit ? ARMVCC::Else : ARMVCC::Then;
6909 if (Pred != VPTPred) {
6910 SMLoc PredLoc;
6911 for (unsigned I = 1; I < Operands.size(); ++I)
6912 if (static_cast(*Operands[I]).isVPTPred())
6913 PredLoc = Operands[I]->getStartLoc();
6914 return Error(PredLoc, "incorrect predication in VPT block; got '" +
6915 StringRef(ARMVPTPredToString(ARMVCC::VPTCodes(Pred))) +
6916 "', but expected '" +
6917 ARMVPTPredToString(ARMVCC::VPTCodes(VPTPred)) + "'");
6918 }
6919 }
6920 else if (isVectorPredicable(MCID) &&
6921 Inst.getOperand(findFirstVectorPredOperandIdx(MCID)).getImm() !=
6922 ARMVCC::None)
6923 return Error(Loc, "VPT predicated instructions must be in VPT block");
66696924
66706925 const unsigned Opcode = Inst.getOpcode();
66716926 switch (Opcode) {
93349589 return true;
93359590 }
93369591 return false;
9592 case ARM::t2VPST:
9593 case ARM::t2VPTv16i8:
9594 case ARM::t2VPTv8i16:
9595 case ARM::t2VPTv4i32:
9596 case ARM::t2VPTv16u8:
9597 case ARM::t2VPTv8u16:
9598 case ARM::t2VPTv4u32:
9599 case ARM::t2VPTv16s8:
9600 case ARM::t2VPTv8s16:
9601 case ARM::t2VPTv4s32:
9602 case ARM::t2VPTv4f32:
9603 case ARM::t2VPTv8f16:
9604 case ARM::t2VPTv16i8r:
9605 case ARM::t2VPTv8i16r:
9606 case ARM::t2VPTv4i32r:
9607 case ARM::t2VPTv16u8r:
9608 case ARM::t2VPTv8u16r:
9609 case ARM::t2VPTv4u32r:
9610 case ARM::t2VPTv16s8r:
9611 case ARM::t2VPTv8s16r:
9612 case ARM::t2VPTv4s32r:
9613 case ARM::t2VPTv4f32r:
9614 case ARM::t2VPTv8f16r: {
9615 assert(!inVPTBlock() && "Nested VPT blocks are not allowed");
9616 MCOperand &MO = Inst.getOperand(0);
9617 VPTState.Mask = MO.getImm();
9618 VPTState.CurPosition = 0;
9619 break;
9620 }
93379621 }
93389622 return false;
93399623 }
95749858 // Still progress the IT block, otherwise one wrong condition causes
95759859 // nasty cascading errors.
95769860 forwardITPosition();
9861 forwardVPTPosition();
95779862 return true;
95789863 }
95799864
96009885 // and process gets a consistent answer about whether we're in an IT
96019886 // block.
96029887 forwardITPosition();
9888 forwardVPTPosition();
96039889
96049890 // ITasm is an ARM mode pseudo-instruction that just sets the ITblock and
96059891 // doesn't actually encode.
1097911265 }
1098011266 return Match_InvalidOperand;
1098111267 }
11268
11269 bool ARMAsmParser::isMnemonicVPTPredicable(StringRef Mnemonic,
11270 StringRef ExtraToken) {
11271 if (!hasMVE())
11272 return false;
11273
11274 return Mnemonic.startswith("vabav") || Mnemonic.startswith("vaddv") ||
11275 Mnemonic.startswith("vaddlv") || Mnemonic.startswith("vminnmv") ||
11276 Mnemonic.startswith("vminnmav") || Mnemonic.startswith("vminv") ||
11277 Mnemonic.startswith("vminav") || Mnemonic.startswith("vmaxnmv") ||
11278 Mnemonic.startswith("vmaxnmav") || Mnemonic.startswith("vmaxv") ||
11279 Mnemonic.startswith("vmaxav") || Mnemonic.startswith("vmladav") ||
11280 Mnemonic.startswith("vrmlaldavh") || Mnemonic.startswith("vrmlalvh") ||
11281 Mnemonic.startswith("vmlsdav") || Mnemonic.startswith("vmlav") ||
11282 Mnemonic.startswith("vmlaldav") || Mnemonic.startswith("vmlalv") ||
11283 Mnemonic.startswith("vmaxnm") || Mnemonic.startswith("vminnm") ||
11284 Mnemonic.startswith("vmax") || Mnemonic.startswith("vmin") ||
11285 Mnemonic.startswith("vshlc") || Mnemonic.startswith("vmovlt") ||
11286 Mnemonic.startswith("vmovlb") || Mnemonic.startswith("vshll") ||
11287 Mnemonic.startswith("vrshrn") || Mnemonic.startswith("vshrn") ||
11288 Mnemonic.startswith("vqrshrun") || Mnemonic.startswith("vqshrun") ||
11289 Mnemonic.startswith("vqrshrn") || Mnemonic.startswith("vqshrn") ||
11290 Mnemonic.startswith("vbic") || Mnemonic.startswith("vrev64") ||
11291 Mnemonic.startswith("vrev32") || Mnemonic.startswith("vrev16") ||
11292 Mnemonic.startswith("vmvn") || Mnemonic.startswith("veor") ||
11293 Mnemonic.startswith("vorn") || Mnemonic.startswith("vorr") ||
11294 Mnemonic.startswith("vand") || Mnemonic.startswith("vmul") ||
11295 Mnemonic.startswith("vqrdmulh") || Mnemonic.startswith("vqdmulh") ||
11296 Mnemonic.startswith("vsub") || Mnemonic.startswith("vadd") ||
11297 Mnemonic.startswith("vqsub") || Mnemonic.startswith("vqadd") ||
11298 Mnemonic.startswith("vabd") || Mnemonic.startswith("vrhadd") ||
11299 Mnemonic.startswith("vhsub") || Mnemonic.startswith("vhadd") ||
11300 Mnemonic.startswith("vdup") || Mnemonic.startswith("vcls") ||
11301 Mnemonic.startswith("vclz") || Mnemonic.startswith("vneg") ||
11302 Mnemonic.startswith("vabs") || Mnemonic.startswith("vqneg") ||
11303 Mnemonic.startswith("vqabs") ||
11304 (Mnemonic.startswith("vrint") && Mnemonic != "vrintr") ||
11305 Mnemonic.startswith("vcmla") || Mnemonic.startswith("vfma") ||
11306 Mnemonic.startswith("vfms") || Mnemonic.startswith("vcadd") ||
11307 Mnemonic.startswith("vadd") || Mnemonic.startswith("vsub") ||
11308 Mnemonic.startswith("vshl") || Mnemonic.startswith("vqshl") ||
11309 Mnemonic.startswith("vqrshl") || Mnemonic.startswith("vrshl") ||
11310 Mnemonic.startswith("vsri") || Mnemonic.startswith("vsli") ||
11311 Mnemonic.startswith("vrshr") || Mnemonic.startswith("vshr") ||
11312 Mnemonic.startswith("vpsel") || Mnemonic.startswith("vcmp") ||
11313 Mnemonic.startswith("vqdmladh") || Mnemonic.startswith("vqrdmladh") ||
11314 Mnemonic.startswith("vqdmlsdh") || Mnemonic.startswith("vqrdmlsdh") ||
11315 Mnemonic.startswith("vcmul") || Mnemonic.startswith("vrmulh") ||
11316 Mnemonic.startswith("vqmovn") || Mnemonic.startswith("vqmovun") ||
11317 Mnemonic.startswith("vmovnt") || Mnemonic.startswith("vmovnb") ||
11318 Mnemonic.startswith("vmaxa") || Mnemonic.startswith("vmaxnma") ||
11319 Mnemonic.startswith("vhcadd") || Mnemonic.startswith("vadc") ||
11320 Mnemonic.startswith("vsbc") || Mnemonic.startswith("vrshr") ||
11321 Mnemonic.startswith("vshr") || Mnemonic.startswith("vstrb") ||
11322 Mnemonic.startswith("vldrb") ||
11323 (Mnemonic.startswith("vstrh") && Mnemonic != "vstrhi") ||
11324 (Mnemonic.startswith("vldrh") && Mnemonic != "vldrhi") ||
11325 Mnemonic.startswith("vstrw") || Mnemonic.startswith("vldrw") ||
11326 Mnemonic.startswith("vldrd") || Mnemonic.startswith("vstrd") ||
11327 Mnemonic.startswith("vqdmull") || Mnemonic.startswith("vbrsr") ||
11328 Mnemonic.startswith("vfmas") || Mnemonic.startswith("vmlas") ||
11329 Mnemonic.startswith("vmla") || Mnemonic.startswith("vqdmlash") ||
11330 Mnemonic.startswith("vqdmlah") || Mnemonic.startswith("vqrdmlash") ||
11331 Mnemonic.startswith("vqrdmlah") || Mnemonic.startswith("viwdup") ||
11332 Mnemonic.startswith("vdwdup") || Mnemonic.startswith("vidup") ||
11333 Mnemonic.startswith("vddup") || Mnemonic.startswith("vctp") ||
11334 Mnemonic.startswith("vpnot") || Mnemonic.startswith("vbic") ||
11335 Mnemonic.startswith("vrmlsldavh") || Mnemonic.startswith("vmlsldav") ||
11336 Mnemonic.startswith("vcvt") ||
11337 (Mnemonic.startswith("vmov") &&
11338 !(ExtraToken == ".f16" || ExtraToken == ".32" ||
11339 ExtraToken == ".16" || ExtraToken == ".8"));
11340 }
55 //
66 //===----------------------------------------------------------------------===//
77
8 #include "ARMBaseInstrInfo.h"
89 #include "MCTargetDesc/ARMAddressingModes.h"
910 #include "MCTargetDesc/ARMBaseInfo.h"
1011 #include "MCTargetDesc/ARMMCTargetDesc.h"
8384 std::vector ITStates;
8485 };
8586
87 class VPTStatus
88 {
89 public:
90 unsigned getVPTPred() {
91 unsigned Pred = ARMVCC::None;
92 if (instrInVPTBlock())
93 Pred = VPTStates.back();
94 return Pred;
95 }
96
97 void advanceVPTState() {
98 VPTStates.pop_back();
99 }
100
101 bool instrInVPTBlock() {
102 return !VPTStates.empty();
103 }
104
105 bool instrLastInVPTBlock() {
106 return VPTStates.size() == 1;
107 }
108
109 void setVPTState(char Mask) {
110 // (3 - the number of trailing zeros) is the number of then / else.
111 unsigned NumTZ = countTrailingZeros(Mask);
112 assert(NumTZ <= 3 && "Invalid VPT mask!");
113 // push predicates onto the stack the correct order for the pops
114 for (unsigned Pos = NumTZ+1; Pos <= 3; ++Pos) {
115 bool T = ((Mask >> Pos) & 1) == 0;
116 if (T)
117 VPTStates.push_back(ARMVCC::Then);
118 else
119 VPTStates.push_back(ARMVCC::Else);
120 }
121 VPTStates.push_back(ARMVCC::Then);
122 }
123
124 private:
125 SmallVector VPTStates;
126 };
127
86128 /// ARM disassembler for all ARM platforms.
87129 class ARMDisassembler : public MCDisassembler {
88130 public:
114156
115157 private:
116158 mutable ITStatus ITBlock;
159 mutable VPTStatus VPTBlock;
117160
118161 DecodeStatus AddThumbPredicate(MCInst&) const;
119162 void UpdateThumbVFPPredicate(DecodeStatus &, MCInst&) const;
179222 const void *Decoder);
180223 static DecodeStatus DecodeQPRRegisterClass(MCInst &Inst, unsigned RegNo,
181224 uint64_t Address, const void *Decoder);
225 static DecodeStatus DecodeMQPRRegisterClass(MCInst &Inst, unsigned RegNo,
226 uint64_t Address, const void *Decoder);
182227 static DecodeStatus DecodeDPairRegisterClass(MCInst &Inst, unsigned RegNo,
183228 uint64_t Address, const void *Decoder);
184229 static DecodeStatus DecodeDPairSpacedRegisterClass(MCInst &Inst,
437482 const void *Decoder);
438483 static DecodeStatus DecodeVSCCLRM(MCInst &Inst, unsigned Insn, uint64_t Address,
439484 const void *Decoder);
485 static DecodeStatus DecodeVPTMaskOperand(MCInst &Inst, unsigned Val,
486 uint64_t Address, const void *Decoder);
487 static DecodeStatus DecodeVpredROperand(MCInst &Inst, unsigned Val,
488 uint64_t Address, const void *Decoder);
489 static DecodeStatus DecodeRestrictedIPredicateOperand(MCInst &Inst, unsigned Val,
490 uint64_t Address,
491 const void *Decoder);
492 static DecodeStatus DecodeRestrictedSPredicateOperand(MCInst &Inst, unsigned Val,
493 uint64_t Address,
494 const void *Decoder);
495 static DecodeStatus DecodeRestrictedUPredicateOperand(MCInst &Inst, unsigned Val,
496 uint64_t Address,
497 const void *Decoder);
498 static DecodeStatus DecodeRestrictedFPPredicateOperand(MCInst &Inst,
499 unsigned Val,
500 uint64_t Address,
501 const void *Decoder);
440502 template
441503 static DecodeStatus DecodeVSTRVLDR_SYSREG(MCInst &Inst, unsigned Insn,
442504 uint64_t Address,
616678 MI.insert(I, MCOperand::createReg(InITBlock ? 0 : ARM::CPSR));
617679 }
618680
681 static bool isVectorPredicable(unsigned Opcode) {
682 const MCOperandInfo *OpInfo = ARMInsts[Opcode].OpInfo;
683 unsigned short NumOps = ARMInsts[Opcode].NumOperands;
684 for (unsigned i = 0; i < NumOps; ++i) {
685 if (ARM::isVpred(OpInfo[i].OperandType))
686 return true;
687 }
688 return false;
689 }
690
619691 // Most Thumb instructions don't have explicit predicates in the
620692 // encoding, but rather get their predicates from IT context. We need
621693 // to fix up the predicate operands using this context information as a
667739 break;
668740 }
669741
670 // If we're in an IT block, base the predicate on that. Otherwise,
742 // Warn on non-VPT predicable instruction in a VPT block and a VPT
743 // predicable instruction in an IT block
744 if ((!isVectorPredicable(MI.getOpcode()) && VPTBlock.instrInVPTBlock()) ||
745 (isVectorPredicable(MI.getOpcode()) && ITBlock.instrInITBlock()))
746 S = SoftFail;
747
748 // If we're in an IT/VPT block, base the predicate on that. Otherwise,
671749 // assume a predicate of AL.
672 unsigned CC;
673 CC = ITBlock.getITCC();
674 if (CC == 0xF)
675 CC = ARMCC::AL;
676 if (ITBlock.instrInITBlock())
750 unsigned CC = ARMCC::AL;
751 unsigned VCC = ARMVCC::None;
752 if (ITBlock.instrInITBlock()) {
753 CC = ITBlock.getITCC();
677754 ITBlock.advanceITState();
755 } else if (VPTBlock.instrInVPTBlock()) {
756 VCC = VPTBlock.getVPTPred();
757 VPTBlock.advanceVPTState();
758 }
678759
679760 const MCOperandInfo *OpInfo = ARMInsts[MI.getOpcode()].OpInfo;
680761 unsigned short NumOps = ARMInsts[MI.getOpcode()].NumOperands;
681 MCInst::iterator I = MI.begin();
682 for (unsigned i = 0; i < NumOps; ++i, ++I) {
683 if (I == MI.end()) break;
684 if (OpInfo[i].isPredicate()) {
685 if (CC != ARMCC::AL && !ARMInsts[MI.getOpcode()].isPredicable())
686 Check(S, SoftFail);
687 I = MI.insert(I, MCOperand::createImm(CC));
688 ++I;
689 if (CC == ARMCC::AL)
690 MI.insert(I, MCOperand::createReg(0));
691 else
692 MI.insert(I, MCOperand::createReg(ARM::CPSR));
693 return S;
762
763 MCInst::iterator CCI = MI.begin();
764 for (unsigned i = 0; i < NumOps; ++i, ++CCI) {
765 if (OpInfo[i].isPredicate() || CCI == MI.end()) break;
766 }
767
768 if (ARMInsts[MI.getOpcode()].isPredicable()) {
769 CCI = MI.insert(CCI, MCOperand::createImm(CC));
770 ++CCI;
771 if (CC == ARMCC::AL)
772 MI.insert(CCI, MCOperand::createReg(0));
773 else
774 MI.insert(CCI, MCOperand::createReg(ARM::CPSR));
775 } else if (CC != ARMCC::AL) {
776 Check(S, SoftFail);
777 }
778
779 MCInst::iterator VCCI = MI.begin();
780 unsigned VCCPos;
781 for (VCCPos = 0; VCCPos < NumOps; ++VCCPos, ++VCCI) {
782 if (ARM::isVpred(OpInfo[VCCPos].OperandType) || VCCI == MI.end()) break;
783 }
784
785 if (isVectorPredicable(MI.getOpcode())) {
786 VCCI = MI.insert(VCCI, MCOperand::createImm(VCC));
787 ++VCCI;
788 if (VCC == ARMVCC::None)
789 MI.insert(VCCI, MCOperand::createReg(0));
790 else
791 MI.insert(VCCI, MCOperand::createReg(ARM::P0));
792 if (OpInfo[VCCPos].OperandType == ARM::OPERAND_VPRED_R) {
793 int TiedOp = ARMInsts[MI.getOpcode()].getOperandConstraint(
794 VCCPos + 2, MCOI::TIED_TO);
795 assert(TiedOp >= 0 &&
796 "Inactive register in vpred_r is not tied to an output!");
797 MI.insert(VCCI, MI.getOperand(TiedOp));
694798 }
695 }
696
697 I = MI.insert(I, MCOperand::createImm(CC));
698 ++I;
699 if (CC == ARMCC::AL)
700 MI.insert(I, MCOperand::createReg(0));
701 else
702 MI.insert(I, MCOperand::createReg(ARM::CPSR));
799 } else if (VCC != ARMVCC::None) {
800 Check(S, SoftFail);
801 }
703802
704803 return S;
705804 }
717816 CC = ARMCC::AL;
718817 if (ITBlock.instrInITBlock())
719818 ITBlock.advanceITState();
819 else if (VPTBlock.instrInVPTBlock()) {
820 CC = VPTBlock.getVPTPred();
821 VPTBlock.advanceVPTState();
822 }
720823
721824 const MCOperandInfo *OpInfo = ARMInsts[MI.getOpcode()].OpInfo;
722825 MCInst::iterator I = MI.begin();
812915 decodeInstruction(DecoderTableMVE32, MI, Insn32, Address, this, STI);
813916 if (Result != MCDisassembler::Fail) {
814917 Size = 4;
918
919 // Nested VPT blocks are UNPREDICTABLE. Must be checked before we add
920 // the VPT predicate.
921 if (isVPTOpcode(MI.getOpcode()) && VPTBlock.instrInVPTBlock())
922 Result = MCDisassembler::SoftFail;
923
815924 Check(Result, AddThumbPredicate(MI));
925
926 if (isVPTOpcode(MI.getOpcode())) {
927 unsigned Mask = MI.getOperand(0).getImm();
928 VPTBlock.setVPTState(Mask);
929 }
930
816931 return Result;
817932 }
818933
57275842 return S;
57285843 }
57295844
5845 static DecodeStatus DecodeMQPRRegisterClass(MCInst &Inst, unsigned RegNo,
5846 uint64_t Address,
5847 const void *Decoder) {
5848 if (RegNo > 7)
5849 return MCDisassembler::Fail;
5850
5851 unsigned Register = QPRDecoderTable[RegNo];
5852 Inst.addOperand(MCOperand::createReg(Register));
5853 return MCDisassembler::Success;
5854 }
5855
5856 static DecodeStatus DecodeVPTMaskOperand(MCInst &Inst, unsigned Val,
5857 uint64_t Address,
5858 const void *Decoder) {
5859 DecodeStatus S = MCDisassembler::Success;
5860
5861 // Parse VPT mask and encode it in the MCInst as an immediate with the same
5862 // format as the it_mask. That is, from the second 'e|t' encode 'e' as 1 and
5863 // 't' as 0 and finish with a 1.
5864 unsigned Imm = 0;
5865 // We always start with a 't'.
5866 unsigned CurBit = 0;
5867 for (int i = 3; i >= 0; --i) {
5868 // If the bit we are looking at is not the same as last one, invert the
5869 // CurBit, if it is the same leave it as is.
5870 CurBit ^= (Val >> i) & 1U;
5871
5872 // Encode the CurBit at the right place in the immediate.
5873 Imm |= (CurBit << i);
5874
5875 // If we are done, finish the encoding with a 1.
5876 if ((Val & ~(~0U << i)) == 0) {
5877 Imm |= 1U << i;
5878 break;
5879 }
5880 }
5881
5882 Inst.addOperand(MCOperand::createImm(Imm));
5883
5884 return S;
5885 }
5886
5887 static DecodeStatus DecodeVpredROperand(MCInst &Inst, unsigned RegNo,
5888 uint64_t Address, const void *Decoder) {
5889 // The vpred_r operand type includes an MQPR register field derived
5890 // from the encoding. But we don't actually want to add an operand
5891 // to the MCInst at this stage, because AddThumbPredicate will do it
5892 // later, and will infer the register number from the TIED_TO
5893 // constraint. So this is a deliberately empty decoder method that
5894 // will inhibit the auto-generated disassembly code from adding an
5895 // operand at all.
5896 return MCDisassembler::Success;
5897 }
5898
5899 static DecodeStatus DecodeRestrictedIPredicateOperand(MCInst &Inst,
5900 unsigned Val,
5901 uint64_t Address,
5902 const void *Decoder) {
5903 Inst.addOperand(MCOperand::createImm((Val & 0x1) == 0 ? ARMCC::EQ : ARMCC::NE));
5904 return MCDisassembler::Success;
5905 }
5906
5907 static DecodeStatus DecodeRestrictedSPredicateOperand(MCInst &Inst,
5908 unsigned Val,
5909 uint64_t Address,
5910 const void *Decoder) {
5911 unsigned Code;
5912 switch (Val & 0x3) {
5913 case 0:
5914 Code = ARMCC::GE;
5915 break;
5916 case 1:
5917 Code = ARMCC::LT;
5918 break;
5919 case 2:
5920 Code = ARMCC::GT;
5921 break;
5922 case 3:
5923 Code = ARMCC::LE;
5924 break;
5925 }
5926 Inst.addOperand(MCOperand::createImm(Code));
5927 return MCDisassembler::Success;
5928 }
5929
5930 static DecodeStatus DecodeRestrictedUPredicateOperand(MCInst &Inst,
5931 unsigned Val,
5932 uint64_t Address,
5933 const void *Decoder) {
5934 Inst.addOperand(MCOperand::createImm((Val & 0x1) == 0 ? ARMCC::HS : ARMCC::HI));
5935 return MCDisassembler::Success;
5936 }
5937
5938 static DecodeStatus DecodeRestrictedFPPredicateOperand(MCInst &Inst, unsigned Val,
5939 uint64_t Address,
5940 const void *Decoder) {
5941 unsigned Code;
5942 switch (Val) {
5943 default:
5944 return MCDisassembler::Fail;
5945 case 0:
5946 Code = ARMCC::EQ;
5947 break;
5948 case 1:
5949 Code = ARMCC::NE;
5950 break;
5951 case 4:
5952 Code = ARMCC::GE;
5953 break;
5954 case 5:
5955 Code = ARMCC::LT;
5956 break;
5957 case 6:
5958 Code = ARMCC::GT;
5959 break;
5960 case 7:
5961 Code = ARMCC::LE;
5962 break;
5963 }
5964
5965 Inst.addOperand(MCOperand::createImm(Code));
5966 return MCDisassembler::Success;
5967 }
5968
57305969 static unsigned FixedRegForVSTRVLDR_SYSREG(unsigned Opcode) {
57315970 switch (Opcode) {
57325971 case ARM::VSTR_P0_off:
15951595 O << "#" << (Val * Angle) + Remainder;
15961596 }
15971597
1598 void ARMInstPrinter::printVPTPredicateOperand(const MCInst *MI, unsigned OpNum,
1599 const MCSubtargetInfo &STI,
1600 raw_ostream &O) {
1601 ARMVCC::VPTCodes CC = (ARMVCC::VPTCodes)MI->getOperand(OpNum).getImm();
1602 if (CC != ARMVCC::None)
1603 O << ARMVPTPredToString(CC);
1604 }
1605
1606 void ARMInstPrinter::printVPTMask(const MCInst *MI, unsigned OpNum,
1607 const MCSubtargetInfo &STI,
1608 raw_ostream &O) {
1609 // (3 - the number of trailing zeroes) is the number of them / else.
1610 unsigned Mask = MI->getOperand(OpNum).getImm();
1611 unsigned NumTZ = countTrailingZeros(Mask);
1612 assert(NumTZ <= 3 && "Invalid VPT mask!");
1613 for (unsigned Pos = 3, e = NumTZ; Pos > e; --Pos) {
1614 bool T = ((Mask >> Pos) & 1) == 0;
1615 if (T)
1616 O << 't';
1617 else
1618 O << 'e';
1619 }
1620 }
1621
245245 template
246246 void printComplexRotationOp(const MCInst *MI, unsigned OpNum,
247247 const MCSubtargetInfo &STI, raw_ostream &O);
248 // MVE
249 void printVPTPredicateOperand(const MCInst *MI, unsigned OpNum,
250 const MCSubtargetInfo &STI,
251 raw_ostream &O);
252 void printVPTMask(const MCInst *MI, unsigned OpNum,
253 const MCSubtargetInfo &STI, raw_ostream &O);
248254
249255 private:
250256 unsigned DefaultAltIdx = ARM::NoRegAltName;
433433 uint32_t getBFAfterTargetOpValue(const MCInst &MI, unsigned OpIdx,
434434 SmallVectorImpl &Fixups,
435435 const MCSubtargetInfo &STI) const;
436
437 uint32_t getVPTMaskOpValue(const MCInst &MI, unsigned OpIdx,
438 SmallVectorImpl &Fixups,
439 const MCSubtargetInfo &STI) const;
440 uint32_t getRestrictedCondCodeOpValue(const MCInst &MI, unsigned OpIdx,
441 SmallVectorImpl &Fixups,
442 const MCSubtargetInfo &STI) const;
436443 };
437444
438445 } // end anonymous namespace
519526 unsigned Reg = MO.getReg();
520527 unsigned RegNo = CTX.getRegisterInfo()->getEncodingValue(Reg);
521528
522 // Q registers are encoded as 2x their register number.
529 // In NEON, Q registers are encoded as 2x their register number,
530 // because they're using the same indices as the D registers they
531 // overlap. In MVE, there are no 64-bit vector instructions, so
532 // the encodings all refer to Q-registers by their literal
533 // register number.
534
535 if (STI.getFeatureBits()[ARM::HasMVEIntegerOps])
536 return RegNo;
537
523538 switch (Reg) {
524539 default:
525540 return RegNo;
17881803
17891804 return Diff == 4;
17901805 }
1806
1807 uint32_t ARMMCCodeEmitter::getVPTMaskOpValue(const MCInst &MI, unsigned OpIdx,
1808 SmallVectorImpl &Fixups,
1809 const MCSubtargetInfo &STI)const {
1810 const MCOperand MO = MI.getOperand(OpIdx);
1811 assert(MO.isImm() && "Unexpected operand type!");
1812
1813 int Value = MO.getImm();
1814 int Imm = 0;
1815
1816 // VPT Masks are actually encoded as a series of invert/don't invert bits,
1817 // rather than true/false bits.
1818 unsigned PrevBit = 0;
1819 for (int i = 3; i >= 0; --i) {
1820 unsigned Bit = (Value >> i) & 1;
1821
1822 // Check if we are at the end of the mask.
1823 if ((Value & ~(~0U << i)) == 0) {
1824 Imm |= (1 << i);
1825 break;
1826 }
1827
1828 // Convert the bit in the mask based on the previous bit.
1829 if (Bit != PrevBit)
1830 Imm |= (1 << i);
1831
1832 PrevBit = Bit;
1833 }
1834
1835 return Imm;
1836 }
1837
1838 uint32_t ARMMCCodeEmitter::getRestrictedCondCodeOpValue(
1839 const MCInst &MI, unsigned OpIdx, SmallVectorImpl &Fixups,
1840 const MCSubtargetInfo &STI) const {
1841
1842 const MCOperand MO = MI.getOperand(OpIdx);
1843 assert(MO.isImm() && "Unexpected operand type!");
1844
1845 switch (MO.getImm()) {
1846 default:
1847 assert(0 && "Unexpected Condition!");
1848 return 0;
1849 case ARMCC::HS:
1850 case ARMCC::EQ:
1851 return 0;
1852 case ARMCC::HI:
1853 case ARMCC::NE:
1854 return 1;
1855 case ARMCC::GE:
1856 return 4;
1857 case ARMCC::LT:
1858 return 5;
1859 case ARMCC::GT:
1860 return 6;
1861 case ARMCC::LE:
1862 return 7;
1863 }
1864 }
1865
17911866 #include "ARMGenMCCodeEmitter.inc"
17921867
17931868 MCCodeEmitter *llvm::createARMLEMCCodeEmitter(const MCInstrInfo &MCII,
1313 #define LLVM_LIB_TARGET_ARM_MCTARGETDESC_ARMMCTARGETDESC_H
1414
1515 #include "llvm/Support/DataTypes.h"
16 #include "llvm/MC/MCInstrDesc.h"
1617 #include
1718 #include
1819
9394
9495 /// Construct ARM Mach-O relocation info.
9596 MCRelocationInfo *createARMMachORelocationInfo(MCContext &Ctx);
97
98 namespace ARM {
99 enum OperandType {
100 OPERAND_VPRED_R = MCOI::OPERAND_FIRST_TARGET,
101 OPERAND_VPRED_N,
102 };
103 inline bool isVpred(OperandType op) {
104 return op == OPERAND_VPRED_R || op == OPERAND_VPRED_N;
105 }
106 inline bool isVpred(uint8_t op) {
107 return isVpred(static_cast(op));
108 }
109 } // end namespace ARM
110
96111 } // End llvm namespace
97112
98113 // Defines symbolic names for ARM registers. This defines a mapping from
6464 }
6565 }
6666 } // end namespace ARMCC
67
68 namespace ARMVCC {
69 enum VPTCodes {
70 None = 0,
71 Then,
72 Else
73 };
74 }
75
76 inline static const char *ARMVPTPredToString(ARMVCC::VPTCodes CC) {
77 switch (CC) {
78 case ARMVCC::None: return "none";
79 case ARMVCC::Then: return "t";
80 case ARMVCC::Else: return "e";
81 }
82 llvm_unreachable("Unknown VPT code");
83 }
84
85 inline static unsigned ARMVectorCondCodeFromString(StringRef CC) {
86 return StringSwitch(CC.lower())
87 .Case("t", ARMVCC::Then)
88 .Case("e", ARMVCC::Else)
89 .Default(~0U);
90 }
6791
6892 inline static const char *ARMCondCodeToString(ARMCC::CondCodes CC) {
6993 switch (CC) {
0 # RUN: not llvm-mc -triple=thumbv8.1m.main-none-eabi -mattr=+mve -show-encoding < %s 2> %t \
1 # RUN: | FileCheck --check-prefix=CHECK-NOFP %s
2 # RUN: FileCheck --check-prefix=ERROR-NOFP %s < %t
3 # RUN: llvm-mc -triple=thumbv8.1m.main-none-eabi -mattr=+mve.fp,+fp64 -show-encoding < %s \
4 # RUN: | FileCheck --check-prefix=CHECK %s
5
6 # CHECK: vmaxnm.f32 q0, q1, q4 @ encoding: [0x02,0xff,0x58,0x0f]
7 # CHECK-NOFP-NOT: vmaxnm.f32 q0, q1, q4 @ encoding: [0x02,0xff,0x58,0x0f]
8 # ERROR-NOFP: [[@LINE+1]]:{{[0-9]+}}: error: instruction requires: mve.fp
9 vmaxnm.f32 q0, q1, q4
10
11 # CHECK: vminnm.f16 q3, q0, q1 @ encoding: [0x30,0xff,0x52,0x6f]
12 # CHECK-NOFP-NOT: vminnm.f16 q3, q0, q1 @ encoding: [0x30,0xff,0x52,0x6f]
13 # ERROR-NOFP: [[@LINE+1]]:{{[0-9]+}}: error: instruction requires: mve.fp
14 vminnm.f16 q3, q0, q1
0 # RUN: llvm-mc -triple=thumbv8.1m.main-none-eabi -mattr=+mve -show-encoding < %s \
1 # RUN: | FileCheck --check-prefix=CHECK-NOFP %s
2 # RUN: llvm-mc -triple=thumbv8.1m.main-none-eabi -mattr=+mve.fp,+fp64 -show-encoding < %s \
3 # RUN: | FileCheck --check-prefix=CHECK %s
4
5 # CHECK: vabav.s8 r0, q1, q3 @ encoding: [0x82,0xee,0x07,0x0f]
6 # CHECK-NOFP: vabav.s8 r0, q1, q3 @ encoding: [0x82,0xee,0x07,0x0f]
7 vabav.s8 r0, q1, q3
8
9 # CHECK: vabav.s16 r0, q1, q3 @ encoding: [0x92,0xee,0x07,0x0f]
10 # CHECK-NOFP: vabav.s16 r0, q1, q3 @ encoding: [0x92,0xee,0x07,0x0f]
11 vabav.s16 r0, q1, q3
12
13 # CHECK: vabav.s32 r0, q1, q3 @ encoding: [0xa2,0xee,0x07,0x0f]
14 # CHECK-NOFP: vabav.s32 r0, q1, q3 @ encoding: [0xa2,0xee,0x07,0x0f]
15 vabav.s32 r0, q1, q3
16
17 # CHECK: vabav.u8 r0, q1, q3 @ encoding: [0x82,0xfe,0x07,0x0f]
18 # CHECK-NOFP: vabav.u8 r0, q1, q3 @ encoding: [0x82,0xfe,0x07,0x0f]
19 vabav.u8 r0, q1, q3
20
21 # CHECK: vabav.u16 r0, q1, q3 @ encoding: [0x92,0xfe,0x07,0x0f]
22 # CHECK-NOFP: vabav.u16 r0, q1, q3 @ encoding: [0x92,0xfe,0x07,0x0f]
23 vabav.u16 r0, q1, q3
24
25 # CHECK: vabav.u32 r0, q1, q3 @ encoding: [0xa2,0xfe,0x07,0x0f]
26 # CHECK-NOFP: vabav.u32 r0, q1, q3 @ encoding: [0xa2,0xfe,0x07,0x0f]
27 vabav.u32 r0, q1, q3
0 # RUN: not llvm-mc -triple=thumbv8.1m.main-none-eabi -mattr=+mve -show-encoding < %s \
1 # RUN: | FileCheck --check-prefix=CHECK-NOFP %s
2 # RUN: not llvm-mc -triple=thumbv8.1m.main-none-eabi -mattr=+mve.fp,+fp64 -show-encoding < %s 2>%t \
3 # RUN: | FileCheck --check-prefix=CHECK %s
4 # RUN: FileCheck --check-prefix=ERROR < %t %s
5
6 # ERROR: [[@LINE+1]]:{{[0-9]+}}: {{error|note}}: VPT predicated instructions must be in VPT block
7 vabavt.s32 lr, q1, q3
8
9 # ERROR: [[@LINE+1]]:{{[0-9]+}}: {{error|note}}: VPT predicated instructions must be in VPT block
10 vabave.u8 r12, q1, q3
11
12 # ERROR: [[@LINE+2]]:{{[0-9]+}}: {{error|note}}: instructions in IT block must be predicable
13 it eq
14 vabav.s16 lr, q1, q3
15
16 # CHECK: vpteee.i8 eq, q0, q1 @ encoding: [0x41,0xfe,0x02,0x2f]
17 # CHECK-NOFP: vpteee.i8 eq, q0, q1 @ encoding: [0x41,0xfe,0x02,0x2f]
18 vpteee.i8 eq, q0, q1
19 vabavt.s32 lr, q1, q3
20 vabave.s32 lr, q1, q3
21 vabave.s32 lr, q1, q3
22 vabave.s32 lr, q1, q3
23
24 # CHECK: vptttt.s32 gt, q0, q1 @ encoding: [0x21,0xfe,0x03,0x3f]
25 # CHECK-NOFP: vptttt.s32 gt, q0, q1 @ encoding: [0x21,0xfe,0x03,0x3f]
26 vptttt.s32 gt, q0, q1
27 vabavt.u32 lr, q1, q3
28 vabavt.s32 lr, q1, q3
29 vabavt.s16 lr, q1, q3
30 vabavt.s8 lr, q1, q3
31
32 # ERROR: [[@LINE+2]]:{{[0-9]+}}: {{error|note}}: instruction in VPT block must be predicable
33 vpt.s8 le, q0, q1
34 cinc lr, r2, lo
35
36 # ----------------------------------------------------------------------
37 # The following tests have to go last because of the NOFP-NOT checks inside the
38 # VPT block.
39
40 # CHECK: vptete.f16 ne, q0, q1 @ encoding: [0x71,0xfe,0x82,0xef]
41 # CHECK-NOFP-NOT: vptete.f16 ne, q0, q1 @ encoding: [0x71,0xfe,0x82,0xef]
42 vptete.f16 ne, q0, q1
43 vabavt.s32 lr, q1, q3
44 vabave.u32 lr, q1, q3
45 vabavt.s32 lr, q1, q3
46 vabave.s16 lr, q1, q3
47 # ERROR: [[@LINE+1]]:{{[0-9]+}}: {{error|note}}: VPT predicated instructions must be in VPT block
48 vabavt.s32 lr, q1, q3
49
50 # CHECK: vpte.i8 eq, q0, q0
51 # CHECK: vmaxnmt.f16 q1, q6, q2 @ encoding: [0x1c,0xff,0x54,0x2f]
52 # CHECK-NOFP-NOT: vmaxnmt.f16 q1, q6, q2 @ encoding: [0x1c,0xff,0x54,0x2f]
53 # CHECK-NOFP-NOT: vmaxnme.f16 q1, q6, q2 @ encoding: [0x1c,0xff,0x54,0x2f]
54 vpte.i8 eq, q0, q0
55 vmaxnmt.f16 q1, q6, q2
56 vmaxnme.f16 q1, q6, q2
0 # RUN: llvm-mc -disassemble -triple=thumbv8.1m.main-none-eabi -mattr=+mve.fp,+fp64 -show-encoding %s | FileCheck %s
1 # RUN: not llvm-mc -disassemble -triple=thumbv8.1m.main-none-eabi -show-encoding %s &> %t
2 # RUN: FileCheck --check-prefix=CHECK-NOMVE < %t %s
3
4 # CHECK: vmaxnm.f32 q0, q1, q4 @ encoding: [0x02,0xff,0x58,0x0f]
5 # CHECK-NOMVE: [[@LINE+1]]:2: warning: invalid instruction encoding
6 [0x02,0xff,0x58,0x0f]
7
8 # CHECK: vminnm.f16 q3, q0, q1 @ encoding: [0x30,0xff,0x52,0x6f]
9 # CHECK-NOMVE: [[@LINE+1]]:2: warning: invalid instruction encoding
10 [0x30,0xff,0x52,0x6f]
0 # RUN: llvm-mc -disassemble -triple=thumbv8.1m.main-none-eabi -mattr=+mve.fp,+fp64 -show-encoding %s | FileCheck %s
1 # RUN: not llvm-mc -disassemble -triple=thumbv8.1m.main-none-eabi -show-encoding %s &> %t
2 # RUN: FileCheck --check-prefix=CHECK-NOMVE < %t %s
3
4 [0x82 0xee 0x07 0x0f]
5 # CHECK: vabav.s8 r0, q1, q3
6 # CHECK-NOMVE: [[@LINE-2]]:2: warning: invalid instruction encoding
7
8 [0x92 0xee 0x07 0x0f]
9 # CHECK: vabav.s16 r0, q1, q3
10 # CHECK-NOMVE: [[@LINE-2]]:2: warning: invalid instruction encoding
11
12 [0xa2 0xee 0x07 0x0f]
13 # CHECK: vabav.s32 r0, q1, q3
14 # CHECK-NOMVE: [[@LINE-2]]:2: warning: invalid instruction encoding
15
16 [0x82 0xfe 0x07 0x0f]
17 # CHECK: vabav.u8 r0, q1, q3
18 # CHECK-NOMVE: [[@LINE-2]]:2: warning: invalid instruction encoding
19
20 [0x92 0xfe 0x07 0x0f]
21 # CHECK: vabav.u16 r0, q1, q3
22 # CHECK-NOMVE: [[@LINE-2]]:2: warning: invalid instruction encoding
23
24 [0xa2 0xfe 0x07 0x0f]
25 # CHECK: vabav.u32 r0, q1, q3
26 # CHECK-NOMVE: [[@LINE-2]]:2: warning: invalid instruction encoding
0 # RUN: llvm-mc -disassemble -triple=thumbv8.1m.main-none-eabi -mattr=+mve.fp,+fp64 -show-encoding %s | FileCheck %s
1 # RUN: not llvm-mc -disassemble -triple=thumbv8.1m.main-none-eabi -show-encoding %s &> %t
2 # RUN: FileCheck --check-prefix=CHECK-NOMVE < %t %s
3
4 # CHECK: vpte.i8 eq, q0, q0 @ encoding: [0x41,0xfe,0x00,0x8f]
5 # CHECK-NOMVE: [[@LINE+5]]:2: warning: invalid instruction encoding
6 # CHECK: vabavt.s16 lr, q3, q4 @ encoding: [0x96,0xee,0x09,0xef]
7 # CHECK-NOMVE: [[@LINE+4]]:2: warning: invalid instruction encoding
8 # CHECK: vabave.s16 lr, q3, q4 @ encoding: [0x96,0xee,0x09,0xef]
9 # CHECK-NOMVE: [[@LINE+3]]:2: warning: invalid instruction encoding
10 [0x41,0xfe,0x00,0x8f]
11 [0x96,0xee,0x09,0xef]
12 [0x96,0xee,0x09,0xef]