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