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 void ARMInstPrinter::printLdStmModeOperand(const MCInst *MI, unsigned OpNum, 607 const MCSubtargetInfo &STI, 608 raw_ostream &O) { 609 ARM_AM::AMSubMode Mode = 610 ARM_AM::getAM4SubMode(MI->getOperand(OpNum).getImm()); 611 O << ARM_AM::getAMSubModeStr(Mode); 612 } 613 614 template <bool AlwaysPrintImm0> 615 void ARMInstPrinter::printAddrMode5Operand(const MCInst *MI, unsigned OpNum, 616 const MCSubtargetInfo &STI, 617 raw_ostream &O) { 618 const MCOperand &MO1 = MI->getOperand(OpNum); 619 const MCOperand &MO2 = MI->getOperand(OpNum + 1); 620 621 if (!MO1.isReg()) { // FIXME: This is for CP entries, but isn't right. 622 printOperand(MI, OpNum, STI, O); 623 return; 624 } 625 626 O << markup("<mem:") << "["; 627 printRegName(O, MO1.getReg()); 628 629 unsigned ImmOffs = ARM_AM::getAM5Offset(MO2.getImm()); 630 ARM_AM::AddrOpc Op = ARM_AM::getAM5Op(MO2.getImm()); 631 if (AlwaysPrintImm0 || ImmOffs || Op == ARM_AM::sub) { 632 O << ", " << markup("<imm:") << "#" << ARM_AM::getAddrOpcStr(Op) 633 << ImmOffs * 4 << markup(">"); 634 } 635 O << "]" << markup(">"); 636 } 637 638 template <bool AlwaysPrintImm0> 639 void ARMInstPrinter::printAddrMode5FP16Operand(const MCInst *MI, unsigned OpNum, 640 const MCSubtargetInfo &STI, 641 raw_ostream &O) { 642 const MCOperand &MO1 = MI->getOperand(OpNum); 643 const MCOperand &MO2 = MI->getOperand(OpNum+1); 644 645 if (!MO1.isReg()) { // FIXME: This is for CP entries, but isn't right. 646 printOperand(MI, OpNum, STI, O); 647 return; 648 } 649 650 O << markup("<mem:") << "["; 651 printRegName(O, MO1.getReg()); 652 653 unsigned ImmOffs = ARM_AM::getAM5FP16Offset(MO2.getImm()); 654 unsigned Op = ARM_AM::getAM5FP16Op(MO2.getImm()); 655 if (AlwaysPrintImm0 || ImmOffs || Op == ARM_AM::sub) { 656 O << ", " 657 << markup("<imm:") 658 << "#" 659 << ARM_AM::getAddrOpcStr(ARM_AM::getAM5FP16Op(MO2.getImm())) 660 << ImmOffs * 2 661 << markup(">"); 662 } 663 O << "]" << markup(">"); 664 } 665 666 void ARMInstPrinter::printAddrMode6Operand(const MCInst *MI, unsigned OpNum, 667 const MCSubtargetInfo &STI, 668 raw_ostream &O) { 669 const MCOperand &MO1 = MI->getOperand(OpNum); 670 const MCOperand &MO2 = MI->getOperand(OpNum + 1); 671 672 O << markup("<mem:") << "["; 673 printRegName(O, MO1.getReg()); 674 if (MO2.getImm()) { 675 O << ":" << (MO2.getImm() << 3); 676 } 677 O << "]" << markup(">"); 678 } 679 680 void ARMInstPrinter::printAddrMode7Operand(const MCInst *MI, unsigned OpNum, 681 const MCSubtargetInfo &STI, 682 raw_ostream &O) { 683 const MCOperand &MO1 = MI->getOperand(OpNum); 684 O << markup("<mem:") << "["; 685 printRegName(O, MO1.getReg()); 686 O << "]" << markup(">"); 687 } 688 689 void ARMInstPrinter::printAddrMode6OffsetOperand(const MCInst *MI, 690 unsigned OpNum, 691 const MCSubtargetInfo &STI, 692 raw_ostream &O) { 693 const MCOperand &MO = MI->getOperand(OpNum); 694 if (MO.getReg() == 0) 695 O << "!"; 696 else { 697 O << ", "; 698 printRegName(O, MO.getReg()); 699 } 700 } 701 702 void ARMInstPrinter::printBitfieldInvMaskImmOperand(const MCInst *MI, 703 unsigned OpNum, 704 const MCSubtargetInfo &STI, 705 raw_ostream &O) { 706 const MCOperand &MO = MI->getOperand(OpNum); 707 uint32_t v = ~MO.getImm(); 708 int32_t lsb = countTrailingZeros(v); 709 int32_t width = (32 - countLeadingZeros(v)) - lsb; 710 assert(MO.isImm() && "Not a valid bf_inv_mask_imm value!"); 711 O << markup("<imm:") << '#' << lsb << markup(">") << ", " << markup("<imm:") 712 << '#' << width << markup(">"); 713 } 714 715 void ARMInstPrinter::printMemBOption(const MCInst *MI, unsigned OpNum, 716 const MCSubtargetInfo &STI, 717 raw_ostream &O) { 718 unsigned val = MI->getOperand(OpNum).getImm(); 719 O << ARM_MB::MemBOptToString(val, STI.getFeatureBits()[ARM::HasV8Ops]); 720 } 721 722 void ARMInstPrinter::printInstSyncBOption(const MCInst *MI, unsigned OpNum, 723 const MCSubtargetInfo &STI, 724 raw_ostream &O) { 725 unsigned val = MI->getOperand(OpNum).getImm(); 726 O << ARM_ISB::InstSyncBOptToString(val); 727 } 728 729 void ARMInstPrinter::printTraceSyncBOption(const MCInst *MI, unsigned OpNum, 730 const MCSubtargetInfo &STI, 731 raw_ostream &O) { 732 unsigned val = MI->getOperand(OpNum).getImm(); 733 O << ARM_TSB::TraceSyncBOptToString(val); 734 } 735 736 void ARMInstPrinter::printShiftImmOperand(const MCInst *MI, unsigned OpNum, 737 const MCSubtargetInfo &STI, 738 raw_ostream &O) { 739 unsigned ShiftOp = MI->getOperand(OpNum).getImm(); 740 bool isASR = (ShiftOp & (1 << 5)) != 0; 741 unsigned Amt = ShiftOp & 0x1f; 742 if (isASR) { 743 O << ", asr " << markup("<imm:") << "#" << (Amt == 0 ? 32 : Amt) 744 << markup(">"); 745 } else if (Amt) { 746 O << ", lsl " << markup("<imm:") << "#" << Amt << markup(">"); 747 } 748 } 749 750 void ARMInstPrinter::printPKHLSLShiftImm(const MCInst *MI, unsigned OpNum, 751 const MCSubtargetInfo &STI, 752 raw_ostream &O) { 753 unsigned Imm = MI->getOperand(OpNum).getImm(); 754 if (Imm == 0) 755 return; 756 assert(Imm > 0 && Imm < 32 && "Invalid PKH shift immediate value!"); 757 O << ", lsl " << markup("<imm:") << "#" << Imm << markup(">"); 758 } 759 760 void ARMInstPrinter::printPKHASRShiftImm(const MCInst *MI, unsigned OpNum, 761 const MCSubtargetInfo &STI, 762 raw_ostream &O) { 763 unsigned Imm = MI->getOperand(OpNum).getImm(); 764 // A shift amount of 32 is encoded as 0. 765 if (Imm == 0) 766 Imm = 32; 767 assert(Imm > 0 && Imm <= 32 && "Invalid PKH shift immediate value!"); 768 O << ", asr " << markup("<imm:") << "#" << Imm << markup(">"); 769 } 770 771 void ARMInstPrinter::printRegisterList(const MCInst *MI, unsigned OpNum, 772 const MCSubtargetInfo &STI, 773 raw_ostream &O) { 774 if (MI->getOpcode() != ARM::t2CLRM) { 775 assert(std::is_sorted(MI->begin() + OpNum, MI->end(), 776 [&](const MCOperand &LHS, const MCOperand &RHS) { 777 return MRI.getEncodingValue(LHS.getReg()) < 778 MRI.getEncodingValue(RHS.getReg()); 779 })); 780 } 781 782 O << "{"; 783 for (unsigned i = OpNum, e = MI->getNumOperands(); i != e; ++i) { 784 if (i != OpNum) 785 O << ", "; 786 printRegName(O, MI->getOperand(i).getReg()); 787 } 788 O << "}"; 789 } 790 791 void ARMInstPrinter::printGPRPairOperand(const MCInst *MI, unsigned OpNum, 792 const MCSubtargetInfo &STI, 793 raw_ostream &O) { 794 unsigned Reg = MI->getOperand(OpNum).getReg(); 795 printRegName(O, MRI.getSubReg(Reg, ARM::gsub_0)); 796 O << ", "; 797 printRegName(O, MRI.getSubReg(Reg, ARM::gsub_1)); 798 } 799 800 void ARMInstPrinter::printSetendOperand(const MCInst *MI, unsigned OpNum, 801 const MCSubtargetInfo &STI, 802 raw_ostream &O) { 803 const MCOperand &Op = MI->getOperand(OpNum); 804 if (Op.getImm()) 805 O << "be"; 806 else 807 O << "le"; 808 } 809 810 void ARMInstPrinter::printCPSIMod(const MCInst *MI, unsigned OpNum, 811 const MCSubtargetInfo &STI, raw_ostream &O) { 812 const MCOperand &Op = MI->getOperand(OpNum); 813 O << ARM_PROC::IModToString(Op.getImm()); 814 } 815 816 void ARMInstPrinter::printCPSIFlag(const MCInst *MI, unsigned OpNum, 817 const MCSubtargetInfo &STI, raw_ostream &O) { 818 const MCOperand &Op = MI->getOperand(OpNum); 819 unsigned IFlags = Op.getImm(); 820 for (int i = 2; i >= 0; --i) 821 if (IFlags & (1 << i)) 822 O << ARM_PROC::IFlagsToString(1 << i); 823 824 if (IFlags == 0) 825 O << "none"; 826 } 827 828 void ARMInstPrinter::printMSRMaskOperand(const MCInst *MI, unsigned OpNum, 829 const MCSubtargetInfo &STI, 830 raw_ostream &O) { 831 const MCOperand &Op = MI->getOperand(OpNum); 832 const FeatureBitset &FeatureBits = STI.getFeatureBits(); 833 if (FeatureBits[ARM::FeatureMClass]) { 834 835 unsigned SYSm = Op.getImm() & 0xFFF; // 12-bit SYSm 836 unsigned Opcode = MI->getOpcode(); 837 838 // For writes, handle extended mask bits if the DSP extension is present. 839 if (Opcode == ARM::t2MSR_M && FeatureBits[ARM::FeatureDSP]) { 840 auto TheReg =ARMSysReg::lookupMClassSysRegBy12bitSYSmValue(SYSm); 841 if (TheReg && TheReg->isInRequiredFeatures({ARM::FeatureDSP})) { 842 O << TheReg->Name; 843 return; 844 } 845 } 846 847 // Handle the basic 8-bit mask. 848 SYSm &= 0xff; 849 if (Opcode == ARM::t2MSR_M && FeatureBits [ARM::HasV7Ops]) { 850 // ARMv7-M deprecates using MSR APSR without a _<bits> qualifier as an 851 // alias for MSR APSR_nzcvq. 852 auto TheReg = ARMSysReg::lookupMClassSysRegAPSRNonDeprecated(SYSm); 853 if (TheReg) { 854 O << TheReg->Name; 855 return; 856 } 857 } 858 859 auto TheReg = ARMSysReg::lookupMClassSysRegBy8bitSYSmValue(SYSm); 860 if (TheReg) { 861 O << TheReg->Name; 862 return; 863 } 864 865 O << SYSm; 866 867 return; 868 } 869 870 // As special cases, CPSR_f, CPSR_s and CPSR_fs prefer printing as 871 // APSR_nzcvq, APSR_g and APSRnzcvqg, respectively. 872 unsigned SpecRegRBit = Op.getImm() >> 4; 873 unsigned Mask = Op.getImm() & 0xf; 874 875 if (!SpecRegRBit && (Mask == 8 || Mask == 4 || Mask == 12)) { 876 O << "APSR_"; 877 switch (Mask) { 878 default: 879 llvm_unreachable("Unexpected mask value!"); 880 case 4: 881 O << "g"; 882 return; 883 case 8: 884 O << "nzcvq"; 885 return; 886 case 12: 887 O << "nzcvqg"; 888 return; 889 } 890 } 891 892 if (SpecRegRBit) 893 O << "SPSR"; 894 else 895 O << "CPSR"; 896 897 if (Mask) { 898 O << '_'; 899 if (Mask & 8) 900 O << 'f'; 901 if (Mask & 4) 902 O << 's'; 903 if (Mask & 2) 904 O << 'x'; 905 if (Mask & 1) 906 O << 'c'; 907 } 908 } 909 910 void ARMInstPrinter::printBankedRegOperand(const MCInst *MI, unsigned OpNum, 911 const MCSubtargetInfo &STI, 912 raw_ostream &O) { 913 uint32_t Banked = MI->getOperand(OpNum).getImm(); 914 auto TheReg = ARMBankedReg::lookupBankedRegByEncoding(Banked); 915 assert(TheReg && "invalid banked register operand"); 916 std::string Name = TheReg->Name; 917 918 uint32_t isSPSR = (Banked & 0x20) >> 5; 919 if (isSPSR) 920 Name.replace(0, 4, "SPSR"); // convert 'spsr_' to 'SPSR_' 921 O << Name; 922 } 923 924 void ARMInstPrinter::printPredicateOperand(const MCInst *MI, unsigned OpNum, 925 const MCSubtargetInfo &STI, 926 raw_ostream &O) { 927 ARMCC::CondCodes CC = (ARMCC::CondCodes)MI->getOperand(OpNum).getImm(); 928 // Handle the undefined 15 CC value here for printing so we don't abort(). 929 if ((unsigned)CC == 15) 930 O << "<und>"; 931 else if (CC != ARMCC::AL) 932 O << ARMCondCodeToString(CC); 933 } 934 935 void ARMInstPrinter::printMandatoryRestrictedPredicateOperand( 936 const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, 937 raw_ostream &O) { 938 if ((ARMCC::CondCodes)MI->getOperand(OpNum).getImm() == ARMCC::HS) 939 O << "cs"; 940 else 941 printMandatoryPredicateOperand(MI, OpNum, STI, O); 942 } 943 944 void ARMInstPrinter::printMandatoryPredicateOperand(const MCInst *MI, 945 unsigned OpNum, 946 const MCSubtargetInfo &STI, 947 raw_ostream &O) { 948 ARMCC::CondCodes CC = (ARMCC::CondCodes)MI->getOperand(OpNum).getImm(); 949 O << ARMCondCodeToString(CC); 950 } 951 952 void ARMInstPrinter::printMandatoryInvertedPredicateOperand(const MCInst *MI, 953 unsigned OpNum, 954 const MCSubtargetInfo &STI, 955 raw_ostream &O) { 956 ARMCC::CondCodes CC = (ARMCC::CondCodes)MI->getOperand(OpNum).getImm(); 957 O << ARMCondCodeToString(ARMCC::getOppositeCondition(CC)); 958 } 959 960 void ARMInstPrinter::printSBitModifierOperand(const MCInst *MI, unsigned OpNum, 961 const MCSubtargetInfo &STI, 962 raw_ostream &O) { 963 if (MI->getOperand(OpNum).getReg()) { 964 assert(MI->getOperand(OpNum).getReg() == ARM::CPSR && 965 "Expect ARM CPSR register!"); 966 O << 's'; 967 } 968 } 969 970 void ARMInstPrinter::printNoHashImmediate(const MCInst *MI, unsigned OpNum, 971 const MCSubtargetInfo &STI, 972 raw_ostream &O) { 973 O << MI->getOperand(OpNum).getImm(); 974 } 975 976 void ARMInstPrinter::printPImmediate(const MCInst *MI, unsigned OpNum, 977 const MCSubtargetInfo &STI, 978 raw_ostream &O) { 979 O << "p" << MI->getOperand(OpNum).getImm(); 980 } 981 982 void ARMInstPrinter::printCImmediate(const MCInst *MI, unsigned OpNum, 983 const MCSubtargetInfo &STI, 984 raw_ostream &O) { 985 O << "c" << MI->getOperand(OpNum).getImm(); 986 } 987 988 void ARMInstPrinter::printCoprocOptionImm(const MCInst *MI, unsigned OpNum, 989 const MCSubtargetInfo &STI, 990 raw_ostream &O) { 991 O << "{" << MI->getOperand(OpNum).getImm() << "}"; 992 } 993 994 void ARMInstPrinter::printPCLabel(const MCInst *MI, unsigned OpNum, 995 const MCSubtargetInfo &STI, raw_ostream &O) { 996 llvm_unreachable("Unhandled PC-relative pseudo-instruction!"); 997 } 998 999 template <unsigned scale> 1000 void ARMInstPrinter::printAdrLabelOperand(const MCInst *MI, unsigned OpNum, 1001 const MCSubtargetInfo &STI, 1002 raw_ostream &O) { 1003 const MCOperand &MO = MI->getOperand(OpNum); 1004 1005 if (MO.isExpr()) { 1006 MO.getExpr()->print(O, &MAI); 1007 return; 1008 } 1009 1010 int32_t OffImm = (int32_t)MO.getImm() << scale; 1011 1012 O << markup("<imm:"); 1013 if (OffImm == INT32_MIN) 1014 O << "#-0"; 1015 else if (OffImm < 0) 1016 O << "#-" << -OffImm; 1017 else 1018 O << "#" << OffImm; 1019 O << markup(">"); 1020 } 1021 1022 void ARMInstPrinter::printThumbS4ImmOperand(const MCInst *MI, unsigned OpNum, 1023 const MCSubtargetInfo &STI, 1024 raw_ostream &O) { 1025 O << markup("<imm:") << "#" << formatImm(MI->getOperand(OpNum).getImm() * 4) 1026 << markup(">"); 1027 } 1028 1029 void ARMInstPrinter::printThumbSRImm(const MCInst *MI, unsigned OpNum, 1030 const MCSubtargetInfo &STI, 1031 raw_ostream &O) { 1032 unsigned Imm = MI->getOperand(OpNum).getImm(); 1033 O << markup("<imm:") << "#" << formatImm((Imm == 0 ? 32 : Imm)) 1034 << markup(">"); 1035 } 1036 1037 void ARMInstPrinter::printThumbITMask(const MCInst *MI, unsigned OpNum, 1038 const MCSubtargetInfo &STI, 1039 raw_ostream &O) { 1040 // (3 - the number of trailing zeros) is the number of then / else. 1041 unsigned Mask = MI->getOperand(OpNum).getImm(); 1042 unsigned NumTZ = countTrailingZeros(Mask); 1043 assert(NumTZ <= 3 && "Invalid IT mask!"); 1044 for (unsigned Pos = 3, e = NumTZ; Pos > e; --Pos) { 1045 if ((Mask >> Pos) & 1) 1046 O << 'e'; 1047 else 1048 O << 't'; 1049 } 1050 } 1051 1052 void ARMInstPrinter::printThumbAddrModeRROperand(const MCInst *MI, unsigned Op, 1053 const MCSubtargetInfo &STI, 1054 raw_ostream &O) { 1055 const MCOperand &MO1 = MI->getOperand(Op); 1056 const MCOperand &MO2 = MI->getOperand(Op + 1); 1057 1058 if (!MO1.isReg()) { // FIXME: This is for CP entries, but isn't right. 1059 printOperand(MI, Op, STI, O); 1060 return; 1061 } 1062 1063 O << markup("<mem:") << "["; 1064 printRegName(O, MO1.getReg()); 1065 if (unsigned RegNum = MO2.getReg()) { 1066 O << ", "; 1067 printRegName(O, RegNum); 1068 } 1069 O << "]" << markup(">"); 1070 } 1071 1072 void ARMInstPrinter::printThumbAddrModeImm5SOperand(const MCInst *MI, 1073 unsigned Op, 1074 const MCSubtargetInfo &STI, 1075 raw_ostream &O, 1076 unsigned Scale) { 1077 const MCOperand &MO1 = MI->getOperand(Op); 1078 const MCOperand &MO2 = MI->getOperand(Op + 1); 1079 1080 if (!MO1.isReg()) { // FIXME: This is for CP entries, but isn't right. 1081 printOperand(MI, Op, STI, O); 1082 return; 1083 } 1084 1085 O << markup("<mem:") << "["; 1086 printRegName(O, MO1.getReg()); 1087 if (unsigned ImmOffs = MO2.getImm()) { 1088 O << ", " << markup("<imm:") << "#" << formatImm(ImmOffs * Scale) 1089 << markup(">"); 1090 } 1091 O << "]" << markup(">"); 1092 } 1093 1094 void ARMInstPrinter::printThumbAddrModeImm5S1Operand(const MCInst *MI, 1095 unsigned Op, 1096 const MCSubtargetInfo &STI, 1097 raw_ostream &O) { 1098 printThumbAddrModeImm5SOperand(MI, Op, STI, O, 1); 1099 } 1100 1101 void ARMInstPrinter::printThumbAddrModeImm5S2Operand(const MCInst *MI, 1102 unsigned Op, 1103 const MCSubtargetInfo &STI, 1104 raw_ostream &O) { 1105 printThumbAddrModeImm5SOperand(MI, Op, STI, O, 2); 1106 } 1107 1108 void ARMInstPrinter::printThumbAddrModeImm5S4Operand(const MCInst *MI, 1109 unsigned Op, 1110 const MCSubtargetInfo &STI, 1111 raw_ostream &O) { 1112 printThumbAddrModeImm5SOperand(MI, Op, STI, O, 4); 1113 } 1114 1115 void ARMInstPrinter::printThumbAddrModeSPOperand(const MCInst *MI, unsigned Op, 1116 const MCSubtargetInfo &STI, 1117 raw_ostream &O) { 1118 printThumbAddrModeImm5SOperand(MI, Op, STI, O, 4); 1119 } 1120 1121 // Constant shifts t2_so_reg is a 2-operand unit corresponding to the Thumb2 1122 // register with shift forms. 1123 // REG 0 0 - e.g. R5 1124 // REG IMM, SH_OPC - e.g. R5, LSL #3 1125 void ARMInstPrinter::printT2SOOperand(const MCInst *MI, unsigned OpNum, 1126 const MCSubtargetInfo &STI, 1127 raw_ostream &O) { 1128 const MCOperand &MO1 = MI->getOperand(OpNum); 1129 const MCOperand &MO2 = MI->getOperand(OpNum + 1); 1130 1131 unsigned Reg = MO1.getReg(); 1132 printRegName(O, Reg); 1133 1134 // Print the shift opc. 1135 assert(MO2.isImm() && "Not a valid t2_so_reg value!"); 1136 printRegImmShift(O, ARM_AM::getSORegShOp(MO2.getImm()), 1137 ARM_AM::getSORegOffset(MO2.getImm()), UseMarkup); 1138 } 1139 1140 template <bool AlwaysPrintImm0> 1141 void ARMInstPrinter::printAddrModeImm12Operand(const MCInst *MI, unsigned OpNum, 1142 const MCSubtargetInfo &STI, 1143 raw_ostream &O) { 1144 const MCOperand &MO1 = MI->getOperand(OpNum); 1145 const MCOperand &MO2 = MI->getOperand(OpNum + 1); 1146 1147 if (!MO1.isReg()) { // FIXME: This is for CP entries, but isn't right. 1148 printOperand(MI, OpNum, STI, O); 1149 return; 1150 } 1151 1152 O << markup("<mem:") << "["; 1153 printRegName(O, MO1.getReg()); 1154 1155 int32_t OffImm = (int32_t)MO2.getImm(); 1156 bool isSub = OffImm < 0; 1157 // Special value for #-0. All others are normal. 1158 if (OffImm == INT32_MIN) 1159 OffImm = 0; 1160 if (isSub) { 1161 O << ", " << markup("<imm:") << "#-" << formatImm(-OffImm) << markup(">"); 1162 } else if (AlwaysPrintImm0 || OffImm > 0) { 1163 O << ", " << markup("<imm:") << "#" << formatImm(OffImm) << markup(">"); 1164 } 1165 O << "]" << markup(">"); 1166 } 1167 1168 template <bool AlwaysPrintImm0> 1169 void ARMInstPrinter::printT2AddrModeImm8Operand(const MCInst *MI, 1170 unsigned OpNum, 1171 const MCSubtargetInfo &STI, 1172 raw_ostream &O) { 1173 const MCOperand &MO1 = MI->getOperand(OpNum); 1174 const MCOperand &MO2 = MI->getOperand(OpNum + 1); 1175 1176 O << markup("<mem:") << "["; 1177 printRegName(O, MO1.getReg()); 1178 1179 int32_t OffImm = (int32_t)MO2.getImm(); 1180 bool isSub = OffImm < 0; 1181 // Don't print +0. 1182 if (OffImm == INT32_MIN) 1183 OffImm = 0; 1184 if (isSub) { 1185 O << ", " << markup("<imm:") << "#-" << -OffImm << markup(">"); 1186 } else if (AlwaysPrintImm0 || OffImm > 0) { 1187 O << ", " << markup("<imm:") << "#" << OffImm << markup(">"); 1188 } 1189 O << "]" << markup(">"); 1190 } 1191 1192 template <bool AlwaysPrintImm0> 1193 void ARMInstPrinter::printT2AddrModeImm8s4Operand(const MCInst *MI, 1194 unsigned OpNum, 1195 const MCSubtargetInfo &STI, 1196 raw_ostream &O) { 1197 const MCOperand &MO1 = MI->getOperand(OpNum); 1198 const MCOperand &MO2 = MI->getOperand(OpNum + 1); 1199 1200 if (!MO1.isReg()) { // For label symbolic references. 1201 printOperand(MI, OpNum, STI, O); 1202 return; 1203 } 1204 1205 O << markup("<mem:") << "["; 1206 printRegName(O, MO1.getReg()); 1207 1208 int32_t OffImm = (int32_t)MO2.getImm(); 1209 bool isSub = OffImm < 0; 1210 1211 assert(((OffImm & 0x3) == 0) && "Not a valid immediate!"); 1212 1213 // Don't print +0. 1214 if (OffImm == INT32_MIN) 1215 OffImm = 0; 1216 if (isSub) { 1217 O << ", " << markup("<imm:") << "#-" << -OffImm << markup(">"); 1218 } else if (AlwaysPrintImm0 || OffImm > 0) { 1219 O << ", " << markup("<imm:") << "#" << OffImm << markup(">"); 1220 } 1221 O << "]" << markup(">"); 1222 } 1223 1224 void ARMInstPrinter::printT2AddrModeImm0_1020s4Operand( 1225 const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, 1226 raw_ostream &O) { 1227 const MCOperand &MO1 = MI->getOperand(OpNum); 1228 const MCOperand &MO2 = MI->getOperand(OpNum + 1); 1229 1230 O << markup("<mem:") << "["; 1231 printRegName(O, MO1.getReg()); 1232 if (MO2.getImm()) { 1233 O << ", " << markup("<imm:") << "#" << formatImm(MO2.getImm() * 4) 1234 << markup(">"); 1235 } 1236 O << "]" << markup(">"); 1237 } 1238 1239 void ARMInstPrinter::printT2AddrModeImm8OffsetOperand( 1240 const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, 1241 raw_ostream &O) { 1242 const MCOperand &MO1 = MI->getOperand(OpNum); 1243 int32_t OffImm = (int32_t)MO1.getImm(); 1244 O << ", " << markup("<imm:"); 1245 if (OffImm == INT32_MIN) 1246 O << "#-0"; 1247 else if (OffImm < 0) 1248 O << "#-" << -OffImm; 1249 else 1250 O << "#" << OffImm; 1251 O << markup(">"); 1252 } 1253 1254 void ARMInstPrinter::printT2AddrModeImm8s4OffsetOperand( 1255 const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, 1256 raw_ostream &O) { 1257 const MCOperand &MO1 = MI->getOperand(OpNum); 1258 int32_t OffImm = (int32_t)MO1.getImm(); 1259 1260 assert(((OffImm & 0x3) == 0) && "Not a valid immediate!"); 1261 1262 O << ", " << markup("<imm:"); 1263 if (OffImm == INT32_MIN) 1264 O << "#-0"; 1265 else if (OffImm < 0) 1266 O << "#-" << -OffImm; 1267 else 1268 O << "#" << OffImm; 1269 O << markup(">"); 1270 } 1271 1272 void ARMInstPrinter::printT2AddrModeSoRegOperand(const MCInst *MI, 1273 unsigned OpNum, 1274 const MCSubtargetInfo &STI, 1275 raw_ostream &O) { 1276 const MCOperand &MO1 = MI->getOperand(OpNum); 1277 const MCOperand &MO2 = MI->getOperand(OpNum + 1); 1278 const MCOperand &MO3 = MI->getOperand(OpNum + 2); 1279 1280 O << markup("<mem:") << "["; 1281 printRegName(O, MO1.getReg()); 1282 1283 assert(MO2.getReg() && "Invalid so_reg load / store address!"); 1284 O << ", "; 1285 printRegName(O, MO2.getReg()); 1286 1287 unsigned ShAmt = MO3.getImm(); 1288 if (ShAmt) { 1289 assert(ShAmt <= 3 && "Not a valid Thumb2 addressing mode!"); 1290 O << ", lsl " << markup("<imm:") << "#" << ShAmt << markup(">"); 1291 } 1292 O << "]" << markup(">"); 1293 } 1294 1295 void ARMInstPrinter::printFPImmOperand(const MCInst *MI, unsigned OpNum, 1296 const MCSubtargetInfo &STI, 1297 raw_ostream &O) { 1298 const MCOperand &MO = MI->getOperand(OpNum); 1299 O << markup("<imm:") << '#' << ARM_AM::getFPImmFloat(MO.getImm()) 1300 << markup(">"); 1301 } 1302 1303 void ARMInstPrinter::printNEONModImmOperand(const MCInst *MI, unsigned OpNum, 1304 const MCSubtargetInfo &STI, 1305 raw_ostream &O) { 1306 unsigned EncodedImm = MI->getOperand(OpNum).getImm(); 1307 unsigned EltBits; 1308 uint64_t Val = ARM_AM::decodeNEONModImm(EncodedImm, EltBits); 1309 O << markup("<imm:") << "#0x"; 1310 O.write_hex(Val); 1311 O << markup(">"); 1312 } 1313 1314 void ARMInstPrinter::printImmPlusOneOperand(const MCInst *MI, unsigned OpNum, 1315 const MCSubtargetInfo &STI, 1316 raw_ostream &O) { 1317 unsigned Imm = MI->getOperand(OpNum).getImm(); 1318 O << markup("<imm:") << "#" << formatImm(Imm + 1) << markup(">"); 1319 } 1320 1321 void ARMInstPrinter::printRotImmOperand(const MCInst *MI, unsigned OpNum, 1322 const MCSubtargetInfo &STI, 1323 raw_ostream &O) { 1324 unsigned Imm = MI->getOperand(OpNum).getImm(); 1325 if (Imm == 0) 1326 return; 1327 assert(Imm <= 3 && "illegal ror immediate!"); 1328 O << ", ror " << markup("<imm:") << "#" << 8 * Imm << markup(">"); 1329 } 1330 1331 void ARMInstPrinter::printModImmOperand(const MCInst *MI, unsigned OpNum, 1332 const MCSubtargetInfo &STI, 1333 raw_ostream &O) { 1334 MCOperand Op = MI->getOperand(OpNum); 1335 1336 // Support for fixups (MCFixup) 1337 if (Op.isExpr()) 1338 return printOperand(MI, OpNum, STI, O); 1339 1340 unsigned Bits = Op.getImm() & 0xFF; 1341 unsigned Rot = (Op.getImm() & 0xF00) >> 7; 1342 1343 bool PrintUnsigned = false; 1344 switch (MI->getOpcode()) { 1345 case ARM::MOVi: 1346 // Movs to PC should be treated unsigned 1347 PrintUnsigned = (MI->getOperand(OpNum - 1).getReg() == ARM::PC); 1348 break; 1349 case ARM::MSRi: 1350 // Movs to special registers should be treated unsigned 1351 PrintUnsigned = true; 1352 break; 1353 } 1354 1355 int32_t Rotated = ARM_AM::rotr32(Bits, Rot); 1356 if (ARM_AM::getSOImmVal(Rotated) == Op.getImm()) { 1357 // #rot has the least possible value 1358 O << "#" << markup("<imm:"); 1359 if (PrintUnsigned) 1360 O << static_cast<uint32_t>(Rotated); 1361 else 1362 O << Rotated; 1363 O << markup(">"); 1364 return; 1365 } 1366 1367 // Explicit #bits, #rot implied 1368 O << "#" << markup("<imm:") << Bits << markup(">") << ", #" << markup("<imm:") 1369 << Rot << markup(">"); 1370 } 1371 1372 void ARMInstPrinter::printFBits16(const MCInst *MI, unsigned OpNum, 1373 const MCSubtargetInfo &STI, raw_ostream &O) { 1374 O << markup("<imm:") << "#" << 16 - MI->getOperand(OpNum).getImm() 1375 << markup(">"); 1376 } 1377 1378 void ARMInstPrinter::printFBits32(const MCInst *MI, unsigned OpNum, 1379 const MCSubtargetInfo &STI, raw_ostream &O) { 1380 O << markup("<imm:") << "#" << 32 - MI->getOperand(OpNum).getImm() 1381 << markup(">"); 1382 } 1383 1384 void ARMInstPrinter::printVectorIndex(const MCInst *MI, unsigned OpNum, 1385 const MCSubtargetInfo &STI, 1386 raw_ostream &O) { 1387 O << "[" << MI->getOperand(OpNum).getImm() << "]"; 1388 } 1389 1390 void ARMInstPrinter::printVectorListOne(const MCInst *MI, unsigned OpNum, 1391 const MCSubtargetInfo &STI, 1392 raw_ostream &O) { 1393 O << "{"; 1394 printRegName(O, MI->getOperand(OpNum).getReg()); 1395 O << "}"; 1396 } 1397 1398 void ARMInstPrinter::printVectorListTwo(const MCInst *MI, unsigned OpNum, 1399 const MCSubtargetInfo &STI, 1400 raw_ostream &O) { 1401 unsigned Reg = MI->getOperand(OpNum).getReg(); 1402 unsigned Reg0 = MRI.getSubReg(Reg, ARM::dsub_0); 1403 unsigned Reg1 = MRI.getSubReg(Reg, ARM::dsub_1); 1404 O << "{"; 1405 printRegName(O, Reg0); 1406 O << ", "; 1407 printRegName(O, Reg1); 1408 O << "}"; 1409 } 1410 1411 void ARMInstPrinter::printVectorListTwoSpaced(const MCInst *MI, unsigned OpNum, 1412 const MCSubtargetInfo &STI, 1413 raw_ostream &O) { 1414 unsigned Reg = MI->getOperand(OpNum).getReg(); 1415 unsigned Reg0 = MRI.getSubReg(Reg, ARM::dsub_0); 1416 unsigned Reg1 = MRI.getSubReg(Reg, ARM::dsub_2); 1417 O << "{"; 1418 printRegName(O, Reg0); 1419 O << ", "; 1420 printRegName(O, Reg1); 1421 O << "}"; 1422 } 1423 1424 void ARMInstPrinter::printVectorListThree(const MCInst *MI, unsigned OpNum, 1425 const MCSubtargetInfo &STI, 1426 raw_ostream &O) { 1427 // Normally, it's not safe to use register enum values directly with 1428 // addition to get the next register, but for VFP registers, the 1429 // sort order is guaranteed because they're all of the form D<n>. 1430 O << "{"; 1431 printRegName(O, MI->getOperand(OpNum).getReg()); 1432 O << ", "; 1433 printRegName(O, MI->getOperand(OpNum).getReg() + 1); 1434 O << ", "; 1435 printRegName(O, MI->getOperand(OpNum).getReg() + 2); 1436 O << "}"; 1437 } 1438 1439 void ARMInstPrinter::printVectorListFour(const MCInst *MI, unsigned OpNum, 1440 const MCSubtargetInfo &STI, 1441 raw_ostream &O) { 1442 // Normally, it's not safe to use register enum values directly with 1443 // addition to get the next register, but for VFP registers, the 1444 // sort order is guaranteed because they're all of the form D<n>. 1445 O << "{"; 1446 printRegName(O, MI->getOperand(OpNum).getReg()); 1447 O << ", "; 1448 printRegName(O, MI->getOperand(OpNum).getReg() + 1); 1449 O << ", "; 1450 printRegName(O, MI->getOperand(OpNum).getReg() + 2); 1451 O << ", "; 1452 printRegName(O, MI->getOperand(OpNum).getReg() + 3); 1453 O << "}"; 1454 } 1455 1456 void ARMInstPrinter::printVectorListOneAllLanes(const MCInst *MI, 1457 unsigned OpNum, 1458 const MCSubtargetInfo &STI, 1459 raw_ostream &O) { 1460 O << "{"; 1461 printRegName(O, MI->getOperand(OpNum).getReg()); 1462 O << "[]}"; 1463 } 1464 1465 void ARMInstPrinter::printVectorListTwoAllLanes(const MCInst *MI, 1466 unsigned OpNum, 1467 const MCSubtargetInfo &STI, 1468 raw_ostream &O) { 1469 unsigned Reg = MI->getOperand(OpNum).getReg(); 1470 unsigned Reg0 = MRI.getSubReg(Reg, ARM::dsub_0); 1471 unsigned Reg1 = MRI.getSubReg(Reg, ARM::dsub_1); 1472 O << "{"; 1473 printRegName(O, Reg0); 1474 O << "[], "; 1475 printRegName(O, Reg1); 1476 O << "[]}"; 1477 } 1478 1479 void ARMInstPrinter::printVectorListThreeAllLanes(const MCInst *MI, 1480 unsigned OpNum, 1481 const MCSubtargetInfo &STI, 1482 raw_ostream &O) { 1483 // Normally, it's not safe to use register enum values directly with 1484 // addition to get the next register, but for VFP registers, the 1485 // sort order is guaranteed because they're all of the form D<n>. 1486 O << "{"; 1487 printRegName(O, MI->getOperand(OpNum).getReg()); 1488 O << "[], "; 1489 printRegName(O, MI->getOperand(OpNum).getReg() + 1); 1490 O << "[], "; 1491 printRegName(O, MI->getOperand(OpNum).getReg() + 2); 1492 O << "[]}"; 1493 } 1494 1495 void ARMInstPrinter::printVectorListFourAllLanes(const MCInst *MI, 1496 unsigned OpNum, 1497 const MCSubtargetInfo &STI, 1498 raw_ostream &O) { 1499 // Normally, it's not safe to use register enum values directly with 1500 // addition to get the next register, but for VFP registers, the 1501 // sort order is guaranteed because they're all of the form D<n>. 1502 O << "{"; 1503 printRegName(O, MI->getOperand(OpNum).getReg()); 1504 O << "[], "; 1505 printRegName(O, MI->getOperand(OpNum).getReg() + 1); 1506 O << "[], "; 1507 printRegName(O, MI->getOperand(OpNum).getReg() + 2); 1508 O << "[], "; 1509 printRegName(O, MI->getOperand(OpNum).getReg() + 3); 1510 O << "[]}"; 1511 } 1512 1513 void ARMInstPrinter::printVectorListTwoSpacedAllLanes( 1514 const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, 1515 raw_ostream &O) { 1516 unsigned Reg = MI->getOperand(OpNum).getReg(); 1517 unsigned Reg0 = MRI.getSubReg(Reg, ARM::dsub_0); 1518 unsigned Reg1 = MRI.getSubReg(Reg, ARM::dsub_2); 1519 O << "{"; 1520 printRegName(O, Reg0); 1521 O << "[], "; 1522 printRegName(O, Reg1); 1523 O << "[]}"; 1524 } 1525 1526 void ARMInstPrinter::printVectorListThreeSpacedAllLanes( 1527 const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, 1528 raw_ostream &O) { 1529 // Normally, it's not safe to use register enum values directly with 1530 // addition to get the next register, but for VFP registers, the 1531 // sort order is guaranteed because they're all of the form D<n>. 1532 O << "{"; 1533 printRegName(O, MI->getOperand(OpNum).getReg()); 1534 O << "[], "; 1535 printRegName(O, MI->getOperand(OpNum).getReg() + 2); 1536 O << "[], "; 1537 printRegName(O, MI->getOperand(OpNum).getReg() + 4); 1538 O << "[]}"; 1539 } 1540 1541 void ARMInstPrinter::printVectorListFourSpacedAllLanes( 1542 const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, 1543 raw_ostream &O) { 1544 // Normally, it's not safe to use register enum values directly with 1545 // addition to get the next register, but for VFP registers, the 1546 // sort order is guaranteed because they're all of the form D<n>. 1547 O << "{"; 1548 printRegName(O, MI->getOperand(OpNum).getReg()); 1549 O << "[], "; 1550 printRegName(O, MI->getOperand(OpNum).getReg() + 2); 1551 O << "[], "; 1552 printRegName(O, MI->getOperand(OpNum).getReg() + 4); 1553 O << "[], "; 1554 printRegName(O, MI->getOperand(OpNum).getReg() + 6); 1555 O << "[]}"; 1556 } 1557 1558 void ARMInstPrinter::printVectorListThreeSpaced(const MCInst *MI, 1559 unsigned OpNum, 1560 const MCSubtargetInfo &STI, 1561 raw_ostream &O) { 1562 // Normally, it's not safe to use register enum values directly with 1563 // addition to get the next register, but for VFP registers, the 1564 // sort order is guaranteed because they're all of the form D<n>. 1565 O << "{"; 1566 printRegName(O, MI->getOperand(OpNum).getReg()); 1567 O << ", "; 1568 printRegName(O, MI->getOperand(OpNum).getReg() + 2); 1569 O << ", "; 1570 printRegName(O, MI->getOperand(OpNum).getReg() + 4); 1571 O << "}"; 1572 } 1573 1574 void ARMInstPrinter::printVectorListFourSpaced(const MCInst *MI, unsigned OpNum, 1575 const MCSubtargetInfo &STI, 1576 raw_ostream &O) { 1577 // Normally, it's not safe to use register enum values directly with 1578 // addition to get the next register, but for VFP registers, the 1579 // sort order is guaranteed because they're all of the form D<n>. 1580 O << "{"; 1581 printRegName(O, MI->getOperand(OpNum).getReg()); 1582 O << ", "; 1583 printRegName(O, MI->getOperand(OpNum).getReg() + 2); 1584 O << ", "; 1585 printRegName(O, MI->getOperand(OpNum).getReg() + 4); 1586 O << ", "; 1587 printRegName(O, MI->getOperand(OpNum).getReg() + 6); 1588 O << "}"; 1589 } 1590 1591 template<int64_t Angle, int64_t Remainder> 1592 void ARMInstPrinter::printComplexRotationOp(const MCInst *MI, unsigned OpNo, 1593 const MCSubtargetInfo &STI, 1594 raw_ostream &O) { 1595 unsigned Val = MI->getOperand(OpNo).getImm(); 1596 O << "#" << (Val * Angle) + Remainder; 1597 } 1598 1599 void ARMInstPrinter::printVPTPredicateOperand(const MCInst *MI, unsigned OpNum, 1600 const MCSubtargetInfo &STI, 1601 raw_ostream &O) { 1602 ARMVCC::VPTCodes CC = (ARMVCC::VPTCodes)MI->getOperand(OpNum).getImm(); 1603 if (CC != ARMVCC::None) 1604 O << ARMVPTPredToString(CC); 1605 } 1606 1607 void ARMInstPrinter::printVPTMask(const MCInst *MI, unsigned OpNum, 1608 const MCSubtargetInfo &STI, 1609 raw_ostream &O) { 1610 // (3 - the number of trailing zeroes) is the number of them / else. 1611 unsigned Mask = MI->getOperand(OpNum).getImm(); 1612 unsigned NumTZ = countTrailingZeros(Mask); 1613 assert(NumTZ <= 3 && "Invalid VPT mask!"); 1614 for (unsigned Pos = 3, e = NumTZ; Pos > e; --Pos) { 1615 bool T = ((Mask >> Pos) & 1) == 0; 1616 if (T) 1617 O << 't'; 1618 else 1619 O << 'e'; 1620 } 1621 } 1622 1623