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