LLVM 20.0.0git
ARMInstPrinter.cpp
Go to the documentation of this file.
1//===-- ARMInstPrinter.cpp - Convert ARM MCInst to assembly syntax --------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This class prints an ARM MCInst to a .s file.
10//
11//===----------------------------------------------------------------------===//
12
13#include "ARMInstPrinter.h"
16#include "Utils/ARMBaseInfo.h"
17#include "llvm/MC/MCAsmInfo.h"
18#include "llvm/MC/MCExpr.h"
19#include "llvm/MC/MCInst.h"
21#include "llvm/MC/MCInstrInfo.h"
28#include <cassert>
29#include <cstdint>
30
31using namespace llvm;
32
33#define DEBUG_TYPE "asm-printer"
34
35#define PRINT_ALIAS_INSTR
36#include "ARMGenAsmWriter.inc"
37
38/// translateShiftImm - Convert shift immediate from 0-31 to 1-32 for printing.
39///
40/// getSORegOffset returns an integer from 0-31, representing '32' as 0.
41static unsigned translateShiftImm(unsigned imm) {
42 // lsr #32 and asr #32 exist, but should be encoded as a 0.
43 assert((imm & ~0x1f) == 0 && "Invalid shift encoding");
44
45 if (imm == 0)
46 return 32;
47 return imm;
48}
49
51 unsigned ShImm, ARMInstPrinter &printer) {
52 if (ShOpc == ARM_AM::no_shift || (ShOpc == ARM_AM::lsl && !ShImm))
53 return;
54 O << ", ";
55
56 assert(!(ShOpc == ARM_AM::ror && !ShImm) && "Cannot have ror #0");
57 O << getShiftOpcStr(ShOpc);
58
59 if (ShOpc != ARM_AM::rrx) {
60 O << " ";
62 << "#" << translateShiftImm(ShImm);
63 }
64}
65
67 const MCRegisterInfo &MRI)
68 : MCInstPrinter(MAI, MII, MRI) {}
69
71 if (Opt == "reg-names-std") {
72 DefaultAltIdx = ARM::NoRegAltName;
73 return true;
74 }
75 if (Opt == "reg-names-raw") {
76 DefaultAltIdx = ARM::RegNamesRaw;
77 return true;
78 }
79 return false;
80}
81
83 markup(OS, Markup::Register) << getRegisterName(Reg, DefaultAltIdx);
84}
85
87 StringRef Annot, const MCSubtargetInfo &STI,
88 raw_ostream &O) {
89 unsigned Opcode = MI->getOpcode();
90
91 switch (Opcode) {
92 case ARM::VLLDM: {
93 const MCOperand &Reg = MI->getOperand(0);
94 O << '\t' << "vlldm" << '\t';
95 printRegName(O, Reg.getReg());
96 O << ", "
97 << "{d0 - d15}";
98 return;
99 }
100 case ARM::VLLDM_T2: {
101 const MCOperand &Reg = MI->getOperand(0);
102 O << '\t' << "vlldm" << '\t';
103 printRegName(O, Reg.getReg());
104 O << ", "
105 << "{d0 - d31}";
106 return;
107 }
108 case ARM::VLSTM: {
109 const MCOperand &Reg = MI->getOperand(0);
110 O << '\t' << "vlstm" << '\t';
111 printRegName(O, Reg.getReg());
112 O << ", "
113 << "{d0 - d15}";
114 return;
115 }
116 case ARM::VLSTM_T2: {
117 const MCOperand &Reg = MI->getOperand(0);
118 O << '\t' << "vlstm" << '\t';
119 printRegName(O, Reg.getReg());
120 O << ", "
121 << "{d0 - d31}";
122 return;
123 }
124 // Check for MOVs and print canonical forms, instead.
125 case ARM::MOVsr: {
126 // FIXME: Thumb variants?
127 const MCOperand &Dst = MI->getOperand(0);
128 const MCOperand &MO1 = MI->getOperand(1);
129 const MCOperand &MO2 = MI->getOperand(2);
130 const MCOperand &MO3 = MI->getOperand(3);
131
133 printSBitModifierOperand(MI, 6, STI, O);
134 printPredicateOperand(MI, 4, STI, O);
135
136 O << '\t';
137 printRegName(O, Dst.getReg());
138 O << ", ";
139 printRegName(O, MO1.getReg());
140
141 O << ", ";
142 printRegName(O, MO2.getReg());
144 printAnnotation(O, Annot);
145 return;
146 }
147
148 case ARM::MOVsi: {
149 // FIXME: Thumb variants?
150 const MCOperand &Dst = MI->getOperand(0);
151 const MCOperand &MO1 = MI->getOperand(1);
152 const MCOperand &MO2 = MI->getOperand(2);
153
155 printSBitModifierOperand(MI, 5, STI, O);
156 printPredicateOperand(MI, 3, STI, O);
157
158 O << '\t';
159 printRegName(O, Dst.getReg());
160 O << ", ";
161 printRegName(O, MO1.getReg());
162
164 printAnnotation(O, Annot);
165 return;
166 }
167
168 O << ", ";
171 printAnnotation(O, Annot);
172 return;
173 }
174
175 // A8.6.123 PUSH
176 case ARM::STMDB_UPD:
177 case ARM::t2STMDB_UPD:
178 if (MI->getOperand(0).getReg() == ARM::SP && MI->getNumOperands() > 5) {
179 // Should only print PUSH if there are at least two registers in the list.
180 O << '\t' << "push";
181 printPredicateOperand(MI, 2, STI, O);
182 if (Opcode == ARM::t2STMDB_UPD)
183 O << ".w";
184 O << '\t';
185 printRegisterList(MI, 4, STI, O);
186 printAnnotation(O, Annot);
187 return;
188 } else
189 break;
190
191 case ARM::STR_PRE_IMM:
192 if (MI->getOperand(2).getReg() == ARM::SP &&
193 MI->getOperand(3).getImm() == -4) {
194 O << '\t' << "push";
195 printPredicateOperand(MI, 4, STI, O);
196 O << "\t{";
197 printRegName(O, MI->getOperand(1).getReg());
198 O << "}";
199 printAnnotation(O, Annot);
200 return;
201 } else
202 break;
203
204 // A8.6.122 POP
205 case ARM::LDMIA_UPD:
206 case ARM::t2LDMIA_UPD:
207 if (MI->getOperand(0).getReg() == ARM::SP && MI->getNumOperands() > 5) {
208 // Should only print POP if there are at least two registers in the list.
209 O << '\t' << "pop";
210 printPredicateOperand(MI, 2, STI, O);
211 if (Opcode == ARM::t2LDMIA_UPD)
212 O << ".w";
213 O << '\t';
214 printRegisterList(MI, 4, STI, O);
215 printAnnotation(O, Annot);
216 return;
217 } else
218 break;
219
220 case ARM::LDR_POST_IMM:
221 if (MI->getOperand(2).getReg() == ARM::SP &&
222 MI->getOperand(4).getImm() == 4) {
223 O << '\t' << "pop";
224 printPredicateOperand(MI, 5, STI, O);
225 O << "\t{";
226 printRegName(O, MI->getOperand(0).getReg());
227 O << "}";
228 printAnnotation(O, Annot);
229 return;
230 } else
231 break;
232
233 // A8.6.355 VPUSH
234 case ARM::VSTMSDB_UPD:
235 case ARM::VSTMDDB_UPD:
236 if (MI->getOperand(0).getReg() == ARM::SP) {
237 O << '\t' << "vpush";
238 printPredicateOperand(MI, 2, STI, O);
239 O << '\t';
240 printRegisterList(MI, 4, STI, O);
241 printAnnotation(O, Annot);
242 return;
243 } else
244 break;
245
246 // A8.6.354 VPOP
247 case ARM::VLDMSIA_UPD:
248 case ARM::VLDMDIA_UPD:
249 if (MI->getOperand(0).getReg() == ARM::SP) {
250 O << '\t' << "vpop";
251 printPredicateOperand(MI, 2, STI, O);
252 O << '\t';
253 printRegisterList(MI, 4, STI, O);
254 printAnnotation(O, Annot);
255 return;
256 } else
257 break;
258
259 case ARM::tLDMIA: {
260 bool Writeback = true;
261 MCRegister BaseReg = MI->getOperand(0).getReg();
262 for (unsigned i = 3; i < MI->getNumOperands(); ++i) {
263 if (MI->getOperand(i).getReg() == BaseReg)
264 Writeback = false;
265 }
266
267 O << "\tldm";
268
269 printPredicateOperand(MI, 1, STI, O);
270 O << '\t';
271 printRegName(O, BaseReg);
272 if (Writeback)
273 O << "!";
274 O << ", ";
275 printRegisterList(MI, 3, STI, O);
276 printAnnotation(O, Annot);
277 return;
278 }
279
280 // Combine 2 GPRs from disassember into a GPRPair to match with instr def.
281 // ldrexd/strexd require even/odd GPR pair. To enforce this constraint,
282 // a single GPRPair reg operand is used in the .td file to replace the two
283 // GPRs. However, when decoding them, the two GRPs cannot be automatically
284 // expressed as a GPRPair, so we have to manually merge them.
285 // FIXME: We would really like to be able to tablegen'erate this.
286 case ARM::LDREXD:
287 case ARM::STREXD:
288 case ARM::LDAEXD:
289 case ARM::STLEXD: {
290 const MCRegisterClass &MRC = MRI.getRegClass(ARM::GPRRegClassID);
291 bool isStore = Opcode == ARM::STREXD || Opcode == ARM::STLEXD;
292 MCRegister Reg = MI->getOperand(isStore ? 1 : 0).getReg();
293 if (MRC.contains(Reg)) {
294 MCInst NewMI;
295 MCOperand NewReg;
296 NewMI.setOpcode(Opcode);
297
298 if (isStore)
299 NewMI.addOperand(MI->getOperand(0));
301 Reg, ARM::gsub_0, &MRI.getRegClass(ARM::GPRPairRegClassID)));
302 NewMI.addOperand(NewReg);
303
304 // Copy the rest operands into NewMI.
305 for (unsigned i = isStore ? 3 : 2; i < MI->getNumOperands(); ++i)
306 NewMI.addOperand(MI->getOperand(i));
307 printInstruction(&NewMI, Address, STI, O);
308 return;
309 }
310 break;
311 }
312 case ARM::TSB:
313 case ARM::t2TSB:
314 O << "\ttsb\tcsync";
315 return;
316 case ARM::t2DSB:
317 switch (MI->getOperand(0).getImm()) {
318 default:
319 if (!printAliasInstr(MI, Address, STI, O))
320 printInstruction(MI, Address, STI, O);
321 break;
322 case 0:
323 O << "\tssbb";
324 break;
325 case 4:
326 O << "\tpssbb";
327 break;
328 }
329 printAnnotation(O, Annot);
330 return;
331 }
332
333 if (!printAliasInstr(MI, Address, STI, O))
334 printInstruction(MI, Address, STI, O);
335
336 printAnnotation(O, Annot);
337}
338
339void ARMInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
340 const MCSubtargetInfo &STI, raw_ostream &O) {
341 const MCOperand &Op = MI->getOperand(OpNo);
342 if (Op.isReg()) {
343 MCRegister Reg = Op.getReg();
344 printRegName(O, Reg);
345 } else if (Op.isImm()) {
346 markup(O, Markup::Immediate) << '#' << formatImm(Op.getImm());
347 } else {
348 assert(Op.isExpr() && "unknown operand kind in printOperand");
349 const MCExpr *Expr = Op.getExpr();
350 switch (Expr->getKind()) {
351 case MCExpr::Binary:
352 O << '#';
353 Expr->print(O, &MAI);
354 break;
355 case MCExpr::Constant: {
356 // If a symbolic branch target was added as a constant expression then
357 // print that address in hex. And only print 32 unsigned bits for the
358 // address.
359 const MCConstantExpr *Constant = cast<MCConstantExpr>(Expr);
360 int64_t TargetAddress;
361 if (!Constant->evaluateAsAbsolute(TargetAddress)) {
362 O << '#';
363 Expr->print(O, &MAI);
364 } else {
365 O << "0x";
366 O.write_hex(static_cast<uint32_t>(TargetAddress));
367 }
368 break;
369 }
370 default:
371 // FIXME: Should we always treat this as if it is a constant literal and
372 // prefix it with '#'?
373 Expr->print(O, &MAI);
374 break;
375 }
376 }
377}
378
380 unsigned OpNum, const MCSubtargetInfo &STI,
381 raw_ostream &O) {
382 const MCOperand &Op = MI->getOperand(OpNum);
383 if (!Op.isImm() || !PrintBranchImmAsAddress || getUseMarkup())
384 return printOperand(MI, OpNum, STI, O);
386 Address, Op.getImm());
387 Target &= 0xffffffff;
388 O << formatHex(Target);
389 if (CommentStream)
390 *CommentStream << "imm = #" << formatImm(Op.getImm()) << '\n';
391}
392
394 const MCSubtargetInfo &STI,
395 raw_ostream &O) {
396 const MCOperand &MO1 = MI->getOperand(OpNum);
397 if (MO1.isExpr()) {
398 MO1.getExpr()->print(O, &MAI);
399 return;
400 }
401
402 WithMarkup ScopedMarkup = markup(O, Markup::Memory);
403 O << "[pc, ";
404
405 int32_t OffImm = (int32_t)MO1.getImm();
406 bool isSub = OffImm < 0;
407
408 // Special value for #-0. All others are normal.
409 if (OffImm == INT32_MIN)
410 OffImm = 0;
411 if (isSub) {
412 markup(O, Markup::Immediate) << "#-" << formatImm(-OffImm);
413 } else {
414 markup(O, Markup::Immediate) << "#" << formatImm(OffImm);
415 }
416 O << "]";
417}
418
419// so_reg is a 4-operand unit corresponding to register forms of the A5.1
420// "Addressing Mode 1 - Data-processing operands" forms. This includes:
421// REG 0 0 - e.g. R5
422// REG REG 0,SH_OPC - e.g. R5, ROR R3
423// REG 0 IMM,SH_OPC - e.g. R5, LSL #3
425 const MCSubtargetInfo &STI,
426 raw_ostream &O) {
427 const MCOperand &MO1 = MI->getOperand(OpNum);
428 const MCOperand &MO2 = MI->getOperand(OpNum + 1);
429 const MCOperand &MO3 = MI->getOperand(OpNum + 2);
430
431 printRegName(O, MO1.getReg());
432
433 // Print the shift opc.
435 O << ", " << ARM_AM::getShiftOpcStr(ShOpc);
436 if (ShOpc == ARM_AM::rrx)
437 return;
438
439 O << ' ';
440 printRegName(O, MO2.getReg());
442}
443
445 const MCSubtargetInfo &STI,
446 raw_ostream &O) {
447 const MCOperand &MO1 = MI->getOperand(OpNum);
448 const MCOperand &MO2 = MI->getOperand(OpNum + 1);
449
450 printRegName(O, MO1.getReg());
451
452 // Print the shift opc.
454 ARM_AM::getSORegOffset(MO2.getImm()), *this);
455}
456
457//===--------------------------------------------------------------------===//
458// Addressing Mode #2
459//===--------------------------------------------------------------------===//
460
462 const MCSubtargetInfo &STI,
463 raw_ostream &O) {
464 const MCOperand &MO1 = MI->getOperand(Op);
465 const MCOperand &MO2 = MI->getOperand(Op + 1);
466 const MCOperand &MO3 = MI->getOperand(Op + 2);
467
468 WithMarkup ScopedMarkup = markup(O, Markup::Memory);
469 O << "[";
470 printRegName(O, MO1.getReg());
471
472 if (!MO2.getReg()) {
473 if (ARM_AM::getAM2Offset(MO3.getImm())) { // Don't print +0.
474 O << ", ";
478 }
479 O << "]";
480 return;
481 }
482
483 O << ", ";
485 printRegName(O, MO2.getReg());
486
488 ARM_AM::getAM2Offset(MO3.getImm()), *this);
489 O << "]";
490}
491
493 const MCSubtargetInfo &STI,
494 raw_ostream &O) {
495 const MCOperand &MO1 = MI->getOperand(Op);
496 const MCOperand &MO2 = MI->getOperand(Op + 1);
497
498 WithMarkup ScopedMarkup = markup(O, Markup::Memory);
499 O << "[";
500 printRegName(O, MO1.getReg());
501 O << ", ";
502 printRegName(O, MO2.getReg());
503 O << "]";
504}
505
507 const MCSubtargetInfo &STI,
508 raw_ostream &O) {
509 const MCOperand &MO1 = MI->getOperand(Op);
510 const MCOperand &MO2 = MI->getOperand(Op + 1);
511 WithMarkup ScopedMarkup = markup(O, Markup::Memory);
512 O << "[";
513 printRegName(O, MO1.getReg());
514 O << ", ";
515 printRegName(O, MO2.getReg());
516 O << ", lsl ";
517 markup(O, Markup::Immediate) << "#1";
518 O << "]";
519}
520
522 const MCSubtargetInfo &STI,
523 raw_ostream &O) {
524 const MCOperand &MO1 = MI->getOperand(Op);
525
526 if (!MO1.isReg()) { // FIXME: This is for CP entries, but isn't right.
527 printOperand(MI, Op, STI, O);
528 return;
529 }
530
531#ifndef NDEBUG
532 const MCOperand &MO3 = MI->getOperand(Op + 2);
533 unsigned IdxMode = ARM_AM::getAM2IdxMode(MO3.getImm());
534 assert(IdxMode != ARMII::IndexModePost && "Should be pre or offset index op");
535#endif
536
538}
539
541 unsigned OpNum,
542 const MCSubtargetInfo &STI,
543 raw_ostream &O) {
544 const MCOperand &MO1 = MI->getOperand(OpNum);
545 const MCOperand &MO2 = MI->getOperand(OpNum + 1);
546
547 if (!MO1.getReg()) {
548 unsigned ImmOffs = ARM_AM::getAM2Offset(MO2.getImm());
551 << ImmOffs;
552 return;
553 }
554
556 printRegName(O, MO1.getReg());
557
559 ARM_AM::getAM2Offset(MO2.getImm()), *this);
560}
561
562//===--------------------------------------------------------------------===//
563// Addressing Mode #3
564//===--------------------------------------------------------------------===//
565
567 raw_ostream &O,
568 bool AlwaysPrintImm0) {
569 const MCOperand &MO1 = MI->getOperand(Op);
570 const MCOperand &MO2 = MI->getOperand(Op + 1);
571 const MCOperand &MO3 = MI->getOperand(Op + 2);
572
573 WithMarkup ScopedMarkup = markup(O, Markup::Memory);
574 O << '[';
575 printRegName(O, MO1.getReg());
576
577 if (MO2.getReg()) {
578 O << ", " << getAddrOpcStr(ARM_AM::getAM3Op(MO3.getImm()));
579 printRegName(O, MO2.getReg());
580 O << ']';
581 return;
582 }
583
584 // If the op is sub we have to print the immediate even if it is 0
585 unsigned ImmOffs = ARM_AM::getAM3Offset(MO3.getImm());
587
588 if (AlwaysPrintImm0 || ImmOffs || (op == ARM_AM::sub)) {
589 O << ", ";
590 markup(O, Markup::Immediate) << "#" << ARM_AM::getAddrOpcStr(op) << ImmOffs;
591 }
592 O << ']';
593}
594
595template <bool AlwaysPrintImm0>
597 const MCSubtargetInfo &STI,
598 raw_ostream &O) {
599 const MCOperand &MO1 = MI->getOperand(Op);
600 if (!MO1.isReg()) { // For label symbolic references.
601 printOperand(MI, Op, STI, O);
602 return;
603 }
604
605 assert(ARM_AM::getAM3IdxMode(MI->getOperand(Op + 2).getImm()) !=
607 "unexpected idxmode");
608 printAM3PreOrOffsetIndexOp(MI, Op, O, AlwaysPrintImm0);
609}
610
612 unsigned OpNum,
613 const MCSubtargetInfo &STI,
614 raw_ostream &O) {
615 const MCOperand &MO1 = MI->getOperand(OpNum);
616 const MCOperand &MO2 = MI->getOperand(OpNum + 1);
617
618 if (MO1.getReg()) {
619 O << getAddrOpcStr(ARM_AM::getAM3Op(MO2.getImm()));
620 printRegName(O, MO1.getReg());
621 return;
622 }
623
624 unsigned ImmOffs = ARM_AM::getAM3Offset(MO2.getImm());
627 << ImmOffs;
628}
629
631 const MCSubtargetInfo &STI,
632 raw_ostream &O) {
633 const MCOperand &MO = MI->getOperand(OpNum);
634 unsigned Imm = MO.getImm();
636 << '#' << ((Imm & 256) ? "" : "-") << (Imm & 0xff);
637}
638
640 const MCSubtargetInfo &STI,
641 raw_ostream &O) {
642 const MCOperand &MO1 = MI->getOperand(OpNum);
643 const MCOperand &MO2 = MI->getOperand(OpNum + 1);
644
645 O << (MO2.getImm() ? "" : "-");
646 printRegName(O, MO1.getReg());
647}
648
650 const MCSubtargetInfo &STI,
651 raw_ostream &O) {
652 const MCOperand &MO = MI->getOperand(OpNum);
653 unsigned Imm = MO.getImm();
655 << '#' << ((Imm & 256) ? "" : "-") << ((Imm & 0xff) << 2);
656}
657
658template<int shift>
660 const MCSubtargetInfo &STI,
661 raw_ostream &O) {
662 const MCOperand &MO1 = MI->getOperand(OpNum);
663 const MCOperand &MO2 = MI->getOperand(OpNum + 1);
664
665 WithMarkup ScopedMarkup = markup(O, Markup::Memory);
666 O << "[";
667 printRegName(O, MO1.getReg());
668 O << ", ";
669 printRegName(O, MO2.getReg());
670
671 if (shift > 0)
672 printRegImmShift(O, ARM_AM::uxtw, shift, *this);
673
674 O << "]";
675}
676
678 const MCSubtargetInfo &STI,
679 raw_ostream &O) {
680 ARM_AM::AMSubMode Mode =
681 ARM_AM::getAM4SubMode(MI->getOperand(OpNum).getImm());
682 O << ARM_AM::getAMSubModeStr(Mode);
683}
684
685template <bool AlwaysPrintImm0>
687 const MCSubtargetInfo &STI,
688 raw_ostream &O) {
689 const MCOperand &MO1 = MI->getOperand(OpNum);
690 const MCOperand &MO2 = MI->getOperand(OpNum + 1);
691
692 if (!MO1.isReg()) { // FIXME: This is for CP entries, but isn't right.
693 printOperand(MI, OpNum, STI, O);
694 return;
695 }
696
697 WithMarkup ScopedMarkup = markup(O, Markup::Memory);
698 O << "[";
699 printRegName(O, MO1.getReg());
700
701 unsigned ImmOffs = ARM_AM::getAM5Offset(MO2.getImm());
703 if (AlwaysPrintImm0 || ImmOffs || Op == ARM_AM::sub) {
704 O << ", ";
706 << "#" << ARM_AM::getAddrOpcStr(Op) << ImmOffs * 4;
707 }
708 O << "]";
709}
710
711template <bool AlwaysPrintImm0>
713 const MCSubtargetInfo &STI,
714 raw_ostream &O) {
715 const MCOperand &MO1 = MI->getOperand(OpNum);
716 const MCOperand &MO2 = MI->getOperand(OpNum+1);
717
718 if (!MO1.isReg()) { // FIXME: This is for CP entries, but isn't right.
719 printOperand(MI, OpNum, STI, O);
720 return;
721 }
722
723 WithMarkup ScopedMarkup = markup(O, Markup::Memory);
724 O << "[";
725 printRegName(O, MO1.getReg());
726
727 unsigned ImmOffs = ARM_AM::getAM5FP16Offset(MO2.getImm());
728 unsigned Op = ARM_AM::getAM5FP16Op(MO2.getImm());
729 if (AlwaysPrintImm0 || ImmOffs || Op == ARM_AM::sub) {
730 O << ", ";
733 << ImmOffs * 2;
734 }
735 O << "]";
736}
737
739 const MCSubtargetInfo &STI,
740 raw_ostream &O) {
741 const MCOperand &MO1 = MI->getOperand(OpNum);
742 const MCOperand &MO2 = MI->getOperand(OpNum + 1);
743
744 WithMarkup ScopedMarkup = markup(O, Markup::Memory);
745 O << "[";
746 printRegName(O, MO1.getReg());
747 if (MO2.getImm()) {
748 O << ":" << (MO2.getImm() << 3);
749 }
750 O << "]";
751}
752
754 const MCSubtargetInfo &STI,
755 raw_ostream &O) {
756 const MCOperand &MO1 = MI->getOperand(OpNum);
757 WithMarkup ScopedMarkup = markup(O, Markup::Memory);
758 O << "[";
759 printRegName(O, MO1.getReg());
760 O << "]";
761}
762
764 unsigned OpNum,
765 const MCSubtargetInfo &STI,
766 raw_ostream &O) {
767 const MCOperand &MO = MI->getOperand(OpNum);
768 if (!MO.getReg())
769 O << "!";
770 else {
771 O << ", ";
772 printRegName(O, MO.getReg());
773 }
774}
775
777 unsigned OpNum,
778 const MCSubtargetInfo &STI,
779 raw_ostream &O) {
780 const MCOperand &MO = MI->getOperand(OpNum);
781 uint32_t v = ~MO.getImm();
782 int32_t lsb = llvm::countr_zero(v);
783 int32_t width = llvm::bit_width(v) - lsb;
784 assert(MO.isImm() && "Not a valid bf_inv_mask_imm value!");
785 markup(O, Markup::Immediate) << '#' << lsb;
786 O << ", ";
787 markup(O, Markup::Immediate) << '#' << width;
788}
789
790void ARMInstPrinter::printMemBOption(const MCInst *MI, unsigned OpNum,
791 const MCSubtargetInfo &STI,
792 raw_ostream &O) {
793 unsigned val = MI->getOperand(OpNum).getImm();
794 O << ARM_MB::MemBOptToString(val, STI.hasFeature(ARM::HasV8Ops));
795}
796
798 const MCSubtargetInfo &STI,
799 raw_ostream &O) {
800 unsigned val = MI->getOperand(OpNum).getImm();
802}
803
805 const MCSubtargetInfo &STI,
806 raw_ostream &O) {
807 unsigned val = MI->getOperand(OpNum).getImm();
809}
810
812 const MCSubtargetInfo &STI,
813 raw_ostream &O) {
814 unsigned ShiftOp = MI->getOperand(OpNum).getImm();
815 bool isASR = (ShiftOp & (1 << 5)) != 0;
816 unsigned Amt = ShiftOp & 0x1f;
817 if (isASR) {
818 O << ", asr ";
819 markup(O, Markup::Immediate) << "#" << (Amt == 0 ? 32 : Amt);
820 } else if (Amt) {
821 O << ", lsl ";
822 markup(O, Markup::Immediate) << "#" << Amt;
823 }
824}
825
827 const MCSubtargetInfo &STI,
828 raw_ostream &O) {
829 unsigned Imm = MI->getOperand(OpNum).getImm();
830 if (Imm == 0)
831 return;
832 assert(Imm > 0 && Imm < 32 && "Invalid PKH shift immediate value!");
833 O << ", lsl ";
834 markup(O, Markup::Immediate) << "#" << Imm;
835}
836
838 const MCSubtargetInfo &STI,
839 raw_ostream &O) {
840 unsigned Imm = MI->getOperand(OpNum).getImm();
841 // A shift amount of 32 is encoded as 0.
842 if (Imm == 0)
843 Imm = 32;
844 assert(Imm > 0 && Imm <= 32 && "Invalid PKH shift immediate value!");
845 O << ", asr ";
846 markup(O, Markup::Immediate) << "#" << Imm;
847}
848
849void ARMInstPrinter::printRegisterList(const MCInst *MI, unsigned OpNum,
850 const MCSubtargetInfo &STI,
851 raw_ostream &O) {
852 if (MI->getOpcode() != ARM::t2CLRM && MI->getOpcode() != ARM::VSCCLRMS) {
853 assert(is_sorted(drop_begin(*MI, OpNum),
854 [&](const MCOperand &LHS, const MCOperand &RHS) {
855 return MRI.getEncodingValue(LHS.getReg()) <
856 MRI.getEncodingValue(RHS.getReg());
857 }));
858 }
859
860 O << "{";
861 for (unsigned i = OpNum, e = MI->getNumOperands(); i != e; ++i) {
862 if (i != OpNum)
863 O << ", ";
864 printRegName(O, MI->getOperand(i).getReg());
865 }
866 O << "}";
867}
868
870 const MCSubtargetInfo &STI,
871 raw_ostream &O) {
872 MCRegister Reg = MI->getOperand(OpNum).getReg();
873 printRegName(O, MRI.getSubReg(Reg, ARM::gsub_0));
874 O << ", ";
875 printRegName(O, MRI.getSubReg(Reg, ARM::gsub_1));
876}
877
878void ARMInstPrinter::printSetendOperand(const MCInst *MI, unsigned OpNum,
879 const MCSubtargetInfo &STI,
880 raw_ostream &O) {
881 const MCOperand &Op = MI->getOperand(OpNum);
882 if (Op.getImm())
883 O << "be";
884 else
885 O << "le";
886}
887
888void ARMInstPrinter::printCPSIMod(const MCInst *MI, unsigned OpNum,
889 const MCSubtargetInfo &STI, raw_ostream &O) {
890 const MCOperand &Op = MI->getOperand(OpNum);
891 O << ARM_PROC::IModToString(Op.getImm());
892}
893
894void ARMInstPrinter::printCPSIFlag(const MCInst *MI, unsigned OpNum,
895 const MCSubtargetInfo &STI, raw_ostream &O) {
896 const MCOperand &Op = MI->getOperand(OpNum);
897 unsigned IFlags = Op.getImm();
898 for (int i = 2; i >= 0; --i)
899 if (IFlags & (1 << i))
900 O << ARM_PROC::IFlagsToString(1 << i);
901
902 if (IFlags == 0)
903 O << "none";
904}
905
907 const MCSubtargetInfo &STI,
908 raw_ostream &O) {
909 const MCOperand &Op = MI->getOperand(OpNum);
910 const FeatureBitset &FeatureBits = STI.getFeatureBits();
911 if (FeatureBits[ARM::FeatureMClass]) {
912
913 unsigned SYSm = Op.getImm() & 0xFFF; // 12-bit SYSm
914 unsigned Opcode = MI->getOpcode();
915
916 // For writes, handle extended mask bits if the DSP extension is present.
917 if (Opcode == ARM::t2MSR_M && FeatureBits[ARM::FeatureDSP]) {
919 if (TheReg && TheReg->isInRequiredFeatures({ARM::FeatureDSP})) {
920 O << TheReg->Name;
921 return;
922 }
923 }
924
925 // Handle the basic 8-bit mask.
926 SYSm &= 0xff;
927 if (Opcode == ARM::t2MSR_M && FeatureBits [ARM::HasV7Ops]) {
928 // ARMv7-M deprecates using MSR APSR without a _<bits> qualifier as an
929 // alias for MSR APSR_nzcvq.
931 if (TheReg) {
932 O << TheReg->Name;
933 return;
934 }
935 }
936
938 if (TheReg) {
939 O << TheReg->Name;
940 return;
941 }
942
943 O << SYSm;
944
945 return;
946 }
947
948 // As special cases, CPSR_f, CPSR_s and CPSR_fs prefer printing as
949 // APSR_nzcvq, APSR_g and APSRnzcvqg, respectively.
950 unsigned SpecRegRBit = Op.getImm() >> 4;
951 unsigned Mask = Op.getImm() & 0xf;
952
953 if (!SpecRegRBit && (Mask == 8 || Mask == 4 || Mask == 12)) {
954 O << "APSR_";
955 switch (Mask) {
956 default:
957 llvm_unreachable("Unexpected mask value!");
958 case 4:
959 O << "g";
960 return;
961 case 8:
962 O << "nzcvq";
963 return;
964 case 12:
965 O << "nzcvqg";
966 return;
967 }
968 }
969
970 if (SpecRegRBit)
971 O << "SPSR";
972 else
973 O << "CPSR";
974
975 if (Mask) {
976 O << '_';
977 if (Mask & 8)
978 O << 'f';
979 if (Mask & 4)
980 O << 's';
981 if (Mask & 2)
982 O << 'x';
983 if (Mask & 1)
984 O << 'c';
985 }
986}
987
989 const MCSubtargetInfo &STI,
990 raw_ostream &O) {
991 uint32_t Banked = MI->getOperand(OpNum).getImm();
992 auto TheReg = ARMBankedReg::lookupBankedRegByEncoding(Banked);
993 assert(TheReg && "invalid banked register operand");
994 std::string Name = TheReg->Name;
995
996 uint32_t isSPSR = (Banked & 0x20) >> 5;
997 if (isSPSR)
998 Name.replace(0, 4, "SPSR"); // convert 'spsr_' to 'SPSR_'
999 O << Name;
1000}
1001
1003 const MCSubtargetInfo &STI,
1004 raw_ostream &O) {
1005 ARMCC::CondCodes CC = (ARMCC::CondCodes)MI->getOperand(OpNum).getImm();
1006 // Handle the undefined 15 CC value here for printing so we don't abort().
1007 if ((unsigned)CC == 15)
1008 O << "<und>";
1009 else if (CC != ARMCC::AL)
1010 O << ARMCondCodeToString(CC);
1011}
1012
1014 const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI,
1015 raw_ostream &O) {
1016 if ((ARMCC::CondCodes)MI->getOperand(OpNum).getImm() == ARMCC::HS)
1017 O << "cs";
1018 else
1019 printMandatoryPredicateOperand(MI, OpNum, STI, O);
1020}
1021
1023 unsigned OpNum,
1024 const MCSubtargetInfo &STI,
1025 raw_ostream &O) {
1026 ARMCC::CondCodes CC = (ARMCC::CondCodes)MI->getOperand(OpNum).getImm();
1027 O << ARMCondCodeToString(CC);
1028}
1029
1031 unsigned OpNum,
1032 const MCSubtargetInfo &STI,
1033 raw_ostream &O) {
1034 ARMCC::CondCodes CC = (ARMCC::CondCodes)MI->getOperand(OpNum).getImm();
1036}
1037
1039 const MCSubtargetInfo &STI,
1040 raw_ostream &O) {
1041 if (MI->getOperand(OpNum).getReg()) {
1042 assert(MI->getOperand(OpNum).getReg() == ARM::CPSR &&
1043 "Expect ARM CPSR register!");
1044 O << 's';
1045 }
1046}
1047
1049 const MCSubtargetInfo &STI,
1050 raw_ostream &O) {
1051 O << MI->getOperand(OpNum).getImm();
1052}
1053
1054void ARMInstPrinter::printPImmediate(const MCInst *MI, unsigned OpNum,
1055 const MCSubtargetInfo &STI,
1056 raw_ostream &O) {
1057 O << "p" << MI->getOperand(OpNum).getImm();
1058}
1059
1060void ARMInstPrinter::printCImmediate(const MCInst *MI, unsigned OpNum,
1061 const MCSubtargetInfo &STI,
1062 raw_ostream &O) {
1063 O << "c" << MI->getOperand(OpNum).getImm();
1064}
1065
1067 const MCSubtargetInfo &STI,
1068 raw_ostream &O) {
1069 O << "{" << MI->getOperand(OpNum).getImm() << "}";
1070}
1071
1072void ARMInstPrinter::printPCLabel(const MCInst *MI, unsigned OpNum,
1073 const MCSubtargetInfo &STI, raw_ostream &O) {
1074 llvm_unreachable("Unhandled PC-relative pseudo-instruction!");
1075}
1076
1077template <unsigned scale>
1079 const MCSubtargetInfo &STI,
1080 raw_ostream &O) {
1081 const MCOperand &MO = MI->getOperand(OpNum);
1082
1083 if (MO.isExpr()) {
1084 MO.getExpr()->print(O, &MAI);
1085 return;
1086 }
1087
1088 int32_t OffImm = (int32_t)MO.getImm() << scale;
1089
1090 WithMarkup ScopedMarkup = markup(O, Markup::Immediate);
1091 if (OffImm == INT32_MIN)
1092 O << "#-0";
1093 else if (OffImm < 0)
1094 O << "#-" << -OffImm;
1095 else
1096 O << "#" << OffImm;
1097}
1098
1100 const MCSubtargetInfo &STI,
1101 raw_ostream &O) {
1103 << "#" << formatImm(MI->getOperand(OpNum).getImm() * 4);
1104}
1105
1106void ARMInstPrinter::printThumbSRImm(const MCInst *MI, unsigned OpNum,
1107 const MCSubtargetInfo &STI,
1108 raw_ostream &O) {
1109 unsigned Imm = MI->getOperand(OpNum).getImm();
1110 markup(O, Markup::Immediate) << "#" << formatImm((Imm == 0 ? 32 : Imm));
1111}
1112
1113void ARMInstPrinter::printThumbITMask(const MCInst *MI, unsigned OpNum,
1114 const MCSubtargetInfo &STI,
1115 raw_ostream &O) {
1116 // (3 - the number of trailing zeros) is the number of then / else.
1117 unsigned Mask = MI->getOperand(OpNum).getImm();
1118 unsigned NumTZ = llvm::countr_zero(Mask);
1119 assert(NumTZ <= 3 && "Invalid IT mask!");
1120 for (unsigned Pos = 3, e = NumTZ; Pos > e; --Pos) {
1121 if ((Mask >> Pos) & 1)
1122 O << 'e';
1123 else
1124 O << 't';
1125 }
1126}
1127
1129 const MCSubtargetInfo &STI,
1130 raw_ostream &O) {
1131 const MCOperand &MO1 = MI->getOperand(Op);
1132 const MCOperand &MO2 = MI->getOperand(Op + 1);
1133
1134 if (!MO1.isReg()) { // FIXME: This is for CP entries, but isn't right.
1135 printOperand(MI, Op, STI, O);
1136 return;
1137 }
1138
1139 WithMarkup ScopedMarkup = markup(O, Markup::Memory);
1140 O << "[";
1141 printRegName(O, MO1.getReg());
1142 if (MCRegister RegNum = MO2.getReg()) {
1143 O << ", ";
1144 printRegName(O, RegNum);
1145 }
1146 O << "]";
1147}
1148
1150 unsigned Op,
1151 const MCSubtargetInfo &STI,
1152 raw_ostream &O,
1153 unsigned Scale) {
1154 const MCOperand &MO1 = MI->getOperand(Op);
1155 const MCOperand &MO2 = MI->getOperand(Op + 1);
1156
1157 if (!MO1.isReg()) { // FIXME: This is for CP entries, but isn't right.
1158 printOperand(MI, Op, STI, O);
1159 return;
1160 }
1161
1162 WithMarkup ScopedMarkup = markup(O, Markup::Memory);
1163 O << "[";
1164 printRegName(O, MO1.getReg());
1165 if (unsigned ImmOffs = MO2.getImm()) {
1166 O << ", ";
1167 markup(O, Markup::Immediate) << "#" << formatImm(ImmOffs * Scale);
1168 }
1169 O << "]";
1170}
1171
1173 unsigned Op,
1174 const MCSubtargetInfo &STI,
1175 raw_ostream &O) {
1177}
1178
1180 unsigned Op,
1181 const MCSubtargetInfo &STI,
1182 raw_ostream &O) {
1184}
1185
1187 unsigned Op,
1188 const MCSubtargetInfo &STI,
1189 raw_ostream &O) {
1191}
1192
1194 const MCSubtargetInfo &STI,
1195 raw_ostream &O) {
1197}
1198
1199// Constant shifts t2_so_reg is a 2-operand unit corresponding to the Thumb2
1200// register with shift forms.
1201// REG 0 0 - e.g. R5
1202// REG IMM, SH_OPC - e.g. R5, LSL #3
1203void ARMInstPrinter::printT2SOOperand(const MCInst *MI, unsigned OpNum,
1204 const MCSubtargetInfo &STI,
1205 raw_ostream &O) {
1206 const MCOperand &MO1 = MI->getOperand(OpNum);
1207 const MCOperand &MO2 = MI->getOperand(OpNum + 1);
1208
1209 MCRegister Reg = MO1.getReg();
1210 printRegName(O, Reg);
1211
1212 // Print the shift opc.
1213 assert(MO2.isImm() && "Not a valid t2_so_reg value!");
1215 ARM_AM::getSORegOffset(MO2.getImm()), *this);
1216}
1217
1218template <bool AlwaysPrintImm0>
1220 const MCSubtargetInfo &STI,
1221 raw_ostream &O) {
1222 const MCOperand &MO1 = MI->getOperand(OpNum);
1223 const MCOperand &MO2 = MI->getOperand(OpNum + 1);
1224
1225 if (!MO1.isReg()) { // FIXME: This is for CP entries, but isn't right.
1226 printOperand(MI, OpNum, STI, O);
1227 return;
1228 }
1229
1230 WithMarkup ScopedMarkup = markup(O, Markup::Memory);
1231 O << "[";
1232 printRegName(O, MO1.getReg());
1233
1234 int32_t OffImm = (int32_t)MO2.getImm();
1235 bool isSub = OffImm < 0;
1236 // Special value for #-0. All others are normal.
1237 if (OffImm == INT32_MIN)
1238 OffImm = 0;
1239 if (isSub) {
1240 O << ", ";
1241 markup(O, Markup::Immediate) << "#-" << formatImm(-OffImm);
1242 } else if (AlwaysPrintImm0 || OffImm > 0) {
1243 O << ", ";
1244 markup(O, Markup::Immediate) << "#" << formatImm(OffImm);
1245 }
1246 O << "]";
1247}
1248
1249template <bool AlwaysPrintImm0>
1251 unsigned OpNum,
1252 const MCSubtargetInfo &STI,
1253 raw_ostream &O) {
1254 const MCOperand &MO1 = MI->getOperand(OpNum);
1255 const MCOperand &MO2 = MI->getOperand(OpNum + 1);
1256
1257 WithMarkup ScopedMarkup = markup(O, Markup::Memory);
1258 O << "[";
1259 printRegName(O, MO1.getReg());
1260
1261 int32_t OffImm = (int32_t)MO2.getImm();
1262 bool isSub = OffImm < 0;
1263 // Don't print +0.
1264 if (OffImm == INT32_MIN)
1265 OffImm = 0;
1266 if (isSub) {
1267 O << ", ";
1268 markup(O, Markup::Immediate) << "#-" << -OffImm;
1269 } else if (AlwaysPrintImm0 || OffImm > 0) {
1270 O << ", ";
1271 markup(O, Markup::Immediate) << "#" << OffImm;
1272 }
1273 O << "]";
1274}
1275
1276template <bool AlwaysPrintImm0>
1278 unsigned OpNum,
1279 const MCSubtargetInfo &STI,
1280 raw_ostream &O) {
1281 const MCOperand &MO1 = MI->getOperand(OpNum);
1282 const MCOperand &MO2 = MI->getOperand(OpNum + 1);
1283
1284 if (!MO1.isReg()) { // For label symbolic references.
1285 printOperand(MI, OpNum, STI, O);
1286 return;
1287 }
1288
1289 WithMarkup ScopedMarkup = markup(O, Markup::Memory);
1290 O << "[";
1291 printRegName(O, MO1.getReg());
1292
1293 int32_t OffImm = (int32_t)MO2.getImm();
1294 bool isSub = OffImm < 0;
1295
1296 assert(((OffImm & 0x3) == 0) && "Not a valid immediate!");
1297
1298 // Don't print +0.
1299 if (OffImm == INT32_MIN)
1300 OffImm = 0;
1301 if (isSub) {
1302 O << ", ";
1303 markup(O, Markup::Immediate) << "#-" << -OffImm;
1304 } else if (AlwaysPrintImm0 || OffImm > 0) {
1305 O << ", ";
1306 markup(O, Markup::Immediate) << "#" << OffImm;
1307 }
1308 O << "]";
1309}
1310
1312 const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI,
1313 raw_ostream &O) {
1314 const MCOperand &MO1 = MI->getOperand(OpNum);
1315 const MCOperand &MO2 = MI->getOperand(OpNum + 1);
1316
1317 WithMarkup ScopedMarkup = markup(O, Markup::Memory);
1318 O << "[";
1319 printRegName(O, MO1.getReg());
1320 if (MO2.getImm()) {
1321 O << ", ";
1322 markup(O, Markup::Immediate) << "#" << formatImm(MO2.getImm() * 4);
1323 }
1324 O << "]";
1325}
1326
1328 const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI,
1329 raw_ostream &O) {
1330 const MCOperand &MO1 = MI->getOperand(OpNum);
1331 int32_t OffImm = (int32_t)MO1.getImm();
1332 O << ", ";
1333 WithMarkup ScopedMarkup = markup(O, Markup::Immediate);
1334 if (OffImm == INT32_MIN)
1335 O << "#-0";
1336 else if (OffImm < 0)
1337 O << "#-" << -OffImm;
1338 else
1339 O << "#" << OffImm;
1340}
1341
1343 const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI,
1344 raw_ostream &O) {
1345 const MCOperand &MO1 = MI->getOperand(OpNum);
1346 int32_t OffImm = (int32_t)MO1.getImm();
1347
1348 assert(((OffImm & 0x3) == 0) && "Not a valid immediate!");
1349
1350 O << ", ";
1351 WithMarkup ScopedMarkup = markup(O, Markup::Immediate);
1352 if (OffImm == INT32_MIN)
1353 O << "#-0";
1354 else if (OffImm < 0)
1355 O << "#-" << -OffImm;
1356 else
1357 O << "#" << OffImm;
1358}
1359
1361 unsigned OpNum,
1362 const MCSubtargetInfo &STI,
1363 raw_ostream &O) {
1364 const MCOperand &MO1 = MI->getOperand(OpNum);
1365 const MCOperand &MO2 = MI->getOperand(OpNum + 1);
1366 const MCOperand &MO3 = MI->getOperand(OpNum + 2);
1367
1368 WithMarkup ScopedMarkup = markup(O, Markup::Memory);
1369 O << "[";
1370 printRegName(O, MO1.getReg());
1371
1372 assert(MO2.getReg() && "Invalid so_reg load / store address!");
1373 O << ", ";
1374 printRegName(O, MO2.getReg());
1375
1376 unsigned ShAmt = MO3.getImm();
1377 if (ShAmt) {
1378 assert(ShAmt <= 3 && "Not a valid Thumb2 addressing mode!");
1379 O << ", lsl ";
1380 markup(O, Markup::Immediate) << "#" << ShAmt;
1381 }
1382 O << "]";
1383}
1384
1385void ARMInstPrinter::printFPImmOperand(const MCInst *MI, unsigned OpNum,
1386 const MCSubtargetInfo &STI,
1387 raw_ostream &O) {
1388 const MCOperand &MO = MI->getOperand(OpNum);
1390}
1391
1393 const MCSubtargetInfo &STI,
1394 raw_ostream &O) {
1395 unsigned EncodedImm = MI->getOperand(OpNum).getImm();
1396 unsigned EltBits;
1397 uint64_t Val = ARM_AM::decodeVMOVModImm(EncodedImm, EltBits);
1398
1399 WithMarkup ScopedMarkup = markup(O, Markup::Immediate);
1400 O << "#0x";
1401 O.write_hex(Val);
1402}
1403
1405 const MCSubtargetInfo &STI,
1406 raw_ostream &O) {
1407 unsigned Imm = MI->getOperand(OpNum).getImm();
1408 markup(O, Markup::Immediate) << "#" << formatImm(Imm + 1);
1409}
1410
1412 const MCSubtargetInfo &STI,
1413 raw_ostream &O) {
1414 unsigned Imm = MI->getOperand(OpNum).getImm();
1415 if (Imm == 0)
1416 return;
1417 assert(Imm <= 3 && "illegal ror immediate!");
1418 O << ", ror ";
1419 markup(O, Markup::Immediate) << "#" << 8 * Imm;
1420}
1421
1423 const MCSubtargetInfo &STI,
1424 raw_ostream &O) {
1425 MCOperand Op = MI->getOperand(OpNum);
1426
1427 // Support for fixups (MCFixup)
1428 if (Op.isExpr())
1429 return printOperand(MI, OpNum, STI, O);
1430
1431 unsigned Bits = Op.getImm() & 0xFF;
1432 unsigned Rot = (Op.getImm() & 0xF00) >> 7;
1433
1434 bool PrintUnsigned = false;
1435 switch (MI->getOpcode()) {
1436 case ARM::MOVi:
1437 // Movs to PC should be treated unsigned
1438 PrintUnsigned = (MI->getOperand(OpNum - 1).getReg() == ARM::PC);
1439 break;
1440 case ARM::MSRi:
1441 // Movs to special registers should be treated unsigned
1442 PrintUnsigned = true;
1443 break;
1444 }
1445
1446 int32_t Rotated = llvm::rotr<uint32_t>(Bits, Rot);
1447 if (ARM_AM::getSOImmVal(Rotated) == Op.getImm()) {
1448 // #rot has the least possible value
1449 O << "#";
1450 if (PrintUnsigned)
1451 markup(O, Markup::Immediate) << static_cast<uint32_t>(Rotated);
1452 else
1453 markup(O, Markup::Immediate) << Rotated;
1454 return;
1455 }
1456
1457 // Explicit #bits, #rot implied
1458 O << "#";
1459 markup(O, Markup::Immediate) << Bits;
1460 O << ", #";
1461 markup(O, Markup::Immediate) << Rot;
1462}
1463
1464void ARMInstPrinter::printFBits16(const MCInst *MI, unsigned OpNum,
1465 const MCSubtargetInfo &STI, raw_ostream &O) {
1466 markup(O, Markup::Immediate) << "#" << 16 - MI->getOperand(OpNum).getImm();
1467}
1468
1469void ARMInstPrinter::printFBits32(const MCInst *MI, unsigned OpNum,
1470 const MCSubtargetInfo &STI, raw_ostream &O) {
1471 markup(O, Markup::Immediate) << "#" << 32 - MI->getOperand(OpNum).getImm();
1472}
1473
1474void ARMInstPrinter::printVectorIndex(const MCInst *MI, unsigned OpNum,
1475 const MCSubtargetInfo &STI,
1476 raw_ostream &O) {
1477 O << "[" << MI->getOperand(OpNum).getImm() << "]";
1478}
1479
1481 const MCSubtargetInfo &STI,
1482 raw_ostream &O) {
1483 O << "{";
1484 printRegName(O, MI->getOperand(OpNum).getReg());
1485 O << "}";
1486}
1487
1489 const MCSubtargetInfo &STI,
1490 raw_ostream &O) {
1491 MCRegister Reg = MI->getOperand(OpNum).getReg();
1492 MCRegister Reg0 = MRI.getSubReg(Reg, ARM::dsub_0);
1493 MCRegister Reg1 = MRI.getSubReg(Reg, ARM::dsub_1);
1494 O << "{";
1495 printRegName(O, Reg0);
1496 O << ", ";
1497 printRegName(O, Reg1);
1498 O << "}";
1499}
1500
1502 const MCSubtargetInfo &STI,
1503 raw_ostream &O) {
1504 MCRegister Reg = MI->getOperand(OpNum).getReg();
1505 MCRegister Reg0 = MRI.getSubReg(Reg, ARM::dsub_0);
1506 MCRegister Reg1 = MRI.getSubReg(Reg, ARM::dsub_2);
1507 O << "{";
1508 printRegName(O, Reg0);
1509 O << ", ";
1510 printRegName(O, Reg1);
1511 O << "}";
1512}
1513
1515 const MCSubtargetInfo &STI,
1516 raw_ostream &O) {
1517 // Normally, it's not safe to use register enum values directly with
1518 // addition to get the next register, but for VFP registers, the
1519 // sort order is guaranteed because they're all of the form D<n>.
1520 O << "{";
1521 printRegName(O, MI->getOperand(OpNum).getReg());
1522 O << ", ";
1523 printRegName(O, MI->getOperand(OpNum).getReg() + 1);
1524 O << ", ";
1525 printRegName(O, MI->getOperand(OpNum).getReg() + 2);
1526 O << "}";
1527}
1528
1530 const MCSubtargetInfo &STI,
1531 raw_ostream &O) {
1532 // Normally, it's not safe to use register enum values directly with
1533 // addition to get the next register, but for VFP registers, the
1534 // sort order is guaranteed because they're all of the form D<n>.
1535 O << "{";
1536 printRegName(O, MI->getOperand(OpNum).getReg());
1537 O << ", ";
1538 printRegName(O, MI->getOperand(OpNum).getReg() + 1);
1539 O << ", ";
1540 printRegName(O, MI->getOperand(OpNum).getReg() + 2);
1541 O << ", ";
1542 printRegName(O, MI->getOperand(OpNum).getReg() + 3);
1543 O << "}";
1544}
1545
1547 unsigned OpNum,
1548 const MCSubtargetInfo &STI,
1549 raw_ostream &O) {
1550 O << "{";
1551 printRegName(O, MI->getOperand(OpNum).getReg());
1552 O << "[]}";
1553}
1554
1556 unsigned OpNum,
1557 const MCSubtargetInfo &STI,
1558 raw_ostream &O) {
1559 MCRegister Reg = MI->getOperand(OpNum).getReg();
1560 MCRegister Reg0 = MRI.getSubReg(Reg, ARM::dsub_0);
1561 MCRegister Reg1 = MRI.getSubReg(Reg, ARM::dsub_1);
1562 O << "{";
1563 printRegName(O, Reg0);
1564 O << "[], ";
1565 printRegName(O, Reg1);
1566 O << "[]}";
1567}
1568
1570 unsigned OpNum,
1571 const MCSubtargetInfo &STI,
1572 raw_ostream &O) {
1573 // Normally, it's not safe to use register enum values directly with
1574 // addition to get the next register, but for VFP registers, the
1575 // sort order is guaranteed because they're all of the form D<n>.
1576 O << "{";
1577 printRegName(O, MI->getOperand(OpNum).getReg());
1578 O << "[], ";
1579 printRegName(O, MI->getOperand(OpNum).getReg() + 1);
1580 O << "[], ";
1581 printRegName(O, MI->getOperand(OpNum).getReg() + 2);
1582 O << "[]}";
1583}
1584
1586 unsigned OpNum,
1587 const MCSubtargetInfo &STI,
1588 raw_ostream &O) {
1589 // Normally, it's not safe to use register enum values directly with
1590 // addition to get the next register, but for VFP registers, the
1591 // sort order is guaranteed because they're all of the form D<n>.
1592 O << "{";
1593 printRegName(O, MI->getOperand(OpNum).getReg());
1594 O << "[], ";
1595 printRegName(O, MI->getOperand(OpNum).getReg() + 1);
1596 O << "[], ";
1597 printRegName(O, MI->getOperand(OpNum).getReg() + 2);
1598 O << "[], ";
1599 printRegName(O, MI->getOperand(OpNum).getReg() + 3);
1600 O << "[]}";
1601}
1602
1604 const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI,
1605 raw_ostream &O) {
1606 MCRegister Reg = MI->getOperand(OpNum).getReg();
1607 MCRegister Reg0 = MRI.getSubReg(Reg, ARM::dsub_0);
1608 MCRegister Reg1 = MRI.getSubReg(Reg, ARM::dsub_2);
1609 O << "{";
1610 printRegName(O, Reg0);
1611 O << "[], ";
1612 printRegName(O, Reg1);
1613 O << "[]}";
1614}
1615
1617 const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI,
1618 raw_ostream &O) {
1619 // Normally, it's not safe to use register enum values directly with
1620 // addition to get the next register, but for VFP registers, the
1621 // sort order is guaranteed because they're all of the form D<n>.
1622 O << "{";
1623 printRegName(O, MI->getOperand(OpNum).getReg());
1624 O << "[], ";
1625 printRegName(O, MI->getOperand(OpNum).getReg() + 2);
1626 O << "[], ";
1627 printRegName(O, MI->getOperand(OpNum).getReg() + 4);
1628 O << "[]}";
1629}
1630
1632 const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI,
1633 raw_ostream &O) {
1634 // Normally, it's not safe to use register enum values directly with
1635 // addition to get the next register, but for VFP registers, the
1636 // sort order is guaranteed because they're all of the form D<n>.
1637 O << "{";
1638 printRegName(O, MI->getOperand(OpNum).getReg());
1639 O << "[], ";
1640 printRegName(O, MI->getOperand(OpNum).getReg() + 2);
1641 O << "[], ";
1642 printRegName(O, MI->getOperand(OpNum).getReg() + 4);
1643 O << "[], ";
1644 printRegName(O, MI->getOperand(OpNum).getReg() + 6);
1645 O << "[]}";
1646}
1647
1649 unsigned OpNum,
1650 const MCSubtargetInfo &STI,
1651 raw_ostream &O) {
1652 // Normally, it's not safe to use register enum values directly with
1653 // addition to get the next register, but for VFP registers, the
1654 // sort order is guaranteed because they're all of the form D<n>.
1655 O << "{";
1656 printRegName(O, MI->getOperand(OpNum).getReg());
1657 O << ", ";
1658 printRegName(O, MI->getOperand(OpNum).getReg() + 2);
1659 O << ", ";
1660 printRegName(O, MI->getOperand(OpNum).getReg() + 4);
1661 O << "}";
1662}
1663
1665 const MCSubtargetInfo &STI,
1666 raw_ostream &O) {
1667 // Normally, it's not safe to use register enum values directly with
1668 // addition to get the next register, but for VFP registers, the
1669 // sort order is guaranteed because they're all of the form D<n>.
1670 O << "{";
1671 printRegName(O, MI->getOperand(OpNum).getReg());
1672 O << ", ";
1673 printRegName(O, MI->getOperand(OpNum).getReg() + 2);
1674 O << ", ";
1675 printRegName(O, MI->getOperand(OpNum).getReg() + 4);
1676 O << ", ";
1677 printRegName(O, MI->getOperand(OpNum).getReg() + 6);
1678 O << "}";
1679}
1680
1681template<unsigned NumRegs>
1683 const MCSubtargetInfo &STI,
1684 raw_ostream &O) {
1685 MCRegister Reg = MI->getOperand(OpNum).getReg();
1686 const char *Prefix = "{";
1687 for (unsigned i = 0; i < NumRegs; i++) {
1688 O << Prefix;
1689 printRegName(O, MRI.getSubReg(Reg, ARM::qsub_0 + i));
1690 Prefix = ", ";
1691 }
1692 O << "}";
1693}
1694
1695template<int64_t Angle, int64_t Remainder>
1697 const MCSubtargetInfo &STI,
1698 raw_ostream &O) {
1699 unsigned Val = MI->getOperand(OpNo).getImm();
1700 O << "#" << (Val * Angle) + Remainder;
1701}
1702
1704 const MCSubtargetInfo &STI,
1705 raw_ostream &O) {
1706 ARMVCC::VPTCodes CC = (ARMVCC::VPTCodes)MI->getOperand(OpNum).getImm();
1707 if (CC != ARMVCC::None)
1708 O << ARMVPTPredToString(CC);
1709}
1710
1711void ARMInstPrinter::printVPTMask(const MCInst *MI, unsigned OpNum,
1712 const MCSubtargetInfo &STI,
1713 raw_ostream &O) {
1714 // (3 - the number of trailing zeroes) is the number of them / else.
1715 unsigned Mask = MI->getOperand(OpNum).getImm();
1716 unsigned NumTZ = llvm::countr_zero(Mask);
1717 assert(NumTZ <= 3 && "Invalid VPT mask!");
1718 for (unsigned Pos = 3, e = NumTZ; Pos > e; --Pos) {
1719 bool T = ((Mask >> Pos) & 1) == 0;
1720 if (T)
1721 O << 't';
1722 else
1723 O << 'e';
1724 }
1725}
1726
1728 const MCSubtargetInfo &STI,
1729 raw_ostream &O) {
1730 uint32_t Val = MI->getOperand(OpNum).getImm();
1731 assert(Val <= 1 && "Invalid MVE saturate operand");
1732 O << "#" << (Val == 1 ? 48 : 64);
1733}
unsigned const MachineRegisterInfo * MRI
static bool isStore(int Opcode)
static void printRegImmShift(raw_ostream &O, ARM_AM::ShiftOpc ShOpc, unsigned ShImm, ARMInstPrinter &printer)
static unsigned translateShiftImm(unsigned imm)
translateShiftImm - Convert shift immediate from 0-31 to 1-32 for printing.
static uint64_t scale(uint64_t Num, uint32_t N, uint32_t D)
dxil pretty printer
std::string Name
#define op(i)
IRTranslator LLVM IR MI
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
raw_pwrite_stream & OS
Value * RHS
Value * LHS
void printT2AddrModeImm0_1020s4Operand(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
void printMVEVectorList(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
void printVectorListTwoAllLanes(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
void printCPSIFlag(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
void printSBitModifierOperand(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
void printVectorListFour(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
void printThumbAddrModeImm5S1Operand(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
void printPKHASRShiftImm(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
void printVPTPredicateOperand(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
void printInstSyncBOption(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
void printAddrMode7Operand(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
void printRegisterList(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
void printOperand(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI, raw_ostream &O)
void printSORegRegOperand(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
void printComplexRotationOp(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
void printMveSaturateOp(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
void printVectorListTwo(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
void printFBits16(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
ARMInstPrinter(const MCAsmInfo &MAI, const MCInstrInfo &MII, const MCRegisterInfo &MRI)
void printAM2PreOrOffsetIndexOp(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
void printPCLabel(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
void printAddrMode3OffsetOperand(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
void printCPSIMod(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
void printVectorListTwoSpaced(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
void printT2AddrModeImm8Operand(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
bool applyTargetSpecificCLOption(StringRef Opt) override
Customize the printer according to a command line option.
virtual bool printAliasInstr(const MCInst *MI, uint64_t Address, const MCSubtargetInfo &STI, raw_ostream &O)
void printThumbAddrModeImm5S4Operand(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
void printAddrMode3Operand(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
void printMveAddrModeRQOperand(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
void printThumbLdrLabelOperand(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
void printVectorListTwoSpacedAllLanes(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
void printT2SOOperand(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
void printAddrModeTBB(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
void printVectorListOne(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
void printThumbITMask(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
void printPostIdxImm8Operand(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
void printAddrMode6OffsetOperand(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
void printAddrMode5Operand(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
void printVectorListThreeSpaced(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
void printImmPlusOneOperand(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
void printTraceSyncBOption(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
void printInstruction(const MCInst *MI, uint64_t Address, const MCSubtargetInfo &STI, raw_ostream &O)
void printPredicateOperand(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
void printAddrMode2Operand(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
void printGPRPairOperand(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
void printT2AddrModeImm8s4OffsetOperand(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
void printThumbAddrModeSPOperand(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
void printVectorListFourAllLanes(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
void printBitfieldInvMaskImmOperand(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
void printPostIdxImm8s4Operand(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
void printCImmediate(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
void printRegName(raw_ostream &OS, MCRegister Reg) override
Print the assembler register name.
void printFBits32(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
void printVectorListThreeAllLanes(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
void printRotImmOperand(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
void printMandatoryPredicateOperand(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
void printMemBOption(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
void printVectorListThreeSpacedAllLanes(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
void printInst(const MCInst *MI, uint64_t Address, StringRef Annot, const MCSubtargetInfo &STI, raw_ostream &O) override
Print the specified MCInst to the specified raw_ostream.
void printPostIdxRegOperand(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
static const char * getRegisterName(MCRegister Reg, unsigned AltIdx=ARM::NoRegAltName)
void printFPImmOperand(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
void printT2AddrModeImm8OffsetOperand(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
void printCoprocOptionImm(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
void printThumbAddrModeRROperand(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
void printT2AddrModeSoRegOperand(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
void printShiftImmOperand(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
void printMSRMaskOperand(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
void printT2AddrModeImm8s4Operand(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
void printSORegImmOperand(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
void printPKHLSLShiftImm(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
void printBankedRegOperand(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
void printThumbSRImm(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
void printModImmOperand(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
void printSetendOperand(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
void printVectorListOneAllLanes(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
void printThumbAddrModeImm5S2Operand(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
void printAddrMode2OffsetOperand(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
void printAddrMode6Operand(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
void printMandatoryRestrictedPredicateOperand(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
void printVectorListFourSpacedAllLanes(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
void printPImmediate(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
void printThumbS4ImmOperand(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
void printVPTMask(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
void printVectorListThree(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
void printVectorListFourSpaced(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
void printVMOVModImmOperand(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
void printAdrLabelOperand(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
void printAddrModeImm12Operand(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
void printAM3PreOrOffsetIndexOp(const MCInst *MI, unsigned Op, raw_ostream &O, bool AlwaysPrintImm0)
void printThumbAddrModeImm5SOperand(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O, unsigned Scale)
void printAddrModeTBH(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
void printNoHashImmediate(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
void printVectorIndex(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
void printLdStmModeOperand(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
void printAddrMode5FP16Operand(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
void printMandatoryInvertedPredicateOperand(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
This is an important base class in LLVM.
Definition: Constant.h:42
This class represents an Operation in the Expression.
Container class for subtarget features.
This class is intended to be used as a base class for asm properties and features specific to the tar...
Definition: MCAsmInfo.h:56
Base class for the full range of assembler expressions which are needed for parsing.
Definition: MCExpr.h:34
@ Constant
Constant expressions.
Definition: MCExpr.h:38
@ Binary
Binary expressions.
Definition: MCExpr.h:37
void print(raw_ostream &OS, const MCAsmInfo *MAI, bool InParens=false) const
Definition: MCExpr.cpp:40
ExprKind getKind() const
Definition: MCExpr.h:78
This is an instance of a target assembly language printer that converts an MCInst to valid target ass...
Definition: MCInstPrinter.h:46
WithMarkup markup(raw_ostream &OS, Markup M)
format_object< int64_t > formatHex(int64_t Value) const
const MCInstrInfo & MII
Definition: MCInstPrinter.h:53
raw_ostream * CommentStream
A stream that comments can be emitted to if desired.
Definition: MCInstPrinter.h:51
const MCRegisterInfo & MRI
Definition: MCInstPrinter.h:54
void printAnnotation(raw_ostream &OS, StringRef Annot)
Utility function for printing annotations.
const MCAsmInfo & MAI
Definition: MCInstPrinter.h:52
format_object< int64_t > formatImm(int64_t Value) const
Utility function to print immediates in decimal or hex.
bool getUseMarkup() const
bool PrintBranchImmAsAddress
If true, a branch immediate (e.g.
Definition: MCInstPrinter.h:75
Instances of this class represent a single low-level machine instruction.
Definition: MCInst.h:185
void addOperand(const MCOperand Op)
Definition: MCInst.h:211
void setOpcode(unsigned Op)
Definition: MCInst.h:198
Interface to description of machine instruction set.
Definition: MCInstrInfo.h:26
const MCInstrDesc & get(unsigned Opcode) const
Return the machine instruction descriptor that corresponds to the specified instruction opcode.
Definition: MCInstrInfo.h:63
Instances of this class represent operands of the MCInst class.
Definition: MCInst.h:37
int64_t getImm() const
Definition: MCInst.h:81
static MCOperand createReg(MCRegister Reg)
Definition: MCInst.h:135
bool isImm() const
Definition: MCInst.h:63
bool isReg() const
Definition: MCInst.h:62
MCRegister getReg() const
Returns the register number.
Definition: MCInst.h:70
const MCExpr * getExpr() const
Definition: MCInst.h:115
bool isExpr() const
Definition: MCInst.h:66
MCRegisterClass - Base class of TargetRegisterClass.
bool contains(MCRegister Reg) const
contains - Return true if the specified register is included in this register class.
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
MCRegister getMatchingSuperReg(MCRegister Reg, unsigned SubIdx, const MCRegisterClass *RC) const
Return a super-register of the specified register Reg so its sub-register of index SubIdx is Reg.
uint16_t getEncodingValue(MCRegister Reg) const
Returns the encoding for Reg.
const MCRegisterClass & getRegClass(unsigned i) const
Returns the register class associated with the enumeration value.
MCRegister getSubReg(MCRegister Reg, unsigned Idx) const
Returns the physical register number of sub-register "Index" for physical register RegNo.
Wrapper class representing physical registers. Should be passed by value.
Definition: MCRegister.h:33
Generic base class for all target subtargets.
bool hasFeature(unsigned Feature) const
const FeatureBitset & getFeatureBits() const
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:51
Target - Wrapper for Target specific information.
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:52
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
static CondCodes getOppositeCondition(CondCodes CC)
Definition: ARMBaseInfo.h:48
const MClassSysReg * lookupMClassSysRegBy8bitSYSmValue(unsigned SYSm)
Definition: ARMBaseInfo.cpp:61
const MClassSysReg * lookupMClassSysRegAPSRNonDeprecated(unsigned SYSm)
Definition: ARMBaseInfo.cpp:56
const MClassSysReg * lookupMClassSysRegBy12bitSYSmValue(unsigned SYSm)
Definition: ARMBaseInfo.cpp:50
unsigned char getAM3Offset(unsigned AM3Opc)
unsigned char getAM5FP16Offset(unsigned AM5Opc)
unsigned getSORegOffset(unsigned Op)
int getSOImmVal(unsigned Arg)
getSOImmVal - Given a 32-bit immediate, if it is something that can fit into an shifter_operand immed...
ShiftOpc getAM2ShiftOpc(unsigned AM2Opc)
uint64_t decodeVMOVModImm(unsigned ModImm, unsigned &EltBits)
decodeVMOVModImm - Decode a NEON/MVE modified immediate value into the element value and the element ...
unsigned getAM2IdxMode(unsigned AM2Opc)
unsigned getAM3IdxMode(unsigned AM3Opc)
unsigned getAM2Offset(unsigned AM2Opc)
const char * getAMSubModeStr(AMSubMode Mode)
float getFPImmFloat(unsigned Imm)
ShiftOpc getSORegShOp(unsigned Op)
AddrOpc getAM5Op(unsigned AM5Opc)
AddrOpc getAM5FP16Op(unsigned AM5Opc)
const char * getAddrOpcStr(AddrOpc Op)
unsigned char getAM5Offset(unsigned AM5Opc)
const StringRef getShiftOpcStr(ShiftOpc Op)
AddrOpc getAM2Op(unsigned AM2Opc)
AddrOpc getAM3Op(unsigned AM3Opc)
AMSubMode getAM4SubMode(unsigned Mode)
static const char * InstSyncBOptToString(unsigned val)
Definition: ARMBaseInfo.h:134
static const char * MemBOptToString(unsigned val, bool HasV8)
Definition: ARMBaseInfo.h:77
uint64_t evaluateBranchTarget(const MCInstrDesc &InstDesc, uint64_t Addr, int64_t Imm)
static const char * IModToString(unsigned val)
Definition: ARMBaseInfo.h:46
static const char * IFlagsToString(unsigned val)
Definition: ARMBaseInfo.h:37
static const char * TraceSyncBOptToString(unsigned val)
Definition: ARMBaseInfo.h:105
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
auto drop_begin(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the first N elements excluded.
Definition: STLExtras.h:329
static const char * ARMVPTPredToString(ARMVCC::VPTCodes CC)
Definition: ARMBaseInfo.h:130
int bit_width(T Value)
Returns the number of bits needed to represent Value if Value is nonzero.
Definition: bit.h:317
int countr_zero(T Val)
Count number of 0's from the least significant bit to the most stopping at the first 1.
Definition: bit.h:215
bool is_sorted(R &&Range, Compare C)
Wrapper function around std::is_sorted to check if elements in a range R are sorted with respect to a...
Definition: STLExtras.h:1926
static const char * ARMCondCodeToString(ARMCC::CondCodes CC)
Definition: ARMBaseInfo.h:146