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