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