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