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