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