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