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