ARMInstPrinter.cpp revision 8cb415e4c0032300a1b728c942f8b31acec0a9f5
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 "ARMBaseInfo.h" 16#include "ARMInstPrinter.h" 17#include "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 32 33void ARMInstPrinter::printInst(const MCInst *MI, raw_ostream &O) { 34 unsigned Opcode = MI->getOpcode(); 35 36 // Check for MOVs and print canonical forms, instead. 37 if (Opcode == ARM::MOVs) { 38 // FIXME: Thumb variants? 39 const MCOperand &Dst = MI->getOperand(0); 40 const MCOperand &MO1 = MI->getOperand(1); 41 const MCOperand &MO2 = MI->getOperand(2); 42 const MCOperand &MO3 = MI->getOperand(3); 43 44 O << '\t' << ARM_AM::getShiftOpcStr(ARM_AM::getSORegShOp(MO3.getImm())); 45 printSBitModifierOperand(MI, 6, O); 46 printPredicateOperand(MI, 4, O); 47 48 O << '\t' << getRegisterName(Dst.getReg()) 49 << ", " << getRegisterName(MO1.getReg()); 50 51 if (ARM_AM::getSORegShOp(MO3.getImm()) == ARM_AM::rrx) 52 return; 53 54 O << ", "; 55 56 if (MO2.getReg()) { 57 O << getRegisterName(MO2.getReg()); 58 assert(ARM_AM::getSORegOffset(MO3.getImm()) == 0); 59 } else { 60 O << "#" << ARM_AM::getSORegOffset(MO3.getImm()); 61 } 62 return; 63 } 64 65 // A8.6.123 PUSH 66 if ((Opcode == ARM::STMDB_UPD || Opcode == ARM::t2STMDB_UPD) && 67 MI->getOperand(0).getReg() == ARM::SP) { 68 O << '\t' << "push"; 69 printPredicateOperand(MI, 2, O); 70 if (Opcode == ARM::t2STMDB_UPD) 71 O << ".w"; 72 O << '\t'; 73 printRegisterList(MI, 4, O); 74 return; 75 } 76 77 // A8.6.122 POP 78 if ((Opcode == ARM::LDMIA_UPD || Opcode == ARM::t2LDMIA_UPD) && 79 MI->getOperand(0).getReg() == ARM::SP) { 80 O << '\t' << "pop"; 81 printPredicateOperand(MI, 2, O); 82 if (Opcode == ARM::t2LDMIA_UPD) 83 O << ".w"; 84 O << '\t'; 85 printRegisterList(MI, 4, O); 86 return; 87 } 88 89 // A8.6.355 VPUSH 90 if ((Opcode == ARM::VSTMSDB_UPD || Opcode == ARM::VSTMDDB_UPD) && 91 MI->getOperand(0).getReg() == ARM::SP) { 92 O << '\t' << "vpush"; 93 printPredicateOperand(MI, 2, O); 94 O << '\t'; 95 printRegisterList(MI, 4, O); 96 return; 97 } 98 99 // A8.6.354 VPOP 100 if ((Opcode == ARM::VLDMSIA_UPD || Opcode == ARM::VLDMDIA_UPD) && 101 MI->getOperand(0).getReg() == ARM::SP) { 102 O << '\t' << "vpop"; 103 printPredicateOperand(MI, 2, O); 104 O << '\t'; 105 printRegisterList(MI, 4, O); 106 return; 107 } 108 109 printInstruction(MI, O); 110} 111 112void ARMInstPrinter::printOperand(const MCInst *MI, unsigned OpNo, 113 raw_ostream &O) { 114 const MCOperand &Op = MI->getOperand(OpNo); 115 if (Op.isReg()) { 116 unsigned Reg = Op.getReg(); 117 O << getRegisterName(Reg); 118 } else if (Op.isImm()) { 119 O << '#' << Op.getImm(); 120 } else { 121 assert(Op.isExpr() && "unknown operand kind in printOperand"); 122 O << *Op.getExpr(); 123 } 124} 125 126static void printSOImm(raw_ostream &O, int64_t V, raw_ostream *CommentStream, 127 const MCAsmInfo *MAI) { 128 // Break it up into two parts that make up a shifter immediate. 129 V = ARM_AM::getSOImmVal(V); 130 assert(V != -1 && "Not a valid so_imm value!"); 131 132 unsigned Imm = ARM_AM::getSOImmValImm(V); 133 unsigned Rot = ARM_AM::getSOImmValRot(V); 134 135 // Print low-level immediate formation info, per 136 // A5.1.3: "Data-processing operands - Immediate". 137 if (Rot) { 138 O << "#" << Imm << ", " << Rot; 139 // Pretty printed version. 140 if (CommentStream) 141 *CommentStream << (int)ARM_AM::rotr32(Imm, Rot) << "\n"; 142 } else { 143 O << "#" << Imm; 144 } 145} 146 147 148/// printSOImmOperand - SOImm is 4-bit rotate amount in bits 8-11 with 8-bit 149/// immediate in bits 0-7. 150void ARMInstPrinter::printSOImmOperand(const MCInst *MI, unsigned OpNum, 151 raw_ostream &O) { 152 const MCOperand &MO = MI->getOperand(OpNum); 153 assert(MO.isImm() && "Not a valid so_imm value!"); 154 printSOImm(O, MO.getImm(), CommentStream, &MAI); 155} 156 157// so_reg is a 4-operand unit corresponding to register forms of the A5.1 158// "Addressing Mode 1 - Data-processing operands" forms. This includes: 159// REG 0 0 - e.g. R5 160// REG REG 0,SH_OPC - e.g. R5, ROR R3 161// REG 0 IMM,SH_OPC - e.g. R5, LSL #3 162void ARMInstPrinter::printSORegOperand(const MCInst *MI, unsigned OpNum, 163 raw_ostream &O) { 164 const MCOperand &MO1 = MI->getOperand(OpNum); 165 const MCOperand &MO2 = MI->getOperand(OpNum+1); 166 const MCOperand &MO3 = MI->getOperand(OpNum+2); 167 168 O << getRegisterName(MO1.getReg()); 169 170 // Print the shift opc. 171 ARM_AM::ShiftOpc ShOpc = ARM_AM::getSORegShOp(MO3.getImm()); 172 O << ", " << ARM_AM::getShiftOpcStr(ShOpc); 173 if (MO2.getReg()) { 174 O << ' ' << getRegisterName(MO2.getReg()); 175 assert(ARM_AM::getSORegOffset(MO3.getImm()) == 0); 176 } else if (ShOpc != ARM_AM::rrx) { 177 O << " #" << ARM_AM::getSORegOffset(MO3.getImm()); 178 } 179} 180 181 182void ARMInstPrinter::printAddrMode2Operand(const MCInst *MI, unsigned Op, 183 raw_ostream &O) { 184 const MCOperand &MO1 = MI->getOperand(Op); 185 const MCOperand &MO2 = MI->getOperand(Op+1); 186 const MCOperand &MO3 = MI->getOperand(Op+2); 187 188 if (!MO1.isReg()) { // FIXME: This is for CP entries, but isn't right. 189 printOperand(MI, Op, O); 190 return; 191 } 192 193 O << "[" << getRegisterName(MO1.getReg()); 194 195 if (!MO2.getReg()) { 196 if (ARM_AM::getAM2Offset(MO3.getImm())) // Don't print +0. 197 O << ", #" 198 << ARM_AM::getAddrOpcStr(ARM_AM::getAM2Op(MO3.getImm())) 199 << ARM_AM::getAM2Offset(MO3.getImm()); 200 O << "]"; 201 return; 202 } 203 204 O << ", " 205 << ARM_AM::getAddrOpcStr(ARM_AM::getAM2Op(MO3.getImm())) 206 << getRegisterName(MO2.getReg()); 207 208 if (unsigned ShImm = ARM_AM::getAM2Offset(MO3.getImm())) 209 O << ", " 210 << ARM_AM::getShiftOpcStr(ARM_AM::getAM2ShiftOpc(MO3.getImm())) 211 << " #" << ShImm; 212 O << "]"; 213} 214 215void ARMInstPrinter::printAddrMode2OffsetOperand(const MCInst *MI, 216 unsigned OpNum, 217 raw_ostream &O) { 218 const MCOperand &MO1 = MI->getOperand(OpNum); 219 const MCOperand &MO2 = MI->getOperand(OpNum+1); 220 221 if (!MO1.getReg()) { 222 unsigned ImmOffs = ARM_AM::getAM2Offset(MO2.getImm()); 223 O << '#' 224 << ARM_AM::getAddrOpcStr(ARM_AM::getAM2Op(MO2.getImm())) 225 << ImmOffs; 226 return; 227 } 228 229 O << ARM_AM::getAddrOpcStr(ARM_AM::getAM2Op(MO2.getImm())) 230 << getRegisterName(MO1.getReg()); 231 232 if (unsigned ShImm = ARM_AM::getAM2Offset(MO2.getImm())) 233 O << ", " 234 << ARM_AM::getShiftOpcStr(ARM_AM::getAM2ShiftOpc(MO2.getImm())) 235 << " #" << ShImm; 236} 237 238void ARMInstPrinter::printAddrMode3Operand(const MCInst *MI, unsigned OpNum, 239 raw_ostream &O) { 240 const MCOperand &MO1 = MI->getOperand(OpNum); 241 const MCOperand &MO2 = MI->getOperand(OpNum+1); 242 const MCOperand &MO3 = MI->getOperand(OpNum+2); 243 244 O << '[' << getRegisterName(MO1.getReg()); 245 246 if (MO2.getReg()) { 247 O << ", " << (char)ARM_AM::getAM3Op(MO3.getImm()) 248 << getRegisterName(MO2.getReg()) << ']'; 249 return; 250 } 251 252 if (unsigned ImmOffs = ARM_AM::getAM3Offset(MO3.getImm())) 253 O << ", #" 254 << ARM_AM::getAddrOpcStr(ARM_AM::getAM3Op(MO3.getImm())) 255 << ImmOffs; 256 O << ']'; 257} 258 259void ARMInstPrinter::printAddrMode3OffsetOperand(const MCInst *MI, 260 unsigned OpNum, 261 raw_ostream &O) { 262 const MCOperand &MO1 = MI->getOperand(OpNum); 263 const MCOperand &MO2 = MI->getOperand(OpNum+1); 264 265 if (MO1.getReg()) { 266 O << (char)ARM_AM::getAM3Op(MO2.getImm()) 267 << getRegisterName(MO1.getReg()); 268 return; 269 } 270 271 unsigned ImmOffs = ARM_AM::getAM3Offset(MO2.getImm()); 272 O << '#' 273 << ARM_AM::getAddrOpcStr(ARM_AM::getAM3Op(MO2.getImm())) 274 << ImmOffs; 275} 276 277void ARMInstPrinter::printLdStmModeOperand(const MCInst *MI, unsigned OpNum, 278 raw_ostream &O) { 279 ARM_AM::AMSubMode Mode = ARM_AM::getAM4SubMode(MI->getOperand(OpNum) 280 .getImm()); 281 O << ARM_AM::getAMSubModeStr(Mode); 282} 283 284void ARMInstPrinter::printAddrMode5Operand(const MCInst *MI, unsigned OpNum, 285 raw_ostream &O) { 286 const MCOperand &MO1 = MI->getOperand(OpNum); 287 const MCOperand &MO2 = MI->getOperand(OpNum+1); 288 289 if (!MO1.isReg()) { // FIXME: This is for CP entries, but isn't right. 290 printOperand(MI, OpNum, O); 291 return; 292 } 293 294 O << "[" << getRegisterName(MO1.getReg()); 295 296 if (unsigned ImmOffs = ARM_AM::getAM5Offset(MO2.getImm())) { 297 O << ", #" 298 << ARM_AM::getAddrOpcStr(ARM_AM::getAM5Op(MO2.getImm())) 299 << ImmOffs * 4; 300 } 301 O << "]"; 302} 303 304void ARMInstPrinter::printAddrMode6Operand(const MCInst *MI, unsigned OpNum, 305 raw_ostream &O) { 306 const MCOperand &MO1 = MI->getOperand(OpNum); 307 const MCOperand &MO2 = MI->getOperand(OpNum+1); 308 309 O << "[" << getRegisterName(MO1.getReg()); 310 if (MO2.getImm()) { 311 // FIXME: Both darwin as and GNU as violate ARM docs here. 312 O << ", :" << (MO2.getImm() << 3); 313 } 314 O << "]"; 315} 316 317void ARMInstPrinter::printAddrMode6OffsetOperand(const MCInst *MI, 318 unsigned OpNum, 319 raw_ostream &O) { 320 const MCOperand &MO = MI->getOperand(OpNum); 321 if (MO.getReg() == 0) 322 O << "!"; 323 else 324 O << ", " << getRegisterName(MO.getReg()); 325} 326 327void ARMInstPrinter::printBitfieldInvMaskImmOperand(const MCInst *MI, 328 unsigned OpNum, 329 raw_ostream &O) { 330 const MCOperand &MO = MI->getOperand(OpNum); 331 uint32_t v = ~MO.getImm(); 332 int32_t lsb = CountTrailingZeros_32(v); 333 int32_t width = (32 - CountLeadingZeros_32 (v)) - lsb; 334 assert(MO.isImm() && "Not a valid bf_inv_mask_imm value!"); 335 O << '#' << lsb << ", #" << width; 336} 337 338void ARMInstPrinter::printMemBOption(const MCInst *MI, unsigned OpNum, 339 raw_ostream &O) { 340 unsigned val = MI->getOperand(OpNum).getImm(); 341 O << ARM_MB::MemBOptToString(val); 342} 343 344void ARMInstPrinter::printShiftImmOperand(const MCInst *MI, unsigned OpNum, 345 raw_ostream &O) { 346 unsigned ShiftOp = MI->getOperand(OpNum).getImm(); 347 ARM_AM::ShiftOpc Opc = ARM_AM::getSORegShOp(ShiftOp); 348 switch (Opc) { 349 case ARM_AM::no_shift: 350 return; 351 case ARM_AM::lsl: 352 O << ", lsl #"; 353 break; 354 case ARM_AM::asr: 355 O << ", asr #"; 356 break; 357 default: 358 assert(0 && "unexpected shift opcode for shift immediate operand"); 359 } 360 O << ARM_AM::getSORegOffset(ShiftOp); 361} 362 363void ARMInstPrinter::printRegisterList(const MCInst *MI, unsigned OpNum, 364 raw_ostream &O) { 365 O << "{"; 366 for (unsigned i = OpNum, e = MI->getNumOperands(); i != e; ++i) { 367 if (i != OpNum) O << ", "; 368 O << getRegisterName(MI->getOperand(i).getReg()); 369 } 370 O << "}"; 371} 372 373void ARMInstPrinter::printSetendOperand(const MCInst *MI, unsigned OpNum, 374 raw_ostream &O) { 375 const MCOperand &Op = MI->getOperand(OpNum); 376 if (Op.getImm()) 377 O << "be"; 378 else 379 O << "le"; 380} 381 382void ARMInstPrinter::printCPSOptionOperand(const MCInst *MI, unsigned OpNum, 383 raw_ostream &O) { 384 const MCOperand &Op = MI->getOperand(OpNum); 385 unsigned option = Op.getImm(); 386 unsigned mode = option & 31; 387 bool changemode = option >> 5 & 1; 388 unsigned AIF = option >> 6 & 7; 389 unsigned imod = option >> 9 & 3; 390 if (imod == 2) 391 O << "ie"; 392 else if (imod == 3) 393 O << "id"; 394 O << '\t'; 395 if (imod > 1) { 396 if (AIF & 4) O << 'a'; 397 if (AIF & 2) O << 'i'; 398 if (AIF & 1) O << 'f'; 399 if (AIF > 0 && changemode) O << ", "; 400 } 401 if (changemode) 402 O << '#' << mode; 403} 404 405void ARMInstPrinter::printMSRMaskOperand(const MCInst *MI, unsigned OpNum, 406 raw_ostream &O) { 407 const MCOperand &Op = MI->getOperand(OpNum); 408 unsigned Mask = Op.getImm(); 409 if (Mask) { 410 O << '_'; 411 if (Mask & 8) O << 'f'; 412 if (Mask & 4) O << 's'; 413 if (Mask & 2) O << 'x'; 414 if (Mask & 1) O << 'c'; 415 } 416} 417 418void ARMInstPrinter::printNegZeroOperand(const MCInst *MI, unsigned OpNum, 419 raw_ostream &O) { 420 const MCOperand &Op = MI->getOperand(OpNum); 421 O << '#'; 422 if (Op.getImm() < 0) 423 O << '-' << (-Op.getImm() - 1); 424 else 425 O << Op.getImm(); 426} 427 428void ARMInstPrinter::printPredicateOperand(const MCInst *MI, unsigned OpNum, 429 raw_ostream &O) { 430 ARMCC::CondCodes CC = (ARMCC::CondCodes)MI->getOperand(OpNum).getImm(); 431 if (CC != ARMCC::AL) 432 O << ARMCondCodeToString(CC); 433} 434 435void ARMInstPrinter::printMandatoryPredicateOperand(const MCInst *MI, 436 unsigned OpNum, 437 raw_ostream &O) { 438 ARMCC::CondCodes CC = (ARMCC::CondCodes)MI->getOperand(OpNum).getImm(); 439 O << ARMCondCodeToString(CC); 440} 441 442void ARMInstPrinter::printSBitModifierOperand(const MCInst *MI, unsigned OpNum, 443 raw_ostream &O) { 444 if (MI->getOperand(OpNum).getReg()) { 445 assert(MI->getOperand(OpNum).getReg() == ARM::CPSR && 446 "Expect ARM CPSR register!"); 447 O << 's'; 448 } 449} 450 451void ARMInstPrinter::printNoHashImmediate(const MCInst *MI, unsigned OpNum, 452 raw_ostream &O) { 453 O << MI->getOperand(OpNum).getImm(); 454} 455 456void ARMInstPrinter::printPImmediate(const MCInst *MI, unsigned OpNum, 457 raw_ostream &O) { 458 O << "p" << MI->getOperand(OpNum).getImm(); 459} 460 461void ARMInstPrinter::printCImmediate(const MCInst *MI, unsigned OpNum, 462 raw_ostream &O) { 463 O << "c" << MI->getOperand(OpNum).getImm(); 464} 465 466void ARMInstPrinter::printPCLabel(const MCInst *MI, unsigned OpNum, 467 raw_ostream &O) { 468 llvm_unreachable("Unhandled PC-relative pseudo-instruction!"); 469} 470 471void ARMInstPrinter::printThumbS4ImmOperand(const MCInst *MI, unsigned OpNum, 472 raw_ostream &O) { 473 O << "#" << MI->getOperand(OpNum).getImm() * 4; 474} 475 476void ARMInstPrinter::printThumbITMask(const MCInst *MI, unsigned OpNum, 477 raw_ostream &O) { 478 // (3 - the number of trailing zeros) is the number of then / else. 479 unsigned Mask = MI->getOperand(OpNum).getImm(); 480 unsigned CondBit0 = Mask >> 4 & 1; 481 unsigned NumTZ = CountTrailingZeros_32(Mask); 482 assert(NumTZ <= 3 && "Invalid IT mask!"); 483 for (unsigned Pos = 3, e = NumTZ; Pos > e; --Pos) { 484 bool T = ((Mask >> Pos) & 1) == CondBit0; 485 if (T) 486 O << 't'; 487 else 488 O << 'e'; 489 } 490} 491 492void ARMInstPrinter::printThumbAddrModeRROperand(const MCInst *MI, unsigned Op, 493 raw_ostream &O) { 494 const MCOperand &MO1 = MI->getOperand(Op); 495 const MCOperand &MO2 = MI->getOperand(Op + 1); 496 497 if (!MO1.isReg()) { // FIXME: This is for CP entries, but isn't right. 498 printOperand(MI, Op, O); 499 return; 500 } 501 502 O << "[" << getRegisterName(MO1.getReg()); 503 if (unsigned RegNum = MO2.getReg()) 504 O << ", " << getRegisterName(RegNum); 505 O << "]"; 506} 507 508void ARMInstPrinter::printThumbAddrModeImm5SOperand(const MCInst *MI, 509 unsigned Op, 510 raw_ostream &O, 511 unsigned Scale) { 512 const MCOperand &MO1 = MI->getOperand(Op); 513 const MCOperand &MO2 = MI->getOperand(Op + 1); 514 515 if (!MO1.isReg()) { // FIXME: This is for CP entries, but isn't right. 516 printOperand(MI, Op, O); 517 return; 518 } 519 520 O << "[" << getRegisterName(MO1.getReg()); 521 if (unsigned ImmOffs = MO2.getImm()) 522 O << ", #" << ImmOffs * Scale; 523 O << "]"; 524} 525 526void ARMInstPrinter::printThumbAddrModeImm5S1Operand(const MCInst *MI, 527 unsigned Op, 528 raw_ostream &O) { 529 printThumbAddrModeImm5SOperand(MI, Op, O, 1); 530} 531 532void ARMInstPrinter::printThumbAddrModeImm5S2Operand(const MCInst *MI, 533 unsigned Op, 534 raw_ostream &O) { 535 printThumbAddrModeImm5SOperand(MI, Op, O, 2); 536} 537 538void ARMInstPrinter::printThumbAddrModeImm5S4Operand(const MCInst *MI, 539 unsigned Op, 540 raw_ostream &O) { 541 printThumbAddrModeImm5SOperand(MI, Op, O, 4); 542} 543 544void ARMInstPrinter::printThumbAddrModeSPOperand(const MCInst *MI, unsigned Op, 545 raw_ostream &O) { 546 printThumbAddrModeImm5SOperand(MI, Op, O, 4); 547} 548 549// Constant shifts t2_so_reg is a 2-operand unit corresponding to the Thumb2 550// register with shift forms. 551// REG 0 0 - e.g. R5 552// REG IMM, SH_OPC - e.g. R5, LSL #3 553void ARMInstPrinter::printT2SOOperand(const MCInst *MI, unsigned OpNum, 554 raw_ostream &O) { 555 const MCOperand &MO1 = MI->getOperand(OpNum); 556 const MCOperand &MO2 = MI->getOperand(OpNum+1); 557 558 unsigned Reg = MO1.getReg(); 559 O << getRegisterName(Reg); 560 561 // Print the shift opc. 562 assert(MO2.isImm() && "Not a valid t2_so_reg value!"); 563 ARM_AM::ShiftOpc ShOpc = ARM_AM::getSORegShOp(MO2.getImm()); 564 O << ", " << ARM_AM::getShiftOpcStr(ShOpc); 565 if (ShOpc != ARM_AM::rrx) 566 O << " #" << ARM_AM::getSORegOffset(MO2.getImm()); 567} 568 569void ARMInstPrinter::printAddrModeImm12Operand(const MCInst *MI, unsigned OpNum, 570 raw_ostream &O) { 571 const MCOperand &MO1 = MI->getOperand(OpNum); 572 const MCOperand &MO2 = MI->getOperand(OpNum+1); 573 574 if (!MO1.isReg()) { // FIXME: This is for CP entries, but isn't right. 575 printOperand(MI, OpNum, O); 576 return; 577 } else if (MO1.getReg() == ARM::PC && MO2.isExpr()) { 578 printOperand(MI, OpNum+1, O); 579 return; 580 } 581 582 O << "[" << getRegisterName(MO1.getReg()); 583 584 int32_t OffImm = (int32_t)MO2.getImm(); 585 bool isSub = OffImm < 0; 586 // Special value for #-0. All others are normal. 587 if (OffImm == INT32_MIN) 588 OffImm = 0; 589 if (isSub) 590 O << ", #-" << -OffImm; 591 else if (OffImm > 0) 592 O << ", #" << OffImm; 593 O << "]"; 594} 595 596void ARMInstPrinter::printT2AddrModeImm8Operand(const MCInst *MI, 597 unsigned OpNum, 598 raw_ostream &O) { 599 const MCOperand &MO1 = MI->getOperand(OpNum); 600 const MCOperand &MO2 = MI->getOperand(OpNum+1); 601 602 O << "[" << getRegisterName(MO1.getReg()); 603 604 int32_t OffImm = (int32_t)MO2.getImm(); 605 // Don't print +0. 606 if (OffImm < 0) 607 O << ", #-" << -OffImm; 608 else if (OffImm > 0) 609 O << ", #" << OffImm; 610 O << "]"; 611} 612 613void ARMInstPrinter::printT2AddrModeImm8s4Operand(const MCInst *MI, 614 unsigned OpNum, 615 raw_ostream &O) { 616 const MCOperand &MO1 = MI->getOperand(OpNum); 617 const MCOperand &MO2 = MI->getOperand(OpNum+1); 618 619 O << "[" << getRegisterName(MO1.getReg()); 620 621 int32_t OffImm = (int32_t)MO2.getImm() / 4; 622 // Don't print +0. 623 if (OffImm < 0) 624 O << ", #-" << -OffImm * 4; 625 else if (OffImm > 0) 626 O << ", #" << OffImm * 4; 627 O << "]"; 628} 629 630void ARMInstPrinter::printT2AddrModeImm8OffsetOperand(const MCInst *MI, 631 unsigned OpNum, 632 raw_ostream &O) { 633 const MCOperand &MO1 = MI->getOperand(OpNum); 634 int32_t OffImm = (int32_t)MO1.getImm(); 635 // Don't print +0. 636 if (OffImm < 0) 637 O << "#-" << -OffImm; 638 else if (OffImm > 0) 639 O << "#" << OffImm; 640} 641 642void ARMInstPrinter::printT2AddrModeImm8s4OffsetOperand(const MCInst *MI, 643 unsigned OpNum, 644 raw_ostream &O) { 645 const MCOperand &MO1 = MI->getOperand(OpNum); 646 int32_t OffImm = (int32_t)MO1.getImm() / 4; 647 // Don't print +0. 648 if (OffImm < 0) 649 O << "#-" << -OffImm * 4; 650 else if (OffImm > 0) 651 O << "#" << OffImm * 4; 652} 653 654void ARMInstPrinter::printT2AddrModeSoRegOperand(const MCInst *MI, 655 unsigned OpNum, 656 raw_ostream &O) { 657 const MCOperand &MO1 = MI->getOperand(OpNum); 658 const MCOperand &MO2 = MI->getOperand(OpNum+1); 659 const MCOperand &MO3 = MI->getOperand(OpNum+2); 660 661 O << "[" << getRegisterName(MO1.getReg()); 662 663 assert(MO2.getReg() && "Invalid so_reg load / store address!"); 664 O << ", " << getRegisterName(MO2.getReg()); 665 666 unsigned ShAmt = MO3.getImm(); 667 if (ShAmt) { 668 assert(ShAmt <= 3 && "Not a valid Thumb2 addressing mode!"); 669 O << ", lsl #" << ShAmt; 670 } 671 O << "]"; 672} 673 674void ARMInstPrinter::printVFPf32ImmOperand(const MCInst *MI, unsigned OpNum, 675 raw_ostream &O) { 676 const MCOperand &MO = MI->getOperand(OpNum); 677 O << '#'; 678 if (MO.isFPImm()) { 679 O << (float)MO.getFPImm(); 680 } else { 681 union { 682 uint32_t I; 683 float F; 684 } FPUnion; 685 686 FPUnion.I = MO.getImm(); 687 O << FPUnion.F; 688 } 689} 690 691void ARMInstPrinter::printVFPf64ImmOperand(const MCInst *MI, unsigned OpNum, 692 raw_ostream &O) { 693 const MCOperand &MO = MI->getOperand(OpNum); 694 O << '#'; 695 if (MO.isFPImm()) { 696 O << MO.getFPImm(); 697 } else { 698 // We expect the binary encoding of a floating point number here. 699 union { 700 uint64_t I; 701 double D; 702 } FPUnion; 703 704 FPUnion.I = MO.getImm(); 705 O << FPUnion.D; 706 } 707} 708 709void ARMInstPrinter::printNEONModImmOperand(const MCInst *MI, unsigned OpNum, 710 raw_ostream &O) { 711 unsigned EncodedImm = MI->getOperand(OpNum).getImm(); 712 unsigned EltBits; 713 uint64_t Val = ARM_AM::decodeNEONModImm(EncodedImm, EltBits); 714 O << "#0x" << utohexstr(Val); 715} 716