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/MCInstrInfo.h" 21 #include "llvm/MC/MCRegisterInfo.h" 22 #include "llvm/MC/MCSubtargetInfo.h" 23 #include "llvm/MC/SubtargetFeature.h" 24 #include "llvm/Support/Casting.h" 25 #include "llvm/Support/ErrorHandling.h" 26 #include "llvm/Support/MathExtras.h" 27 #include "llvm/Support/raw_ostream.h" 28 #include <algorithm> 29 #include <cassert> 30 #include <cstdint> 31 32 using namespace llvm; 33 34 #define DEBUG_TYPE "asm-printer" 35 36 #define PRINT_ALIAS_INSTR 37 #include "ARMGenAsmWriter.inc" 38 39 /// translateShiftImm - Convert shift immediate from 0-31 to 1-32 for printing. 40 /// 41 /// getSORegOffset returns an integer from 0-31, representing '32' as 0. 42 static unsigned translateShiftImm(unsigned imm) { 43 // lsr #32 and asr #32 exist, but should be encoded as a 0. 44 assert((imm & ~0x1f) == 0 && "Invalid shift encoding"); 45 46 if (imm == 0) 47 return 32; 48 return imm; 49 } 50 51 /// Prints the shift value with an immediate value. 52 static void printRegImmShift(raw_ostream &O, ARM_AM::ShiftOpc ShOpc, 53 unsigned ShImm, bool UseMarkup) { 54 if (ShOpc == ARM_AM::no_shift || (ShOpc == ARM_AM::lsl && !ShImm)) 55 return; 56 O << ", "; 57 58 assert(!(ShOpc == ARM_AM::ror && !ShImm) && "Cannot have ror #0"); 59 O << getShiftOpcStr(ShOpc); 60 61 if (ShOpc != ARM_AM::rrx) { 62 O << " "; 63 if (UseMarkup) 64 O << "<imm:"; 65 O << "#" << translateShiftImm(ShImm); 66 if (UseMarkup) 67 O << ">"; 68 } 69 } 70 71 ARMInstPrinter::ARMInstPrinter(const MCAsmInfo &MAI, const MCInstrInfo &MII, 72 const MCRegisterInfo &MRI) 73 : MCInstPrinter(MAI, MII, MRI) {} 74 75 bool ARMInstPrinter::applyTargetSpecificCLOption(StringRef Opt) { 76 if (Opt == "reg-names-std") { 77 DefaultAltIdx = ARM::NoRegAltName; 78 return true; 79 } 80 if (Opt == "reg-names-raw") { 81 DefaultAltIdx = ARM::RegNamesRaw; 82 return true; 83 } 84 return false; 85 } 86 87 void ARMInstPrinter::printRegName(raw_ostream &OS, unsigned RegNo) const { 88 OS << markup("<reg:") << getRegisterName(RegNo, DefaultAltIdx) << markup(">"); 89 } 90 91 void ARMInstPrinter::printInst(const MCInst *MI, raw_ostream &O, 92 StringRef Annot, const MCSubtargetInfo &STI) { 93 unsigned Opcode = MI->getOpcode(); 94 95 switch (Opcode) { 96 // Check for MOVs and print canonical forms, instead. 97 case ARM::MOVsr: { 98 // FIXME: Thumb variants? 99 const MCOperand &Dst = MI->getOperand(0); 100 const MCOperand &MO1 = MI->getOperand(1); 101 const MCOperand &MO2 = MI->getOperand(2); 102 const MCOperand &MO3 = MI->getOperand(3); 103 104 O << '\t' << ARM_AM::getShiftOpcStr(ARM_AM::getSORegShOp(MO3.getImm())); 105 printSBitModifierOperand(MI, 6, STI, O); 106 printPredicateOperand(MI, 4, STI, O); 107 108 O << '\t'; 109 printRegName(O, Dst.getReg()); 110 O << ", "; 111 printRegName(O, MO1.getReg()); 112 113 O << ", "; 114 printRegName(O, MO2.getReg()); 115 assert(ARM_AM::getSORegOffset(MO3.getImm()) == 0); 116 printAnnotation(O, Annot); 117 return; 118 } 119 120 case ARM::MOVsi: { 121 // FIXME: Thumb variants? 122 const MCOperand &Dst = MI->getOperand(0); 123 const MCOperand &MO1 = MI->getOperand(1); 124 const MCOperand &MO2 = MI->getOperand(2); 125 126 O << '\t' << ARM_AM::getShiftOpcStr(ARM_AM::getSORegShOp(MO2.getImm())); 127 printSBitModifierOperand(MI, 5, STI, O); 128 printPredicateOperand(MI, 3, STI, O); 129 130 O << '\t'; 131 printRegName(O, Dst.getReg()); 132 O << ", "; 133 printRegName(O, MO1.getReg()); 134 135 if (ARM_AM::getSORegShOp(MO2.getImm()) == ARM_AM::rrx) { 136 printAnnotation(O, Annot); 137 return; 138 } 139 140 O << ", " << markup("<imm:") << "#" 141 << translateShiftImm(ARM_AM::getSORegOffset(MO2.getImm())) << markup(">"); 142 printAnnotation(O, Annot); 143 return; 144 } 145 146 // A8.6.123 PUSH 147 case ARM::STMDB_UPD: 148 case ARM::t2STMDB_UPD: 149 if (MI->getOperand(0).getReg() == ARM::SP && MI->getNumOperands() > 5) { 150 // Should only print PUSH if there are at least two registers in the list. 151 O << '\t' << "push"; 152 printPredicateOperand(MI, 2, STI, O); 153 if (Opcode == ARM::t2STMDB_UPD) 154 O << ".w"; 155 O << '\t'; 156 printRegisterList(MI, 4, STI, O); 157 printAnnotation(O, Annot); 158 return; 159 } else 160 break; 161 162 case ARM::STR_PRE_IMM: 163 if (MI->getOperand(2).getReg() == ARM::SP && 164 MI->getOperand(3).getImm() == -4) { 165 O << '\t' << "push"; 166 printPredicateOperand(MI, 4, STI, O); 167 O << "\t{"; 168 printRegName(O, MI->getOperand(1).getReg()); 169 O << "}"; 170 printAnnotation(O, Annot); 171 return; 172 } else 173 break; 174 175 // A8.6.122 POP 176 case ARM::LDMIA_UPD: 177 case ARM::t2LDMIA_UPD: 178 if (MI->getOperand(0).getReg() == ARM::SP && MI->getNumOperands() > 5) { 179 // Should only print POP if there are at least two registers in the list. 180 O << '\t' << "pop"; 181 printPredicateOperand(MI, 2, STI, O); 182 if (Opcode == ARM::t2LDMIA_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::LDR_POST_IMM: 192 if (MI->getOperand(2).getReg() == ARM::SP && 193 MI->getOperand(4).getImm() == 4) { 194 O << '\t' << "pop"; 195 printPredicateOperand(MI, 5, STI, O); 196 O << "\t{"; 197 printRegName(O, MI->getOperand(0).getReg()); 198 O << "}"; 199 printAnnotation(O, Annot); 200 return; 201 } else 202 break; 203 204 // A8.6.355 VPUSH 205 case ARM::VSTMSDB_UPD: 206 case ARM::VSTMDDB_UPD: 207 if (MI->getOperand(0).getReg() == ARM::SP) { 208 O << '\t' << "vpush"; 209 printPredicateOperand(MI, 2, STI, O); 210 O << '\t'; 211 printRegisterList(MI, 4, STI, O); 212 printAnnotation(O, Annot); 213 return; 214 } else 215 break; 216 217 // A8.6.354 VPOP 218 case ARM::VLDMSIA_UPD: 219 case ARM::VLDMDIA_UPD: 220 if (MI->getOperand(0).getReg() == ARM::SP) { 221 O << '\t' << "vpop"; 222 printPredicateOperand(MI, 2, STI, O); 223 O << '\t'; 224 printRegisterList(MI, 4, STI, O); 225 printAnnotation(O, Annot); 226 return; 227 } else 228 break; 229 230 case ARM::tLDMIA: { 231 bool Writeback = true; 232 unsigned BaseReg = MI->getOperand(0).getReg(); 233 for (unsigned i = 3; i < MI->getNumOperands(); ++i) { 234 if (MI->getOperand(i).getReg() == BaseReg) 235 Writeback = false; 236 } 237 238 O << "\tldm"; 239 240 printPredicateOperand(MI, 1, STI, O); 241 O << '\t'; 242 printRegName(O, BaseReg); 243 if (Writeback) 244 O << "!"; 245 O << ", "; 246 printRegisterList(MI, 3, STI, O); 247 printAnnotation(O, Annot); 248 return; 249 } 250 251 // Combine 2 GPRs from disassember into a GPRPair to match with instr def. 252 // ldrexd/strexd require even/odd GPR pair. To enforce this constraint, 253 // a single GPRPair reg operand is used in the .td file to replace the two 254 // GPRs. However, when decoding them, the two GRPs cannot be automatically 255 // expressed as a GPRPair, so we have to manually merge them. 256 // FIXME: We would really like to be able to tablegen'erate this. 257 case ARM::LDREXD: 258 case ARM::STREXD: 259 case ARM::LDAEXD: 260 case ARM::STLEXD: { 261 const MCRegisterClass &MRC = MRI.getRegClass(ARM::GPRRegClassID); 262 bool isStore = Opcode == ARM::STREXD || Opcode == ARM::STLEXD; 263 unsigned Reg = MI->getOperand(isStore ? 1 : 0).getReg(); 264 if (MRC.contains(Reg)) { 265 MCInst NewMI; 266 MCOperand NewReg; 267 NewMI.setOpcode(Opcode); 268 269 if (isStore) 270 NewMI.addOperand(MI->getOperand(0)); 271 NewReg = MCOperand::createReg(MRI.getMatchingSuperReg( 272 Reg, ARM::gsub_0, &MRI.getRegClass(ARM::GPRPairRegClassID))); 273 NewMI.addOperand(NewReg); 274 275 // Copy the rest operands into NewMI. 276 for (unsigned i = isStore ? 3 : 2; i < MI->getNumOperands(); ++i) 277 NewMI.addOperand(MI->getOperand(i)); 278 printInstruction(&NewMI, STI, O); 279 return; 280 } 281 break; 282 } 283 case ARM::TSB: 284 case ARM::t2TSB: 285 O << "\ttsb\tcsync"; 286 return; 287 case ARM::t2DSB: 288 switch (MI->getOperand(0).getImm()) { 289 default: 290 if (!printAliasInstr(MI, STI, O)) 291 printInstruction(MI, STI, O); 292 break; 293 case 0: 294 O << "\tssbb"; 295 break; 296 case 4: 297 O << "\tpssbb"; 298 break; 299 } 300 printAnnotation(O, Annot); 301 return; 302 } 303 304 if (!printAliasInstr(MI, STI, O)) 305 printInstruction(MI, STI, O); 306 307 printAnnotation(O, Annot); 308 } 309 310 void ARMInstPrinter::printOperand(const MCInst *MI, unsigned OpNo, 311 const MCSubtargetInfo &STI, raw_ostream &O) { 312 const MCOperand &Op = MI->getOperand(OpNo); 313 if (Op.isReg()) { 314 unsigned Reg = Op.getReg(); 315 printRegName(O, Reg); 316 } else if (Op.isImm()) { 317 O << markup("<imm:") << '#' << formatImm(Op.getImm()) << markup(">"); 318 } else { 319 assert(Op.isExpr() && "unknown operand kind in printOperand"); 320 const MCExpr *Expr = Op.getExpr(); 321 switch (Expr->getKind()) { 322 case MCExpr::Binary: 323 O << '#'; 324 Expr->print(O, &MAI); 325 break; 326 case MCExpr::Constant: { 327 // If a symbolic branch target was added as a constant expression then 328 // print that address in hex. And only print 32 unsigned bits for the 329 // address. 330 const MCConstantExpr *Constant = cast<MCConstantExpr>(Expr); 331 int64_t TargetAddress; 332 if (!Constant->evaluateAsAbsolute(TargetAddress)) { 333 O << '#'; 334 Expr->print(O, &MAI); 335 } else { 336 O << "0x"; 337 O.write_hex(static_cast<uint32_t>(TargetAddress)); 338 } 339 break; 340 } 341 default: 342 // FIXME: Should we always treat this as if it is a constant literal and 343 // prefix it with '#'? 344 Expr->print(O, &MAI); 345 break; 346 } 347 } 348 } 349 350 void ARMInstPrinter::printThumbLdrLabelOperand(const MCInst *MI, unsigned OpNum, 351 const MCSubtargetInfo &STI, 352 raw_ostream &O) { 353 const MCOperand &MO1 = MI->getOperand(OpNum); 354 if (MO1.isExpr()) { 355 MO1.getExpr()->print(O, &MAI); 356 return; 357 } 358 359 O << markup("<mem:") << "[pc, "; 360 361 int32_t OffImm = (int32_t)MO1.getImm(); 362 bool isSub = OffImm < 0; 363 364 // Special value for #-0. All others are normal. 365 if (OffImm == INT32_MIN) 366 OffImm = 0; 367 if (isSub) { 368 O << markup("<imm:") << "#-" << formatImm(-OffImm) << markup(">"); 369 } else { 370 O << markup("<imm:") << "#" << formatImm(OffImm) << markup(">"); 371 } 372 O << "]" << markup(">"); 373 } 374 375 // so_reg is a 4-operand unit corresponding to register forms of the A5.1 376 // "Addressing Mode 1 - Data-processing operands" forms. This includes: 377 // REG 0 0 - e.g. R5 378 // REG REG 0,SH_OPC - e.g. R5, ROR R3 379 // REG 0 IMM,SH_OPC - e.g. R5, LSL #3 380 void ARMInstPrinter::printSORegRegOperand(const MCInst *MI, unsigned OpNum, 381 const MCSubtargetInfo &STI, 382 raw_ostream &O) { 383 const MCOperand &MO1 = MI->getOperand(OpNum); 384 const MCOperand &MO2 = MI->getOperand(OpNum + 1); 385 const MCOperand &MO3 = MI->getOperand(OpNum + 2); 386 387 printRegName(O, MO1.getReg()); 388 389 // Print the shift opc. 390 ARM_AM::ShiftOpc ShOpc = ARM_AM::getSORegShOp(MO3.getImm()); 391 O << ", " << ARM_AM::getShiftOpcStr(ShOpc); 392 if (ShOpc == ARM_AM::rrx) 393 return; 394 395 O << ' '; 396 printRegName(O, MO2.getReg()); 397 assert(ARM_AM::getSORegOffset(MO3.getImm()) == 0); 398 } 399 400 void ARMInstPrinter::printSORegImmOperand(const MCInst *MI, unsigned OpNum, 401 const MCSubtargetInfo &STI, 402 raw_ostream &O) { 403 const MCOperand &MO1 = MI->getOperand(OpNum); 404 const MCOperand &MO2 = MI->getOperand(OpNum + 1); 405 406 printRegName(O, MO1.getReg()); 407 408 // Print the shift opc. 409 printRegImmShift(O, ARM_AM::getSORegShOp(MO2.getImm()), 410 ARM_AM::getSORegOffset(MO2.getImm()), UseMarkup); 411 } 412 413 //===--------------------------------------------------------------------===// 414 // Addressing Mode #2 415 //===--------------------------------------------------------------------===// 416 417 void ARMInstPrinter::printAM2PreOrOffsetIndexOp(const MCInst *MI, unsigned Op, 418 const MCSubtargetInfo &STI, 419 raw_ostream &O) { 420 const MCOperand &MO1 = MI->getOperand(Op); 421 const MCOperand &MO2 = MI->getOperand(Op + 1); 422 const MCOperand &MO3 = MI->getOperand(Op + 2); 423 424 O << markup("<mem:") << "["; 425 printRegName(O, MO1.getReg()); 426 427 if (!MO2.getReg()) { 428 if (ARM_AM::getAM2Offset(MO3.getImm())) { // Don't print +0. 429 O << ", " << markup("<imm:") << "#" 430 << ARM_AM::getAddrOpcStr(ARM_AM::getAM2Op(MO3.getImm())) 431 << ARM_AM::getAM2Offset(MO3.getImm()) << markup(">"); 432 } 433 O << "]" << markup(">"); 434 return; 435 } 436 437 O << ", "; 438 O << ARM_AM::getAddrOpcStr(ARM_AM::getAM2Op(MO3.getImm())); 439 printRegName(O, MO2.getReg()); 440 441 printRegImmShift(O, ARM_AM::getAM2ShiftOpc(MO3.getImm()), 442 ARM_AM::getAM2Offset(MO3.getImm()), UseMarkup); 443 O << "]" << markup(">"); 444 } 445 446 void ARMInstPrinter::printAddrModeTBB(const MCInst *MI, unsigned Op, 447 const MCSubtargetInfo &STI, 448 raw_ostream &O) { 449 const MCOperand &MO1 = MI->getOperand(Op); 450 const MCOperand &MO2 = MI->getOperand(Op + 1); 451 O << markup("<mem:") << "["; 452 printRegName(O, MO1.getReg()); 453 O << ", "; 454 printRegName(O, MO2.getReg()); 455 O << "]" << markup(">"); 456 } 457 458 void ARMInstPrinter::printAddrModeTBH(const MCInst *MI, unsigned Op, 459 const MCSubtargetInfo &STI, 460 raw_ostream &O) { 461 const MCOperand &MO1 = MI->getOperand(Op); 462 const MCOperand &MO2 = MI->getOperand(Op + 1); 463 O << markup("<mem:") << "["; 464 printRegName(O, MO1.getReg()); 465 O << ", "; 466 printRegName(O, MO2.getReg()); 467 O << ", lsl " << markup("<imm:") << "#1" << markup(">") << "]" << markup(">"); 468 } 469 470 void ARMInstPrinter::printAddrMode2Operand(const MCInst *MI, unsigned Op, 471 const MCSubtargetInfo &STI, 472 raw_ostream &O) { 473 const MCOperand &MO1 = MI->getOperand(Op); 474 475 if (!MO1.isReg()) { // FIXME: This is for CP entries, but isn't right. 476 printOperand(MI, Op, STI, O); 477 return; 478 } 479 480 #ifndef NDEBUG 481 const MCOperand &MO3 = MI->getOperand(Op + 2); 482 unsigned IdxMode = ARM_AM::getAM2IdxMode(MO3.getImm()); 483 assert(IdxMode != ARMII::IndexModePost && "Should be pre or offset index op"); 484 #endif 485 486 printAM2PreOrOffsetIndexOp(MI, Op, STI, O); 487 } 488 489 void ARMInstPrinter::printAddrMode2OffsetOperand(const MCInst *MI, 490 unsigned OpNum, 491 const MCSubtargetInfo &STI, 492 raw_ostream &O) { 493 const MCOperand &MO1 = MI->getOperand(OpNum); 494 const MCOperand &MO2 = MI->getOperand(OpNum + 1); 495 496 if (!MO1.getReg()) { 497 unsigned ImmOffs = ARM_AM::getAM2Offset(MO2.getImm()); 498 O << markup("<imm:") << '#' 499 << ARM_AM::getAddrOpcStr(ARM_AM::getAM2Op(MO2.getImm())) << ImmOffs 500 << markup(">"); 501 return; 502 } 503 504 O << ARM_AM::getAddrOpcStr(ARM_AM::getAM2Op(MO2.getImm())); 505 printRegName(O, MO1.getReg()); 506 507 printRegImmShift(O, ARM_AM::getAM2ShiftOpc(MO2.getImm()), 508 ARM_AM::getAM2Offset(MO2.getImm()), UseMarkup); 509 } 510 511 //===--------------------------------------------------------------------===// 512 // Addressing Mode #3 513 //===--------------------------------------------------------------------===// 514 515 void ARMInstPrinter::printAM3PreOrOffsetIndexOp(const MCInst *MI, unsigned Op, 516 raw_ostream &O, 517 bool AlwaysPrintImm0) { 518 const MCOperand &MO1 = MI->getOperand(Op); 519 const MCOperand &MO2 = MI->getOperand(Op + 1); 520 const MCOperand &MO3 = MI->getOperand(Op + 2); 521 522 O << markup("<mem:") << '['; 523 printRegName(O, MO1.getReg()); 524 525 if (MO2.getReg()) { 526 O << ", " << getAddrOpcStr(ARM_AM::getAM3Op(MO3.getImm())); 527 printRegName(O, MO2.getReg()); 528 O << ']' << markup(">"); 529 return; 530 } 531 532 // If the op is sub we have to print the immediate even if it is 0 533 unsigned ImmOffs = ARM_AM::getAM3Offset(MO3.getImm()); 534 ARM_AM::AddrOpc op = ARM_AM::getAM3Op(MO3.getImm()); 535 536 if (AlwaysPrintImm0 || ImmOffs || (op == ARM_AM::sub)) { 537 O << ", " << markup("<imm:") << "#" << ARM_AM::getAddrOpcStr(op) << ImmOffs 538 << markup(">"); 539 } 540 O << ']' << markup(">"); 541 } 542 543 template <bool AlwaysPrintImm0> 544 void ARMInstPrinter::printAddrMode3Operand(const MCInst *MI, unsigned Op, 545 const MCSubtargetInfo &STI, 546 raw_ostream &O) { 547 const MCOperand &MO1 = MI->getOperand(Op); 548 if (!MO1.isReg()) { // For label symbolic references. 549 printOperand(MI, Op, STI, O); 550 return; 551 } 552 553 assert(ARM_AM::getAM3IdxMode(MI->getOperand(Op + 2).getImm()) != 554 ARMII::IndexModePost && 555 "unexpected idxmode"); 556 printAM3PreOrOffsetIndexOp(MI, Op, O, AlwaysPrintImm0); 557 } 558 559 void ARMInstPrinter::printAddrMode3OffsetOperand(const MCInst *MI, 560 unsigned OpNum, 561 const MCSubtargetInfo &STI, 562 raw_ostream &O) { 563 const MCOperand &MO1 = MI->getOperand(OpNum); 564 const MCOperand &MO2 = MI->getOperand(OpNum + 1); 565 566 if (MO1.getReg()) { 567 O << getAddrOpcStr(ARM_AM::getAM3Op(MO2.getImm())); 568 printRegName(O, MO1.getReg()); 569 return; 570 } 571 572 unsigned ImmOffs = ARM_AM::getAM3Offset(MO2.getImm()); 573 O << markup("<imm:") << '#' 574 << ARM_AM::getAddrOpcStr(ARM_AM::getAM3Op(MO2.getImm())) << ImmOffs 575 << markup(">"); 576 } 577 578 void ARMInstPrinter::printPostIdxImm8Operand(const MCInst *MI, unsigned OpNum, 579 const MCSubtargetInfo &STI, 580 raw_ostream &O) { 581 const MCOperand &MO = MI->getOperand(OpNum); 582 unsigned Imm = MO.getImm(); 583 O << markup("<imm:") << '#' << ((Imm & 256) ? "" : "-") << (Imm & 0xff) 584 << markup(">"); 585 } 586 587 void ARMInstPrinter::printPostIdxRegOperand(const MCInst *MI, unsigned OpNum, 588 const MCSubtargetInfo &STI, 589 raw_ostream &O) { 590 const MCOperand &MO1 = MI->getOperand(OpNum); 591 const MCOperand &MO2 = MI->getOperand(OpNum + 1); 592 593 O << (MO2.getImm() ? "" : "-"); 594 printRegName(O, MO1.getReg()); 595 } 596 597 void ARMInstPrinter::printPostIdxImm8s4Operand(const MCInst *MI, unsigned OpNum, 598 const MCSubtargetInfo &STI, 599 raw_ostream &O) { 600 const MCOperand &MO = MI->getOperand(OpNum); 601 unsigned Imm = MO.getImm(); 602 O << markup("<imm:") << '#' << ((Imm & 256) ? "" : "-") << ((Imm & 0xff) << 2) 603 << markup(">"); 604 } 605 606 template<int shift> 607 void ARMInstPrinter::printMveAddrModeRQOperand(const MCInst *MI, unsigned OpNum, 608 const MCSubtargetInfo &STI, 609 raw_ostream &O) { 610 const MCOperand &MO1 = MI->getOperand(OpNum); 611 const MCOperand &MO2 = MI->getOperand(OpNum + 1); 612 613 O << markup("<mem:") << "["; 614 printRegName(O, MO1.getReg()); 615 O << ", "; 616 printRegName(O, MO2.getReg()); 617 618 if (shift > 0) 619 printRegImmShift(O, ARM_AM::uxtw, shift, UseMarkup); 620 621 O << "]" << markup(">"); 622 } 623 624 void ARMInstPrinter::printMveAddrModeQOperand(const MCInst *MI, unsigned OpNum, 625 const MCSubtargetInfo &STI, 626 raw_ostream &O) { 627 const MCOperand &MO1 = MI->getOperand(OpNum); 628 const MCOperand &MO2 = MI->getOperand(OpNum + 1); 629 630 O << markup("<mem:") << "["; 631 printRegName(O, MO1.getReg()); 632 633 int64_t Imm = MO2.getImm(); 634 if (Imm != 0) 635 O << ", " << markup("<imm:") << '#' << Imm << markup(">"); 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 = countTrailingZeros(v); 743 int32_t width = (32 - countLeadingZeros(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.getFeatureBits()[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(std::is_sorted(MI->begin() + OpNum, MI->end(), 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 = countTrailingZeros(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 = ARM_AM::rotr32(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 = countTrailingZeros(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::printExpandedImmOperand(const MCInst *MI, unsigned OpNum, 1672 const MCSubtargetInfo &STI, 1673 raw_ostream &O) { 1674 uint32_t Val = MI->getOperand(OpNum).getImm(); 1675 O << markup("<imm:") << "#0x"; 1676 O.write_hex(Val); 1677 O << markup(">"); 1678 } 1679 1680 void ARMInstPrinter::printMveSaturateOp(const MCInst *MI, unsigned OpNum, 1681 const MCSubtargetInfo &STI, 1682 raw_ostream &O) { 1683 uint32_t Val = MI->getOperand(OpNum).getImm(); 1684 assert(Val <= 1 && "Invalid MVE saturate operand"); 1685 O << "#" << (Val == 1 ? 48 : 64); 1686 } 1687