ARMInstPrinter.cpp revision 2dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31
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 // If a symbolic branch target was added as a constant expression then print 211 // that address in hex. 212 const MCConstantExpr *BranchTarget = dyn_cast<MCConstantExpr>(Op.getExpr()); 213 int64_t Address; 214 if (BranchTarget && BranchTarget->EvaluateAsAbsolute(Address)) { 215 O << "0x"; 216 O.write_hex(Address); 217 } 218 else { 219 // Otherwise, just print the expression. 220 O << *Op.getExpr(); 221 } 222 } 223} 224 225void ARMInstPrinter::printT2LdrLabelOperand(const MCInst *MI, unsigned OpNum, 226 raw_ostream &O) { 227 const MCOperand &MO1 = MI->getOperand(OpNum); 228 if (MO1.isExpr()) 229 O << *MO1.getExpr(); 230 else if (MO1.isImm()) 231 O << "[pc, #" << MO1.getImm() << "]"; 232 else 233 llvm_unreachable("Unknown LDR label operand?"); 234} 235 236// so_reg is a 4-operand unit corresponding to register forms of the A5.1 237// "Addressing Mode 1 - Data-processing operands" forms. This includes: 238// REG 0 0 - e.g. R5 239// REG REG 0,SH_OPC - e.g. R5, ROR R3 240// REG 0 IMM,SH_OPC - e.g. R5, LSL #3 241void ARMInstPrinter::printSORegRegOperand(const MCInst *MI, unsigned OpNum, 242 raw_ostream &O) { 243 const MCOperand &MO1 = MI->getOperand(OpNum); 244 const MCOperand &MO2 = MI->getOperand(OpNum+1); 245 const MCOperand &MO3 = MI->getOperand(OpNum+2); 246 247 O << getRegisterName(MO1.getReg()); 248 249 // Print the shift opc. 250 ARM_AM::ShiftOpc ShOpc = ARM_AM::getSORegShOp(MO3.getImm()); 251 O << ", " << ARM_AM::getShiftOpcStr(ShOpc); 252 if (ShOpc == ARM_AM::rrx) 253 return; 254 255 O << ' ' << getRegisterName(MO2.getReg()); 256 assert(ARM_AM::getSORegOffset(MO3.getImm()) == 0); 257} 258 259void ARMInstPrinter::printSORegImmOperand(const MCInst *MI, unsigned OpNum, 260 raw_ostream &O) { 261 const MCOperand &MO1 = MI->getOperand(OpNum); 262 const MCOperand &MO2 = MI->getOperand(OpNum+1); 263 264 O << getRegisterName(MO1.getReg()); 265 266 // Print the shift opc. 267 ARM_AM::ShiftOpc ShOpc = ARM_AM::getSORegShOp(MO2.getImm()); 268 O << ", " << ARM_AM::getShiftOpcStr(ShOpc); 269 if (ShOpc == ARM_AM::rrx) 270 return; 271 O << " #" << translateShiftImm(ARM_AM::getSORegOffset(MO2.getImm())); 272} 273 274 275//===--------------------------------------------------------------------===// 276// Addressing Mode #2 277//===--------------------------------------------------------------------===// 278 279void ARMInstPrinter::printAM2PreOrOffsetIndexOp(const MCInst *MI, unsigned Op, 280 raw_ostream &O) { 281 const MCOperand &MO1 = MI->getOperand(Op); 282 const MCOperand &MO2 = MI->getOperand(Op+1); 283 const MCOperand &MO3 = MI->getOperand(Op+2); 284 285 O << "[" << getRegisterName(MO1.getReg()); 286 287 if (!MO2.getReg()) { 288 if (ARM_AM::getAM2Offset(MO3.getImm())) // Don't print +0. 289 O << ", #" 290 << ARM_AM::getAddrOpcStr(ARM_AM::getAM2Op(MO3.getImm())) 291 << ARM_AM::getAM2Offset(MO3.getImm()); 292 O << "]"; 293 return; 294 } 295 296 O << ", " 297 << ARM_AM::getAddrOpcStr(ARM_AM::getAM2Op(MO3.getImm())) 298 << getRegisterName(MO2.getReg()); 299 300 if (unsigned ShImm = ARM_AM::getAM2Offset(MO3.getImm())) 301 O << ", " 302 << ARM_AM::getShiftOpcStr(ARM_AM::getAM2ShiftOpc(MO3.getImm())) 303 << " #" << ShImm; 304 O << "]"; 305} 306 307void ARMInstPrinter::printAM2PostIndexOp(const MCInst *MI, unsigned Op, 308 raw_ostream &O) { 309 const MCOperand &MO1 = MI->getOperand(Op); 310 const MCOperand &MO2 = MI->getOperand(Op+1); 311 const MCOperand &MO3 = MI->getOperand(Op+2); 312 313 O << "[" << getRegisterName(MO1.getReg()) << "], "; 314 315 if (!MO2.getReg()) { 316 unsigned ImmOffs = ARM_AM::getAM2Offset(MO3.getImm()); 317 O << '#' 318 << ARM_AM::getAddrOpcStr(ARM_AM::getAM2Op(MO3.getImm())) 319 << ImmOffs; 320 return; 321 } 322 323 O << ARM_AM::getAddrOpcStr(ARM_AM::getAM2Op(MO3.getImm())) 324 << getRegisterName(MO2.getReg()); 325 326 if (unsigned ShImm = ARM_AM::getAM2Offset(MO3.getImm())) 327 O << ", " 328 << ARM_AM::getShiftOpcStr(ARM_AM::getAM2ShiftOpc(MO3.getImm())) 329 << " #" << ShImm; 330} 331 332void ARMInstPrinter::printAddrModeTBB(const MCInst *MI, unsigned Op, 333 raw_ostream &O) { 334 const MCOperand &MO1 = MI->getOperand(Op); 335 const MCOperand &MO2 = MI->getOperand(Op+1); 336 O << "[" << getRegisterName(MO1.getReg()) << ", " 337 << getRegisterName(MO2.getReg()) << "]"; 338} 339 340void ARMInstPrinter::printAddrModeTBH(const MCInst *MI, unsigned Op, 341 raw_ostream &O) { 342 const MCOperand &MO1 = MI->getOperand(Op); 343 const MCOperand &MO2 = MI->getOperand(Op+1); 344 O << "[" << getRegisterName(MO1.getReg()) << ", " 345 << getRegisterName(MO2.getReg()) << ", lsl #1]"; 346} 347 348void ARMInstPrinter::printAddrMode2Operand(const MCInst *MI, unsigned Op, 349 raw_ostream &O) { 350 const MCOperand &MO1 = MI->getOperand(Op); 351 352 if (!MO1.isReg()) { // FIXME: This is for CP entries, but isn't right. 353 printOperand(MI, Op, O); 354 return; 355 } 356 357 const MCOperand &MO3 = MI->getOperand(Op+2); 358 unsigned IdxMode = ARM_AM::getAM2IdxMode(MO3.getImm()); 359 360 if (IdxMode == ARMII::IndexModePost) { 361 printAM2PostIndexOp(MI, Op, O); 362 return; 363 } 364 printAM2PreOrOffsetIndexOp(MI, Op, O); 365} 366 367void ARMInstPrinter::printAddrMode2OffsetOperand(const MCInst *MI, 368 unsigned OpNum, 369 raw_ostream &O) { 370 const MCOperand &MO1 = MI->getOperand(OpNum); 371 const MCOperand &MO2 = MI->getOperand(OpNum+1); 372 373 if (!MO1.getReg()) { 374 unsigned ImmOffs = ARM_AM::getAM2Offset(MO2.getImm()); 375 O << '#' 376 << ARM_AM::getAddrOpcStr(ARM_AM::getAM2Op(MO2.getImm())) 377 << ImmOffs; 378 return; 379 } 380 381 O << ARM_AM::getAddrOpcStr(ARM_AM::getAM2Op(MO2.getImm())) 382 << getRegisterName(MO1.getReg()); 383 384 if (unsigned ShImm = ARM_AM::getAM2Offset(MO2.getImm())) 385 O << ", " 386 << ARM_AM::getShiftOpcStr(ARM_AM::getAM2ShiftOpc(MO2.getImm())) 387 << " #" << ShImm; 388} 389 390//===--------------------------------------------------------------------===// 391// Addressing Mode #3 392//===--------------------------------------------------------------------===// 393 394void ARMInstPrinter::printAM3PostIndexOp(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 << "[" << getRegisterName(MO1.getReg()) << "], "; 401 402 if (MO2.getReg()) { 403 O << (char)ARM_AM::getAM3Op(MO3.getImm()) 404 << getRegisterName(MO2.getReg()); 405 return; 406 } 407 408 unsigned ImmOffs = ARM_AM::getAM3Offset(MO3.getImm()); 409 O << '#' 410 << ARM_AM::getAddrOpcStr(ARM_AM::getAM3Op(MO3.getImm())) 411 << ImmOffs; 412} 413 414void ARMInstPrinter::printAM3PreOrOffsetIndexOp(const MCInst *MI, unsigned Op, 415 raw_ostream &O) { 416 const MCOperand &MO1 = MI->getOperand(Op); 417 const MCOperand &MO2 = MI->getOperand(Op+1); 418 const MCOperand &MO3 = MI->getOperand(Op+2); 419 420 O << '[' << getRegisterName(MO1.getReg()); 421 422 if (MO2.getReg()) { 423 O << ", " << getAddrOpcStr(ARM_AM::getAM3Op(MO3.getImm())) 424 << getRegisterName(MO2.getReg()) << ']'; 425 return; 426 } 427 428 if (unsigned ImmOffs = ARM_AM::getAM3Offset(MO3.getImm())) 429 O << ", #" 430 << ARM_AM::getAddrOpcStr(ARM_AM::getAM3Op(MO3.getImm())) 431 << ImmOffs; 432 O << ']'; 433} 434 435void ARMInstPrinter::printAddrMode3Operand(const MCInst *MI, unsigned Op, 436 raw_ostream &O) { 437 const MCOperand &MO3 = MI->getOperand(Op+2); 438 unsigned IdxMode = ARM_AM::getAM3IdxMode(MO3.getImm()); 439 440 if (IdxMode == ARMII::IndexModePost) { 441 printAM3PostIndexOp(MI, Op, O); 442 return; 443 } 444 printAM3PreOrOffsetIndexOp(MI, Op, O); 445} 446 447void ARMInstPrinter::printAddrMode3OffsetOperand(const MCInst *MI, 448 unsigned OpNum, 449 raw_ostream &O) { 450 const MCOperand &MO1 = MI->getOperand(OpNum); 451 const MCOperand &MO2 = MI->getOperand(OpNum+1); 452 453 if (MO1.getReg()) { 454 O << getAddrOpcStr(ARM_AM::getAM3Op(MO2.getImm())) 455 << getRegisterName(MO1.getReg()); 456 return; 457 } 458 459 unsigned ImmOffs = ARM_AM::getAM3Offset(MO2.getImm()); 460 O << '#' 461 << ARM_AM::getAddrOpcStr(ARM_AM::getAM3Op(MO2.getImm())) 462 << ImmOffs; 463} 464 465void ARMInstPrinter::printPostIdxImm8Operand(const MCInst *MI, 466 unsigned OpNum, 467 raw_ostream &O) { 468 const MCOperand &MO = MI->getOperand(OpNum); 469 unsigned Imm = MO.getImm(); 470 O << '#' << ((Imm & 256) ? "" : "-") << (Imm & 0xff); 471} 472 473void ARMInstPrinter::printPostIdxRegOperand(const MCInst *MI, unsigned OpNum, 474 raw_ostream &O) { 475 const MCOperand &MO1 = MI->getOperand(OpNum); 476 const MCOperand &MO2 = MI->getOperand(OpNum+1); 477 478 O << (MO2.getImm() ? "" : "-") << getRegisterName(MO1.getReg()); 479} 480 481void ARMInstPrinter::printPostIdxImm8s4Operand(const MCInst *MI, 482 unsigned OpNum, 483 raw_ostream &O) { 484 const MCOperand &MO = MI->getOperand(OpNum); 485 unsigned Imm = MO.getImm(); 486 O << '#' << ((Imm & 256) ? "" : "-") << ((Imm & 0xff) << 2); 487} 488 489 490void ARMInstPrinter::printLdStmModeOperand(const MCInst *MI, unsigned OpNum, 491 raw_ostream &O) { 492 ARM_AM::AMSubMode Mode = ARM_AM::getAM4SubMode(MI->getOperand(OpNum) 493 .getImm()); 494 O << ARM_AM::getAMSubModeStr(Mode); 495} 496 497void ARMInstPrinter::printAddrMode5Operand(const MCInst *MI, unsigned OpNum, 498 raw_ostream &O) { 499 const MCOperand &MO1 = MI->getOperand(OpNum); 500 const MCOperand &MO2 = MI->getOperand(OpNum+1); 501 502 if (!MO1.isReg()) { // FIXME: This is for CP entries, but isn't right. 503 printOperand(MI, OpNum, O); 504 return; 505 } 506 507 O << "[" << getRegisterName(MO1.getReg()); 508 509 unsigned ImmOffs = ARM_AM::getAM5Offset(MO2.getImm()); 510 unsigned Op = ARM_AM::getAM5Op(MO2.getImm()); 511 if (ImmOffs || Op == ARM_AM::sub) { 512 O << ", #" 513 << ARM_AM::getAddrOpcStr(ARM_AM::getAM5Op(MO2.getImm())) 514 << ImmOffs * 4; 515 } 516 O << "]"; 517} 518 519void ARMInstPrinter::printAddrMode6Operand(const MCInst *MI, unsigned OpNum, 520 raw_ostream &O) { 521 const MCOperand &MO1 = MI->getOperand(OpNum); 522 const MCOperand &MO2 = MI->getOperand(OpNum+1); 523 524 O << "[" << getRegisterName(MO1.getReg()); 525 if (MO2.getImm()) { 526 // FIXME: Both darwin as and GNU as violate ARM docs here. 527 O << ", :" << (MO2.getImm() << 3); 528 } 529 O << "]"; 530} 531 532void ARMInstPrinter::printAddrMode7Operand(const MCInst *MI, unsigned OpNum, 533 raw_ostream &O) { 534 const MCOperand &MO1 = MI->getOperand(OpNum); 535 O << "[" << getRegisterName(MO1.getReg()) << "]"; 536} 537 538void ARMInstPrinter::printAddrMode6OffsetOperand(const MCInst *MI, 539 unsigned OpNum, 540 raw_ostream &O) { 541 const MCOperand &MO = MI->getOperand(OpNum); 542 if (MO.getReg() == 0) 543 O << "!"; 544 else 545 O << ", " << getRegisterName(MO.getReg()); 546} 547 548void ARMInstPrinter::printBitfieldInvMaskImmOperand(const MCInst *MI, 549 unsigned OpNum, 550 raw_ostream &O) { 551 const MCOperand &MO = MI->getOperand(OpNum); 552 uint32_t v = ~MO.getImm(); 553 int32_t lsb = CountTrailingZeros_32(v); 554 int32_t width = (32 - CountLeadingZeros_32 (v)) - lsb; 555 assert(MO.isImm() && "Not a valid bf_inv_mask_imm value!"); 556 O << '#' << lsb << ", #" << width; 557} 558 559void ARMInstPrinter::printMemBOption(const MCInst *MI, unsigned OpNum, 560 raw_ostream &O) { 561 unsigned val = MI->getOperand(OpNum).getImm(); 562 O << ARM_MB::MemBOptToString(val); 563} 564 565void ARMInstPrinter::printShiftImmOperand(const MCInst *MI, unsigned OpNum, 566 raw_ostream &O) { 567 unsigned ShiftOp = MI->getOperand(OpNum).getImm(); 568 bool isASR = (ShiftOp & (1 << 5)) != 0; 569 unsigned Amt = ShiftOp & 0x1f; 570 if (isASR) 571 O << ", asr #" << (Amt == 0 ? 32 : Amt); 572 else if (Amt) 573 O << ", lsl #" << Amt; 574} 575 576void ARMInstPrinter::printPKHLSLShiftImm(const MCInst *MI, unsigned OpNum, 577 raw_ostream &O) { 578 unsigned Imm = MI->getOperand(OpNum).getImm(); 579 if (Imm == 0) 580 return; 581 assert(Imm > 0 && Imm < 32 && "Invalid PKH shift immediate value!"); 582 O << ", lsl #" << Imm; 583} 584 585void ARMInstPrinter::printPKHASRShiftImm(const MCInst *MI, unsigned OpNum, 586 raw_ostream &O) { 587 unsigned Imm = MI->getOperand(OpNum).getImm(); 588 // A shift amount of 32 is encoded as 0. 589 if (Imm == 0) 590 Imm = 32; 591 assert(Imm > 0 && Imm <= 32 && "Invalid PKH shift immediate value!"); 592 O << ", asr #" << Imm; 593} 594 595void ARMInstPrinter::printRegisterList(const MCInst *MI, unsigned OpNum, 596 raw_ostream &O) { 597 O << "{"; 598 for (unsigned i = OpNum, e = MI->getNumOperands(); i != e; ++i) { 599 if (i != OpNum) O << ", "; 600 O << getRegisterName(MI->getOperand(i).getReg()); 601 } 602 O << "}"; 603} 604 605void ARMInstPrinter::printSetendOperand(const MCInst *MI, unsigned OpNum, 606 raw_ostream &O) { 607 const MCOperand &Op = MI->getOperand(OpNum); 608 if (Op.getImm()) 609 O << "be"; 610 else 611 O << "le"; 612} 613 614void ARMInstPrinter::printCPSIMod(const MCInst *MI, unsigned OpNum, 615 raw_ostream &O) { 616 const MCOperand &Op = MI->getOperand(OpNum); 617 O << ARM_PROC::IModToString(Op.getImm()); 618} 619 620void ARMInstPrinter::printCPSIFlag(const MCInst *MI, unsigned OpNum, 621 raw_ostream &O) { 622 const MCOperand &Op = MI->getOperand(OpNum); 623 unsigned IFlags = Op.getImm(); 624 for (int i=2; i >= 0; --i) 625 if (IFlags & (1 << i)) 626 O << ARM_PROC::IFlagsToString(1 << i); 627 628 if (IFlags == 0) 629 O << "none"; 630} 631 632void ARMInstPrinter::printMSRMaskOperand(const MCInst *MI, unsigned OpNum, 633 raw_ostream &O) { 634 const MCOperand &Op = MI->getOperand(OpNum); 635 unsigned SpecRegRBit = Op.getImm() >> 4; 636 unsigned Mask = Op.getImm() & 0xf; 637 638 if (getAvailableFeatures() & ARM::FeatureMClass) { 639 switch (Op.getImm()) { 640 default: assert(0 && "Unexpected mask value!"); 641 case 0: O << "apsr"; return; 642 case 1: O << "iapsr"; return; 643 case 2: O << "eapsr"; return; 644 case 3: O << "xpsr"; return; 645 case 5: O << "ipsr"; return; 646 case 6: O << "epsr"; return; 647 case 7: O << "iepsr"; return; 648 case 8: O << "msp"; return; 649 case 9: O << "psp"; return; 650 case 16: O << "primask"; return; 651 case 17: O << "basepri"; return; 652 case 18: O << "basepri_max"; return; 653 case 19: O << "faultmask"; return; 654 case 20: O << "control"; return; 655 } 656 } 657 658 // As special cases, CPSR_f, CPSR_s and CPSR_fs prefer printing as 659 // APSR_nzcvq, APSR_g and APSRnzcvqg, respectively. 660 if (!SpecRegRBit && (Mask == 8 || Mask == 4 || Mask == 12)) { 661 O << "APSR_"; 662 switch (Mask) { 663 default: assert(0); 664 case 4: O << "g"; return; 665 case 8: O << "nzcvq"; return; 666 case 12: O << "nzcvqg"; return; 667 } 668 llvm_unreachable("Unexpected mask value!"); 669 } 670 671 if (SpecRegRBit) 672 O << "SPSR"; 673 else 674 O << "CPSR"; 675 676 if (Mask) { 677 O << '_'; 678 if (Mask & 8) O << 'f'; 679 if (Mask & 4) O << 's'; 680 if (Mask & 2) O << 'x'; 681 if (Mask & 1) O << 'c'; 682 } 683} 684 685void ARMInstPrinter::printPredicateOperand(const MCInst *MI, unsigned OpNum, 686 raw_ostream &O) { 687 ARMCC::CondCodes CC = (ARMCC::CondCodes)MI->getOperand(OpNum).getImm(); 688 if (CC != ARMCC::AL) 689 O << ARMCondCodeToString(CC); 690} 691 692void ARMInstPrinter::printMandatoryPredicateOperand(const MCInst *MI, 693 unsigned OpNum, 694 raw_ostream &O) { 695 ARMCC::CondCodes CC = (ARMCC::CondCodes)MI->getOperand(OpNum).getImm(); 696 O << ARMCondCodeToString(CC); 697} 698 699void ARMInstPrinter::printSBitModifierOperand(const MCInst *MI, unsigned OpNum, 700 raw_ostream &O) { 701 if (MI->getOperand(OpNum).getReg()) { 702 assert(MI->getOperand(OpNum).getReg() == ARM::CPSR && 703 "Expect ARM CPSR register!"); 704 O << 's'; 705 } 706} 707 708void ARMInstPrinter::printNoHashImmediate(const MCInst *MI, unsigned OpNum, 709 raw_ostream &O) { 710 O << MI->getOperand(OpNum).getImm(); 711} 712 713void ARMInstPrinter::printPImmediate(const MCInst *MI, unsigned OpNum, 714 raw_ostream &O) { 715 O << "p" << MI->getOperand(OpNum).getImm(); 716} 717 718void ARMInstPrinter::printCImmediate(const MCInst *MI, unsigned OpNum, 719 raw_ostream &O) { 720 O << "c" << MI->getOperand(OpNum).getImm(); 721} 722 723void ARMInstPrinter::printPCLabel(const MCInst *MI, unsigned OpNum, 724 raw_ostream &O) { 725 llvm_unreachable("Unhandled PC-relative pseudo-instruction!"); 726} 727 728void ARMInstPrinter::printThumbS4ImmOperand(const MCInst *MI, unsigned OpNum, 729 raw_ostream &O) { 730 O << "#" << MI->getOperand(OpNum).getImm() * 4; 731} 732 733void ARMInstPrinter::printThumbSRImm(const MCInst *MI, unsigned OpNum, 734 raw_ostream &O) { 735 unsigned Imm = MI->getOperand(OpNum).getImm(); 736 O << "#" << (Imm == 0 ? 32 : Imm); 737} 738 739void ARMInstPrinter::printThumbITMask(const MCInst *MI, unsigned OpNum, 740 raw_ostream &O) { 741 // (3 - the number of trailing zeros) is the number of then / else. 742 unsigned Mask = MI->getOperand(OpNum).getImm(); 743 unsigned CondBit0 = Mask >> 4 & 1; 744 unsigned NumTZ = CountTrailingZeros_32(Mask); 745 assert(NumTZ <= 3 && "Invalid IT mask!"); 746 for (unsigned Pos = 3, e = NumTZ; Pos > e; --Pos) { 747 bool T = ((Mask >> Pos) & 1) == CondBit0; 748 if (T) 749 O << 't'; 750 else 751 O << 'e'; 752 } 753} 754 755void ARMInstPrinter::printThumbAddrModeRROperand(const MCInst *MI, unsigned Op, 756 raw_ostream &O) { 757 const MCOperand &MO1 = MI->getOperand(Op); 758 const MCOperand &MO2 = MI->getOperand(Op + 1); 759 760 if (!MO1.isReg()) { // FIXME: This is for CP entries, but isn't right. 761 printOperand(MI, Op, O); 762 return; 763 } 764 765 O << "[" << getRegisterName(MO1.getReg()); 766 if (unsigned RegNum = MO2.getReg()) 767 O << ", " << getRegisterName(RegNum); 768 O << "]"; 769} 770 771void ARMInstPrinter::printThumbAddrModeImm5SOperand(const MCInst *MI, 772 unsigned Op, 773 raw_ostream &O, 774 unsigned Scale) { 775 const MCOperand &MO1 = MI->getOperand(Op); 776 const MCOperand &MO2 = MI->getOperand(Op + 1); 777 778 if (!MO1.isReg()) { // FIXME: This is for CP entries, but isn't right. 779 printOperand(MI, Op, O); 780 return; 781 } 782 783 O << "[" << getRegisterName(MO1.getReg()); 784 if (unsigned ImmOffs = MO2.getImm()) 785 O << ", #" << ImmOffs * Scale; 786 O << "]"; 787} 788 789void ARMInstPrinter::printThumbAddrModeImm5S1Operand(const MCInst *MI, 790 unsigned Op, 791 raw_ostream &O) { 792 printThumbAddrModeImm5SOperand(MI, Op, O, 1); 793} 794 795void ARMInstPrinter::printThumbAddrModeImm5S2Operand(const MCInst *MI, 796 unsigned Op, 797 raw_ostream &O) { 798 printThumbAddrModeImm5SOperand(MI, Op, O, 2); 799} 800 801void ARMInstPrinter::printThumbAddrModeImm5S4Operand(const MCInst *MI, 802 unsigned Op, 803 raw_ostream &O) { 804 printThumbAddrModeImm5SOperand(MI, Op, O, 4); 805} 806 807void ARMInstPrinter::printThumbAddrModeSPOperand(const MCInst *MI, unsigned Op, 808 raw_ostream &O) { 809 printThumbAddrModeImm5SOperand(MI, Op, O, 4); 810} 811 812// Constant shifts t2_so_reg is a 2-operand unit corresponding to the Thumb2 813// register with shift forms. 814// REG 0 0 - e.g. R5 815// REG IMM, SH_OPC - e.g. R5, LSL #3 816void ARMInstPrinter::printT2SOOperand(const MCInst *MI, unsigned OpNum, 817 raw_ostream &O) { 818 const MCOperand &MO1 = MI->getOperand(OpNum); 819 const MCOperand &MO2 = MI->getOperand(OpNum+1); 820 821 unsigned Reg = MO1.getReg(); 822 O << getRegisterName(Reg); 823 824 // Print the shift opc. 825 assert(MO2.isImm() && "Not a valid t2_so_reg value!"); 826 ARM_AM::ShiftOpc ShOpc = ARM_AM::getSORegShOp(MO2.getImm()); 827 O << ", " << ARM_AM::getShiftOpcStr(ShOpc); 828 if (ShOpc != ARM_AM::rrx) 829 O << " #" << translateShiftImm(ARM_AM::getSORegOffset(MO2.getImm())); 830} 831 832void ARMInstPrinter::printAddrModeImm12Operand(const MCInst *MI, unsigned OpNum, 833 raw_ostream &O) { 834 const MCOperand &MO1 = MI->getOperand(OpNum); 835 const MCOperand &MO2 = MI->getOperand(OpNum+1); 836 837 if (!MO1.isReg()) { // FIXME: This is for CP entries, but isn't right. 838 printOperand(MI, OpNum, O); 839 return; 840 } 841 842 O << "[" << getRegisterName(MO1.getReg()); 843 844 int32_t OffImm = (int32_t)MO2.getImm(); 845 bool isSub = OffImm < 0; 846 // Special value for #-0. All others are normal. 847 if (OffImm == INT32_MIN) 848 OffImm = 0; 849 if (isSub) 850 O << ", #-" << -OffImm; 851 else if (OffImm > 0) 852 O << ", #" << OffImm; 853 O << "]"; 854} 855 856void ARMInstPrinter::printT2AddrModeImm8Operand(const MCInst *MI, 857 unsigned OpNum, 858 raw_ostream &O) { 859 const MCOperand &MO1 = MI->getOperand(OpNum); 860 const MCOperand &MO2 = MI->getOperand(OpNum+1); 861 862 O << "[" << getRegisterName(MO1.getReg()); 863 864 int32_t OffImm = (int32_t)MO2.getImm(); 865 // Don't print +0. 866 if (OffImm == INT32_MIN) 867 O << ", #-0"; 868 else if (OffImm < 0) 869 O << ", #-" << -OffImm; 870 else if (OffImm > 0) 871 O << ", #" << OffImm; 872 O << "]"; 873} 874 875void ARMInstPrinter::printT2AddrModeImm8s4Operand(const MCInst *MI, 876 unsigned OpNum, 877 raw_ostream &O) { 878 const MCOperand &MO1 = MI->getOperand(OpNum); 879 const MCOperand &MO2 = MI->getOperand(OpNum+1); 880 881 O << "[" << getRegisterName(MO1.getReg()); 882 883 int32_t OffImm = (int32_t)MO2.getImm() / 4; 884 // Don't print +0. 885 if (OffImm < 0) 886 O << ", #-" << -OffImm * 4; 887 else if (OffImm > 0) 888 O << ", #" << OffImm * 4; 889 O << "]"; 890} 891 892void ARMInstPrinter::printT2AddrModeImm0_1020s4Operand(const MCInst *MI, 893 unsigned OpNum, 894 raw_ostream &O) { 895 const MCOperand &MO1 = MI->getOperand(OpNum); 896 const MCOperand &MO2 = MI->getOperand(OpNum+1); 897 898 O << "[" << getRegisterName(MO1.getReg()); 899 if (MO2.getImm()) 900 O << ", #" << MO2.getImm() * 4; 901 O << "]"; 902} 903 904void ARMInstPrinter::printT2AddrModeImm8OffsetOperand(const MCInst *MI, 905 unsigned OpNum, 906 raw_ostream &O) { 907 const MCOperand &MO1 = MI->getOperand(OpNum); 908 int32_t OffImm = (int32_t)MO1.getImm(); 909 // Don't print +0. 910 if (OffImm < 0) 911 O << ", #-" << -OffImm; 912 else 913 O << ", #" << OffImm; 914} 915 916void ARMInstPrinter::printT2AddrModeImm8s4OffsetOperand(const MCInst *MI, 917 unsigned OpNum, 918 raw_ostream &O) { 919 const MCOperand &MO1 = MI->getOperand(OpNum); 920 int32_t OffImm = (int32_t)MO1.getImm() / 4; 921 // Don't print +0. 922 if (OffImm != 0) { 923 O << ", "; 924 if (OffImm < 0) 925 O << "#-" << -OffImm * 4; 926 else if (OffImm > 0) 927 O << "#" << OffImm * 4; 928 } 929} 930 931void ARMInstPrinter::printT2AddrModeSoRegOperand(const MCInst *MI, 932 unsigned OpNum, 933 raw_ostream &O) { 934 const MCOperand &MO1 = MI->getOperand(OpNum); 935 const MCOperand &MO2 = MI->getOperand(OpNum+1); 936 const MCOperand &MO3 = MI->getOperand(OpNum+2); 937 938 O << "[" << getRegisterName(MO1.getReg()); 939 940 assert(MO2.getReg() && "Invalid so_reg load / store address!"); 941 O << ", " << getRegisterName(MO2.getReg()); 942 943 unsigned ShAmt = MO3.getImm(); 944 if (ShAmt) { 945 assert(ShAmt <= 3 && "Not a valid Thumb2 addressing mode!"); 946 O << ", lsl #" << ShAmt; 947 } 948 O << "]"; 949} 950 951void ARMInstPrinter::printFPImmOperand(const MCInst *MI, unsigned OpNum, 952 raw_ostream &O) { 953 const MCOperand &MO = MI->getOperand(OpNum); 954 O << '#' << ARM_AM::getFPImmFloat(MO.getImm()); 955} 956 957void ARMInstPrinter::printNEONModImmOperand(const MCInst *MI, unsigned OpNum, 958 raw_ostream &O) { 959 unsigned EncodedImm = MI->getOperand(OpNum).getImm(); 960 unsigned EltBits; 961 uint64_t Val = ARM_AM::decodeNEONModImm(EncodedImm, EltBits); 962 O << "#0x" << utohexstr(Val); 963} 964 965void ARMInstPrinter::printImmPlusOneOperand(const MCInst *MI, unsigned OpNum, 966 raw_ostream &O) { 967 unsigned Imm = MI->getOperand(OpNum).getImm(); 968 O << "#" << Imm + 1; 969} 970 971void ARMInstPrinter::printRotImmOperand(const MCInst *MI, unsigned OpNum, 972 raw_ostream &O) { 973 unsigned Imm = MI->getOperand(OpNum).getImm(); 974 if (Imm == 0) 975 return; 976 O << ", ror #"; 977 switch (Imm) { 978 default: assert (0 && "illegal ror immediate!"); 979 case 1: O << "8"; break; 980 case 2: O << "16"; break; 981 case 3: O << "24"; break; 982 } 983} 984