#define DEBUG_TYPE "asm-printer"
#include "X86ATTAsmPrinter.h"
+#include "X86MCInstLower.h"
#include "X86.h"
#include "X86COFF.h"
#include "X86MachineFunctionInfo.h"
#include "X86TargetMachine.h"
-#include "X86MCAsmInfo.h"
#include "llvm/CallingConv.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Module.h"
#include "llvm/Type.h"
-#include "llvm/ADT/Statistic.h"
-#include "llvm/ADT/StringExtras.h"
#include "llvm/Assembly/Writer.h"
#include "llvm/MC/MCContext.h"
-#include "llvm/MC/MCExpr.h"
-#include "llvm/MC/MCInst.h"
#include "llvm/MC/MCSectionMachO.h"
#include "llvm/MC/MCStreamer.h"
-#include "llvm/CodeGen/DwarfWriter.h"
+#include "llvm/MC/MCSymbol.h"
#include "llvm/CodeGen/MachineJumpTableInfo.h"
-#include "llvm/Support/CommandLine.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/FormattedStream.h"
#include "llvm/Support/Mangler.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/Target/TargetLoweringObjectFile.h"
#include "llvm/Target/TargetOptions.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/Statistic.h"
using namespace llvm;
STATISTIC(EmittedInsts, "Number of machine instrs printed");
-static cl::opt<bool> NewAsmPrinter("experimental-asm-printer",
- cl::Hidden);
-
//===----------------------------------------------------------------------===//
// Primitive Helper Functions.
//===----------------------------------------------------------------------===//
void X86ATTAsmPrinter::PrintPICBaseSymbol() const {
- // FIXME: the actual label generated doesn't matter here! Just mangle in
- // something unique (the function number) with Private prefix.
- if (Subtarget->isTargetDarwin())
- O << "\"L" << getFunctionNumber() << "$pb\"";
- else {
- assert(Subtarget->isTargetELF() && "Don't know how to print PIC label!");
- O << ".Lllvm$" << getFunctionNumber() << ".$piclabel";
- }
-}
-
-MCSymbol *X86ATTAsmPrinter::GetPICBaseSymbol() {
- // FIXME: the actual label generated doesn't matter here! Just mangle in
- // something unique (the function number) with Private prefix.
- std::string Name;
-
- if (Subtarget->isTargetDarwin()) {
- Name = "L" + utostr(getFunctionNumber())+"$pb";
- } else {
- assert(Subtarget->isTargetELF() && "Don't know how to print PIC label!");
- Name = ".Lllvm$" + utostr(getFunctionNumber())+".$piclabel";
- }
- return OutContext.GetOrCreateSymbol(Name);
+ // FIXME: Gross const cast hack.
+ X86ATTAsmPrinter *AP = const_cast<X86ATTAsmPrinter*>(this);
+ X86MCInstLower(OutContext, 0, *AP).GetPICBaseSymbol()->print(O, MAI);
}
static X86MachineFunctionInfo calculateFunctionInfo(const Function *F,
/// DecorateCygMingName - Query FunctionInfoMap and use this information for
/// various name decorations for Cygwin and MingW.
-void X86ATTAsmPrinter::DecorateCygMingName(std::string &Name,
+void X86ATTAsmPrinter::DecorateCygMingName(SmallVectorImpl<char> &Name,
const GlobalValue *GV) {
assert(Subtarget->isTargetCygMing() && "This is only for cygwin and mingw");
const Function *F = dyn_cast<Function>(GV);
if (!F) return;
-
+
// Save function name for later type emission.
if (F->isDeclaration())
- CygMingStubs.insert(Name);
+ CygMingStubs.insert(StringRef(Name.data(), Name.size()));
// We don't want to decorate non-stdcall or non-fastcall functions right now
- unsigned CC = F->getCallingConv();
+ CallingConv::ID CC = F->getCallingConv();
if (CC != CallingConv::X86_StdCall && CC != CallingConv::X86_FastCall)
return;
-
-
+
+
const X86MachineFunctionInfo *Info;
FMFInfoMap::const_iterator info_item = FunctionInfoMap.find(F);
} else {
Info = &info_item->second;
}
-
+
+ if (Info->getDecorationStyle() == None) return;
const FunctionType *FT = F->getFunctionType();
- switch (Info->getDecorationStyle()) {
- case None:
- break;
- case StdCall:
- // "Pure" variadic functions do not receive @0 suffix.
- if (!FT->isVarArg() || (FT->getNumParams() == 0) ||
- (FT->getNumParams() == 1 && F->hasStructRetAttr()))
- Name += '@' + utostr_32(Info->getBytesToPopOnReturn());
- break;
- case FastCall:
- // "Pure" variadic functions do not receive @0 suffix.
- if (!FT->isVarArg() || (FT->getNumParams() == 0) ||
- (FT->getNumParams() == 1 && F->hasStructRetAttr()))
- Name += '@' + utostr_32(Info->getBytesToPopOnReturn());
- if (Name[0] == '_') {
+ // "Pure" variadic functions do not receive @0 suffix.
+ if (!FT->isVarArg() || FT->getNumParams() == 0 ||
+ (FT->getNumParams() == 1 && F->hasStructRetAttr()))
+ raw_svector_ostream(Name) << '@' << Info->getBytesToPopOnReturn();
+
+ if (Info->getDecorationStyle() == FastCall) {
+ if (Name[0] == '_')
Name[0] = '@';
- } else {
- Name = '@' + Name;
- }
- break;
- default:
- llvm_unreachable("Unsupported DecorationStyle");
- }
+ else
+ Name.insert(Name.begin(), '@');
+ }
+}
+
+/// DecorateCygMingName - Query FunctionInfoMap and use this information for
+/// various name decorations for Cygwin and MingW.
+void X86ATTAsmPrinter::DecorateCygMingName(std::string &Name,
+ const GlobalValue *GV) {
+ SmallString<128> NameStr(Name.begin(), Name.end());
+ DecorateCygMingName(NameStr, GV);
+ Name.assign(NameStr.begin(), NameStr.end());
}
void X86ATTAsmPrinter::emitFunctionHeader(const MachineFunction &MF) {
bool X86ATTAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
const Function *F = MF.getFunction();
this->MF = &MF;
- unsigned CC = F->getCallingConv();
+ CallingConv::ID CC = F->getCallingConv();
SetupMachineFunction(MF);
O << "\n\n";
// This is an entry block or a block that's only reachable via a
// fallthrough edge. In non-VerboseAsm mode, don't print the label.
} else {
- printBasicBlockLabel(I, true, true, VerboseAsm);
+ EmitBasicBlockStart(I);
O << '\n';
}
for (MachineBasicBlock::const_iterator II = I->begin(), IE = I->end();
Suffix = "$stub";
else if (MO.getTargetFlags() == X86II::MO_DARWIN_NONLAZY ||
MO.getTargetFlags() == X86II::MO_DARWIN_NONLAZY_PIC_BASE ||
- MO.getTargetFlags() == X86II::MO_DARWIN_HIDDEN_NONLAZY ||
MO.getTargetFlags() == X86II::MO_DARWIN_HIDDEN_NONLAZY_PIC_BASE)
Suffix = "$non_lazy_ptr";
Name = "__imp_" + Name;
if (MO.getTargetFlags() == X86II::MO_DARWIN_NONLAZY ||
- MO.getTargetFlags() == X86II::MO_DARWIN_NONLAZY_PIC_BASE)
- GVStubs[Name] = Mang->getMangledName(GV);
- else if (MO.getTargetFlags() == X86II::MO_DARWIN_HIDDEN_NONLAZY ||
- MO.getTargetFlags() == X86II::MO_DARWIN_HIDDEN_NONLAZY_PIC_BASE)
- HiddenGVStubs[Name] = Mang->getMangledName(GV);
- else if (MO.getTargetFlags() == X86II::MO_DARWIN_STUB)
- FnStubs[Name] = Mang->getMangledName(GV);
+ MO.getTargetFlags() == X86II::MO_DARWIN_NONLAZY_PIC_BASE) {
+ SmallString<128> NameStr;
+ Mang->getNameWithPrefix(NameStr, GV, true);
+ NameStr += "$non_lazy_ptr";
+ MCSymbol *Sym = OutContext.GetOrCreateSymbol(NameStr.str());
+ MCSymbol *&StubSym = GVStubs[Sym];
+ if (StubSym == 0) {
+ NameStr.clear();
+ Mang->getNameWithPrefix(NameStr, GV, false);
+ StubSym = OutContext.GetOrCreateSymbol(NameStr.str());
+ }
+ } else if (MO.getTargetFlags() == X86II::MO_DARWIN_HIDDEN_NONLAZY_PIC_BASE){
+ SmallString<128> NameStr;
+ Mang->getNameWithPrefix(NameStr, GV, true);
+ NameStr += "$non_lazy_ptr";
+ MCSymbol *Sym = OutContext.GetOrCreateSymbol(NameStr.str());
+ MCSymbol *&StubSym = HiddenGVStubs[Sym];
+ if (StubSym == 0) {
+ NameStr.clear();
+ Mang->getNameWithPrefix(NameStr, GV, false);
+ StubSym = OutContext.GetOrCreateSymbol(NameStr.str());
+ }
+ } else if (MO.getTargetFlags() == X86II::MO_DARWIN_STUB) {
+ SmallString<128> NameStr;
+ Mang->getNameWithPrefix(NameStr, GV, true);
+ NameStr += "$stub";
+ MCSymbol *Sym = OutContext.GetOrCreateSymbol(NameStr.str());
+ MCSymbol *&StubSym = FnStubs[Sym];
+ if (StubSym == 0) {
+ NameStr.clear();
+ Mang->getNameWithPrefix(NameStr, GV, false);
+ StubSym = OutContext.GetOrCreateSymbol(NameStr.str());
+ }
+ }
// If the name begins with a dollar-sign, enclose it in parens. We do this
// to avoid having it look like an integer immediate to the assembler.
case MachineOperand::MO_ExternalSymbol: {
std::string Name = Mang->makeNameProper(MO.getSymbolName());
if (MO.getTargetFlags() == X86II::MO_DARWIN_STUB) {
- FnStubs[Name+"$stub"] = Name;
Name += "$stub";
+ MCSymbol *&StubSym = FnStubs[OutContext.GetOrCreateSymbol(Name)];
+ if (StubSym == 0) {
+ Name.erase(Name.end()-5, Name.end());
+ StubSym = OutContext.GetOrCreateSymbol(Name);
+ }
}
// If the name begins with a dollar-sign, enclose it in parens. We do this
case X86II::MO_NO_FLAG: // No flag.
break;
case X86II::MO_DARWIN_NONLAZY:
- case X86II::MO_DARWIN_HIDDEN_NONLAZY:
case X86II::MO_DLLIMPORT:
case X86II::MO_DARWIN_STUB:
// These affect the name of the symbol, not any suffix.
O << MO.getImm();
return;
case MachineOperand::MO_MachineBasicBlock:
- printBasicBlockLabel(MO.getMBB(), false, false, false);
+ GetMBBSymbol(MO.getMBB()->getNumber())->print(O, MAI);
return;
case MachineOperand::MO_GlobalAddress:
case MachineOperand::MO_ExternalSymbol:
}
-
void X86ATTAsmPrinter::printOperand(const MachineInstr *MI, unsigned OpNo,
const char *Modifier) {
const MachineOperand &MO = MI->getOperand(OpNo);
O << MAI->getSetDirective() << ' ' << MAI->getPrivateGlobalPrefix()
<< getFunctionNumber() << '_' << uid << "_set_" << MBB->getNumber() << ',';
- printBasicBlockLabel(MBB, false, false, false);
+
+ GetMBBSymbol(MBB->getNumber())->print(O, MAI);
+
if (Subtarget->isPICStyleRIPRel())
O << '-' << MAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber()
<< '_' << uid << '\n';
O << ':';
}
-
void X86ATTAsmPrinter::printPICJumpTableEntry(const MachineJumpTableInfo *MJTI,
const MachineBasicBlock *MBB,
unsigned uid) const {
O << MAI->getPrivateGlobalPrefix() << getFunctionNumber()
<< '_' << uid << "_set_" << MBB->getNumber();
} else if (Subtarget->isPICStyleGOT()) {
- printBasicBlockLabel(MBB, false, false, false);
+ GetMBBSymbol(MBB->getNumber())->print(O, MAI);
O << "@GOTOFF";
} else
- printBasicBlockLabel(MBB, false, false, false);
+ GetMBBSymbol(MBB->getNumber())->print(O, MAI);
}
bool X86ATTAsmPrinter::printAsmMRegister(const MachineOperand &MO, char Mode) {
return false;
}
-static void lower_lea64_32mem(MCInst *MI, unsigned OpNo) {
- // Convert registers in the addr mode according to subreg64.
- for (unsigned i = 0; i != 4; ++i) {
- if (!MI->getOperand(i).isReg()) continue;
-
- unsigned Reg = MI->getOperand(i).getReg();
- if (Reg == 0) continue;
-
- MI->getOperand(i).setReg(getX86SubSuperRegister(Reg, MVT::i64));
- }
-}
-
-/// LowerGlobalAddressOperand - Lower an MO_GlobalAddress operand to an
-/// MCOperand.
-MCOperand X86ATTAsmPrinter::LowerGlobalAddressOperand(const MachineOperand &MO){
- const GlobalValue *GV = MO.getGlobal();
-
- const char *Suffix = "";
- if (MO.getTargetFlags() == X86II::MO_DARWIN_STUB)
- Suffix = "$stub";
- else if (MO.getTargetFlags() == X86II::MO_DARWIN_NONLAZY ||
- MO.getTargetFlags() == X86II::MO_DARWIN_NONLAZY_PIC_BASE ||
- MO.getTargetFlags() == X86II::MO_DARWIN_HIDDEN_NONLAZY ||
- MO.getTargetFlags() == X86II::MO_DARWIN_HIDDEN_NONLAZY_PIC_BASE)
- Suffix = "$non_lazy_ptr";
-
- std::string Name = Mang->getMangledName(GV, Suffix, Suffix[0] != '\0');
- if (Subtarget->isTargetCygMing())
- DecorateCygMingName(Name, GV);
-
- // Handle dllimport linkage.
- if (MO.getTargetFlags() == X86II::MO_DLLIMPORT)
- Name = "__imp_" + Name;
-
- if (MO.getTargetFlags() == X86II::MO_DARWIN_NONLAZY ||
- MO.getTargetFlags() == X86II::MO_DARWIN_NONLAZY_PIC_BASE)
- GVStubs[Name] = Mang->getMangledName(GV);
- else if (MO.getTargetFlags() == X86II::MO_DARWIN_HIDDEN_NONLAZY ||
- MO.getTargetFlags() == X86II::MO_DARWIN_HIDDEN_NONLAZY_PIC_BASE)
- HiddenGVStubs[Name] = Mang->getMangledName(GV);
- else if (MO.getTargetFlags() == X86II::MO_DARWIN_STUB)
- FnStubs[Name] = Mang->getMangledName(GV);
-
-
- // Handle target operand flags.
- // FIXME: This should be common between external symbols, constant pool etc.
- MCSymbol *NegatedSymbol = 0;
-
- switch (MO.getTargetFlags()) {
- default:
- llvm_unreachable("Unknown target flag on GV operand");
- case X86II::MO_NO_FLAG: // No flag.
- break;
- case X86II::MO_DARWIN_NONLAZY:
- case X86II::MO_DARWIN_HIDDEN_NONLAZY:
- case X86II::MO_DLLIMPORT:
- case X86II::MO_DARWIN_STUB:
- // These affect the name of the symbol, not any suffix.
- break;
- case X86II::MO_GOT_ABSOLUTE_ADDRESS:
- assert(0 && "Reloc mode unimp!");
- //O << " + [.-";
- //PrintPICBaseSymbol();
- //O << ']';
- break;
- case X86II::MO_PIC_BASE_OFFSET:
- case X86II::MO_DARWIN_NONLAZY_PIC_BASE:
- case X86II::MO_DARWIN_HIDDEN_NONLAZY_PIC_BASE:
- // Subtract the pic base.
- NegatedSymbol = GetPICBaseSymbol();
- break;
-
- // FIXME: These probably should be a modifier on the symbol or something??
- case X86II::MO_TLSGD: Name += "@TLSGD"; break;
- case X86II::MO_GOTTPOFF: Name += "@GOTTPOFF"; break;
- case X86II::MO_INDNTPOFF: Name += "@INDNTPOFF"; break;
- case X86II::MO_TPOFF: Name += "@TPOFF"; break;
- case X86II::MO_NTPOFF: Name += "@NTPOFF"; break;
- case X86II::MO_GOTPCREL: Name += "@GOTPCREL"; break;
- case X86II::MO_GOT: Name += "@GOT"; break;
- case X86II::MO_GOTOFF: Name += "@GOTOFF"; break;
- case X86II::MO_PLT: Name += "@PLT"; break;
- }
-
- // Create a symbol for the name.
- MCSymbol *Sym = OutContext.GetOrCreateSymbol(Name);
- // FIXME: We would like an efficient form for this, so we don't have to do a
- // lot of extra uniquing.
- const MCExpr *Expr = MCSymbolRefExpr::Create(Sym, OutContext);
- if (NegatedSymbol)
- Expr = MCBinaryExpr::CreateSub(Expr, MCSymbolRefExpr::Create(NegatedSymbol,
- OutContext),
- OutContext);
- Expr = MCBinaryExpr::CreateAdd(Expr, MCConstantExpr::Create(MO.getOffset(),
- OutContext),
- OutContext);
- return MCOperand::CreateExpr(Expr);
-}
-
-MCOperand X86ATTAsmPrinter::
-LowerExternalSymbolOperand(const MachineOperand &MO){
- std::string Name = Mang->makeNameProper(MO.getSymbolName());
- if (MO.getTargetFlags() == X86II::MO_DARWIN_STUB) {
- FnStubs[Name+"$stub"] = Name;
- Name += "$stub";
- }
-
- MCSymbol *Sym = OutContext.GetOrCreateSymbol(Name);
- // FIXME: We would like an efficient form for this, so we don't have to do a
- // lot of extra uniquing.
- const MCExpr *Expr =
- MCBinaryExpr::CreateAdd(MCSymbolRefExpr::Create(Sym, OutContext),
- MCConstantExpr::Create(MO.getOffset(),OutContext),
- OutContext);
- return MCOperand::CreateExpr(Expr);
-}
/// printMachineInstruction -- Print out a single X86 LLVM instruction MI in
void X86ATTAsmPrinter::printMachineInstruction(const MachineInstr *MI) {
++EmittedInsts;
- if (!NewAsmPrinter) {
- // Call the autogenerated instruction printer routines.
- printInstruction(MI);
- return;
- }
+ processDebugLoc(MI->getDebugLoc());
- MCInst TmpInst;
-
- switch (MI->getOpcode()) {
- case TargetInstrInfo::DBG_LABEL:
- case TargetInstrInfo::EH_LABEL:
- case TargetInstrInfo::GC_LABEL:
- printLabel(MI);
- return;
- case TargetInstrInfo::INLINEASM:
- O << '\t';
- printInlineAsm(MI);
- return;
- case TargetInstrInfo::IMPLICIT_DEF:
- printImplicitDef(MI);
- return;
- case X86::MOVPC32r: {
- // This is a pseudo op for a two instruction sequence with a label, which
- // looks like:
- // call "L1$pb"
- // "L1$pb":
- // popl %esi
-
- // Emit the call.
- MCSymbol *PICBase = GetPICBaseSymbol();
- TmpInst.setOpcode(X86::CALLpcrel32);
- // FIXME: We would like an efficient form for this, so we don't have to do a
- // lot of extra uniquing.
- TmpInst.addOperand(MCOperand::CreateExpr(MCSymbolRefExpr::Create(PICBase,
- OutContext)));
- printInstruction(&TmpInst);
-
- // Emit the label.
- OutStreamer.EmitLabel(PICBase);
-
- // popl $reg
- TmpInst.setOpcode(X86::POP32r);
- TmpInst.getOperand(0) = MCOperand::CreateReg(MI->getOperand(0).getReg());
- printInstruction(&TmpInst);
- O << "OLD: ";
- // Call the autogenerated instruction printer routines.
- printInstruction(MI);
- return;
- }
- }
-
- O << "NEW: ";
-
- TmpInst.setOpcode(MI->getOpcode());
+ printInstructionThroughMCStreamer(MI);
- for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
- const MachineOperand &MO = MI->getOperand(i);
-
- MCOperand MCOp;
- switch (MO.getType()) {
- default:
- O.flush();
- errs() << "Cannot lower operand #" << i << " of :" << *MI;
- llvm_unreachable("Unimp");
- case MachineOperand::MO_Register:
- MCOp = MCOperand::CreateReg(MO.getReg());
- break;
- case MachineOperand::MO_Immediate:
- MCOp = MCOperand::CreateImm(MO.getImm());
- break;
- case MachineOperand::MO_MachineBasicBlock:
- MCOp = MCOperand::CreateMBBLabel(getFunctionNumber(),
- MO.getMBB()->getNumber());
- break;
- case MachineOperand::MO_GlobalAddress:
- MCOp = LowerGlobalAddressOperand(MO);
- break;
- case MachineOperand::MO_ExternalSymbol:
- MCOp = LowerExternalSymbolOperand(MO);
- break;
- }
-
- TmpInst.addOperand(MCOp);
- }
-
- switch (TmpInst.getOpcode()) {
- case X86::LEA64_32r:
- // Handle the 'subreg rewriting' for the lea64_32mem operand.
- lower_lea64_32mem(&TmpInst, 1);
- break;
- }
-
- // FIXME: Convert TmpInst.
- printInstruction(&TmpInst);
- O << "OLD: ";
-
- // Call the autogenerated instruction printer routines.
- printInstruction(MI);
+ if (VerboseAsm && !MI->getDebugLoc().isUnknown())
+ EmitComments(*MI);
+ O << '\n';
}
void X86ATTAsmPrinter::PrintGlobalVariable(const GlobalVariable* GVar) {
O << "\t.size\t" << name << ", " << Size << '\n';
}
+static int SortSymbolPair(const void *LHS, const void *RHS) {
+ MCSymbol *LHSS = ((const std::pair<MCSymbol*, MCSymbol*>*)LHS)->first;
+ MCSymbol *RHSS = ((const std::pair<MCSymbol*, MCSymbol*>*)RHS)->first;
+ return LHSS->getName().compare(RHSS->getName());
+}
+
+/// GetSortedStubs - Return the entries from a DenseMap in a deterministic
+/// sorted orer.
+static std::vector<std::pair<MCSymbol*, MCSymbol*> >
+GetSortedStubs(const DenseMap<MCSymbol*, MCSymbol*> &Map) {
+ assert(!Map.empty());
+ std::vector<std::pair<MCSymbol*, MCSymbol*> > List(Map.begin(), Map.end());
+ qsort(&List[0], List.size(), sizeof(List[0]), SortSymbolPair);
+ return List;
+}
+
bool X86ATTAsmPrinter::doFinalization(Module &M) {
// Print out module-level global variables here.
for (Module::const_global_iterator I = M.global_begin(), E = M.global_end();
if (MAI->doesSupportExceptionHandling() && MMI && !Subtarget->is64Bit()) {
const std::vector<Function*> &Personalities = MMI->getPersonalities();
for (unsigned i = 0, e = Personalities.size(); i != e; ++i) {
- if (Personalities[i])
- GVStubs[Mang->getMangledName(Personalities[i], "$non_lazy_ptr",
- true /*private label*/)] =
- Mang->getMangledName(Personalities[i]);
+ if (Personalities[i] == 0)
+ continue;
+
+ SmallString<128> Name;
+ Mang->getNameWithPrefix(Name, Personalities[i], true /*private label*/);
+ Name += "$non_lazy_ptr";
+ MCSymbol *NLPName = OutContext.GetOrCreateSymbol(Name.str());
+
+ MCSymbol *&StubName = GVStubs[NLPName];
+ if (StubName != 0) continue;
+
+
+ Name.clear();
+ Mang->getNameWithPrefix(Name, Personalities[i], false);
+ StubName = OutContext.GetOrCreateSymbol(Name.str());
}
}
MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
5, SectionKind::getMetadata());
OutStreamer.SwitchSection(TheSection);
- for (StringMap<std::string>::iterator I = FnStubs.begin(),
- E = FnStubs.end(); I != E; ++I)
- O << I->getKeyData() << ":\n" << "\t.indirect_symbol " << I->second
- << "\n\thlt ; hlt ; hlt ; hlt ; hlt\n";
+
+ std::vector<std::pair<MCSymbol*, MCSymbol*> > Stubs
+ = GetSortedStubs(FnStubs);
+ for (unsigned i = 0, e = Stubs.size(); i != e; ++i) {
+ Stubs[i].first->print(O, MAI);
+ O << ":\n" << "\t.indirect_symbol ";
+ // Get the MCSymbol without the $stub suffix.
+ Stubs[i].second->print(O, MAI);
+ O << "\n\thlt ; hlt ; hlt ; hlt ; hlt\n";
+ }
O << '\n';
}
MCSectionMachO::S_NON_LAZY_SYMBOL_POINTERS,
SectionKind::getMetadata());
OutStreamer.SwitchSection(TheSection);
- for (StringMap<std::string>::iterator I = GVStubs.begin(),
- E = GVStubs.end(); I != E; ++I)
- O << I->getKeyData() << ":\n\t.indirect_symbol "
- << I->second << "\n\t.long\t0\n";
+
+ std::vector<std::pair<MCSymbol*, MCSymbol*> > Stubs
+ = GetSortedStubs(GVStubs);
+ for (unsigned i = 0, e = Stubs.size(); i != e; ++i) {
+ Stubs[i].first->print(O, MAI);
+ O << ":\n\t.indirect_symbol ";
+ Stubs[i].second->print(O, MAI);
+ O << "\n\t.long\t0\n";
+ }
}
if (!HiddenGVStubs.empty()) {
OutStreamer.SwitchSection(getObjFileLowering().getDataSection());
EmitAlignment(2);
- for (StringMap<std::string>::iterator I = HiddenGVStubs.begin(),
- E = HiddenGVStubs.end(); I != E; ++I)
- O << I->getKeyData() << ":\n" << MAI->getData32bitsDirective()
- << I->second << '\n';
+
+ std::vector<std::pair<MCSymbol*, MCSymbol*> > Stubs
+ = GetSortedStubs(HiddenGVStubs);
+ for (unsigned i = 0, e = Stubs.size(); i != e; ++i) {
+ Stubs[i].first->print(O, MAI);
+ O << ":\n" << MAI->getData32bitsDirective();
+ Stubs[i].second->print(O, MAI);
+ O << '\n';
+ }
}
// Funny Darwin hack: This flag tells the linker that no global symbols
return AsmPrinter::doFinalization(M);
}
-// Include the auto-generated portion of the assembly writer.
-#include "X86GenAsmWriter.inc"