LLVM API Documentation
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 }