SwitchToTextSection(getSectionForFunction(*F).c_str(), F);
+ unsigned FnAlign = OptimizeForSize ? 1 : 4;
switch (F->getLinkage()) {
default: assert(0 && "Unknown linkage type!");
case Function::InternalLinkage: // Symbols default to internal.
- EmitAlignment(4, F);
+ EmitAlignment(FnAlign, F);
break;
case Function::DLLExportLinkage:
DLLExportedFns.insert(Mang->makeNameProper(F->getName(), ""));
//FALLS THROUGH
case Function::ExternalLinkage:
- EmitAlignment(4, F);
+ EmitAlignment(FnAlign, F);
O << "\t.globl\t" << CurrentFnName << "\n";
break;
case Function::LinkOnceLinkage:
case Function::WeakLinkage:
- EmitAlignment(4, F);
+ EmitAlignment(FnAlign, F);
if (Subtarget->isTargetDarwin()) {
O << "\t.globl\t" << CurrentFnName << "\n";
O << TAI->getWeakDefDirective() << CurrentFnName << "\n";
F->getLinkage() == Function::WeakLinkage))
O << "Lllvm$workaround$fake$stub$" << CurrentFnName << ":\n";
- if (TAI->doesSupportDebugInformation()) {
- // Emit pre-function debug information.
+ if (TAI->doesSupportDebugInformation() ||
+ TAI->doesSupportExceptionHandling()) {
+ // Emit pre-function debug and/or EH information.
DW.BeginFunction(&MF);
}
- if (Subtarget->isTargetDarwin()) {
- // If the function is empty, then we need to emit *something*. Otherwise,
- // the function's label might be associated with something that it wasn't
- // meant to be associated with. We emit a noop in this situation.
- MachineFunction::iterator I = MF.begin();
-
- if (++I == MF.end() && MF.front().empty())
- O << "\tnop\n";
- }
-
// Print out code for the function.
+ bool hasAnyRealCode = false;
for (MachineFunction::const_iterator I = MF.begin(), E = MF.end();
I != E; ++I) {
// Print a label for the basic block.
for (MachineBasicBlock::const_iterator II = I->begin(), IE = I->end();
II != IE; ++II) {
// Print the assembly for the instruction.
+ if (II->getOpcode() != X86::LABEL)
+ hasAnyRealCode = true;
printMachineInstruction(II);
}
}
+ if (Subtarget->isTargetDarwin() && !hasAnyRealCode) {
+ // If the function is empty, then we need to emit *something*. Otherwise,
+ // the function's label might be associated with something that it wasn't
+ // meant to be associated with. We emit a noop in this situation.
+ // We are assuming inline asms are code.
+ O << "\tnop\n";
+ }
+
if (TAI->hasDotTypeDotSizeDirective())
O << "\t.size\t" << CurrentFnName << ", .-" << CurrentFnName << "\n";
return false;
}
-static inline bool printGOT(TargetMachine &TM, const X86Subtarget* ST) {
+static inline bool shouldPrintGOT(TargetMachine &TM, const X86Subtarget* ST) {
return ST->isPICStyleGOT() && TM.getRelocationModel() == Reloc::PIC_;
}
-static inline bool printStub(TargetMachine &TM, const X86Subtarget* ST) {
+static inline bool shouldPrintPLT(TargetMachine &TM, const X86Subtarget* ST) {
+ return ST->isTargetELF() && TM.getRelocationModel() == Reloc::PIC_ &&
+ (ST->isPICStyleRIPRel() || ST->isPICStyleGOT());
+}
+
+static inline bool shouldPrintStub(TargetMachine &TM, const X86Subtarget* ST) {
return ST->isPICStyleStub() && TM.getRelocationModel() != Reloc::Static;
}
void X86ATTAsmPrinter::printOperand(const MachineInstr *MI, unsigned OpNo,
const char *Modifier, bool NotRIPRel) {
const MachineOperand &MO = MI->getOperand(OpNo);
- const TargetRegisterInfo &RI = *TM.getRegisterInfo();
switch (MO.getType()) {
case MachineOperand::MO_Register: {
assert(TargetRegisterInfo::isPhysicalRegister(MO.getReg()) &&
O << '%';
unsigned Reg = MO.getReg();
if (Modifier && strncmp(Modifier, "subreg", strlen("subreg")) == 0) {
- MVT::ValueType VT = (strcmp(Modifier+6,"64") == 0) ?
+ MVT VT = (strcmp(Modifier+6,"64") == 0) ?
MVT::i64 : ((strcmp(Modifier+6, "32") == 0) ? MVT::i32 :
((strcmp(Modifier+6,"16") == 0) ? MVT::i16 : MVT::i8));
Reg = getX86SubSuperRegister(Reg, VT);
}
- for (const char *Name = RI.get(Reg).AsmName; *Name; ++Name)
+ for (const char *Name = TRI->getAsmName(Reg); *Name; ++Name)
O << (char)tolower(*Name);
return;
}
const GlobalValue *GV = MO.getGlobal();
const GlobalVariable *GVar = dyn_cast<GlobalVariable>(GV);
if (!GVar) {
- // If GV is an alias - use aliasee for determing thread-localness
+ // 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());
}
needCloseParen = true;
}
- if (printStub(TM, Subtarget)) {
+ if (shouldPrintStub(TM, Subtarget)) {
// Link-once, declaration, or Weakly-linked global variables need
// non-lazily-resolved stubs
if (GV->isDeclaration() ||
GV->hasWeakLinkage() ||
- GV->hasLinkOnceLinkage()) {
+ GV->hasLinkOnceLinkage() ||
+ GV->hasCommonLinkage()) {
// Dynamically-resolved functions need a stub for the function.
if (isCallOp && isa<Function>(GV)) {
FnStubs.insert(Name);
- O << TAI->getPrivateGlobalPrefix() << Name << "$stub";
+ printSuffixedName(Name, "$stub");
} else {
GVStubs.insert(Name);
- O << TAI->getPrivateGlobalPrefix() << Name << "$non_lazy_ptr";
+ printSuffixedName(Name, "$non_lazy_ptr");
}
} else {
if (GV->hasDLLImportLinkage())
}
O << Name;
- if (isCallOp && isa<Function>(GV)) {
- if (printGOT(TM, Subtarget)) {
- // Assemble call via PLT for non-local symbols
- if (!(GV->hasHiddenVisibility() || GV->hasProtectedVisibility()) ||
- GV->isDeclaration())
+ if (isCallOp) {
+ if (shouldPrintPLT(TM, Subtarget)) {
+ // Assemble call via PLT for externally visible symbols
+ if (!GV->hasHiddenVisibility() && !GV->hasProtectedVisibility() &&
+ !GV->hasInternalLinkage())
O << "@PLT";
}
if (Subtarget->isTargetCygMing() && GV->isDeclaration())
if (GV->hasExternalWeakLinkage())
ExtWeakSymbols.insert(GV);
-
+
int Offset = MO.getOffset();
if (Offset > 0)
O << "+" << Offset;
O << Offset;
if (isThreadLocal) {
- if (TM.getRelocationModel() == Reloc::PIC_)
+ if (TM.getRelocationModel() == Reloc::PIC_ || Subtarget->is64Bit())
O << "@TLSGD"; // general dynamic TLS model
else
if (GV->isDeclaration())
else
O << "@NTPOFF"; // local exec TLS model
} else if (isMemOp) {
- if (printGOT(TM, Subtarget)) {
+ if (shouldPrintGOT(TM, Subtarget)) {
if (Subtarget->GVRequiresExtraLoad(GV, TM, false))
O << "@GOT";
else
bool needCloseParen = false;
std::string Name(TAI->getGlobalPrefix());
Name += MO.getSymbolName();
- if (isCallOp && printStub(TM, Subtarget)) {
+ if (isCallOp && shouldPrintStub(TM, Subtarget)) {
FnStubs.insert(Name);
- O << TAI->getPrivateGlobalPrefix() << Name << "$stub";
+ printSuffixedName(Name, "$stub");
return;
}
if (!isCallOp)
O << Name;
- if (printGOT(TM, Subtarget)) {
+ if (shouldPrintPLT(TM, Subtarget)) {
std::string GOTName(TAI->getGlobalPrefix());
GOTName+="_GLOBAL_OFFSET_TABLE_";
if (Name == GOTName)
bool X86ATTAsmPrinter::printAsmMRegister(const MachineOperand &MO,
const char Mode) {
- const TargetRegisterInfo &RI = *TM.getRegisterInfo();
unsigned Reg = MO.getReg();
switch (Mode) {
default: return true; // Unknown mode.
}
O << '%';
- for (const char *Name = RI.get(Reg).AsmName; *Name; ++Name)
+ for (const char *Name = TRI->getAsmName(Reg); *Name; ++Name)
O << (char)tolower(*Name);
return false;
}
void X86ATTAsmPrinter::printMachineInstruction(const MachineInstr *MI) {
++EmittedInsts;
- // See if a truncate instruction can be turned into a nop.
- switch (MI->getOpcode()) {
- default: break;
- case X86::PsMOVZX64rr32:
- O << TAI->getCommentString() << " ZERO-EXTEND " << "\n\t";
- break;
- }
-
// Call the autogenerated instruction printer routines.
printInstruction(MI);
}
// Include the auto-generated portion of the assembly writer.
#include "X86GenAsmWriter.inc"
-