X86AsmPrinter.cpp revision 212793
1//===-- X86AsmPrinter.cpp - Convert X86 LLVM code to AT&T assembly --------===// 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 X86 machine code. 12// 13//===----------------------------------------------------------------------===// 14 15#include "X86AsmPrinter.h" 16#include "AsmPrinter/X86ATTInstPrinter.h" 17#include "AsmPrinter/X86IntelInstPrinter.h" 18#include "X86MCInstLower.h" 19#include "X86.h" 20#include "X86COFFMachineModuleInfo.h" 21#include "X86MachineFunctionInfo.h" 22#include "X86TargetMachine.h" 23#include "llvm/CallingConv.h" 24#include "llvm/DerivedTypes.h" 25#include "llvm/Module.h" 26#include "llvm/Type.h" 27#include "llvm/Analysis/DebugInfo.h" 28#include "llvm/Assembly/Writer.h" 29#include "llvm/MC/MCAsmInfo.h" 30#include "llvm/MC/MCContext.h" 31#include "llvm/MC/MCExpr.h" 32#include "llvm/MC/MCSectionMachO.h" 33#include "llvm/MC/MCStreamer.h" 34#include "llvm/MC/MCSymbol.h" 35#include "llvm/CodeGen/MachineJumpTableInfo.h" 36#include "llvm/CodeGen/MachineModuleInfoImpls.h" 37#include "llvm/CodeGen/TargetLoweringObjectFileImpl.h" 38#include "llvm/Support/COFF.h" 39#include "llvm/Support/Debug.h" 40#include "llvm/Support/ErrorHandling.h" 41#include "llvm/Target/Mangler.h" 42#include "llvm/Target/TargetOptions.h" 43#include "llvm/Target/TargetRegistry.h" 44#include "llvm/ADT/SmallString.h" 45using namespace llvm; 46 47//===----------------------------------------------------------------------===// 48// Primitive Helper Functions. 49//===----------------------------------------------------------------------===// 50 51void X86AsmPrinter::PrintPICBaseSymbol(raw_ostream &O) const { 52 const TargetLowering *TLI = TM.getTargetLowering(); 53 O << *static_cast<const X86TargetLowering*>(TLI)->getPICBaseSymbol(MF, 54 OutContext); 55} 56 57/// runOnMachineFunction - Emit the function body. 58/// 59bool X86AsmPrinter::runOnMachineFunction(MachineFunction &MF) { 60 SetupMachineFunction(MF); 61 62 if (Subtarget->isTargetCOFF()) { 63 bool Intrn = MF.getFunction()->hasInternalLinkage(); 64 OutStreamer.BeginCOFFSymbolDef(CurrentFnSym); 65 OutStreamer.EmitCOFFSymbolStorageClass(Intrn ? COFF::IMAGE_SYM_CLASS_STATIC 66 : COFF::IMAGE_SYM_CLASS_EXTERNAL); 67 OutStreamer.EmitCOFFSymbolType(COFF::IMAGE_SYM_DTYPE_FUNCTION 68 << COFF::SCT_COMPLEX_TYPE_SHIFT); 69 OutStreamer.EndCOFFSymbolDef(); 70 } 71 72 // Have common code print out the function header with linkage info etc. 73 EmitFunctionHeader(); 74 75 // Emit the rest of the function body. 76 EmitFunctionBody(); 77 78 // We didn't modify anything. 79 return false; 80} 81 82/// printSymbolOperand - Print a raw symbol reference operand. This handles 83/// jump tables, constant pools, global address and external symbols, all of 84/// which print to a label with various suffixes for relocation types etc. 85void X86AsmPrinter::printSymbolOperand(const MachineOperand &MO, 86 raw_ostream &O) { 87 switch (MO.getType()) { 88 default: llvm_unreachable("unknown symbol type!"); 89 case MachineOperand::MO_JumpTableIndex: 90 O << *GetJTISymbol(MO.getIndex()); 91 break; 92 case MachineOperand::MO_ConstantPoolIndex: 93 O << *GetCPISymbol(MO.getIndex()); 94 printOffset(MO.getOffset(), O); 95 break; 96 case MachineOperand::MO_GlobalAddress: { 97 const GlobalValue *GV = MO.getGlobal(); 98 99 MCSymbol *GVSym; 100 if (MO.getTargetFlags() == X86II::MO_DARWIN_STUB) 101 GVSym = GetSymbolWithGlobalValueBase(GV, "$stub"); 102 else if (MO.getTargetFlags() == X86II::MO_DARWIN_NONLAZY || 103 MO.getTargetFlags() == X86II::MO_DARWIN_NONLAZY_PIC_BASE || 104 MO.getTargetFlags() == X86II::MO_DARWIN_HIDDEN_NONLAZY_PIC_BASE) 105 GVSym = GetSymbolWithGlobalValueBase(GV, "$non_lazy_ptr"); 106 else 107 GVSym = Mang->getSymbol(GV); 108 109 // Handle dllimport linkage. 110 if (MO.getTargetFlags() == X86II::MO_DLLIMPORT) 111 GVSym = OutContext.GetOrCreateSymbol(Twine("__imp_") + GVSym->getName()); 112 113 if (MO.getTargetFlags() == X86II::MO_DARWIN_NONLAZY || 114 MO.getTargetFlags() == X86II::MO_DARWIN_NONLAZY_PIC_BASE) { 115 MCSymbol *Sym = GetSymbolWithGlobalValueBase(GV, "$non_lazy_ptr"); 116 MachineModuleInfoImpl::StubValueTy &StubSym = 117 MMI->getObjFileInfo<MachineModuleInfoMachO>().getGVStubEntry(Sym); 118 if (StubSym.getPointer() == 0) 119 StubSym = MachineModuleInfoImpl:: 120 StubValueTy(Mang->getSymbol(GV), !GV->hasInternalLinkage()); 121 } else if (MO.getTargetFlags() == X86II::MO_DARWIN_HIDDEN_NONLAZY_PIC_BASE){ 122 MCSymbol *Sym = GetSymbolWithGlobalValueBase(GV, "$non_lazy_ptr"); 123 MachineModuleInfoImpl::StubValueTy &StubSym = 124 MMI->getObjFileInfo<MachineModuleInfoMachO>().getHiddenGVStubEntry(Sym); 125 if (StubSym.getPointer() == 0) 126 StubSym = MachineModuleInfoImpl:: 127 StubValueTy(Mang->getSymbol(GV), !GV->hasInternalLinkage()); 128 } else if (MO.getTargetFlags() == X86II::MO_DARWIN_STUB) { 129 MCSymbol *Sym = GetSymbolWithGlobalValueBase(GV, "$stub"); 130 MachineModuleInfoImpl::StubValueTy &StubSym = 131 MMI->getObjFileInfo<MachineModuleInfoMachO>().getFnStubEntry(Sym); 132 if (StubSym.getPointer() == 0) 133 StubSym = MachineModuleInfoImpl:: 134 StubValueTy(Mang->getSymbol(GV), !GV->hasInternalLinkage()); 135 } 136 137 // If the name begins with a dollar-sign, enclose it in parens. We do this 138 // to avoid having it look like an integer immediate to the assembler. 139 if (GVSym->getName()[0] != '$') 140 O << *GVSym; 141 else 142 O << '(' << *GVSym << ')'; 143 printOffset(MO.getOffset(), O); 144 break; 145 } 146 case MachineOperand::MO_ExternalSymbol: { 147 const MCSymbol *SymToPrint; 148 if (MO.getTargetFlags() == X86II::MO_DARWIN_STUB) { 149 SmallString<128> TempNameStr; 150 TempNameStr += StringRef(MO.getSymbolName()); 151 TempNameStr += StringRef("$stub"); 152 153 MCSymbol *Sym = GetExternalSymbolSymbol(TempNameStr.str()); 154 MachineModuleInfoImpl::StubValueTy &StubSym = 155 MMI->getObjFileInfo<MachineModuleInfoMachO>().getFnStubEntry(Sym); 156 if (StubSym.getPointer() == 0) { 157 TempNameStr.erase(TempNameStr.end()-5, TempNameStr.end()); 158 StubSym = MachineModuleInfoImpl:: 159 StubValueTy(OutContext.GetOrCreateSymbol(TempNameStr.str()), 160 true); 161 } 162 SymToPrint = StubSym.getPointer(); 163 } else { 164 SymToPrint = GetExternalSymbolSymbol(MO.getSymbolName()); 165 } 166 167 // If the name begins with a dollar-sign, enclose it in parens. We do this 168 // to avoid having it look like an integer immediate to the assembler. 169 if (SymToPrint->getName()[0] != '$') 170 O << *SymToPrint; 171 else 172 O << '(' << *SymToPrint << '('; 173 break; 174 } 175 } 176 177 switch (MO.getTargetFlags()) { 178 default: 179 llvm_unreachable("Unknown target flag on GV operand"); 180 case X86II::MO_NO_FLAG: // No flag. 181 break; 182 case X86II::MO_DARWIN_NONLAZY: 183 case X86II::MO_DLLIMPORT: 184 case X86II::MO_DARWIN_STUB: 185 // These affect the name of the symbol, not any suffix. 186 break; 187 case X86II::MO_GOT_ABSOLUTE_ADDRESS: 188 O << " + [.-"; 189 PrintPICBaseSymbol(O); 190 O << ']'; 191 break; 192 case X86II::MO_PIC_BASE_OFFSET: 193 case X86II::MO_DARWIN_NONLAZY_PIC_BASE: 194 case X86II::MO_DARWIN_HIDDEN_NONLAZY_PIC_BASE: 195 O << '-'; 196 PrintPICBaseSymbol(O); 197 break; 198 case X86II::MO_TLSGD: O << "@TLSGD"; break; 199 case X86II::MO_GOTTPOFF: O << "@GOTTPOFF"; break; 200 case X86II::MO_INDNTPOFF: O << "@INDNTPOFF"; break; 201 case X86II::MO_TPOFF: O << "@TPOFF"; break; 202 case X86II::MO_NTPOFF: O << "@NTPOFF"; break; 203 case X86II::MO_GOTPCREL: O << "@GOTPCREL"; break; 204 case X86II::MO_GOT: O << "@GOT"; break; 205 case X86II::MO_GOTOFF: O << "@GOTOFF"; break; 206 case X86II::MO_PLT: O << "@PLT"; break; 207 case X86II::MO_TLVP: O << "@TLVP"; break; 208 case X86II::MO_TLVP_PIC_BASE: 209 O << "@TLVP" << '-'; 210 PrintPICBaseSymbol(O); 211 break; 212 } 213} 214 215/// print_pcrel_imm - This is used to print an immediate value that ends up 216/// being encoded as a pc-relative value. These print slightly differently, for 217/// example, a $ is not emitted. 218void X86AsmPrinter::print_pcrel_imm(const MachineInstr *MI, unsigned OpNo, 219 raw_ostream &O) { 220 const MachineOperand &MO = MI->getOperand(OpNo); 221 switch (MO.getType()) { 222 default: llvm_unreachable("Unknown pcrel immediate operand"); 223 case MachineOperand::MO_Register: 224 // pc-relativeness was handled when computing the value in the reg. 225 printOperand(MI, OpNo, O); 226 return; 227 case MachineOperand::MO_Immediate: 228 O << MO.getImm(); 229 return; 230 case MachineOperand::MO_MachineBasicBlock: 231 O << *MO.getMBB()->getSymbol(); 232 return; 233 case MachineOperand::MO_GlobalAddress: 234 case MachineOperand::MO_ExternalSymbol: 235 printSymbolOperand(MO, O); 236 return; 237 } 238} 239 240 241void X86AsmPrinter::printOperand(const MachineInstr *MI, unsigned OpNo, 242 raw_ostream &O, const char *Modifier) { 243 const MachineOperand &MO = MI->getOperand(OpNo); 244 switch (MO.getType()) { 245 default: llvm_unreachable("unknown operand type!"); 246 case MachineOperand::MO_Register: { 247 O << '%'; 248 unsigned Reg = MO.getReg(); 249 if (Modifier && strncmp(Modifier, "subreg", strlen("subreg")) == 0) { 250 EVT VT = (strcmp(Modifier+6,"64") == 0) ? 251 MVT::i64 : ((strcmp(Modifier+6, "32") == 0) ? MVT::i32 : 252 ((strcmp(Modifier+6,"16") == 0) ? MVT::i16 : MVT::i8)); 253 Reg = getX86SubSuperRegister(Reg, VT); 254 } 255 O << X86ATTInstPrinter::getRegisterName(Reg); 256 return; 257 } 258 259 case MachineOperand::MO_Immediate: 260 O << '$' << MO.getImm(); 261 return; 262 263 case MachineOperand::MO_JumpTableIndex: 264 case MachineOperand::MO_ConstantPoolIndex: 265 case MachineOperand::MO_GlobalAddress: 266 case MachineOperand::MO_ExternalSymbol: { 267 O << '$'; 268 printSymbolOperand(MO, O); 269 break; 270 } 271 } 272} 273 274void X86AsmPrinter::printSSECC(const MachineInstr *MI, unsigned Op, 275 raw_ostream &O) { 276 unsigned char value = MI->getOperand(Op).getImm(); 277 assert(value <= 7 && "Invalid ssecc argument!"); 278 switch (value) { 279 case 0: O << "eq"; break; 280 case 1: O << "lt"; break; 281 case 2: O << "le"; break; 282 case 3: O << "unord"; break; 283 case 4: O << "neq"; break; 284 case 5: O << "nlt"; break; 285 case 6: O << "nle"; break; 286 case 7: O << "ord"; break; 287 } 288} 289 290void X86AsmPrinter::printLeaMemReference(const MachineInstr *MI, unsigned Op, 291 raw_ostream &O, const char *Modifier) { 292 const MachineOperand &BaseReg = MI->getOperand(Op); 293 const MachineOperand &IndexReg = MI->getOperand(Op+2); 294 const MachineOperand &DispSpec = MI->getOperand(Op+3); 295 296 // If we really don't want to print out (rip), don't. 297 bool HasBaseReg = BaseReg.getReg() != 0; 298 if (HasBaseReg && Modifier && !strcmp(Modifier, "no-rip") && 299 BaseReg.getReg() == X86::RIP) 300 HasBaseReg = false; 301 302 // HasParenPart - True if we will print out the () part of the mem ref. 303 bool HasParenPart = IndexReg.getReg() || HasBaseReg; 304 305 if (DispSpec.isImm()) { 306 int DispVal = DispSpec.getImm(); 307 if (DispVal || !HasParenPart) 308 O << DispVal; 309 } else { 310 assert(DispSpec.isGlobal() || DispSpec.isCPI() || 311 DispSpec.isJTI() || DispSpec.isSymbol()); 312 printSymbolOperand(MI->getOperand(Op+3), O); 313 } 314 315 if (HasParenPart) { 316 assert(IndexReg.getReg() != X86::ESP && 317 "X86 doesn't allow scaling by ESP"); 318 319 O << '('; 320 if (HasBaseReg) 321 printOperand(MI, Op, O, Modifier); 322 323 if (IndexReg.getReg()) { 324 O << ','; 325 printOperand(MI, Op+2, O, Modifier); 326 unsigned ScaleVal = MI->getOperand(Op+1).getImm(); 327 if (ScaleVal != 1) 328 O << ',' << ScaleVal; 329 } 330 O << ')'; 331 } 332} 333 334void X86AsmPrinter::printMemReference(const MachineInstr *MI, unsigned Op, 335 raw_ostream &O, const char *Modifier) { 336 assert(isMem(MI, Op) && "Invalid memory reference!"); 337 const MachineOperand &Segment = MI->getOperand(Op+4); 338 if (Segment.getReg()) { 339 printOperand(MI, Op+4, O, Modifier); 340 O << ':'; 341 } 342 printLeaMemReference(MI, Op, O, Modifier); 343} 344 345void X86AsmPrinter::printPICLabel(const MachineInstr *MI, unsigned Op, 346 raw_ostream &O) { 347 PrintPICBaseSymbol(O); 348 O << '\n'; 349 PrintPICBaseSymbol(O); 350 O << ':'; 351} 352 353bool X86AsmPrinter::printAsmMRegister(const MachineOperand &MO, char Mode, 354 raw_ostream &O) { 355 unsigned Reg = MO.getReg(); 356 switch (Mode) { 357 default: return true; // Unknown mode. 358 case 'b': // Print QImode register 359 Reg = getX86SubSuperRegister(Reg, MVT::i8); 360 break; 361 case 'h': // Print QImode high register 362 Reg = getX86SubSuperRegister(Reg, MVT::i8, true); 363 break; 364 case 'w': // Print HImode register 365 Reg = getX86SubSuperRegister(Reg, MVT::i16); 366 break; 367 case 'k': // Print SImode register 368 Reg = getX86SubSuperRegister(Reg, MVT::i32); 369 break; 370 case 'q': // Print DImode register 371 Reg = getX86SubSuperRegister(Reg, MVT::i64); 372 break; 373 } 374 375 O << '%' << X86ATTInstPrinter::getRegisterName(Reg); 376 return false; 377} 378 379/// PrintAsmOperand - Print out an operand for an inline asm expression. 380/// 381bool X86AsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, 382 unsigned AsmVariant, 383 const char *ExtraCode, raw_ostream &O) { 384 // Does this asm operand have a single letter operand modifier? 385 if (ExtraCode && ExtraCode[0]) { 386 if (ExtraCode[1] != 0) return true; // Unknown modifier. 387 388 const MachineOperand &MO = MI->getOperand(OpNo); 389 390 switch (ExtraCode[0]) { 391 default: return true; // Unknown modifier. 392 case 'a': // This is an address. Currently only 'i' and 'r' are expected. 393 if (MO.isImm()) { 394 O << MO.getImm(); 395 return false; 396 } 397 if (MO.isGlobal() || MO.isCPI() || MO.isJTI() || MO.isSymbol()) { 398 printSymbolOperand(MO, O); 399 if (Subtarget->isPICStyleRIPRel()) 400 O << "(%rip)"; 401 return false; 402 } 403 if (MO.isReg()) { 404 O << '('; 405 printOperand(MI, OpNo, O); 406 O << ')'; 407 return false; 408 } 409 return true; 410 411 case 'c': // Don't print "$" before a global var name or constant. 412 if (MO.isImm()) 413 O << MO.getImm(); 414 else if (MO.isGlobal() || MO.isCPI() || MO.isJTI() || MO.isSymbol()) 415 printSymbolOperand(MO, O); 416 else 417 printOperand(MI, OpNo, O); 418 return false; 419 420 case 'A': // Print '*' before a register (it must be a register) 421 if (MO.isReg()) { 422 O << '*'; 423 printOperand(MI, OpNo, O); 424 return false; 425 } 426 return true; 427 428 case 'b': // Print QImode register 429 case 'h': // Print QImode high register 430 case 'w': // Print HImode register 431 case 'k': // Print SImode register 432 case 'q': // Print DImode register 433 if (MO.isReg()) 434 return printAsmMRegister(MO, ExtraCode[0], O); 435 printOperand(MI, OpNo, O); 436 return false; 437 438 case 'P': // This is the operand of a call, treat specially. 439 print_pcrel_imm(MI, OpNo, O); 440 return false; 441 442 case 'n': // Negate the immediate or print a '-' before the operand. 443 // Note: this is a temporary solution. It should be handled target 444 // independently as part of the 'MC' work. 445 if (MO.isImm()) { 446 O << -MO.getImm(); 447 return false; 448 } 449 O << '-'; 450 } 451 } 452 453 printOperand(MI, OpNo, O); 454 return false; 455} 456 457bool X86AsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, 458 unsigned OpNo, unsigned AsmVariant, 459 const char *ExtraCode, 460 raw_ostream &O) { 461 if (ExtraCode && ExtraCode[0]) { 462 if (ExtraCode[1] != 0) return true; // Unknown modifier. 463 464 switch (ExtraCode[0]) { 465 default: return true; // Unknown modifier. 466 case 'b': // Print QImode register 467 case 'h': // Print QImode high register 468 case 'w': // Print HImode register 469 case 'k': // Print SImode register 470 case 'q': // Print SImode register 471 // These only apply to registers, ignore on mem. 472 break; 473 case 'P': // Don't print @PLT, but do print as memory. 474 printMemReference(MI, OpNo, O, "no-rip"); 475 return false; 476 } 477 } 478 printMemReference(MI, OpNo, O); 479 return false; 480} 481 482void X86AsmPrinter::EmitStartOfAsmFile(Module &M) { 483 if (Subtarget->isTargetDarwin()) 484 OutStreamer.SwitchSection(getObjFileLowering().getTextSection()); 485} 486 487 488void X86AsmPrinter::EmitEndOfAsmFile(Module &M) { 489 if (Subtarget->isTargetDarwin()) { 490 // All darwin targets use mach-o. 491 MachineModuleInfoMachO &MMIMacho = 492 MMI->getObjFileInfo<MachineModuleInfoMachO>(); 493 494 // Output stubs for dynamically-linked functions. 495 MachineModuleInfoMachO::SymbolListTy Stubs; 496 497 Stubs = MMIMacho.GetFnStubList(); 498 if (!Stubs.empty()) { 499 const MCSection *TheSection = 500 OutContext.getMachOSection("__IMPORT", "__jump_table", 501 MCSectionMachO::S_SYMBOL_STUBS | 502 MCSectionMachO::S_ATTR_SELF_MODIFYING_CODE | 503 MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS, 504 5, SectionKind::getMetadata()); 505 OutStreamer.SwitchSection(TheSection); 506 507 for (unsigned i = 0, e = Stubs.size(); i != e; ++i) { 508 // L_foo$stub: 509 OutStreamer.EmitLabel(Stubs[i].first); 510 // .indirect_symbol _foo 511 OutStreamer.EmitSymbolAttribute(Stubs[i].second.getPointer(), 512 MCSA_IndirectSymbol); 513 // hlt; hlt; hlt; hlt; hlt hlt = 0xf4 = -12. 514 const char HltInsts[] = { -12, -12, -12, -12, -12 }; 515 OutStreamer.EmitBytes(StringRef(HltInsts, 5), 0/*addrspace*/); 516 } 517 518 Stubs.clear(); 519 OutStreamer.AddBlankLine(); 520 } 521 522 // Output stubs for external and common global variables. 523 Stubs = MMIMacho.GetGVStubList(); 524 if (!Stubs.empty()) { 525 const MCSection *TheSection = 526 OutContext.getMachOSection("__IMPORT", "__pointers", 527 MCSectionMachO::S_NON_LAZY_SYMBOL_POINTERS, 528 SectionKind::getMetadata()); 529 OutStreamer.SwitchSection(TheSection); 530 531 for (unsigned i = 0, e = Stubs.size(); i != e; ++i) { 532 // L_foo$non_lazy_ptr: 533 OutStreamer.EmitLabel(Stubs[i].first); 534 // .indirect_symbol _foo 535 MachineModuleInfoImpl::StubValueTy &MCSym = Stubs[i].second; 536 OutStreamer.EmitSymbolAttribute(MCSym.getPointer(), 537 MCSA_IndirectSymbol); 538 // .long 0 539 if (MCSym.getInt()) 540 // External to current translation unit. 541 OutStreamer.EmitIntValue(0, 4/*size*/, 0/*addrspace*/); 542 else 543 // Internal to current translation unit. 544 // 545 // When we place the LSDA into the TEXT section, the type info 546 // pointers need to be indirect and pc-rel. We accomplish this by 547 // using NLPs. However, sometimes the types are local to the file. So 548 // we need to fill in the value for the NLP in those cases. 549 OutStreamer.EmitValue(MCSymbolRefExpr::Create(MCSym.getPointer(), 550 OutContext), 551 4/*size*/, 0/*addrspace*/); 552 } 553 Stubs.clear(); 554 OutStreamer.AddBlankLine(); 555 } 556 557 Stubs = MMIMacho.GetHiddenGVStubList(); 558 if (!Stubs.empty()) { 559 OutStreamer.SwitchSection(getObjFileLowering().getDataSection()); 560 EmitAlignment(2); 561 562 for (unsigned i = 0, e = Stubs.size(); i != e; ++i) { 563 // L_foo$non_lazy_ptr: 564 OutStreamer.EmitLabel(Stubs[i].first); 565 // .long _foo 566 OutStreamer.EmitValue(MCSymbolRefExpr:: 567 Create(Stubs[i].second.getPointer(), 568 OutContext), 569 4/*size*/, 0/*addrspace*/); 570 } 571 Stubs.clear(); 572 OutStreamer.AddBlankLine(); 573 } 574 575 // Funny Darwin hack: This flag tells the linker that no global symbols 576 // contain code that falls through to other global symbols (e.g. the obvious 577 // implementation of multiple entry points). If this doesn't occur, the 578 // linker can safely perform dead code stripping. Since LLVM never 579 // generates code that does this, it is always safe to set. 580 OutStreamer.EmitAssemblerFlag(MCAF_SubsectionsViaSymbols); 581 } 582 583 if (Subtarget->isTargetCOFF()) { 584 X86COFFMachineModuleInfo &COFFMMI = 585 MMI->getObjFileInfo<X86COFFMachineModuleInfo>(); 586 587 // Emit type information for external functions 588 typedef X86COFFMachineModuleInfo::externals_iterator externals_iterator; 589 for (externals_iterator I = COFFMMI.externals_begin(), 590 E = COFFMMI.externals_end(); 591 I != E; ++I) { 592 OutStreamer.BeginCOFFSymbolDef(CurrentFnSym); 593 OutStreamer.EmitCOFFSymbolStorageClass(COFF::IMAGE_SYM_CLASS_EXTERNAL); 594 OutStreamer.EmitCOFFSymbolType(COFF::IMAGE_SYM_DTYPE_FUNCTION 595 << COFF::SCT_COMPLEX_TYPE_SHIFT); 596 OutStreamer.EndCOFFSymbolDef(); 597 } 598 599 // Necessary for dllexport support 600 std::vector<const MCSymbol*> DLLExportedFns, DLLExportedGlobals; 601 602 const TargetLoweringObjectFileCOFF &TLOFCOFF = 603 static_cast<const TargetLoweringObjectFileCOFF&>(getObjFileLowering()); 604 605 for (Module::const_iterator I = M.begin(), E = M.end(); I != E; ++I) 606 if (I->hasDLLExportLinkage()) 607 DLLExportedFns.push_back(Mang->getSymbol(I)); 608 609 for (Module::const_global_iterator I = M.global_begin(), 610 E = M.global_end(); I != E; ++I) 611 if (I->hasDLLExportLinkage()) 612 DLLExportedGlobals.push_back(Mang->getSymbol(I)); 613 614 // Output linker support code for dllexported globals on windows. 615 if (!DLLExportedGlobals.empty() || !DLLExportedFns.empty()) { 616 OutStreamer.SwitchSection(TLOFCOFF.getDrectveSection()); 617 SmallString<128> name; 618 for (unsigned i = 0, e = DLLExportedGlobals.size(); i != e; ++i) { 619 if (Subtarget->isTargetWindows()) 620 name = " /EXPORT:"; 621 else 622 name = " -export:"; 623 name += DLLExportedGlobals[i]->getName(); 624 if (Subtarget->isTargetWindows()) 625 name += ",DATA"; 626 else 627 name += ",data"; 628 OutStreamer.EmitBytes(name, 0); 629 } 630 631 for (unsigned i = 0, e = DLLExportedFns.size(); i != e; ++i) { 632 if (Subtarget->isTargetWindows()) 633 name = " /EXPORT:"; 634 else 635 name = " -export:"; 636 name += DLLExportedFns[i]->getName(); 637 OutStreamer.EmitBytes(name, 0); 638 } 639 } 640 } 641 642 if (Subtarget->isTargetELF()) { 643 const TargetLoweringObjectFileELF &TLOFELF = 644 static_cast<const TargetLoweringObjectFileELF &>(getObjFileLowering()); 645 646 MachineModuleInfoELF &MMIELF = MMI->getObjFileInfo<MachineModuleInfoELF>(); 647 648 // Output stubs for external and common global variables. 649 MachineModuleInfoELF::SymbolListTy Stubs = MMIELF.GetGVStubList(); 650 if (!Stubs.empty()) { 651 OutStreamer.SwitchSection(TLOFELF.getDataRelSection()); 652 const TargetData *TD = TM.getTargetData(); 653 654 for (unsigned i = 0, e = Stubs.size(); i != e; ++i) { 655 OutStreamer.EmitLabel(Stubs[i].first); 656 OutStreamer.EmitSymbolValue(Stubs[i].second.getPointer(), 657 TD->getPointerSize(), 0); 658 } 659 Stubs.clear(); 660 } 661 } 662} 663 664MachineLocation 665X86AsmPrinter::getDebugValueLocation(const MachineInstr *MI) const { 666 MachineLocation Location; 667 assert (MI->getNumOperands() == 7 && "Invalid no. of machine operands!"); 668 // Frame address. Currently handles register +- offset only. 669 670 if (MI->getOperand(0).isReg() && MI->getOperand(3).isImm()) 671 Location.set(MI->getOperand(0).getReg(), MI->getOperand(3).getImm()); 672 else { 673 DEBUG(dbgs() << "DBG_VALUE instruction ignored! " << *MI << "\n"); 674 } 675 return Location; 676} 677 678void X86AsmPrinter::PrintDebugValueComment(const MachineInstr *MI, 679 raw_ostream &O) { 680 // Only the target-dependent form of DBG_VALUE should get here. 681 // Referencing the offset and metadata as NOps-2 and NOps-1 is 682 // probably portable to other targets; frame pointer location is not. 683 unsigned NOps = MI->getNumOperands(); 684 assert(NOps==7); 685 O << '\t' << MAI->getCommentString() << "DEBUG_VALUE: "; 686 // cast away const; DIetc do not take const operands for some reason. 687 DIVariable V(const_cast<MDNode *>(MI->getOperand(NOps-1).getMetadata())); 688 if (V.getContext().isSubprogram()) 689 O << DISubprogram(V.getContext()).getDisplayName() << ":"; 690 O << V.getName(); 691 O << " <- "; 692 // Frame address. Currently handles register +- offset only. 693 O << '['; 694 if (MI->getOperand(0).isReg() && MI->getOperand(0).getReg()) 695 printOperand(MI, 0, O); 696 else 697 O << "undef"; 698 O << '+'; printOperand(MI, 3, O); 699 O << ']'; 700 O << "+"; 701 printOperand(MI, NOps-2, O); 702} 703 704 705 706//===----------------------------------------------------------------------===// 707// Target Registry Stuff 708//===----------------------------------------------------------------------===// 709 710static MCInstPrinter *createX86MCInstPrinter(const Target &T, 711 unsigned SyntaxVariant, 712 const MCAsmInfo &MAI) { 713 if (SyntaxVariant == 0) 714 return new X86ATTInstPrinter(MAI); 715 if (SyntaxVariant == 1) 716 return new X86IntelInstPrinter(MAI); 717 return 0; 718} 719 720// Force static initialization. 721extern "C" void LLVMInitializeX86AsmPrinter() { 722 RegisterAsmPrinter<X86AsmPrinter> X(TheX86_32Target); 723 RegisterAsmPrinter<X86AsmPrinter> Y(TheX86_64Target); 724 725 TargetRegistry::RegisterMCInstPrinter(TheX86_32Target,createX86MCInstPrinter); 726 TargetRegistry::RegisterMCInstPrinter(TheX86_64Target,createX86MCInstPrinter); 727} 728