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