ARMAsmPrinter.cpp revision e89a05337a9946040251a5f19165c41b9a1a7b27
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 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 162MachineLocation ARMAsmPrinter:: 163getDebugValueLocation(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 175void 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/// 187bool ARMAsmPrinter::runOnMachineFunction(MachineFunction &MF) { 188 AFI = MF.getInfo<ARMFunctionInfo>(); 189 MCP = MF.getConstantPool(); 190 191 return AsmPrinter::runOnMachineFunction(MF); 192} 193 194void 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 256MCSymbol *ARMAsmPrinter:: 257GetARMSetPICJumpTableLabel2(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 266MCSymbol *ARMAsmPrinter:: 267GetARMJTIPICJumpTableLabel2(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 275MCSymbol *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 282bool 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 320bool 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 333void 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 382void 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 457void 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 566void 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 590static 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 598static MCSymbolRefExpr::VariantKind 599getModifierVariantKind(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 612MCSymbol *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 631void ARMAsmPrinter:: 632EmitMachineConstantPoolValue(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 682void 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 723void 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 775void 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 792static 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 804void 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 814void ARMAsmPrinter::EmitInstruction(const MachineInstr *MI) { 815 unsigned Opc = MI->getOpcode(); 816 switch (Opc) { 817 default: break; 818 case ARM::t2ADDrSPi: 819 case ARM::t2ADDrSPi12: 820 case ARM::t2SUBrSPi: 821 case ARM::t2SUBrSPi12: 822 assert ((MI->getOperand(1).getReg() == ARM::SP) && 823 "Unexpected source register!"); 824 break; 825 826 case ARM::t2MOVi32imm: assert(0 && "Should be lowered by thumb2it pass"); 827 case ARM::DBG_VALUE: { 828 if (isVerbose() && OutStreamer.hasRawTextSupport()) { 829 SmallString<128> TmpStr; 830 raw_svector_ostream OS(TmpStr); 831 PrintDebugValueComment(MI, OS); 832 OutStreamer.EmitRawText(StringRef(OS.str())); 833 } 834 return; 835 } 836 case ARM::tBfar: { 837 MCInst TmpInst; 838 TmpInst.setOpcode(ARM::tBL); 839 TmpInst.addOperand(MCOperand::CreateExpr(MCSymbolRefExpr::Create( 840 MI->getOperand(0).getMBB()->getSymbol(), OutContext))); 841 OutStreamer.EmitInstruction(TmpInst); 842 return; 843 } 844 case ARM::LEApcrel: 845 case ARM::tLEApcrel: 846 case ARM::t2LEApcrel: { 847 // FIXME: Need to also handle globals and externals 848 MCInst TmpInst; 849 TmpInst.setOpcode(MI->getOpcode() == ARM::t2LEApcrel ? ARM::t2ADR 850 : (MI->getOpcode() == ARM::tLEApcrel ? ARM::tADR 851 : ARM::ADR)); 852 populateADROperands(TmpInst, MI->getOperand(0).getReg(), 853 GetCPISymbol(MI->getOperand(1).getIndex()), 854 MI->getOperand(2).getImm(), MI->getOperand(3).getReg(), 855 OutContext); 856 OutStreamer.EmitInstruction(TmpInst); 857 return; 858 } 859 case ARM::LEApcrelJT: 860 case ARM::tLEApcrelJT: 861 case ARM::t2LEApcrelJT: { 862 MCInst TmpInst; 863 TmpInst.setOpcode(MI->getOpcode() == ARM::t2LEApcrelJT ? ARM::t2ADR 864 : (MI->getOpcode() == ARM::tLEApcrelJT ? ARM::tADR 865 : ARM::ADR)); 866 populateADROperands(TmpInst, MI->getOperand(0).getReg(), 867 GetARMJTIPICJumpTableLabel2(MI->getOperand(1).getIndex(), 868 MI->getOperand(2).getImm()), 869 MI->getOperand(3).getImm(), MI->getOperand(4).getReg(), 870 OutContext); 871 OutStreamer.EmitInstruction(TmpInst); 872 return; 873 } 874 case ARM::MOVPCRX: { 875 MCInst TmpInst; 876 TmpInst.setOpcode(ARM::MOVr); 877 TmpInst.addOperand(MCOperand::CreateReg(ARM::PC)); 878 TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); 879 // Add predicate operands. 880 TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 881 TmpInst.addOperand(MCOperand::CreateReg(0)); 882 // Add 's' bit operand (always reg0 for this) 883 TmpInst.addOperand(MCOperand::CreateReg(0)); 884 OutStreamer.EmitInstruction(TmpInst); 885 return; 886 } 887 case ARM::BXr9_CALL: 888 case ARM::BX_CALL: { 889 { 890 MCInst TmpInst; 891 TmpInst.setOpcode(ARM::MOVr); 892 TmpInst.addOperand(MCOperand::CreateReg(ARM::LR)); 893 TmpInst.addOperand(MCOperand::CreateReg(ARM::PC)); 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 } 901 { 902 MCInst TmpInst; 903 TmpInst.setOpcode(ARM::BX); 904 TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); 905 OutStreamer.EmitInstruction(TmpInst); 906 } 907 return; 908 } 909 case ARM::BMOVPCRXr9_CALL: 910 case ARM::BMOVPCRX_CALL: { 911 { 912 MCInst TmpInst; 913 TmpInst.setOpcode(ARM::MOVr); 914 TmpInst.addOperand(MCOperand::CreateReg(ARM::LR)); 915 TmpInst.addOperand(MCOperand::CreateReg(ARM::PC)); 916 // Add predicate operands. 917 TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 918 TmpInst.addOperand(MCOperand::CreateReg(0)); 919 // Add 's' bit operand (always reg0 for this) 920 TmpInst.addOperand(MCOperand::CreateReg(0)); 921 OutStreamer.EmitInstruction(TmpInst); 922 } 923 { 924 MCInst TmpInst; 925 TmpInst.setOpcode(ARM::MOVr); 926 TmpInst.addOperand(MCOperand::CreateReg(ARM::PC)); 927 TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); 928 // Add predicate operands. 929 TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 930 TmpInst.addOperand(MCOperand::CreateReg(0)); 931 // Add 's' bit operand (always reg0 for this) 932 TmpInst.addOperand(MCOperand::CreateReg(0)); 933 OutStreamer.EmitInstruction(TmpInst); 934 } 935 return; 936 } 937 case ARM::MOVi16_ga_pcrel: 938 case ARM::t2MOVi16_ga_pcrel: { 939 MCInst TmpInst; 940 TmpInst.setOpcode(Opc == ARM::MOVi16_ga_pcrel? ARM::MOVi16 : ARM::t2MOVi16); 941 TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); 942 943 unsigned TF = MI->getOperand(1).getTargetFlags(); 944 bool isPIC = TF == ARMII::MO_LO16_NONLAZY_PIC; 945 const GlobalValue *GV = MI->getOperand(1).getGlobal(); 946 MCSymbol *GVSym = GetARMGVSymbol(GV); 947 const MCExpr *GVSymExpr = MCSymbolRefExpr::Create(GVSym, OutContext); 948 if (isPIC) { 949 MCSymbol *LabelSym = getPICLabel(MAI->getPrivateGlobalPrefix(), 950 getFunctionNumber(), 951 MI->getOperand(2).getImm(), OutContext); 952 const MCExpr *LabelSymExpr= MCSymbolRefExpr::Create(LabelSym, OutContext); 953 unsigned PCAdj = (Opc == ARM::MOVi16_ga_pcrel) ? 8 : 4; 954 const MCExpr *PCRelExpr = 955 ARMMCExpr::CreateLower16(MCBinaryExpr::CreateSub(GVSymExpr, 956 MCBinaryExpr::CreateAdd(LabelSymExpr, 957 MCConstantExpr::Create(PCAdj, OutContext), 958 OutContext), OutContext), OutContext); 959 TmpInst.addOperand(MCOperand::CreateExpr(PCRelExpr)); 960 } else { 961 const MCExpr *RefExpr= ARMMCExpr::CreateLower16(GVSymExpr, OutContext); 962 TmpInst.addOperand(MCOperand::CreateExpr(RefExpr)); 963 } 964 965 // Add predicate operands. 966 TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 967 TmpInst.addOperand(MCOperand::CreateReg(0)); 968 // Add 's' bit operand (always reg0 for this) 969 TmpInst.addOperand(MCOperand::CreateReg(0)); 970 OutStreamer.EmitInstruction(TmpInst); 971 return; 972 } 973 case ARM::MOVTi16_ga_pcrel: 974 case ARM::t2MOVTi16_ga_pcrel: { 975 MCInst TmpInst; 976 TmpInst.setOpcode(Opc == ARM::MOVTi16_ga_pcrel 977 ? ARM::MOVTi16 : ARM::t2MOVTi16); 978 TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); 979 TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(1).getReg())); 980 981 unsigned TF = MI->getOperand(2).getTargetFlags(); 982 bool isPIC = TF == ARMII::MO_HI16_NONLAZY_PIC; 983 const GlobalValue *GV = MI->getOperand(2).getGlobal(); 984 MCSymbol *GVSym = GetARMGVSymbol(GV); 985 const MCExpr *GVSymExpr = MCSymbolRefExpr::Create(GVSym, OutContext); 986 if (isPIC) { 987 MCSymbol *LabelSym = getPICLabel(MAI->getPrivateGlobalPrefix(), 988 getFunctionNumber(), 989 MI->getOperand(3).getImm(), OutContext); 990 const MCExpr *LabelSymExpr= MCSymbolRefExpr::Create(LabelSym, OutContext); 991 unsigned PCAdj = (Opc == ARM::MOVTi16_ga_pcrel) ? 8 : 4; 992 const MCExpr *PCRelExpr = 993 ARMMCExpr::CreateUpper16(MCBinaryExpr::CreateSub(GVSymExpr, 994 MCBinaryExpr::CreateAdd(LabelSymExpr, 995 MCConstantExpr::Create(PCAdj, OutContext), 996 OutContext), OutContext), OutContext); 997 TmpInst.addOperand(MCOperand::CreateExpr(PCRelExpr)); 998 } else { 999 const MCExpr *RefExpr= ARMMCExpr::CreateUpper16(GVSymExpr, OutContext); 1000 TmpInst.addOperand(MCOperand::CreateExpr(RefExpr)); 1001 } 1002 // Add predicate operands. 1003 TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1004 TmpInst.addOperand(MCOperand::CreateReg(0)); 1005 // Add 's' bit operand (always reg0 for this) 1006 TmpInst.addOperand(MCOperand::CreateReg(0)); 1007 OutStreamer.EmitInstruction(TmpInst); 1008 return; 1009 } 1010 case ARM::tPICADD: { 1011 // This is a pseudo op for a label + instruction sequence, which looks like: 1012 // LPC0: 1013 // add r0, pc 1014 // This adds the address of LPC0 to r0. 1015 1016 // Emit the label. 1017 OutStreamer.EmitLabel(getPICLabel(MAI->getPrivateGlobalPrefix(), 1018 getFunctionNumber(), MI->getOperand(2).getImm(), 1019 OutContext)); 1020 1021 // Form and emit the add. 1022 MCInst AddInst; 1023 AddInst.setOpcode(ARM::tADDhirr); 1024 AddInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); 1025 AddInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); 1026 AddInst.addOperand(MCOperand::CreateReg(ARM::PC)); 1027 // Add predicate operands. 1028 AddInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1029 AddInst.addOperand(MCOperand::CreateReg(0)); 1030 OutStreamer.EmitInstruction(AddInst); 1031 return; 1032 } 1033 case ARM::PICADD: { 1034 // This is a pseudo op for a label + instruction sequence, which looks like: 1035 // LPC0: 1036 // add r0, pc, r0 1037 // This adds the address of LPC0 to r0. 1038 1039 // Emit the label. 1040 OutStreamer.EmitLabel(getPICLabel(MAI->getPrivateGlobalPrefix(), 1041 getFunctionNumber(), MI->getOperand(2).getImm(), 1042 OutContext)); 1043 1044 // Form and emit the add. 1045 MCInst AddInst; 1046 AddInst.setOpcode(ARM::ADDrr); 1047 AddInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); 1048 AddInst.addOperand(MCOperand::CreateReg(ARM::PC)); 1049 AddInst.addOperand(MCOperand::CreateReg(MI->getOperand(1).getReg())); 1050 // Add predicate operands. 1051 AddInst.addOperand(MCOperand::CreateImm(MI->getOperand(3).getImm())); 1052 AddInst.addOperand(MCOperand::CreateReg(MI->getOperand(4).getReg())); 1053 // Add 's' bit operand (always reg0 for this) 1054 AddInst.addOperand(MCOperand::CreateReg(0)); 1055 OutStreamer.EmitInstruction(AddInst); 1056 return; 1057 } 1058 case ARM::PICSTR: 1059 case ARM::PICSTRB: 1060 case ARM::PICSTRH: 1061 case ARM::PICLDR: 1062 case ARM::PICLDRB: 1063 case ARM::PICLDRH: 1064 case ARM::PICLDRSB: 1065 case ARM::PICLDRSH: { 1066 // This is a pseudo op for a label + instruction sequence, which looks like: 1067 // LPC0: 1068 // OP r0, [pc, r0] 1069 // The LCP0 label is referenced by a constant pool entry in order to get 1070 // a PC-relative address at the ldr instruction. 1071 1072 // Emit the label. 1073 OutStreamer.EmitLabel(getPICLabel(MAI->getPrivateGlobalPrefix(), 1074 getFunctionNumber(), MI->getOperand(2).getImm(), 1075 OutContext)); 1076 1077 // Form and emit the load 1078 unsigned Opcode; 1079 switch (MI->getOpcode()) { 1080 default: 1081 llvm_unreachable("Unexpected opcode!"); 1082 case ARM::PICSTR: Opcode = ARM::STRrs; break; 1083 case ARM::PICSTRB: Opcode = ARM::STRBrs; break; 1084 case ARM::PICSTRH: Opcode = ARM::STRH; break; 1085 case ARM::PICLDR: Opcode = ARM::LDRrs; break; 1086 case ARM::PICLDRB: Opcode = ARM::LDRBrs; break; 1087 case ARM::PICLDRH: Opcode = ARM::LDRH; break; 1088 case ARM::PICLDRSB: Opcode = ARM::LDRSB; break; 1089 case ARM::PICLDRSH: Opcode = ARM::LDRSH; break; 1090 } 1091 MCInst LdStInst; 1092 LdStInst.setOpcode(Opcode); 1093 LdStInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); 1094 LdStInst.addOperand(MCOperand::CreateReg(ARM::PC)); 1095 LdStInst.addOperand(MCOperand::CreateReg(MI->getOperand(1).getReg())); 1096 LdStInst.addOperand(MCOperand::CreateImm(0)); 1097 // Add predicate operands. 1098 LdStInst.addOperand(MCOperand::CreateImm(MI->getOperand(3).getImm())); 1099 LdStInst.addOperand(MCOperand::CreateReg(MI->getOperand(4).getReg())); 1100 OutStreamer.EmitInstruction(LdStInst); 1101 1102 return; 1103 } 1104 case ARM::CONSTPOOL_ENTRY: { 1105 /// CONSTPOOL_ENTRY - This instruction represents a floating constant pool 1106 /// in the function. The first operand is the ID# for this instruction, the 1107 /// second is the index into the MachineConstantPool that this is, the third 1108 /// is the size in bytes of this constant pool entry. 1109 unsigned LabelId = (unsigned)MI->getOperand(0).getImm(); 1110 unsigned CPIdx = (unsigned)MI->getOperand(1).getIndex(); 1111 1112 EmitAlignment(2); 1113 OutStreamer.EmitLabel(GetCPISymbol(LabelId)); 1114 1115 const MachineConstantPoolEntry &MCPE = MCP->getConstants()[CPIdx]; 1116 if (MCPE.isMachineConstantPoolEntry()) 1117 EmitMachineConstantPoolValue(MCPE.Val.MachineCPVal); 1118 else 1119 EmitGlobalConstant(MCPE.Val.ConstVal); 1120 1121 return; 1122 } 1123 case ARM::t2BR_JT: { 1124 // Lower and emit the instruction itself, then the jump table following it. 1125 MCInst TmpInst; 1126 TmpInst.setOpcode(ARM::tMOVgpr2gpr); 1127 TmpInst.addOperand(MCOperand::CreateReg(ARM::PC)); 1128 TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); 1129 // Add predicate operands. 1130 TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1131 TmpInst.addOperand(MCOperand::CreateReg(0)); 1132 OutStreamer.EmitInstruction(TmpInst); 1133 // Output the data for the jump table itself 1134 EmitJump2Table(MI); 1135 return; 1136 } 1137 case ARM::t2TBB_JT: { 1138 // Lower and emit the instruction itself, then the jump table following it. 1139 MCInst TmpInst; 1140 1141 TmpInst.setOpcode(ARM::t2TBB); 1142 TmpInst.addOperand(MCOperand::CreateReg(ARM::PC)); 1143 TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); 1144 // Add predicate operands. 1145 TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1146 TmpInst.addOperand(MCOperand::CreateReg(0)); 1147 OutStreamer.EmitInstruction(TmpInst); 1148 // Output the data for the jump table itself 1149 EmitJump2Table(MI); 1150 // Make sure the next instruction is 2-byte aligned. 1151 EmitAlignment(1); 1152 return; 1153 } 1154 case ARM::t2TBH_JT: { 1155 // Lower and emit the instruction itself, then the jump table following it. 1156 MCInst TmpInst; 1157 1158 TmpInst.setOpcode(ARM::t2TBH); 1159 TmpInst.addOperand(MCOperand::CreateReg(ARM::PC)); 1160 TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); 1161 // Add predicate operands. 1162 TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1163 TmpInst.addOperand(MCOperand::CreateReg(0)); 1164 OutStreamer.EmitInstruction(TmpInst); 1165 // Output the data for the jump table itself 1166 EmitJump2Table(MI); 1167 return; 1168 } 1169 case ARM::tBR_JTr: 1170 case ARM::BR_JTr: { 1171 // Lower and emit the instruction itself, then the jump table following it. 1172 // mov pc, target 1173 MCInst TmpInst; 1174 unsigned Opc = MI->getOpcode() == ARM::BR_JTr ? 1175 ARM::MOVr : ARM::tMOVgpr2gpr; 1176 TmpInst.setOpcode(Opc); 1177 TmpInst.addOperand(MCOperand::CreateReg(ARM::PC)); 1178 TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); 1179 // Add predicate operands. 1180 TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1181 TmpInst.addOperand(MCOperand::CreateReg(0)); 1182 // Add 's' bit operand (always reg0 for this) 1183 if (Opc == ARM::MOVr) 1184 TmpInst.addOperand(MCOperand::CreateReg(0)); 1185 OutStreamer.EmitInstruction(TmpInst); 1186 1187 // Make sure the Thumb jump table is 4-byte aligned. 1188 if (Opc == ARM::tMOVgpr2gpr) 1189 EmitAlignment(2); 1190 1191 // Output the data for the jump table itself 1192 EmitJumpTable(MI); 1193 return; 1194 } 1195 case ARM::BR_JTm: { 1196 // Lower and emit the instruction itself, then the jump table following it. 1197 // ldr pc, target 1198 MCInst TmpInst; 1199 if (MI->getOperand(1).getReg() == 0) { 1200 // literal offset 1201 TmpInst.setOpcode(ARM::LDRi12); 1202 TmpInst.addOperand(MCOperand::CreateReg(ARM::PC)); 1203 TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); 1204 TmpInst.addOperand(MCOperand::CreateImm(MI->getOperand(2).getImm())); 1205 } else { 1206 TmpInst.setOpcode(ARM::LDRrs); 1207 TmpInst.addOperand(MCOperand::CreateReg(ARM::PC)); 1208 TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); 1209 TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(1).getReg())); 1210 TmpInst.addOperand(MCOperand::CreateImm(0)); 1211 } 1212 // Add predicate operands. 1213 TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1214 TmpInst.addOperand(MCOperand::CreateReg(0)); 1215 OutStreamer.EmitInstruction(TmpInst); 1216 1217 // Output the data for the jump table itself 1218 EmitJumpTable(MI); 1219 return; 1220 } 1221 case ARM::BR_JTadd: { 1222 // Lower and emit the instruction itself, then the jump table following it. 1223 // add pc, target, idx 1224 MCInst TmpInst; 1225 TmpInst.setOpcode(ARM::ADDrr); 1226 TmpInst.addOperand(MCOperand::CreateReg(ARM::PC)); 1227 TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); 1228 TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(1).getReg())); 1229 // Add predicate operands. 1230 TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1231 TmpInst.addOperand(MCOperand::CreateReg(0)); 1232 // Add 's' bit operand (always reg0 for this) 1233 TmpInst.addOperand(MCOperand::CreateReg(0)); 1234 OutStreamer.EmitInstruction(TmpInst); 1235 1236 // Output the data for the jump table itself 1237 EmitJumpTable(MI); 1238 return; 1239 } 1240 case ARM::TRAP: { 1241 // Non-Darwin binutils don't yet support the "trap" mnemonic. 1242 // FIXME: Remove this special case when they do. 1243 if (!Subtarget->isTargetDarwin()) { 1244 //.long 0xe7ffdefe @ trap 1245 uint32_t Val = 0xe7ffdefeUL; 1246 OutStreamer.AddComment("trap"); 1247 OutStreamer.EmitIntValue(Val, 4); 1248 return; 1249 } 1250 break; 1251 } 1252 case ARM::tTRAP: { 1253 // Non-Darwin binutils don't yet support the "trap" mnemonic. 1254 // FIXME: Remove this special case when they do. 1255 if (!Subtarget->isTargetDarwin()) { 1256 //.short 57086 @ trap 1257 uint16_t Val = 0xdefe; 1258 OutStreamer.AddComment("trap"); 1259 OutStreamer.EmitIntValue(Val, 2); 1260 return; 1261 } 1262 break; 1263 } 1264 case ARM::t2Int_eh_sjlj_setjmp: 1265 case ARM::t2Int_eh_sjlj_setjmp_nofp: 1266 case ARM::tInt_eh_sjlj_setjmp: { 1267 // Two incoming args: GPR:$src, GPR:$val 1268 // mov $val, pc 1269 // adds $val, #7 1270 // str $val, [$src, #4] 1271 // movs r0, #0 1272 // b 1f 1273 // movs r0, #1 1274 // 1: 1275 unsigned SrcReg = MI->getOperand(0).getReg(); 1276 unsigned ValReg = MI->getOperand(1).getReg(); 1277 MCSymbol *Label = GetARMSJLJEHLabel(); 1278 { 1279 MCInst TmpInst; 1280 TmpInst.setOpcode(ARM::tMOVgpr2tgpr); 1281 TmpInst.addOperand(MCOperand::CreateReg(ValReg)); 1282 TmpInst.addOperand(MCOperand::CreateReg(ARM::PC)); 1283 // 's' bit operand 1284 TmpInst.addOperand(MCOperand::CreateReg(ARM::CPSR)); 1285 OutStreamer.AddComment("eh_setjmp begin"); 1286 OutStreamer.EmitInstruction(TmpInst); 1287 } 1288 { 1289 MCInst TmpInst; 1290 TmpInst.setOpcode(ARM::tADDi3); 1291 TmpInst.addOperand(MCOperand::CreateReg(ValReg)); 1292 // 's' bit operand 1293 TmpInst.addOperand(MCOperand::CreateReg(ARM::CPSR)); 1294 TmpInst.addOperand(MCOperand::CreateReg(ValReg)); 1295 TmpInst.addOperand(MCOperand::CreateImm(7)); 1296 // Predicate. 1297 TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1298 TmpInst.addOperand(MCOperand::CreateReg(0)); 1299 OutStreamer.EmitInstruction(TmpInst); 1300 } 1301 { 1302 MCInst TmpInst; 1303 TmpInst.setOpcode(ARM::tSTRi); 1304 TmpInst.addOperand(MCOperand::CreateReg(ValReg)); 1305 TmpInst.addOperand(MCOperand::CreateReg(SrcReg)); 1306 // The offset immediate is #4. The operand value is scaled by 4 for the 1307 // tSTR instruction. 1308 TmpInst.addOperand(MCOperand::CreateImm(1)); 1309 // Predicate. 1310 TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1311 TmpInst.addOperand(MCOperand::CreateReg(0)); 1312 OutStreamer.EmitInstruction(TmpInst); 1313 } 1314 { 1315 MCInst TmpInst; 1316 TmpInst.setOpcode(ARM::tMOVi8); 1317 TmpInst.addOperand(MCOperand::CreateReg(ARM::R0)); 1318 TmpInst.addOperand(MCOperand::CreateReg(ARM::CPSR)); 1319 TmpInst.addOperand(MCOperand::CreateImm(0)); 1320 // Predicate. 1321 TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1322 TmpInst.addOperand(MCOperand::CreateReg(0)); 1323 OutStreamer.EmitInstruction(TmpInst); 1324 } 1325 { 1326 const MCExpr *SymbolExpr = MCSymbolRefExpr::Create(Label, OutContext); 1327 MCInst TmpInst; 1328 TmpInst.setOpcode(ARM::tB); 1329 TmpInst.addOperand(MCOperand::CreateExpr(SymbolExpr)); 1330 OutStreamer.EmitInstruction(TmpInst); 1331 } 1332 { 1333 MCInst TmpInst; 1334 TmpInst.setOpcode(ARM::tMOVi8); 1335 TmpInst.addOperand(MCOperand::CreateReg(ARM::R0)); 1336 TmpInst.addOperand(MCOperand::CreateReg(ARM::CPSR)); 1337 TmpInst.addOperand(MCOperand::CreateImm(1)); 1338 // Predicate. 1339 TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1340 TmpInst.addOperand(MCOperand::CreateReg(0)); 1341 OutStreamer.AddComment("eh_setjmp end"); 1342 OutStreamer.EmitInstruction(TmpInst); 1343 } 1344 OutStreamer.EmitLabel(Label); 1345 return; 1346 } 1347 1348 case ARM::Int_eh_sjlj_setjmp_nofp: 1349 case ARM::Int_eh_sjlj_setjmp: { 1350 // Two incoming args: GPR:$src, GPR:$val 1351 // add $val, pc, #8 1352 // str $val, [$src, #+4] 1353 // mov r0, #0 1354 // add pc, pc, #0 1355 // mov r0, #1 1356 unsigned SrcReg = MI->getOperand(0).getReg(); 1357 unsigned ValReg = MI->getOperand(1).getReg(); 1358 1359 { 1360 MCInst TmpInst; 1361 TmpInst.setOpcode(ARM::ADDri); 1362 TmpInst.addOperand(MCOperand::CreateReg(ValReg)); 1363 TmpInst.addOperand(MCOperand::CreateReg(ARM::PC)); 1364 TmpInst.addOperand(MCOperand::CreateImm(8)); 1365 // Predicate. 1366 TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1367 TmpInst.addOperand(MCOperand::CreateReg(0)); 1368 // 's' bit operand (always reg0 for this). 1369 TmpInst.addOperand(MCOperand::CreateReg(0)); 1370 OutStreamer.AddComment("eh_setjmp begin"); 1371 OutStreamer.EmitInstruction(TmpInst); 1372 } 1373 { 1374 MCInst TmpInst; 1375 TmpInst.setOpcode(ARM::STRi12); 1376 TmpInst.addOperand(MCOperand::CreateReg(ValReg)); 1377 TmpInst.addOperand(MCOperand::CreateReg(SrcReg)); 1378 TmpInst.addOperand(MCOperand::CreateImm(4)); 1379 // Predicate. 1380 TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1381 TmpInst.addOperand(MCOperand::CreateReg(0)); 1382 OutStreamer.EmitInstruction(TmpInst); 1383 } 1384 { 1385 MCInst TmpInst; 1386 TmpInst.setOpcode(ARM::MOVi); 1387 TmpInst.addOperand(MCOperand::CreateReg(ARM::R0)); 1388 TmpInst.addOperand(MCOperand::CreateImm(0)); 1389 // Predicate. 1390 TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1391 TmpInst.addOperand(MCOperand::CreateReg(0)); 1392 // 's' bit operand (always reg0 for this). 1393 TmpInst.addOperand(MCOperand::CreateReg(0)); 1394 OutStreamer.EmitInstruction(TmpInst); 1395 } 1396 { 1397 MCInst TmpInst; 1398 TmpInst.setOpcode(ARM::ADDri); 1399 TmpInst.addOperand(MCOperand::CreateReg(ARM::PC)); 1400 TmpInst.addOperand(MCOperand::CreateReg(ARM::PC)); 1401 TmpInst.addOperand(MCOperand::CreateImm(0)); 1402 // Predicate. 1403 TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1404 TmpInst.addOperand(MCOperand::CreateReg(0)); 1405 // 's' bit operand (always reg0 for this). 1406 TmpInst.addOperand(MCOperand::CreateReg(0)); 1407 OutStreamer.EmitInstruction(TmpInst); 1408 } 1409 { 1410 MCInst TmpInst; 1411 TmpInst.setOpcode(ARM::MOVi); 1412 TmpInst.addOperand(MCOperand::CreateReg(ARM::R0)); 1413 TmpInst.addOperand(MCOperand::CreateImm(1)); 1414 // Predicate. 1415 TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1416 TmpInst.addOperand(MCOperand::CreateReg(0)); 1417 // 's' bit operand (always reg0 for this). 1418 TmpInst.addOperand(MCOperand::CreateReg(0)); 1419 OutStreamer.AddComment("eh_setjmp end"); 1420 OutStreamer.EmitInstruction(TmpInst); 1421 } 1422 return; 1423 } 1424 case ARM::Int_eh_sjlj_longjmp: { 1425 // ldr sp, [$src, #8] 1426 // ldr $scratch, [$src, #4] 1427 // ldr r7, [$src] 1428 // bx $scratch 1429 unsigned SrcReg = MI->getOperand(0).getReg(); 1430 unsigned ScratchReg = MI->getOperand(1).getReg(); 1431 { 1432 MCInst TmpInst; 1433 TmpInst.setOpcode(ARM::LDRi12); 1434 TmpInst.addOperand(MCOperand::CreateReg(ARM::SP)); 1435 TmpInst.addOperand(MCOperand::CreateReg(SrcReg)); 1436 TmpInst.addOperand(MCOperand::CreateImm(8)); 1437 // Predicate. 1438 TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1439 TmpInst.addOperand(MCOperand::CreateReg(0)); 1440 OutStreamer.EmitInstruction(TmpInst); 1441 } 1442 { 1443 MCInst TmpInst; 1444 TmpInst.setOpcode(ARM::LDRi12); 1445 TmpInst.addOperand(MCOperand::CreateReg(ScratchReg)); 1446 TmpInst.addOperand(MCOperand::CreateReg(SrcReg)); 1447 TmpInst.addOperand(MCOperand::CreateImm(4)); 1448 // Predicate. 1449 TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1450 TmpInst.addOperand(MCOperand::CreateReg(0)); 1451 OutStreamer.EmitInstruction(TmpInst); 1452 } 1453 { 1454 MCInst TmpInst; 1455 TmpInst.setOpcode(ARM::LDRi12); 1456 TmpInst.addOperand(MCOperand::CreateReg(ARM::R7)); 1457 TmpInst.addOperand(MCOperand::CreateReg(SrcReg)); 1458 TmpInst.addOperand(MCOperand::CreateImm(0)); 1459 // Predicate. 1460 TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1461 TmpInst.addOperand(MCOperand::CreateReg(0)); 1462 OutStreamer.EmitInstruction(TmpInst); 1463 } 1464 { 1465 MCInst TmpInst; 1466 TmpInst.setOpcode(ARM::BX); 1467 TmpInst.addOperand(MCOperand::CreateReg(ScratchReg)); 1468 // Predicate. 1469 TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1470 TmpInst.addOperand(MCOperand::CreateReg(0)); 1471 OutStreamer.EmitInstruction(TmpInst); 1472 } 1473 return; 1474 } 1475 case ARM::tInt_eh_sjlj_longjmp: { 1476 // ldr $scratch, [$src, #8] 1477 // mov sp, $scratch 1478 // ldr $scratch, [$src, #4] 1479 // ldr r7, [$src] 1480 // bx $scratch 1481 unsigned SrcReg = MI->getOperand(0).getReg(); 1482 unsigned ScratchReg = MI->getOperand(1).getReg(); 1483 { 1484 MCInst TmpInst; 1485 TmpInst.setOpcode(ARM::tLDRi); 1486 TmpInst.addOperand(MCOperand::CreateReg(ScratchReg)); 1487 TmpInst.addOperand(MCOperand::CreateReg(SrcReg)); 1488 // The offset immediate is #8. The operand value is scaled by 4 for the 1489 // tLDR instruction. 1490 TmpInst.addOperand(MCOperand::CreateImm(2)); 1491 // Predicate. 1492 TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1493 TmpInst.addOperand(MCOperand::CreateReg(0)); 1494 OutStreamer.EmitInstruction(TmpInst); 1495 } 1496 { 1497 MCInst TmpInst; 1498 TmpInst.setOpcode(ARM::tMOVtgpr2gpr); 1499 TmpInst.addOperand(MCOperand::CreateReg(ARM::SP)); 1500 TmpInst.addOperand(MCOperand::CreateReg(ScratchReg)); 1501 // Predicate. 1502 TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1503 TmpInst.addOperand(MCOperand::CreateReg(0)); 1504 OutStreamer.EmitInstruction(TmpInst); 1505 } 1506 { 1507 MCInst TmpInst; 1508 TmpInst.setOpcode(ARM::tLDRi); 1509 TmpInst.addOperand(MCOperand::CreateReg(ScratchReg)); 1510 TmpInst.addOperand(MCOperand::CreateReg(SrcReg)); 1511 TmpInst.addOperand(MCOperand::CreateImm(1)); 1512 // Predicate. 1513 TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1514 TmpInst.addOperand(MCOperand::CreateReg(0)); 1515 OutStreamer.EmitInstruction(TmpInst); 1516 } 1517 { 1518 MCInst TmpInst; 1519 TmpInst.setOpcode(ARM::tLDRr); 1520 TmpInst.addOperand(MCOperand::CreateReg(ARM::R7)); 1521 TmpInst.addOperand(MCOperand::CreateReg(SrcReg)); 1522 TmpInst.addOperand(MCOperand::CreateReg(0)); 1523 // Predicate. 1524 TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1525 TmpInst.addOperand(MCOperand::CreateReg(0)); 1526 OutStreamer.EmitInstruction(TmpInst); 1527 } 1528 { 1529 MCInst TmpInst; 1530 TmpInst.setOpcode(ARM::tBX_RET_vararg); 1531 TmpInst.addOperand(MCOperand::CreateReg(ScratchReg)); 1532 // Predicate. 1533 TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); 1534 TmpInst.addOperand(MCOperand::CreateReg(0)); 1535 OutStreamer.EmitInstruction(TmpInst); 1536 } 1537 return; 1538 } 1539 // These are the pseudos created to comply with stricter operand restrictions 1540 // on ARMv5. Lower them now to "normal" instructions, since all the 1541 // restrictions are already satisfied. 1542 case ARM::MULv5: 1543 EmitPatchedInstruction(MI, ARM::MUL); 1544 return; 1545 case ARM::MLAv5: 1546 EmitPatchedInstruction(MI, ARM::MLA); 1547 return; 1548 case ARM::SMULLv5: 1549 EmitPatchedInstruction(MI, ARM::SMULL); 1550 return; 1551 case ARM::UMULLv5: 1552 EmitPatchedInstruction(MI, ARM::UMULL); 1553 return; 1554 case ARM::SMLALv5: 1555 EmitPatchedInstruction(MI, ARM::SMLAL); 1556 return; 1557 case ARM::UMLALv5: 1558 EmitPatchedInstruction(MI, ARM::UMLAL); 1559 return; 1560 case ARM::UMAALv5: 1561 EmitPatchedInstruction(MI, ARM::UMAAL); 1562 return; 1563 } 1564 1565 MCInst TmpInst; 1566 LowerARMMachineInstrToMCInst(MI, TmpInst, *this); 1567 OutStreamer.EmitInstruction(TmpInst); 1568} 1569 1570//===----------------------------------------------------------------------===// 1571// Target Registry Stuff 1572//===----------------------------------------------------------------------===// 1573 1574static MCInstPrinter *createARMMCInstPrinter(const Target &T, 1575 unsigned SyntaxVariant, 1576 const MCAsmInfo &MAI) { 1577 if (SyntaxVariant == 0) 1578 return new ARMInstPrinter(MAI); 1579 return 0; 1580} 1581 1582// Force static initialization. 1583extern "C" void LLVMInitializeARMAsmPrinter() { 1584 RegisterAsmPrinter<ARMAsmPrinter> X(TheARMTarget); 1585 RegisterAsmPrinter<ARMAsmPrinter> Y(TheThumbTarget); 1586 1587 TargetRegistry::RegisterMCInstPrinter(TheARMTarget, createARMMCInstPrinter); 1588 TargetRegistry::RegisterMCInstPrinter(TheThumbTarget, createARMMCInstPrinter); 1589} 1590 1591