ARMInstPrinter.cpp revision 17463b3ef1a3d39b10619254f12e806c8c43f9e7
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/ARMBaseInfo.h" 17#include "MCTargetDesc/ARMAddressingModes.h" 18#include "llvm/MC/MCInst.h" 19#include "llvm/MC/MCAsmInfo.h" 20#include "llvm/MC/MCExpr.h" 21#include "llvm/MC/MCRegisterInfo.h" 22#include "llvm/Support/raw_ostream.h" 23using namespace llvm; 24 25#define GET_INSTRUCTION_NAME 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 if (imm == 0) 33 return 32; 34 return imm; 35} 36 37 38ARMInstPrinter::ARMInstPrinter(const MCAsmInfo &MAI, 39 const MCInstrInfo &MII, 40 const MCRegisterInfo &MRI, 41 const MCSubtargetInfo &STI) : 42 MCInstPrinter(MAI, MII, MRI) { 43 // Initialize the set of available features. 44 setAvailableFeatures(STI.getFeatureBits()); 45} 46 47StringRef ARMInstPrinter::getOpcodeName(unsigned Opcode) const { 48 return getInstructionName(Opcode); 49} 50 51void ARMInstPrinter::printRegName(raw_ostream &OS, unsigned RegNo) const { 52 OS << getRegisterName(RegNo); 53} 54 55void ARMInstPrinter::printInst(const MCInst *MI, raw_ostream &O, 56 StringRef Annot) { 57 unsigned Opcode = MI->getOpcode(); 58 59 // Check for MOVs and print canonical forms, instead. 60 if (Opcode == ARM::MOVsr) { 61 // FIXME: Thumb variants? 62 const MCOperand &Dst = MI->getOperand(0); 63 const MCOperand &MO1 = MI->getOperand(1); 64 const MCOperand &MO2 = MI->getOperand(2); 65 const MCOperand &MO3 = MI->getOperand(3); 66 67 O << '\t' << ARM_AM::getShiftOpcStr(ARM_AM::getSORegShOp(MO3.getImm())); 68 printSBitModifierOperand(MI, 6, O); 69 printPredicateOperand(MI, 4, O); 70 71 O << '\t' << getRegisterName(Dst.getReg()) 72 << ", " << getRegisterName(MO1.getReg()); 73 74 O << ", " << getRegisterName(MO2.getReg()); 75 assert(ARM_AM::getSORegOffset(MO3.getImm()) == 0); 76 printAnnotation(O, Annot); 77 return; 78 } 79 80 if (Opcode == ARM::MOVsi) { 81 // FIXME: Thumb variants? 82 const MCOperand &Dst = MI->getOperand(0); 83 const MCOperand &MO1 = MI->getOperand(1); 84 const MCOperand &MO2 = MI->getOperand(2); 85 86 O << '\t' << ARM_AM::getShiftOpcStr(ARM_AM::getSORegShOp(MO2.getImm())); 87 printSBitModifierOperand(MI, 5, O); 88 printPredicateOperand(MI, 3, O); 89 90 O << '\t' << getRegisterName(Dst.getReg()) 91 << ", " << getRegisterName(MO1.getReg()); 92 93 if (ARM_AM::getSORegShOp(MO2.getImm()) == ARM_AM::rrx) { 94 printAnnotation(O, Annot); 95 return; 96 } 97 98 O << ", #" << translateShiftImm(ARM_AM::getSORegOffset(MO2.getImm())); 99 printAnnotation(O, Annot); 100 return; 101 } 102 103 104 // A8.6.123 PUSH 105 if ((Opcode == ARM::STMDB_UPD || Opcode == ARM::t2STMDB_UPD) && 106 MI->getOperand(0).getReg() == ARM::SP && 107 MI->getNumOperands() > 5) { 108 // Should only print PUSH if there are at least two registers in the list. 109 O << '\t' << "push"; 110 printPredicateOperand(MI, 2, O); 111 if (Opcode == ARM::t2STMDB_UPD) 112 O << ".w"; 113 O << '\t'; 114 printRegisterList(MI, 4, O); 115 printAnnotation(O, Annot); 116 return; 117 } 118 if (Opcode == ARM::STR_PRE_IMM && MI->getOperand(2).getReg() == ARM::SP && 119 MI->getOperand(3).getImm() == -4) { 120 O << '\t' << "push"; 121 printPredicateOperand(MI, 4, O); 122 O << "\t{" << getRegisterName(MI->getOperand(1).getReg()) << "}"; 123 printAnnotation(O, Annot); 124 return; 125 } 126 127 // A8.6.122 POP 128 if ((Opcode == ARM::LDMIA_UPD || Opcode == ARM::t2LDMIA_UPD) && 129 MI->getOperand(0).getReg() == ARM::SP && 130 MI->getNumOperands() > 5) { 131 // Should only print POP if there are at least two registers in the list. 132 O << '\t' << "pop"; 133 printPredicateOperand(MI, 2, O); 134 if (Opcode == ARM::t2LDMIA_UPD) 135 O << ".w"; 136 O << '\t'; 137 printRegisterList(MI, 4, O); 138 printAnnotation(O, Annot); 139 return; 140 } 141 if (Opcode == ARM::LDR_POST_IMM && MI->getOperand(2).getReg() == ARM::SP && 142 MI->getOperand(4).getImm() == 4) { 143 O << '\t' << "pop"; 144 printPredicateOperand(MI, 5, O); 145 O << "\t{" << getRegisterName(MI->getOperand(0).getReg()) << "}"; 146 printAnnotation(O, Annot); 147 return; 148 } 149 150 151 // A8.6.355 VPUSH 152 if ((Opcode == ARM::VSTMSDB_UPD || Opcode == ARM::VSTMDDB_UPD) && 153 MI->getOperand(0).getReg() == ARM::SP) { 154 O << '\t' << "vpush"; 155 printPredicateOperand(MI, 2, O); 156 O << '\t'; 157 printRegisterList(MI, 4, O); 158 printAnnotation(O, Annot); 159 return; 160 } 161 162 // A8.6.354 VPOP 163 if ((Opcode == ARM::VLDMSIA_UPD || Opcode == ARM::VLDMDIA_UPD) && 164 MI->getOperand(0).getReg() == ARM::SP) { 165 O << '\t' << "vpop"; 166 printPredicateOperand(MI, 2, O); 167 O << '\t'; 168 printRegisterList(MI, 4, O); 169 printAnnotation(O, Annot); 170 return; 171 } 172 173 if (Opcode == ARM::tLDMIA) { 174 bool Writeback = true; 175 unsigned BaseReg = MI->getOperand(0).getReg(); 176 for (unsigned i = 3; i < MI->getNumOperands(); ++i) { 177 if (MI->getOperand(i).getReg() == BaseReg) 178 Writeback = false; 179 } 180 181 O << "\tldm"; 182 183 printPredicateOperand(MI, 1, O); 184 O << '\t' << getRegisterName(BaseReg); 185 if (Writeback) O << "!"; 186 O << ", "; 187 printRegisterList(MI, 3, O); 188 printAnnotation(O, Annot); 189 return; 190 } 191 192 // Thumb1 NOP 193 if (Opcode == ARM::tMOVr && MI->getOperand(0).getReg() == ARM::R8 && 194 MI->getOperand(1).getReg() == ARM::R8) { 195 O << "\tnop"; 196 printPredicateOperand(MI, 2, O); 197 printAnnotation(O, Annot); 198 return; 199 } 200 201 printInstruction(MI, O); 202 printAnnotation(O, Annot); 203} 204 205void ARMInstPrinter::printOperand(const MCInst *MI, unsigned OpNo, 206 raw_ostream &O) { 207 const MCOperand &Op = MI->getOperand(OpNo); 208 if (Op.isReg()) { 209 unsigned Reg = Op.getReg(); 210 O << getRegisterName(Reg); 211 } else if (Op.isImm()) { 212 O << '#' << Op.getImm(); 213 } else { 214 assert(Op.isExpr() && "unknown operand kind in printOperand"); 215 // If a symbolic branch target was added as a constant expression then print 216 // that address in hex. 217 const MCConstantExpr *BranchTarget = dyn_cast<MCConstantExpr>(Op.getExpr()); 218 int64_t Address; 219 if (BranchTarget && BranchTarget->EvaluateAsAbsolute(Address)) { 220 O << "0x"; 221 O.write_hex(Address); 222 } 223 else { 224 // Otherwise, just print the expression. 225 O << *Op.getExpr(); 226 } 227 } 228} 229 230void ARMInstPrinter::printT2LdrLabelOperand(const MCInst *MI, unsigned OpNum, 231 raw_ostream &O) { 232 const MCOperand &MO1 = MI->getOperand(OpNum); 233 if (MO1.isExpr()) 234 O << *MO1.getExpr(); 235 else if (MO1.isImm()) 236 O << "[pc, #" << MO1.getImm() << "]"; 237 else 238 llvm_unreachable("Unknown LDR label operand?"); 239} 240 241// so_reg is a 4-operand unit corresponding to register forms of the A5.1 242// "Addressing Mode 1 - Data-processing operands" forms. This includes: 243// REG 0 0 - e.g. R5 244// REG REG 0,SH_OPC - e.g. R5, ROR R3 245// REG 0 IMM,SH_OPC - e.g. R5, LSL #3 246void ARMInstPrinter::printSORegRegOperand(const MCInst *MI, unsigned OpNum, 247 raw_ostream &O) { 248 const MCOperand &MO1 = MI->getOperand(OpNum); 249 const MCOperand &MO2 = MI->getOperand(OpNum+1); 250 const MCOperand &MO3 = MI->getOperand(OpNum+2); 251 252 O << getRegisterName(MO1.getReg()); 253 254 // Print the shift opc. 255 ARM_AM::ShiftOpc ShOpc = ARM_AM::getSORegShOp(MO3.getImm()); 256 O << ", " << ARM_AM::getShiftOpcStr(ShOpc); 257 if (ShOpc == ARM_AM::rrx) 258 return; 259 260 O << ' ' << getRegisterName(MO2.getReg()); 261 assert(ARM_AM::getSORegOffset(MO3.getImm()) == 0); 262} 263 264void ARMInstPrinter::printSORegImmOperand(const MCInst *MI, unsigned OpNum, 265 raw_ostream &O) { 266 const MCOperand &MO1 = MI->getOperand(OpNum); 267 const MCOperand &MO2 = MI->getOperand(OpNum+1); 268 269 O << getRegisterName(MO1.getReg()); 270 271 // Print the shift opc. 272 ARM_AM::ShiftOpc ShOpc = ARM_AM::getSORegShOp(MO2.getImm()); 273 O << ", " << ARM_AM::getShiftOpcStr(ShOpc); 274 if (ShOpc == ARM_AM::rrx) 275 return; 276 O << " #" << translateShiftImm(ARM_AM::getSORegOffset(MO2.getImm())); 277} 278 279 280//===--------------------------------------------------------------------===// 281// Addressing Mode #2 282//===--------------------------------------------------------------------===// 283 284void ARMInstPrinter::printAM2PreOrOffsetIndexOp(const MCInst *MI, unsigned Op, 285 raw_ostream &O) { 286 const MCOperand &MO1 = MI->getOperand(Op); 287 const MCOperand &MO2 = MI->getOperand(Op+1); 288 const MCOperand &MO3 = MI->getOperand(Op+2); 289 290 O << "[" << getRegisterName(MO1.getReg()); 291 292 if (!MO2.getReg()) { 293 if (ARM_AM::getAM2Offset(MO3.getImm())) // Don't print +0. 294 O << ", #" 295 << ARM_AM::getAddrOpcStr(ARM_AM::getAM2Op(MO3.getImm())) 296 << ARM_AM::getAM2Offset(MO3.getImm()); 297 O << "]"; 298 return; 299 } 300 301 O << ", " 302 << ARM_AM::getAddrOpcStr(ARM_AM::getAM2Op(MO3.getImm())) 303 << getRegisterName(MO2.getReg()); 304 305 if (unsigned ShImm = ARM_AM::getAM2Offset(MO3.getImm())) 306 O << ", " 307 << ARM_AM::getShiftOpcStr(ARM_AM::getAM2ShiftOpc(MO3.getImm())) 308 << " #" << ShImm; 309 O << "]"; 310} 311 312void ARMInstPrinter::printAM2PostIndexOp(const MCInst *MI, unsigned Op, 313 raw_ostream &O) { 314 const MCOperand &MO1 = MI->getOperand(Op); 315 const MCOperand &MO2 = MI->getOperand(Op+1); 316 const MCOperand &MO3 = MI->getOperand(Op+2); 317 318 O << "[" << getRegisterName(MO1.getReg()) << "], "; 319 320 if (!MO2.getReg()) { 321 unsigned ImmOffs = ARM_AM::getAM2Offset(MO3.getImm()); 322 O << '#' 323 << ARM_AM::getAddrOpcStr(ARM_AM::getAM2Op(MO3.getImm())) 324 << ImmOffs; 325 return; 326 } 327 328 O << ARM_AM::getAddrOpcStr(ARM_AM::getAM2Op(MO3.getImm())) 329 << getRegisterName(MO2.getReg()); 330 331 if (unsigned ShImm = ARM_AM::getAM2Offset(MO3.getImm())) 332 O << ", " 333 << ARM_AM::getShiftOpcStr(ARM_AM::getAM2ShiftOpc(MO3.getImm())) 334 << " #" << ShImm; 335} 336 337void ARMInstPrinter::printAddrModeTBB(const MCInst *MI, unsigned Op, 338 raw_ostream &O) { 339 const MCOperand &MO1 = MI->getOperand(Op); 340 const MCOperand &MO2 = MI->getOperand(Op+1); 341 O << "[" << getRegisterName(MO1.getReg()) << ", " 342 << getRegisterName(MO2.getReg()) << "]"; 343} 344 345void ARMInstPrinter::printAddrModeTBH(const MCInst *MI, unsigned Op, 346 raw_ostream &O) { 347 const MCOperand &MO1 = MI->getOperand(Op); 348 const MCOperand &MO2 = MI->getOperand(Op+1); 349 O << "[" << getRegisterName(MO1.getReg()) << ", " 350 << getRegisterName(MO2.getReg()) << ", lsl #1]"; 351} 352 353void ARMInstPrinter::printAddrMode2Operand(const MCInst *MI, unsigned Op, 354 raw_ostream &O) { 355 const MCOperand &MO1 = MI->getOperand(Op); 356 357 if (!MO1.isReg()) { // FIXME: This is for CP entries, but isn't right. 358 printOperand(MI, Op, O); 359 return; 360 } 361 362 const MCOperand &MO3 = MI->getOperand(Op+2); 363 unsigned IdxMode = ARM_AM::getAM2IdxMode(MO3.getImm()); 364 365 if (IdxMode == ARMII::IndexModePost) { 366 printAM2PostIndexOp(MI, Op, O); 367 return; 368 } 369 printAM2PreOrOffsetIndexOp(MI, Op, O); 370} 371 372void ARMInstPrinter::printAddrMode2OffsetOperand(const MCInst *MI, 373 unsigned OpNum, 374 raw_ostream &O) { 375 const MCOperand &MO1 = MI->getOperand(OpNum); 376 const MCOperand &MO2 = MI->getOperand(OpNum+1); 377 378 if (!MO1.getReg()) { 379 unsigned ImmOffs = ARM_AM::getAM2Offset(MO2.getImm()); 380 O << '#' 381 << ARM_AM::getAddrOpcStr(ARM_AM::getAM2Op(MO2.getImm())) 382 << ImmOffs; 383 return; 384 } 385 386 O << ARM_AM::getAddrOpcStr(ARM_AM::getAM2Op(MO2.getImm())) 387 << getRegisterName(MO1.getReg()); 388 389 if (unsigned ShImm = ARM_AM::getAM2Offset(MO2.getImm())) 390 O << ", " 391 << ARM_AM::getShiftOpcStr(ARM_AM::getAM2ShiftOpc(MO2.getImm())) 392 << " #" << ShImm; 393} 394 395//===--------------------------------------------------------------------===// 396// Addressing Mode #3 397//===--------------------------------------------------------------------===// 398 399void ARMInstPrinter::printAM3PostIndexOp(const MCInst *MI, unsigned Op, 400 raw_ostream &O) { 401 const MCOperand &MO1 = MI->getOperand(Op); 402 const MCOperand &MO2 = MI->getOperand(Op+1); 403 const MCOperand &MO3 = MI->getOperand(Op+2); 404 405 O << "[" << getRegisterName(MO1.getReg()) << "], "; 406 407 if (MO2.getReg()) { 408 O << (char)ARM_AM::getAM3Op(MO3.getImm()) 409 << getRegisterName(MO2.getReg()); 410 return; 411 } 412 413 unsigned ImmOffs = ARM_AM::getAM3Offset(MO3.getImm()); 414 O << '#' 415 << ARM_AM::getAddrOpcStr(ARM_AM::getAM3Op(MO3.getImm())) 416 << ImmOffs; 417} 418 419void ARMInstPrinter::printAM3PreOrOffsetIndexOp(const MCInst *MI, unsigned Op, 420 raw_ostream &O) { 421 const MCOperand &MO1 = MI->getOperand(Op); 422 const MCOperand &MO2 = MI->getOperand(Op+1); 423 const MCOperand &MO3 = MI->getOperand(Op+2); 424 425 O << '[' << getRegisterName(MO1.getReg()); 426 427 if (MO2.getReg()) { 428 O << ", " << getAddrOpcStr(ARM_AM::getAM3Op(MO3.getImm())) 429 << getRegisterName(MO2.getReg()) << ']'; 430 return; 431 } 432 433 if (unsigned ImmOffs = ARM_AM::getAM3Offset(MO3.getImm())) 434 O << ", #" 435 << ARM_AM::getAddrOpcStr(ARM_AM::getAM3Op(MO3.getImm())) 436 << ImmOffs; 437 O << ']'; 438} 439 440void ARMInstPrinter::printAddrMode3Operand(const MCInst *MI, unsigned Op, 441 raw_ostream &O) { 442 const MCOperand &MO1 = MI->getOperand(Op); 443 if (!MO1.isReg()) { // For label symbolic references. 444 printOperand(MI, Op, O); 445 return; 446 } 447 448 const MCOperand &MO3 = MI->getOperand(Op+2); 449 unsigned IdxMode = ARM_AM::getAM3IdxMode(MO3.getImm()); 450 451 if (IdxMode == ARMII::IndexModePost) { 452 printAM3PostIndexOp(MI, Op, O); 453 return; 454 } 455 printAM3PreOrOffsetIndexOp(MI, Op, O); 456} 457 458void ARMInstPrinter::printAddrMode3OffsetOperand(const MCInst *MI, 459 unsigned OpNum, 460 raw_ostream &O) { 461 const MCOperand &MO1 = MI->getOperand(OpNum); 462 const MCOperand &MO2 = MI->getOperand(OpNum+1); 463 464 if (MO1.getReg()) { 465 O << getAddrOpcStr(ARM_AM::getAM3Op(MO2.getImm())) 466 << getRegisterName(MO1.getReg()); 467 return; 468 } 469 470 unsigned ImmOffs = ARM_AM::getAM3Offset(MO2.getImm()); 471 O << '#' 472 << ARM_AM::getAddrOpcStr(ARM_AM::getAM3Op(MO2.getImm())) 473 << ImmOffs; 474} 475 476void ARMInstPrinter::printPostIdxImm8Operand(const MCInst *MI, 477 unsigned OpNum, 478 raw_ostream &O) { 479 const MCOperand &MO = MI->getOperand(OpNum); 480 unsigned Imm = MO.getImm(); 481 O << '#' << ((Imm & 256) ? "" : "-") << (Imm & 0xff); 482} 483 484void ARMInstPrinter::printPostIdxRegOperand(const MCInst *MI, unsigned OpNum, 485 raw_ostream &O) { 486 const MCOperand &MO1 = MI->getOperand(OpNum); 487 const MCOperand &MO2 = MI->getOperand(OpNum+1); 488 489 O << (MO2.getImm() ? "" : "-") << getRegisterName(MO1.getReg()); 490} 491 492void ARMInstPrinter::printPostIdxImm8s4Operand(const MCInst *MI, 493 unsigned OpNum, 494 raw_ostream &O) { 495 const MCOperand &MO = MI->getOperand(OpNum); 496 unsigned Imm = MO.getImm(); 497 O << '#' << ((Imm & 256) ? "" : "-") << ((Imm & 0xff) << 2); 498} 499 500 501void ARMInstPrinter::printLdStmModeOperand(const MCInst *MI, unsigned OpNum, 502 raw_ostream &O) { 503 ARM_AM::AMSubMode Mode = ARM_AM::getAM4SubMode(MI->getOperand(OpNum) 504 .getImm()); 505 O << ARM_AM::getAMSubModeStr(Mode); 506} 507 508void ARMInstPrinter::printAddrMode5Operand(const MCInst *MI, unsigned OpNum, 509 raw_ostream &O) { 510 const MCOperand &MO1 = MI->getOperand(OpNum); 511 const MCOperand &MO2 = MI->getOperand(OpNum+1); 512 513 if (!MO1.isReg()) { // FIXME: This is for CP entries, but isn't right. 514 printOperand(MI, OpNum, O); 515 return; 516 } 517 518 O << "[" << getRegisterName(MO1.getReg()); 519 520 unsigned ImmOffs = ARM_AM::getAM5Offset(MO2.getImm()); 521 unsigned Op = ARM_AM::getAM5Op(MO2.getImm()); 522 if (ImmOffs || Op == ARM_AM::sub) { 523 O << ", #" 524 << ARM_AM::getAddrOpcStr(ARM_AM::getAM5Op(MO2.getImm())) 525 << ImmOffs * 4; 526 } 527 O << "]"; 528} 529 530void ARMInstPrinter::printAddrMode6Operand(const MCInst *MI, unsigned OpNum, 531 raw_ostream &O) { 532 const MCOperand &MO1 = MI->getOperand(OpNum); 533 const MCOperand &MO2 = MI->getOperand(OpNum+1); 534 535 O << "[" << getRegisterName(MO1.getReg()); 536 if (MO2.getImm()) { 537 // FIXME: Both darwin as and GNU as violate ARM docs here. 538 O << ", :" << (MO2.getImm() << 3); 539 } 540 O << "]"; 541} 542 543void ARMInstPrinter::printAddrMode7Operand(const MCInst *MI, unsigned OpNum, 544 raw_ostream &O) { 545 const MCOperand &MO1 = MI->getOperand(OpNum); 546 O << "[" << getRegisterName(MO1.getReg()) << "]"; 547} 548 549void ARMInstPrinter::printAddrMode6OffsetOperand(const MCInst *MI, 550 unsigned OpNum, 551 raw_ostream &O) { 552 const MCOperand &MO = MI->getOperand(OpNum); 553 if (MO.getReg() == 0) 554 O << "!"; 555 else 556 O << ", " << getRegisterName(MO.getReg()); 557} 558 559void ARMInstPrinter::printBitfieldInvMaskImmOperand(const MCInst *MI, 560 unsigned OpNum, 561 raw_ostream &O) { 562 const MCOperand &MO = MI->getOperand(OpNum); 563 uint32_t v = ~MO.getImm(); 564 int32_t lsb = CountTrailingZeros_32(v); 565 int32_t width = (32 - CountLeadingZeros_32 (v)) - lsb; 566 assert(MO.isImm() && "Not a valid bf_inv_mask_imm value!"); 567 O << '#' << lsb << ", #" << width; 568} 569 570void ARMInstPrinter::printMemBOption(const MCInst *MI, unsigned OpNum, 571 raw_ostream &O) { 572 unsigned val = MI->getOperand(OpNum).getImm(); 573 O << ARM_MB::MemBOptToString(val); 574} 575 576void ARMInstPrinter::printShiftImmOperand(const MCInst *MI, unsigned OpNum, 577 raw_ostream &O) { 578 unsigned ShiftOp = MI->getOperand(OpNum).getImm(); 579 bool isASR = (ShiftOp & (1 << 5)) != 0; 580 unsigned Amt = ShiftOp & 0x1f; 581 if (isASR) 582 O << ", asr #" << (Amt == 0 ? 32 : Amt); 583 else if (Amt) 584 O << ", lsl #" << Amt; 585} 586 587void ARMInstPrinter::printPKHLSLShiftImm(const MCInst *MI, unsigned OpNum, 588 raw_ostream &O) { 589 unsigned Imm = MI->getOperand(OpNum).getImm(); 590 if (Imm == 0) 591 return; 592 assert(Imm > 0 && Imm < 32 && "Invalid PKH shift immediate value!"); 593 O << ", lsl #" << Imm; 594} 595 596void ARMInstPrinter::printPKHASRShiftImm(const MCInst *MI, unsigned OpNum, 597 raw_ostream &O) { 598 unsigned Imm = MI->getOperand(OpNum).getImm(); 599 // A shift amount of 32 is encoded as 0. 600 if (Imm == 0) 601 Imm = 32; 602 assert(Imm > 0 && Imm <= 32 && "Invalid PKH shift immediate value!"); 603 O << ", asr #" << Imm; 604} 605 606void ARMInstPrinter::printRegisterList(const MCInst *MI, unsigned OpNum, 607 raw_ostream &O) { 608 O << "{"; 609 for (unsigned i = OpNum, e = MI->getNumOperands(); i != e; ++i) { 610 if (i != OpNum) O << ", "; 611 O << getRegisterName(MI->getOperand(i).getReg()); 612 } 613 O << "}"; 614} 615 616void ARMInstPrinter::printSetendOperand(const MCInst *MI, unsigned OpNum, 617 raw_ostream &O) { 618 const MCOperand &Op = MI->getOperand(OpNum); 619 if (Op.getImm()) 620 O << "be"; 621 else 622 O << "le"; 623} 624 625void ARMInstPrinter::printCPSIMod(const MCInst *MI, unsigned OpNum, 626 raw_ostream &O) { 627 const MCOperand &Op = MI->getOperand(OpNum); 628 O << ARM_PROC::IModToString(Op.getImm()); 629} 630 631void ARMInstPrinter::printCPSIFlag(const MCInst *MI, unsigned OpNum, 632 raw_ostream &O) { 633 const MCOperand &Op = MI->getOperand(OpNum); 634 unsigned IFlags = Op.getImm(); 635 for (int i=2; i >= 0; --i) 636 if (IFlags & (1 << i)) 637 O << ARM_PROC::IFlagsToString(1 << i); 638 639 if (IFlags == 0) 640 O << "none"; 641} 642 643void ARMInstPrinter::printMSRMaskOperand(const MCInst *MI, unsigned OpNum, 644 raw_ostream &O) { 645 const MCOperand &Op = MI->getOperand(OpNum); 646 unsigned SpecRegRBit = Op.getImm() >> 4; 647 unsigned Mask = Op.getImm() & 0xf; 648 649 if (getAvailableFeatures() & ARM::FeatureMClass) { 650 switch (Op.getImm()) { 651 default: llvm_unreachable("Unexpected mask value!"); 652 case 0: O << "apsr"; return; 653 case 1: O << "iapsr"; return; 654 case 2: O << "eapsr"; return; 655 case 3: O << "xpsr"; return; 656 case 5: O << "ipsr"; return; 657 case 6: O << "epsr"; return; 658 case 7: O << "iepsr"; return; 659 case 8: O << "msp"; return; 660 case 9: O << "psp"; return; 661 case 16: O << "primask"; return; 662 case 17: O << "basepri"; return; 663 case 18: O << "basepri_max"; return; 664 case 19: O << "faultmask"; return; 665 case 20: O << "control"; return; 666 } 667 } 668 669 // As special cases, CPSR_f, CPSR_s and CPSR_fs prefer printing as 670 // APSR_nzcvq, APSR_g and APSRnzcvqg, respectively. 671 if (!SpecRegRBit && (Mask == 8 || Mask == 4 || Mask == 12)) { 672 O << "APSR_"; 673 switch (Mask) { 674 default: llvm_unreachable("Unexpected mask value!"); 675 case 4: O << "g"; return; 676 case 8: O << "nzcvq"; return; 677 case 12: O << "nzcvqg"; return; 678 } 679 } 680 681 if (SpecRegRBit) 682 O << "SPSR"; 683 else 684 O << "CPSR"; 685 686 if (Mask) { 687 O << '_'; 688 if (Mask & 8) O << 'f'; 689 if (Mask & 4) O << 's'; 690 if (Mask & 2) O << 'x'; 691 if (Mask & 1) O << 'c'; 692 } 693} 694 695void ARMInstPrinter::printPredicateOperand(const MCInst *MI, unsigned OpNum, 696 raw_ostream &O) { 697 ARMCC::CondCodes CC = (ARMCC::CondCodes)MI->getOperand(OpNum).getImm(); 698 // Handle the undefined 15 CC value here for printing so we don't abort(). 699 if ((unsigned)CC == 15) 700 O << "<und>"; 701 else if (CC != ARMCC::AL) 702 O << ARMCondCodeToString(CC); 703} 704 705void ARMInstPrinter::printMandatoryPredicateOperand(const MCInst *MI, 706 unsigned OpNum, 707 raw_ostream &O) { 708 ARMCC::CondCodes CC = (ARMCC::CondCodes)MI->getOperand(OpNum).getImm(); 709 O << ARMCondCodeToString(CC); 710} 711 712void ARMInstPrinter::printSBitModifierOperand(const MCInst *MI, unsigned OpNum, 713 raw_ostream &O) { 714 if (MI->getOperand(OpNum).getReg()) { 715 assert(MI->getOperand(OpNum).getReg() == ARM::CPSR && 716 "Expect ARM CPSR register!"); 717 O << 's'; 718 } 719} 720 721void ARMInstPrinter::printNoHashImmediate(const MCInst *MI, unsigned OpNum, 722 raw_ostream &O) { 723 O << MI->getOperand(OpNum).getImm(); 724} 725 726void ARMInstPrinter::printPImmediate(const MCInst *MI, unsigned OpNum, 727 raw_ostream &O) { 728 O << "p" << MI->getOperand(OpNum).getImm(); 729} 730 731void ARMInstPrinter::printCImmediate(const MCInst *MI, unsigned OpNum, 732 raw_ostream &O) { 733 O << "c" << MI->getOperand(OpNum).getImm(); 734} 735 736void ARMInstPrinter::printCoprocOptionImm(const MCInst *MI, unsigned OpNum, 737 raw_ostream &O) { 738 O << "{" << MI->getOperand(OpNum).getImm() << "}"; 739} 740 741void ARMInstPrinter::printPCLabel(const MCInst *MI, unsigned OpNum, 742 raw_ostream &O) { 743 llvm_unreachable("Unhandled PC-relative pseudo-instruction!"); 744} 745 746void ARMInstPrinter::printThumbS4ImmOperand(const MCInst *MI, unsigned OpNum, 747 raw_ostream &O) { 748 O << "#" << MI->getOperand(OpNum).getImm() * 4; 749} 750 751void ARMInstPrinter::printThumbSRImm(const MCInst *MI, unsigned OpNum, 752 raw_ostream &O) { 753 unsigned Imm = MI->getOperand(OpNum).getImm(); 754 O << "#" << (Imm == 0 ? 32 : Imm); 755} 756 757void ARMInstPrinter::printThumbITMask(const MCInst *MI, unsigned OpNum, 758 raw_ostream &O) { 759 // (3 - the number of trailing zeros) is the number of then / else. 760 unsigned Mask = MI->getOperand(OpNum).getImm(); 761 unsigned CondBit0 = Mask >> 4 & 1; 762 unsigned NumTZ = CountTrailingZeros_32(Mask); 763 assert(NumTZ <= 3 && "Invalid IT mask!"); 764 for (unsigned Pos = 3, e = NumTZ; Pos > e; --Pos) { 765 bool T = ((Mask >> Pos) & 1) == CondBit0; 766 if (T) 767 O << 't'; 768 else 769 O << 'e'; 770 } 771} 772 773void ARMInstPrinter::printThumbAddrModeRROperand(const MCInst *MI, unsigned Op, 774 raw_ostream &O) { 775 const MCOperand &MO1 = MI->getOperand(Op); 776 const MCOperand &MO2 = MI->getOperand(Op + 1); 777 778 if (!MO1.isReg()) { // FIXME: This is for CP entries, but isn't right. 779 printOperand(MI, Op, O); 780 return; 781 } 782 783 O << "[" << getRegisterName(MO1.getReg()); 784 if (unsigned RegNum = MO2.getReg()) 785 O << ", " << getRegisterName(RegNum); 786 O << "]"; 787} 788 789void ARMInstPrinter::printThumbAddrModeImm5SOperand(const MCInst *MI, 790 unsigned Op, 791 raw_ostream &O, 792 unsigned Scale) { 793 const MCOperand &MO1 = MI->getOperand(Op); 794 const MCOperand &MO2 = MI->getOperand(Op + 1); 795 796 if (!MO1.isReg()) { // FIXME: This is for CP entries, but isn't right. 797 printOperand(MI, Op, O); 798 return; 799 } 800 801 O << "[" << getRegisterName(MO1.getReg()); 802 if (unsigned ImmOffs = MO2.getImm()) 803 O << ", #" << ImmOffs * Scale; 804 O << "]"; 805} 806 807void ARMInstPrinter::printThumbAddrModeImm5S1Operand(const MCInst *MI, 808 unsigned Op, 809 raw_ostream &O) { 810 printThumbAddrModeImm5SOperand(MI, Op, O, 1); 811} 812 813void ARMInstPrinter::printThumbAddrModeImm5S2Operand(const MCInst *MI, 814 unsigned Op, 815 raw_ostream &O) { 816 printThumbAddrModeImm5SOperand(MI, Op, O, 2); 817} 818 819void ARMInstPrinter::printThumbAddrModeImm5S4Operand(const MCInst *MI, 820 unsigned Op, 821 raw_ostream &O) { 822 printThumbAddrModeImm5SOperand(MI, Op, O, 4); 823} 824 825void ARMInstPrinter::printThumbAddrModeSPOperand(const MCInst *MI, unsigned Op, 826 raw_ostream &O) { 827 printThumbAddrModeImm5SOperand(MI, Op, O, 4); 828} 829 830// Constant shifts t2_so_reg is a 2-operand unit corresponding to the Thumb2 831// register with shift forms. 832// REG 0 0 - e.g. R5 833// REG IMM, SH_OPC - e.g. R5, LSL #3 834void ARMInstPrinter::printT2SOOperand(const MCInst *MI, unsigned OpNum, 835 raw_ostream &O) { 836 const MCOperand &MO1 = MI->getOperand(OpNum); 837 const MCOperand &MO2 = MI->getOperand(OpNum+1); 838 839 unsigned Reg = MO1.getReg(); 840 O << getRegisterName(Reg); 841 842 // Print the shift opc. 843 assert(MO2.isImm() && "Not a valid t2_so_reg value!"); 844 ARM_AM::ShiftOpc ShOpc = ARM_AM::getSORegShOp(MO2.getImm()); 845 O << ", " << ARM_AM::getShiftOpcStr(ShOpc); 846 if (ShOpc != ARM_AM::rrx) 847 O << " #" << translateShiftImm(ARM_AM::getSORegOffset(MO2.getImm())); 848} 849 850void ARMInstPrinter::printAddrModeImm12Operand(const MCInst *MI, unsigned OpNum, 851 raw_ostream &O) { 852 const MCOperand &MO1 = MI->getOperand(OpNum); 853 const MCOperand &MO2 = MI->getOperand(OpNum+1); 854 855 if (!MO1.isReg()) { // FIXME: This is for CP entries, but isn't right. 856 printOperand(MI, OpNum, O); 857 return; 858 } 859 860 O << "[" << getRegisterName(MO1.getReg()); 861 862 int32_t OffImm = (int32_t)MO2.getImm(); 863 bool isSub = OffImm < 0; 864 // Special value for #-0. All others are normal. 865 if (OffImm == INT32_MIN) 866 OffImm = 0; 867 if (isSub) 868 O << ", #-" << -OffImm; 869 else if (OffImm > 0) 870 O << ", #" << OffImm; 871 O << "]"; 872} 873 874void ARMInstPrinter::printT2AddrModeImm8Operand(const MCInst *MI, 875 unsigned OpNum, 876 raw_ostream &O) { 877 const MCOperand &MO1 = MI->getOperand(OpNum); 878 const MCOperand &MO2 = MI->getOperand(OpNum+1); 879 880 O << "[" << getRegisterName(MO1.getReg()); 881 882 int32_t OffImm = (int32_t)MO2.getImm(); 883 // Don't print +0. 884 if (OffImm == INT32_MIN) 885 O << ", #-0"; 886 else if (OffImm < 0) 887 O << ", #-" << -OffImm; 888 else if (OffImm > 0) 889 O << ", #" << OffImm; 890 O << "]"; 891} 892 893void ARMInstPrinter::printT2AddrModeImm8s4Operand(const MCInst *MI, 894 unsigned OpNum, 895 raw_ostream &O) { 896 const MCOperand &MO1 = MI->getOperand(OpNum); 897 const MCOperand &MO2 = MI->getOperand(OpNum+1); 898 899 if (!MO1.isReg()) { // For label symbolic references. 900 printOperand(MI, OpNum, O); 901 return; 902 } 903 904 O << "[" << getRegisterName(MO1.getReg()); 905 906 int32_t OffImm = (int32_t)MO2.getImm() / 4; 907 // Don't print +0. 908 if (OffImm < 0) 909 O << ", #-" << -OffImm * 4; 910 else if (OffImm > 0) 911 O << ", #" << OffImm * 4; 912 O << "]"; 913} 914 915void ARMInstPrinter::printT2AddrModeImm0_1020s4Operand(const MCInst *MI, 916 unsigned OpNum, 917 raw_ostream &O) { 918 const MCOperand &MO1 = MI->getOperand(OpNum); 919 const MCOperand &MO2 = MI->getOperand(OpNum+1); 920 921 O << "[" << getRegisterName(MO1.getReg()); 922 if (MO2.getImm()) 923 O << ", #" << MO2.getImm() * 4; 924 O << "]"; 925} 926 927void ARMInstPrinter::printT2AddrModeImm8OffsetOperand(const MCInst *MI, 928 unsigned OpNum, 929 raw_ostream &O) { 930 const MCOperand &MO1 = MI->getOperand(OpNum); 931 int32_t OffImm = (int32_t)MO1.getImm(); 932 // Don't print +0. 933 if (OffImm < 0) 934 O << ", #-" << -OffImm; 935 else 936 O << ", #" << OffImm; 937} 938 939void ARMInstPrinter::printT2AddrModeImm8s4OffsetOperand(const MCInst *MI, 940 unsigned OpNum, 941 raw_ostream &O) { 942 const MCOperand &MO1 = MI->getOperand(OpNum); 943 int32_t OffImm = (int32_t)MO1.getImm() / 4; 944 // Don't print +0. 945 if (OffImm != 0) { 946 O << ", "; 947 if (OffImm < 0) 948 O << "#-" << -OffImm * 4; 949 else if (OffImm > 0) 950 O << "#" << OffImm * 4; 951 } 952} 953 954void ARMInstPrinter::printT2AddrModeSoRegOperand(const MCInst *MI, 955 unsigned OpNum, 956 raw_ostream &O) { 957 const MCOperand &MO1 = MI->getOperand(OpNum); 958 const MCOperand &MO2 = MI->getOperand(OpNum+1); 959 const MCOperand &MO3 = MI->getOperand(OpNum+2); 960 961 O << "[" << getRegisterName(MO1.getReg()); 962 963 assert(MO2.getReg() && "Invalid so_reg load / store address!"); 964 O << ", " << getRegisterName(MO2.getReg()); 965 966 unsigned ShAmt = MO3.getImm(); 967 if (ShAmt) { 968 assert(ShAmt <= 3 && "Not a valid Thumb2 addressing mode!"); 969 O << ", lsl #" << ShAmt; 970 } 971 O << "]"; 972} 973 974void ARMInstPrinter::printFPImmOperand(const MCInst *MI, unsigned OpNum, 975 raw_ostream &O) { 976 const MCOperand &MO = MI->getOperand(OpNum); 977 O << '#' << ARM_AM::getFPImmFloat(MO.getImm()); 978} 979 980void ARMInstPrinter::printNEONModImmOperand(const MCInst *MI, unsigned OpNum, 981 raw_ostream &O) { 982 unsigned EncodedImm = MI->getOperand(OpNum).getImm(); 983 unsigned EltBits; 984 uint64_t Val = ARM_AM::decodeNEONModImm(EncodedImm, EltBits); 985 O << "#0x"; 986 O.write_hex(Val); 987} 988 989void ARMInstPrinter::printImmPlusOneOperand(const MCInst *MI, unsigned OpNum, 990 raw_ostream &O) { 991 unsigned Imm = MI->getOperand(OpNum).getImm(); 992 O << "#" << Imm + 1; 993} 994 995void ARMInstPrinter::printRotImmOperand(const MCInst *MI, unsigned OpNum, 996 raw_ostream &O) { 997 unsigned Imm = MI->getOperand(OpNum).getImm(); 998 if (Imm == 0) 999 return; 1000 O << ", ror #"; 1001 switch (Imm) { 1002 default: assert (0 && "illegal ror immediate!"); 1003 case 1: O << "8"; break; 1004 case 2: O << "16"; break; 1005 case 3: O << "24"; break; 1006 } 1007} 1008 1009void ARMInstPrinter::printFBits16(const MCInst *MI, unsigned OpNum, 1010 raw_ostream &O) { 1011 O << "#" << 16 - MI->getOperand(OpNum).getImm(); 1012} 1013 1014void ARMInstPrinter::printFBits32(const MCInst *MI, unsigned OpNum, 1015 raw_ostream &O) { 1016 O << "#" << 32 - MI->getOperand(OpNum).getImm(); 1017} 1018 1019void ARMInstPrinter::printVectorIndex(const MCInst *MI, unsigned OpNum, 1020 raw_ostream &O) { 1021 O << "[" << MI->getOperand(OpNum).getImm() << "]"; 1022} 1023 1024void ARMInstPrinter::printVectorListOne(const MCInst *MI, unsigned OpNum, 1025 raw_ostream &O) { 1026 O << "{" << getRegisterName(MI->getOperand(OpNum).getReg()) << "}"; 1027} 1028 1029void ARMInstPrinter::printVectorListTwo(const MCInst *MI, unsigned OpNum, 1030 raw_ostream &O) { 1031 unsigned Reg = MI->getOperand(OpNum).getReg(); 1032 unsigned Reg0 = MRI.getSubReg(Reg, ARM::dsub_0); 1033 unsigned Reg1 = MRI.getSubReg(Reg, ARM::dsub_1); 1034 O << "{" << getRegisterName(Reg0) << ", " << getRegisterName(Reg1) << "}"; 1035} 1036 1037void ARMInstPrinter::printVectorListTwoSpaced(const MCInst *MI, 1038 unsigned OpNum, 1039 raw_ostream &O) { 1040 unsigned Reg = MI->getOperand(OpNum).getReg(); 1041 unsigned Reg0 = MRI.getSubReg(Reg, ARM::dsub_0); 1042 unsigned Reg1 = MRI.getSubReg(Reg, ARM::dsub_2); 1043 O << "{" << getRegisterName(Reg0) << ", " << getRegisterName(Reg1) << "}"; 1044} 1045 1046void ARMInstPrinter::printVectorListThree(const MCInst *MI, unsigned OpNum, 1047 raw_ostream &O) { 1048 // Normally, it's not safe to use register enum values directly with 1049 // addition to get the next register, but for VFP registers, the 1050 // sort order is guaranteed because they're all of the form D<n>. 1051 O << "{" << getRegisterName(MI->getOperand(OpNum).getReg()) << ", " 1052 << getRegisterName(MI->getOperand(OpNum).getReg() + 1) << ", " 1053 << getRegisterName(MI->getOperand(OpNum).getReg() + 2) << "}"; 1054} 1055 1056void ARMInstPrinter::printVectorListFour(const MCInst *MI, unsigned OpNum, 1057 raw_ostream &O) { 1058 // Normally, it's not safe to use register enum values directly with 1059 // addition to get the next register, but for VFP registers, the 1060 // sort order is guaranteed because they're all of the form D<n>. 1061 O << "{" << getRegisterName(MI->getOperand(OpNum).getReg()) << ", " 1062 << getRegisterName(MI->getOperand(OpNum).getReg() + 1) << ", " 1063 << getRegisterName(MI->getOperand(OpNum).getReg() + 2) << ", " 1064 << getRegisterName(MI->getOperand(OpNum).getReg() + 3) << "}"; 1065} 1066 1067void ARMInstPrinter::printVectorListOneAllLanes(const MCInst *MI, 1068 unsigned OpNum, 1069 raw_ostream &O) { 1070 O << "{" << getRegisterName(MI->getOperand(OpNum).getReg()) << "[]}"; 1071} 1072 1073void ARMInstPrinter::printVectorListTwoAllLanes(const MCInst *MI, 1074 unsigned OpNum, 1075 raw_ostream &O) { 1076 unsigned Reg = MI->getOperand(OpNum).getReg(); 1077 unsigned Reg0 = MRI.getSubReg(Reg, ARM::dsub_0); 1078 unsigned Reg1 = MRI.getSubReg(Reg, ARM::dsub_1); 1079 O << "{" << getRegisterName(Reg0) << "[], " << getRegisterName(Reg1) << "[]}"; 1080} 1081 1082void ARMInstPrinter::printVectorListThreeAllLanes(const MCInst *MI, 1083 unsigned OpNum, 1084 raw_ostream &O) { 1085 // Normally, it's not safe to use register enum values directly with 1086 // addition to get the next register, but for VFP registers, the 1087 // sort order is guaranteed because they're all of the form D<n>. 1088 O << "{" << getRegisterName(MI->getOperand(OpNum).getReg()) << "[], " 1089 << getRegisterName(MI->getOperand(OpNum).getReg() + 1) << "[], " 1090 << getRegisterName(MI->getOperand(OpNum).getReg() + 2) << "[]}"; 1091} 1092 1093void ARMInstPrinter::printVectorListFourAllLanes(const MCInst *MI, 1094 unsigned OpNum, 1095 raw_ostream &O) { 1096 // Normally, it's not safe to use register enum values directly with 1097 // addition to get the next register, but for VFP registers, the 1098 // sort order is guaranteed because they're all of the form D<n>. 1099 O << "{" << getRegisterName(MI->getOperand(OpNum).getReg()) << "[], " 1100 << getRegisterName(MI->getOperand(OpNum).getReg() + 1) << "[], " 1101 << getRegisterName(MI->getOperand(OpNum).getReg() + 2) << "[], " 1102 << getRegisterName(MI->getOperand(OpNum).getReg() + 3) << "[]}"; 1103} 1104 1105void ARMInstPrinter::printVectorListTwoSpacedAllLanes(const MCInst *MI, 1106 unsigned OpNum, 1107 raw_ostream &O) { 1108 unsigned Reg = MI->getOperand(OpNum).getReg(); 1109 unsigned Reg0 = MRI.getSubReg(Reg, ARM::dsub_0); 1110 unsigned Reg1 = MRI.getSubReg(Reg, ARM::dsub_2); 1111 O << "{" << getRegisterName(Reg0) << "[], " << getRegisterName(Reg1) << "[]}"; 1112} 1113 1114void ARMInstPrinter::printVectorListThreeSpacedAllLanes(const MCInst *MI, 1115 unsigned OpNum, 1116 raw_ostream &O) { 1117 // Normally, it's not safe to use register enum values directly with 1118 // addition to get the next register, but for VFP registers, the 1119 // sort order is guaranteed because they're all of the form D<n>. 1120 O << "{" << getRegisterName(MI->getOperand(OpNum).getReg()) << "[], " 1121 << getRegisterName(MI->getOperand(OpNum).getReg() + 2) << "[], " 1122 << getRegisterName(MI->getOperand(OpNum).getReg() + 4) << "[]}"; 1123} 1124 1125void ARMInstPrinter::printVectorListFourSpacedAllLanes(const MCInst *MI, 1126 unsigned OpNum, 1127 raw_ostream &O) { 1128 // Normally, it's not safe to use register enum values directly with 1129 // addition to get the next register, but for VFP registers, the 1130 // sort order is guaranteed because they're all of the form D<n>. 1131 O << "{" << getRegisterName(MI->getOperand(OpNum).getReg()) << "[], " 1132 << getRegisterName(MI->getOperand(OpNum).getReg() + 2) << "[], " 1133 << getRegisterName(MI->getOperand(OpNum).getReg() + 4) << "[], " 1134 << getRegisterName(MI->getOperand(OpNum).getReg() + 6) << "[]}"; 1135} 1136 1137void ARMInstPrinter::printVectorListThreeSpaced(const MCInst *MI, 1138 unsigned OpNum, 1139 raw_ostream &O) { 1140 // Normally, it's not safe to use register enum values directly with 1141 // addition to get the next register, but for VFP registers, the 1142 // sort order is guaranteed because they're all of the form D<n>. 1143 O << "{" << getRegisterName(MI->getOperand(OpNum).getReg()) << ", " 1144 << getRegisterName(MI->getOperand(OpNum).getReg() + 2) << ", " 1145 << getRegisterName(MI->getOperand(OpNum).getReg() + 4) << "}"; 1146} 1147 1148void ARMInstPrinter::printVectorListFourSpaced(const MCInst *MI, 1149 unsigned OpNum, 1150 raw_ostream &O) { 1151 // Normally, it's not safe to use register enum values directly with 1152 // addition to get the next register, but for VFP registers, the 1153 // sort order is guaranteed because they're all of the form D<n>. 1154 O << "{" << getRegisterName(MI->getOperand(OpNum).getReg()) << ", " 1155 << getRegisterName(MI->getOperand(OpNum).getReg() + 2) << ", " 1156 << getRegisterName(MI->getOperand(OpNum).getReg() + 4) << ", " 1157 << getRegisterName(MI->getOperand(OpNum).getReg() + 6) << "}"; 1158} 1159