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