ARMAsmPrinter.cpp revision 53519f015e3e84e9f57b677cc8724805a6009b73
1//===-- ARMAsmPrinter.cpp - Print machine code to an ARM .s file ----------===// 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 file contains a printer that converts from our internal representation 11// of machine-dependent LLVM code to GAS-format ARM assembly language. 12// 13//===----------------------------------------------------------------------===// 14 15#define DEBUG_TYPE "asm-printer" 16#include "ARM.h" 17#include "ARMAsmPrinter.h" 18#include "ARMAddressingModes.h" 19#include "ARMBuildAttrs.h" 20#include "ARMBaseRegisterInfo.h" 21#include "ARMConstantPoolValue.h" 22#include "ARMMachineFunctionInfo.h" 23#include "ARMMCExpr.h" 24#include "ARMTargetMachine.h" 25#include "ARMTargetObjectFile.h" 26#include "InstPrinter/ARMInstPrinter.h" 27#include "llvm/Analysis/DebugInfo.h" 28#include "llvm/Constants.h" 29#include "llvm/Module.h" 30#include "llvm/Type.h" 31#include "llvm/Assembly/Writer.h" 32#include "llvm/CodeGen/MachineModuleInfoImpls.h" 33#include "llvm/CodeGen/MachineFunctionPass.h" 34#include "llvm/CodeGen/MachineJumpTableInfo.h" 35#include "llvm/MC/MCAsmInfo.h" 36#include "llvm/MC/MCAssembler.h" 37#include "llvm/MC/MCContext.h" 38#include "llvm/MC/MCExpr.h" 39#include "llvm/MC/MCInst.h" 40#include "llvm/MC/MCSectionMachO.h" 41#include "llvm/MC/MCObjectStreamer.h" 42#include "llvm/MC/MCStreamer.h" 43#include "llvm/MC/MCSymbol.h" 44#include "llvm/Target/Mangler.h" 45#include "llvm/Target/TargetData.h" 46#include "llvm/Target/TargetMachine.h" 47#include "llvm/Target/TargetOptions.h" 48#include "llvm/Target/TargetRegistry.h" 49#include "llvm/ADT/SmallPtrSet.h" 50#include "llvm/ADT/SmallString.h" 51#include "llvm/ADT/StringExtras.h" 52#include "llvm/Support/CommandLine.h" 53#include "llvm/Support/Debug.h" 54#include "llvm/Support/ErrorHandling.h" 55#include "llvm/Support/raw_ostream.h" 56#include <cctype> 57using namespace llvm; 58 59namespace { 60 61 // Per section and per symbol attributes are not supported. 62 // To implement them we would need the ability to delay this emission 63 // until the assembly file is fully parsed/generated as only then do we 64 // know the symbol and section numbers. 65 class AttributeEmitter { 66 public: 67 virtual void MaybeSwitchVendor(StringRef Vendor) = 0; 68 virtual void EmitAttribute(unsigned Attribute, unsigned Value) = 0; 69 virtual void Finish() = 0; 70 virtual ~AttributeEmitter() {} 71 }; 72 73 class AsmAttributeEmitter : public AttributeEmitter { 74 MCStreamer &Streamer; 75 76 public: 77 AsmAttributeEmitter(MCStreamer &Streamer_) : Streamer(Streamer_) {} 78 void MaybeSwitchVendor(StringRef Vendor) { } 79 80 void EmitAttribute(unsigned Attribute, unsigned Value) { 81 Streamer.EmitRawText("\t.eabi_attribute " + 82 Twine(Attribute) + ", " + Twine(Value)); 83 } 84 85 void Finish() { } 86 }; 87 88 class ObjectAttributeEmitter : public AttributeEmitter { 89 MCObjectStreamer &Streamer; 90 StringRef CurrentVendor; 91 SmallString<64> Contents; 92 93 public: 94 ObjectAttributeEmitter(MCObjectStreamer &Streamer_) : 95 Streamer(Streamer_), CurrentVendor("") { } 96 97 void MaybeSwitchVendor(StringRef Vendor) { 98 assert(!Vendor.empty() && "Vendor cannot be empty."); 99 100 if (CurrentVendor.empty()) 101 CurrentVendor = Vendor; 102 else if (CurrentVendor == Vendor) 103 return; 104 else 105 Finish(); 106 107 CurrentVendor = Vendor; 108 109 assert(Contents.size() == 0); 110 } 111 112 void EmitAttribute(unsigned Attribute, unsigned Value) { 113 // FIXME: should be ULEB 114 Contents += Attribute; 115 Contents += Value; 116 } 117 118 void Finish() { 119 const size_t ContentsSize = Contents.size(); 120 121 // Vendor size + Vendor name + '\0' 122 const size_t VendorHeaderSize = 4 + CurrentVendor.size() + 1; 123 124 // Tag + Tag Size 125 const size_t TagHeaderSize = 1 + 4; 126 127 Streamer.EmitIntValue(VendorHeaderSize + TagHeaderSize + ContentsSize, 4); 128 Streamer.EmitBytes(CurrentVendor, 0); 129 Streamer.EmitIntValue(0, 1); // '\0' 130 131 Streamer.EmitIntValue(ARMBuildAttrs::File, 1); 132 Streamer.EmitIntValue(TagHeaderSize + ContentsSize, 4); 133 134 Streamer.EmitBytes(Contents, 0); 135 136 Contents.clear(); 137 } 138 }; 139 140} // end of anonymous namespace 141 142MachineLocation ARMAsmPrinter:: 143getDebugValueLocation(const MachineInstr *MI) const { 144 MachineLocation Location; 145 assert(MI->getNumOperands() == 4 && "Invalid no. of machine operands!"); 146 // Frame address. Currently handles register +- offset only. 147 if (MI->getOperand(0).isReg() && MI->getOperand(1).isImm()) 148 Location.set(MI->getOperand(0).getReg(), MI->getOperand(1).getImm()); 149 else { 150 DEBUG(dbgs() << "DBG_VALUE instruction ignored! " << *MI << "\n"); 151 } 152 return Location; 153} 154 155void ARMAsmPrinter::EmitFunctionEntryLabel() { 156 if (AFI->isThumbFunction()) { 157 OutStreamer.EmitAssemblerFlag(MCAF_Code16); 158 OutStreamer.EmitThumbFunc(Subtarget->isTargetDarwin()? CurrentFnSym : 0); 159 } 160 161 OutStreamer.EmitLabel(CurrentFnSym); 162} 163 164/// runOnMachineFunction - This uses the EmitInstruction() 165/// method to print assembly for each instruction. 166/// 167bool ARMAsmPrinter::runOnMachineFunction(MachineFunction &MF) { 168 AFI = MF.getInfo<ARMFunctionInfo>(); 169 MCP = MF.getConstantPool(); 170 171 return AsmPrinter::runOnMachineFunction(MF); 172} 173 174void ARMAsmPrinter::printOperand(const MachineInstr *MI, int OpNum, 175 raw_ostream &O, const char *Modifier) { 176 const MachineOperand &MO = MI->getOperand(OpNum); 177 unsigned TF = MO.getTargetFlags(); 178 179 switch (MO.getType()) { 180 default: 181 assert(0 && "<unknown operand type>"); 182 case MachineOperand::MO_Register: { 183 unsigned Reg = MO.getReg(); 184 assert(TargetRegisterInfo::isPhysicalRegister(Reg)); 185 assert(!MO.getSubReg() && "Subregs should be eliminated!"); 186 O << ARMInstPrinter::getRegisterName(Reg); 187 break; 188 } 189 case MachineOperand::MO_Immediate: { 190 int64_t Imm = MO.getImm(); 191 O << '#'; 192 if ((Modifier && strcmp(Modifier, "lo16") == 0) || 193 (TF == ARMII::MO_LO16)) 194 O << ":lower16:"; 195 else if ((Modifier && strcmp(Modifier, "hi16") == 0) || 196 (TF == ARMII::MO_HI16)) 197 O << ":upper16:"; 198 O << Imm; 199 break; 200 } 201 case MachineOperand::MO_MachineBasicBlock: 202 O << *MO.getMBB()->getSymbol(); 203 return; 204 case MachineOperand::MO_GlobalAddress: { 205 const GlobalValue *GV = MO.getGlobal(); 206 if ((Modifier && strcmp(Modifier, "lo16") == 0) || 207 (TF & ARMII::MO_LO16)) 208 O << ":lower16:"; 209 else if ((Modifier && strcmp(Modifier, "hi16") == 0) || 210 (TF & ARMII::MO_HI16)) 211 O << ":upper16:"; 212 O << *Mang->getSymbol(GV); 213 214 printOffset(MO.getOffset(), O); 215 if (TF == ARMII::MO_PLT) 216 O << "(PLT)"; 217 break; 218 } 219 case MachineOperand::MO_ExternalSymbol: { 220 O << *GetExternalSymbolSymbol(MO.getSymbolName()); 221 if (TF == ARMII::MO_PLT) 222 O << "(PLT)"; 223 break; 224 } 225 case MachineOperand::MO_ConstantPoolIndex: 226 O << *GetCPISymbol(MO.getIndex()); 227 break; 228 case MachineOperand::MO_JumpTableIndex: 229 O << *GetJTISymbol(MO.getIndex()); 230 break; 231 } 232} 233 234//===--------------------------------------------------------------------===// 235 236MCSymbol *ARMAsmPrinter:: 237GetARMSetPICJumpTableLabel2(unsigned uid, unsigned uid2, 238 const MachineBasicBlock *MBB) const { 239 SmallString<60> Name; 240 raw_svector_ostream(Name) << MAI->getPrivateGlobalPrefix() 241 << getFunctionNumber() << '_' << uid << '_' << uid2 242 << "_set_" << MBB->getNumber(); 243 return OutContext.GetOrCreateSymbol(Name.str()); 244} 245 246MCSymbol *ARMAsmPrinter:: 247GetARMJTIPICJumpTableLabel2(unsigned uid, unsigned uid2) const { 248 SmallString<60> Name; 249 raw_svector_ostream(Name) << MAI->getPrivateGlobalPrefix() << "JTI" 250 << getFunctionNumber() << '_' << uid << '_' << uid2; 251 return OutContext.GetOrCreateSymbol(Name.str()); 252} 253 254 255MCSymbol *ARMAsmPrinter::GetARMSJLJEHLabel(void) const { 256 SmallString<60> Name; 257 raw_svector_ostream(Name) << MAI->getPrivateGlobalPrefix() << "SJLJEH" 258 << getFunctionNumber(); 259 return OutContext.GetOrCreateSymbol(Name.str()); 260} 261 262bool ARMAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNum, 263 unsigned AsmVariant, const char *ExtraCode, 264 raw_ostream &O) { 265 // Does this asm operand have a single letter operand modifier? 266 if (ExtraCode && ExtraCode[0]) { 267 if (ExtraCode[1] != 0) return true; // Unknown modifier. 268 269 switch (ExtraCode[0]) { 270 default: return true; // Unknown modifier. 271 case 'a': // Print as a memory address. 272 if (MI->getOperand(OpNum).isReg()) { 273 O << "[" 274 << ARMInstPrinter::getRegisterName(MI->getOperand(OpNum).getReg()) 275 << "]"; 276 return false; 277 } 278 // Fallthrough 279 case 'c': // Don't print "#" before an immediate operand. 280 if (!MI->getOperand(OpNum).isImm()) 281 return true; 282 O << MI->getOperand(OpNum).getImm(); 283 return false; 284 case 'P': // Print a VFP double precision register. 285 case 'q': // Print a NEON quad precision register. 286 printOperand(MI, OpNum, O); 287 return false; 288 case 'Q': 289 case 'R': 290 case 'H': 291 // These modifiers are not yet supported. 292 return true; 293 } 294 } 295 296 printOperand(MI, OpNum, O); 297 return false; 298} 299 300bool ARMAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, 301 unsigned OpNum, unsigned AsmVariant, 302 const char *ExtraCode, 303 raw_ostream &O) { 304 if (ExtraCode && ExtraCode[0]) 305 return true; // Unknown modifier. 306 307 const MachineOperand &MO = MI->getOperand(OpNum); 308 assert(MO.isReg() && "unexpected inline asm memory operand"); 309 O << "[" << ARMInstPrinter::getRegisterName(MO.getReg()) << "]"; 310 return false; 311} 312 313void ARMAsmPrinter::EmitStartOfAsmFile(Module &M) { 314 if (Subtarget->isTargetDarwin()) { 315 Reloc::Model RelocM = TM.getRelocationModel(); 316 if (RelocM == Reloc::PIC_ || RelocM == Reloc::DynamicNoPIC) { 317 // Declare all the text sections up front (before the DWARF sections 318 // emitted by AsmPrinter::doInitialization) so the assembler will keep 319 // them together at the beginning of the object file. This helps 320 // avoid out-of-range branches that are due a fundamental limitation of 321 // the way symbol offsets are encoded with the current Darwin ARM 322 // relocations. 323 const TargetLoweringObjectFileMachO &TLOFMacho = 324 static_cast<const TargetLoweringObjectFileMachO &>( 325 getObjFileLowering()); 326 OutStreamer.SwitchSection(TLOFMacho.getTextSection()); 327 OutStreamer.SwitchSection(TLOFMacho.getTextCoalSection()); 328 OutStreamer.SwitchSection(TLOFMacho.getConstTextCoalSection()); 329 if (RelocM == Reloc::DynamicNoPIC) { 330 const MCSection *sect = 331 OutContext.getMachOSection("__TEXT", "__symbol_stub4", 332 MCSectionMachO::S_SYMBOL_STUBS, 333 12, SectionKind::getText()); 334 OutStreamer.SwitchSection(sect); 335 } else { 336 const MCSection *sect = 337 OutContext.getMachOSection("__TEXT", "__picsymbolstub4", 338 MCSectionMachO::S_SYMBOL_STUBS, 339 16, SectionKind::getText()); 340 OutStreamer.SwitchSection(sect); 341 } 342 const MCSection *StaticInitSect = 343 OutContext.getMachOSection("__TEXT", "__StaticInit", 344 MCSectionMachO::S_REGULAR | 345 MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS, 346 SectionKind::getText()); 347 OutStreamer.SwitchSection(StaticInitSect); 348 } 349 } 350 351 // Use unified assembler syntax. 352 OutStreamer.EmitAssemblerFlag(MCAF_SyntaxUnified); 353 354 // Emit ARM Build Attributes 355 if (Subtarget->isTargetELF()) { 356 357 emitAttributes(); 358 } 359} 360 361 362void ARMAsmPrinter::EmitEndOfAsmFile(Module &M) { 363 if (Subtarget->isTargetDarwin()) { 364 // All darwin targets use mach-o. 365 const TargetLoweringObjectFileMachO &TLOFMacho = 366 static_cast<const TargetLoweringObjectFileMachO &>(getObjFileLowering()); 367 MachineModuleInfoMachO &MMIMacho = 368 MMI->getObjFileInfo<MachineModuleInfoMachO>(); 369 370 // Output non-lazy-pointers for external and common global variables. 371 MachineModuleInfoMachO::SymbolListTy Stubs = MMIMacho.GetGVStubList(); 372 373 if (!Stubs.empty()) { 374 // Switch with ".non_lazy_symbol_pointer" directive. 375 OutStreamer.SwitchSection(TLOFMacho.getNonLazySymbolPointerSection()); 376 EmitAlignment(2); 377 for (unsigned i = 0, e = Stubs.size(); i != e; ++i) { 378 // L_foo$stub: 379 OutStreamer.EmitLabel(Stubs[i].first); 380 // .indirect_symbol _foo 381 MachineModuleInfoImpl::StubValueTy &MCSym = Stubs[i].second; 382 OutStreamer.EmitSymbolAttribute(MCSym.getPointer(),MCSA_IndirectSymbol); 383 384 if (MCSym.getInt()) 385 // External to current translation unit. 386 OutStreamer.EmitIntValue(0, 4/*size*/, 0/*addrspace*/); 387 else 388 // Internal to current translation unit. 389 // 390 // When we place the LSDA into the TEXT section, the type info 391 // pointers need to be indirect and pc-rel. We accomplish this by 392 // using NLPs; however, sometimes the types are local to the file. 393 // We need to fill in the value for the NLP in those cases. 394 OutStreamer.EmitValue(MCSymbolRefExpr::Create(MCSym.getPointer(), 395 OutContext), 396 4/*size*/, 0/*addrspace*/); 397 } 398 399 Stubs.clear(); 400 OutStreamer.AddBlankLine(); 401 } 402 403 Stubs = MMIMacho.GetHiddenGVStubList(); 404 if (!Stubs.empty()) { 405 OutStreamer.SwitchSection(getObjFileLowering().getDataSection()); 406 EmitAlignment(2); 407 for (unsigned i = 0, e = Stubs.size(); i != e; ++i) { 408 // L_foo$stub: 409 OutStreamer.EmitLabel(Stubs[i].first); 410 // .long _foo 411 OutStreamer.EmitValue(MCSymbolRefExpr:: 412 Create(Stubs[i].second.getPointer(), 413 OutContext), 414 4/*size*/, 0/*addrspace*/); 415 } 416 417 Stubs.clear(); 418 OutStreamer.AddBlankLine(); 419 } 420 421 // Funny Darwin hack: This flag tells the linker that no global symbols 422 // contain code that falls through to other global symbols (e.g. the obvious 423 // implementation of multiple entry points). If this doesn't occur, the 424 // linker can safely perform dead code stripping. Since LLVM never 425 // generates code that does this, it is always safe to set. 426 OutStreamer.EmitAssemblerFlag(MCAF_SubsectionsViaSymbols); 427 } 428} 429 430//===----------------------------------------------------------------------===// 431// Helper routines for EmitStartOfAsmFile() and EmitEndOfAsmFile() 432// FIXME: 433// The following seem like one-off assembler flags, but they actually need 434// to appear in the .ARM.attributes section in ELF. 435// Instead of subclassing the MCELFStreamer, we do the work here. 436 437void ARMAsmPrinter::emitAttributes() { 438 439 emitARMAttributeSection(); 440 441 AttributeEmitter *AttrEmitter; 442 if (OutStreamer.hasRawTextSupport()) 443 AttrEmitter = new AsmAttributeEmitter(OutStreamer); 444 else { 445 MCObjectStreamer &O = static_cast<MCObjectStreamer&>(OutStreamer); 446 AttrEmitter = new ObjectAttributeEmitter(O); 447 } 448 449 AttrEmitter->MaybeSwitchVendor("aeabi"); 450 451 std::string CPUString = Subtarget->getCPUString(); 452 if (OutStreamer.hasRawTextSupport()) { 453 if (CPUString != "generic") 454 OutStreamer.EmitRawText(StringRef("\t.cpu ") + CPUString); 455 } else { 456 assert(CPUString == "generic" && "Unsupported .cpu attribute for ELF/.o"); 457 // FIXME: Why these defaults? 458 AttrEmitter->EmitAttribute(ARMBuildAttrs::CPU_arch, ARMBuildAttrs::v4T); 459 AttrEmitter->EmitAttribute(ARMBuildAttrs::ARM_ISA_use, 1); 460 AttrEmitter->EmitAttribute(ARMBuildAttrs::THUMB_ISA_use, 1); 461 } 462 463 // FIXME: Emit FPU type 464 if (Subtarget->hasVFP2()) 465 AttrEmitter->EmitAttribute(ARMBuildAttrs::VFP_arch, 2); 466 467 // Signal various FP modes. 468 if (!UnsafeFPMath) { 469 AttrEmitter->EmitAttribute(ARMBuildAttrs::ABI_FP_denormal, 1); 470 AttrEmitter->EmitAttribute(ARMBuildAttrs::ABI_FP_exceptions, 1); 471 } 472 473 if (NoInfsFPMath && NoNaNsFPMath) 474 AttrEmitter->EmitAttribute(ARMBuildAttrs::ABI_FP_number_model, 1); 475 else 476 AttrEmitter->EmitAttribute(ARMBuildAttrs::ABI_FP_number_model, 3); 477 478 // 8-bytes alignment stuff. 479 AttrEmitter->EmitAttribute(ARMBuildAttrs::ABI_align8_needed, 1); 480 AttrEmitter->EmitAttribute(ARMBuildAttrs::ABI_align8_preserved, 1); 481 482 // Hard float. Use both S and D registers and conform to AAPCS-VFP. 483 if (Subtarget->isAAPCS_ABI() && FloatABIType == FloatABI::Hard) { 484 AttrEmitter->EmitAttribute(ARMBuildAttrs::ABI_HardFP_use, 3); 485 AttrEmitter->EmitAttribute(ARMBuildAttrs::ABI_VFP_args, 1); 486 } 487 // FIXME: Should we signal R9 usage? 488 489 AttrEmitter->EmitAttribute(ARMBuildAttrs::DIV_use, 1); 490 491 AttrEmitter->Finish(); 492 delete AttrEmitter; 493} 494 495void ARMAsmPrinter::emitARMAttributeSection() { 496 // <format-version> 497 // [ <section-length> "vendor-name" 498 // [ <file-tag> <size> <attribute>* 499 // | <section-tag> <size> <section-number>* 0 <attribute>* 500 // | <symbol-tag> <size> <symbol-number>* 0 <attribute>* 501 // ]+ 502 // ]* 503 504 if (OutStreamer.hasRawTextSupport()) 505 return; 506 507 const ARMElfTargetObjectFile &TLOFELF = 508 static_cast<const ARMElfTargetObjectFile &> 509 (getObjFileLowering()); 510 511 OutStreamer.SwitchSection(TLOFELF.getAttributesSection()); 512 513 // Format version 514 OutStreamer.EmitIntValue(0x41, 1); 515} 516 517//===----------------------------------------------------------------------===// 518 519static MCSymbol *getPICLabel(const char *Prefix, unsigned FunctionNumber, 520 unsigned LabelId, MCContext &Ctx) { 521 522 MCSymbol *Label = Ctx.GetOrCreateSymbol(Twine(Prefix) 523 + "PC" + Twine(FunctionNumber) + "_" + Twine(LabelId)); 524 return Label; 525} 526 527static MCSymbolRefExpr::VariantKind 528getModifierVariantKind(ARMCP::ARMCPModifier Modifier) { 529 switch (Modifier) { 530 default: llvm_unreachable("Unknown modifier!"); 531 case ARMCP::no_modifier: return MCSymbolRefExpr::VK_None; 532 case ARMCP::TLSGD: return MCSymbolRefExpr::VK_ARM_TLSGD; 533 case ARMCP::TPOFF: return MCSymbolRefExpr::VK_ARM_TPOFF; 534 case ARMCP::GOTTPOFF: return MCSymbolRefExpr::VK_ARM_GOTTPOFF; 535 case ARMCP::GOT: return MCSymbolRefExpr::VK_ARM_GOT; 536 case ARMCP::GOTOFF: return MCSymbolRefExpr::VK_ARM_GOTOFF; 537 } 538 return MCSymbolRefExpr::VK_None; 539} 540 541MCSymbol *ARMAsmPrinter::GetARMGVSymbol(const GlobalValue *GV) { 542 bool isIndirect = Subtarget->isTargetDarwin() && 543 Subtarget->GVIsIndirectSymbol(GV, TM.getRelocationModel()); 544 if (!isIndirect) 545 return Mang->getSymbol(GV); 546 547 // FIXME: Remove this when Darwin transition to @GOT like syntax. 548 MCSymbol *MCSym = GetSymbolWithGlobalValueBase(GV, "$non_lazy_ptr"); 549 MachineModuleInfoMachO &MMIMachO = 550 MMI->getObjFileInfo<MachineModuleInfoMachO>(); 551 MachineModuleInfoImpl::StubValueTy &StubSym = 552 GV->hasHiddenVisibility() ? MMIMachO.getHiddenGVStubEntry(MCSym) : 553 MMIMachO.getGVStubEntry(MCSym); 554 if (StubSym.getPointer() == 0) 555 StubSym = MachineModuleInfoImpl:: 556 StubValueTy(Mang->getSymbol(GV), !GV->hasInternalLinkage()); 557 return MCSym; 558} 559 560void ARMAsmPrinter:: 561EmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV) { 562 int Size = TM.getTargetData()->getTypeAllocSize(MCPV->getType()); 563 564 ARMConstantPoolValue *ACPV = static_cast<ARMConstantPoolValue*>(MCPV); 565 566 MCSymbol *MCSym; 567 if (ACPV->isLSDA()) { 568 SmallString<128> Str; 569 raw_svector_ostream OS(Str); 570 OS << MAI->getPrivateGlobalPrefix() << "_LSDA_" << getFunctionNumber(); 571 MCSym = OutContext.GetOrCreateSymbol(OS.str()); 572 } else if (ACPV->isBlockAddress()) { 573 MCSym = GetBlockAddressSymbol(ACPV->getBlockAddress()); 574 } else if (ACPV->isGlobalValue()) { 575 const GlobalValue *GV = ACPV->getGV(); 576 MCSym = GetARMGVSymbol(GV); 577 } else { 578 assert(ACPV->isExtSymbol() && "unrecognized constant pool value"); 579 MCSym = GetExternalSymbolSymbol(ACPV->getSymbol()); 580 } 581 582 // Create an MCSymbol for the reference. 583 const MCExpr *Expr = 584 MCSymbolRefExpr::Create(MCSym, getModifierVariantKind(ACPV->getModifier()), 585 OutContext); 586 587 if (ACPV->getPCAdjustment()) { 588 MCSymbol *PCLabel = getPICLabel(MAI->getPrivateGlobalPrefix(), 589 getFunctionNumber(), 590 ACPV->getLabelId(), 591 OutContext); 592 const MCExpr *PCRelExpr = MCSymbolRefExpr::Create(PCLabel, OutContext); 593 PCRelExpr = 594 MCBinaryExpr::CreateAdd(PCRelExpr, 595 MCConstantExpr::Create(ACPV->getPCAdjustment(), 596 OutContext), 597 OutContext); 598 if (ACPV->mustAddCurrentAddress()) { 599 // We want "(<expr> - .)", but MC doesn't have a concept of the '.' 600 // label, so just emit a local label end reference that instead. 601 MCSymbol *DotSym = OutContext.CreateTempSymbol(); 602 OutStreamer.EmitLabel(DotSym); 603 const MCExpr *DotExpr = MCSymbolRefExpr::Create(DotSym, OutContext); 604 PCRelExpr = MCBinaryExpr::CreateSub(PCRelExpr, DotExpr, OutContext); 605 } 606 Expr = MCBinaryExpr::CreateSub(Expr, PCRelExpr, OutContext); 607 } 608 OutStreamer.EmitValue(Expr, Size); 609} 610 611void ARMAsmPrinter::EmitJumpTable(const MachineInstr *MI) { 612 unsigned Opcode = MI->getOpcode(); 613 int OpNum = 1; 614 if (Opcode == ARM::BR_JTadd) 615 OpNum = 2; 616 else if (Opcode == ARM::BR_JTm) 617 OpNum = 3; 618 619 const MachineOperand &MO1 = MI->getOperand(OpNum); 620 const MachineOperand &MO2 = MI->getOperand(OpNum+1); // Unique Id 621 unsigned JTI = MO1.getIndex(); 622 623 // Emit a label for the jump table. 624 MCSymbol *JTISymbol = GetARMJTIPICJumpTableLabel2(JTI, MO2.getImm()); 625 OutStreamer.EmitLabel(JTISymbol); 626 627 // Emit each entry of the table. 628 const MachineJumpTableInfo *MJTI = MF->getJumpTableInfo(); 629 const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables(); 630 const std::vector<MachineBasicBlock*> &JTBBs = JT[JTI].MBBs; 631 632 for (unsigned i = 0, e = JTBBs.size(); i != e; ++i) { 633 MachineBasicBlock *MBB = JTBBs[i]; 634 // Construct an MCExpr for the entry. We want a value of the form: 635 // (BasicBlockAddr - TableBeginAddr) 636 // 637 // For example, a table with entries jumping to basic blocks BB0 and BB1 638 // would look like: 639 // LJTI_0_0: 640 // .word (LBB0 - LJTI_0_0) 641 // .word (LBB1 - LJTI_0_0) 642 const MCExpr *Expr = MCSymbolRefExpr::Create(MBB->getSymbol(), OutContext); 643 644 if (TM.getRelocationModel() == Reloc::PIC_) 645 Expr = MCBinaryExpr::CreateSub(Expr, MCSymbolRefExpr::Create(JTISymbol, 646 OutContext), 647 OutContext); 648 OutStreamer.EmitValue(Expr, 4); 649 } 650} 651 652void ARMAsmPrinter::EmitJump2Table(const MachineInstr *MI) { 653 unsigned Opcode = MI->getOpcode(); 654 int OpNum = (Opcode == ARM::t2BR_JT) ? 2 : 1; 655 const MachineOperand &MO1 = MI->getOperand(OpNum); 656 const MachineOperand &MO2 = MI->getOperand(OpNum+1); // Unique Id 657 unsigned JTI = MO1.getIndex(); 658 659 // Emit a label for the jump table. 660 MCSymbol *JTISymbol = GetARMJTIPICJumpTableLabel2(JTI, MO2.getImm()); 661 OutStreamer.EmitLabel(JTISymbol); 662 663 // Emit each entry of the table. 664 const MachineJumpTableInfo *MJTI = MF->getJumpTableInfo(); 665 const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables(); 666 const std::vector<MachineBasicBlock*> &JTBBs = JT[JTI].MBBs; 667 unsigned OffsetWidth = 4; 668 if (MI->getOpcode() == ARM::t2TBB_JT) 669 OffsetWidth = 1; 670 else if (MI->getOpcode() == ARM::t2TBH_JT) 671 OffsetWidth = 2; 672 673 for (unsigned i = 0, e = JTBBs.size(); i != e; ++i) { 674 MachineBasicBlock *MBB = JTBBs[i]; 675 const MCExpr *MBBSymbolExpr = MCSymbolRefExpr::Create(MBB->getSymbol(), 676 OutContext); 677 // If this isn't a TBB or TBH, the entries are direct branch instructions. 678 if (OffsetWidth == 4) { 679 MCInst BrInst; 680 BrInst.setOpcode(ARM::t2B); 681 BrInst.addOperand(MCOperand::CreateExpr(MBBSymbolExpr)); 682 OutStreamer.EmitInstruction(BrInst); 683 continue; 684 } 685 // Otherwise it's an offset from the dispatch instruction. Construct an 686 // MCExpr for the entry. We want a value of the form: 687 // (BasicBlockAddr - TableBeginAddr) / 2 688 // 689 // For example, a TBB table with entries jumping to basic blocks BB0 and BB1 690 // would look like: 691 // LJTI_0_0: 692 // .byte (LBB0 - LJTI_0_0) / 2 693 // .byte (LBB1 - LJTI_0_0) / 2 694 const MCExpr *Expr = 695 MCBinaryExpr::CreateSub(MBBSymbolExpr, 696 MCSymbolRefExpr::Create(JTISymbol, OutContext), 697 OutContext); 698 Expr = MCBinaryExpr::CreateDiv(Expr, MCConstantExpr::Create(2, OutContext), 699 OutContext); 700 OutStreamer.EmitValue(Expr, OffsetWidth); 701 } 702} 703 704void ARMAsmPrinter::PrintDebugValueComment(const MachineInstr *MI, 705 raw_ostream &OS) { 706 unsigned NOps = MI->getNumOperands(); 707 assert(NOps==4); 708 OS << '\t' << MAI->getCommentString() << "DEBUG_VALUE: "; 709 // cast away const; DIetc do not take const operands for some reason. 710 DIVariable V(const_cast<MDNode *>(MI->getOperand(NOps-1).getMetadata())); 711 OS << V.getName(); 712 OS << " <- "; 713 // Frame address. Currently handles register +- offset only. 714 assert(MI->getOperand(0).isReg() && MI->getOperand(1).isImm()); 715 OS << '['; printOperand(MI, 0, OS); OS << '+'; printOperand(MI, 1, OS); 716 OS << ']'; 717 OS << "+"; 718 printOperand(MI, NOps-2, OS); 719} 720 721static void populateADROperands(MCInst &Inst, unsigned Dest, 722 const MCSymbol *Label, 723 unsigned pred, unsigned ccreg, 724 MCContext &Ctx) { 725 const MCExpr *SymbolExpr = MCSymbolRefExpr::Create(Label, Ctx); 726 Inst.addOperand(MCOperand::CreateReg(Dest)); 727 Inst.addOperand(MCOperand::CreateExpr(SymbolExpr)); 728 // Add predicate operands. 729 Inst.addOperand(MCOperand::CreateImm(pred)); 730 Inst.addOperand(MCOperand::CreateReg(ccreg)); 731} 732 733void ARMAsmPrinter::EmitPatchedInstruction(const MachineInstr *MI, 734 unsigned Opcode) { 735 MCInst TmpInst; 736 737 // Emit the instruction as usual, just patch the opcode. 738 LowerARMMachineInstrToMCInst(MI, TmpInst, *this); 739 TmpInst.setOpcode(Opcode); 740 OutStreamer.EmitInstruction(TmpInst); 741} 742 743void ARMAsmPrinter::EmitInstruction(const MachineInstr *MI) { 744 unsigned Opc = MI->getOpcode(); 745 switch (Opc) { 746 default: break; 747 case ARM::t2ADDrSPi: 748 case ARM::t2ADDrSPi12: 749 case ARM::t2SUBrSPi: 750 case ARM::t2SUBrSPi12: 751 assert ((MI->getOperand(1).getReg() == ARM::SP) && 752 "Unexpected source register!"); 753 break; 754 755 case ARM::t2MOVi32imm: assert(0 && "Should be lowered by thumb2it pass"); 756 case ARM::DBG_VALUE: { 757 if (isVerbose() && OutStreamer.hasRawTextSupport()) { 758 SmallString<128> TmpStr; 759 raw_svector_ostream OS(TmpStr); 760 PrintDebugValueComment(MI, OS); 761 OutStreamer.EmitRawText(StringRef(OS.str())); 762 } 763 return; 764 } 765 case ARM::tBfar: { 766 MCInst TmpInst; 767 TmpInst.setOpcode(ARM::tBL); 768 TmpInst.addOperand(MCOperand::CreateExpr(MCSymbolRefExpr::Create( 769 MI->getOperand(0).getMBB()->getSymbol(), OutContext))); 770 OutStreamer.EmitInstruction(TmpInst); 771 return; 772 } 773 case ARM::LEApcrel: 774 case ARM::tLEApcrel: 775 case ARM::t2LEApcrel: { 776 // FIXME: Need to also handle globals and externals 777 MCInst TmpInst; 778 TmpInst.setOpcode(MI->getOpcode() == ARM::t2LEApcrel ? ARM::t2ADR 779 : (MI->getOpcode() == ARM::tLEApcrel ? ARM::tADR 780 : ARM::ADR)); 781 populateADROperands(TmpInst, MI->getOperand(0).getReg(), 782 GetCPISymbol(MI->getOperand(1).getIndex()), 783 MI->getOperand(2).getImm(), MI->getOperand(3).getReg(), 784 OutContext); 785 OutStreamer.EmitInstruction(TmpInst); 786 return; 787 } 788 case ARM::LEApcrelJT: 789 case ARM::tLEApcrelJT: 790 case ARM::t2LEApcrelJT: { 791 MCInst TmpInst; 792 TmpInst.setOpcode(MI->getOpcode() == ARM::t2LEApcrelJT ? ARM::t2ADR 793 : (MI->getOpcode() == ARM::tLEApcrelJT ? ARM::tADR 794 : ARM::ADR)); 795 populateADROperands(TmpInst, MI->getOperand(0).getReg(), 796 GetARMJTIPICJumpTableLabel2(MI->getOperand(1).getIndex(), 797 MI->getOperand(2).getImm()), 798 MI->getOperand(3).getImm(), MI->getOperand(4).getReg(), 799 OutContext); 800 OutStreamer.EmitInstruction(TmpInst); 801 return; 802 } 803 case ARM::MOVPCRX: { 804 MCInst TmpInst; 805 TmpInst.setOpcode(ARM::MOVr); 806 TmpInst.addOperand(MCOperand::CreateReg(ARM::PC)); 807 TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); 808 // Add predicate operands. 809 TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 810 TmpInst.addOperand(MCOperand::CreateReg(0)); 811 // Add 's' bit operand (always reg0 for this) 812 TmpInst.addOperand(MCOperand::CreateReg(0)); 813 OutStreamer.EmitInstruction(TmpInst); 814 return; 815 } 816 case ARM::BXr9_CALL: 817 case ARM::BX_CALL: { 818 { 819 MCInst TmpInst; 820 TmpInst.setOpcode(ARM::MOVr); 821 TmpInst.addOperand(MCOperand::CreateReg(ARM::LR)); 822 TmpInst.addOperand(MCOperand::CreateReg(ARM::PC)); 823 // Add predicate operands. 824 TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 825 TmpInst.addOperand(MCOperand::CreateReg(0)); 826 // Add 's' bit operand (always reg0 for this) 827 TmpInst.addOperand(MCOperand::CreateReg(0)); 828 OutStreamer.EmitInstruction(TmpInst); 829 } 830 { 831 MCInst TmpInst; 832 TmpInst.setOpcode(ARM::BX); 833 TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); 834 OutStreamer.EmitInstruction(TmpInst); 835 } 836 return; 837 } 838 case ARM::BMOVPCRXr9_CALL: 839 case ARM::BMOVPCRX_CALL: { 840 { 841 MCInst TmpInst; 842 TmpInst.setOpcode(ARM::MOVr); 843 TmpInst.addOperand(MCOperand::CreateReg(ARM::LR)); 844 TmpInst.addOperand(MCOperand::CreateReg(ARM::PC)); 845 // Add predicate operands. 846 TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 847 TmpInst.addOperand(MCOperand::CreateReg(0)); 848 // Add 's' bit operand (always reg0 for this) 849 TmpInst.addOperand(MCOperand::CreateReg(0)); 850 OutStreamer.EmitInstruction(TmpInst); 851 } 852 { 853 MCInst TmpInst; 854 TmpInst.setOpcode(ARM::MOVr); 855 TmpInst.addOperand(MCOperand::CreateReg(ARM::PC)); 856 TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); 857 // Add predicate operands. 858 TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 859 TmpInst.addOperand(MCOperand::CreateReg(0)); 860 // Add 's' bit operand (always reg0 for this) 861 TmpInst.addOperand(MCOperand::CreateReg(0)); 862 OutStreamer.EmitInstruction(TmpInst); 863 } 864 return; 865 } 866 case ARM::MOVi16_ga_pcrel: 867 case ARM::t2MOVi16_ga_pcrel: { 868 MCInst TmpInst; 869 TmpInst.setOpcode(Opc == ARM::MOVi16_ga_pcrel? ARM::MOVi16 : ARM::t2MOVi16); 870 TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); 871 872 unsigned TF = MI->getOperand(1).getTargetFlags(); 873 bool isPIC = TF == ARMII::MO_LO16_NONLAZY_PIC; 874 const GlobalValue *GV = MI->getOperand(1).getGlobal(); 875 MCSymbol *GVSym = GetARMGVSymbol(GV); 876 const MCExpr *GVSymExpr = MCSymbolRefExpr::Create(GVSym, OutContext); 877 if (isPIC) { 878 MCSymbol *LabelSym = getPICLabel(MAI->getPrivateGlobalPrefix(), 879 getFunctionNumber(), 880 MI->getOperand(2).getImm(), OutContext); 881 const MCExpr *LabelSymExpr= MCSymbolRefExpr::Create(LabelSym, OutContext); 882 unsigned PCAdj = (Opc == ARM::MOVi16_ga_pcrel) ? 8 : 4; 883 const MCExpr *PCRelExpr = 884 ARMMCExpr::CreateLower16(MCBinaryExpr::CreateSub(GVSymExpr, 885 MCBinaryExpr::CreateAdd(LabelSymExpr, 886 MCConstantExpr::Create(PCAdj, OutContext), 887 OutContext), OutContext), OutContext); 888 TmpInst.addOperand(MCOperand::CreateExpr(PCRelExpr)); 889 } else { 890 const MCExpr *RefExpr= ARMMCExpr::CreateLower16(GVSymExpr, OutContext); 891 TmpInst.addOperand(MCOperand::CreateExpr(RefExpr)); 892 } 893 894 // Add predicate operands. 895 TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 896 TmpInst.addOperand(MCOperand::CreateReg(0)); 897 // Add 's' bit operand (always reg0 for this) 898 TmpInst.addOperand(MCOperand::CreateReg(0)); 899 OutStreamer.EmitInstruction(TmpInst); 900 return; 901 } 902 case ARM::MOVTi16_ga_pcrel: 903 case ARM::t2MOVTi16_ga_pcrel: { 904 MCInst TmpInst; 905 TmpInst.setOpcode(Opc == ARM::MOVTi16_ga_pcrel 906 ? ARM::MOVTi16 : ARM::t2MOVTi16); 907 TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); 908 TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(1).getReg())); 909 910 unsigned TF = MI->getOperand(2).getTargetFlags(); 911 bool isPIC = TF == ARMII::MO_HI16_NONLAZY_PIC; 912 const GlobalValue *GV = MI->getOperand(2).getGlobal(); 913 MCSymbol *GVSym = GetARMGVSymbol(GV); 914 const MCExpr *GVSymExpr = MCSymbolRefExpr::Create(GVSym, OutContext); 915 if (isPIC) { 916 MCSymbol *LabelSym = getPICLabel(MAI->getPrivateGlobalPrefix(), 917 getFunctionNumber(), 918 MI->getOperand(3).getImm(), OutContext); 919 const MCExpr *LabelSymExpr= MCSymbolRefExpr::Create(LabelSym, OutContext); 920 unsigned PCAdj = (Opc == ARM::MOVTi16_ga_pcrel) ? 8 : 4; 921 const MCExpr *PCRelExpr = 922 ARMMCExpr::CreateUpper16(MCBinaryExpr::CreateSub(GVSymExpr, 923 MCBinaryExpr::CreateAdd(LabelSymExpr, 924 MCConstantExpr::Create(PCAdj, OutContext), 925 OutContext), OutContext), OutContext); 926 TmpInst.addOperand(MCOperand::CreateExpr(PCRelExpr)); 927 } else { 928 const MCExpr *RefExpr= ARMMCExpr::CreateUpper16(GVSymExpr, OutContext); 929 TmpInst.addOperand(MCOperand::CreateExpr(RefExpr)); 930 } 931 // Add predicate operands. 932 TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 933 TmpInst.addOperand(MCOperand::CreateReg(0)); 934 // Add 's' bit operand (always reg0 for this) 935 TmpInst.addOperand(MCOperand::CreateReg(0)); 936 OutStreamer.EmitInstruction(TmpInst); 937 return; 938 } 939 case ARM::tPICADD: { 940 // This is a pseudo op for a label + instruction sequence, which looks like: 941 // LPC0: 942 // add r0, pc 943 // This adds the address of LPC0 to r0. 944 945 // Emit the label. 946 OutStreamer.EmitLabel(getPICLabel(MAI->getPrivateGlobalPrefix(), 947 getFunctionNumber(), MI->getOperand(2).getImm(), 948 OutContext)); 949 950 // Form and emit the add. 951 MCInst AddInst; 952 AddInst.setOpcode(ARM::tADDhirr); 953 AddInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); 954 AddInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); 955 AddInst.addOperand(MCOperand::CreateReg(ARM::PC)); 956 // Add predicate operands. 957 AddInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 958 AddInst.addOperand(MCOperand::CreateReg(0)); 959 OutStreamer.EmitInstruction(AddInst); 960 return; 961 } 962 case ARM::PICADD: { 963 // This is a pseudo op for a label + instruction sequence, which looks like: 964 // LPC0: 965 // add r0, pc, r0 966 // This adds the address of LPC0 to r0. 967 968 // Emit the label. 969 OutStreamer.EmitLabel(getPICLabel(MAI->getPrivateGlobalPrefix(), 970 getFunctionNumber(), MI->getOperand(2).getImm(), 971 OutContext)); 972 973 // Form and emit the add. 974 MCInst AddInst; 975 AddInst.setOpcode(ARM::ADDrr); 976 AddInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); 977 AddInst.addOperand(MCOperand::CreateReg(ARM::PC)); 978 AddInst.addOperand(MCOperand::CreateReg(MI->getOperand(1).getReg())); 979 // Add predicate operands. 980 AddInst.addOperand(MCOperand::CreateImm(MI->getOperand(3).getImm())); 981 AddInst.addOperand(MCOperand::CreateReg(MI->getOperand(4).getReg())); 982 // Add 's' bit operand (always reg0 for this) 983 AddInst.addOperand(MCOperand::CreateReg(0)); 984 OutStreamer.EmitInstruction(AddInst); 985 return; 986 } 987 case ARM::PICSTR: 988 case ARM::PICSTRB: 989 case ARM::PICSTRH: 990 case ARM::PICLDR: 991 case ARM::PICLDRB: 992 case ARM::PICLDRH: 993 case ARM::PICLDRSB: 994 case ARM::PICLDRSH: { 995 // This is a pseudo op for a label + instruction sequence, which looks like: 996 // LPC0: 997 // OP r0, [pc, r0] 998 // The LCP0 label is referenced by a constant pool entry in order to get 999 // a PC-relative address at the ldr instruction. 1000 1001 // Emit the label. 1002 OutStreamer.EmitLabel(getPICLabel(MAI->getPrivateGlobalPrefix(), 1003 getFunctionNumber(), MI->getOperand(2).getImm(), 1004 OutContext)); 1005 1006 // Form and emit the load 1007 unsigned Opcode; 1008 switch (MI->getOpcode()) { 1009 default: 1010 llvm_unreachable("Unexpected opcode!"); 1011 case ARM::PICSTR: Opcode = ARM::STRrs; break; 1012 case ARM::PICSTRB: Opcode = ARM::STRBrs; break; 1013 case ARM::PICSTRH: Opcode = ARM::STRH; break; 1014 case ARM::PICLDR: Opcode = ARM::LDRrs; break; 1015 case ARM::PICLDRB: Opcode = ARM::LDRBrs; break; 1016 case ARM::PICLDRH: Opcode = ARM::LDRH; break; 1017 case ARM::PICLDRSB: Opcode = ARM::LDRSB; break; 1018 case ARM::PICLDRSH: Opcode = ARM::LDRSH; break; 1019 } 1020 MCInst LdStInst; 1021 LdStInst.setOpcode(Opcode); 1022 LdStInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); 1023 LdStInst.addOperand(MCOperand::CreateReg(ARM::PC)); 1024 LdStInst.addOperand(MCOperand::CreateReg(MI->getOperand(1).getReg())); 1025 LdStInst.addOperand(MCOperand::CreateImm(0)); 1026 // Add predicate operands. 1027 LdStInst.addOperand(MCOperand::CreateImm(MI->getOperand(3).getImm())); 1028 LdStInst.addOperand(MCOperand::CreateReg(MI->getOperand(4).getReg())); 1029 OutStreamer.EmitInstruction(LdStInst); 1030 1031 return; 1032 } 1033 case ARM::CONSTPOOL_ENTRY: { 1034 /// CONSTPOOL_ENTRY - This instruction represents a floating constant pool 1035 /// in the function. The first operand is the ID# for this instruction, the 1036 /// second is the index into the MachineConstantPool that this is, the third 1037 /// is the size in bytes of this constant pool entry. 1038 unsigned LabelId = (unsigned)MI->getOperand(0).getImm(); 1039 unsigned CPIdx = (unsigned)MI->getOperand(1).getIndex(); 1040 1041 EmitAlignment(2); 1042 OutStreamer.EmitLabel(GetCPISymbol(LabelId)); 1043 1044 const MachineConstantPoolEntry &MCPE = MCP->getConstants()[CPIdx]; 1045 if (MCPE.isMachineConstantPoolEntry()) 1046 EmitMachineConstantPoolValue(MCPE.Val.MachineCPVal); 1047 else 1048 EmitGlobalConstant(MCPE.Val.ConstVal); 1049 1050 return; 1051 } 1052 case ARM::t2BR_JT: { 1053 // Lower and emit the instruction itself, then the jump table following it. 1054 MCInst TmpInst; 1055 TmpInst.setOpcode(ARM::tMOVgpr2gpr); 1056 TmpInst.addOperand(MCOperand::CreateReg(ARM::PC)); 1057 TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); 1058 // Add predicate operands. 1059 TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1060 TmpInst.addOperand(MCOperand::CreateReg(0)); 1061 OutStreamer.EmitInstruction(TmpInst); 1062 // Output the data for the jump table itself 1063 EmitJump2Table(MI); 1064 return; 1065 } 1066 case ARM::t2TBB_JT: { 1067 // Lower and emit the instruction itself, then the jump table following it. 1068 MCInst TmpInst; 1069 1070 TmpInst.setOpcode(ARM::t2TBB); 1071 TmpInst.addOperand(MCOperand::CreateReg(ARM::PC)); 1072 TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); 1073 // Add predicate operands. 1074 TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1075 TmpInst.addOperand(MCOperand::CreateReg(0)); 1076 OutStreamer.EmitInstruction(TmpInst); 1077 // Output the data for the jump table itself 1078 EmitJump2Table(MI); 1079 // Make sure the next instruction is 2-byte aligned. 1080 EmitAlignment(1); 1081 return; 1082 } 1083 case ARM::t2TBH_JT: { 1084 // Lower and emit the instruction itself, then the jump table following it. 1085 MCInst TmpInst; 1086 1087 TmpInst.setOpcode(ARM::t2TBH); 1088 TmpInst.addOperand(MCOperand::CreateReg(ARM::PC)); 1089 TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); 1090 // Add predicate operands. 1091 TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1092 TmpInst.addOperand(MCOperand::CreateReg(0)); 1093 OutStreamer.EmitInstruction(TmpInst); 1094 // Output the data for the jump table itself 1095 EmitJump2Table(MI); 1096 return; 1097 } 1098 case ARM::tBR_JTr: 1099 case ARM::BR_JTr: { 1100 // Lower and emit the instruction itself, then the jump table following it. 1101 // mov pc, target 1102 MCInst TmpInst; 1103 unsigned Opc = MI->getOpcode() == ARM::BR_JTr ? 1104 ARM::MOVr : ARM::tMOVgpr2gpr; 1105 TmpInst.setOpcode(Opc); 1106 TmpInst.addOperand(MCOperand::CreateReg(ARM::PC)); 1107 TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); 1108 // Add predicate operands. 1109 TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1110 TmpInst.addOperand(MCOperand::CreateReg(0)); 1111 // Add 's' bit operand (always reg0 for this) 1112 if (Opc == ARM::MOVr) 1113 TmpInst.addOperand(MCOperand::CreateReg(0)); 1114 OutStreamer.EmitInstruction(TmpInst); 1115 1116 // Make sure the Thumb jump table is 4-byte aligned. 1117 if (Opc == ARM::tMOVgpr2gpr) 1118 EmitAlignment(2); 1119 1120 // Output the data for the jump table itself 1121 EmitJumpTable(MI); 1122 return; 1123 } 1124 case ARM::BR_JTm: { 1125 // Lower and emit the instruction itself, then the jump table following it. 1126 // ldr pc, target 1127 MCInst TmpInst; 1128 if (MI->getOperand(1).getReg() == 0) { 1129 // literal offset 1130 TmpInst.setOpcode(ARM::LDRi12); 1131 TmpInst.addOperand(MCOperand::CreateReg(ARM::PC)); 1132 TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); 1133 TmpInst.addOperand(MCOperand::CreateImm(MI->getOperand(2).getImm())); 1134 } else { 1135 TmpInst.setOpcode(ARM::LDRrs); 1136 TmpInst.addOperand(MCOperand::CreateReg(ARM::PC)); 1137 TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); 1138 TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(1).getReg())); 1139 TmpInst.addOperand(MCOperand::CreateImm(0)); 1140 } 1141 // Add predicate operands. 1142 TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1143 TmpInst.addOperand(MCOperand::CreateReg(0)); 1144 OutStreamer.EmitInstruction(TmpInst); 1145 1146 // Output the data for the jump table itself 1147 EmitJumpTable(MI); 1148 return; 1149 } 1150 case ARM::BR_JTadd: { 1151 // Lower and emit the instruction itself, then the jump table following it. 1152 // add pc, target, idx 1153 MCInst TmpInst; 1154 TmpInst.setOpcode(ARM::ADDrr); 1155 TmpInst.addOperand(MCOperand::CreateReg(ARM::PC)); 1156 TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); 1157 TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(1).getReg())); 1158 // Add predicate operands. 1159 TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1160 TmpInst.addOperand(MCOperand::CreateReg(0)); 1161 // Add 's' bit operand (always reg0 for this) 1162 TmpInst.addOperand(MCOperand::CreateReg(0)); 1163 OutStreamer.EmitInstruction(TmpInst); 1164 1165 // Output the data for the jump table itself 1166 EmitJumpTable(MI); 1167 return; 1168 } 1169 case ARM::TRAP: { 1170 // Non-Darwin binutils don't yet support the "trap" mnemonic. 1171 // FIXME: Remove this special case when they do. 1172 if (!Subtarget->isTargetDarwin()) { 1173 //.long 0xe7ffdefe @ trap 1174 uint32_t Val = 0xe7ffdefeUL; 1175 OutStreamer.AddComment("trap"); 1176 OutStreamer.EmitIntValue(Val, 4); 1177 return; 1178 } 1179 break; 1180 } 1181 case ARM::tTRAP: { 1182 // Non-Darwin binutils don't yet support the "trap" mnemonic. 1183 // FIXME: Remove this special case when they do. 1184 if (!Subtarget->isTargetDarwin()) { 1185 //.short 57086 @ trap 1186 uint16_t Val = 0xdefe; 1187 OutStreamer.AddComment("trap"); 1188 OutStreamer.EmitIntValue(Val, 2); 1189 return; 1190 } 1191 break; 1192 } 1193 case ARM::t2Int_eh_sjlj_setjmp: 1194 case ARM::t2Int_eh_sjlj_setjmp_nofp: 1195 case ARM::tInt_eh_sjlj_setjmp: { 1196 // Two incoming args: GPR:$src, GPR:$val 1197 // mov $val, pc 1198 // adds $val, #7 1199 // str $val, [$src, #4] 1200 // movs r0, #0 1201 // b 1f 1202 // movs r0, #1 1203 // 1: 1204 unsigned SrcReg = MI->getOperand(0).getReg(); 1205 unsigned ValReg = MI->getOperand(1).getReg(); 1206 MCSymbol *Label = GetARMSJLJEHLabel(); 1207 { 1208 MCInst TmpInst; 1209 TmpInst.setOpcode(ARM::tMOVgpr2tgpr); 1210 TmpInst.addOperand(MCOperand::CreateReg(ValReg)); 1211 TmpInst.addOperand(MCOperand::CreateReg(ARM::PC)); 1212 // 's' bit operand 1213 TmpInst.addOperand(MCOperand::CreateReg(ARM::CPSR)); 1214 OutStreamer.AddComment("eh_setjmp begin"); 1215 OutStreamer.EmitInstruction(TmpInst); 1216 } 1217 { 1218 MCInst TmpInst; 1219 TmpInst.setOpcode(ARM::tADDi3); 1220 TmpInst.addOperand(MCOperand::CreateReg(ValReg)); 1221 // 's' bit operand 1222 TmpInst.addOperand(MCOperand::CreateReg(ARM::CPSR)); 1223 TmpInst.addOperand(MCOperand::CreateReg(ValReg)); 1224 TmpInst.addOperand(MCOperand::CreateImm(7)); 1225 // Predicate. 1226 TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1227 TmpInst.addOperand(MCOperand::CreateReg(0)); 1228 OutStreamer.EmitInstruction(TmpInst); 1229 } 1230 { 1231 MCInst TmpInst; 1232 TmpInst.setOpcode(ARM::tSTRi); 1233 TmpInst.addOperand(MCOperand::CreateReg(ValReg)); 1234 TmpInst.addOperand(MCOperand::CreateReg(SrcReg)); 1235 // The offset immediate is #4. The operand value is scaled by 4 for the 1236 // tSTR instruction. 1237 TmpInst.addOperand(MCOperand::CreateImm(1)); 1238 // Predicate. 1239 TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1240 TmpInst.addOperand(MCOperand::CreateReg(0)); 1241 OutStreamer.EmitInstruction(TmpInst); 1242 } 1243 { 1244 MCInst TmpInst; 1245 TmpInst.setOpcode(ARM::tMOVi8); 1246 TmpInst.addOperand(MCOperand::CreateReg(ARM::R0)); 1247 TmpInst.addOperand(MCOperand::CreateReg(ARM::CPSR)); 1248 TmpInst.addOperand(MCOperand::CreateImm(0)); 1249 // Predicate. 1250 TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1251 TmpInst.addOperand(MCOperand::CreateReg(0)); 1252 OutStreamer.EmitInstruction(TmpInst); 1253 } 1254 { 1255 const MCExpr *SymbolExpr = MCSymbolRefExpr::Create(Label, OutContext); 1256 MCInst TmpInst; 1257 TmpInst.setOpcode(ARM::tB); 1258 TmpInst.addOperand(MCOperand::CreateExpr(SymbolExpr)); 1259 OutStreamer.EmitInstruction(TmpInst); 1260 } 1261 { 1262 MCInst TmpInst; 1263 TmpInst.setOpcode(ARM::tMOVi8); 1264 TmpInst.addOperand(MCOperand::CreateReg(ARM::R0)); 1265 TmpInst.addOperand(MCOperand::CreateReg(ARM::CPSR)); 1266 TmpInst.addOperand(MCOperand::CreateImm(1)); 1267 // Predicate. 1268 TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1269 TmpInst.addOperand(MCOperand::CreateReg(0)); 1270 OutStreamer.AddComment("eh_setjmp end"); 1271 OutStreamer.EmitInstruction(TmpInst); 1272 } 1273 OutStreamer.EmitLabel(Label); 1274 return; 1275 } 1276 1277 case ARM::Int_eh_sjlj_setjmp_nofp: 1278 case ARM::Int_eh_sjlj_setjmp: { 1279 // Two incoming args: GPR:$src, GPR:$val 1280 // add $val, pc, #8 1281 // str $val, [$src, #+4] 1282 // mov r0, #0 1283 // add pc, pc, #0 1284 // mov r0, #1 1285 unsigned SrcReg = MI->getOperand(0).getReg(); 1286 unsigned ValReg = MI->getOperand(1).getReg(); 1287 1288 { 1289 MCInst TmpInst; 1290 TmpInst.setOpcode(ARM::ADDri); 1291 TmpInst.addOperand(MCOperand::CreateReg(ValReg)); 1292 TmpInst.addOperand(MCOperand::CreateReg(ARM::PC)); 1293 TmpInst.addOperand(MCOperand::CreateImm(8)); 1294 // Predicate. 1295 TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1296 TmpInst.addOperand(MCOperand::CreateReg(0)); 1297 // 's' bit operand (always reg0 for this). 1298 TmpInst.addOperand(MCOperand::CreateReg(0)); 1299 OutStreamer.AddComment("eh_setjmp begin"); 1300 OutStreamer.EmitInstruction(TmpInst); 1301 } 1302 { 1303 MCInst TmpInst; 1304 TmpInst.setOpcode(ARM::STRi12); 1305 TmpInst.addOperand(MCOperand::CreateReg(ValReg)); 1306 TmpInst.addOperand(MCOperand::CreateReg(SrcReg)); 1307 TmpInst.addOperand(MCOperand::CreateImm(4)); 1308 // Predicate. 1309 TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1310 TmpInst.addOperand(MCOperand::CreateReg(0)); 1311 OutStreamer.EmitInstruction(TmpInst); 1312 } 1313 { 1314 MCInst TmpInst; 1315 TmpInst.setOpcode(ARM::MOVi); 1316 TmpInst.addOperand(MCOperand::CreateReg(ARM::R0)); 1317 TmpInst.addOperand(MCOperand::CreateImm(0)); 1318 // Predicate. 1319 TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1320 TmpInst.addOperand(MCOperand::CreateReg(0)); 1321 // 's' bit operand (always reg0 for this). 1322 TmpInst.addOperand(MCOperand::CreateReg(0)); 1323 OutStreamer.EmitInstruction(TmpInst); 1324 } 1325 { 1326 MCInst TmpInst; 1327 TmpInst.setOpcode(ARM::ADDri); 1328 TmpInst.addOperand(MCOperand::CreateReg(ARM::PC)); 1329 TmpInst.addOperand(MCOperand::CreateReg(ARM::PC)); 1330 TmpInst.addOperand(MCOperand::CreateImm(0)); 1331 // Predicate. 1332 TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1333 TmpInst.addOperand(MCOperand::CreateReg(0)); 1334 // 's' bit operand (always reg0 for this). 1335 TmpInst.addOperand(MCOperand::CreateReg(0)); 1336 OutStreamer.EmitInstruction(TmpInst); 1337 } 1338 { 1339 MCInst TmpInst; 1340 TmpInst.setOpcode(ARM::MOVi); 1341 TmpInst.addOperand(MCOperand::CreateReg(ARM::R0)); 1342 TmpInst.addOperand(MCOperand::CreateImm(1)); 1343 // Predicate. 1344 TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1345 TmpInst.addOperand(MCOperand::CreateReg(0)); 1346 // 's' bit operand (always reg0 for this). 1347 TmpInst.addOperand(MCOperand::CreateReg(0)); 1348 OutStreamer.AddComment("eh_setjmp end"); 1349 OutStreamer.EmitInstruction(TmpInst); 1350 } 1351 return; 1352 } 1353 case ARM::Int_eh_sjlj_longjmp: { 1354 // ldr sp, [$src, #8] 1355 // ldr $scratch, [$src, #4] 1356 // ldr r7, [$src] 1357 // bx $scratch 1358 unsigned SrcReg = MI->getOperand(0).getReg(); 1359 unsigned ScratchReg = MI->getOperand(1).getReg(); 1360 { 1361 MCInst TmpInst; 1362 TmpInst.setOpcode(ARM::LDRi12); 1363 TmpInst.addOperand(MCOperand::CreateReg(ARM::SP)); 1364 TmpInst.addOperand(MCOperand::CreateReg(SrcReg)); 1365 TmpInst.addOperand(MCOperand::CreateImm(8)); 1366 // Predicate. 1367 TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1368 TmpInst.addOperand(MCOperand::CreateReg(0)); 1369 OutStreamer.EmitInstruction(TmpInst); 1370 } 1371 { 1372 MCInst TmpInst; 1373 TmpInst.setOpcode(ARM::LDRi12); 1374 TmpInst.addOperand(MCOperand::CreateReg(ScratchReg)); 1375 TmpInst.addOperand(MCOperand::CreateReg(SrcReg)); 1376 TmpInst.addOperand(MCOperand::CreateImm(4)); 1377 // Predicate. 1378 TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1379 TmpInst.addOperand(MCOperand::CreateReg(0)); 1380 OutStreamer.EmitInstruction(TmpInst); 1381 } 1382 { 1383 MCInst TmpInst; 1384 TmpInst.setOpcode(ARM::LDRi12); 1385 TmpInst.addOperand(MCOperand::CreateReg(ARM::R7)); 1386 TmpInst.addOperand(MCOperand::CreateReg(SrcReg)); 1387 TmpInst.addOperand(MCOperand::CreateImm(0)); 1388 // Predicate. 1389 TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1390 TmpInst.addOperand(MCOperand::CreateReg(0)); 1391 OutStreamer.EmitInstruction(TmpInst); 1392 } 1393 { 1394 MCInst TmpInst; 1395 TmpInst.setOpcode(ARM::BX); 1396 TmpInst.addOperand(MCOperand::CreateReg(ScratchReg)); 1397 // Predicate. 1398 TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1399 TmpInst.addOperand(MCOperand::CreateReg(0)); 1400 OutStreamer.EmitInstruction(TmpInst); 1401 } 1402 return; 1403 } 1404 case ARM::tInt_eh_sjlj_longjmp: { 1405 // ldr $scratch, [$src, #8] 1406 // mov sp, $scratch 1407 // ldr $scratch, [$src, #4] 1408 // ldr r7, [$src] 1409 // bx $scratch 1410 unsigned SrcReg = MI->getOperand(0).getReg(); 1411 unsigned ScratchReg = MI->getOperand(1).getReg(); 1412 { 1413 MCInst TmpInst; 1414 TmpInst.setOpcode(ARM::tLDRi); 1415 TmpInst.addOperand(MCOperand::CreateReg(ScratchReg)); 1416 TmpInst.addOperand(MCOperand::CreateReg(SrcReg)); 1417 // The offset immediate is #8. The operand value is scaled by 4 for the 1418 // tLDR instruction. 1419 TmpInst.addOperand(MCOperand::CreateImm(2)); 1420 // Predicate. 1421 TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1422 TmpInst.addOperand(MCOperand::CreateReg(0)); 1423 OutStreamer.EmitInstruction(TmpInst); 1424 } 1425 { 1426 MCInst TmpInst; 1427 TmpInst.setOpcode(ARM::tMOVtgpr2gpr); 1428 TmpInst.addOperand(MCOperand::CreateReg(ARM::SP)); 1429 TmpInst.addOperand(MCOperand::CreateReg(ScratchReg)); 1430 // Predicate. 1431 TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1432 TmpInst.addOperand(MCOperand::CreateReg(0)); 1433 OutStreamer.EmitInstruction(TmpInst); 1434 } 1435 { 1436 MCInst TmpInst; 1437 TmpInst.setOpcode(ARM::tLDRi); 1438 TmpInst.addOperand(MCOperand::CreateReg(ScratchReg)); 1439 TmpInst.addOperand(MCOperand::CreateReg(SrcReg)); 1440 TmpInst.addOperand(MCOperand::CreateImm(1)); 1441 // Predicate. 1442 TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1443 TmpInst.addOperand(MCOperand::CreateReg(0)); 1444 OutStreamer.EmitInstruction(TmpInst); 1445 } 1446 { 1447 MCInst TmpInst; 1448 TmpInst.setOpcode(ARM::tLDRr); 1449 TmpInst.addOperand(MCOperand::CreateReg(ARM::R7)); 1450 TmpInst.addOperand(MCOperand::CreateReg(SrcReg)); 1451 TmpInst.addOperand(MCOperand::CreateReg(0)); 1452 // Predicate. 1453 TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1454 TmpInst.addOperand(MCOperand::CreateReg(0)); 1455 OutStreamer.EmitInstruction(TmpInst); 1456 } 1457 { 1458 MCInst TmpInst; 1459 TmpInst.setOpcode(ARM::tBX_RET_vararg); 1460 TmpInst.addOperand(MCOperand::CreateReg(ScratchReg)); 1461 // Predicate. 1462 TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1463 TmpInst.addOperand(MCOperand::CreateReg(0)); 1464 OutStreamer.EmitInstruction(TmpInst); 1465 } 1466 return; 1467 } 1468 // These are the pseudos created to comply with stricter operand restrictions 1469 // on ARMv5. Lower them now to "normal" instructions, since all the 1470 // restrictions are already satisfied. 1471 case ARM::MULv5: 1472 EmitPatchedInstruction(MI, ARM::MUL); 1473 return; 1474 case ARM::MLAv5: 1475 EmitPatchedInstruction(MI, ARM::MLA); 1476 return; 1477 case ARM::SMULLv5: 1478 EmitPatchedInstruction(MI, ARM::SMULL); 1479 return; 1480 case ARM::UMULLv5: 1481 EmitPatchedInstruction(MI, ARM::UMULL); 1482 return; 1483 case ARM::SMLALv5: 1484 EmitPatchedInstruction(MI, ARM::SMLAL); 1485 return; 1486 case ARM::UMLALv5: 1487 EmitPatchedInstruction(MI, ARM::UMLAL); 1488 return; 1489 case ARM::UMAALv5: 1490 EmitPatchedInstruction(MI, ARM::UMAAL); 1491 return; 1492 } 1493 1494 MCInst TmpInst; 1495 LowerARMMachineInstrToMCInst(MI, TmpInst, *this); 1496 OutStreamer.EmitInstruction(TmpInst); 1497} 1498 1499//===----------------------------------------------------------------------===// 1500// Target Registry Stuff 1501//===----------------------------------------------------------------------===// 1502 1503static MCInstPrinter *createARMMCInstPrinter(const Target &T, 1504 unsigned SyntaxVariant, 1505 const MCAsmInfo &MAI) { 1506 if (SyntaxVariant == 0) 1507 return new ARMInstPrinter(MAI); 1508 return 0; 1509} 1510 1511// Force static initialization. 1512extern "C" void LLVMInitializeARMAsmPrinter() { 1513 RegisterAsmPrinter<ARMAsmPrinter> X(TheARMTarget); 1514 RegisterAsmPrinter<ARMAsmPrinter> Y(TheThumbTarget); 1515 1516 TargetRegistry::RegisterMCInstPrinter(TheARMTarget, createARMMCInstPrinter); 1517 TargetRegistry::RegisterMCInstPrinter(TheThumbTarget, createARMMCInstPrinter); 1518} 1519 1520