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 assert(std::is_sorted(MI->begin() + OpNum, MI->end(), 730 [&](const MCOperand &LHS, const MCOperand &RHS) { 731 return MRI.getEncodingValue(LHS.getReg()) < 732 MRI.getEncodingValue(RHS.getReg()); 733 })); 734 735 O << "{"; 736 for (unsigned i = OpNum, e = MI->getNumOperands(); i != e; ++i) { 737 if (i != OpNum) 738 O << ", "; 739 printRegName(O, MI->getOperand(i).getReg()); 740 } 741 O << "}"; 742 } 743 744 void ARMInstPrinter::printGPRPairOperand(const MCInst *MI, unsigned OpNum, 745 const MCSubtargetInfo &STI, 746 raw_ostream &O) { 747 unsigned Reg = MI->getOperand(OpNum).getReg(); 748 printRegName(O, MRI.getSubReg(Reg, ARM::gsub_0)); 749 O << ", "; 750 printRegName(O, MRI.getSubReg(Reg, ARM::gsub_1)); 751 } 752 753 void ARMInstPrinter::printSetendOperand(const MCInst *MI, unsigned OpNum, 754 const MCSubtargetInfo &STI, 755 raw_ostream &O) { 756 const MCOperand &Op = MI->getOperand(OpNum); 757 if (Op.getImm()) 758 O << "be"; 759 else 760 O << "le"; 761 } 762 763 void ARMInstPrinter::printCPSIMod(const MCInst *MI, unsigned OpNum, 764 const MCSubtargetInfo &STI, raw_ostream &O) { 765 const MCOperand &Op = MI->getOperand(OpNum); 766 O << ARM_PROC::IModToString(Op.getImm()); 767 } 768 769 void ARMInstPrinter::printCPSIFlag(const MCInst *MI, unsigned OpNum, 770 const MCSubtargetInfo &STI, raw_ostream &O) { 771 const MCOperand &Op = MI->getOperand(OpNum); 772 unsigned IFlags = Op.getImm(); 773 for (int i = 2; i >= 0; --i) 774 if (IFlags & (1 << i)) 775 O << ARM_PROC::IFlagsToString(1 << i); 776 777 if (IFlags == 0) 778 O << "none"; 779 } 780 781 void ARMInstPrinter::printMSRMaskOperand(const MCInst *MI, unsigned OpNum, 782 const MCSubtargetInfo &STI, 783 raw_ostream &O) { 784 const MCOperand &Op = MI->getOperand(OpNum); 785 unsigned SpecRegRBit = Op.getImm() >> 4; 786 unsigned Mask = Op.getImm() & 0xf; 787 const FeatureBitset &FeatureBits = STI.getFeatureBits(); 788 789 if (FeatureBits[ARM::FeatureMClass]) { 790 unsigned SYSm = Op.getImm(); 791 unsigned Opcode = MI->getOpcode(); 792 793 // For writes, handle extended mask bits if the DSP extension is present. 794 if (Opcode == ARM::t2MSR_M && FeatureBits[ARM::FeatureDSP]) { 795 switch (SYSm) { 796 case 0x400: 797 O << "apsr_g"; 798 return; 799 case 0xc00: 800 O << "apsr_nzcvqg"; 801 return; 802 case 0x401: 803 O << "iapsr_g"; 804 return; 805 case 0xc01: 806 O << "iapsr_nzcvqg"; 807 return; 808 case 0x402: 809 O << "eapsr_g"; 810 return; 811 case 0xc02: 812 O << "eapsr_nzcvqg"; 813 return; 814 case 0x403: 815 O << "xpsr_g"; 816 return; 817 case 0xc03: 818 O << "xpsr_nzcvqg"; 819 return; 820 } 821 } 822 823 // Handle the basic 8-bit mask. 824 SYSm &= 0xff; 825 826 if (Opcode == ARM::t2MSR_M && FeatureBits [ARM::HasV7Ops]) { 827 // ARMv7-M deprecates using MSR APSR without a _<bits> qualifier as an 828 // alias for MSR APSR_nzcvq. 829 switch (SYSm) { 830 case 0: 831 O << "apsr_nzcvq"; 832 return; 833 case 1: 834 O << "iapsr_nzcvq"; 835 return; 836 case 2: 837 O << "eapsr_nzcvq"; 838 return; 839 case 3: 840 O << "xpsr_nzcvq"; 841 return; 842 } 843 } 844 845 switch (SYSm) { 846 default: 847 llvm_unreachable("Unexpected mask value!"); 848 case 0: 849 O << "apsr"; 850 return; 851 case 1: 852 O << "iapsr"; 853 return; 854 case 2: 855 O << "eapsr"; 856 return; 857 case 3: 858 O << "xpsr"; 859 return; 860 case 5: 861 O << "ipsr"; 862 return; 863 case 6: 864 O << "epsr"; 865 return; 866 case 7: 867 O << "iepsr"; 868 return; 869 case 8: 870 O << "msp"; 871 return; 872 case 9: 873 O << "psp"; 874 return; 875 case 16: 876 O << "primask"; 877 return; 878 case 17: 879 O << "basepri"; 880 return; 881 case 18: 882 O << "basepri_max"; 883 return; 884 case 19: 885 O << "faultmask"; 886 return; 887 case 20: 888 O << "control"; 889 return; 890 case 10: 891 O << "msplim"; 892 return; 893 case 11: 894 O << "psplim"; 895 return; 896 case 0x88: 897 O << "msp_ns"; 898 return; 899 case 0x89: 900 O << "psp_ns"; 901 return; 902 case 0x8a: 903 O << "msplim_ns"; 904 return; 905 case 0x8b: 906 O << "psplim_ns"; 907 return; 908 case 0x90: 909 O << "primask_ns"; 910 return; 911 case 0x91: 912 O << "basepri_ns"; 913 return; 914 case 0x92: 915 O << "basepri_max_ns"; 916 return; 917 case 0x93: 918 O << "faultmask_ns"; 919 return; 920 case 0x94: 921 O << "control_ns"; 922 return; 923 case 0x98: 924 O << "sp_ns"; 925 return; 926 } 927 } 928 929 // As special cases, CPSR_f, CPSR_s and CPSR_fs prefer printing as 930 // APSR_nzcvq, APSR_g and APSRnzcvqg, respectively. 931 if (!SpecRegRBit && (Mask == 8 || Mask == 4 || Mask == 12)) { 932 O << "APSR_"; 933 switch (Mask) { 934 default: 935 llvm_unreachable("Unexpected mask value!"); 936 case 4: 937 O << "g"; 938 return; 939 case 8: 940 O << "nzcvq"; 941 return; 942 case 12: 943 O << "nzcvqg"; 944 return; 945 } 946 } 947 948 if (SpecRegRBit) 949 O << "SPSR"; 950 else 951 O << "CPSR"; 952 953 if (Mask) { 954 O << '_'; 955 if (Mask & 8) 956 O << 'f'; 957 if (Mask & 4) 958 O << 's'; 959 if (Mask & 2) 960 O << 'x'; 961 if (Mask & 1) 962 O << 'c'; 963 } 964 } 965 966 void ARMInstPrinter::printBankedRegOperand(const MCInst *MI, unsigned OpNum, 967 const MCSubtargetInfo &STI, 968 raw_ostream &O) { 969 uint32_t Banked = MI->getOperand(OpNum).getImm(); 970 uint32_t R = (Banked & 0x20) >> 5; 971 uint32_t SysM = Banked & 0x1f; 972 973 // Nothing much we can do about this, the encodings are specified in B9.2.3 of 974 // the ARM ARM v7C, and are all over the shop. 975 if (R) { 976 O << "SPSR_"; 977 978 switch (SysM) { 979 case 0x0e: 980 O << "fiq"; 981 return; 982 case 0x10: 983 O << "irq"; 984 return; 985 case 0x12: 986 O << "svc"; 987 return; 988 case 0x14: 989 O << "abt"; 990 return; 991 case 0x16: 992 O << "und"; 993 return; 994 case 0x1c: 995 O << "mon"; 996 return; 997 case 0x1e: 998 O << "hyp"; 999 return; 1000 default: 1001 llvm_unreachable("Invalid banked SPSR register"); 1002 } 1003 } 1004 1005 assert(!R && "should have dealt with SPSR regs"); 1006 const char *RegNames[] = { 1007 "r8_usr", "r9_usr", "r10_usr", "r11_usr", "r12_usr", "sp_usr", "lr_usr", 1008 "", "r8_fiq", "r9_fiq", "r10_fiq", "r11_fiq", "r12_fiq", "sp_fiq", 1009 "lr_fiq", "", "lr_irq", "sp_irq", "lr_svc", "sp_svc", "lr_abt", 1010 "sp_abt", "lr_und", "sp_und", "", "", "", "", 1011 "lr_mon", "sp_mon", "elr_hyp", "sp_hyp"}; 1012 const char *Name = RegNames[SysM]; 1013 assert(Name[0] && "invalid banked register operand"); 1014 1015 O << Name; 1016 } 1017 1018 void ARMInstPrinter::printPredicateOperand(const MCInst *MI, unsigned OpNum, 1019 const MCSubtargetInfo &STI, 1020 raw_ostream &O) { 1021 ARMCC::CondCodes CC = (ARMCC::CondCodes)MI->getOperand(OpNum).getImm(); 1022 // Handle the undefined 15 CC value here for printing so we don't abort(). 1023 if ((unsigned)CC == 15) 1024 O << "<und>"; 1025 else if (CC != ARMCC::AL) 1026 O << ARMCondCodeToString(CC); 1027 } 1028 1029 void ARMInstPrinter::printMandatoryPredicateOperand(const MCInst *MI, 1030 unsigned OpNum, 1031 const MCSubtargetInfo &STI, 1032 raw_ostream &O) { 1033 ARMCC::CondCodes CC = (ARMCC::CondCodes)MI->getOperand(OpNum).getImm(); 1034 O << ARMCondCodeToString(CC); 1035 } 1036 1037 void ARMInstPrinter::printSBitModifierOperand(const MCInst *MI, unsigned OpNum, 1038 const MCSubtargetInfo &STI, 1039 raw_ostream &O) { 1040 if (MI->getOperand(OpNum).getReg()) { 1041 assert(MI->getOperand(OpNum).getReg() == ARM::CPSR && 1042 "Expect ARM CPSR register!"); 1043 O << 's'; 1044 } 1045 } 1046 1047 void ARMInstPrinter::printNoHashImmediate(const MCInst *MI, unsigned OpNum, 1048 const MCSubtargetInfo &STI, 1049 raw_ostream &O) { 1050 O << MI->getOperand(OpNum).getImm(); 1051 } 1052 1053 void ARMInstPrinter::printPImmediate(const MCInst *MI, unsigned OpNum, 1054 const MCSubtargetInfo &STI, 1055 raw_ostream &O) { 1056 O << "p" << MI->getOperand(OpNum).getImm(); 1057 } 1058 1059 void ARMInstPrinter::printCImmediate(const MCInst *MI, unsigned OpNum, 1060 const MCSubtargetInfo &STI, 1061 raw_ostream &O) { 1062 O << "c" << MI->getOperand(OpNum).getImm(); 1063 } 1064 1065 void ARMInstPrinter::printCoprocOptionImm(const MCInst *MI, unsigned OpNum, 1066 const MCSubtargetInfo &STI, 1067 raw_ostream &O) { 1068 O << "{" << MI->getOperand(OpNum).getImm() << "}"; 1069 } 1070 1071 void ARMInstPrinter::printPCLabel(const MCInst *MI, unsigned OpNum, 1072 const MCSubtargetInfo &STI, raw_ostream &O) { 1073 llvm_unreachable("Unhandled PC-relative pseudo-instruction!"); 1074 } 1075 1076 template <unsigned scale> 1077 void ARMInstPrinter::printAdrLabelOperand(const MCInst *MI, unsigned OpNum, 1078 const MCSubtargetInfo &STI, 1079 raw_ostream &O) { 1080 const MCOperand &MO = MI->getOperand(OpNum); 1081 1082 if (MO.isExpr()) { 1083 MO.getExpr()->print(O, &MAI); 1084 return; 1085 } 1086 1087 int32_t OffImm = (int32_t)MO.getImm() << scale; 1088 1089 O << markup("<imm:"); 1090 if (OffImm == INT32_MIN) 1091 O << "#-0"; 1092 else if (OffImm < 0) 1093 O << "#-" << -OffImm; 1094 else 1095 O << "#" << OffImm; 1096 O << markup(">"); 1097 } 1098 1099 void ARMInstPrinter::printThumbS4ImmOperand(const MCInst *MI, unsigned OpNum, 1100 const MCSubtargetInfo &STI, 1101 raw_ostream &O) { 1102 O << markup("<imm:") << "#" << formatImm(MI->getOperand(OpNum).getImm() * 4) 1103 << markup(">"); 1104 } 1105 1106 void ARMInstPrinter::printThumbSRImm(const MCInst *MI, unsigned OpNum, 1107 const MCSubtargetInfo &STI, 1108 raw_ostream &O) { 1109 unsigned Imm = MI->getOperand(OpNum).getImm(); 1110 O << markup("<imm:") << "#" << formatImm((Imm == 0 ? 32 : Imm)) 1111 << markup(">"); 1112 } 1113 1114 void ARMInstPrinter::printThumbITMask(const MCInst *MI, unsigned OpNum, 1115 const MCSubtargetInfo &STI, 1116 raw_ostream &O) { 1117 // (3 - the number of trailing zeros) is the number of then / else. 1118 unsigned Mask = MI->getOperand(OpNum).getImm(); 1119 unsigned Firstcond = MI->getOperand(OpNum - 1).getImm(); 1120 unsigned CondBit0 = Firstcond & 1; 1121 unsigned NumTZ = countTrailingZeros(Mask); 1122 assert(NumTZ <= 3 && "Invalid IT mask!"); 1123 for (unsigned Pos = 3, e = NumTZ; Pos > e; --Pos) { 1124 bool T = ((Mask >> Pos) & 1) == CondBit0; 1125 if (T) 1126 O << 't'; 1127 else 1128 O << 'e'; 1129 } 1130 } 1131 1132 void ARMInstPrinter::printThumbAddrModeRROperand(const MCInst *MI, unsigned Op, 1133 const MCSubtargetInfo &STI, 1134 raw_ostream &O) { 1135 const MCOperand &MO1 = MI->getOperand(Op); 1136 const MCOperand &MO2 = MI->getOperand(Op + 1); 1137 1138 if (!MO1.isReg()) { // FIXME: This is for CP entries, but isn't right. 1139 printOperand(MI, Op, STI, O); 1140 return; 1141 } 1142 1143 O << markup("<mem:") << "["; 1144 printRegName(O, MO1.getReg()); 1145 if (unsigned RegNum = MO2.getReg()) { 1146 O << ", "; 1147 printRegName(O, RegNum); 1148 } 1149 O << "]" << markup(">"); 1150 } 1151 1152 void ARMInstPrinter::printThumbAddrModeImm5SOperand(const MCInst *MI, 1153 unsigned Op, 1154 const MCSubtargetInfo &STI, 1155 raw_ostream &O, 1156 unsigned Scale) { 1157 const MCOperand &MO1 = MI->getOperand(Op); 1158 const MCOperand &MO2 = MI->getOperand(Op + 1); 1159 1160 if (!MO1.isReg()) { // FIXME: This is for CP entries, but isn't right. 1161 printOperand(MI, Op, STI, O); 1162 return; 1163 } 1164 1165 O << markup("<mem:") << "["; 1166 printRegName(O, MO1.getReg()); 1167 if (unsigned ImmOffs = MO2.getImm()) { 1168 O << ", " << markup("<imm:") << "#" << formatImm(ImmOffs * Scale) 1169 << markup(">"); 1170 } 1171 O << "]" << markup(">"); 1172 } 1173 1174 void ARMInstPrinter::printThumbAddrModeImm5S1Operand(const MCInst *MI, 1175 unsigned Op, 1176 const MCSubtargetInfo &STI, 1177 raw_ostream &O) { 1178 printThumbAddrModeImm5SOperand(MI, Op, STI, O, 1); 1179 } 1180 1181 void ARMInstPrinter::printThumbAddrModeImm5S2Operand(const MCInst *MI, 1182 unsigned Op, 1183 const MCSubtargetInfo &STI, 1184 raw_ostream &O) { 1185 printThumbAddrModeImm5SOperand(MI, Op, STI, O, 2); 1186 } 1187 1188 void ARMInstPrinter::printThumbAddrModeImm5S4Operand(const MCInst *MI, 1189 unsigned Op, 1190 const MCSubtargetInfo &STI, 1191 raw_ostream &O) { 1192 printThumbAddrModeImm5SOperand(MI, Op, STI, O, 4); 1193 } 1194 1195 void ARMInstPrinter::printThumbAddrModeSPOperand(const MCInst *MI, unsigned Op, 1196 const MCSubtargetInfo &STI, 1197 raw_ostream &O) { 1198 printThumbAddrModeImm5SOperand(MI, Op, STI, O, 4); 1199 } 1200 1201 // Constant shifts t2_so_reg is a 2-operand unit corresponding to the Thumb2 1202 // register with shift forms. 1203 // REG 0 0 - e.g. R5 1204 // REG IMM, SH_OPC - e.g. R5, LSL #3 1205 void ARMInstPrinter::printT2SOOperand(const MCInst *MI, unsigned OpNum, 1206 const MCSubtargetInfo &STI, 1207 raw_ostream &O) { 1208 const MCOperand &MO1 = MI->getOperand(OpNum); 1209 const MCOperand &MO2 = MI->getOperand(OpNum + 1); 1210 1211 unsigned Reg = MO1.getReg(); 1212 printRegName(O, Reg); 1213 1214 // Print the shift opc. 1215 assert(MO2.isImm() && "Not a valid t2_so_reg value!"); 1216 printRegImmShift(O, ARM_AM::getSORegShOp(MO2.getImm()), 1217 ARM_AM::getSORegOffset(MO2.getImm()), UseMarkup); 1218 } 1219 1220 template <bool AlwaysPrintImm0> 1221 void ARMInstPrinter::printAddrModeImm12Operand(const MCInst *MI, unsigned OpNum, 1222 const MCSubtargetInfo &STI, 1223 raw_ostream &O) { 1224 const MCOperand &MO1 = MI->getOperand(OpNum); 1225 const MCOperand &MO2 = MI->getOperand(OpNum + 1); 1226 1227 if (!MO1.isReg()) { // FIXME: This is for CP entries, but isn't right. 1228 printOperand(MI, OpNum, STI, O); 1229 return; 1230 } 1231 1232 O << markup("<mem:") << "["; 1233 printRegName(O, MO1.getReg()); 1234 1235 int32_t OffImm = (int32_t)MO2.getImm(); 1236 bool isSub = OffImm < 0; 1237 // Special value for #-0. All others are normal. 1238 if (OffImm == INT32_MIN) 1239 OffImm = 0; 1240 if (isSub) { 1241 O << ", " << markup("<imm:") << "#-" << formatImm(-OffImm) << markup(">"); 1242 } else if (AlwaysPrintImm0 || OffImm > 0) { 1243 O << ", " << markup("<imm:") << "#" << formatImm(OffImm) << markup(">"); 1244 } 1245 O << "]" << markup(">"); 1246 } 1247 1248 template <bool AlwaysPrintImm0> 1249 void ARMInstPrinter::printT2AddrModeImm8Operand(const MCInst *MI, 1250 unsigned OpNum, 1251 const MCSubtargetInfo &STI, 1252 raw_ostream &O) { 1253 const MCOperand &MO1 = MI->getOperand(OpNum); 1254 const MCOperand &MO2 = MI->getOperand(OpNum + 1); 1255 1256 O << markup("<mem:") << "["; 1257 printRegName(O, MO1.getReg()); 1258 1259 int32_t OffImm = (int32_t)MO2.getImm(); 1260 bool isSub = OffImm < 0; 1261 // Don't print +0. 1262 if (OffImm == INT32_MIN) 1263 OffImm = 0; 1264 if (isSub) { 1265 O << ", " << markup("<imm:") << "#-" << -OffImm << markup(">"); 1266 } else if (AlwaysPrintImm0 || OffImm > 0) { 1267 O << ", " << markup("<imm:") << "#" << OffImm << markup(">"); 1268 } 1269 O << "]" << markup(">"); 1270 } 1271 1272 template <bool AlwaysPrintImm0> 1273 void ARMInstPrinter::printT2AddrModeImm8s4Operand(const MCInst *MI, 1274 unsigned OpNum, 1275 const MCSubtargetInfo &STI, 1276 raw_ostream &O) { 1277 const MCOperand &MO1 = MI->getOperand(OpNum); 1278 const MCOperand &MO2 = MI->getOperand(OpNum + 1); 1279 1280 if (!MO1.isReg()) { // For label symbolic references. 1281 printOperand(MI, OpNum, STI, O); 1282 return; 1283 } 1284 1285 O << markup("<mem:") << "["; 1286 printRegName(O, MO1.getReg()); 1287 1288 int32_t OffImm = (int32_t)MO2.getImm(); 1289 bool isSub = OffImm < 0; 1290 1291 assert(((OffImm & 0x3) == 0) && "Not a valid immediate!"); 1292 1293 // Don't print +0. 1294 if (OffImm == INT32_MIN) 1295 OffImm = 0; 1296 if (isSub) { 1297 O << ", " << markup("<imm:") << "#-" << -OffImm << markup(">"); 1298 } else if (AlwaysPrintImm0 || OffImm > 0) { 1299 O << ", " << markup("<imm:") << "#" << OffImm << markup(">"); 1300 } 1301 O << "]" << markup(">"); 1302 } 1303 1304 void ARMInstPrinter::printT2AddrModeImm0_1020s4Operand( 1305 const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, 1306 raw_ostream &O) { 1307 const MCOperand &MO1 = MI->getOperand(OpNum); 1308 const MCOperand &MO2 = MI->getOperand(OpNum + 1); 1309 1310 O << markup("<mem:") << "["; 1311 printRegName(O, MO1.getReg()); 1312 if (MO2.getImm()) { 1313 O << ", " << markup("<imm:") << "#" << formatImm(MO2.getImm() * 4) 1314 << markup(">"); 1315 } 1316 O << "]" << markup(">"); 1317 } 1318 1319 void ARMInstPrinter::printT2AddrModeImm8OffsetOperand( 1320 const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, 1321 raw_ostream &O) { 1322 const MCOperand &MO1 = MI->getOperand(OpNum); 1323 int32_t OffImm = (int32_t)MO1.getImm(); 1324 O << ", " << markup("<imm:"); 1325 if (OffImm == INT32_MIN) 1326 O << "#-0"; 1327 else if (OffImm < 0) 1328 O << "#-" << -OffImm; 1329 else 1330 O << "#" << OffImm; 1331 O << markup(">"); 1332 } 1333 1334 void ARMInstPrinter::printT2AddrModeImm8s4OffsetOperand( 1335 const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, 1336 raw_ostream &O) { 1337 const MCOperand &MO1 = MI->getOperand(OpNum); 1338 int32_t OffImm = (int32_t)MO1.getImm(); 1339 1340 assert(((OffImm & 0x3) == 0) && "Not a valid immediate!"); 1341 1342 O << ", " << markup("<imm:"); 1343 if (OffImm == INT32_MIN) 1344 O << "#-0"; 1345 else if (OffImm < 0) 1346 O << "#-" << -OffImm; 1347 else 1348 O << "#" << OffImm; 1349 O << markup(">"); 1350 } 1351 1352 void ARMInstPrinter::printT2AddrModeSoRegOperand(const MCInst *MI, 1353 unsigned OpNum, 1354 const MCSubtargetInfo &STI, 1355 raw_ostream &O) { 1356 const MCOperand &MO1 = MI->getOperand(OpNum); 1357 const MCOperand &MO2 = MI->getOperand(OpNum + 1); 1358 const MCOperand &MO3 = MI->getOperand(OpNum + 2); 1359 1360 O << markup("<mem:") << "["; 1361 printRegName(O, MO1.getReg()); 1362 1363 assert(MO2.getReg() && "Invalid so_reg load / store address!"); 1364 O << ", "; 1365 printRegName(O, MO2.getReg()); 1366 1367 unsigned ShAmt = MO3.getImm(); 1368 if (ShAmt) { 1369 assert(ShAmt <= 3 && "Not a valid Thumb2 addressing mode!"); 1370 O << ", lsl " << markup("<imm:") << "#" << ShAmt << markup(">"); 1371 } 1372 O << "]" << markup(">"); 1373 } 1374 1375 void ARMInstPrinter::printFPImmOperand(const MCInst *MI, unsigned OpNum, 1376 const MCSubtargetInfo &STI, 1377 raw_ostream &O) { 1378 const MCOperand &MO = MI->getOperand(OpNum); 1379 O << markup("<imm:") << '#' << ARM_AM::getFPImmFloat(MO.getImm()) 1380 << markup(">"); 1381 } 1382 1383 void ARMInstPrinter::printNEONModImmOperand(const MCInst *MI, unsigned OpNum, 1384 const MCSubtargetInfo &STI, 1385 raw_ostream &O) { 1386 unsigned EncodedImm = MI->getOperand(OpNum).getImm(); 1387 unsigned EltBits; 1388 uint64_t Val = ARM_AM::decodeNEONModImm(EncodedImm, EltBits); 1389 O << markup("<imm:") << "#0x"; 1390 O.write_hex(Val); 1391 O << markup(">"); 1392 } 1393 1394 void ARMInstPrinter::printImmPlusOneOperand(const MCInst *MI, unsigned OpNum, 1395 const MCSubtargetInfo &STI, 1396 raw_ostream &O) { 1397 unsigned Imm = MI->getOperand(OpNum).getImm(); 1398 O << markup("<imm:") << "#" << formatImm(Imm + 1) << markup(">"); 1399 } 1400 1401 void ARMInstPrinter::printRotImmOperand(const MCInst *MI, unsigned OpNum, 1402 const MCSubtargetInfo &STI, 1403 raw_ostream &O) { 1404 unsigned Imm = MI->getOperand(OpNum).getImm(); 1405 if (Imm == 0) 1406 return; 1407 assert(Imm <= 3 && "illegal ror immediate!"); 1408 O << ", ror " << markup("<imm:") << "#" << 8 * Imm << markup(">"); 1409 } 1410 1411 void ARMInstPrinter::printModImmOperand(const MCInst *MI, unsigned OpNum, 1412 const MCSubtargetInfo &STI, 1413 raw_ostream &O) { 1414 MCOperand Op = MI->getOperand(OpNum); 1415 1416 // Support for fixups (MCFixup) 1417 if (Op.isExpr()) 1418 return printOperand(MI, OpNum, STI, O); 1419 1420 unsigned Bits = Op.getImm() & 0xFF; 1421 unsigned Rot = (Op.getImm() & 0xF00) >> 7; 1422 1423 bool PrintUnsigned = false; 1424 switch (MI->getOpcode()) { 1425 case ARM::MOVi: 1426 // Movs to PC should be treated unsigned 1427 PrintUnsigned = (MI->getOperand(OpNum - 1).getReg() == ARM::PC); 1428 break; 1429 case ARM::MSRi: 1430 // Movs to special registers should be treated unsigned 1431 PrintUnsigned = true; 1432 break; 1433 } 1434 1435 int32_t Rotated = ARM_AM::rotr32(Bits, Rot); 1436 if (ARM_AM::getSOImmVal(Rotated) == Op.getImm()) { 1437 // #rot has the least possible value 1438 O << "#" << markup("<imm:"); 1439 if (PrintUnsigned) 1440 O << static_cast<uint32_t>(Rotated); 1441 else 1442 O << Rotated; 1443 O << markup(">"); 1444 return; 1445 } 1446 1447 // Explicit #bits, #rot implied 1448 O << "#" << markup("<imm:") << Bits << markup(">") << ", #" << markup("<imm:") 1449 << Rot << markup(">"); 1450 } 1451 1452 void ARMInstPrinter::printFBits16(const MCInst *MI, unsigned OpNum, 1453 const MCSubtargetInfo &STI, raw_ostream &O) { 1454 O << markup("<imm:") << "#" << 16 - MI->getOperand(OpNum).getImm() 1455 << markup(">"); 1456 } 1457 1458 void ARMInstPrinter::printFBits32(const MCInst *MI, unsigned OpNum, 1459 const MCSubtargetInfo &STI, raw_ostream &O) { 1460 O << markup("<imm:") << "#" << 32 - MI->getOperand(OpNum).getImm() 1461 << markup(">"); 1462 } 1463 1464 void ARMInstPrinter::printVectorIndex(const MCInst *MI, unsigned OpNum, 1465 const MCSubtargetInfo &STI, 1466 raw_ostream &O) { 1467 O << "[" << MI->getOperand(OpNum).getImm() << "]"; 1468 } 1469 1470 void ARMInstPrinter::printVectorListOne(const MCInst *MI, unsigned OpNum, 1471 const MCSubtargetInfo &STI, 1472 raw_ostream &O) { 1473 O << "{"; 1474 printRegName(O, MI->getOperand(OpNum).getReg()); 1475 O << "}"; 1476 } 1477 1478 void ARMInstPrinter::printVectorListTwo(const MCInst *MI, unsigned OpNum, 1479 const MCSubtargetInfo &STI, 1480 raw_ostream &O) { 1481 unsigned Reg = MI->getOperand(OpNum).getReg(); 1482 unsigned Reg0 = MRI.getSubReg(Reg, ARM::dsub_0); 1483 unsigned Reg1 = MRI.getSubReg(Reg, ARM::dsub_1); 1484 O << "{"; 1485 printRegName(O, Reg0); 1486 O << ", "; 1487 printRegName(O, Reg1); 1488 O << "}"; 1489 } 1490 1491 void ARMInstPrinter::printVectorListTwoSpaced(const MCInst *MI, unsigned OpNum, 1492 const MCSubtargetInfo &STI, 1493 raw_ostream &O) { 1494 unsigned Reg = MI->getOperand(OpNum).getReg(); 1495 unsigned Reg0 = MRI.getSubReg(Reg, ARM::dsub_0); 1496 unsigned Reg1 = MRI.getSubReg(Reg, ARM::dsub_2); 1497 O << "{"; 1498 printRegName(O, Reg0); 1499 O << ", "; 1500 printRegName(O, Reg1); 1501 O << "}"; 1502 } 1503 1504 void ARMInstPrinter::printVectorListThree(const MCInst *MI, unsigned OpNum, 1505 const MCSubtargetInfo &STI, 1506 raw_ostream &O) { 1507 // Normally, it's not safe to use register enum values directly with 1508 // addition to get the next register, but for VFP registers, the 1509 // sort order is guaranteed because they're all of the form D<n>. 1510 O << "{"; 1511 printRegName(O, MI->getOperand(OpNum).getReg()); 1512 O << ", "; 1513 printRegName(O, MI->getOperand(OpNum).getReg() + 1); 1514 O << ", "; 1515 printRegName(O, MI->getOperand(OpNum).getReg() + 2); 1516 O << "}"; 1517 } 1518 1519 void ARMInstPrinter::printVectorListFour(const MCInst *MI, unsigned OpNum, 1520 const MCSubtargetInfo &STI, 1521 raw_ostream &O) { 1522 // Normally, it's not safe to use register enum values directly with 1523 // addition to get the next register, but for VFP registers, the 1524 // sort order is guaranteed because they're all of the form D<n>. 1525 O << "{"; 1526 printRegName(O, MI->getOperand(OpNum).getReg()); 1527 O << ", "; 1528 printRegName(O, MI->getOperand(OpNum).getReg() + 1); 1529 O << ", "; 1530 printRegName(O, MI->getOperand(OpNum).getReg() + 2); 1531 O << ", "; 1532 printRegName(O, MI->getOperand(OpNum).getReg() + 3); 1533 O << "}"; 1534 } 1535 1536 void ARMInstPrinter::printVectorListOneAllLanes(const MCInst *MI, 1537 unsigned OpNum, 1538 const MCSubtargetInfo &STI, 1539 raw_ostream &O) { 1540 O << "{"; 1541 printRegName(O, MI->getOperand(OpNum).getReg()); 1542 O << "[]}"; 1543 } 1544 1545 void ARMInstPrinter::printVectorListTwoAllLanes(const MCInst *MI, 1546 unsigned OpNum, 1547 const MCSubtargetInfo &STI, 1548 raw_ostream &O) { 1549 unsigned Reg = MI->getOperand(OpNum).getReg(); 1550 unsigned Reg0 = MRI.getSubReg(Reg, ARM::dsub_0); 1551 unsigned Reg1 = MRI.getSubReg(Reg, ARM::dsub_1); 1552 O << "{"; 1553 printRegName(O, Reg0); 1554 O << "[], "; 1555 printRegName(O, Reg1); 1556 O << "[]}"; 1557 } 1558 1559 void ARMInstPrinter::printVectorListThreeAllLanes(const MCInst *MI, 1560 unsigned OpNum, 1561 const MCSubtargetInfo &STI, 1562 raw_ostream &O) { 1563 // Normally, it's not safe to use register enum values directly with 1564 // addition to get the next register, but for VFP registers, the 1565 // sort order is guaranteed because they're all of the form D<n>. 1566 O << "{"; 1567 printRegName(O, MI->getOperand(OpNum).getReg()); 1568 O << "[], "; 1569 printRegName(O, MI->getOperand(OpNum).getReg() + 1); 1570 O << "[], "; 1571 printRegName(O, MI->getOperand(OpNum).getReg() + 2); 1572 O << "[]}"; 1573 } 1574 1575 void ARMInstPrinter::printVectorListFourAllLanes(const MCInst *MI, 1576 unsigned OpNum, 1577 const MCSubtargetInfo &STI, 1578 raw_ostream &O) { 1579 // Normally, it's not safe to use register enum values directly with 1580 // addition to get the next register, but for VFP registers, the 1581 // sort order is guaranteed because they're all of the form D<n>. 1582 O << "{"; 1583 printRegName(O, MI->getOperand(OpNum).getReg()); 1584 O << "[], "; 1585 printRegName(O, MI->getOperand(OpNum).getReg() + 1); 1586 O << "[], "; 1587 printRegName(O, MI->getOperand(OpNum).getReg() + 2); 1588 O << "[], "; 1589 printRegName(O, MI->getOperand(OpNum).getReg() + 3); 1590 O << "[]}"; 1591 } 1592 1593 void ARMInstPrinter::printVectorListTwoSpacedAllLanes( 1594 const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, 1595 raw_ostream &O) { 1596 unsigned Reg = MI->getOperand(OpNum).getReg(); 1597 unsigned Reg0 = MRI.getSubReg(Reg, ARM::dsub_0); 1598 unsigned Reg1 = MRI.getSubReg(Reg, ARM::dsub_2); 1599 O << "{"; 1600 printRegName(O, Reg0); 1601 O << "[], "; 1602 printRegName(O, Reg1); 1603 O << "[]}"; 1604 } 1605 1606 void ARMInstPrinter::printVectorListThreeSpacedAllLanes( 1607 const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, 1608 raw_ostream &O) { 1609 // Normally, it's not safe to use register enum values directly with 1610 // addition to get the next register, but for VFP registers, the 1611 // sort order is guaranteed because they're all of the form D<n>. 1612 O << "{"; 1613 printRegName(O, MI->getOperand(OpNum).getReg()); 1614 O << "[], "; 1615 printRegName(O, MI->getOperand(OpNum).getReg() + 2); 1616 O << "[], "; 1617 printRegName(O, MI->getOperand(OpNum).getReg() + 4); 1618 O << "[]}"; 1619 } 1620 1621 void ARMInstPrinter::printVectorListFourSpacedAllLanes( 1622 const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, 1623 raw_ostream &O) { 1624 // Normally, it's not safe to use register enum values directly with 1625 // addition to get the next register, but for VFP registers, the 1626 // sort order is guaranteed because they're all of the form D<n>. 1627 O << "{"; 1628 printRegName(O, MI->getOperand(OpNum).getReg()); 1629 O << "[], "; 1630 printRegName(O, MI->getOperand(OpNum).getReg() + 2); 1631 O << "[], "; 1632 printRegName(O, MI->getOperand(OpNum).getReg() + 4); 1633 O << "[], "; 1634 printRegName(O, MI->getOperand(OpNum).getReg() + 6); 1635 O << "[]}"; 1636 } 1637 1638 void ARMInstPrinter::printVectorListThreeSpaced(const MCInst *MI, 1639 unsigned OpNum, 1640 const MCSubtargetInfo &STI, 1641 raw_ostream &O) { 1642 // Normally, it's not safe to use register enum values directly with 1643 // addition to get the next register, but for VFP registers, the 1644 // sort order is guaranteed because they're all of the form D<n>. 1645 O << "{"; 1646 printRegName(O, MI->getOperand(OpNum).getReg()); 1647 O << ", "; 1648 printRegName(O, MI->getOperand(OpNum).getReg() + 2); 1649 O << ", "; 1650 printRegName(O, MI->getOperand(OpNum).getReg() + 4); 1651 O << "}"; 1652 } 1653 1654 void ARMInstPrinter::printVectorListFourSpaced(const MCInst *MI, unsigned OpNum, 1655 const MCSubtargetInfo &STI, 1656 raw_ostream &O) { 1657 // Normally, it's not safe to use register enum values directly with 1658 // addition to get the next register, but for VFP registers, the 1659 // sort order is guaranteed because they're all of the form D<n>. 1660 O << "{"; 1661 printRegName(O, MI->getOperand(OpNum).getReg()); 1662 O << ", "; 1663 printRegName(O, MI->getOperand(OpNum).getReg() + 2); 1664 O << ", "; 1665 printRegName(O, MI->getOperand(OpNum).getReg() + 4); 1666 O << ", "; 1667 printRegName(O, MI->getOperand(OpNum).getReg() + 6); 1668 O << "}"; 1669 } 1670