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