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