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