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