summaryrefslogtreecommitdiffstats
path: root/lib/Target/X86/AsmPrinter
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Target/X86/AsmPrinter')
-rw-r--r--lib/Target/X86/AsmPrinter/CMakeLists.txt1
-rw-r--r--lib/Target/X86/AsmPrinter/X86ATTAsmPrinter.cpp491
-rw-r--r--lib/Target/X86/AsmPrinter/X86ATTAsmPrinter.h23
-rw-r--r--lib/Target/X86/AsmPrinter/X86ATTInstPrinter.cpp6
-rw-r--r--lib/Target/X86/AsmPrinter/X86AsmPrinter.cpp7
5 files changed, 212 insertions, 316 deletions
diff --git a/lib/Target/X86/AsmPrinter/CMakeLists.txt b/lib/Target/X86/AsmPrinter/CMakeLists.txt
index 2079a9f..a28c826 100644
--- a/lib/Target/X86/AsmPrinter/CMakeLists.txt
+++ b/lib/Target/X86/AsmPrinter/CMakeLists.txt
@@ -6,3 +6,4 @@ add_llvm_library(LLVMX86AsmPrinter
X86AsmPrinter.cpp
X86IntelAsmPrinter.cpp
)
+add_dependencies(LLVMX86AsmPrinter X86CodeGenTable_gen) \ No newline at end of file
diff --git a/lib/Target/X86/AsmPrinter/X86ATTAsmPrinter.cpp b/lib/Target/X86/AsmPrinter/X86ATTAsmPrinter.cpp
index 60ed4f0..e75cfc5 100644
--- a/lib/Target/X86/AsmPrinter/X86ATTAsmPrinter.cpp
+++ b/lib/Target/X86/AsmPrinter/X86ATTAsmPrinter.cpp
@@ -23,10 +23,13 @@
#include "llvm/CallingConv.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Module.h"
+#include "llvm/MDNode.h"
#include "llvm/Type.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/ADT/StringExtras.h"
+#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCInst.h"
+#include "llvm/MC/MCStreamer.h"
#include "llvm/CodeGen/DwarfWriter.h"
#include "llvm/CodeGen/MachineJumpTableInfo.h"
#include "llvm/Support/CommandLine.h"
@@ -41,18 +44,26 @@ STATISTIC(EmittedInsts, "Number of machine instrs printed");
static cl::opt<bool> NewAsmPrinter("experimental-asm-printer",
cl::Hidden);
-static std::string getPICLabelString(unsigned FnNum,
- const TargetAsmInfo *TAI,
- const X86Subtarget* Subtarget) {
- std::string label;
+//===----------------------------------------------------------------------===//
+// Primitive Helper Functions.
+//===----------------------------------------------------------------------===//
+
+void X86ATTAsmPrinter::PrintPICBaseSymbol() const {
if (Subtarget->isTargetDarwin())
- label = "\"L" + utostr_32(FnNum) + "$pb\"";
+ O << "\"L" << getFunctionNumber() << "$pb\"";
else if (Subtarget->isTargetELF())
- label = ".Lllvm$" + utostr_32(FnNum) + "." "$piclabel";
+ O << ".Lllvm$" << getFunctionNumber() << "." "$piclabel";
else
assert(0 && "Don't know how to print PIC label!\n");
+}
- return label;
+/// PrintUnmangledNameSafely - Print out the printable characters in the name.
+/// Don't print things like \\n or \\0.
+static void PrintUnmangledNameSafely(const Value *V, raw_ostream &OS) {
+ for (const char *Name = V->getNameStart(), *E = Name+V->getNameLen();
+ Name != E; ++Name)
+ if (isprint(*Name))
+ OS << *Name;
}
static X86MachineFunctionInfo calculateFunctionInfo(const Function *F,
@@ -89,15 +100,6 @@ static X86MachineFunctionInfo calculateFunctionInfo(const Function *F,
return Info;
}
-/// PrintUnmangledNameSafely - Print out the printable characters in the name.
-/// Don't print things like \\n or \\0.
-static void PrintUnmangledNameSafely(const Value *V, raw_ostream &OS) {
- for (const char *Name = V->getNameStart(), *E = Name+V->getNameLen();
- Name != E; ++Name)
- if (isprint(*Name))
- OS << *Name;
-}
-
/// decorateName - Query FunctionInfoMap and use this information for various
/// name decoration.
void X86ATTAsmPrinter::decorateName(std::string &Name,
@@ -152,6 +154,8 @@ void X86ATTAsmPrinter::decorateName(std::string &Name,
}
}
+
+
void X86ATTAsmPrinter::emitFunctionHeader(const MachineFunction &MF) {
const Function *F = MF.getFunction();
@@ -159,9 +163,12 @@ void X86ATTAsmPrinter::emitFunctionHeader(const MachineFunction &MF) {
SwitchToSection(TAI->SectionForGlobal(F));
+ // FIXME: A function's alignment should be part of MachineFunction. There
+ // shouldn't be a policy decision here.
unsigned FnAlign = 4;
if (F->hasFnAttr(Attribute::OptimizeForSize))
FnAlign = 1;
+
switch (F->getLinkage()) {
default: assert(0 && "Unknown linkage type!");
case Function::InternalLinkage: // Symbols default to internal.
@@ -283,13 +290,8 @@ bool X86ATTAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
return false;
}
-static inline bool shouldPrintGOT(TargetMachine &TM, const X86Subtarget* ST) {
- return ST->isPICStyleGOT() && TM.getRelocationModel() == Reloc::PIC_;
-}
-
static inline bool shouldPrintPLT(TargetMachine &TM, const X86Subtarget* ST) {
- return ST->isTargetELF() && TM.getRelocationModel() == Reloc::PIC_ &&
- (ST->isPICStyleRIPRel() || ST->isPICStyleGOT());
+ return ST->isTargetELF() && TM.getRelocationModel() == Reloc::PIC_;
}
static inline bool shouldPrintStub(TargetMachine &TM, const X86Subtarget* ST) {
@@ -324,6 +326,8 @@ void X86ATTAsmPrinter::print_pcrel_imm(const MachineInstr *MI, unsigned OpNo) {
}
if (shouldPrintStub(TM, Subtarget)) {
+ // DARWIN/X86-32 in != static mode.
+
// Link-once, declaration, or Weakly-linked global variables need
// non-lazily-resolved stubs
if (GV->isDeclaration() || GV->isWeakForLinker()) {
@@ -354,9 +358,8 @@ void X86ATTAsmPrinter::print_pcrel_imm(const MachineInstr *MI, unsigned OpNo) {
O << Name;
}
} else {
- if (GV->hasDLLImportLinkage()) {
+ if (GV->hasDLLImportLinkage())
O << "__imp_";
- }
O << Name;
if (shouldPrintPLT(TM, Subtarget)) {
@@ -370,9 +373,6 @@ void X86ATTAsmPrinter::print_pcrel_imm(const MachineInstr *MI, unsigned OpNo) {
FnStubs.insert(Name);
}
- if (GV->hasExternalWeakLinkage())
- ExtWeakSymbols.insert(GV);
-
printOffset(MO.getOffset());
if (needCloseParen)
@@ -386,7 +386,9 @@ void X86ATTAsmPrinter::print_pcrel_imm(const MachineInstr *MI, unsigned OpNo) {
Name += MO.getSymbolName();
// Print function stub suffix unless it's Mac OS X 10.5 and up.
if (shouldPrintStub(TM, Subtarget) &&
+ // DARWIN/X86-32 in != static mode.
!(Subtarget->isTargetDarwin() && Subtarget->getDarwinVers() >= 9)) {
+
FnStubs.insert(Name);
printSuffixedName(Name, "$stub");
return;
@@ -401,23 +403,15 @@ void X86ATTAsmPrinter::print_pcrel_imm(const MachineInstr *MI, unsigned OpNo) {
O << Name;
- if (shouldPrintPLT(TM, Subtarget)) {
- std::string GOTName(TAI->getGlobalPrefix());
- GOTName+="_GLOBAL_OFFSET_TABLE_";
- if (Name == GOTName)
- // HACK! Emit extra offset to PC during printing GOT offset to
- // compensate for the size of popl instruction. The resulting code
- // should look like:
- // call .piclabel
- // piclabel:
- // popl %some_register
- // addl $_GLOBAL_ADDRESS_TABLE_ + [.-piclabel], %some_register
- O << " + [.-"
- << getPICLabelString(getFunctionNumber(), TAI, Subtarget) << ']';
-
- O << "@PLT";
+ if (MO.getTargetFlags() == X86II::MO_GOT_ABSOLUTE_ADDRESS) {
+ O << " + [.-";
+ PrintPICBaseSymbol();
+ O << ']';
}
+ if (shouldPrintPLT(TM, Subtarget))
+ O << "@PLT";
+
if (needCloseParen)
O << ')';
@@ -427,9 +421,10 @@ void X86ATTAsmPrinter::print_pcrel_imm(const MachineInstr *MI, unsigned OpNo) {
}
void X86ATTAsmPrinter::printOperand(const MachineInstr *MI, unsigned OpNo,
- const char *Modifier, bool NotRIPRel) {
+ const char *Modifier) {
const MachineOperand &MO = MI->getOperand(OpNo);
switch (MO.getType()) {
+ default: assert(0 && "unknown operand type!");
case MachineOperand::MO_Register: {
assert(TargetRegisterInfo::isPhysicalRegister(MO.getReg()) &&
"Virtual registers should not make it this far!");
@@ -456,18 +451,7 @@ void X86ATTAsmPrinter::printOperand(const MachineInstr *MI, unsigned OpNo,
if (!isMemOp) O << '$';
O << TAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber() << '_'
<< MO.getIndex();
-
- if (TM.getRelocationModel() == Reloc::PIC_) {
- if (Subtarget->isPICStyleStub())
- O << "-\"" << TAI->getPrivateGlobalPrefix() << getFunctionNumber()
- << "$pb\"";
- else if (Subtarget->isPICStyleGOT())
- O << "@GOTOFF";
- }
-
- if (isMemOp && Subtarget->isPICStyleRIPRel() && !NotRIPRel)
- O << "(%rip)";
- return;
+ break;
}
case MachineOperand::MO_ConstantPoolIndex: {
bool isMemOp = Modifier && !strcmp(Modifier, "mem");
@@ -475,38 +459,17 @@ void X86ATTAsmPrinter::printOperand(const MachineInstr *MI, unsigned OpNo,
O << TAI->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber() << '_'
<< MO.getIndex();
- if (TM.getRelocationModel() == Reloc::PIC_) {
- if (Subtarget->isPICStyleStub())
- O << "-\"" << TAI->getPrivateGlobalPrefix() << getFunctionNumber()
- << "$pb\"";
- else if (Subtarget->isPICStyleGOT())
- O << "@GOTOFF";
- }
-
printOffset(MO.getOffset());
-
- if (isMemOp && Subtarget->isPICStyleRIPRel() && !NotRIPRel)
- O << "(%rip)";
- return;
+ break;
}
case MachineOperand::MO_GlobalAddress: {
bool isMemOp = Modifier && !strcmp(Modifier, "mem");
- bool needCloseParen = false;
const GlobalValue *GV = MO.getGlobal();
- const GlobalVariable *GVar = dyn_cast<GlobalVariable>(GV);
- if (!GVar) {
- // If GV is an alias then use the aliasee for determining
- // thread-localness.
- if (const GlobalAlias *GA = dyn_cast<GlobalAlias>(GV))
- GVar =dyn_cast_or_null<GlobalVariable>(GA->resolveAliasedGlobal(false));
- }
-
- bool isThreadLocal = GVar && GVar->isThreadLocal();
-
std::string Name = Mang->getValueName(GV);
decorateName(Name, GV);
+ bool needCloseParen = false;
if (!isMemOp)
O << '$';
else if (Name[0] == '$') {
@@ -517,6 +480,8 @@ void X86ATTAsmPrinter::printOperand(const MachineInstr *MI, unsigned OpNo,
}
if (shouldPrintStub(TM, Subtarget)) {
+ // DARWIN/X86-32 in != static mode.
+
// Link-once, declaration, or Weakly-linked global variables need
// non-lazily-resolved stubs
if (GV->isDeclaration() || GV->isWeakForLinker()) {
@@ -539,118 +504,59 @@ void X86ATTAsmPrinter::printOperand(const MachineInstr *MI, unsigned OpNo,
O << Name;
}
- if (TM.getRelocationModel() == Reloc::PIC_)
- O << '-' << getPICLabelString(getFunctionNumber(), TAI, Subtarget);
+ if (TM.getRelocationModel() == Reloc::PIC_) {
+ O << '-';
+ PrintPICBaseSymbol();
+ }
} else {
if (GV->hasDLLImportLinkage())
O << "__imp_";
O << Name;
}
- if (GV->hasExternalWeakLinkage())
- ExtWeakSymbols.insert(GV);
-
printOffset(MO.getOffset());
if (needCloseParen)
O << ')';
- bool isRIPRelative = false;
- if (isThreadLocal) {
- TLSModel::Model model = getTLSModel(GVar, TM.getRelocationModel());
- switch (model) {
- case TLSModel::GeneralDynamic:
- O << "@TLSGD";
- break;
- case TLSModel::LocalDynamic:
- // O << "@TLSLD"; // local dynamic not implemented
- O << "@TLSGD";
- break;
- case TLSModel::InitialExec:
- if (Subtarget->is64Bit()) {
- assert (!NotRIPRel);
- O << "@GOTTPOFF";
- isRIPRelative = true;
- } else {
- O << "@INDNTPOFF";
- }
- break;
- case TLSModel::LocalExec:
- if (Subtarget->is64Bit())
- O << "@TPOFF";
- else
- O << "@NTPOFF";
- break;
- default:
- assert (0 && "Unknown TLS model");
- }
- } else if (isMemOp) {
- if (shouldPrintGOT(TM, Subtarget)) {
- if (Subtarget->GVRequiresExtraLoad(GV, TM, false))
- O << "@GOT";
- else
- O << "@GOTOFF";
- } else if (Subtarget->isPICStyleRIPRel() &&
- !NotRIPRel) {
- if (TM.getRelocationModel() != Reloc::Static) {
- if (Subtarget->GVRequiresExtraLoad(GV, TM, false))
- O << "@GOTPCREL";
- }
-
- isRIPRelative = true;
- }
- }
-
- // Use rip when possible to reduce code size, except when
- // index or base register are also part of the address. e.g.
- // foo(%rip)(%rcx,%rax,4) is not legal.
- if (isRIPRelative)
- O << "(%rip)";
-
- return;
+ break;
}
- case MachineOperand::MO_ExternalSymbol: {
- bool isMemOp = Modifier && !strcmp(Modifier, "mem");
- bool needCloseParen = false;
- std::string Name(TAI->getGlobalPrefix());
- Name += MO.getSymbolName();
-
- // Print function stub suffix unless it's Mac OS X 10.5 and up.
- if (!isMemOp)
- O << '$';
- else if (Name[0] == '$') {
- // The name begins with a dollar-sign. In order to avoid having it look
- // like an integer immediate to the assembler, enclose it in parens.
- O << '(';
- needCloseParen = true;
- }
-
- O << Name;
-
- if (shouldPrintPLT(TM, Subtarget)) {
- std::string GOTName(TAI->getGlobalPrefix());
- GOTName+="_GLOBAL_OFFSET_TABLE_";
- if (Name == GOTName)
- // HACK! Emit extra offset to PC during printing GOT offset to
- // compensate for the size of popl instruction. The resulting code
- // should look like:
- // call .piclabel
- // piclabel:
- // popl %some_register
- // addl $_GLOBAL_ADDRESS_TABLE_ + [.-piclabel], %some_register
- O << " + [.-"
- << getPICLabelString(getFunctionNumber(), TAI, Subtarget) << ']';
- }
-
- if (needCloseParen)
- O << ')';
-
- if (Subtarget->isPICStyleRIPRel())
- O << "(%rip)";
- return;
+ case MachineOperand::MO_ExternalSymbol:
+ /// NOTE: MO_ExternalSymbol in a non-pcrel_imm context is *only* generated
+ /// by _GLOBAL_OFFSET_TABLE_ on X86-32. All others are call operands, which
+ /// are pcrel_imm's.
+ assert(!Subtarget->is64Bit() && !Subtarget->isPICStyleRIPRel());
+ // These are never used as memory operands.
+ assert(!(Modifier && !strcmp(Modifier, "mem")));
+
+ O << '$';
+ O << TAI->getGlobalPrefix();
+ O << MO.getSymbolName();
+ break;
}
+
+ switch (MO.getTargetFlags()) {
default:
- O << "<unknown operand type>"; return;
+ assert(0 && "Unknown target flag on GV operand");
+ case X86II::MO_NO_FLAG:
+ break;
+ case X86II::MO_GOT_ABSOLUTE_ADDRESS:
+ O << " + [.-";
+ PrintPICBaseSymbol();
+ O << ']';
+ break;
+ case X86II::MO_PIC_BASE_OFFSET:
+ O << '-';
+ PrintPICBaseSymbol();
+ break;
+ case X86II::MO_TLSGD: O << "@TLSGD"; break;
+ case X86II::MO_GOTTPOFF: O << "@GOTTPOFF"; break;
+ case X86II::MO_INDNTPOFF: O << "@INDNTPOFF"; break;
+ case X86II::MO_TPOFF: O << "@TPOFF"; break;
+ case X86II::MO_NTPOFF: O << "@NTPOFF"; break;
+ case X86II::MO_GOTPCREL: O << "@GOTPCREL"; break;
+ case X86II::MO_GOT: O << "@GOT"; break;
+ case X86II::MO_GOTOFF: O << "@GOTOFF"; break;
}
}
@@ -670,25 +576,24 @@ void X86ATTAsmPrinter::printSSECC(const MachineInstr *MI, unsigned Op) {
}
void X86ATTAsmPrinter::printLeaMemReference(const MachineInstr *MI, unsigned Op,
- const char *Modifier,
- bool NotRIPRel) {
+ const char *Modifier) {
MachineOperand BaseReg = MI->getOperand(Op);
MachineOperand IndexReg = MI->getOperand(Op+2);
const MachineOperand &DispSpec = MI->getOperand(Op+3);
- NotRIPRel |= IndexReg.getReg() || BaseReg.getReg();
if (DispSpec.isGlobal() ||
DispSpec.isCPI() ||
DispSpec.isJTI() ||
DispSpec.isSymbol()) {
- printOperand(MI, Op+3, "mem", NotRIPRel);
+ printOperand(MI, Op+3, "mem");
} else {
int DispVal = DispSpec.getImm();
if (DispVal || (!IndexReg.getReg() && !BaseReg.getReg()))
O << DispVal;
}
- if (IndexReg.getReg() || BaseReg.getReg()) {
+ if ((IndexReg.getReg() || BaseReg.getReg()) &&
+ (Modifier == 0 || strcmp(Modifier, "no-rip"))) {
unsigned ScaleVal = MI->getOperand(Op+1).getImm();
unsigned BaseRegOperand = 0, IndexRegOperand = 2;
@@ -716,14 +621,14 @@ void X86ATTAsmPrinter::printLeaMemReference(const MachineInstr *MI, unsigned Op,
}
void X86ATTAsmPrinter::printMemReference(const MachineInstr *MI, unsigned Op,
- const char *Modifier, bool NotRIPRel){
+ const char *Modifier) {
assert(isMem(MI, Op) && "Invalid memory reference!");
MachineOperand Segment = MI->getOperand(Op+4);
if (Segment.getReg()) {
printOperand(MI, Op+4, Modifier);
O << ':';
}
- printLeaMemReference(MI, Op, Modifier, NotRIPRel);
+ printLeaMemReference(MI, Op, Modifier);
}
void X86ATTAsmPrinter::printPICJumpTableSetLabel(unsigned uid,
@@ -741,13 +646,19 @@ void X86ATTAsmPrinter::printPICJumpTableSetLabel(unsigned uid,
if (Subtarget->isPICStyleRIPRel())
O << '-' << TAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber()
<< '_' << uid << '\n';
- else
- O << '-' << getPICLabelString(getFunctionNumber(), TAI, Subtarget) << '\n';
+ else {
+ O << '-';
+ PrintPICBaseSymbol();
+ O << '\n';
+ }
}
+
void X86ATTAsmPrinter::printPICLabel(const MachineInstr *MI, unsigned Op) {
- std::string label = getPICLabelString(getFunctionNumber(), TAI, Subtarget);
- O << label << '\n' << label << ':';
+ PrintPICBaseSymbol();
+ O << '\n';
+ PrintPICBaseSymbol();
+ O << ':';
}
@@ -810,7 +721,7 @@ bool X86ATTAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
switch (ExtraCode[0]) {
default: return true; // Unknown modifier.
case 'c': // Don't print "$" before a global var name or constant.
- printOperand(MI, OpNo, "mem", /*NotRIPRel=*/true);
+ printOperand(MI, OpNo, "mem");
return false;
case 'b': // Print QImode register
case 'h': // Print QImode high register
@@ -823,8 +734,19 @@ bool X86ATTAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
return false;
case 'P': // Don't print @PLT, but do print as memory.
- printOperand(MI, OpNo, "mem", /*NotRIPRel=*/true);
+ printOperand(MI, OpNo, "mem");
return false;
+
+ case 'n': { // Negate the immediate or print a '-' before the operand.
+ // Note: this is a temporary solution. It should be handled target
+ // independently as part of the 'MC' work.
+ const MachineOperand &MO = MI->getOperand(OpNo);
+ if (MO.isImm()) {
+ O << -MO.getImm();
+ return false;
+ }
+ O << '-';
+ }
}
}
@@ -849,7 +771,7 @@ bool X86ATTAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI,
// These only apply to registers, ignore on mem.
break;
case 'P': // Don't print @PLT, but do print as memory.
- printMemReference(MI, OpNo, "mem", /*NotRIPRel=*/true);
+ printMemReference(MI, OpNo, "no-rip");
return false;
}
}
@@ -931,8 +853,13 @@ void X86ATTAsmPrinter::printMachineInstruction(const MachineInstr *MI) {
/// doInitialization
bool X86ATTAsmPrinter::doInitialization(Module &M) {
- if (TAI->doesSupportDebugInformation() || TAI->doesSupportExceptionHandling())
- MMI = getAnalysisIfAvailable<MachineModuleInfo>();
+ if (NewAsmPrinter) {
+ Context = new MCContext();
+ // FIXME: Send this to "O" instead of outs(). For now, we force it to
+ // stdout to make it easy to compare.
+ Streamer = createAsmStreamer(*Context, outs());
+ }
+
return AsmPrinter::doInitialization(M);
}
@@ -956,6 +883,8 @@ void X86ATTAsmPrinter::printModuleLevelGV(const GlobalVariable* GVar) {
std::string name = Mang->getValueName(GVar);
Constant *C = GVar->getInitializer();
+ if (isa<MDNode>(C) || isa<MDString>(C))
+ return;
const Type *Type = C->getType();
unsigned Size = TD->getTypeAllocSize(Type);
unsigned Align = TD->getPreferredAlignmentLog(GVar);
@@ -1068,25 +997,6 @@ void X86ATTAsmPrinter::printModuleLevelGV(const GlobalVariable* GVar) {
EmitGlobalConstant(C);
}
-/// printGVStub - Print stub for a global value.
-///
-void X86ATTAsmPrinter::printGVStub(const char *GV, const char *Prefix) {
- printSuffixedName(GV, "$non_lazy_ptr", Prefix);
- O << ":\n\t.indirect_symbol ";
- if (Prefix) O << Prefix;
- O << GV << "\n\t.long\t0\n";
-}
-
-/// printHiddenGVStub - Print stub for a hidden global value.
-///
-void X86ATTAsmPrinter::printHiddenGVStub(const char *GV, const char *Prefix) {
- EmitAlignment(2);
- printSuffixedName(GV, "$non_lazy_ptr", Prefix);
- if (Prefix) O << Prefix;
- O << ":\n" << TAI->getData32bitsDirective() << GV << '\n';
-}
-
-
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();
@@ -1095,100 +1005,62 @@ bool X86ATTAsmPrinter::doFinalization(Module &M) {
if (I->hasDLLExportLinkage())
DLLExportedGVs.insert(Mang->makeNameProper(I->getName(),""));
-
- // If the global is a extern weak symbol, remember to emit the weak
- // reference!
- // FIXME: This is rather hacky, since we'll emit references to ALL weak
- // stuff, not used. But currently it's the only way to deal with extern weak
- // initializers hidden deep inside constant expressions.
- if (I->hasExternalWeakLinkage())
- ExtWeakSymbols.insert(I);
- }
-
- for (Module::const_iterator I = M.begin(), E = M.end();
- I != E; ++I) {
- // If the global is a extern weak symbol, remember to emit the weak
- // reference!
- // FIXME: This is rather hacky, since we'll emit references to ALL weak
- // stuff, not used. But currently it's the only way to deal with extern weak
- // initializers hidden deep inside constant expressions.
- if (I->hasExternalWeakLinkage())
- ExtWeakSymbols.insert(I);
}
- // Output linker support code for dllexported globals
- if (!DLLExportedGVs.empty())
- SwitchToDataSection(".section .drectve");
-
- for (StringSet<>::iterator i = DLLExportedGVs.begin(),
- e = DLLExportedGVs.end();
- i != e; ++i)
- O << "\t.ascii \" -export:" << i->getKeyData() << ",data\"\n";
-
- if (!DLLExportedFns.empty()) {
- SwitchToDataSection(".section .drectve");
- }
-
- for (StringSet<>::iterator i = DLLExportedFns.begin(),
- e = DLLExportedFns.end();
- i != e; ++i)
- O << "\t.ascii \" -export:" << i->getKeyData() << "\"\n";
-
if (Subtarget->isTargetDarwin()) {
SwitchToDataSection("");
-
- // Output stubs for dynamically-linked functions
- for (StringSet<>::iterator i = FnStubs.begin(), e = FnStubs.end();
- i != e; ++i) {
- SwitchToDataSection("\t.section __IMPORT,__jump_table,symbol_stubs,"
- "self_modifying_code+pure_instructions,5", 0);
- const char *p = i->getKeyData();
- printSuffixedName(p, "$stub");
- O << ":\n"
- "\t.indirect_symbol " << p << "\n"
- "\thlt ; hlt ; hlt ; hlt ; hlt\n";
- }
-
- O << '\n';
-
- // Print global value stubs.
- bool InStubSection = false;
+
+ // Add the (possibly multiple) personalities to the set of global value
+ // stubs. Only referenced functions get into the Personalities list.
if (TAI->doesSupportExceptionHandling() && MMI && !Subtarget->is64Bit()) {
- // Add the (possibly multiple) personalities to the set of global values.
- // Only referenced functions get into the Personalities list.
- const std::vector<Function *>& Personalities = MMI->getPersonalities();
- for (std::vector<Function *>::const_iterator I = Personalities.begin(),
- E = Personalities.end(); I != E; ++I) {
- if (!*I)
+ const std::vector<Function*> &Personalities = MMI->getPersonalities();
+ for (unsigned i = 0, e = Personalities.size(); i != e; ++i) {
+ if (Personalities[i] == 0)
continue;
- if (!InStubSection) {
- SwitchToDataSection(
- "\t.section __IMPORT,__pointers,non_lazy_symbol_pointers");
- InStubSection = true;
- }
- printGVStub((*I)->getNameStart(), "_");
+ std::string Name = Mang->getValueName(Personalities[i]);
+ decorateName(Name, Personalities[i]);
+ GVStubs.insert(Name);
}
}
+ // Output stubs for dynamically-linked functions
+ if (!FnStubs.empty()) {
+ for (StringSet<>::iterator I = FnStubs.begin(), E = FnStubs.end();
+ I != E; ++I) {
+ SwitchToDataSection("\t.section __IMPORT,__jump_table,symbol_stubs,"
+ "self_modifying_code+pure_instructions,5", 0);
+ const char *Name = I->getKeyData();
+ printSuffixedName(Name, "$stub");
+ O << ":\n"
+ "\t.indirect_symbol " << Name << "\n"
+ "\thlt ; hlt ; hlt ; hlt ; hlt\n";
+ }
+ O << '\n';
+ }
+
// Output stubs for external and common global variables.
- if (!InStubSection && !GVStubs.empty())
+ if (!GVStubs.empty()) {
SwitchToDataSection(
"\t.section __IMPORT,__pointers,non_lazy_symbol_pointers");
- for (StringSet<>::iterator i = GVStubs.begin(), e = GVStubs.end();
- i != e; ++i)
- printGVStub(i->getKeyData());
+ for (StringSet<>::iterator I = GVStubs.begin(), E = GVStubs.end();
+ I != E; ++I) {
+ const char *Name = I->getKeyData();
+ printSuffixedName(Name, "$non_lazy_ptr");
+ O << ":\n\t.indirect_symbol " << Name << "\n\t.long\t0\n";
+ }
+ }
if (!HiddenGVStubs.empty()) {
SwitchToSection(TAI->getDataSection());
- for (StringSet<>::iterator i = HiddenGVStubs.begin(), e = HiddenGVStubs.end();
- i != e; ++i)
- printHiddenGVStub(i->getKeyData());
+ EmitAlignment(2);
+ for (StringSet<>::iterator I = HiddenGVStubs.begin(),
+ E = HiddenGVStubs.end(); I != E; ++I) {
+ const char *Name = I->getKeyData();
+ printSuffixedName(Name, "$non_lazy_ptr");
+ O << ":\n" << TAI->getData32bitsDirective() << Name << '\n';
+ }
}
- // Emit final debug information.
- if (TAI->doesSupportDebugInformation() || TAI->doesSupportExceptionHandling())
- DW->EndModule();
-
// Funny Darwin hack: This flag tells the linker that no global symbols
// contain code that falls through to other global symbols (e.g. the obvious
// implementation of multiple entry points). If this doesn't occur, the
@@ -1204,17 +1076,40 @@ bool X86ATTAsmPrinter::doFinalization(Module &M) {
<< ";\t.type\t" << (COFF::DT_FCN << COFF::N_BTSHFT)
<< ";\t.endef\n";
}
-
- // Emit final debug information.
- if (TAI->doesSupportDebugInformation() || TAI->doesSupportExceptionHandling())
- DW->EndModule();
- } else if (Subtarget->isTargetELF()) {
- // Emit final debug information.
- if (TAI->doesSupportDebugInformation() || TAI->doesSupportExceptionHandling())
- DW->EndModule();
}
-
- return AsmPrinter::doFinalization(M);
+
+
+ // Output linker support code for dllexported globals on windows.
+ if (!DLLExportedGVs.empty()) {
+ SwitchToDataSection(".section .drectve");
+
+ for (StringSet<>::iterator i = DLLExportedGVs.begin(),
+ e = DLLExportedGVs.end(); i != e; ++i)
+ O << "\t.ascii \" -export:" << i->getKeyData() << ",data\"\n";
+ }
+
+ if (!DLLExportedFns.empty()) {
+ SwitchToDataSection(".section .drectve");
+
+ for (StringSet<>::iterator i = DLLExportedFns.begin(),
+ e = DLLExportedFns.end();
+ i != e; ++i)
+ O << "\t.ascii \" -export:" << i->getKeyData() << "\"\n";
+ }
+
+ // Do common shutdown.
+ bool Changed = AsmPrinter::doFinalization(M);
+
+ if (NewAsmPrinter) {
+ Streamer->Finish();
+
+ delete Streamer;
+ delete Context;
+ Streamer = 0;
+ Context = 0;
+ }
+
+ return Changed;
}
// Include the auto-generated portion of the assembly writer.
diff --git a/lib/Target/X86/AsmPrinter/X86ATTAsmPrinter.h b/lib/Target/X86/AsmPrinter/X86ATTAsmPrinter.h
index 68a6bc8..bd96115 100644
--- a/lib/Target/X86/AsmPrinter/X86ATTAsmPrinter.h
+++ b/lib/Target/X86/AsmPrinter/X86ATTAsmPrinter.h
@@ -27,17 +27,23 @@
namespace llvm {
class MachineJumpTableInfo;
+class MCContext;
class MCInst;
+class MCStreamer;
class VISIBILITY_HIDDEN X86ATTAsmPrinter : public AsmPrinter {
- MachineModuleInfo *MMI;
const X86Subtarget *Subtarget;
+
+ MCContext *Context;
+ MCStreamer *Streamer;
public:
explicit X86ATTAsmPrinter(raw_ostream &O, X86TargetMachine &TM,
const TargetAsmInfo *T, CodeGenOpt::Level OL,
bool V)
- : AsmPrinter(O, TM, T, OL, V), MMI(0) {
+ : AsmPrinter(O, TM, T, OL, V) {
Subtarget = &TM.getSubtarget<X86Subtarget>();
+ Context = 0;
+ Streamer = 0;
}
virtual const char *getPassName() const {
@@ -69,7 +75,7 @@ class VISIBILITY_HIDDEN X86ATTAsmPrinter : public AsmPrinter {
bool printInstruction(const MCInst *MI);
void printOperand(const MCInst *MI, unsigned OpNo,
- const char *Modifier = 0, bool NotRIPRel = false);
+ const char *Modifier = 0);
void printMemReference(const MCInst *MI, unsigned Op);
void printLeaMemReference(const MCInst *MI, unsigned Op);
void printSSECC(const MCInst *MI, unsigned Op);
@@ -117,7 +123,7 @@ class VISIBILITY_HIDDEN X86ATTAsmPrinter : public AsmPrinter {
// These methods are used by the tablegen'erated instruction printer.
void printOperand(const MachineInstr *MI, unsigned OpNo,
- const char *Modifier = 0, bool NotRIPRel = false);
+ const char *Modifier = 0);
void print_pcrel_imm(const MachineInstr *MI, unsigned OpNo);
void printi8mem(const MachineInstr *MI, unsigned OpNo) {
printMemReference(MI, OpNo);
@@ -165,9 +171,9 @@ class VISIBILITY_HIDDEN X86ATTAsmPrinter : public AsmPrinter {
void printMachineInstruction(const MachineInstr *MI);
void printSSECC(const MachineInstr *MI, unsigned Op);
void printMemReference(const MachineInstr *MI, unsigned Op,
- const char *Modifier=NULL, bool NotRIPRel = false);
+ const char *Modifier=NULL);
void printLeaMemReference(const MachineInstr *MI, unsigned Op,
- const char *Modifier=NULL, bool NotRIPRel = false);
+ const char *Modifier=NULL);
void printPICJumpTableSetLabel(unsigned uid,
const MachineBasicBlock *MBB) const;
void printPICJumpTableSetLabel(unsigned uid, unsigned uid2,
@@ -181,9 +187,8 @@ class VISIBILITY_HIDDEN X86ATTAsmPrinter : public AsmPrinter {
void printPICLabel(const MachineInstr *MI, unsigned Op);
void printModuleLevelGV(const GlobalVariable* GVar);
- void printGVStub(const char *GV, const char *Prefix = NULL);
- void printHiddenGVStub(const char *GV, const char *Prefix = NULL);
-
+ void PrintPICBaseSymbol() const;
+
bool runOnMachineFunction(MachineFunction &F);
void emitFunctionHeader(const MachineFunction &MF);
diff --git a/lib/Target/X86/AsmPrinter/X86ATTInstPrinter.cpp b/lib/Target/X86/AsmPrinter/X86ATTInstPrinter.cpp
index 9d50edc..fa0ee75 100644
--- a/lib/Target/X86/AsmPrinter/X86ATTInstPrinter.cpp
+++ b/lib/Target/X86/AsmPrinter/X86ATTInstPrinter.cpp
@@ -65,7 +65,7 @@ void X86ATTAsmPrinter::print_pcrel_imm(const MCInst *MI, unsigned OpNo) {
void X86ATTAsmPrinter::printOperand(const MCInst *MI, unsigned OpNo,
- const char *Modifier, bool NotRIPRel) {
+ const char *Modifier) {
assert(Modifier == 0 && "Modifiers should not be used");
const MCOperand &Op = MI->getOperand(OpNo);
@@ -93,13 +93,11 @@ void X86ATTAsmPrinter::printOperand(const MCInst *MI, unsigned OpNo,
}
void X86ATTAsmPrinter::printLeaMemReference(const MCInst *MI, unsigned Op) {
- bool NotRIPRel = false;
const MCOperand &BaseReg = MI->getOperand(Op);
const MCOperand &IndexReg = MI->getOperand(Op+2);
const MCOperand &DispSpec = MI->getOperand(Op+3);
- NotRIPRel |= IndexReg.getReg() || BaseReg.getReg();
if (DispSpec.isImm()) {
int64_t DispVal = DispSpec.getImm();
if (DispVal || (!IndexReg.getReg() && !BaseReg.getReg()))
@@ -108,7 +106,7 @@ void X86ATTAsmPrinter::printLeaMemReference(const MCInst *MI, unsigned Op) {
abort();
//assert(DispSpec.isGlobal() || DispSpec.isCPI() ||
// DispSpec.isJTI() || DispSpec.isSymbol());
- //printOperand(MI, Op+3, "mem", NotRIPRel);
+ //printOperand(MI, Op+3, "mem");
}
if (IndexReg.getReg() || BaseReg.getReg()) {
diff --git a/lib/Target/X86/AsmPrinter/X86AsmPrinter.cpp b/lib/Target/X86/AsmPrinter/X86AsmPrinter.cpp
index a39203b..d1623d6 100644
--- a/lib/Target/X86/AsmPrinter/X86AsmPrinter.cpp
+++ b/lib/Target/X86/AsmPrinter/X86AsmPrinter.cpp
@@ -47,8 +47,5 @@ namespace {
extern "C" int X86AsmPrinterForceLink;
int X86AsmPrinterForceLink = 0;
-// Force static initialization when called from
-// llvm/InitializeAllAsmPrinters.h
-namespace llvm {
- void InitializeX86AsmPrinter() { }
-}
+// Force static initialization.
+extern "C" void LLVMInitializeX86AsmPrinter() { }
OpenPOWER on IntegriCloud