LLVM API Documentation

ARMInstPrinter.cpp
Go to the documentation of this file.
00001 //===-- ARMInstPrinter.cpp - Convert ARM MCInst to assembly syntax --------===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 // This class prints an ARM MCInst to a .s file.
00011 //
00012 //===----------------------------------------------------------------------===//
00013 
00014 #include "ARMInstPrinter.h"
00015 #include "MCTargetDesc/ARMAddressingModes.h"
00016 #include "MCTargetDesc/ARMBaseInfo.h"
00017 #include "llvm/MC/MCAsmInfo.h"
00018 #include "llvm/MC/MCExpr.h"
00019 #include "llvm/MC/MCInst.h"
00020 #include "llvm/MC/MCInstrInfo.h"
00021 #include "llvm/MC/MCRegisterInfo.h"
00022 #include "llvm/Support/raw_ostream.h"
00023 using namespace llvm;
00024 
00025 #define DEBUG_TYPE "asm-printer"
00026 
00027 #include "ARMGenAsmWriter.inc"
00028 
00029 /// translateShiftImm - Convert shift immediate from 0-31 to 1-32 for printing.
00030 ///
00031 /// getSORegOffset returns an integer from 0-31, representing '32' as 0.
00032 static unsigned translateShiftImm(unsigned imm) {
00033   // lsr #32 and asr #32 exist, but should be encoded as a 0.
00034   assert((imm & ~0x1f) == 0 && "Invalid shift encoding");
00035 
00036   if (imm == 0)
00037     return 32;
00038   return imm;
00039 }
00040 
00041 /// Prints the shift value with an immediate value.
00042 static void printRegImmShift(raw_ostream &O, ARM_AM::ShiftOpc ShOpc,
00043                           unsigned ShImm, bool UseMarkup) {
00044   if (ShOpc == ARM_AM::no_shift || (ShOpc == ARM_AM::lsl && !ShImm))
00045     return;
00046   O << ", ";
00047 
00048   assert (!(ShOpc == ARM_AM::ror && !ShImm) && "Cannot have ror #0");
00049   O << getShiftOpcStr(ShOpc);
00050 
00051   if (ShOpc != ARM_AM::rrx) {
00052     O << " ";
00053     if (UseMarkup)
00054       O << "<imm:";
00055     O << "#" << translateShiftImm(ShImm);
00056     if (UseMarkup)
00057       O << ">";
00058   }
00059 }
00060 
00061 ARMInstPrinter::ARMInstPrinter(const MCAsmInfo &MAI,
00062                                const MCInstrInfo &MII,
00063                                const MCRegisterInfo &MRI,
00064                                const MCSubtargetInfo &STI) :
00065   MCInstPrinter(MAI, MII, MRI) {
00066   // Initialize the set of available features.
00067   setAvailableFeatures(STI.getFeatureBits());
00068 }
00069 
00070 void ARMInstPrinter::printRegName(raw_ostream &OS, unsigned RegNo) const {
00071   OS << markup("<reg:")
00072      << getRegisterName(RegNo)
00073      << markup(">");
00074 }
00075 
00076 void ARMInstPrinter::printInst(const MCInst *MI, raw_ostream &O,
00077                                StringRef Annot) {
00078   unsigned Opcode = MI->getOpcode();
00079 
00080   switch(Opcode) {
00081 
00082   // Check for HINT instructions w/ canonical names.
00083   case ARM::HINT:
00084   case ARM::tHINT:
00085   case ARM::t2HINT:
00086     switch (MI->getOperand(0).getImm()) {
00087     case 0: O << "\tnop"; break;
00088     case 1: O << "\tyield"; break;
00089     case 2: O << "\twfe"; break;
00090     case 3: O << "\twfi"; break;
00091     case 4: O << "\tsev"; break;
00092     case 5:
00093       if ((getAvailableFeatures() & ARM::HasV8Ops)) {
00094         O << "\tsevl";
00095         break;
00096       } // Fallthrough for non-v8
00097     default:
00098       // Anything else should just print normally.
00099       printInstruction(MI, O);
00100       printAnnotation(O, Annot);
00101       return;
00102     }
00103     printPredicateOperand(MI, 1, O);
00104     if (Opcode == ARM::t2HINT)
00105       O << ".w";
00106     printAnnotation(O, Annot);
00107     return;
00108 
00109   // Check for MOVs and print canonical forms, instead.
00110   case ARM::MOVsr: {
00111     // FIXME: Thumb variants?
00112     const MCOperand &Dst = MI->getOperand(0);
00113     const MCOperand &MO1 = MI->getOperand(1);
00114     const MCOperand &MO2 = MI->getOperand(2);
00115     const MCOperand &MO3 = MI->getOperand(3);
00116 
00117     O << '\t' << ARM_AM::getShiftOpcStr(ARM_AM::getSORegShOp(MO3.getImm()));
00118     printSBitModifierOperand(MI, 6, O);
00119     printPredicateOperand(MI, 4, O);
00120 
00121     O << '\t';
00122     printRegName(O, Dst.getReg());
00123     O << ", ";
00124     printRegName(O, MO1.getReg());
00125 
00126     O << ", ";
00127     printRegName(O, MO2.getReg());
00128     assert(ARM_AM::getSORegOffset(MO3.getImm()) == 0);
00129     printAnnotation(O, Annot);
00130     return;
00131   }
00132 
00133   case ARM::MOVsi: {
00134     // FIXME: Thumb variants?
00135     const MCOperand &Dst = MI->getOperand(0);
00136     const MCOperand &MO1 = MI->getOperand(1);
00137     const MCOperand &MO2 = MI->getOperand(2);
00138 
00139     O << '\t' << ARM_AM::getShiftOpcStr(ARM_AM::getSORegShOp(MO2.getImm()));
00140     printSBitModifierOperand(MI, 5, O);
00141     printPredicateOperand(MI, 3, O);
00142 
00143     O << '\t';
00144     printRegName(O, Dst.getReg());
00145     O << ", ";
00146     printRegName(O, MO1.getReg());
00147 
00148     if (ARM_AM::getSORegShOp(MO2.getImm()) == ARM_AM::rrx) {
00149       printAnnotation(O, Annot);
00150       return;
00151     }
00152 
00153     O << ", "
00154       << markup("<imm:")
00155       << "#" << translateShiftImm(ARM_AM::getSORegOffset(MO2.getImm()))
00156       << markup(">");
00157     printAnnotation(O, Annot);
00158     return;
00159   }
00160 
00161   // A8.6.123 PUSH
00162   case ARM::STMDB_UPD:
00163   case ARM::t2STMDB_UPD:
00164     if (MI->getOperand(0).getReg() == ARM::SP && MI->getNumOperands() > 5) {
00165       // Should only print PUSH if there are at least two registers in the list.
00166       O << '\t' << "push";
00167       printPredicateOperand(MI, 2, O);
00168       if (Opcode == ARM::t2STMDB_UPD)
00169         O << ".w";
00170       O << '\t';
00171       printRegisterList(MI, 4, O);
00172       printAnnotation(O, Annot);
00173       return;
00174     } else
00175       break;
00176 
00177   case ARM::STR_PRE_IMM:
00178     if (MI->getOperand(2).getReg() == ARM::SP &&
00179         MI->getOperand(3).getImm() == -4) {
00180       O << '\t' << "push";
00181       printPredicateOperand(MI, 4, O);
00182       O << "\t{";
00183       printRegName(O, MI->getOperand(1).getReg());
00184       O << "}";
00185       printAnnotation(O, Annot);
00186       return;
00187     } else
00188       break;
00189 
00190   // A8.6.122 POP
00191   case ARM::LDMIA_UPD:
00192   case ARM::t2LDMIA_UPD:
00193     if (MI->getOperand(0).getReg() == ARM::SP && MI->getNumOperands() > 5) {
00194       // Should only print POP if there are at least two registers in the list.
00195       O << '\t' << "pop";
00196       printPredicateOperand(MI, 2, O);
00197       if (Opcode == ARM::t2LDMIA_UPD)
00198         O << ".w";
00199       O << '\t';
00200       printRegisterList(MI, 4, O);
00201       printAnnotation(O, Annot);
00202       return;
00203     } else
00204       break;
00205 
00206   case ARM::LDR_POST_IMM:
00207     if (MI->getOperand(2).getReg() == ARM::SP &&
00208         MI->getOperand(4).getImm() == 4) {
00209       O << '\t' << "pop";
00210       printPredicateOperand(MI, 5, O);
00211       O << "\t{";
00212       printRegName(O, MI->getOperand(0).getReg());
00213       O << "}";
00214       printAnnotation(O, Annot);
00215       return;
00216     } else
00217       break;
00218 
00219   // A8.6.355 VPUSH
00220   case ARM::VSTMSDB_UPD:
00221   case ARM::VSTMDDB_UPD:
00222     if (MI->getOperand(0).getReg() == ARM::SP) {
00223       O << '\t' << "vpush";
00224       printPredicateOperand(MI, 2, O);
00225       O << '\t';
00226       printRegisterList(MI, 4, O);
00227       printAnnotation(O, Annot);
00228       return;
00229     } else
00230       break;
00231 
00232   // A8.6.354 VPOP
00233   case ARM::VLDMSIA_UPD:
00234   case ARM::VLDMDIA_UPD:
00235     if (MI->getOperand(0).getReg() == ARM::SP) {
00236       O << '\t' << "vpop";
00237       printPredicateOperand(MI, 2, O);
00238       O << '\t';
00239       printRegisterList(MI, 4, O);
00240       printAnnotation(O, Annot);
00241       return;
00242     } else
00243       break;
00244 
00245   case ARM::tLDMIA: {
00246     bool Writeback = true;
00247     unsigned BaseReg = MI->getOperand(0).getReg();
00248     for (unsigned i = 3; i < MI->getNumOperands(); ++i) {
00249       if (MI->getOperand(i).getReg() == BaseReg)
00250         Writeback = false;
00251     }
00252 
00253     O << "\tldm";
00254 
00255     printPredicateOperand(MI, 1, O);
00256     O << '\t';
00257     printRegName(O, BaseReg);
00258     if (Writeback) O << "!";
00259     O << ", ";
00260     printRegisterList(MI, 3, O);
00261     printAnnotation(O, Annot);
00262     return;
00263   }
00264 
00265   // Combine 2 GPRs from disassember into a GPRPair to match with instr def.
00266   // ldrexd/strexd require even/odd GPR pair. To enforce this constraint,
00267   // a single GPRPair reg operand is used in the .td file to replace the two
00268   // GPRs. However, when decoding them, the two GRPs cannot be automatically
00269   // expressed as a GPRPair, so we have to manually merge them.
00270   // FIXME: We would really like to be able to tablegen'erate this.
00271   case ARM::LDREXD: case ARM::STREXD:
00272   case ARM::LDAEXD: case ARM::STLEXD:
00273     const MCRegisterClass& MRC = MRI.getRegClass(ARM::GPRRegClassID);
00274     bool isStore = Opcode == ARM::STREXD || Opcode == ARM::STLEXD;
00275     unsigned Reg = MI->getOperand(isStore ? 1 : 0).getReg();
00276     if (MRC.contains(Reg)) {
00277       MCInst NewMI;
00278       MCOperand NewReg;
00279       NewMI.setOpcode(Opcode);
00280 
00281       if (isStore)
00282         NewMI.addOperand(MI->getOperand(0));
00283       NewReg = MCOperand::CreateReg(MRI.getMatchingSuperReg(Reg, ARM::gsub_0,
00284         &MRI.getRegClass(ARM::GPRPairRegClassID)));
00285       NewMI.addOperand(NewReg);
00286 
00287       // Copy the rest operands into NewMI.
00288       for(unsigned i= isStore ? 3 : 2; i < MI->getNumOperands(); ++i)
00289         NewMI.addOperand(MI->getOperand(i));
00290       printInstruction(&NewMI, O);
00291       return;
00292     }
00293   }
00294 
00295   printInstruction(MI, O);
00296   printAnnotation(O, Annot);
00297 }
00298 
00299 void ARMInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
00300                                   raw_ostream &O) {
00301   const MCOperand &Op = MI->getOperand(OpNo);
00302   if (Op.isReg()) {
00303     unsigned Reg = Op.getReg();
00304     printRegName(O, Reg);
00305   } else if (Op.isImm()) {
00306     O << markup("<imm:")
00307       << '#' << formatImm(Op.getImm())
00308       << markup(">");
00309   } else {
00310     assert(Op.isExpr() && "unknown operand kind in printOperand");
00311     const MCExpr *Expr = Op.getExpr();
00312     switch (Expr->getKind()) {
00313     case MCExpr::Binary:
00314       O << '#' << *Expr;
00315       break;
00316     case MCExpr::Constant: {
00317       // If a symbolic branch target was added as a constant expression then
00318       // print that address in hex. And only print 32 unsigned bits for the
00319       // address.
00320       const MCConstantExpr *Constant = cast<MCConstantExpr>(Expr);
00321       int64_t TargetAddress;
00322       if (!Constant->EvaluateAsAbsolute(TargetAddress)) {
00323         O << '#' << *Expr;
00324       } else {
00325         O << "0x";
00326         O.write_hex(static_cast<uint32_t>(TargetAddress));
00327       }
00328       break;
00329     }
00330     default:
00331       // FIXME: Should we always treat this as if it is a constant literal and
00332       // prefix it with '#'?
00333       O << *Expr;
00334       break;
00335     }
00336   }
00337 }
00338 
00339 void ARMInstPrinter::printThumbLdrLabelOperand(const MCInst *MI, unsigned OpNum,
00340                                                raw_ostream &O) {
00341   const MCOperand &MO1 = MI->getOperand(OpNum);
00342   if (MO1.isExpr()) {
00343     O << *MO1.getExpr();
00344     return;
00345   }
00346 
00347   O << markup("<mem:") << "[pc, ";
00348 
00349   int32_t OffImm = (int32_t)MO1.getImm();
00350   bool isSub = OffImm < 0;
00351 
00352   // Special value for #-0. All others are normal.
00353   if (OffImm == INT32_MIN)
00354     OffImm = 0;
00355   if (isSub) {
00356     O << markup("<imm:")
00357       << "#-" << formatImm(-OffImm)
00358       << markup(">");
00359   } else {
00360     O << markup("<imm:")
00361       << "#" << formatImm(OffImm)
00362       << markup(">");
00363   }
00364   O << "]" << markup(">");
00365 }
00366 
00367 // so_reg is a 4-operand unit corresponding to register forms of the A5.1
00368 // "Addressing Mode 1 - Data-processing operands" forms.  This includes:
00369 //    REG 0   0           - e.g. R5
00370 //    REG REG 0,SH_OPC    - e.g. R5, ROR R3
00371 //    REG 0   IMM,SH_OPC  - e.g. R5, LSL #3
00372 void ARMInstPrinter::printSORegRegOperand(const MCInst *MI, unsigned OpNum,
00373                                        raw_ostream &O) {
00374   const MCOperand &MO1 = MI->getOperand(OpNum);
00375   const MCOperand &MO2 = MI->getOperand(OpNum+1);
00376   const MCOperand &MO3 = MI->getOperand(OpNum+2);
00377 
00378   printRegName(O, MO1.getReg());
00379 
00380   // Print the shift opc.
00381   ARM_AM::ShiftOpc ShOpc = ARM_AM::getSORegShOp(MO3.getImm());
00382   O << ", " << ARM_AM::getShiftOpcStr(ShOpc);
00383   if (ShOpc == ARM_AM::rrx)
00384     return;
00385 
00386   O << ' ';
00387   printRegName(O, MO2.getReg());
00388   assert(ARM_AM::getSORegOffset(MO3.getImm()) == 0);
00389 }
00390 
00391 void ARMInstPrinter::printSORegImmOperand(const MCInst *MI, unsigned OpNum,
00392                                        raw_ostream &O) {
00393   const MCOperand &MO1 = MI->getOperand(OpNum);
00394   const MCOperand &MO2 = MI->getOperand(OpNum+1);
00395 
00396   printRegName(O, MO1.getReg());
00397 
00398   // Print the shift opc.
00399   printRegImmShift(O, ARM_AM::getSORegShOp(MO2.getImm()),
00400                    ARM_AM::getSORegOffset(MO2.getImm()), UseMarkup);
00401 }
00402 
00403 
00404 //===--------------------------------------------------------------------===//
00405 // Addressing Mode #2
00406 //===--------------------------------------------------------------------===//
00407 
00408 void ARMInstPrinter::printAM2PreOrOffsetIndexOp(const MCInst *MI, unsigned Op,
00409                                                 raw_ostream &O) {
00410   const MCOperand &MO1 = MI->getOperand(Op);
00411   const MCOperand &MO2 = MI->getOperand(Op+1);
00412   const MCOperand &MO3 = MI->getOperand(Op+2);
00413 
00414   O << markup("<mem:") << "[";
00415   printRegName(O, MO1.getReg());
00416 
00417   if (!MO2.getReg()) {
00418     if (ARM_AM::getAM2Offset(MO3.getImm())) { // Don't print +0.
00419       O << ", "
00420         << markup("<imm:")
00421         << "#"
00422         << ARM_AM::getAddrOpcStr(ARM_AM::getAM2Op(MO3.getImm()))
00423         << ARM_AM::getAM2Offset(MO3.getImm())
00424         << markup(">");
00425     }
00426     O << "]" << markup(">");
00427     return;
00428   }
00429 
00430   O << ", ";
00431   O << ARM_AM::getAddrOpcStr(ARM_AM::getAM2Op(MO3.getImm()));
00432   printRegName(O, MO2.getReg());
00433 
00434   printRegImmShift(O, ARM_AM::getAM2ShiftOpc(MO3.getImm()),
00435                    ARM_AM::getAM2Offset(MO3.getImm()), UseMarkup);
00436   O << "]" << markup(">");
00437 }
00438 
00439 void ARMInstPrinter::printAddrModeTBB(const MCInst *MI, unsigned Op,
00440                                            raw_ostream &O) {
00441   const MCOperand &MO1 = MI->getOperand(Op);
00442   const MCOperand &MO2 = MI->getOperand(Op+1);
00443   O << markup("<mem:") << "[";
00444   printRegName(O, MO1.getReg());
00445   O << ", ";
00446   printRegName(O, MO2.getReg());
00447   O << "]" << markup(">");
00448 }
00449 
00450 void ARMInstPrinter::printAddrModeTBH(const MCInst *MI, unsigned Op,
00451                                            raw_ostream &O) {
00452   const MCOperand &MO1 = MI->getOperand(Op);
00453   const MCOperand &MO2 = MI->getOperand(Op+1);
00454   O << markup("<mem:") << "[";
00455   printRegName(O, MO1.getReg());
00456   O << ", ";
00457   printRegName(O, MO2.getReg());
00458   O << ", lsl " << markup("<imm:") << "#1" << markup(">") << "]" << markup(">");
00459 }
00460 
00461 void ARMInstPrinter::printAddrMode2Operand(const MCInst *MI, unsigned Op,
00462                                            raw_ostream &O) {
00463   const MCOperand &MO1 = MI->getOperand(Op);
00464 
00465   if (!MO1.isReg()) {   // FIXME: This is for CP entries, but isn't right.
00466     printOperand(MI, Op, O);
00467     return;
00468   }
00469 
00470 #ifndef NDEBUG
00471   const MCOperand &MO3 = MI->getOperand(Op+2);
00472   unsigned IdxMode = ARM_AM::getAM2IdxMode(MO3.getImm());
00473   assert(IdxMode != ARMII::IndexModePost &&
00474          "Should be pre or offset index op");
00475 #endif
00476 
00477   printAM2PreOrOffsetIndexOp(MI, Op, O);
00478 }
00479 
00480 void ARMInstPrinter::printAddrMode2OffsetOperand(const MCInst *MI,
00481                                                  unsigned OpNum,
00482                                                  raw_ostream &O) {
00483   const MCOperand &MO1 = MI->getOperand(OpNum);
00484   const MCOperand &MO2 = MI->getOperand(OpNum+1);
00485 
00486   if (!MO1.getReg()) {
00487     unsigned ImmOffs = ARM_AM::getAM2Offset(MO2.getImm());
00488     O << markup("<imm:")
00489       << '#' << ARM_AM::getAddrOpcStr(ARM_AM::getAM2Op(MO2.getImm()))
00490       << ImmOffs
00491       << markup(">");
00492     return;
00493   }
00494 
00495   O << ARM_AM::getAddrOpcStr(ARM_AM::getAM2Op(MO2.getImm()));
00496   printRegName(O, MO1.getReg());
00497 
00498   printRegImmShift(O, ARM_AM::getAM2ShiftOpc(MO2.getImm()),
00499                    ARM_AM::getAM2Offset(MO2.getImm()), UseMarkup);
00500 }
00501 
00502 //===--------------------------------------------------------------------===//
00503 // Addressing Mode #3
00504 //===--------------------------------------------------------------------===//
00505 
00506 void ARMInstPrinter::printAM3PostIndexOp(const MCInst *MI, unsigned Op,
00507                                          raw_ostream &O) {
00508   const MCOperand &MO1 = MI->getOperand(Op);
00509   const MCOperand &MO2 = MI->getOperand(Op+1);
00510   const MCOperand &MO3 = MI->getOperand(Op+2);
00511 
00512   O << markup("<mem:") << "[";
00513   printRegName(O, MO1.getReg());
00514   O << "], " << markup(">");
00515 
00516   if (MO2.getReg()) {
00517     O << (char)ARM_AM::getAM3Op(MO3.getImm());
00518     printRegName(O, MO2.getReg());
00519     return;
00520   }
00521 
00522   unsigned ImmOffs = ARM_AM::getAM3Offset(MO3.getImm());
00523   O << markup("<imm:")
00524     << '#'
00525     << ARM_AM::getAddrOpcStr(ARM_AM::getAM3Op(MO3.getImm()))
00526     << ImmOffs
00527     << markup(">");
00528 }
00529 
00530 void ARMInstPrinter::printAM3PreOrOffsetIndexOp(const MCInst *MI, unsigned Op,
00531                                                 raw_ostream &O,
00532                                                 bool AlwaysPrintImm0) {
00533   const MCOperand &MO1 = MI->getOperand(Op);
00534   const MCOperand &MO2 = MI->getOperand(Op+1);
00535   const MCOperand &MO3 = MI->getOperand(Op+2);
00536 
00537   O << markup("<mem:") << '[';
00538   printRegName(O, MO1.getReg());
00539 
00540   if (MO2.getReg()) {
00541     O << ", " << getAddrOpcStr(ARM_AM::getAM3Op(MO3.getImm()));
00542     printRegName(O, MO2.getReg());
00543     O << ']' << markup(">");
00544     return;
00545   }
00546 
00547   //If the op is sub we have to print the immediate even if it is 0
00548   unsigned ImmOffs = ARM_AM::getAM3Offset(MO3.getImm());
00549   ARM_AM::AddrOpc op = ARM_AM::getAM3Op(MO3.getImm());
00550 
00551   if (AlwaysPrintImm0 || ImmOffs || (op == ARM_AM::sub)) {
00552     O << ", "
00553       << markup("<imm:")
00554       << "#"
00555       << ARM_AM::getAddrOpcStr(op)
00556       << ImmOffs
00557       << markup(">");
00558   }
00559   O << ']' << markup(">");
00560 }
00561 
00562 template <bool AlwaysPrintImm0>
00563 void ARMInstPrinter::printAddrMode3Operand(const MCInst *MI, unsigned Op,
00564                                            raw_ostream &O) {
00565   const MCOperand &MO1 = MI->getOperand(Op);
00566   if (!MO1.isReg()) {   //  For label symbolic references.
00567     printOperand(MI, Op, O);
00568     return;
00569   }
00570 
00571   const MCOperand &MO3 = MI->getOperand(Op+2);
00572   unsigned IdxMode = ARM_AM::getAM3IdxMode(MO3.getImm());
00573 
00574   if (IdxMode == ARMII::IndexModePost) {
00575     printAM3PostIndexOp(MI, Op, O);
00576     return;
00577   }
00578   printAM3PreOrOffsetIndexOp(MI, Op, O, AlwaysPrintImm0);
00579 }
00580 
00581 void ARMInstPrinter::printAddrMode3OffsetOperand(const MCInst *MI,
00582                                                  unsigned OpNum,
00583                                                  raw_ostream &O) {
00584   const MCOperand &MO1 = MI->getOperand(OpNum);
00585   const MCOperand &MO2 = MI->getOperand(OpNum+1);
00586 
00587   if (MO1.getReg()) {
00588     O << getAddrOpcStr(ARM_AM::getAM3Op(MO2.getImm()));
00589     printRegName(O, MO1.getReg());
00590     return;
00591   }
00592 
00593   unsigned ImmOffs = ARM_AM::getAM3Offset(MO2.getImm());
00594   O << markup("<imm:")
00595     << '#' << ARM_AM::getAddrOpcStr(ARM_AM::getAM3Op(MO2.getImm())) << ImmOffs
00596     << markup(">");
00597 }
00598 
00599 void ARMInstPrinter::printPostIdxImm8Operand(const MCInst *MI,
00600                                              unsigned OpNum,
00601                                              raw_ostream &O) {
00602   const MCOperand &MO = MI->getOperand(OpNum);
00603   unsigned Imm = MO.getImm();
00604   O << markup("<imm:")
00605     << '#' << ((Imm & 256) ? "" : "-") << (Imm & 0xff)
00606     << markup(">");
00607 }
00608 
00609 void ARMInstPrinter::printPostIdxRegOperand(const MCInst *MI, unsigned OpNum,
00610                                             raw_ostream &O) {
00611   const MCOperand &MO1 = MI->getOperand(OpNum);
00612   const MCOperand &MO2 = MI->getOperand(OpNum+1);
00613 
00614   O << (MO2.getImm() ? "" : "-");
00615   printRegName(O, MO1.getReg());
00616 }
00617 
00618 void ARMInstPrinter::printPostIdxImm8s4Operand(const MCInst *MI,
00619                                              unsigned OpNum,
00620                                              raw_ostream &O) {
00621   const MCOperand &MO = MI->getOperand(OpNum);
00622   unsigned Imm = MO.getImm();
00623   O << markup("<imm:")
00624     << '#' << ((Imm & 256) ? "" : "-") << ((Imm & 0xff) << 2)
00625     << markup(">");
00626 }
00627 
00628 
00629 void ARMInstPrinter::printLdStmModeOperand(const MCInst *MI, unsigned OpNum,
00630                                            raw_ostream &O) {
00631   ARM_AM::AMSubMode Mode = ARM_AM::getAM4SubMode(MI->getOperand(OpNum)
00632                                                  .getImm());
00633   O << ARM_AM::getAMSubModeStr(Mode);
00634 }
00635 
00636 template <bool AlwaysPrintImm0>
00637 void ARMInstPrinter::printAddrMode5Operand(const MCInst *MI, unsigned OpNum,
00638                                            raw_ostream &O) {
00639   const MCOperand &MO1 = MI->getOperand(OpNum);
00640   const MCOperand &MO2 = MI->getOperand(OpNum+1);
00641 
00642   if (!MO1.isReg()) {   // FIXME: This is for CP entries, but isn't right.
00643     printOperand(MI, OpNum, O);
00644     return;
00645   }
00646 
00647   O << markup("<mem:") << "[";
00648   printRegName(O, MO1.getReg());
00649 
00650   unsigned ImmOffs = ARM_AM::getAM5Offset(MO2.getImm());
00651   unsigned Op = ARM_AM::getAM5Op(MO2.getImm());
00652   if (AlwaysPrintImm0 || ImmOffs || Op == ARM_AM::sub) {
00653     O << ", "
00654       << markup("<imm:")
00655       << "#"
00656       << ARM_AM::getAddrOpcStr(ARM_AM::getAM5Op(MO2.getImm()))
00657       << ImmOffs * 4
00658       << markup(">");
00659   }
00660   O << "]" << markup(">");
00661 }
00662 
00663 void ARMInstPrinter::printAddrMode6Operand(const MCInst *MI, unsigned OpNum,
00664                                            raw_ostream &O) {
00665   const MCOperand &MO1 = MI->getOperand(OpNum);
00666   const MCOperand &MO2 = MI->getOperand(OpNum+1);
00667 
00668   O << markup("<mem:") << "[";
00669   printRegName(O, MO1.getReg());
00670   if (MO2.getImm()) {
00671     O << ":" << (MO2.getImm() << 3);
00672   }
00673   O << "]" << markup(">");
00674 }
00675 
00676 void ARMInstPrinter::printAddrMode7Operand(const MCInst *MI, unsigned OpNum,
00677                                            raw_ostream &O) {
00678   const MCOperand &MO1 = MI->getOperand(OpNum);
00679   O << markup("<mem:") << "[";
00680   printRegName(O, MO1.getReg());
00681   O << "]" << markup(">");
00682 }
00683 
00684 void ARMInstPrinter::printAddrMode6OffsetOperand(const MCInst *MI,
00685                                                  unsigned OpNum,
00686                                                  raw_ostream &O) {
00687   const MCOperand &MO = MI->getOperand(OpNum);
00688   if (MO.getReg() == 0)
00689     O << "!";
00690   else {
00691     O << ", ";
00692     printRegName(O, MO.getReg());
00693   }
00694 }
00695 
00696 void ARMInstPrinter::printBitfieldInvMaskImmOperand(const MCInst *MI,
00697                                                     unsigned OpNum,
00698                                                     raw_ostream &O) {
00699   const MCOperand &MO = MI->getOperand(OpNum);
00700   uint32_t v = ~MO.getImm();
00701   int32_t lsb = countTrailingZeros(v);
00702   int32_t width = (32 - countLeadingZeros (v)) - lsb;
00703   assert(MO.isImm() && "Not a valid bf_inv_mask_imm value!");
00704   O << markup("<imm:") << '#' << lsb << markup(">")
00705     << ", "
00706     << markup("<imm:") << '#' << width << markup(">");
00707 }
00708 
00709 void ARMInstPrinter::printMemBOption(const MCInst *MI, unsigned OpNum,
00710                                      raw_ostream &O) {
00711   unsigned val = MI->getOperand(OpNum).getImm();
00712   O << ARM_MB::MemBOptToString(val, (getAvailableFeatures() & ARM::HasV8Ops));
00713 }
00714 
00715 void ARMInstPrinter::printInstSyncBOption(const MCInst *MI, unsigned OpNum,
00716                                           raw_ostream &O) {
00717   unsigned val = MI->getOperand(OpNum).getImm();
00718   O << ARM_ISB::InstSyncBOptToString(val);
00719 }
00720 
00721 void ARMInstPrinter::printShiftImmOperand(const MCInst *MI, unsigned OpNum,
00722                                           raw_ostream &O) {
00723   unsigned ShiftOp = MI->getOperand(OpNum).getImm();
00724   bool isASR = (ShiftOp & (1 << 5)) != 0;
00725   unsigned Amt = ShiftOp & 0x1f;
00726   if (isASR) {
00727     O << ", asr "
00728       << markup("<imm:")
00729       << "#" << (Amt == 0 ? 32 : Amt)
00730       << markup(">");
00731   }
00732   else if (Amt) {
00733     O << ", lsl "
00734       << markup("<imm:")
00735       << "#" << Amt
00736       << markup(">");
00737   }
00738 }
00739 
00740 void ARMInstPrinter::printPKHLSLShiftImm(const MCInst *MI, unsigned OpNum,
00741                                          raw_ostream &O) {
00742   unsigned Imm = MI->getOperand(OpNum).getImm();
00743   if (Imm == 0)
00744     return;
00745   assert(Imm > 0 && Imm < 32 && "Invalid PKH shift immediate value!");
00746   O << ", lsl " << markup("<imm:") << "#" << Imm << markup(">");
00747 }
00748 
00749 void ARMInstPrinter::printPKHASRShiftImm(const MCInst *MI, unsigned OpNum,
00750                                          raw_ostream &O) {
00751   unsigned Imm = MI->getOperand(OpNum).getImm();
00752   // A shift amount of 32 is encoded as 0.
00753   if (Imm == 0)
00754     Imm = 32;
00755   assert(Imm > 0 && Imm <= 32 && "Invalid PKH shift immediate value!");
00756   O << ", asr " << markup("<imm:") << "#" << Imm << markup(">");
00757 }
00758 
00759 void ARMInstPrinter::printRegisterList(const MCInst *MI, unsigned OpNum,
00760                                        raw_ostream &O) {
00761   O << "{";
00762   for (unsigned i = OpNum, e = MI->getNumOperands(); i != e; ++i) {
00763     if (i != OpNum) O << ", ";
00764     printRegName(O, MI->getOperand(i).getReg());
00765   }
00766   O << "}";
00767 }
00768 
00769 void ARMInstPrinter::printGPRPairOperand(const MCInst *MI, unsigned OpNum,
00770                                          raw_ostream &O) {
00771   unsigned Reg = MI->getOperand(OpNum).getReg();
00772   printRegName(O, MRI.getSubReg(Reg, ARM::gsub_0));
00773   O << ", ";
00774   printRegName(O, MRI.getSubReg(Reg, ARM::gsub_1));
00775 }
00776 
00777 
00778 void ARMInstPrinter::printSetendOperand(const MCInst *MI, unsigned OpNum,
00779                                         raw_ostream &O) {
00780   const MCOperand &Op = MI->getOperand(OpNum);
00781   if (Op.getImm())
00782     O << "be";
00783   else
00784     O << "le";
00785 }
00786 
00787 void ARMInstPrinter::printCPSIMod(const MCInst *MI, unsigned OpNum,
00788                                   raw_ostream &O) {
00789   const MCOperand &Op = MI->getOperand(OpNum);
00790   O << ARM_PROC::IModToString(Op.getImm());
00791 }
00792 
00793 void ARMInstPrinter::printCPSIFlag(const MCInst *MI, unsigned OpNum,
00794                                    raw_ostream &O) {
00795   const MCOperand &Op = MI->getOperand(OpNum);
00796   unsigned IFlags = Op.getImm();
00797   for (int i=2; i >= 0; --i)
00798     if (IFlags & (1 << i))
00799       O << ARM_PROC::IFlagsToString(1 << i);
00800 
00801   if (IFlags == 0)
00802     O << "none";
00803 }
00804 
00805 void ARMInstPrinter::printMSRMaskOperand(const MCInst *MI, unsigned OpNum,
00806                                          raw_ostream &O) {
00807   const MCOperand &Op = MI->getOperand(OpNum);
00808   unsigned SpecRegRBit = Op.getImm() >> 4;
00809   unsigned Mask = Op.getImm() & 0xf;
00810   uint64_t FeatureBits = getAvailableFeatures();
00811 
00812   if (FeatureBits & ARM::FeatureMClass) {
00813     unsigned SYSm = Op.getImm();
00814     unsigned Opcode = MI->getOpcode();
00815 
00816     // For writes, handle extended mask bits if the DSP extension is present.
00817     if (Opcode == ARM::t2MSR_M && (FeatureBits & ARM::FeatureDSPThumb2)) {
00818       switch (SYSm) {
00819       case 0x400: O << "apsr_g"; return;
00820       case 0xc00: O << "apsr_nzcvqg"; return;
00821       case 0x401: O << "iapsr_g"; return;
00822       case 0xc01: O << "iapsr_nzcvqg"; return;
00823       case 0x402: O << "eapsr_g"; return;
00824       case 0xc02: O << "eapsr_nzcvqg"; return;
00825       case 0x403: O << "xpsr_g"; return;
00826       case 0xc03: O << "xpsr_nzcvqg"; return;
00827       }
00828     }
00829 
00830     // Handle the basic 8-bit mask.
00831     SYSm &= 0xff;
00832 
00833     if (Opcode == ARM::t2MSR_M && (FeatureBits & ARM::HasV7Ops)) {
00834       // ARMv7-M deprecates using MSR APSR without a _<bits> qualifier as an
00835       // alias for MSR APSR_nzcvq.
00836       switch (SYSm) {
00837       case 0: O << "apsr_nzcvq"; return;
00838       case 1: O << "iapsr_nzcvq"; return;
00839       case 2: O << "eapsr_nzcvq"; return;
00840       case 3: O << "xpsr_nzcvq"; return;
00841       }
00842     }
00843 
00844     switch (SYSm) {
00845     default: llvm_unreachable("Unexpected mask value!");
00846     case  0: O << "apsr"; return;
00847     case  1: O << "iapsr"; return;
00848     case  2: O << "eapsr"; return;
00849     case  3: O << "xpsr"; return;
00850     case  5: O << "ipsr"; return;
00851     case  6: O << "epsr"; return;
00852     case  7: O << "iepsr"; return;
00853     case  8: O << "msp"; return;
00854     case  9: O << "psp"; return;
00855     case 16: O << "primask"; return;
00856     case 17: O << "basepri"; return;
00857     case 18: O << "basepri_max"; return;
00858     case 19: O << "faultmask"; return;
00859     case 20: O << "control"; return;
00860     }
00861   }
00862 
00863   // As special cases, CPSR_f, CPSR_s and CPSR_fs prefer printing as
00864   // APSR_nzcvq, APSR_g and APSRnzcvqg, respectively.
00865   if (!SpecRegRBit && (Mask == 8 || Mask == 4 || Mask == 12)) {
00866     O << "APSR_";
00867     switch (Mask) {
00868     default: llvm_unreachable("Unexpected mask value!");
00869     case 4:  O << "g"; return;
00870     case 8:  O << "nzcvq"; return;
00871     case 12: O << "nzcvqg"; return;
00872     }
00873   }
00874 
00875   if (SpecRegRBit)
00876     O << "SPSR";
00877   else
00878     O << "CPSR";
00879 
00880   if (Mask) {
00881     O << '_';
00882     if (Mask & 8) O << 'f';
00883     if (Mask & 4) O << 's';
00884     if (Mask & 2) O << 'x';
00885     if (Mask & 1) O << 'c';
00886   }
00887 }
00888 
00889 void ARMInstPrinter::printBankedRegOperand(const MCInst *MI, unsigned OpNum,
00890                                            raw_ostream &O) {
00891   uint32_t Banked = MI->getOperand(OpNum).getImm();
00892   uint32_t R = (Banked & 0x20) >> 5;
00893   uint32_t SysM = Banked & 0x1f;
00894 
00895   // Nothing much we can do about this, the encodings are specified in B9.2.3 of
00896   // the ARM ARM v7C, and are all over the shop.
00897   if (R) {
00898     O << "SPSR_";
00899 
00900     switch(SysM) {
00901     case 0x0e: O << "fiq"; return;
00902     case 0x10: O << "irq"; return;
00903     case 0x12: O << "svc"; return;
00904     case 0x14: O << "abt"; return;
00905     case 0x16: O << "und"; return;
00906     case 0x1c: O << "mon"; return;
00907     case 0x1e: O << "hyp"; return;
00908     default: llvm_unreachable("Invalid banked SPSR register");
00909     }
00910   }
00911 
00912   assert(!R && "should have dealt with SPSR regs");
00913   const char *RegNames[] = {
00914     "r8_usr", "r9_usr", "r10_usr", "r11_usr", "r12_usr", "sp_usr", "lr_usr", "",
00915     "r8_fiq", "r9_fiq", "r10_fiq", "r11_fiq", "r12_fiq", "sp_fiq", "lr_fiq", "",
00916     "lr_irq", "sp_irq", "lr_svc",  "sp_svc",  "lr_abt",  "sp_abt", "lr_und", "sp_und",
00917     "",       "",       "",        "",        "lr_mon",  "sp_mon", "elr_hyp", "sp_hyp"
00918   };
00919   const char *Name = RegNames[SysM];
00920   assert(Name[0] && "invalid banked register operand");
00921 
00922   O << Name;
00923 }
00924 
00925 void ARMInstPrinter::printPredicateOperand(const MCInst *MI, unsigned OpNum,
00926                                            raw_ostream &O) {
00927   ARMCC::CondCodes CC = (ARMCC::CondCodes)MI->getOperand(OpNum).getImm();
00928   // Handle the undefined 15 CC value here for printing so we don't abort().
00929   if ((unsigned)CC == 15)
00930     O << "<und>";
00931   else if (CC != ARMCC::AL)
00932     O << ARMCondCodeToString(CC);
00933 }
00934 
00935 void ARMInstPrinter::printMandatoryPredicateOperand(const MCInst *MI,
00936                                                     unsigned OpNum,
00937                                                     raw_ostream &O) {
00938   ARMCC::CondCodes CC = (ARMCC::CondCodes)MI->getOperand(OpNum).getImm();
00939   O << ARMCondCodeToString(CC);
00940 }
00941 
00942 void ARMInstPrinter::printSBitModifierOperand(const MCInst *MI, unsigned OpNum,
00943                                               raw_ostream &O) {
00944   if (MI->getOperand(OpNum).getReg()) {
00945     assert(MI->getOperand(OpNum).getReg() == ARM::CPSR &&
00946            "Expect ARM CPSR register!");
00947     O << 's';
00948   }
00949 }
00950 
00951 void ARMInstPrinter::printNoHashImmediate(const MCInst *MI, unsigned OpNum,
00952                                           raw_ostream &O) {
00953   O << MI->getOperand(OpNum).getImm();
00954 }
00955 
00956 void ARMInstPrinter::printPImmediate(const MCInst *MI, unsigned OpNum,
00957                                      raw_ostream &O) {
00958   O << "p" << MI->getOperand(OpNum).getImm();
00959 }
00960 
00961 void ARMInstPrinter::printCImmediate(const MCInst *MI, unsigned OpNum,
00962                                      raw_ostream &O) {
00963   O << "c" << MI->getOperand(OpNum).getImm();
00964 }
00965 
00966 void ARMInstPrinter::printCoprocOptionImm(const MCInst *MI, unsigned OpNum,
00967                                           raw_ostream &O) {
00968   O << "{" << MI->getOperand(OpNum).getImm() << "}";
00969 }
00970 
00971 void ARMInstPrinter::printPCLabel(const MCInst *MI, unsigned OpNum,
00972                                   raw_ostream &O) {
00973   llvm_unreachable("Unhandled PC-relative pseudo-instruction!");
00974 }
00975 
00976 template<unsigned scale>
00977 void ARMInstPrinter::printAdrLabelOperand(const MCInst *MI, unsigned OpNum,
00978                                   raw_ostream &O) {
00979   const MCOperand &MO = MI->getOperand(OpNum);
00980 
00981   if (MO.isExpr()) {
00982     O << *MO.getExpr();
00983     return;
00984   }
00985 
00986   int32_t OffImm = (int32_t)MO.getImm() << scale;
00987 
00988   O << markup("<imm:");
00989   if (OffImm == INT32_MIN)
00990     O << "#-0";
00991   else if (OffImm < 0)
00992     O << "#-" << -OffImm;
00993   else
00994     O << "#" << OffImm;
00995   O << markup(">");
00996 }
00997 
00998 void ARMInstPrinter::printThumbS4ImmOperand(const MCInst *MI, unsigned OpNum,
00999                                             raw_ostream &O) {
01000   O << markup("<imm:")
01001     << "#" << formatImm(MI->getOperand(OpNum).getImm() * 4)
01002     << markup(">");
01003 }
01004 
01005 void ARMInstPrinter::printThumbSRImm(const MCInst *MI, unsigned OpNum,
01006                                      raw_ostream &O) {
01007   unsigned Imm = MI->getOperand(OpNum).getImm();
01008   O << markup("<imm:")
01009     << "#" << formatImm((Imm == 0 ? 32 : Imm))
01010     << markup(">");
01011 }
01012 
01013 void ARMInstPrinter::printThumbITMask(const MCInst *MI, unsigned OpNum,
01014                                       raw_ostream &O) {
01015   // (3 - the number of trailing zeros) is the number of then / else.
01016   unsigned Mask = MI->getOperand(OpNum).getImm();
01017   unsigned Firstcond = MI->getOperand(OpNum-1).getImm();
01018   unsigned CondBit0 = Firstcond & 1;
01019   unsigned NumTZ = countTrailingZeros(Mask);
01020   assert(NumTZ <= 3 && "Invalid IT mask!");
01021   for (unsigned Pos = 3, e = NumTZ; Pos > e; --Pos) {
01022     bool T = ((Mask >> Pos) & 1) == CondBit0;
01023     if (T)
01024       O << 't';
01025     else
01026       O << 'e';
01027   }
01028 }
01029 
01030 void ARMInstPrinter::printThumbAddrModeRROperand(const MCInst *MI, unsigned Op,
01031                                                  raw_ostream &O) {
01032   const MCOperand &MO1 = MI->getOperand(Op);
01033   const MCOperand &MO2 = MI->getOperand(Op + 1);
01034 
01035   if (!MO1.isReg()) {   // FIXME: This is for CP entries, but isn't right.
01036     printOperand(MI, Op, O);
01037     return;
01038   }
01039 
01040   O << markup("<mem:") << "[";
01041   printRegName(O, MO1.getReg());
01042   if (unsigned RegNum = MO2.getReg()) {
01043     O << ", ";
01044     printRegName(O, RegNum);
01045   }
01046   O << "]" << markup(">");
01047 }
01048 
01049 void ARMInstPrinter::printThumbAddrModeImm5SOperand(const MCInst *MI,
01050                                                     unsigned Op,
01051                                                     raw_ostream &O,
01052                                                     unsigned Scale) {
01053   const MCOperand &MO1 = MI->getOperand(Op);
01054   const MCOperand &MO2 = MI->getOperand(Op + 1);
01055 
01056   if (!MO1.isReg()) {   // FIXME: This is for CP entries, but isn't right.
01057     printOperand(MI, Op, O);
01058     return;
01059   }
01060 
01061   O << markup("<mem:") << "[";
01062   printRegName(O, MO1.getReg());
01063   if (unsigned ImmOffs = MO2.getImm()) {
01064     O << ", "
01065       << markup("<imm:")
01066       << "#" << formatImm(ImmOffs * Scale)
01067       << markup(">");
01068   }
01069   O << "]" << markup(">");
01070 }
01071 
01072 void ARMInstPrinter::printThumbAddrModeImm5S1Operand(const MCInst *MI,
01073                                                      unsigned Op,
01074                                                      raw_ostream &O) {
01075   printThumbAddrModeImm5SOperand(MI, Op, O, 1);
01076 }
01077 
01078 void ARMInstPrinter::printThumbAddrModeImm5S2Operand(const MCInst *MI,
01079                                                      unsigned Op,
01080                                                      raw_ostream &O) {
01081   printThumbAddrModeImm5SOperand(MI, Op, O, 2);
01082 }
01083 
01084 void ARMInstPrinter::printThumbAddrModeImm5S4Operand(const MCInst *MI,
01085                                                      unsigned Op,
01086                                                      raw_ostream &O) {
01087   printThumbAddrModeImm5SOperand(MI, Op, O, 4);
01088 }
01089 
01090 void ARMInstPrinter::printThumbAddrModeSPOperand(const MCInst *MI, unsigned Op,
01091                                                  raw_ostream &O) {
01092   printThumbAddrModeImm5SOperand(MI, Op, O, 4);
01093 }
01094 
01095 // Constant shifts t2_so_reg is a 2-operand unit corresponding to the Thumb2
01096 // register with shift forms.
01097 // REG 0   0           - e.g. R5
01098 // REG IMM, SH_OPC     - e.g. R5, LSL #3
01099 void ARMInstPrinter::printT2SOOperand(const MCInst *MI, unsigned OpNum,
01100                                       raw_ostream &O) {
01101   const MCOperand &MO1 = MI->getOperand(OpNum);
01102   const MCOperand &MO2 = MI->getOperand(OpNum+1);
01103 
01104   unsigned Reg = MO1.getReg();
01105   printRegName(O, Reg);
01106 
01107   // Print the shift opc.
01108   assert(MO2.isImm() && "Not a valid t2_so_reg value!");
01109   printRegImmShift(O, ARM_AM::getSORegShOp(MO2.getImm()),
01110                    ARM_AM::getSORegOffset(MO2.getImm()), UseMarkup);
01111 }
01112 
01113 template <bool AlwaysPrintImm0>
01114 void ARMInstPrinter::printAddrModeImm12Operand(const MCInst *MI, unsigned OpNum,
01115                                                raw_ostream &O) {
01116   const MCOperand &MO1 = MI->getOperand(OpNum);
01117   const MCOperand &MO2 = MI->getOperand(OpNum+1);
01118 
01119   if (!MO1.isReg()) {   // FIXME: This is for CP entries, but isn't right.
01120     printOperand(MI, OpNum, O);
01121     return;
01122   }
01123 
01124   O << markup("<mem:") << "[";
01125   printRegName(O, MO1.getReg());
01126 
01127   int32_t OffImm = (int32_t)MO2.getImm();
01128   bool isSub = OffImm < 0;
01129   // Special value for #-0. All others are normal.
01130   if (OffImm == INT32_MIN)
01131     OffImm = 0;
01132   if (isSub) {
01133     O << ", "
01134       << markup("<imm:")
01135       << "#-" << formatImm(-OffImm)
01136       << markup(">");
01137   }
01138   else if (AlwaysPrintImm0 || OffImm > 0) {
01139     O << ", "
01140       << markup("<imm:")
01141       << "#" << formatImm(OffImm)
01142       << markup(">");
01143   }
01144   O << "]" << markup(">");
01145 }
01146 
01147 template<bool AlwaysPrintImm0>
01148 void ARMInstPrinter::printT2AddrModeImm8Operand(const MCInst *MI,
01149                                                 unsigned OpNum,
01150                                                 raw_ostream &O) {
01151   const MCOperand &MO1 = MI->getOperand(OpNum);
01152   const MCOperand &MO2 = MI->getOperand(OpNum+1);
01153 
01154   O << markup("<mem:") << "[";
01155   printRegName(O, MO1.getReg());
01156 
01157   int32_t OffImm = (int32_t)MO2.getImm();
01158   bool isSub = OffImm < 0;
01159   // Don't print +0.
01160   if (OffImm == INT32_MIN)
01161     OffImm = 0;
01162   if (isSub) {
01163     O << ", "
01164       << markup("<imm:")
01165       << "#-" << -OffImm
01166       << markup(">");
01167   } else if (AlwaysPrintImm0 || OffImm > 0) {
01168     O << ", "
01169       << markup("<imm:")
01170       << "#" << OffImm
01171       << markup(">");
01172   }
01173   O << "]" << markup(">");
01174 }
01175 
01176 template<bool AlwaysPrintImm0>
01177 void ARMInstPrinter::printT2AddrModeImm8s4Operand(const MCInst *MI,
01178                                                   unsigned OpNum,
01179                                                   raw_ostream &O) {
01180   const MCOperand &MO1 = MI->getOperand(OpNum);
01181   const MCOperand &MO2 = MI->getOperand(OpNum+1);
01182 
01183   if (!MO1.isReg()) {   //  For label symbolic references.
01184     printOperand(MI, OpNum, O);
01185     return;
01186   }
01187 
01188   O << markup("<mem:") << "[";
01189   printRegName(O, MO1.getReg());
01190 
01191   int32_t OffImm = (int32_t)MO2.getImm();
01192   bool isSub = OffImm < 0;
01193 
01194   assert(((OffImm & 0x3) == 0) && "Not a valid immediate!");
01195 
01196   // Don't print +0.
01197   if (OffImm == INT32_MIN)
01198     OffImm = 0;
01199   if (isSub) {
01200     O << ", "
01201       << markup("<imm:")
01202       << "#-" << -OffImm
01203       << markup(">");
01204   } else if (AlwaysPrintImm0 || OffImm > 0) {
01205     O << ", "
01206       << markup("<imm:")
01207       << "#" << OffImm
01208       << markup(">");
01209   }
01210   O << "]" << markup(">");
01211 }
01212 
01213 void ARMInstPrinter::printT2AddrModeImm0_1020s4Operand(const MCInst *MI,
01214                                                        unsigned OpNum,
01215                                                        raw_ostream &O) {
01216   const MCOperand &MO1 = MI->getOperand(OpNum);
01217   const MCOperand &MO2 = MI->getOperand(OpNum+1);
01218 
01219   O << markup("<mem:") << "[";
01220   printRegName(O, MO1.getReg());
01221   if (MO2.getImm()) {
01222     O << ", "
01223       << markup("<imm:")
01224       << "#" << formatImm(MO2.getImm() * 4)
01225       << markup(">");
01226   }
01227   O << "]" << markup(">");
01228 }
01229 
01230 void ARMInstPrinter::printT2AddrModeImm8OffsetOperand(const MCInst *MI,
01231                                                       unsigned OpNum,
01232                                                       raw_ostream &O) {
01233   const MCOperand &MO1 = MI->getOperand(OpNum);
01234   int32_t OffImm = (int32_t)MO1.getImm();
01235   O << ", " << markup("<imm:");
01236   if (OffImm == INT32_MIN)
01237     O << "#-0";
01238   else if (OffImm < 0)
01239     O << "#-" << -OffImm;
01240   else
01241     O << "#" << OffImm;
01242   O << markup(">");
01243 }
01244 
01245 void ARMInstPrinter::printT2AddrModeImm8s4OffsetOperand(const MCInst *MI,
01246                                                         unsigned OpNum,
01247                                                         raw_ostream &O) {
01248   const MCOperand &MO1 = MI->getOperand(OpNum);
01249   int32_t OffImm = (int32_t)MO1.getImm();
01250 
01251   assert(((OffImm & 0x3) == 0) && "Not a valid immediate!");
01252 
01253   O << ", " << markup("<imm:");
01254   if (OffImm == INT32_MIN)
01255     O << "#-0";
01256   else if (OffImm < 0)
01257     O << "#-" << -OffImm;
01258   else
01259     O << "#" << OffImm;
01260   O << markup(">");
01261 }
01262 
01263 void ARMInstPrinter::printT2AddrModeSoRegOperand(const MCInst *MI,
01264                                                  unsigned OpNum,
01265                                                  raw_ostream &O) {
01266   const MCOperand &MO1 = MI->getOperand(OpNum);
01267   const MCOperand &MO2 = MI->getOperand(OpNum+1);
01268   const MCOperand &MO3 = MI->getOperand(OpNum+2);
01269 
01270   O << markup("<mem:") << "[";
01271   printRegName(O, MO1.getReg());
01272 
01273   assert(MO2.getReg() && "Invalid so_reg load / store address!");
01274   O << ", ";
01275   printRegName(O, MO2.getReg());
01276 
01277   unsigned ShAmt = MO3.getImm();
01278   if (ShAmt) {
01279     assert(ShAmt <= 3 && "Not a valid Thumb2 addressing mode!");
01280     O << ", lsl "
01281       << markup("<imm:")
01282       << "#" << ShAmt
01283       << markup(">");
01284   }
01285   O << "]" << markup(">");
01286 }
01287 
01288 void ARMInstPrinter::printFPImmOperand(const MCInst *MI, unsigned OpNum,
01289                                        raw_ostream &O) {
01290   const MCOperand &MO = MI->getOperand(OpNum);
01291   O << markup("<imm:")
01292     << '#' << ARM_AM::getFPImmFloat(MO.getImm())
01293     << markup(">");
01294 }
01295 
01296 void ARMInstPrinter::printNEONModImmOperand(const MCInst *MI, unsigned OpNum,
01297                                             raw_ostream &O) {
01298   unsigned EncodedImm = MI->getOperand(OpNum).getImm();
01299   unsigned EltBits;
01300   uint64_t Val = ARM_AM::decodeNEONModImm(EncodedImm, EltBits);
01301   O << markup("<imm:")
01302     << "#0x";
01303   O.write_hex(Val);
01304   O << markup(">");
01305 }
01306 
01307 void ARMInstPrinter::printImmPlusOneOperand(const MCInst *MI, unsigned OpNum,
01308                                             raw_ostream &O) {
01309   unsigned Imm = MI->getOperand(OpNum).getImm();
01310   O << markup("<imm:")
01311     << "#" << formatImm(Imm + 1)
01312     << markup(">");
01313 }
01314 
01315 void ARMInstPrinter::printRotImmOperand(const MCInst *MI, unsigned OpNum,
01316                                         raw_ostream &O) {
01317   unsigned Imm = MI->getOperand(OpNum).getImm();
01318   if (Imm == 0)
01319     return;
01320   O << ", ror "
01321     << markup("<imm:")
01322     << "#";
01323   switch (Imm) {
01324   default: assert (0 && "illegal ror immediate!");
01325   case 1: O << "8"; break;
01326   case 2: O << "16"; break;
01327   case 3: O << "24"; break;
01328   }
01329   O << markup(">");
01330 }
01331 
01332 void ARMInstPrinter::printFBits16(const MCInst *MI, unsigned OpNum,
01333                                   raw_ostream &O) {
01334   O << markup("<imm:")
01335     << "#" << 16 - MI->getOperand(OpNum).getImm()
01336     << markup(">");
01337 }
01338 
01339 void ARMInstPrinter::printFBits32(const MCInst *MI, unsigned OpNum,
01340                                   raw_ostream &O) {
01341   O << markup("<imm:")
01342     << "#" << 32 - MI->getOperand(OpNum).getImm()
01343     << markup(">");
01344 }
01345 
01346 void ARMInstPrinter::printVectorIndex(const MCInst *MI, unsigned OpNum,
01347                                       raw_ostream &O) {
01348   O << "[" << MI->getOperand(OpNum).getImm() << "]";
01349 }
01350 
01351 void ARMInstPrinter::printVectorListOne(const MCInst *MI, unsigned OpNum,
01352                                         raw_ostream &O) {
01353   O << "{";
01354   printRegName(O, MI->getOperand(OpNum).getReg());
01355   O << "}";
01356 }
01357 
01358 void ARMInstPrinter::printVectorListTwo(const MCInst *MI, unsigned OpNum,
01359                                           raw_ostream &O) {
01360   unsigned Reg = MI->getOperand(OpNum).getReg();
01361   unsigned Reg0 = MRI.getSubReg(Reg, ARM::dsub_0);
01362   unsigned Reg1 = MRI.getSubReg(Reg, ARM::dsub_1);
01363   O << "{";
01364   printRegName(O, Reg0);
01365   O << ", ";
01366   printRegName(O, Reg1);
01367   O << "}";
01368 }
01369 
01370 void ARMInstPrinter::printVectorListTwoSpaced(const MCInst *MI,
01371                                               unsigned OpNum,
01372                                               raw_ostream &O) {
01373   unsigned Reg = MI->getOperand(OpNum).getReg();
01374   unsigned Reg0 = MRI.getSubReg(Reg, ARM::dsub_0);
01375   unsigned Reg1 = MRI.getSubReg(Reg, ARM::dsub_2);
01376   O << "{";
01377   printRegName(O, Reg0);
01378   O << ", ";
01379   printRegName(O, Reg1);
01380   O << "}";
01381 }
01382 
01383 void ARMInstPrinter::printVectorListThree(const MCInst *MI, unsigned OpNum,
01384                                           raw_ostream &O) {
01385   // Normally, it's not safe to use register enum values directly with
01386   // addition to get the next register, but for VFP registers, the
01387   // sort order is guaranteed because they're all of the form D<n>.
01388   O << "{";
01389   printRegName(O, MI->getOperand(OpNum).getReg());
01390   O << ", ";
01391   printRegName(O, MI->getOperand(OpNum).getReg() + 1);
01392   O << ", ";
01393   printRegName(O, MI->getOperand(OpNum).getReg() + 2);
01394   O << "}";
01395 }
01396 
01397 void ARMInstPrinter::printVectorListFour(const MCInst *MI, unsigned OpNum,
01398                                          raw_ostream &O) {
01399   // Normally, it's not safe to use register enum values directly with
01400   // addition to get the next register, but for VFP registers, the
01401   // sort order is guaranteed because they're all of the form D<n>.
01402   O << "{";
01403   printRegName(O, MI->getOperand(OpNum).getReg());
01404   O << ", ";
01405   printRegName(O, MI->getOperand(OpNum).getReg() + 1);
01406   O << ", ";
01407   printRegName(O, MI->getOperand(OpNum).getReg() + 2);
01408   O << ", ";
01409   printRegName(O, MI->getOperand(OpNum).getReg() + 3);
01410   O << "}";
01411 }
01412 
01413 void ARMInstPrinter::printVectorListOneAllLanes(const MCInst *MI,
01414                                                 unsigned OpNum,
01415                                                 raw_ostream &O) {
01416   O << "{";
01417   printRegName(O, MI->getOperand(OpNum).getReg());
01418   O << "[]}";
01419 }
01420 
01421 void ARMInstPrinter::printVectorListTwoAllLanes(const MCInst *MI,
01422                                                 unsigned OpNum,
01423                                                 raw_ostream &O) {
01424   unsigned Reg = MI->getOperand(OpNum).getReg();
01425   unsigned Reg0 = MRI.getSubReg(Reg, ARM::dsub_0);
01426   unsigned Reg1 = MRI.getSubReg(Reg, ARM::dsub_1);
01427   O << "{";
01428   printRegName(O, Reg0);
01429   O << "[], ";
01430   printRegName(O, Reg1);
01431   O << "[]}";
01432 }
01433 
01434 void ARMInstPrinter::printVectorListThreeAllLanes(const MCInst *MI,
01435                                                   unsigned OpNum,
01436                                                   raw_ostream &O) {
01437   // Normally, it's not safe to use register enum values directly with
01438   // addition to get the next register, but for VFP registers, the
01439   // sort order is guaranteed because they're all of the form D<n>.
01440   O << "{";
01441   printRegName(O, MI->getOperand(OpNum).getReg());
01442   O << "[], ";
01443   printRegName(O, MI->getOperand(OpNum).getReg() + 1);
01444   O << "[], ";
01445   printRegName(O, MI->getOperand(OpNum).getReg() + 2);
01446   O << "[]}";
01447 }
01448 
01449 void ARMInstPrinter::printVectorListFourAllLanes(const MCInst *MI,
01450                                                   unsigned OpNum,
01451                                                   raw_ostream &O) {
01452   // Normally, it's not safe to use register enum values directly with
01453   // addition to get the next register, but for VFP registers, the
01454   // sort order is guaranteed because they're all of the form D<n>.
01455   O << "{";
01456   printRegName(O, MI->getOperand(OpNum).getReg());
01457   O << "[], ";
01458   printRegName(O, MI->getOperand(OpNum).getReg() + 1);
01459   O << "[], ";
01460   printRegName(O, MI->getOperand(OpNum).getReg() + 2);
01461   O << "[], ";
01462   printRegName(O, MI->getOperand(OpNum).getReg() + 3);
01463   O << "[]}";
01464 }
01465 
01466 void ARMInstPrinter::printVectorListTwoSpacedAllLanes(const MCInst *MI,
01467                                                       unsigned OpNum,
01468                                                       raw_ostream &O) {
01469   unsigned Reg = MI->getOperand(OpNum).getReg();
01470   unsigned Reg0 = MRI.getSubReg(Reg, ARM::dsub_0);
01471   unsigned Reg1 = MRI.getSubReg(Reg, ARM::dsub_2);
01472   O << "{";
01473   printRegName(O, Reg0);
01474   O << "[], ";
01475   printRegName(O, Reg1);
01476   O << "[]}";
01477 }
01478 
01479 void ARMInstPrinter::printVectorListThreeSpacedAllLanes(const MCInst *MI,
01480                                                         unsigned OpNum,
01481                                                         raw_ostream &O) {
01482   // Normally, it's not safe to use register enum values directly with
01483   // addition to get the next register, but for VFP registers, the
01484   // sort order is guaranteed because they're all of the form D<n>.
01485   O << "{";
01486   printRegName(O, MI->getOperand(OpNum).getReg());
01487   O  << "[], ";
01488   printRegName(O, MI->getOperand(OpNum).getReg() + 2);
01489   O << "[], ";
01490   printRegName(O, MI->getOperand(OpNum).getReg() + 4);
01491   O << "[]}";
01492 }
01493 
01494 void ARMInstPrinter::printVectorListFourSpacedAllLanes(const MCInst *MI,
01495                                                        unsigned OpNum,
01496                                                        raw_ostream &O) {
01497   // Normally, it's not safe to use register enum values directly with
01498   // addition to get the next register, but for VFP registers, the
01499   // sort order is guaranteed because they're all of the form D<n>.
01500   O << "{";
01501   printRegName(O, MI->getOperand(OpNum).getReg());
01502   O << "[], ";
01503   printRegName(O, MI->getOperand(OpNum).getReg() + 2);
01504   O << "[], ";
01505   printRegName(O, MI->getOperand(OpNum).getReg() + 4);
01506   O << "[], ";
01507   printRegName(O, MI->getOperand(OpNum).getReg() + 6);
01508   O << "[]}";
01509 }
01510 
01511 void ARMInstPrinter::printVectorListThreeSpaced(const MCInst *MI,
01512                                                 unsigned OpNum,
01513                                                 raw_ostream &O) {
01514   // Normally, it's not safe to use register enum values directly with
01515   // addition to get the next register, but for VFP registers, the
01516   // sort order is guaranteed because they're all of the form D<n>.
01517   O << "{";
01518   printRegName(O, MI->getOperand(OpNum).getReg());
01519   O << ", ";
01520   printRegName(O, MI->getOperand(OpNum).getReg() + 2);
01521   O << ", ";
01522   printRegName(O, MI->getOperand(OpNum).getReg() + 4);
01523   O << "}";
01524 }
01525 
01526 void ARMInstPrinter::printVectorListFourSpaced(const MCInst *MI,
01527                                                 unsigned OpNum,
01528                                                 raw_ostream &O) {
01529   // Normally, it's not safe to use register enum values directly with
01530   // addition to get the next register, but for VFP registers, the
01531   // sort order is guaranteed because they're all of the form D<n>.
01532   O << "{";
01533   printRegName(O, MI->getOperand(OpNum).getReg());
01534   O << ", ";
01535   printRegName(O, MI->getOperand(OpNum).getReg() + 2);
01536   O << ", ";
01537   printRegName(O, MI->getOperand(OpNum).getReg() + 4);
01538   O << ", ";
01539   printRegName(O, MI->getOperand(OpNum).getReg() + 6);
01540   O << "}";
01541 }