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