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