unsigned AsmVariant,
const char *ExtraCode);
- /// PrintGlobalVariable - Emit the specified global variable and its
- /// initializer to the output stream.
- virtual void PrintGlobalVariable(const GlobalVariable *GV) = 0;
-
/// SetupMachineFunction - This should be called when a new MachineFunction
/// is being processed from runOnMachineFunction.
void SetupMachineFunction(MachineFunction &MF);
void EmitJumpTableInfo(MachineJumpTableInfo *MJTI, MachineFunction &MF);
/// EmitGlobalVariable - Emit the specified global variable to the .s file.
- void EmitGlobalVariable(const GlobalVariable *GV);
+ virtual void EmitGlobalVariable(const GlobalVariable *GV);
/// EmitSpecialLLVMGlobal - Check to see if the specified global is a
/// special global used by LLVM. If so, emit it and return true, otherwise
// Check to see if this is a special global used by LLVM, if so, emit it.
if (EmitSpecialLLVMGlobal(GV))
return;
+
+ MCSymbol *GVSym = GetGlobalValueSymbol(GV);
+ printVisibility(GVSym, GV->getVisibility());
+
+ if (MAI->hasDotTypeDotSizeDirective()) {
+ O << "\t.type\t" << *GVSym;
+ if (MAI->getCommentString()[0] != '@')
+ O << ",@object\n";
+ else
+ O << ",%object\n";
+ }
- // Let the target emit it.
- PrintGlobalVariable(GV);
+ SectionKind GVKind = TargetLoweringObjectFile::getKindForGlobal(GV, TM);
+
+ const TargetData *TD = TM.getTargetData();
+ unsigned Size = TD->getTypeAllocSize(GV->getType()->getElementType());
+ unsigned AlignLog = TD->getPreferredAlignmentLog(GV);
+
+ // Handle normal common symbols.
+ if (GVKind.isCommon()) {
+ if (Size == 0) Size = 1; // .comm Foo, 0 is undefined, avoid it.
+
+ O << MAI->getCOMMDirective() << *GVSym << ',' << Size;
+ if (MAI->getCOMMDirectiveTakesAlignment())
+ O << ',' << (MAI->getAlignmentIsInBytes() ? (1 << AlignLog) : AlignLog);
+
+ if (VerboseAsm) {
+ O << "\t\t" << MAI->getCommentString() << " '";
+ WriteAsOperand(O, GV, /*PrintType=*/false, GV->getParent());
+ O << '\'';
+ }
+ O << '\n';
+ return;
+ }
+
+ if (GVKind.isBSSLocal()) {
+ if (Size == 0) Size = 1; // .comm Foo, 0 is undefined, avoid it.
+
+ if (const char *LComm = MAI->getLCOMMDirective()) {
+ O << LComm << *GVSym << ',' << Size;
+ if (MAI->getLCOMMDirectiveTakesAlignment())
+ O << ',' << AlignLog;
+ } else {
+ O << "\t.local\t" << *GVSym << '\n';
+ O << MAI->getCOMMDirective() << *GVSym << ',' << Size;
+ if (MAI->getCOMMDirectiveTakesAlignment())
+ O << ',' << (MAI->getAlignmentIsInBytes() ? (1 << AlignLog) : AlignLog);
+ }
+ if (VerboseAsm) {
+ O.PadToColumn(MAI->getCommentColumn());
+ O << MAI->getCommentString() << ' ';
+ WriteAsOperand(O, GV, /*PrintType=*/false, GV->getParent());
+ }
+ O << '\n';
+ return;
+ }
+
+ const MCSection *TheSection =
+ getObjFileLowering().SectionForGlobal(GV, GVKind, Mang, TM);
+
+ // Handle the zerofill directive on darwin, which is a special form of BSS
+ // emission.
+ if (GVKind.isBSSExtern() && MAI->hasMachoZeroFillDirective()) {
+ // .globl _foo
+ OutStreamer.EmitSymbolAttribute(GVSym, MCStreamer::Global);
+ // .zerofill __DATA, __common, _foo, 400, 5
+ OutStreamer.EmitZerofill(TheSection, GVSym, Size, 1 << AlignLog);
+ return;
+ }
+
+ OutStreamer.SwitchSection(TheSection);
+
+ // TODO: Factor into an 'emit linkage' thing that is shared with function
+ // bodies.
+ switch (GV->getLinkage()) {
+ case GlobalValue::CommonLinkage:
+ case GlobalValue::LinkOnceAnyLinkage:
+ case GlobalValue::LinkOnceODRLinkage:
+ case GlobalValue::WeakAnyLinkage:
+ case GlobalValue::WeakODRLinkage:
+ case GlobalValue::LinkerPrivateLinkage:
+ if (const char *WeakDef = MAI->getWeakDefDirective()) {
+ // .globl _foo
+ OutStreamer.EmitSymbolAttribute(GVSym, MCStreamer::Global);
+ // .weak_definition _foo
+ O << WeakDef << *GVSym << '\n';
+ } else if (const char *LinkOnce = MAI->getLinkOnceDirective()) {
+ // .globl _foo
+ OutStreamer.EmitSymbolAttribute(GVSym, MCStreamer::Global);
+ // .linkonce same_size
+ O << LinkOnce;
+ } else
+ O << "\t.weak\t" << *GVSym << '\n';
+ break;
+ case GlobalValue::DLLExportLinkage:
+ case GlobalValue::AppendingLinkage:
+ // FIXME: appending linkage variables should go into a section of
+ // their name or something. For now, just emit them as external.
+ case GlobalValue::ExternalLinkage:
+ // If external or appending, declare as a global symbol.
+ // .globl _foo
+ OutStreamer.EmitSymbolAttribute(GVSym, MCStreamer::Global);
+ break;
+ case GlobalValue::PrivateLinkage:
+ case GlobalValue::InternalLinkage:
+ break;
+ default:
+ llvm_unreachable("Unknown linkage type!");
+ }
+
+ EmitAlignment(AlignLog, GV);
+ O << *GVSym << ":";
+ if (VerboseAsm) {
+ O.PadToColumn(MAI->getCommentColumn());
+ O << MAI->getCommentString() << ' ';
+ WriteAsOperand(O, GV, /*PrintType=*/false, GV->getParent());
+ }
+ O << '\n';
+
+ EmitGlobalConstant(GV->getInitializer());
+
+ if (MAI->hasDotTypeDotSizeDirective())
+ O << "\t.size\t" << *GVSym << ", " << Size << '\n';
}
void printOp(const MachineOperand &MO, bool IsCallOp = false);
void printOperand(const MachineInstr *MI, int opNum);
void printBaseOffsetPair(const MachineInstr *MI, int i, bool brackets=true);
- void PrintGlobalVariable(const GlobalVariable *GVar);
bool runOnMachineFunction(MachineFunction &F);
void EmitStartOfAsmFile(Module &M);
O << "\t.set noat\n";
}
-void AlphaAsmPrinter::PrintGlobalVariable(const GlobalVariable *GVar) {
- const TargetData *TD = TM.getTargetData();
-
- if (!GVar->hasInitializer()) return; // External global require no code
-
- // Check to see if this is a special global used by LLVM, if so, emit it.
- if (EmitSpecialLLVMGlobal(GVar))
- return;
-
- MCSymbol *GVarSym = GetGlobalValueSymbol(GVar);
- Constant *C = GVar->getInitializer();
- unsigned Size = TD->getTypeAllocSize(C->getType());
- unsigned Align = TD->getPreferredAlignmentLog(GVar);
-
- // 0: Switch to section
- OutStreamer.SwitchSection(getObjFileLowering().SectionForGlobal(GVar, Mang,
- TM));
-
- // 1: Check visibility
- printVisibility(GVarSym, GVar->getVisibility());
-
- // 2: Kind
- switch (GVar->getLinkage()) {
- case GlobalValue::LinkOnceAnyLinkage:
- case GlobalValue::LinkOnceODRLinkage:
- case GlobalValue::WeakAnyLinkage:
- case GlobalValue::WeakODRLinkage:
- case GlobalValue::CommonLinkage:
- O << MAI->getWeakRefDirective() << *GVarSym << '\n';
- break;
- case GlobalValue::AppendingLinkage:
- case GlobalValue::ExternalLinkage:
- O << MAI->getGlobalDirective() << *GVarSym << '\n';
- break;
- case GlobalValue::InternalLinkage:
- case GlobalValue::PrivateLinkage:
- case GlobalValue::LinkerPrivateLinkage:
- break;
- default:
- llvm_unreachable("Unknown linkage type!");
- }
-
- // 3: Type, Size, Align
- if (MAI->hasDotTypeDotSizeDirective()) {
- O << "\t.type\t" << *GVarSym << ", @object\n";
- O << "\t.size\t" << *GVarSym << ", " << Size << "\n";
- }
-
- EmitAlignment(Align, GVar);
-
- O << *GVarSym << ":\n";
-
- EmitGlobalConstant(C);
- O << '\n';
-}
-
/// PrintAsmOperand - Print out an operand for an inline asm expression.
///
bool AlphaAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
unsigned AsmVariant, const char *ExtraCode);
bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo,
unsigned AsmVariant, const char *ExtraCode);
- void PrintGlobalVariable(const GlobalVariable* GVar);
};
} // end of anonymous namespace
}
}
-void BlackfinAsmPrinter::PrintGlobalVariable(const GlobalVariable* GV) {
- const TargetData *TD = TM.getTargetData();
-
- if (!GV->hasInitializer() || EmitSpecialLLVMGlobal(GV))
- return;
-
- MCSymbol *GVSym = GetGlobalValueSymbol(GV);
- Constant *C = GV->getInitializer();
-
- OutStreamer.SwitchSection(getObjFileLowering().SectionForGlobal(GV, Mang,
- TM));
- emitLinkage(GVSym, GV->getLinkage());
- EmitAlignment(TD->getPreferredAlignmentLog(GV), GV);
- printVisibility(GVSym, GV->getVisibility());
-
- O << "\t.type " << *GVSym << ", STT_OBJECT\n";
- O << "\t.size " << *GVSym << "\n";
- O << ',' << TD->getTypeAllocSize(C->getType()) << '\n';
- O << *GVSym << ":\n";
- EmitGlobalConstant(C);
-}
-
/// runOnMachineFunction - This uses the printInstruction()
/// method to print assembly for each instruction.
///
AU.addRequired<DwarfWriter>();
SPUAsmPrinter::getAnalysisUsage(AU);
}
-
- //! Emit a global variable according to its section and type
- void PrintGlobalVariable(const GlobalVariable* GVar);
};
} // end of anonymous namespace
return false;
}
-
-/*!
- Emit a global variable according to its section, alignment, etc.
-
- \note This code was shamelessly copied from the PowerPC's assembly printer,
- which sort of screams for some kind of refactorization of common code.
- */
-void LinuxAsmPrinter::PrintGlobalVariable(const GlobalVariable *GVar) {
- const TargetData *TD = TM.getTargetData();
-
- if (!GVar->hasInitializer())
- return;
-
- // Check to see if this is a special global used by LLVM, if so, emit it.
- if (EmitSpecialLLVMGlobal(GVar))
- return;
-
- MCSymbol *GVarSym = GetGlobalValueSymbol(GVar);
-
- printVisibility(GVarSym, GVar->getVisibility());
-
- Constant *C = GVar->getInitializer();
- const Type *Type = C->getType();
- unsigned Size = TD->getTypeAllocSize(Type);
- unsigned Align = TD->getPreferredAlignmentLog(GVar);
-
- OutStreamer.SwitchSection(getObjFileLowering().SectionForGlobal(GVar, Mang,
- TM));
-
- if (C->isNullValue() && /* FIXME: Verify correct */
- !GVar->hasSection() &&
- (GVar->hasLocalLinkage() || GVar->hasExternalLinkage() ||
- GVar->isWeakForLinker())) {
- if (Size == 0) Size = 1; // .comm Foo, 0 is undefined, avoid it.
-
- if (GVar->hasExternalLinkage()) {
- O << "\t.global " << *GVarSym << '\n';
- O << "\t.type " << *GVarSym << ", @object\n";
- O << *GVarSym << ":\n";
- O << "\t.zero " << Size << '\n';
- } else if (GVar->hasLocalLinkage()) {
- O << MAI->getLCOMMDirective() << *GVarSym << ',' << Size;
- } else {
- O << ".comm " << *GVarSym << ',' << Size;
- }
- O << "\t\t" << MAI->getCommentString() << " '";
- WriteAsOperand(O, GVar, /*PrintType=*/false, GVar->getParent());
- O << "'\n";
- return;
- }
-
- switch (GVar->getLinkage()) {
- // Should never be seen for the CellSPU platform...
- case GlobalValue::LinkOnceAnyLinkage:
- case GlobalValue::LinkOnceODRLinkage:
- case GlobalValue::WeakAnyLinkage:
- case GlobalValue::WeakODRLinkage:
- case GlobalValue::CommonLinkage:
- O << "\t.global " << *GVarSym << "\n\t.type " << *GVarSym << ", @object\n";
- O << "\t.weak " << *GVarSym << '\n';
- break;
- case GlobalValue::AppendingLinkage:
- // FIXME: appending linkage variables should go into a section of
- // their name or something. For now, just emit them as external.
- case GlobalValue::ExternalLinkage:
- // If external or appending, declare as a global symbol
- O << "\t.global " << *GVarSym << "\n\t.type " << *GVarSym << ", @object\n";
- break;
- case GlobalValue::PrivateLinkage:
- case GlobalValue::LinkerPrivateLinkage:
- case GlobalValue::InternalLinkage:
- break;
- default:
- llvm_report_error("Unknown linkage type!");
- }
-
- EmitAlignment(Align, GVar);
- O << *GVarSym << ":\t\t\t\t" << MAI->getCommentString() << " '";
- WriteAsOperand(O, GVar, /*PrintType=*/false, GVar->getParent());
- O << "'\n";
-
- EmitGlobalConstant(C);
- O << '\n';
-}
-
// Force static initialization.
extern "C" void LLVMInitializeCellSPUAsmPrinter() {
RegisterAsmPrinter<LinuxAsmPrinter> X(TheCellSPUTarget);
const char *ExtraCode);
void printInstructionThroughMCStreamer(const MachineInstr *MI);
- void PrintGlobalVariable(const GlobalVariable* GVar);
void emitFunctionHeader(const MachineFunction &MF);
bool runOnMachineFunction(MachineFunction &F);
};
} // end of anonymous namespace
-void MSP430AsmPrinter::PrintGlobalVariable(const GlobalVariable* GVar) {
- if (!GVar->hasInitializer())
- return; // External global require no code
-
- // Check to see if this is a special global used by LLVM, if so, emit it.
- if (EmitSpecialLLVMGlobal(GVar))
- return;
-
- const TargetData *TD = TM.getTargetData();
-
- MCSymbol *GVarSym = GetGlobalValueSymbol(GVar);
- Constant *C = GVar->getInitializer();
- unsigned Size = TD->getTypeAllocSize(C->getType());
- unsigned Align = TD->getPreferredAlignmentLog(GVar);
-
- printVisibility(GVarSym, GVar->getVisibility());
-
- O << "\t.type\t" << *GVarSym << ",@object\n";
-
- OutStreamer.SwitchSection(getObjFileLowering().SectionForGlobal(GVar, Mang,
- TM));
-
- if (C->isNullValue() && !GVar->hasSection() &&
- !GVar->isThreadLocal() &&
- (GVar->hasLocalLinkage() || GVar->isWeakForLinker())) {
-
- if (Size == 0) Size = 1; // .comm Foo, 0 is undefined, avoid it.
-
- if (GVar->hasLocalLinkage())
- O << "\t.local\t" << *GVarSym << '\n';
-
- O << MAI->getCOMMDirective() << *GVarSym << ',' << Size;
- if (MAI->getCOMMDirectiveTakesAlignment())
- O << ',' << (MAI->getAlignmentIsInBytes() ? (1 << Align) : Align);
-
- if (VerboseAsm) {
- O.PadToColumn(MAI->getCommentColumn());
- O << MAI->getCommentString() << ' ';
- WriteAsOperand(O, GVar, /*PrintType=*/false, GVar->getParent());
- }
- O << '\n';
- return;
- }
-
- switch (GVar->getLinkage()) {
- case GlobalValue::CommonLinkage:
- case GlobalValue::LinkOnceAnyLinkage:
- case GlobalValue::LinkOnceODRLinkage:
- case GlobalValue::WeakAnyLinkage:
- case GlobalValue::WeakODRLinkage:
- O << "\t.weak\t" << *GVarSym << '\n';
- break;
- case GlobalValue::DLLExportLinkage:
- case GlobalValue::AppendingLinkage:
- // FIXME: appending linkage variables should go into a section of
- // their name or something. For now, just emit them as external.
- case GlobalValue::ExternalLinkage:
- // If external or appending, declare as a global symbol
- O << "\t.globl " << *GVarSym << '\n';
- // FALL THROUGH
- case GlobalValue::PrivateLinkage:
- case GlobalValue::LinkerPrivateLinkage:
- case GlobalValue::InternalLinkage:
- break;
- default:
- assert(0 && "Unknown linkage type!");
- }
-
- // Use 16-bit alignment by default to simplify bunch of stuff
- EmitAlignment(Align, GVar);
- O << *GVarSym << ":";
- if (VerboseAsm) {
- O.PadToColumn(MAI->getCommentColumn());
- O << MAI->getCommentString() << ' ';
- WriteAsOperand(O, GVar, /*PrintType=*/false, GVar->getParent());
- }
- O << '\n';
-
- EmitGlobalConstant(C);
-
- if (MAI->hasDotTypeDotSizeDirective())
- O << "\t.size\t" << *GVarSym << ", " << Size << '\n';
-}
void MSP430AsmPrinter::emitFunctionHeader(const MachineFunction &MF) {
const Function *F = MF.getFunction();
const char *Modifier = 0);
void printFCCOperand(const MachineInstr *MI, int opNum,
const char *Modifier = 0);
- void PrintGlobalVariable(const GlobalVariable *GVar);
void printSavedRegsBitmask(MachineFunction &MF);
void printHex32(unsigned int Value);
O << "\t.previous" << '\n';
}
-void MipsAsmPrinter::PrintGlobalVariable(const GlobalVariable *GVar) {
- const TargetData *TD = TM.getTargetData();
-
- if (!GVar->hasInitializer())
- return; // External global require no code
-
- // Check to see if this is a special global used by LLVM, if so, emit it.
- if (EmitSpecialLLVMGlobal(GVar))
- return;
-
- O << "\n\n";
- MCSymbol *GVarSym = GetGlobalValueSymbol(GVar);
- Constant *C = GVar->getInitializer();
- const Type *CTy = C->getType();
- unsigned Size = TD->getTypeAllocSize(CTy);
-
- // A data structure or array is aligned in memory to the largest
- // alignment boundary required by any data type inside it (this matches
- // the Preferred Type Alignment). For integral types, the alignment is
- // the type size.
- unsigned Align;
- if (CTy->getTypeID() == Type::IntegerTyID ||
- CTy->getTypeID() == Type::VoidTyID) {
- assert(!(Size & (Size-1)) && "Alignment is not a power of two!");
- Align = Log2_32(Size);
- } else
- Align = TD->getPreferredTypeAlignmentShift(CTy);
-
- printVisibility(GVarSym, GVar->getVisibility());
-
- OutStreamer.SwitchSection(getObjFileLowering().SectionForGlobal(GVar, Mang,
- TM));
-
- if (C->isNullValue() && !GVar->hasSection()) {
- if (!GVar->isThreadLocal() &&
- (GVar->hasLocalLinkage() || GVar->isWeakForLinker())) {
- if (Size == 0) Size = 1; // .comm Foo, 0 is undefined, avoid it.
-
- if (GVar->hasLocalLinkage())
- O << "\t.local\t" << *GVarSym << '\n';
-
- O << MAI->getCOMMDirective() << *GVarSym << ',' << Size;
- if (MAI->getCOMMDirectiveTakesAlignment())
- O << ',' << (1 << Align);
-
- O << '\n';
- return;
- }
- }
- switch (GVar->getLinkage()) {
- case GlobalValue::LinkOnceAnyLinkage:
- case GlobalValue::LinkOnceODRLinkage:
- case GlobalValue::CommonLinkage:
- case GlobalValue::WeakAnyLinkage:
- case GlobalValue::WeakODRLinkage:
- // FIXME: Verify correct for weak.
- // Nonnull linkonce -> weak
- O << "\t.weak " << *GVarSym << '\n';
- break;
- case GlobalValue::AppendingLinkage:
- // FIXME: appending linkage variables should go into a section of their name
- // or something. For now, just emit them as external.
- case GlobalValue::ExternalLinkage:
- // If external or appending, declare as a global symbol
- O << MAI->getGlobalDirective() << *GVarSym << '\n';
- // Fall Through
- case GlobalValue::PrivateLinkage:
- case GlobalValue::LinkerPrivateLinkage:
- case GlobalValue::InternalLinkage:
- break;
- case GlobalValue::GhostLinkage:
- llvm_unreachable("Should not have any unmaterialized functions!");
- case GlobalValue::DLLImportLinkage:
- llvm_unreachable("DLLImport linkage is not supported by this target!");
- case GlobalValue::DLLExportLinkage:
- llvm_unreachable("DLLExport linkage is not supported by this target!");
- default:
- llvm_unreachable("Unknown linkage type!");
- }
-
- EmitAlignment(Align, GVar);
-
- if (MAI->hasDotTypeDotSizeDirective()) {
- O << "\t.type " << *GVarSym << ",@object\n";
- O << "\t.size " << *GVarSym << ',' << Size << '\n';
- }
-
- O << *GVarSym << ":\n";
- EmitGlobalConstant(C);
-}
-
-
// Force static initialization.
extern "C" void LLVMInitializeMipsAsmPrinter() {
RegisterAsmPrinter<MipsAsmPrinter> X(TheMipsTarget);
bool doInitialization(Module &M);
bool doFinalization(Module &M);
- /// PrintGlobalVariable - Emit the specified global variable and its
+ /// EmitGlobalVariable - Emit the specified global variable and its
/// initializer to the output stream.
- virtual void PrintGlobalVariable(const GlobalVariable *GV) {
+ virtual void EmitGlobalVariable(const GlobalVariable *GV) {
// PIC16 doesn't use normal hooks for this.
}
AU.addRequired<DwarfWriter>();
PPCAsmPrinter::getAnalysisUsage(AU);
}
-
- void PrintGlobalVariable(const GlobalVariable *GVar);
};
/// PPCDarwinAsmPrinter - PowerPC assembly printer, customized for Darwin/Mac
AU.addRequired<DwarfWriter>();
PPCAsmPrinter::getAnalysisUsage(AU);
}
-
- void PrintGlobalVariable(const GlobalVariable *GVar);
};
} // end of anonymous namespace
return false;
}
-void PPCLinuxAsmPrinter::PrintGlobalVariable(const GlobalVariable *GVar) {
- const TargetData *TD = TM.getTargetData();
- MCSymbol *GVarSym = GetGlobalValueSymbol(GVar);
-
- printVisibility(GVarSym, GVar->getVisibility());
-
- Constant *C = GVar->getInitializer();
- const Type *Type = C->getType();
- unsigned Size = TD->getTypeAllocSize(Type);
- unsigned Align = TD->getPreferredAlignmentLog(GVar);
-
- SectionKind GVKind = TargetLoweringObjectFile::getKindForGlobal(GVar, TM);
-
- // Handle normal common symbols.
- if (GVKind.isCommon()) {
- if (Size == 0) Size = 1; // .comm Foo, 0 is undefined, avoid it.
-
- O << ".comm " << *GVarSym << ',' << Size;
- if (MAI->getCOMMDirectiveTakesAlignment())
- O << ',' << Align;
-
- if (VerboseAsm) {
- O << "\t\t" << MAI->getCommentString() << " '";
- WriteAsOperand(O, GVar, /*PrintType=*/false, GVar->getParent());
- O << '\'';
- }
- O << '\n';
- return;
- }
-
- if (GVKind.isBSSLocal()) {
- if (Size == 0) Size = 1; // .comm Foo, 0 is undefined, avoid it.
-
- O << MAI->getLCOMMDirective() << *GVarSym << ',' << Size;
-
- if (VerboseAsm) {
- O << "\t\t" << MAI->getCommentString() << " '";
- WriteAsOperand(O, GVar, /*PrintType=*/false, GVar->getParent());
- O << "'";
- }
- O << '\n';
- return;
- }
-
- OutStreamer.SwitchSection(getObjFileLowering().
- SectionForGlobal(GVar, GVKind, Mang, TM));
-
- switch (GVar->getLinkage()) {
- case GlobalValue::LinkOnceAnyLinkage:
- case GlobalValue::LinkOnceODRLinkage:
- case GlobalValue::WeakAnyLinkage:
- case GlobalValue::WeakODRLinkage:
- case GlobalValue::LinkerPrivateLinkage:
- O << "\t.global " << *GVarSym;
- O << "\n\t.type " << *GVarSym << ", @object\n\t.weak " << *GVarSym << '\n';
- break;
- case GlobalValue::AppendingLinkage:
- // FIXME: appending linkage variables should go into a section of
- // their name or something. For now, just emit them as external.
- case GlobalValue::ExternalLinkage:
- // If external or appending, declare as a global symbol
- O << "\t.global " << *GVarSym;
- O << "\n\t.type " << *GVarSym << ", @object\n";
- // FALL THROUGH
- case GlobalValue::InternalLinkage:
- case GlobalValue::PrivateLinkage:
- break;
- default:
- llvm_unreachable("Unknown linkage type!");
- }
-
- EmitAlignment(Align, GVar);
- O << *GVarSym << ":";
- if (VerboseAsm) {
- O << "\t\t\t\t" << MAI->getCommentString() << " '";
- WriteAsOperand(O, GVar, /*PrintType=*/false, GVar->getParent());
- O << "'";
- }
- O << '\n';
-
- EmitGlobalConstant(C);
- O << '\n';
-}
-
bool PPCLinuxAsmPrinter::doFinalization(Module &M) {
const TargetData *TD = TM.getTargetData();
OutStreamer.SwitchSection(getObjFileLowering().getTextSection());
}
-void PPCDarwinAsmPrinter::PrintGlobalVariable(const GlobalVariable *GVar) {
- const TargetData *TD = TM.getTargetData();
-
- MCSymbol *GVarSym = GetGlobalValueSymbol(GVar);
- printVisibility(GVarSym, GVar->getVisibility());
-
- Constant *C = GVar->getInitializer();
- const Type *Type = C->getType();
- unsigned Size = TD->getTypeAllocSize(Type);
- unsigned Align = TD->getPreferredAlignmentLog(GVar);
-
- SectionKind GVKind = TargetLoweringObjectFile::getKindForGlobal(GVar, TM);
-
- // Handle normal common symbols.
- if (GVKind.isCommon()) {
- if (Size == 0) Size = 1; // .comm Foo, 0 is undefined, avoid it.
-
- O << ".comm " << *GVarSym << ',' << Size;
- if (MAI->getCOMMDirectiveTakesAlignment())
- O << ',' << (MAI->getAlignmentIsInBytes() ? (1 << Align) : Align);
-
- if (VerboseAsm) {
- O << "\t\t" << MAI->getCommentString() << " '";
- WriteAsOperand(O, GVar, /*PrintType=*/false, GVar->getParent());
- O << '\'';
- }
- O << '\n';
- return;
- }
-
- if (GVKind.isBSSLocal()) {
- if (Size == 0) Size = 1; // .comm Foo, 0 is undefined, avoid it.
-
- O << MAI->getLCOMMDirective() << *GVarSym << ',' << Size;
- if (MAI->getLCOMMDirectiveTakesAlignment())
- O << ',' << Align;
-
- if (VerboseAsm) {
- O << "\t\t" << MAI->getCommentString() << " '";
- WriteAsOperand(O, GVar, /*PrintType=*/false, GVar->getParent());
- O << "'";
- }
- O << '\n';
- return;
- }
-
- const MCSection *TheSection =
- getObjFileLowering().SectionForGlobal(GVar, GVKind, Mang, TM);
-
- // Handle the zerofill directive on darwin, which is a special form of BSS
- // emission.
- if (GVKind.isBSSExtern() && MAI->hasMachoZeroFillDirective()) {
- // .globl _foo
- OutStreamer.EmitSymbolAttribute(GVarSym, MCStreamer::Global);
- // .zerofill __DATA, __common, _foo, 400, 5
- OutStreamer.EmitZerofill(TheSection, GVarSym, Size, 1 << Align);
- return;
- }
-
- OutStreamer.SwitchSection(TheSection);
-
- switch (GVar->getLinkage()) {
- case GlobalValue::LinkOnceAnyLinkage:
- case GlobalValue::LinkOnceODRLinkage:
- case GlobalValue::WeakAnyLinkage:
- case GlobalValue::WeakODRLinkage:
- case GlobalValue::CommonLinkage:
- case GlobalValue::LinkerPrivateLinkage:
- O << "\t.globl " << *GVarSym << "\n\t.weak_definition " << *GVarSym << '\n';
- break;
- case GlobalValue::AppendingLinkage:
- // FIXME: appending linkage variables should go into a section of
- // their name or something. For now, just emit them as external.
- case GlobalValue::ExternalLinkage:
- // If external or appending, declare as a global symbol
- O << "\t.globl " << *GVarSym << '\n';
- // FALL THROUGH
- case GlobalValue::InternalLinkage:
- case GlobalValue::PrivateLinkage:
- break;
- default:
- llvm_unreachable("Unknown linkage type!");
- }
-
- EmitAlignment(Align, GVar);
- O << *GVarSym << ":";
- if (VerboseAsm) {
- O << "\t\t\t\t" << MAI->getCommentString() << " '";
- WriteAsOperand(O, GVar, /*PrintType=*/false, GVar->getParent());
- O << "'";
- }
- O << '\n';
-
- EmitGlobalConstant(C);
- O << '\n';
-}
-
bool PPCDarwinAsmPrinter::doFinalization(Module &M) {
const TargetData *TD = TM.getTargetData();
return "Sparc Assembly Printer";
}
- void PrintGlobalVariable(const GlobalVariable *GVar);
void printOperand(const MachineInstr *MI, int opNum);
void printMemOperand(const MachineInstr *MI, int opNum,
const char *Modifier = 0);
O << SPARCCondCodeToString((SPCC::CondCodes)CC);
}
-void SparcAsmPrinter::PrintGlobalVariable(const GlobalVariable* GVar) {
- const TargetData *TD = TM.getTargetData();
-
- if (!GVar->hasInitializer())
- return; // External global require no code
-
- // Check to see if this is a special global used by LLVM, if so, emit it.
- if (EmitSpecialLLVMGlobal(GVar))
- return;
-
- O << "\n\n";
- MCSymbol *GVarSym = GetGlobalValueSymbol(GVar);
- Constant *C = GVar->getInitializer();
- unsigned Size = TD->getTypeAllocSize(C->getType());
- unsigned Align = TD->getPreferredAlignment(GVar);
-
- printVisibility(GVarSym, GVar->getVisibility());
-
- OutStreamer.SwitchSection(getObjFileLowering().SectionForGlobal(GVar, Mang,
- TM));
-
- if (C->isNullValue() && !GVar->hasSection()) {
- if (!GVar->isThreadLocal() &&
- (GVar->hasLocalLinkage() || GVar->isWeakForLinker())) {
- if (Size == 0) Size = 1; // .comm Foo, 0 is undefined, avoid it.
-
- if (GVar->hasLocalLinkage()) {
- O << "\t.local " << *GVarSym << '\n';
- }
-
- O << MAI->getCOMMDirective() << *GVarSym << ',' << Size;
- if (MAI->getCOMMDirectiveTakesAlignment())
- O << ',' << (1 << Align);
-
- O << '\n';
- return;
- }
- }
-
- switch (GVar->getLinkage()) {
- case GlobalValue::CommonLinkage:
- case GlobalValue::LinkOnceAnyLinkage:
- case GlobalValue::LinkOnceODRLinkage:
- case GlobalValue::WeakAnyLinkage: // FIXME: Verify correct for weak.
- case GlobalValue::WeakODRLinkage: // FIXME: Verify correct for weak.
- // Nonnull linkonce -> weak
- O << "\t.weak " << *GVarSym << '\n';
- break;
- case GlobalValue::AppendingLinkage:
- // FIXME: appending linkage variables should go into a section of
- // their name or something. For now, just emit them as external.
- case GlobalValue::ExternalLinkage:
- // If external or appending, declare as a global symbol
- O << MAI->getGlobalDirective() << *GVarSym << '\n';
- // FALL THROUGH
- case GlobalValue::PrivateLinkage:
- case GlobalValue::LinkerPrivateLinkage:
- case GlobalValue::InternalLinkage:
- break;
- case GlobalValue::GhostLinkage:
- llvm_unreachable("Should not have any unmaterialized functions!");
- case GlobalValue::DLLImportLinkage:
- llvm_unreachable("DLLImport linkage is not supported by this target!");
- case GlobalValue::DLLExportLinkage:
- llvm_unreachable("DLLExport linkage is not supported by this target!");
- default:
- llvm_unreachable("Unknown linkage type!");
- }
-
- EmitAlignment(Align, GVar);
-
- if (MAI->hasDotTypeDotSizeDirective()) {
- O << "\t.type " << *GVarSym << ",%object\n";
- O << "\t.size " << *GVarSym << ',' << Size << '\n';
- }
-
- O << *GVarSym << ":\n";
- EmitGlobalConstant(C);
-}
-
/// PrintAsmOperand - Print out an operand for an inline asm expression.
///
bool SparcAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
void emitFunctionHeader(const MachineFunction &MF);
bool runOnMachineFunction(MachineFunction &F);
- void PrintGlobalVariable(const GlobalVariable* GVar);
void getAnalysisUsage(AnalysisUsage &AU) const {
AsmPrinter::getAnalysisUsage(AU);
assert(!Index.getReg() && "Should allocate base register first!");
}
-void SystemZAsmPrinter::PrintGlobalVariable(const GlobalVariable* GVar) {
- const TargetData *TD = TM.getTargetData();
-
- if (!GVar->hasInitializer())
- return; // External global require no code
-
- // Check to see if this is a special global used by LLVM, if so, emit it.
- if (EmitSpecialLLVMGlobal(GVar))
- return;
-
- MCSymbol *GVarSym = GetGlobalValueSymbol(GVar);
- Constant *C = GVar->getInitializer();
- unsigned Size = TD->getTypeAllocSize(C->getType());
- unsigned Align = std::max(1U, TD->getPreferredAlignmentLog(GVar));
-
- printVisibility(GVarSym, GVar->getVisibility());
-
- O << "\t.type\t" << *GVarSym << ",@object\n";
-
- OutStreamer.SwitchSection(getObjFileLowering().SectionForGlobal(GVar, Mang,
- TM));
-
- if (C->isNullValue() && !GVar->hasSection() &&
- !GVar->isThreadLocal() &&
- (GVar->hasLocalLinkage() || GVar->hasCommonLinkage())) {
-
- if (Size == 0) Size = 1; // .comm Foo, 0 is undefined, avoid it.
-
- if (GVar->hasLocalLinkage())
- O << "\t.local\t" << *GVarSym << '\n';
-
- O << MAI->getCOMMDirective() << *GVarSym << ',' << Size;
- if (MAI->getCOMMDirectiveTakesAlignment())
- O << ',' << (MAI->getAlignmentIsInBytes() ? (1 << Align) : Align);
-
- if (VerboseAsm) {
- O << "\t\t" << MAI->getCommentString() << ' ';
- WriteAsOperand(O, GVar, /*PrintType=*/false, GVar->getParent());
- }
- O << '\n';
- return;
- }
-
- switch (GVar->getLinkage()) {
- case GlobalValue::CommonLinkage:
- case GlobalValue::LinkOnceAnyLinkage:
- case GlobalValue::LinkOnceODRLinkage:
- case GlobalValue::WeakAnyLinkage:
- case GlobalValue::WeakODRLinkage:
- O << "\t.weak\t" << *GVarSym << '\n';
- break;
- case GlobalValue::DLLExportLinkage:
- case GlobalValue::AppendingLinkage:
- // FIXME: appending linkage variables should go into a section of
- // their name or something. For now, just emit them as external.
- case GlobalValue::ExternalLinkage:
- // If external or appending, declare as a global symbol
- O << "\t.globl " << *GVarSym << '\n';
- // FALL THROUGH
- case GlobalValue::PrivateLinkage:
- case GlobalValue::LinkerPrivateLinkage:
- case GlobalValue::InternalLinkage:
- break;
- default:
- assert(0 && "Unknown linkage type!");
- }
-
- // Use 16-bit alignment by default to simplify bunch of stuff
- EmitAlignment(Align, GVar, 1);
- O << *GVarSym << ":";
- if (VerboseAsm) {
- O << "\t\t\t\t" << MAI->getCommentString() << ' ';
- WriteAsOperand(O, GVar, /*PrintType=*/false, GVar->getParent());
- }
- O << '\n';
- if (MAI->hasDotTypeDotSizeDirective())
- O << "\t.size\t" << *GVarSym << ", " << Size << '\n';
-
- EmitGlobalConstant(C);
-}
-
// Force static initialization.
extern "C" void LLVMInitializeSystemZAsmPrinter() {
RegisterAsmPrinter<SystemZAsmPrinter> X(TheSystemZTarget);
processDebugLoc(MI, false);
}
-void X86AsmPrinter::PrintGlobalVariable(const GlobalVariable* GVar) {
- MCSymbol *GVarSym = GetGlobalValueSymbol(GVar);
- printVisibility(GVarSym, GVar->getVisibility());
-
- if (MAI->hasDotTypeDotSizeDirective()) {
- O << "\t.type\t" << *GVarSym;
- if (MAI->getCommentString()[0] != '@')
- O << ",@object\n";
- else
- O << ",%object\n";
- }
-
- SectionKind GVKind = TargetLoweringObjectFile::getKindForGlobal(GVar, TM);
-
- const TargetData *TD = TM.getTargetData();
- unsigned Size = TD->getTypeAllocSize(GVar->getType()->getElementType());
- unsigned AlignLog = TD->getPreferredAlignmentLog(GVar);
-
- // Handle normal common symbols.
- if (GVKind.isCommon()) {
- if (Size == 0) Size = 1; // .comm Foo, 0 is undefined, avoid it.
-
- O << MAI->getCOMMDirective() << *GVarSym << ',' << Size;
- if (MAI->getCOMMDirectiveTakesAlignment())
- O << ',' << (MAI->getAlignmentIsInBytes() ? (1 << AlignLog) : AlignLog);
-
- if (VerboseAsm) {
- O << "\t\t" << MAI->getCommentString() << " '";
- WriteAsOperand(O, GVar, /*PrintType=*/false, GVar->getParent());
- O << '\'';
- }
- O << '\n';
- return;
- }
-
- if (GVKind.isBSSLocal()) {
- if (Size == 0) Size = 1; // .comm Foo, 0 is undefined, avoid it.
-
- if (const char *LComm = MAI->getLCOMMDirective()) {
- if (GVar->hasLocalLinkage()) {
- O << LComm << *GVarSym << ',' << Size;
- if (MAI->getLCOMMDirectiveTakesAlignment())
- O << ',' << AlignLog;
- }
- } else {
- O << "\t.local\t" << *GVarSym << '\n';
- O << MAI->getCOMMDirective() << *GVarSym << ',' << Size;
- if (MAI->getCOMMDirectiveTakesAlignment())
- O << ',' << (MAI->getAlignmentIsInBytes() ? (1 << AlignLog) : AlignLog);
- }
- if (VerboseAsm) {
- O.PadToColumn(MAI->getCommentColumn());
- O << MAI->getCommentString() << ' ';
- WriteAsOperand(O, GVar, /*PrintType=*/false, GVar->getParent());
- }
- O << '\n';
- return;
- }
-
- const MCSection *TheSection =
- getObjFileLowering().SectionForGlobal(GVar, GVKind, Mang, TM);
-
- // Handle the zerofill directive on darwin, which is a special form of BSS
- // emission.
- if (GVKind.isBSSExtern() && MAI->hasMachoZeroFillDirective()) {
- // .globl _foo
- OutStreamer.EmitSymbolAttribute(GVarSym, MCStreamer::Global);
- // .zerofill __DATA, __common, _foo, 400, 5
- OutStreamer.EmitZerofill(TheSection, GVarSym, Size, 1 << AlignLog);
- return;
- }
-
- OutStreamer.SwitchSection(TheSection);
-
- switch (GVar->getLinkage()) {
- case GlobalValue::CommonLinkage:
- case GlobalValue::LinkOnceAnyLinkage:
- case GlobalValue::LinkOnceODRLinkage:
- case GlobalValue::WeakAnyLinkage:
- case GlobalValue::WeakODRLinkage:
- case GlobalValue::LinkerPrivateLinkage:
- if (const char *WeakDef = MAI->getWeakDefDirective()) {
- // .globl _foo
- OutStreamer.EmitSymbolAttribute(GVarSym, MCStreamer::Global);
- // .weak_definition _foo
- O << WeakDef << *GVarSym << '\n';
- } else if (const char *LinkOnce = MAI->getLinkOnceDirective()) {
- // .globl _foo
- OutStreamer.EmitSymbolAttribute(GVarSym, MCStreamer::Global);
- // .linkonce same_size
- O << LinkOnce;
- } else
- O << "\t.weak\t" << *GVarSym << '\n';
- break;
- case GlobalValue::DLLExportLinkage:
- case GlobalValue::AppendingLinkage:
- // FIXME: appending linkage variables should go into a section of
- // their name or something. For now, just emit them as external.
- case GlobalValue::ExternalLinkage:
- // If external or appending, declare as a global symbol.
- // .globl _foo
- OutStreamer.EmitSymbolAttribute(GVarSym, MCStreamer::Global);
- break;
- case GlobalValue::PrivateLinkage:
- case GlobalValue::InternalLinkage:
- break;
- default:
- llvm_unreachable("Unknown linkage type!");
- }
-
- EmitAlignment(AlignLog, GVar);
- O << *GVarSym << ":";
- if (VerboseAsm) {
- O.PadToColumn(MAI->getCommentColumn());
- O << MAI->getCommentString() << ' ';
- WriteAsOperand(O, GVar, /*PrintType=*/false, GVar->getParent());
- }
- O << '\n';
-
- EmitGlobalConstant(GVar->getInitializer());
-
- if (MAI->hasDotTypeDotSizeDirective())
- O << "\t.size\t" << *GVarSym << ", " << Size << '\n';
-}
-
void X86AsmPrinter::EmitEndOfAsmFile(Module &M) {
if (Subtarget->isTargetDarwin()) {
// All darwin targets use mach-o.
unsigned uid) const;
void printPICLabel(const MachineInstr *MI, unsigned Op);
- void PrintGlobalVariable(const GlobalVariable* GVar);
void PrintPICBaseSymbol() const;
void emitGlobalDirective(const MCSymbol *Sym);
void emitArrayBound(const MCSymbol *Sym, const GlobalVariable *GV);
- virtual void PrintGlobalVariable(const GlobalVariable *GV);
+ virtual void EmitGlobalVariable(const GlobalVariable *GV);
void emitFunctionStart(MachineFunction &MF);
void emitFunctionEnd(MachineFunction &MF);
}
}
-void XCoreAsmPrinter::PrintGlobalVariable(const GlobalVariable *GV) {
+void XCoreAsmPrinter::EmitGlobalVariable(const GlobalVariable *GV) {
// Check to see if this is a special global used by LLVM, if so, emit it.
if (!GV->hasInitializer() ||
EmitSpecialLLVMGlobal(GV))
@A = global i32 0
; CHECK: .section .bss,"aw",@nobits
-; CHECK: .global A
+; CHECK: .globl A