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