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