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