LLVM  3.7.0
ARMInstPrinter.cpp
Go to the documentation of this file.
1 //===-- ARMInstPrinter.cpp - Convert ARM MCInst to assembly syntax --------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This class prints an ARM MCInst to a .s file.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #include "ARMInstPrinter.h"
17 #include "llvm/MC/MCAsmInfo.h"
18 #include "llvm/MC/MCExpr.h"
19 #include "llvm/MC/MCInst.h"
20 #include "llvm/MC/MCInstrInfo.h"
21 #include "llvm/MC/MCRegisterInfo.h"
23 using namespace llvm;
24 
25 #define DEBUG_TYPE "asm-printer"
26 
27 #include "ARMGenAsmWriter.inc"
28 
29 /// translateShiftImm - Convert shift immediate from 0-31 to 1-32 for printing.
30 ///
31 /// getSORegOffset returns an integer from 0-31, representing '32' as 0.
32 static unsigned translateShiftImm(unsigned imm) {
33  // lsr #32 and asr #32 exist, but should be encoded as a 0.
34  assert((imm & ~0x1f) == 0 && "Invalid shift encoding");
35 
36  if (imm == 0)
37  return 32;
38  return imm;
39 }
40 
41 /// Prints the shift value with an immediate value.
43  unsigned ShImm, bool UseMarkup) {
44  if (ShOpc == ARM_AM::no_shift || (ShOpc == ARM_AM::lsl && !ShImm))
45  return;
46  O << ", ";
47 
48  assert(!(ShOpc == ARM_AM::ror && !ShImm) && "Cannot have ror #0");
49  O << getShiftOpcStr(ShOpc);
50 
51  if (ShOpc != ARM_AM::rrx) {
52  O << " ";
53  if (UseMarkup)
54  O << "<imm:";
55  O << "#" << translateShiftImm(ShImm);
56  if (UseMarkup)
57  O << ">";
58  }
59 }
60 
62  const MCRegisterInfo &MRI)
63  : MCInstPrinter(MAI, MII, MRI) {}
64 
65 void ARMInstPrinter::printRegName(raw_ostream &OS, unsigned RegNo) const {
66  OS << markup("<reg:") << getRegisterName(RegNo) << markup(">");
67 }
68 
70  StringRef Annot, const MCSubtargetInfo &STI) {
71  unsigned Opcode = MI->getOpcode();
72 
73  switch (Opcode) {
74 
75  // Check for HINT instructions w/ canonical names.
76  case ARM::HINT:
77  case ARM::tHINT:
78  case ARM::t2HINT:
79  switch (MI->getOperand(0).getImm()) {
80  case 0:
81  O << "\tnop";
82  break;
83  case 1:
84  O << "\tyield";
85  break;
86  case 2:
87  O << "\twfe";
88  break;
89  case 3:
90  O << "\twfi";
91  break;
92  case 4:
93  O << "\tsev";
94  break;
95  case 5:
96  if (STI.getFeatureBits()[ARM::HasV8Ops]) {
97  O << "\tsevl";
98  break;
99  } // Fallthrough for non-v8
100  default:
101  // Anything else should just print normally.
102  printInstruction(MI, STI, O);
103  printAnnotation(O, Annot);
104  return;
105  }
106  printPredicateOperand(MI, 1, STI, O);
107  if (Opcode == ARM::t2HINT)
108  O << ".w";
109  printAnnotation(O, Annot);
110  return;
111 
112  // Check for MOVs and print canonical forms, instead.
113  case ARM::MOVsr: {
114  // FIXME: Thumb variants?
115  const MCOperand &Dst = MI->getOperand(0);
116  const MCOperand &MO1 = MI->getOperand(1);
117  const MCOperand &MO2 = MI->getOperand(2);
118  const MCOperand &MO3 = MI->getOperand(3);
119 
121  printSBitModifierOperand(MI, 6, STI, O);
122  printPredicateOperand(MI, 4, STI, O);
123 
124  O << '\t';
125  printRegName(O, Dst.getReg());
126  O << ", ";
127  printRegName(O, MO1.getReg());
128 
129  O << ", ";
130  printRegName(O, MO2.getReg());
131  assert(ARM_AM::getSORegOffset(MO3.getImm()) == 0);
132  printAnnotation(O, Annot);
133  return;
134  }
135 
136  case ARM::MOVsi: {
137  // FIXME: Thumb variants?
138  const MCOperand &Dst = MI->getOperand(0);
139  const MCOperand &MO1 = MI->getOperand(1);
140  const MCOperand &MO2 = MI->getOperand(2);
141 
143  printSBitModifierOperand(MI, 5, STI, O);
144  printPredicateOperand(MI, 3, STI, O);
145 
146  O << '\t';
147  printRegName(O, Dst.getReg());
148  O << ", ";
149  printRegName(O, MO1.getReg());
150 
151  if (ARM_AM::getSORegShOp(MO2.getImm()) == ARM_AM::rrx) {
152  printAnnotation(O, Annot);
153  return;
154  }
155 
156  O << ", " << markup("<imm:") << "#"
158  printAnnotation(O, Annot);
159  return;
160  }
161 
162  // A8.6.123 PUSH
163  case ARM::STMDB_UPD:
164  case ARM::t2STMDB_UPD:
165  if (MI->getOperand(0).getReg() == ARM::SP && MI->getNumOperands() > 5) {
166  // Should only print PUSH if there are at least two registers in the list.
167  O << '\t' << "push";
168  printPredicateOperand(MI, 2, STI, O);
169  if (Opcode == ARM::t2STMDB_UPD)
170  O << ".w";
171  O << '\t';
172  printRegisterList(MI, 4, STI, O);
173  printAnnotation(O, Annot);
174  return;
175  } else
176  break;
177 
178  case ARM::STR_PRE_IMM:
179  if (MI->getOperand(2).getReg() == ARM::SP &&
180  MI->getOperand(3).getImm() == -4) {
181  O << '\t' << "push";
182  printPredicateOperand(MI, 4, STI, O);
183  O << "\t{";
184  printRegName(O, MI->getOperand(1).getReg());
185  O << "}";
186  printAnnotation(O, Annot);
187  return;
188  } else
189  break;
190 
191  // A8.6.122 POP
192  case ARM::LDMIA_UPD:
193  case ARM::t2LDMIA_UPD:
194  if (MI->getOperand(0).getReg() == ARM::SP && MI->getNumOperands() > 5) {
195  // Should only print POP if there are at least two registers in the list.
196  O << '\t' << "pop";
197  printPredicateOperand(MI, 2, STI, O);
198  if (Opcode == ARM::t2LDMIA_UPD)
199  O << ".w";
200  O << '\t';
201  printRegisterList(MI, 4, STI, O);
202  printAnnotation(O, Annot);
203  return;
204  } else
205  break;
206 
207  case ARM::LDR_POST_IMM:
208  if (MI->getOperand(2).getReg() == ARM::SP &&
209  MI->getOperand(4).getImm() == 4) {
210  O << '\t' << "pop";
211  printPredicateOperand(MI, 5, STI, O);
212  O << "\t{";
213  printRegName(O, MI->getOperand(0).getReg());
214  O << "}";
215  printAnnotation(O, Annot);
216  return;
217  } else
218  break;
219 
220  // A8.6.355 VPUSH
221  case ARM::VSTMSDB_UPD:
222  case ARM::VSTMDDB_UPD:
223  if (MI->getOperand(0).getReg() == ARM::SP) {
224  O << '\t' << "vpush";
225  printPredicateOperand(MI, 2, STI, O);
226  O << '\t';
227  printRegisterList(MI, 4, STI, O);
228  printAnnotation(O, Annot);
229  return;
230  } else
231  break;
232 
233  // A8.6.354 VPOP
234  case ARM::VLDMSIA_UPD:
235  case ARM::VLDMDIA_UPD:
236  if (MI->getOperand(0).getReg() == ARM::SP) {
237  O << '\t' << "vpop";
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  case ARM::tLDMIA: {
247  bool Writeback = true;
248  unsigned BaseReg = MI->getOperand(0).getReg();
249  for (unsigned i = 3; i < MI->getNumOperands(); ++i) {
250  if (MI->getOperand(i).getReg() == BaseReg)
251  Writeback = false;
252  }
253 
254  O << "\tldm";
255 
256  printPredicateOperand(MI, 1, STI, O);
257  O << '\t';
258  printRegName(O, BaseReg);
259  if (Writeback)
260  O << "!";
261  O << ", ";
262  printRegisterList(MI, 3, STI, O);
263  printAnnotation(O, Annot);
264  return;
265  }
266 
267  // Combine 2 GPRs from disassember into a GPRPair to match with instr def.
268  // ldrexd/strexd require even/odd GPR pair. To enforce this constraint,
269  // a single GPRPair reg operand is used in the .td file to replace the two
270  // GPRs. However, when decoding them, the two GRPs cannot be automatically
271  // expressed as a GPRPair, so we have to manually merge them.
272  // FIXME: We would really like to be able to tablegen'erate this.
273  case ARM::LDREXD:
274  case ARM::STREXD:
275  case ARM::LDAEXD:
276  case ARM::STLEXD: {
277  const MCRegisterClass &MRC = MRI.getRegClass(ARM::GPRRegClassID);
278  bool isStore = Opcode == ARM::STREXD || Opcode == ARM::STLEXD;
279  unsigned Reg = MI->getOperand(isStore ? 1 : 0).getReg();
280  if (MRC.contains(Reg)) {
281  MCInst NewMI;
282  MCOperand NewReg;
283  NewMI.setOpcode(Opcode);
284 
285  if (isStore)
286  NewMI.addOperand(MI->getOperand(0));
288  Reg, ARM::gsub_0, &MRI.getRegClass(ARM::GPRPairRegClassID)));
289  NewMI.addOperand(NewReg);
290 
291  // Copy the rest operands into NewMI.
292  for (unsigned i = isStore ? 3 : 2; i < MI->getNumOperands(); ++i)
293  NewMI.addOperand(MI->getOperand(i));
294  printInstruction(&NewMI, STI, O);
295  return;
296  }
297  break;
298  }
299  // B9.3.3 ERET (Thumb)
300  // For a target that has Virtualization Extensions, ERET is the preferred
301  // disassembly of SUBS PC, LR, #0
302  case ARM::t2SUBS_PC_LR: {
303  if (MI->getNumOperands() == 3 && MI->getOperand(0).isImm() &&
304  MI->getOperand(0).getImm() == 0 &&
305  STI.getFeatureBits()[ARM::FeatureVirtualization]) {
306  O << "\teret";
307  printPredicateOperand(MI, 1, STI, O);
308  printAnnotation(O, Annot);
309  return;
310  }
311  break;
312  }
313  }
314 
315  printInstruction(MI, STI, O);
316  printAnnotation(O, Annot);
317 }
318 
319 void ARMInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
320  const MCSubtargetInfo &STI, raw_ostream &O) {
321  const MCOperand &Op = MI->getOperand(OpNo);
322  if (Op.isReg()) {
323  unsigned Reg = Op.getReg();
324  printRegName(O, Reg);
325  } else if (Op.isImm()) {
326  O << markup("<imm:") << '#' << formatImm(Op.getImm()) << markup(">");
327  } else {
328  assert(Op.isExpr() && "unknown operand kind in printOperand");
329  const MCExpr *Expr = Op.getExpr();
330  switch (Expr->getKind()) {
331  case MCExpr::Binary:
332  O << '#';
333  Expr->print(O, &MAI);
334  break;
335  case MCExpr::Constant: {
336  // If a symbolic branch target was added as a constant expression then
337  // print that address in hex. And only print 32 unsigned bits for the
338  // address.
339  const MCConstantExpr *Constant = cast<MCConstantExpr>(Expr);
340  int64_t TargetAddress;
341  if (!Constant->evaluateAsAbsolute(TargetAddress)) {
342  O << '#';
343  Expr->print(O, &MAI);
344  } else {
345  O << "0x";
346  O.write_hex(static_cast<uint32_t>(TargetAddress));
347  }
348  break;
349  }
350  default:
351  // FIXME: Should we always treat this as if it is a constant literal and
352  // prefix it with '#'?
353  Expr->print(O, &MAI);
354  break;
355  }
356  }
357 }
358 
360  const MCSubtargetInfo &STI,
361  raw_ostream &O) {
362  const MCOperand &MO1 = MI->getOperand(OpNum);
363  if (MO1.isExpr()) {
364  MO1.getExpr()->print(O, &MAI);
365  return;
366  }
367 
368  O << markup("<mem:") << "[pc, ";
369 
370  int32_t OffImm = (int32_t)MO1.getImm();
371  bool isSub = OffImm < 0;
372 
373  // Special value for #-0. All others are normal.
374  if (OffImm == INT32_MIN)
375  OffImm = 0;
376  if (isSub) {
377  O << markup("<imm:") << "#-" << formatImm(-OffImm) << markup(">");
378  } else {
379  O << markup("<imm:") << "#" << formatImm(OffImm) << markup(">");
380  }
381  O << "]" << markup(">");
382 }
383 
384 // so_reg is a 4-operand unit corresponding to register forms of the A5.1
385 // "Addressing Mode 1 - Data-processing operands" forms. This includes:
386 // REG 0 0 - e.g. R5
387 // REG REG 0,SH_OPC - e.g. R5, ROR R3
388 // REG 0 IMM,SH_OPC - e.g. R5, LSL #3
389 void ARMInstPrinter::printSORegRegOperand(const MCInst *MI, unsigned OpNum,
390  const MCSubtargetInfo &STI,
391  raw_ostream &O) {
392  const MCOperand &MO1 = MI->getOperand(OpNum);
393  const MCOperand &MO2 = MI->getOperand(OpNum + 1);
394  const MCOperand &MO3 = MI->getOperand(OpNum + 2);
395 
396  printRegName(O, MO1.getReg());
397 
398  // Print the shift opc.
400  O << ", " << ARM_AM::getShiftOpcStr(ShOpc);
401  if (ShOpc == ARM_AM::rrx)
402  return;
403 
404  O << ' ';
405  printRegName(O, MO2.getReg());
406  assert(ARM_AM::getSORegOffset(MO3.getImm()) == 0);
407 }
408 
409 void ARMInstPrinter::printSORegImmOperand(const MCInst *MI, unsigned OpNum,
410  const MCSubtargetInfo &STI,
411  raw_ostream &O) {
412  const MCOperand &MO1 = MI->getOperand(OpNum);
413  const MCOperand &MO2 = MI->getOperand(OpNum + 1);
414 
415  printRegName(O, MO1.getReg());
416 
417  // Print the shift opc.
420 }
421 
422 //===--------------------------------------------------------------------===//
423 // Addressing Mode #2
424 //===--------------------------------------------------------------------===//
425 
427  const MCSubtargetInfo &STI,
428  raw_ostream &O) {
429  const MCOperand &MO1 = MI->getOperand(Op);
430  const MCOperand &MO2 = MI->getOperand(Op + 1);
431  const MCOperand &MO3 = MI->getOperand(Op + 2);
432 
433  O << markup("<mem:") << "[";
434  printRegName(O, MO1.getReg());
435 
436  if (!MO2.getReg()) {
437  if (ARM_AM::getAM2Offset(MO3.getImm())) { // Don't print +0.
438  O << ", " << markup("<imm:") << "#"
440  << ARM_AM::getAM2Offset(MO3.getImm()) << markup(">");
441  }
442  O << "]" << markup(">");
443  return;
444  }
445 
446  O << ", ";
448  printRegName(O, MO2.getReg());
449 
452  O << "]" << markup(">");
453 }
454 
455 void ARMInstPrinter::printAddrModeTBB(const MCInst *MI, unsigned Op,
456  const MCSubtargetInfo &STI,
457  raw_ostream &O) {
458  const MCOperand &MO1 = MI->getOperand(Op);
459  const MCOperand &MO2 = MI->getOperand(Op + 1);
460  O << markup("<mem:") << "[";
461  printRegName(O, MO1.getReg());
462  O << ", ";
463  printRegName(O, MO2.getReg());
464  O << "]" << markup(">");
465 }
466 
467 void ARMInstPrinter::printAddrModeTBH(const MCInst *MI, unsigned Op,
468  const MCSubtargetInfo &STI,
469  raw_ostream &O) {
470  const MCOperand &MO1 = MI->getOperand(Op);
471  const MCOperand &MO2 = MI->getOperand(Op + 1);
472  O << markup("<mem:") << "[";
473  printRegName(O, MO1.getReg());
474  O << ", ";
475  printRegName(O, MO2.getReg());
476  O << ", lsl " << markup("<imm:") << "#1" << markup(">") << "]" << markup(">");
477 }
478 
480  const MCSubtargetInfo &STI,
481  raw_ostream &O) {
482  const MCOperand &MO1 = MI->getOperand(Op);
483 
484  if (!MO1.isReg()) { // FIXME: This is for CP entries, but isn't right.
485  printOperand(MI, Op, STI, O);
486  return;
487  }
488 
489 #ifndef NDEBUG
490  const MCOperand &MO3 = MI->getOperand(Op + 2);
491  unsigned IdxMode = ARM_AM::getAM2IdxMode(MO3.getImm());
492  assert(IdxMode != ARMII::IndexModePost && "Should be pre or offset index op");
493 #endif
494 
495  printAM2PreOrOffsetIndexOp(MI, Op, STI, O);
496 }
497 
499  unsigned OpNum,
500  const MCSubtargetInfo &STI,
501  raw_ostream &O) {
502  const MCOperand &MO1 = MI->getOperand(OpNum);
503  const MCOperand &MO2 = MI->getOperand(OpNum + 1);
504 
505  if (!MO1.getReg()) {
506  unsigned ImmOffs = ARM_AM::getAM2Offset(MO2.getImm());
507  O << markup("<imm:") << '#'
508  << ARM_AM::getAddrOpcStr(ARM_AM::getAM2Op(MO2.getImm())) << ImmOffs
509  << markup(">");
510  return;
511  }
512 
514  printRegName(O, MO1.getReg());
515 
518 }
519 
520 //===--------------------------------------------------------------------===//
521 // Addressing Mode #3
522 //===--------------------------------------------------------------------===//
523 
525  raw_ostream &O,
526  bool AlwaysPrintImm0) {
527  const MCOperand &MO1 = MI->getOperand(Op);
528  const MCOperand &MO2 = MI->getOperand(Op + 1);
529  const MCOperand &MO3 = MI->getOperand(Op + 2);
530 
531  O << markup("<mem:") << '[';
532  printRegName(O, MO1.getReg());
533 
534  if (MO2.getReg()) {
535  O << ", " << getAddrOpcStr(ARM_AM::getAM3Op(MO3.getImm()));
536  printRegName(O, MO2.getReg());
537  O << ']' << markup(">");
538  return;
539  }
540 
541  // If the op is sub we have to print the immediate even if it is 0
542  unsigned ImmOffs = ARM_AM::getAM3Offset(MO3.getImm());
544 
545  if (AlwaysPrintImm0 || ImmOffs || (op == ARM_AM::sub)) {
546  O << ", " << markup("<imm:") << "#" << ARM_AM::getAddrOpcStr(op) << ImmOffs
547  << markup(">");
548  }
549  O << ']' << markup(">");
550 }
551 
552 template <bool AlwaysPrintImm0>
554  const MCSubtargetInfo &STI,
555  raw_ostream &O) {
556  const MCOperand &MO1 = MI->getOperand(Op);
557  if (!MO1.isReg()) { // For label symbolic references.
558  printOperand(MI, Op, STI, O);
559  return;
560  }
561 
562  assert(ARM_AM::getAM3IdxMode(MI->getOperand(Op + 2).getImm()) !=
564  "unexpected idxmode");
565  printAM3PreOrOffsetIndexOp(MI, Op, O, AlwaysPrintImm0);
566 }
567 
569  unsigned OpNum,
570  const MCSubtargetInfo &STI,
571  raw_ostream &O) {
572  const MCOperand &MO1 = MI->getOperand(OpNum);
573  const MCOperand &MO2 = MI->getOperand(OpNum + 1);
574 
575  if (MO1.getReg()) {
577  printRegName(O, MO1.getReg());
578  return;
579  }
580 
581  unsigned ImmOffs = ARM_AM::getAM3Offset(MO2.getImm());
582  O << markup("<imm:") << '#'
583  << ARM_AM::getAddrOpcStr(ARM_AM::getAM3Op(MO2.getImm())) << ImmOffs
584  << markup(">");
585 }
586 
588  const MCSubtargetInfo &STI,
589  raw_ostream &O) {
590  const MCOperand &MO = MI->getOperand(OpNum);
591  unsigned Imm = MO.getImm();
592  O << markup("<imm:") << '#' << ((Imm & 256) ? "" : "-") << (Imm & 0xff)
593  << markup(">");
594 }
595 
597  const MCSubtargetInfo &STI,
598  raw_ostream &O) {
599  const MCOperand &MO1 = MI->getOperand(OpNum);
600  const MCOperand &MO2 = MI->getOperand(OpNum + 1);
601 
602  O << (MO2.getImm() ? "" : "-");
603  printRegName(O, MO1.getReg());
604 }
605 
607  const MCSubtargetInfo &STI,
608  raw_ostream &O) {
609  const MCOperand &MO = MI->getOperand(OpNum);
610  unsigned Imm = MO.getImm();
611  O << markup("<imm:") << '#' << ((Imm & 256) ? "" : "-") << ((Imm & 0xff) << 2)
612  << markup(">");
613 }
614 
615 void ARMInstPrinter::printLdStmModeOperand(const MCInst *MI, unsigned OpNum,
616  const MCSubtargetInfo &STI,
617  raw_ostream &O) {
618  ARM_AM::AMSubMode Mode =
620  O << ARM_AM::getAMSubModeStr(Mode);
621 }
622 
623 template <bool AlwaysPrintImm0>
624 void ARMInstPrinter::printAddrMode5Operand(const MCInst *MI, unsigned OpNum,
625  const MCSubtargetInfo &STI,
626  raw_ostream &O) {
627  const MCOperand &MO1 = MI->getOperand(OpNum);
628  const MCOperand &MO2 = MI->getOperand(OpNum + 1);
629 
630  if (!MO1.isReg()) { // FIXME: This is for CP entries, but isn't right.
631  printOperand(MI, OpNum, STI, O);
632  return;
633  }
634 
635  O << markup("<mem:") << "[";
636  printRegName(O, MO1.getReg());
637 
638  unsigned ImmOffs = ARM_AM::getAM5Offset(MO2.getImm());
640  if (AlwaysPrintImm0 || ImmOffs || Op == ARM_AM::sub) {
641  O << ", " << markup("<imm:") << "#" << ARM_AM::getAddrOpcStr(Op)
642  << ImmOffs * 4 << markup(">");
643  }
644  O << "]" << markup(">");
645 }
646 
647 void ARMInstPrinter::printAddrMode6Operand(const MCInst *MI, unsigned OpNum,
648  const MCSubtargetInfo &STI,
649  raw_ostream &O) {
650  const MCOperand &MO1 = MI->getOperand(OpNum);
651  const MCOperand &MO2 = MI->getOperand(OpNum + 1);
652 
653  O << markup("<mem:") << "[";
654  printRegName(O, MO1.getReg());
655  if (MO2.getImm()) {
656  O << ":" << (MO2.getImm() << 3);
657  }
658  O << "]" << markup(">");
659 }
660 
661 void ARMInstPrinter::printAddrMode7Operand(const MCInst *MI, unsigned OpNum,
662  const MCSubtargetInfo &STI,
663  raw_ostream &O) {
664  const MCOperand &MO1 = MI->getOperand(OpNum);
665  O << markup("<mem:") << "[";
666  printRegName(O, MO1.getReg());
667  O << "]" << markup(">");
668 }
669 
671  unsigned OpNum,
672  const MCSubtargetInfo &STI,
673  raw_ostream &O) {
674  const MCOperand &MO = MI->getOperand(OpNum);
675  if (MO.getReg() == 0)
676  O << "!";
677  else {
678  O << ", ";
679  printRegName(O, MO.getReg());
680  }
681 }
682 
684  unsigned OpNum,
685  const MCSubtargetInfo &STI,
686  raw_ostream &O) {
687  const MCOperand &MO = MI->getOperand(OpNum);
688  uint32_t v = ~MO.getImm();
689  int32_t lsb = countTrailingZeros(v);
690  int32_t width = (32 - countLeadingZeros(v)) - lsb;
691  assert(MO.isImm() && "Not a valid bf_inv_mask_imm value!");
692  O << markup("<imm:") << '#' << lsb << markup(">") << ", " << markup("<imm:")
693  << '#' << width << markup(">");
694 }
695 
696 void ARMInstPrinter::printMemBOption(const MCInst *MI, unsigned OpNum,
697  const MCSubtargetInfo &STI,
698  raw_ostream &O) {
699  unsigned val = MI->getOperand(OpNum).getImm();
700  O << ARM_MB::MemBOptToString(val, STI.getFeatureBits()[ARM::HasV8Ops]);
701 }
702 
703 void ARMInstPrinter::printInstSyncBOption(const MCInst *MI, unsigned OpNum,
704  const MCSubtargetInfo &STI,
705  raw_ostream &O) {
706  unsigned val = MI->getOperand(OpNum).getImm();
708 }
709 
710 void ARMInstPrinter::printShiftImmOperand(const MCInst *MI, unsigned OpNum,
711  const MCSubtargetInfo &STI,
712  raw_ostream &O) {
713  unsigned ShiftOp = MI->getOperand(OpNum).getImm();
714  bool isASR = (ShiftOp & (1 << 5)) != 0;
715  unsigned Amt = ShiftOp & 0x1f;
716  if (isASR) {
717  O << ", asr " << markup("<imm:") << "#" << (Amt == 0 ? 32 : Amt)
718  << markup(">");
719  } else if (Amt) {
720  O << ", lsl " << markup("<imm:") << "#" << Amt << markup(">");
721  }
722 }
723 
724 void ARMInstPrinter::printPKHLSLShiftImm(const MCInst *MI, unsigned OpNum,
725  const MCSubtargetInfo &STI,
726  raw_ostream &O) {
727  unsigned Imm = MI->getOperand(OpNum).getImm();
728  if (Imm == 0)
729  return;
730  assert(Imm > 0 && Imm < 32 && "Invalid PKH shift immediate value!");
731  O << ", lsl " << markup("<imm:") << "#" << Imm << markup(">");
732 }
733 
734 void ARMInstPrinter::printPKHASRShiftImm(const MCInst *MI, unsigned OpNum,
735  const MCSubtargetInfo &STI,
736  raw_ostream &O) {
737  unsigned Imm = MI->getOperand(OpNum).getImm();
738  // A shift amount of 32 is encoded as 0.
739  if (Imm == 0)
740  Imm = 32;
741  assert(Imm > 0 && Imm <= 32 && "Invalid PKH shift immediate value!");
742  O << ", asr " << markup("<imm:") << "#" << Imm << markup(">");
743 }
744 
745 void ARMInstPrinter::printRegisterList(const MCInst *MI, unsigned OpNum,
746  const MCSubtargetInfo &STI,
747  raw_ostream &O) {
748  O << "{";
749  for (unsigned i = OpNum, e = MI->getNumOperands(); i != e; ++i) {
750  if (i != OpNum)
751  O << ", ";
752  printRegName(O, MI->getOperand(i).getReg());
753  }
754  O << "}";
755 }
756 
757 void ARMInstPrinter::printGPRPairOperand(const MCInst *MI, unsigned OpNum,
758  const MCSubtargetInfo &STI,
759  raw_ostream &O) {
760  unsigned Reg = MI->getOperand(OpNum).getReg();
761  printRegName(O, MRI.getSubReg(Reg, ARM::gsub_0));
762  O << ", ";
763  printRegName(O, MRI.getSubReg(Reg, ARM::gsub_1));
764 }
765 
766 void ARMInstPrinter::printSetendOperand(const MCInst *MI, unsigned OpNum,
767  const MCSubtargetInfo &STI,
768  raw_ostream &O) {
769  const MCOperand &Op = MI->getOperand(OpNum);
770  if (Op.getImm())
771  O << "be";
772  else
773  O << "le";
774 }
775 
776 void ARMInstPrinter::printCPSIMod(const MCInst *MI, unsigned OpNum,
777  const MCSubtargetInfo &STI, raw_ostream &O) {
778  const MCOperand &Op = MI->getOperand(OpNum);
779  O << ARM_PROC::IModToString(Op.getImm());
780 }
781 
782 void ARMInstPrinter::printCPSIFlag(const MCInst *MI, unsigned OpNum,
783  const MCSubtargetInfo &STI, raw_ostream &O) {
784  const MCOperand &Op = MI->getOperand(OpNum);
785  unsigned IFlags = Op.getImm();
786  for (int i = 2; i >= 0; --i)
787  if (IFlags & (1 << i))
788  O << ARM_PROC::IFlagsToString(1 << i);
789 
790  if (IFlags == 0)
791  O << "none";
792 }
793 
794 void ARMInstPrinter::printMSRMaskOperand(const MCInst *MI, unsigned OpNum,
795  const MCSubtargetInfo &STI,
796  raw_ostream &O) {
797  const MCOperand &Op = MI->getOperand(OpNum);
798  unsigned SpecRegRBit = Op.getImm() >> 4;
799  unsigned Mask = Op.getImm() & 0xf;
800  const FeatureBitset &FeatureBits = STI.getFeatureBits();
801 
802  if (FeatureBits[ARM::FeatureMClass]) {
803  unsigned SYSm = Op.getImm();
804  unsigned Opcode = MI->getOpcode();
805 
806  // For writes, handle extended mask bits if the DSP extension is present.
807  if (Opcode == ARM::t2MSR_M && FeatureBits[ARM::FeatureDSPThumb2]) {
808  switch (SYSm) {
809  case 0x400:
810  O << "apsr_g";
811  return;
812  case 0xc00:
813  O << "apsr_nzcvqg";
814  return;
815  case 0x401:
816  O << "iapsr_g";
817  return;
818  case 0xc01:
819  O << "iapsr_nzcvqg";
820  return;
821  case 0x402:
822  O << "eapsr_g";
823  return;
824  case 0xc02:
825  O << "eapsr_nzcvqg";
826  return;
827  case 0x403:
828  O << "xpsr_g";
829  return;
830  case 0xc03:
831  O << "xpsr_nzcvqg";
832  return;
833  }
834  }
835 
836  // Handle the basic 8-bit mask.
837  SYSm &= 0xff;
838 
839  if (Opcode == ARM::t2MSR_M && FeatureBits [ARM::HasV7Ops]) {
840  // ARMv7-M deprecates using MSR APSR without a _<bits> qualifier as an
841  // alias for MSR APSR_nzcvq.
842  switch (SYSm) {
843  case 0:
844  O << "apsr_nzcvq";
845  return;
846  case 1:
847  O << "iapsr_nzcvq";
848  return;
849  case 2:
850  O << "eapsr_nzcvq";
851  return;
852  case 3:
853  O << "xpsr_nzcvq";
854  return;
855  }
856  }
857 
858  switch (SYSm) {
859  default:
860  llvm_unreachable("Unexpected mask value!");
861  case 0:
862  O << "apsr";
863  return;
864  case 1:
865  O << "iapsr";
866  return;
867  case 2:
868  O << "eapsr";
869  return;
870  case 3:
871  O << "xpsr";
872  return;
873  case 5:
874  O << "ipsr";
875  return;
876  case 6:
877  O << "epsr";
878  return;
879  case 7:
880  O << "iepsr";
881  return;
882  case 8:
883  O << "msp";
884  return;
885  case 9:
886  O << "psp";
887  return;
888  case 16:
889  O << "primask";
890  return;
891  case 17:
892  O << "basepri";
893  return;
894  case 18:
895  O << "basepri_max";
896  return;
897  case 19:
898  O << "faultmask";
899  return;
900  case 20:
901  O << "control";
902  return;
903  }
904  }
905 
906  // As special cases, CPSR_f, CPSR_s and CPSR_fs prefer printing as
907  // APSR_nzcvq, APSR_g and APSRnzcvqg, respectively.
908  if (!SpecRegRBit && (Mask == 8 || Mask == 4 || Mask == 12)) {
909  O << "APSR_";
910  switch (Mask) {
911  default:
912  llvm_unreachable("Unexpected mask value!");
913  case 4:
914  O << "g";
915  return;
916  case 8:
917  O << "nzcvq";
918  return;
919  case 12:
920  O << "nzcvqg";
921  return;
922  }
923  }
924 
925  if (SpecRegRBit)
926  O << "SPSR";
927  else
928  O << "CPSR";
929 
930  if (Mask) {
931  O << '_';
932  if (Mask & 8)
933  O << 'f';
934  if (Mask & 4)
935  O << 's';
936  if (Mask & 2)
937  O << 'x';
938  if (Mask & 1)
939  O << 'c';
940  }
941 }
942 
943 void ARMInstPrinter::printBankedRegOperand(const MCInst *MI, unsigned OpNum,
944  const MCSubtargetInfo &STI,
945  raw_ostream &O) {
946  uint32_t Banked = MI->getOperand(OpNum).getImm();
947  uint32_t R = (Banked & 0x20) >> 5;
948  uint32_t SysM = Banked & 0x1f;
949 
950  // Nothing much we can do about this, the encodings are specified in B9.2.3 of
951  // the ARM ARM v7C, and are all over the shop.
952  if (R) {
953  O << "SPSR_";
954 
955  switch (SysM) {
956  case 0x0e:
957  O << "fiq";
958  return;
959  case 0x10:
960  O << "irq";
961  return;
962  case 0x12:
963  O << "svc";
964  return;
965  case 0x14:
966  O << "abt";
967  return;
968  case 0x16:
969  O << "und";
970  return;
971  case 0x1c:
972  O << "mon";
973  return;
974  case 0x1e:
975  O << "hyp";
976  return;
977  default:
978  llvm_unreachable("Invalid banked SPSR register");
979  }
980  }
981 
982  assert(!R && "should have dealt with SPSR regs");
983  const char *RegNames[] = {
984  "r8_usr", "r9_usr", "r10_usr", "r11_usr", "r12_usr", "sp_usr", "lr_usr",
985  "", "r8_fiq", "r9_fiq", "r10_fiq", "r11_fiq", "r12_fiq", "sp_fiq",
986  "lr_fiq", "", "lr_irq", "sp_irq", "lr_svc", "sp_svc", "lr_abt",
987  "sp_abt", "lr_und", "sp_und", "", "", "", "",
988  "lr_mon", "sp_mon", "elr_hyp", "sp_hyp"};
989  const char *Name = RegNames[SysM];
990  assert(Name[0] && "invalid banked register operand");
991 
992  O << Name;
993 }
994 
995 void ARMInstPrinter::printPredicateOperand(const MCInst *MI, unsigned OpNum,
996  const MCSubtargetInfo &STI,
997  raw_ostream &O) {
999  // Handle the undefined 15 CC value here for printing so we don't abort().
1000  if ((unsigned)CC == 15)
1001  O << "<und>";
1002  else if (CC != ARMCC::AL)
1003  O << ARMCondCodeToString(CC);
1004 }
1005 
1007  unsigned OpNum,
1008  const MCSubtargetInfo &STI,
1009  raw_ostream &O) {
1011  O << ARMCondCodeToString(CC);
1012 }
1013 
1015  const MCSubtargetInfo &STI,
1016  raw_ostream &O) {
1017  if (MI->getOperand(OpNum).getReg()) {
1018  assert(MI->getOperand(OpNum).getReg() == ARM::CPSR &&
1019  "Expect ARM CPSR register!");
1020  O << 's';
1021  }
1022 }
1023 
1024 void ARMInstPrinter::printNoHashImmediate(const MCInst *MI, unsigned OpNum,
1025  const MCSubtargetInfo &STI,
1026  raw_ostream &O) {
1027  O << MI->getOperand(OpNum).getImm();
1028 }
1029 
1030 void ARMInstPrinter::printPImmediate(const MCInst *MI, unsigned OpNum,
1031  const MCSubtargetInfo &STI,
1032  raw_ostream &O) {
1033  O << "p" << MI->getOperand(OpNum).getImm();
1034 }
1035 
1036 void ARMInstPrinter::printCImmediate(const MCInst *MI, unsigned OpNum,
1037  const MCSubtargetInfo &STI,
1038  raw_ostream &O) {
1039  O << "c" << MI->getOperand(OpNum).getImm();
1040 }
1041 
1042 void ARMInstPrinter::printCoprocOptionImm(const MCInst *MI, unsigned OpNum,
1043  const MCSubtargetInfo &STI,
1044  raw_ostream &O) {
1045  O << "{" << MI->getOperand(OpNum).getImm() << "}";
1046 }
1047 
1048 void ARMInstPrinter::printPCLabel(const MCInst *MI, unsigned OpNum,
1049  const MCSubtargetInfo &STI, raw_ostream &O) {
1050  llvm_unreachable("Unhandled PC-relative pseudo-instruction!");
1051 }
1052 
1053 template <unsigned scale>
1054 void ARMInstPrinter::printAdrLabelOperand(const MCInst *MI, unsigned OpNum,
1055  const MCSubtargetInfo &STI,
1056  raw_ostream &O) {
1057  const MCOperand &MO = MI->getOperand(OpNum);
1058 
1059  if (MO.isExpr()) {
1060  MO.getExpr()->print(O, &MAI);
1061  return;
1062  }
1063 
1064  int32_t OffImm = (int32_t)MO.getImm() << scale;
1065 
1066  O << markup("<imm:");
1067  if (OffImm == INT32_MIN)
1068  O << "#-0";
1069  else if (OffImm < 0)
1070  O << "#-" << -OffImm;
1071  else
1072  O << "#" << OffImm;
1073  O << markup(">");
1074 }
1075 
1077  const MCSubtargetInfo &STI,
1078  raw_ostream &O) {
1079  O << markup("<imm:") << "#" << formatImm(MI->getOperand(OpNum).getImm() * 4)
1080  << markup(">");
1081 }
1082 
1083 void ARMInstPrinter::printThumbSRImm(const MCInst *MI, unsigned OpNum,
1084  const MCSubtargetInfo &STI,
1085  raw_ostream &O) {
1086  unsigned Imm = MI->getOperand(OpNum).getImm();
1087  O << markup("<imm:") << "#" << formatImm((Imm == 0 ? 32 : Imm))
1088  << markup(">");
1089 }
1090 
1091 void ARMInstPrinter::printThumbITMask(const MCInst *MI, unsigned OpNum,
1092  const MCSubtargetInfo &STI,
1093  raw_ostream &O) {
1094  // (3 - the number of trailing zeros) is the number of then / else.
1095  unsigned Mask = MI->getOperand(OpNum).getImm();
1096  unsigned Firstcond = MI->getOperand(OpNum - 1).getImm();
1097  unsigned CondBit0 = Firstcond & 1;
1098  unsigned NumTZ = countTrailingZeros(Mask);
1099  assert(NumTZ <= 3 && "Invalid IT mask!");
1100  for (unsigned Pos = 3, e = NumTZ; Pos > e; --Pos) {
1101  bool T = ((Mask >> Pos) & 1) == CondBit0;
1102  if (T)
1103  O << 't';
1104  else
1105  O << 'e';
1106  }
1107 }
1108 
1110  const MCSubtargetInfo &STI,
1111  raw_ostream &O) {
1112  const MCOperand &MO1 = MI->getOperand(Op);
1113  const MCOperand &MO2 = MI->getOperand(Op + 1);
1114 
1115  if (!MO1.isReg()) { // FIXME: This is for CP entries, but isn't right.
1116  printOperand(MI, Op, STI, O);
1117  return;
1118  }
1119 
1120  O << markup("<mem:") << "[";
1121  printRegName(O, MO1.getReg());
1122  if (unsigned RegNum = MO2.getReg()) {
1123  O << ", ";
1124  printRegName(O, RegNum);
1125  }
1126  O << "]" << markup(">");
1127 }
1128 
1130  unsigned Op,
1131  const MCSubtargetInfo &STI,
1132  raw_ostream &O,
1133  unsigned Scale) {
1134  const MCOperand &MO1 = MI->getOperand(Op);
1135  const MCOperand &MO2 = MI->getOperand(Op + 1);
1136 
1137  if (!MO1.isReg()) { // FIXME: This is for CP entries, but isn't right.
1138  printOperand(MI, Op, STI, O);
1139  return;
1140  }
1141 
1142  O << markup("<mem:") << "[";
1143  printRegName(O, MO1.getReg());
1144  if (unsigned ImmOffs = MO2.getImm()) {
1145  O << ", " << markup("<imm:") << "#" << formatImm(ImmOffs * Scale)
1146  << markup(">");
1147  }
1148  O << "]" << markup(">");
1149 }
1150 
1152  unsigned Op,
1153  const MCSubtargetInfo &STI,
1154  raw_ostream &O) {
1155  printThumbAddrModeImm5SOperand(MI, Op, STI, O, 1);
1156 }
1157 
1159  unsigned Op,
1160  const MCSubtargetInfo &STI,
1161  raw_ostream &O) {
1162  printThumbAddrModeImm5SOperand(MI, Op, STI, O, 2);
1163 }
1164 
1166  unsigned Op,
1167  const MCSubtargetInfo &STI,
1168  raw_ostream &O) {
1169  printThumbAddrModeImm5SOperand(MI, Op, STI, O, 4);
1170 }
1171 
1173  const MCSubtargetInfo &STI,
1174  raw_ostream &O) {
1175  printThumbAddrModeImm5SOperand(MI, Op, STI, O, 4);
1176 }
1177 
1178 // Constant shifts t2_so_reg is a 2-operand unit corresponding to the Thumb2
1179 // register with shift forms.
1180 // REG 0 0 - e.g. R5
1181 // REG IMM, SH_OPC - e.g. R5, LSL #3
1182 void ARMInstPrinter::printT2SOOperand(const MCInst *MI, unsigned OpNum,
1183  const MCSubtargetInfo &STI,
1184  raw_ostream &O) {
1185  const MCOperand &MO1 = MI->getOperand(OpNum);
1186  const MCOperand &MO2 = MI->getOperand(OpNum + 1);
1187 
1188  unsigned Reg = MO1.getReg();
1189  printRegName(O, Reg);
1190 
1191  // Print the shift opc.
1192  assert(MO2.isImm() && "Not a valid t2_so_reg value!");
1195 }
1196 
1197 template <bool AlwaysPrintImm0>
1199  const MCSubtargetInfo &STI,
1200  raw_ostream &O) {
1201  const MCOperand &MO1 = MI->getOperand(OpNum);
1202  const MCOperand &MO2 = MI->getOperand(OpNum + 1);
1203 
1204  if (!MO1.isReg()) { // FIXME: This is for CP entries, but isn't right.
1205  printOperand(MI, OpNum, STI, O);
1206  return;
1207  }
1208 
1209  O << markup("<mem:") << "[";
1210  printRegName(O, MO1.getReg());
1211 
1212  int32_t OffImm = (int32_t)MO2.getImm();
1213  bool isSub = OffImm < 0;
1214  // Special value for #-0. All others are normal.
1215  if (OffImm == INT32_MIN)
1216  OffImm = 0;
1217  if (isSub) {
1218  O << ", " << markup("<imm:") << "#-" << formatImm(-OffImm) << markup(">");
1219  } else if (AlwaysPrintImm0 || OffImm > 0) {
1220  O << ", " << markup("<imm:") << "#" << formatImm(OffImm) << markup(">");
1221  }
1222  O << "]" << markup(">");
1223 }
1224 
1225 template <bool AlwaysPrintImm0>
1227  unsigned OpNum,
1228  const MCSubtargetInfo &STI,
1229  raw_ostream &O) {
1230  const MCOperand &MO1 = MI->getOperand(OpNum);
1231  const MCOperand &MO2 = MI->getOperand(OpNum + 1);
1232 
1233  O << markup("<mem:") << "[";
1234  printRegName(O, MO1.getReg());
1235 
1236  int32_t OffImm = (int32_t)MO2.getImm();
1237  bool isSub = OffImm < 0;
1238  // Don't print +0.
1239  if (OffImm == INT32_MIN)
1240  OffImm = 0;
1241  if (isSub) {
1242  O << ", " << markup("<imm:") << "#-" << -OffImm << markup(">");
1243  } else if (AlwaysPrintImm0 || OffImm > 0) {
1244  O << ", " << markup("<imm:") << "#" << OffImm << markup(">");
1245  }
1246  O << "]" << markup(">");
1247 }
1248 
1249 template <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  if (!MO1.isReg()) { // For label symbolic references.
1258  printOperand(MI, OpNum, STI, O);
1259  return;
1260  }
1261 
1262  O << markup("<mem:") << "[";
1263  printRegName(O, MO1.getReg());
1264 
1265  int32_t OffImm = (int32_t)MO2.getImm();
1266  bool isSub = OffImm < 0;
1267 
1268  assert(((OffImm & 0x3) == 0) && "Not a valid immediate!");
1269 
1270  // Don't print +0.
1271  if (OffImm == INT32_MIN)
1272  OffImm = 0;
1273  if (isSub) {
1274  O << ", " << markup("<imm:") << "#-" << -OffImm << markup(">");
1275  } else if (AlwaysPrintImm0 || OffImm > 0) {
1276  O << ", " << markup("<imm:") << "#" << OffImm << markup(">");
1277  }
1278  O << "]" << markup(">");
1279 }
1280 
1282  const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI,
1283  raw_ostream &O) {
1284  const MCOperand &MO1 = MI->getOperand(OpNum);
1285  const MCOperand &MO2 = MI->getOperand(OpNum + 1);
1286 
1287  O << markup("<mem:") << "[";
1288  printRegName(O, MO1.getReg());
1289  if (MO2.getImm()) {
1290  O << ", " << markup("<imm:") << "#" << formatImm(MO2.getImm() * 4)
1291  << markup(">");
1292  }
1293  O << "]" << markup(">");
1294 }
1295 
1297  const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI,
1298  raw_ostream &O) {
1299  const MCOperand &MO1 = MI->getOperand(OpNum);
1300  int32_t OffImm = (int32_t)MO1.getImm();
1301  O << ", " << markup("<imm:");
1302  if (OffImm == INT32_MIN)
1303  O << "#-0";
1304  else if (OffImm < 0)
1305  O << "#-" << -OffImm;
1306  else
1307  O << "#" << OffImm;
1308  O << markup(">");
1309 }
1310 
1312  const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI,
1313  raw_ostream &O) {
1314  const MCOperand &MO1 = MI->getOperand(OpNum);
1315  int32_t OffImm = (int32_t)MO1.getImm();
1316 
1317  assert(((OffImm & 0x3) == 0) && "Not a valid immediate!");
1318 
1319  O << ", " << markup("<imm:");
1320  if (OffImm == INT32_MIN)
1321  O << "#-0";
1322  else if (OffImm < 0)
1323  O << "#-" << -OffImm;
1324  else
1325  O << "#" << OffImm;
1326  O << markup(">");
1327 }
1328 
1330  unsigned OpNum,
1331  const MCSubtargetInfo &STI,
1332  raw_ostream &O) {
1333  const MCOperand &MO1 = MI->getOperand(OpNum);
1334  const MCOperand &MO2 = MI->getOperand(OpNum + 1);
1335  const MCOperand &MO3 = MI->getOperand(OpNum + 2);
1336 
1337  O << markup("<mem:") << "[";
1338  printRegName(O, MO1.getReg());
1339 
1340  assert(MO2.getReg() && "Invalid so_reg load / store address!");
1341  O << ", ";
1342  printRegName(O, MO2.getReg());
1343 
1344  unsigned ShAmt = MO3.getImm();
1345  if (ShAmt) {
1346  assert(ShAmt <= 3 && "Not a valid Thumb2 addressing mode!");
1347  O << ", lsl " << markup("<imm:") << "#" << ShAmt << markup(">");
1348  }
1349  O << "]" << markup(">");
1350 }
1351 
1352 void ARMInstPrinter::printFPImmOperand(const MCInst *MI, unsigned OpNum,
1353  const MCSubtargetInfo &STI,
1354  raw_ostream &O) {
1355  const MCOperand &MO = MI->getOperand(OpNum);
1356  O << markup("<imm:") << '#' << ARM_AM::getFPImmFloat(MO.getImm())
1357  << markup(">");
1358 }
1359 
1361  const MCSubtargetInfo &STI,
1362  raw_ostream &O) {
1363  unsigned EncodedImm = MI->getOperand(OpNum).getImm();
1364  unsigned EltBits;
1365  uint64_t Val = ARM_AM::decodeNEONModImm(EncodedImm, EltBits);
1366  O << markup("<imm:") << "#0x";
1367  O.write_hex(Val);
1368  O << markup(">");
1369 }
1370 
1372  const MCSubtargetInfo &STI,
1373  raw_ostream &O) {
1374  unsigned Imm = MI->getOperand(OpNum).getImm();
1375  O << markup("<imm:") << "#" << formatImm(Imm + 1) << markup(">");
1376 }
1377 
1378 void ARMInstPrinter::printRotImmOperand(const MCInst *MI, unsigned OpNum,
1379  const MCSubtargetInfo &STI,
1380  raw_ostream &O) {
1381  unsigned Imm = MI->getOperand(OpNum).getImm();
1382  if (Imm == 0)
1383  return;
1384  assert(Imm <= 3 && "illegal ror immediate!");
1385  O << ", ror " << markup("<imm:") << "#" << 8 * Imm << markup(">");
1386 }
1387 
1388 void ARMInstPrinter::printModImmOperand(const MCInst *MI, unsigned OpNum,
1389  const MCSubtargetInfo &STI,
1390  raw_ostream &O) {
1391  MCOperand Op = MI->getOperand(OpNum);
1392 
1393  // Support for fixups (MCFixup)
1394  if (Op.isExpr())
1395  return printOperand(MI, OpNum, STI, O);
1396 
1397  unsigned Bits = Op.getImm() & 0xFF;
1398  unsigned Rot = (Op.getImm() & 0xF00) >> 7;
1399 
1400  bool PrintUnsigned = false;
1401  switch (MI->getOpcode()) {
1402  case ARM::MOVi:
1403  // Movs to PC should be treated unsigned
1404  PrintUnsigned = (MI->getOperand(OpNum - 1).getReg() == ARM::PC);
1405  break;
1406  case ARM::MSRi:
1407  // Movs to special registers should be treated unsigned
1408  PrintUnsigned = true;
1409  break;
1410  }
1411 
1412  int32_t Rotated = ARM_AM::rotr32(Bits, Rot);
1413  if (ARM_AM::getSOImmVal(Rotated) == Op.getImm()) {
1414  // #rot has the least possible value
1415  O << "#" << markup("<imm:");
1416  if (PrintUnsigned)
1417  O << static_cast<uint32_t>(Rotated);
1418  else
1419  O << Rotated;
1420  O << markup(">");
1421  return;
1422  }
1423 
1424  // Explicit #bits, #rot implied
1425  O << "#" << markup("<imm:") << Bits << markup(">") << ", #" << markup("<imm:")
1426  << Rot << markup(">");
1427 }
1428 
1429 void ARMInstPrinter::printFBits16(const MCInst *MI, unsigned OpNum,
1430  const MCSubtargetInfo &STI, raw_ostream &O) {
1431  O << markup("<imm:") << "#" << 16 - MI->getOperand(OpNum).getImm()
1432  << markup(">");
1433 }
1434 
1435 void ARMInstPrinter::printFBits32(const MCInst *MI, unsigned OpNum,
1436  const MCSubtargetInfo &STI, raw_ostream &O) {
1437  O << markup("<imm:") << "#" << 32 - MI->getOperand(OpNum).getImm()
1438  << markup(">");
1439 }
1440 
1441 void ARMInstPrinter::printVectorIndex(const MCInst *MI, unsigned OpNum,
1442  const MCSubtargetInfo &STI,
1443  raw_ostream &O) {
1444  O << "[" << MI->getOperand(OpNum).getImm() << "]";
1445 }
1446 
1447 void ARMInstPrinter::printVectorListOne(const MCInst *MI, unsigned OpNum,
1448  const MCSubtargetInfo &STI,
1449  raw_ostream &O) {
1450  O << "{";
1451  printRegName(O, MI->getOperand(OpNum).getReg());
1452  O << "}";
1453 }
1454 
1455 void ARMInstPrinter::printVectorListTwo(const MCInst *MI, unsigned OpNum,
1456  const MCSubtargetInfo &STI,
1457  raw_ostream &O) {
1458  unsigned Reg = MI->getOperand(OpNum).getReg();
1459  unsigned Reg0 = MRI.getSubReg(Reg, ARM::dsub_0);
1460  unsigned Reg1 = MRI.getSubReg(Reg, ARM::dsub_1);
1461  O << "{";
1462  printRegName(O, Reg0);
1463  O << ", ";
1464  printRegName(O, Reg1);
1465  O << "}";
1466 }
1467 
1469  const MCSubtargetInfo &STI,
1470  raw_ostream &O) {
1471  unsigned Reg = MI->getOperand(OpNum).getReg();
1472  unsigned Reg0 = MRI.getSubReg(Reg, ARM::dsub_0);
1473  unsigned Reg1 = MRI.getSubReg(Reg, ARM::dsub_2);
1474  O << "{";
1475  printRegName(O, Reg0);
1476  O << ", ";
1477  printRegName(O, Reg1);
1478  O << "}";
1479 }
1480 
1481 void ARMInstPrinter::printVectorListThree(const MCInst *MI, unsigned OpNum,
1482  const MCSubtargetInfo &STI,
1483  raw_ostream &O) {
1484  // Normally, it's not safe to use register enum values directly with
1485  // addition to get the next register, but for VFP registers, the
1486  // sort order is guaranteed because they're all of the form D<n>.
1487  O << "{";
1488  printRegName(O, MI->getOperand(OpNum).getReg());
1489  O << ", ";
1490  printRegName(O, MI->getOperand(OpNum).getReg() + 1);
1491  O << ", ";
1492  printRegName(O, MI->getOperand(OpNum).getReg() + 2);
1493  O << "}";
1494 }
1495 
1496 void ARMInstPrinter::printVectorListFour(const MCInst *MI, unsigned OpNum,
1497  const MCSubtargetInfo &STI,
1498  raw_ostream &O) {
1499  // Normally, it's not safe to use register enum values directly with
1500  // addition to get the next register, but for VFP registers, the
1501  // sort order is guaranteed because they're all of the form D<n>.
1502  O << "{";
1503  printRegName(O, MI->getOperand(OpNum).getReg());
1504  O << ", ";
1505  printRegName(O, MI->getOperand(OpNum).getReg() + 1);
1506  O << ", ";
1507  printRegName(O, MI->getOperand(OpNum).getReg() + 2);
1508  O << ", ";
1509  printRegName(O, MI->getOperand(OpNum).getReg() + 3);
1510  O << "}";
1511 }
1512 
1514  unsigned OpNum,
1515  const MCSubtargetInfo &STI,
1516  raw_ostream &O) {
1517  O << "{";
1518  printRegName(O, MI->getOperand(OpNum).getReg());
1519  O << "[]}";
1520 }
1521 
1523  unsigned OpNum,
1524  const MCSubtargetInfo &STI,
1525  raw_ostream &O) {
1526  unsigned Reg = MI->getOperand(OpNum).getReg();
1527  unsigned Reg0 = MRI.getSubReg(Reg, ARM::dsub_0);
1528  unsigned Reg1 = MRI.getSubReg(Reg, ARM::dsub_1);
1529  O << "{";
1530  printRegName(O, Reg0);
1531  O << "[], ";
1532  printRegName(O, Reg1);
1533  O << "[]}";
1534 }
1535 
1537  unsigned OpNum,
1538  const MCSubtargetInfo &STI,
1539  raw_ostream &O) {
1540  // Normally, it's not safe to use register enum values directly with
1541  // addition to get the next register, but for VFP registers, the
1542  // sort order is guaranteed because they're all of the form D<n>.
1543  O << "{";
1544  printRegName(O, MI->getOperand(OpNum).getReg());
1545  O << "[], ";
1546  printRegName(O, MI->getOperand(OpNum).getReg() + 1);
1547  O << "[], ";
1548  printRegName(O, MI->getOperand(OpNum).getReg() + 2);
1549  O << "[]}";
1550 }
1551 
1553  unsigned OpNum,
1554  const MCSubtargetInfo &STI,
1555  raw_ostream &O) {
1556  // Normally, it's not safe to use register enum values directly with
1557  // addition to get the next register, but for VFP registers, the
1558  // sort order is guaranteed because they're all of the form D<n>.
1559  O << "{";
1560  printRegName(O, MI->getOperand(OpNum).getReg());
1561  O << "[], ";
1562  printRegName(O, MI->getOperand(OpNum).getReg() + 1);
1563  O << "[], ";
1564  printRegName(O, MI->getOperand(OpNum).getReg() + 2);
1565  O << "[], ";
1566  printRegName(O, MI->getOperand(OpNum).getReg() + 3);
1567  O << "[]}";
1568 }
1569 
1571  const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI,
1572  raw_ostream &O) {
1573  unsigned Reg = MI->getOperand(OpNum).getReg();
1574  unsigned Reg0 = MRI.getSubReg(Reg, ARM::dsub_0);
1575  unsigned Reg1 = MRI.getSubReg(Reg, ARM::dsub_2);
1576  O << "{";
1577  printRegName(O, Reg0);
1578  O << "[], ";
1579  printRegName(O, Reg1);
1580  O << "[]}";
1581 }
1582 
1584  const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI,
1585  raw_ostream &O) {
1586  // Normally, it's not safe to use register enum values directly with
1587  // addition to get the next register, but for VFP registers, the
1588  // sort order is guaranteed because they're all of the form D<n>.
1589  O << "{";
1590  printRegName(O, MI->getOperand(OpNum).getReg());
1591  O << "[], ";
1592  printRegName(O, MI->getOperand(OpNum).getReg() + 2);
1593  O << "[], ";
1594  printRegName(O, MI->getOperand(OpNum).getReg() + 4);
1595  O << "[]}";
1596 }
1597 
1599  const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI,
1600  raw_ostream &O) {
1601  // Normally, it's not safe to use register enum values directly with
1602  // addition to get the next register, but for VFP registers, the
1603  // sort order is guaranteed because they're all of the form D<n>.
1604  O << "{";
1605  printRegName(O, MI->getOperand(OpNum).getReg());
1606  O << "[], ";
1607  printRegName(O, MI->getOperand(OpNum).getReg() + 2);
1608  O << "[], ";
1609  printRegName(O, MI->getOperand(OpNum).getReg() + 4);
1610  O << "[], ";
1611  printRegName(O, MI->getOperand(OpNum).getReg() + 6);
1612  O << "[]}";
1613 }
1614 
1616  unsigned OpNum,
1617  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 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 }
void printVectorListTwoAllLanes(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
static uint64_t scale(uint64_t Num, uint32_t N, uint32_t D)
void printThumbAddrModeImm5S1Operand(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 printNoHashImmediate(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
static unsigned char getAM3Offset(unsigned AM3Opc)
void printVectorListThreeAllLanes(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
void printT2AddrModeImm8Operand(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
void printAddrModeTBB(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
bool isReg() const
Definition: MCInst.h:56
void printThumbAddrModeImm5S2Operand(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
void printBankedRegOperand(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
static const char * getShiftOpcStr(ShiftOpc Op)
#define op(i)
void printBitfieldInvMaskImmOperand(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
void printT2AddrModeImm8s4Operand(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
std::size_t countLeadingZeros(T Val, ZeroBehavior ZB=ZB_Width)
Count number of 0's from the most significant bit to the least stopping at the first 1...
Definition: MathExtras.h:178
void printAddrMode7Operand(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
void printThumbLdrLabelOperand(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
static unsigned rotr32(unsigned Val, unsigned Amt)
rotr32 - Rotate a 32-bit unsigned value right by a specified # bits.
void printPKHASRShiftImm(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
static unsigned translateShiftImm(unsigned imm)
translateShiftImm - Convert shift immediate from 0-31 to 1-32 for printing.
void printAM2PreOrOffsetIndexOp(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
static unsigned getAM3IdxMode(unsigned AM3Opc)
void printThumbAddrModeSPOperand(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
static MCOperand createReg(unsigned Reg)
Definition: MCInst.h:111
void printT2AddrModeImm8s4OffsetOperand(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 printVectorListTwoSpacedAllLanes(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Definition: ErrorHandling.h:98
void printT2AddrModeImm8OffsetOperand(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
void printLdStmModeOperand(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
Base class for the full range of assembler expressions which are needed for parsing.
Definition: MCExpr.h:33
Reg
All possible values of the reg field in the ModR/M byte.
static AMSubMode getAM4SubMode(unsigned Mode)
void printFBits32(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 printCPSIFlag(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
unsigned getReg() const
Returns the register number.
Definition: MCInst.h:63
raw_ostream & write_hex(unsigned long long N)
Output N in hexadecimal, without any prefix or padding.
void printInstruction(const MCInst *MI, const MCSubtargetInfo &STI, raw_ostream &O)
void printSBitModifierOperand(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
static const char * getRegisterName(unsigned RegNo)
MCRegisterClass - Base class of TargetRegisterClass.
Instances of this class represent a single low-level machine instruction.
Definition: MCInst.h:150
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
bool isImm() const
Definition: MCInst.h:57
This class is intended to be used as a base class for asm properties and features specific to the tar...
Definition: MCAsmInfo.h:58
static unsigned getAM2IdxMode(unsigned AM2Opc)
const MCExpr * getExpr() const
Definition: MCInst.h:93
void print(raw_ostream &OS, const MCAsmInfo *MAI) const
Definition: MCExpr.cpp:33
void printThumbSRImm(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 printMandatoryPredicateOperand(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
std::size_t countTrailingZeros(T Val, ZeroBehavior ZB=ZB_Width)
Count number of 0's from the least significant bit to the most stopping at the first 1...
Definition: MathExtras.h:109
static const char * InstSyncBOptToString(unsigned val)
Definition: ARMBaseInfo.h:184
void printGPRPairOperand(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
StringRef markup(StringRef s) const
Utility functions to make adding mark ups simpler.
void printRegisterList(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
const MCRegisterClass & getRegClass(unsigned i) const
Returns the register class associated with the enumeration value.
This is an important base class in LLVM.
Definition: Constant.h:41
static unsigned char getAM5Offset(unsigned AM5Opc)
void printThumbAddrModeImm5S4Operand(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
unsigned getSubReg(unsigned Reg, unsigned Idx) const
Returns the physical register number of sub-register "Index" for physical register RegNo...
Interface to description of machine instruction set.
Definition: MCInstrInfo.h:24
bool isExpr() const
Definition: MCInst.h:59
void printVectorListOne(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 printAddrModeTBH(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 printAddrMode6Operand(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 printMemBOption(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 printSORegRegOperand(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
static const char * getAddrOpcStr(AddrOpc Op)
void printThumbAddrModeRROperand(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 printPKHLSLShiftImm(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
void printCImmediate(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
format_object< int64_t > formatImm(int64_t Value) const
Utility function to print immediates in decimal or hex.
Definition: MCInstPrinter.h:96
void printVectorListFourSpacedAllLanes(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
unsigned getMatchingSuperReg(unsigned 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...
static const char * ARMCondCodeToString(ARMCC::CondCodes CC)
Definition: ARMBaseInfo.h:68
static const char * IModToString(unsigned val)
Definition: ARMBaseInfo.h:110
static AddrOpc getAM2Op(unsigned AM2Opc)
void printPostIdxRegOperand(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 setOpcode(unsigned Op)
Definition: MCInst.h:158
void printFBits16(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
bool contains(unsigned Reg) const
contains - Return true if the specified register is included in this register class.
void printVectorListTwoSpaced(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
static unsigned getAM2Offset(unsigned AM2Opc)
void printVectorListThreeSpaced(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
ARMInstPrinter(const MCAsmInfo &MAI, const MCInstrInfo &MII, const MCRegisterInfo &MRI)
const FeatureBitset & getFeatureBits() const
getFeatureBits - Return the feature bits.
uint64_t TargetAddress
Represents an address in the target process's address space.
Definition: JITSymbol.h:26
void printPCLabel(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
void printAddrMode6OffsetOperand(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
unsigned getOpcode() const
Definition: MCInst.h:159
static void printRegImmShift(raw_ostream &O, ARM_AM::ShiftOpc ShOpc, unsigned ShImm, bool UseMarkup)
Prints the shift value with an immediate value.
static const char * MemBOptToString(unsigned val, bool HasV8)
Definition: ARMBaseInfo.h:141
static AddrOpc getAM3Op(unsigned AM3Opc)
int64_t getImm() const
Definition: MCInst.h:74
static const char * IFlagsToString(unsigned val)
Definition: ARMBaseInfo.h:101
static int getSOImmVal(unsigned Arg)
getSOImmVal - Given a 32-bit immediate, if it is something that can fit into an shifter_operand immed...
const MCAsmInfo & MAI
Definition: MCInstPrinter.h:44
static const char * getAMSubModeStr(AMSubMode Mode)
void printVectorListFourAllLanes(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
void printThumbAddrModeImm5SOperand(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O, unsigned Scale)
bool UseMarkup
True if we are printing marked up assembly.
Definition: MCInstPrinter.h:49
This is an instance of a target assembly language printer that converts an MCInst to valid target ass...
Definition: MCInstPrinter.h:38
void printT2SOOperand(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 printAddrMode2Operand(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
unsigned getNumOperands() const
Definition: MCInst.h:166
void printT2AddrModeImm0_1020s4Operand(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
MCSubtargetInfo - Generic base class for all target subtargets.
void printVectorListFour(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
bool evaluateAsAbsolute(int64_t &Res, const MCAsmLayout &Layout, const SectionAddrMap &Addrs) const
Try to evaluate the expression to an absolute value.
Definition: MCExpr.cpp:418
void printT2AddrModeSoRegOperand(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
static AddrOpc getAM5Op(unsigned AM5Opc)
void printPostIdxImm8Operand(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 printImmPlusOneOperand(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 printNEONModImmOperand(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
static ShiftOpc getAM2ShiftOpc(unsigned AM2Opc)
void printSetendOperand(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
static unsigned getSORegOffset(unsigned Op)
void printAnnotation(raw_ostream &OS, StringRef Annot)
Utility function for printing annotations.
void printMSRMaskOperand(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
Constant expressions.
Definition: MCExpr.h:37
Binary expressions.
Definition: MCExpr.h:36
void printAddrModeImm12Operand(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
This class implements an extremely fast bulk output stream that can only output to a stream...
Definition: raw_ostream.h:38
void printVectorListThreeSpacedAllLanes(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
void addOperand(const MCOperand &Op)
Definition: MCInst.h:168
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:40
void printPImmediate(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 printShiftImmOperand(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
void printAM3PreOrOffsetIndexOp(const MCInst *MI, unsigned Op, raw_ostream &O, bool AlwaysPrintImm0)
Instances of this class represent operands of the MCInst class.
Definition: MCInst.h:33
void printAddrMode3Operand(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
void printSORegImmOperand(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
static float getFPImmFloat(unsigned Imm)
void printInst(const MCInst *MI, raw_ostream &O, StringRef Annot, const MCSubtargetInfo &STI) override
Print the specified MCInst to the specified raw_ostream.
void printThumbS4ImmOperand(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
const MCOperand & getOperand(unsigned i) const
Definition: MCInst.h:164
void printPredicateOperand(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
void printRegName(raw_ostream &OS, unsigned RegNo) const override
Print the assembler register name.
void printInstSyncBOption(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
void printFPImmOperand(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
void printCPSIMod(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
static ShiftOpc getSORegShOp(unsigned Op)
const MCRegisterInfo & MRI
Definition: MCInstPrinter.h:46
static uint64_t decodeNEONModImm(unsigned ModImm, unsigned &EltBits)
decodeNEONModImm - Decode a NEON modified immediate value into the element value and the element size...
void printModImmOperand(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O)