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