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