ARMInstPrinter.cpp revision be74029f44c32efc09274a16cbff588ad10dc5ea
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/ADT/StringExtras.h" 22#include "llvm/Support/raw_ostream.h" 23using namespace llvm; 24 25#define GET_INSTRUCTION_NAME 26#include "ARMGenAsmWriter.inc" 27 28StringRef ARMInstPrinter::getOpcodeName(unsigned Opcode) const { 29 return getInstructionName(Opcode); 30} 31 32void ARMInstPrinter::printRegName(raw_ostream &OS, unsigned RegNo) const { 33 OS << getRegisterName(RegNo); 34} 35 36void ARMInstPrinter::printInst(const MCInst *MI, raw_ostream &O) { 37 unsigned Opcode = MI->getOpcode(); 38 39 // Check for MOVs and print canonical forms, instead. 40 if (Opcode == ARM::MOVsr) { 41 // FIXME: Thumb variants? 42 const MCOperand &Dst = MI->getOperand(0); 43 const MCOperand &MO1 = MI->getOperand(1); 44 const MCOperand &MO2 = MI->getOperand(2); 45 const MCOperand &MO3 = MI->getOperand(3); 46 47 O << '\t' << ARM_AM::getShiftOpcStr(ARM_AM::getSORegShOp(MO3.getImm())); 48 printSBitModifierOperand(MI, 6, O); 49 printPredicateOperand(MI, 4, O); 50 51 O << '\t' << getRegisterName(Dst.getReg()) 52 << ", " << getRegisterName(MO1.getReg()); 53 54 O << ", " << getRegisterName(MO2.getReg()); 55 assert(ARM_AM::getSORegOffset(MO3.getImm()) == 0); 56 return; 57 } 58 59 if (Opcode == ARM::MOVsi) { 60 // FIXME: Thumb variants? 61 const MCOperand &Dst = MI->getOperand(0); 62 const MCOperand &MO1 = MI->getOperand(1); 63 const MCOperand &MO2 = MI->getOperand(2); 64 65 O << '\t' << ARM_AM::getShiftOpcStr(ARM_AM::getSORegShOp(MO2.getImm())); 66 printSBitModifierOperand(MI, 5, O); 67 printPredicateOperand(MI, 3, O); 68 69 O << '\t' << getRegisterName(Dst.getReg()) 70 << ", " << getRegisterName(MO1.getReg()); 71 72 if (ARM_AM::getSORegShOp(MO2.getImm()) == ARM_AM::rrx) 73 return; 74 75 O << ", #" << ARM_AM::getSORegOffset(MO2.getImm()); 76 return; 77 } 78 79 80 // A8.6.123 PUSH 81 if ((Opcode == ARM::STMDB_UPD || Opcode == ARM::t2STMDB_UPD) && 82 MI->getOperand(0).getReg() == ARM::SP) { 83 O << '\t' << "push"; 84 printPredicateOperand(MI, 2, O); 85 if (Opcode == ARM::t2STMDB_UPD) 86 O << ".w"; 87 O << '\t'; 88 printRegisterList(MI, 4, O); 89 return; 90 } 91 92 // A8.6.122 POP 93 if ((Opcode == ARM::LDMIA_UPD || Opcode == ARM::t2LDMIA_UPD) && 94 MI->getOperand(0).getReg() == ARM::SP) { 95 O << '\t' << "pop"; 96 printPredicateOperand(MI, 2, O); 97 if (Opcode == ARM::t2LDMIA_UPD) 98 O << ".w"; 99 O << '\t'; 100 printRegisterList(MI, 4, O); 101 return; 102 } 103 104 // A8.6.355 VPUSH 105 if ((Opcode == ARM::VSTMSDB_UPD || Opcode == ARM::VSTMDDB_UPD) && 106 MI->getOperand(0).getReg() == ARM::SP) { 107 O << '\t' << "vpush"; 108 printPredicateOperand(MI, 2, O); 109 O << '\t'; 110 printRegisterList(MI, 4, O); 111 return; 112 } 113 114 // A8.6.354 VPOP 115 if ((Opcode == ARM::VLDMSIA_UPD || Opcode == ARM::VLDMDIA_UPD) && 116 MI->getOperand(0).getReg() == ARM::SP) { 117 O << '\t' << "vpop"; 118 printPredicateOperand(MI, 2, O); 119 O << '\t'; 120 printRegisterList(MI, 4, O); 121 return; 122 } 123 124 if (Opcode == ARM::tLDMIA || Opcode == ARM::tSTMIA) { 125 bool Writeback = true; 126 unsigned BaseReg = MI->getOperand(0).getReg(); 127 for (unsigned i = 3; i < MI->getNumOperands(); ++i) { 128 if (MI->getOperand(i).getReg() == BaseReg) 129 Writeback = false; 130 } 131 132 if (Opcode == ARM::tLDMIA) 133 O << "\tldmia"; 134 else if (Opcode == ARM::tSTMIA) 135 O << "\tstmia"; 136 else 137 llvm_unreachable("Unknown opcode!"); 138 139 printPredicateOperand(MI, 1, O); 140 O << '\t' << getRegisterName(BaseReg); 141 if (Writeback) O << "!"; 142 O << ", "; 143 printRegisterList(MI, 3, O); 144 return; 145 } 146 147 printInstruction(MI, O); 148} 149 150void ARMInstPrinter::printOperand(const MCInst *MI, unsigned OpNo, 151 raw_ostream &O) { 152 const MCOperand &Op = MI->getOperand(OpNo); 153 if (Op.isReg()) { 154 unsigned Reg = Op.getReg(); 155 O << getRegisterName(Reg); 156 } else if (Op.isImm()) { 157 O << '#' << Op.getImm(); 158 } else { 159 assert(Op.isExpr() && "unknown operand kind in printOperand"); 160 O << *Op.getExpr(); 161 } 162} 163 164// so_reg is a 4-operand unit corresponding to register forms of the A5.1 165// "Addressing Mode 1 - Data-processing operands" forms. This includes: 166// REG 0 0 - e.g. R5 167// REG REG 0,SH_OPC - e.g. R5, ROR R3 168// REG 0 IMM,SH_OPC - e.g. R5, LSL #3 169void ARMInstPrinter::printSORegRegOperand(const MCInst *MI, unsigned OpNum, 170 raw_ostream &O) { 171 const MCOperand &MO1 = MI->getOperand(OpNum); 172 const MCOperand &MO2 = MI->getOperand(OpNum+1); 173 const MCOperand &MO3 = MI->getOperand(OpNum+2); 174 175 O << getRegisterName(MO1.getReg()); 176 177 // Print the shift opc. 178 ARM_AM::ShiftOpc ShOpc = ARM_AM::getSORegShOp(MO3.getImm()); 179 O << ", " << ARM_AM::getShiftOpcStr(ShOpc); 180 if (ShOpc == ARM_AM::rrx) 181 return; 182 183 O << ' ' << getRegisterName(MO2.getReg()); 184 assert(ARM_AM::getSORegOffset(MO3.getImm()) == 0); 185} 186 187void ARMInstPrinter::printSORegImmOperand(const MCInst *MI, unsigned OpNum, 188 raw_ostream &O) { 189 const MCOperand &MO1 = MI->getOperand(OpNum); 190 const MCOperand &MO2 = MI->getOperand(OpNum+1); 191 192 O << getRegisterName(MO1.getReg()); 193 194 // Print the shift opc. 195 ARM_AM::ShiftOpc ShOpc = ARM_AM::getSORegShOp(MO2.getImm()); 196 O << ", " << ARM_AM::getShiftOpcStr(ShOpc); 197 if (ShOpc == ARM_AM::rrx) 198 return; 199 O << " #" << ARM_AM::getSORegOffset(MO2.getImm()); 200} 201 202 203//===--------------------------------------------------------------------===// 204// Addressing Mode #2 205//===--------------------------------------------------------------------===// 206 207void ARMInstPrinter::printAM2PreOrOffsetIndexOp(const MCInst *MI, unsigned Op, 208 raw_ostream &O) { 209 const MCOperand &MO1 = MI->getOperand(Op); 210 const MCOperand &MO2 = MI->getOperand(Op+1); 211 const MCOperand &MO3 = MI->getOperand(Op+2); 212 213 O << "[" << getRegisterName(MO1.getReg()); 214 215 if (!MO2.getReg()) { 216 if (ARM_AM::getAM2Offset(MO3.getImm())) // Don't print +0. 217 O << ", #" 218 << ARM_AM::getAddrOpcStr(ARM_AM::getAM2Op(MO3.getImm())) 219 << ARM_AM::getAM2Offset(MO3.getImm()); 220 O << "]"; 221 return; 222 } 223 224 O << ", " 225 << ARM_AM::getAddrOpcStr(ARM_AM::getAM2Op(MO3.getImm())) 226 << getRegisterName(MO2.getReg()); 227 228 if (unsigned ShImm = ARM_AM::getAM2Offset(MO3.getImm())) 229 O << ", " 230 << ARM_AM::getShiftOpcStr(ARM_AM::getAM2ShiftOpc(MO3.getImm())) 231 << " #" << ShImm; 232 O << "]"; 233} 234 235void ARMInstPrinter::printAM2PostIndexOp(const MCInst *MI, unsigned Op, 236 raw_ostream &O) { 237 const MCOperand &MO1 = MI->getOperand(Op); 238 const MCOperand &MO2 = MI->getOperand(Op+1); 239 const MCOperand &MO3 = MI->getOperand(Op+2); 240 241 O << "[" << getRegisterName(MO1.getReg()) << "], "; 242 243 if (!MO2.getReg()) { 244 unsigned ImmOffs = ARM_AM::getAM2Offset(MO3.getImm()); 245 O << '#' 246 << ARM_AM::getAddrOpcStr(ARM_AM::getAM2Op(MO3.getImm())) 247 << ImmOffs; 248 return; 249 } 250 251 O << ARM_AM::getAddrOpcStr(ARM_AM::getAM2Op(MO3.getImm())) 252 << getRegisterName(MO2.getReg()); 253 254 if (unsigned ShImm = ARM_AM::getAM2Offset(MO3.getImm())) 255 O << ", " 256 << ARM_AM::getShiftOpcStr(ARM_AM::getAM2ShiftOpc(MO3.getImm())) 257 << " #" << ShImm; 258} 259 260void ARMInstPrinter::printAddrMode2Operand(const MCInst *MI, unsigned Op, 261 raw_ostream &O) { 262 const MCOperand &MO1 = MI->getOperand(Op); 263 264 if (!MO1.isReg()) { // FIXME: This is for CP entries, but isn't right. 265 printOperand(MI, Op, O); 266 return; 267 } 268 269 const MCOperand &MO3 = MI->getOperand(Op+2); 270 unsigned IdxMode = ARM_AM::getAM2IdxMode(MO3.getImm()); 271 272 if (IdxMode == ARMII::IndexModePost) { 273 printAM2PostIndexOp(MI, Op, O); 274 return; 275 } 276 printAM2PreOrOffsetIndexOp(MI, Op, O); 277} 278 279void ARMInstPrinter::printAddrMode2OffsetOperand(const MCInst *MI, 280 unsigned OpNum, 281 raw_ostream &O) { 282 const MCOperand &MO1 = MI->getOperand(OpNum); 283 const MCOperand &MO2 = MI->getOperand(OpNum+1); 284 285 if (!MO1.getReg()) { 286 unsigned ImmOffs = ARM_AM::getAM2Offset(MO2.getImm()); 287 O << '#' 288 << ARM_AM::getAddrOpcStr(ARM_AM::getAM2Op(MO2.getImm())) 289 << ImmOffs; 290 return; 291 } 292 293 O << ARM_AM::getAddrOpcStr(ARM_AM::getAM2Op(MO2.getImm())) 294 << getRegisterName(MO1.getReg()); 295 296 if (unsigned ShImm = ARM_AM::getAM2Offset(MO2.getImm())) 297 O << ", " 298 << ARM_AM::getShiftOpcStr(ARM_AM::getAM2ShiftOpc(MO2.getImm())) 299 << " #" << ShImm; 300} 301 302//===--------------------------------------------------------------------===// 303// Addressing Mode #3 304//===--------------------------------------------------------------------===// 305 306void ARMInstPrinter::printAM3PostIndexOp(const MCInst *MI, unsigned Op, 307 raw_ostream &O) { 308 const MCOperand &MO1 = MI->getOperand(Op); 309 const MCOperand &MO2 = MI->getOperand(Op+1); 310 const MCOperand &MO3 = MI->getOperand(Op+2); 311 312 O << "[" << getRegisterName(MO1.getReg()) << "], "; 313 314 if (MO2.getReg()) { 315 O << (char)ARM_AM::getAM3Op(MO3.getImm()) 316 << getRegisterName(MO2.getReg()); 317 return; 318 } 319 320 unsigned ImmOffs = ARM_AM::getAM3Offset(MO3.getImm()); 321 O << '#' 322 << ARM_AM::getAddrOpcStr(ARM_AM::getAM3Op(MO3.getImm())) 323 << ImmOffs; 324} 325 326void ARMInstPrinter::printAM3PreOrOffsetIndexOp(const MCInst *MI, unsigned Op, 327 raw_ostream &O) { 328 const MCOperand &MO1 = MI->getOperand(Op); 329 const MCOperand &MO2 = MI->getOperand(Op+1); 330 const MCOperand &MO3 = MI->getOperand(Op+2); 331 332 O << '[' << getRegisterName(MO1.getReg()); 333 334 if (MO2.getReg()) { 335 O << ", " << (char)ARM_AM::getAM3Op(MO3.getImm()) 336 << getRegisterName(MO2.getReg()) << ']'; 337 return; 338 } 339 340 if (unsigned ImmOffs = ARM_AM::getAM3Offset(MO3.getImm())) 341 O << ", #" 342 << ARM_AM::getAddrOpcStr(ARM_AM::getAM3Op(MO3.getImm())) 343 << ImmOffs; 344 O << ']'; 345} 346 347void ARMInstPrinter::printAddrMode3Operand(const MCInst *MI, unsigned Op, 348 raw_ostream &O) { 349 const MCOperand &MO3 = MI->getOperand(Op+2); 350 unsigned IdxMode = ARM_AM::getAM3IdxMode(MO3.getImm()); 351 352 if (IdxMode == ARMII::IndexModePost) { 353 printAM3PostIndexOp(MI, Op, O); 354 return; 355 } 356 printAM3PreOrOffsetIndexOp(MI, Op, O); 357} 358 359void ARMInstPrinter::printAddrMode3OffsetOperand(const MCInst *MI, 360 unsigned OpNum, 361 raw_ostream &O) { 362 const MCOperand &MO1 = MI->getOperand(OpNum); 363 const MCOperand &MO2 = MI->getOperand(OpNum+1); 364 365 if (MO1.getReg()) { 366 O << (char)ARM_AM::getAM3Op(MO2.getImm()) 367 << getRegisterName(MO1.getReg()); 368 return; 369 } 370 371 unsigned ImmOffs = ARM_AM::getAM3Offset(MO2.getImm()); 372 O << '#' 373 << ARM_AM::getAddrOpcStr(ARM_AM::getAM3Op(MO2.getImm())) 374 << ImmOffs; 375} 376 377void ARMInstPrinter::printLdStmModeOperand(const MCInst *MI, unsigned OpNum, 378 raw_ostream &O) { 379 ARM_AM::AMSubMode Mode = ARM_AM::getAM4SubMode(MI->getOperand(OpNum) 380 .getImm()); 381 O << ARM_AM::getAMSubModeStr(Mode); 382} 383 384void ARMInstPrinter::printAddrMode5Operand(const MCInst *MI, unsigned OpNum, 385 raw_ostream &O) { 386 const MCOperand &MO1 = MI->getOperand(OpNum); 387 const MCOperand &MO2 = MI->getOperand(OpNum+1); 388 389 if (!MO1.isReg()) { // FIXME: This is for CP entries, but isn't right. 390 printOperand(MI, OpNum, O); 391 return; 392 } 393 394 O << "[" << getRegisterName(MO1.getReg()); 395 396 if (unsigned ImmOffs = ARM_AM::getAM5Offset(MO2.getImm())) { 397 O << ", #" 398 << ARM_AM::getAddrOpcStr(ARM_AM::getAM5Op(MO2.getImm())) 399 << ImmOffs * 4; 400 } 401 O << "]"; 402} 403 404void ARMInstPrinter::printAddrMode6Operand(const MCInst *MI, unsigned OpNum, 405 raw_ostream &O) { 406 const MCOperand &MO1 = MI->getOperand(OpNum); 407 const MCOperand &MO2 = MI->getOperand(OpNum+1); 408 409 O << "[" << getRegisterName(MO1.getReg()); 410 if (MO2.getImm()) { 411 // FIXME: Both darwin as and GNU as violate ARM docs here. 412 O << ", :" << (MO2.getImm() << 3); 413 } 414 O << "]"; 415} 416 417void ARMInstPrinter::printAddrMode7Operand(const MCInst *MI, unsigned OpNum, 418 raw_ostream &O) { 419 const MCOperand &MO1 = MI->getOperand(OpNum); 420 O << "[" << getRegisterName(MO1.getReg()) << "]"; 421} 422 423void ARMInstPrinter::printAddrMode6OffsetOperand(const MCInst *MI, 424 unsigned OpNum, 425 raw_ostream &O) { 426 const MCOperand &MO = MI->getOperand(OpNum); 427 if (MO.getReg() == 0) 428 O << "!"; 429 else 430 O << ", " << getRegisterName(MO.getReg()); 431} 432 433void ARMInstPrinter::printBitfieldInvMaskImmOperand(const MCInst *MI, 434 unsigned OpNum, 435 raw_ostream &O) { 436 const MCOperand &MO = MI->getOperand(OpNum); 437 uint32_t v = ~MO.getImm(); 438 int32_t lsb = CountTrailingZeros_32(v); 439 int32_t width = (32 - CountLeadingZeros_32 (v)) - lsb; 440 assert(MO.isImm() && "Not a valid bf_inv_mask_imm value!"); 441 O << '#' << lsb << ", #" << width; 442} 443 444void ARMInstPrinter::printMemBOption(const MCInst *MI, unsigned OpNum, 445 raw_ostream &O) { 446 unsigned val = MI->getOperand(OpNum).getImm(); 447 O << ARM_MB::MemBOptToString(val); 448} 449 450void ARMInstPrinter::printShiftImmOperand(const MCInst *MI, unsigned OpNum, 451 raw_ostream &O) { 452 unsigned ShiftOp = MI->getOperand(OpNum).getImm(); 453 ARM_AM::ShiftOpc Opc = ARM_AM::getSORegShOp(ShiftOp); 454 switch (Opc) { 455 case ARM_AM::no_shift: 456 return; 457 case ARM_AM::lsl: 458 O << ", lsl #"; 459 break; 460 case ARM_AM::asr: 461 O << ", asr #"; 462 break; 463 default: 464 assert(0 && "unexpected shift opcode for shift immediate operand"); 465 } 466 O << ARM_AM::getSORegOffset(ShiftOp); 467} 468 469void ARMInstPrinter::printPKHLSLShiftImm(const MCInst *MI, unsigned OpNum, 470 raw_ostream &O) { 471 unsigned Imm = MI->getOperand(OpNum).getImm(); 472 if (Imm == 0) 473 return; 474 assert(Imm > 0 && Imm < 32 && "Invalid PKH shift immediate value!"); 475 O << ", lsl #" << Imm; 476} 477 478void ARMInstPrinter::printPKHASRShiftImm(const MCInst *MI, unsigned OpNum, 479 raw_ostream &O) { 480 unsigned Imm = MI->getOperand(OpNum).getImm(); 481 // A shift amount of 32 is encoded as 0. 482 if (Imm == 0) 483 Imm = 32; 484 assert(Imm > 0 && Imm <= 32 && "Invalid PKH shift immediate value!"); 485 O << ", asr #" << Imm; 486} 487 488void ARMInstPrinter::printRegisterList(const MCInst *MI, unsigned OpNum, 489 raw_ostream &O) { 490 O << "{"; 491 for (unsigned i = OpNum, e = MI->getNumOperands(); i != e; ++i) { 492 if (i != OpNum) O << ", "; 493 O << getRegisterName(MI->getOperand(i).getReg()); 494 } 495 O << "}"; 496} 497 498void ARMInstPrinter::printSetendOperand(const MCInst *MI, unsigned OpNum, 499 raw_ostream &O) { 500 const MCOperand &Op = MI->getOperand(OpNum); 501 if (Op.getImm()) 502 O << "be"; 503 else 504 O << "le"; 505} 506 507void ARMInstPrinter::printCPSIMod(const MCInst *MI, unsigned OpNum, 508 raw_ostream &O) { 509 const MCOperand &Op = MI->getOperand(OpNum); 510 O << ARM_PROC::IModToString(Op.getImm()); 511} 512 513void ARMInstPrinter::printCPSIFlag(const MCInst *MI, unsigned OpNum, 514 raw_ostream &O) { 515 const MCOperand &Op = MI->getOperand(OpNum); 516 unsigned IFlags = Op.getImm(); 517 for (int i=2; i >= 0; --i) 518 if (IFlags & (1 << i)) 519 O << ARM_PROC::IFlagsToString(1 << i); 520} 521 522void ARMInstPrinter::printMSRMaskOperand(const MCInst *MI, unsigned OpNum, 523 raw_ostream &O) { 524 const MCOperand &Op = MI->getOperand(OpNum); 525 unsigned SpecRegRBit = Op.getImm() >> 4; 526 unsigned Mask = Op.getImm() & 0xf; 527 528 // As special cases, CPSR_f, CPSR_s and CPSR_fs prefer printing as 529 // APSR_nzcvq, APSR_g and APSRnzcvqg, respectively. 530 if (!SpecRegRBit && (Mask == 8 || Mask == 4 || Mask == 12)) { 531 O << "APSR_"; 532 switch (Mask) { 533 default: assert(0); 534 case 4: O << "g"; return; 535 case 8: O << "nzcvq"; return; 536 case 12: O << "nzcvqg"; return; 537 } 538 llvm_unreachable("Unexpected mask value!"); 539 } 540 541 if (SpecRegRBit) 542 O << "SPSR"; 543 else 544 O << "CPSR"; 545 546 if (Mask) { 547 O << '_'; 548 if (Mask & 8) O << 'f'; 549 if (Mask & 4) O << 's'; 550 if (Mask & 2) O << 'x'; 551 if (Mask & 1) O << 'c'; 552 } 553} 554 555void ARMInstPrinter::printPredicateOperand(const MCInst *MI, unsigned OpNum, 556 raw_ostream &O) { 557 ARMCC::CondCodes CC = (ARMCC::CondCodes)MI->getOperand(OpNum).getImm(); 558 if (CC != ARMCC::AL) 559 O << ARMCondCodeToString(CC); 560} 561 562void ARMInstPrinter::printMandatoryPredicateOperand(const MCInst *MI, 563 unsigned OpNum, 564 raw_ostream &O) { 565 ARMCC::CondCodes CC = (ARMCC::CondCodes)MI->getOperand(OpNum).getImm(); 566 O << ARMCondCodeToString(CC); 567} 568 569void ARMInstPrinter::printSBitModifierOperand(const MCInst *MI, unsigned OpNum, 570 raw_ostream &O) { 571 if (MI->getOperand(OpNum).getReg()) { 572 assert(MI->getOperand(OpNum).getReg() == ARM::CPSR && 573 "Expect ARM CPSR register!"); 574 O << 's'; 575 } 576} 577 578void ARMInstPrinter::printNoHashImmediate(const MCInst *MI, unsigned OpNum, 579 raw_ostream &O) { 580 O << MI->getOperand(OpNum).getImm(); 581} 582 583void ARMInstPrinter::printPImmediate(const MCInst *MI, unsigned OpNum, 584 raw_ostream &O) { 585 O << "p" << MI->getOperand(OpNum).getImm(); 586} 587 588void ARMInstPrinter::printCImmediate(const MCInst *MI, unsigned OpNum, 589 raw_ostream &O) { 590 O << "c" << MI->getOperand(OpNum).getImm(); 591} 592 593void ARMInstPrinter::printPCLabel(const MCInst *MI, unsigned OpNum, 594 raw_ostream &O) { 595 llvm_unreachable("Unhandled PC-relative pseudo-instruction!"); 596} 597 598void ARMInstPrinter::printThumbS4ImmOperand(const MCInst *MI, unsigned OpNum, 599 raw_ostream &O) { 600 O << "#" << MI->getOperand(OpNum).getImm() * 4; 601} 602 603void ARMInstPrinter::printThumbITMask(const MCInst *MI, unsigned OpNum, 604 raw_ostream &O) { 605 // (3 - the number of trailing zeros) is the number of then / else. 606 unsigned Mask = MI->getOperand(OpNum).getImm(); 607 unsigned CondBit0 = Mask >> 4 & 1; 608 unsigned NumTZ = CountTrailingZeros_32(Mask); 609 assert(NumTZ <= 3 && "Invalid IT mask!"); 610 for (unsigned Pos = 3, e = NumTZ; Pos > e; --Pos) { 611 bool T = ((Mask >> Pos) & 1) == CondBit0; 612 if (T) 613 O << 't'; 614 else 615 O << 'e'; 616 } 617} 618 619void ARMInstPrinter::printThumbAddrModeRROperand(const MCInst *MI, unsigned Op, 620 raw_ostream &O) { 621 const MCOperand &MO1 = MI->getOperand(Op); 622 const MCOperand &MO2 = MI->getOperand(Op + 1); 623 624 if (!MO1.isReg()) { // FIXME: This is for CP entries, but isn't right. 625 printOperand(MI, Op, O); 626 return; 627 } 628 629 O << "[" << getRegisterName(MO1.getReg()); 630 if (unsigned RegNum = MO2.getReg()) 631 O << ", " << getRegisterName(RegNum); 632 O << "]"; 633} 634 635void ARMInstPrinter::printThumbAddrModeImm5SOperand(const MCInst *MI, 636 unsigned Op, 637 raw_ostream &O, 638 unsigned Scale) { 639 const MCOperand &MO1 = MI->getOperand(Op); 640 const MCOperand &MO2 = MI->getOperand(Op + 1); 641 642 if (!MO1.isReg()) { // FIXME: This is for CP entries, but isn't right. 643 printOperand(MI, Op, O); 644 return; 645 } 646 647 O << "[" << getRegisterName(MO1.getReg()); 648 if (unsigned ImmOffs = MO2.getImm()) 649 O << ", #" << ImmOffs * Scale; 650 O << "]"; 651} 652 653void ARMInstPrinter::printThumbAddrModeImm5S1Operand(const MCInst *MI, 654 unsigned Op, 655 raw_ostream &O) { 656 printThumbAddrModeImm5SOperand(MI, Op, O, 1); 657} 658 659void ARMInstPrinter::printThumbAddrModeImm5S2Operand(const MCInst *MI, 660 unsigned Op, 661 raw_ostream &O) { 662 printThumbAddrModeImm5SOperand(MI, Op, O, 2); 663} 664 665void ARMInstPrinter::printThumbAddrModeImm5S4Operand(const MCInst *MI, 666 unsigned Op, 667 raw_ostream &O) { 668 printThumbAddrModeImm5SOperand(MI, Op, O, 4); 669} 670 671void ARMInstPrinter::printThumbAddrModeSPOperand(const MCInst *MI, unsigned Op, 672 raw_ostream &O) { 673 printThumbAddrModeImm5SOperand(MI, Op, O, 4); 674} 675 676// Constant shifts t2_so_reg is a 2-operand unit corresponding to the Thumb2 677// register with shift forms. 678// REG 0 0 - e.g. R5 679// REG IMM, SH_OPC - e.g. R5, LSL #3 680void ARMInstPrinter::printT2SOOperand(const MCInst *MI, unsigned OpNum, 681 raw_ostream &O) { 682 const MCOperand &MO1 = MI->getOperand(OpNum); 683 const MCOperand &MO2 = MI->getOperand(OpNum+1); 684 685 unsigned Reg = MO1.getReg(); 686 O << getRegisterName(Reg); 687 688 // Print the shift opc. 689 assert(MO2.isImm() && "Not a valid t2_so_reg value!"); 690 ARM_AM::ShiftOpc ShOpc = ARM_AM::getSORegShOp(MO2.getImm()); 691 O << ", " << ARM_AM::getShiftOpcStr(ShOpc); 692 if (ShOpc != ARM_AM::rrx) 693 O << " #" << ARM_AM::getSORegOffset(MO2.getImm()); 694} 695 696void ARMInstPrinter::printAddrModeImm12Operand(const MCInst *MI, unsigned OpNum, 697 raw_ostream &O) { 698 const MCOperand &MO1 = MI->getOperand(OpNum); 699 const MCOperand &MO2 = MI->getOperand(OpNum+1); 700 701 if (!MO1.isReg()) { // FIXME: This is for CP entries, but isn't right. 702 printOperand(MI, OpNum, O); 703 return; 704 } 705 706 O << "[" << getRegisterName(MO1.getReg()); 707 708 int32_t OffImm = (int32_t)MO2.getImm(); 709 bool isSub = OffImm < 0; 710 // Special value for #-0. All others are normal. 711 if (OffImm == INT32_MIN) 712 OffImm = 0; 713 if (isSub) 714 O << ", #-" << -OffImm; 715 else if (OffImm > 0) 716 O << ", #" << OffImm; 717 O << "]"; 718} 719 720void ARMInstPrinter::printT2AddrModeImm8Operand(const MCInst *MI, 721 unsigned OpNum, 722 raw_ostream &O) { 723 const MCOperand &MO1 = MI->getOperand(OpNum); 724 const MCOperand &MO2 = MI->getOperand(OpNum+1); 725 726 O << "[" << getRegisterName(MO1.getReg()); 727 728 int32_t OffImm = (int32_t)MO2.getImm(); 729 // Don't print +0. 730 if (OffImm < 0) 731 O << ", #-" << -OffImm; 732 else if (OffImm > 0) 733 O << ", #" << OffImm; 734 O << "]"; 735} 736 737void ARMInstPrinter::printT2AddrModeImm8s4Operand(const MCInst *MI, 738 unsigned OpNum, 739 raw_ostream &O) { 740 const MCOperand &MO1 = MI->getOperand(OpNum); 741 const MCOperand &MO2 = MI->getOperand(OpNum+1); 742 743 O << "[" << getRegisterName(MO1.getReg()); 744 745 int32_t OffImm = (int32_t)MO2.getImm() / 4; 746 // Don't print +0. 747 if (OffImm < 0) 748 O << ", #-" << -OffImm * 4; 749 else if (OffImm > 0) 750 O << ", #" << OffImm * 4; 751 O << "]"; 752} 753 754void ARMInstPrinter::printT2AddrModeImm8OffsetOperand(const MCInst *MI, 755 unsigned OpNum, 756 raw_ostream &O) { 757 const MCOperand &MO1 = MI->getOperand(OpNum); 758 int32_t OffImm = (int32_t)MO1.getImm(); 759 // Don't print +0. 760 if (OffImm < 0) 761 O << "#-" << -OffImm; 762 else if (OffImm > 0) 763 O << "#" << OffImm; 764} 765 766void ARMInstPrinter::printT2AddrModeImm8s4OffsetOperand(const MCInst *MI, 767 unsigned OpNum, 768 raw_ostream &O) { 769 const MCOperand &MO1 = MI->getOperand(OpNum); 770 int32_t OffImm = (int32_t)MO1.getImm() / 4; 771 // Don't print +0. 772 if (OffImm < 0) 773 O << "#-" << -OffImm * 4; 774 else if (OffImm > 0) 775 O << "#" << OffImm * 4; 776} 777 778void ARMInstPrinter::printT2AddrModeSoRegOperand(const MCInst *MI, 779 unsigned OpNum, 780 raw_ostream &O) { 781 const MCOperand &MO1 = MI->getOperand(OpNum); 782 const MCOperand &MO2 = MI->getOperand(OpNum+1); 783 const MCOperand &MO3 = MI->getOperand(OpNum+2); 784 785 O << "[" << getRegisterName(MO1.getReg()); 786 787 assert(MO2.getReg() && "Invalid so_reg load / store address!"); 788 O << ", " << getRegisterName(MO2.getReg()); 789 790 unsigned ShAmt = MO3.getImm(); 791 if (ShAmt) { 792 assert(ShAmt <= 3 && "Not a valid Thumb2 addressing mode!"); 793 O << ", lsl #" << ShAmt; 794 } 795 O << "]"; 796} 797 798void ARMInstPrinter::printVFPf32ImmOperand(const MCInst *MI, unsigned OpNum, 799 raw_ostream &O) { 800 const MCOperand &MO = MI->getOperand(OpNum); 801 O << '#'; 802 if (MO.isFPImm()) { 803 O << (float)MO.getFPImm(); 804 } else { 805 union { 806 uint32_t I; 807 float F; 808 } FPUnion; 809 810 FPUnion.I = MO.getImm(); 811 O << FPUnion.F; 812 } 813} 814 815void ARMInstPrinter::printVFPf64ImmOperand(const MCInst *MI, unsigned OpNum, 816 raw_ostream &O) { 817 const MCOperand &MO = MI->getOperand(OpNum); 818 O << '#'; 819 if (MO.isFPImm()) { 820 O << MO.getFPImm(); 821 } else { 822 // We expect the binary encoding of a floating point number here. 823 union { 824 uint64_t I; 825 double D; 826 } FPUnion; 827 828 FPUnion.I = MO.getImm(); 829 O << FPUnion.D; 830 } 831} 832 833void ARMInstPrinter::printNEONModImmOperand(const MCInst *MI, unsigned OpNum, 834 raw_ostream &O) { 835 unsigned EncodedImm = MI->getOperand(OpNum).getImm(); 836 unsigned EltBits; 837 uint64_t Val = ARM_AM::decodeNEONModImm(EncodedImm, EltBits); 838 O << "#0x" << utohexstr(Val); 839} 840 841void ARMInstPrinter::printImm1_32Operand(const MCInst *MI, unsigned OpNum, 842 raw_ostream &O) { 843 unsigned Imm = MI->getOperand(OpNum).getImm(); 844 O << "#" << Imm + 1; 845} 846