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