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