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