diff options
author | Chris Lattner <sabre@nondot.org> | 2005-12-13 06:32:10 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2005-12-13 06:32:10 +0000 |
commit | ed13893ff729bc3b91697f6d80a3ba303782efcc (patch) | |
tree | 71a4ab9b1de6e889a1edf38b9221fe63f8019896 /lib/CodeGen | |
parent | a046e0d79f9f4011b6ebcb02e3b038a9601bf7fc (diff) |
Add a couple more fields, move ctor init list to .cpp file, add support
for emitting the ctor/dtor list for common targets.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@24694 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen')
-rw-r--r-- | lib/CodeGen/AsmPrinter.cpp | 70 |
1 files changed, 70 insertions, 0 deletions
diff --git a/lib/CodeGen/AsmPrinter.cpp b/lib/CodeGen/AsmPrinter.cpp index dd100c6e19..0539d46325 100644 --- a/lib/CodeGen/AsmPrinter.cpp +++ b/lib/CodeGen/AsmPrinter.cpp @@ -21,6 +21,35 @@ #include "llvm/Target/TargetMachine.h" using namespace llvm; +AsmPrinter::AsmPrinter(std::ostream &o, TargetMachine &tm) +: FunctionNumber(0), O(o), TM(tm), + CommentString("#"), + GlobalPrefix(""), + PrivateGlobalPrefix("."), + GlobalVarAddrPrefix(""), + GlobalVarAddrSuffix(""), + FunctionAddrPrefix(""), + FunctionAddrSuffix(""), + ZeroDirective("\t.zero\t"), + AsciiDirective("\t.ascii\t"), + AscizDirective("\t.asciz\t"), + Data8bitsDirective("\t.byte\t"), + Data16bitsDirective("\t.short\t"), + Data32bitsDirective("\t.long\t"), + Data64bitsDirective("\t.quad\t"), + AlignDirective("\t.align\t"), + AlignmentIsInBytes(true), + SwitchToSectionDirective("\t.section\t"), + ConstantPoolSection("\t.section .rodata\n"), + StaticCtorsSection("\t.section .ctors,\"aw\",@progbits"), + StaticDtorsSection("\t.section .dtors,\"aw\",@progbits"), + LCOMMDirective(0), + COMMDirective("\t.comm\t"), + COMMDirectiveTakesAlignment(true), + HasDotTypeDotSizeDirective(true) { +} + + /// SwitchSection - Switch to the specified section of the executable if we /// are not already in it! /// @@ -80,6 +109,47 @@ void AsmPrinter::EmitConstantPool(MachineConstantPool *MCP) { } } +/// EmitSpecialLLVMGlobal - Check to see if the specified global is a +/// special global used by LLVM. If so, emit it and return true, otherwise +/// do nothing and return false. +bool AsmPrinter::EmitSpecialLLVMGlobal(const GlobalVariable *GV) { + assert(GV->hasInitializer() && GV->hasAppendingLinkage() && + "Not a special LLVM global!"); + + if (GV->getName() == "llvm.used") + return true; // No need to emit this at all. + + if (GV->getName() == "llvm.global_ctors") { + SwitchSection(StaticCtorsSection, 0); + EmitAlignment(2, 0); + EmitXXStructorList(GV->getInitializer()); + return true; + } + + if (GV->getName() == "llvm.global_dtors") { + SwitchSection(StaticDtorsSection, 0); + EmitAlignment(2, 0); + EmitXXStructorList(GV->getInitializer()); + return true; + } + + return false; +} + +/// EmitXXStructorList - Emit the ctor or dtor list. This just prints out the +/// function pointers, ignoring the init priority. +void AsmPrinter::EmitXXStructorList(Constant *List) { + // Should be an array of '{ int, void ()* }' structs. The first value is the + // init priority, which we ignore. + if (!isa<ConstantArray>(List)) return; + ConstantArray *InitList = cast<ConstantArray>(List); + for (unsigned i = 0, e = InitList->getNumOperands(); i != e; ++i) + if (ConstantStruct *CS = dyn_cast<ConstantStruct>(InitList->getOperand(i))){ + if (CS->getNumOperands() != 2) return; // Not array of 2-element structs. + // Emit the function pointer. + EmitGlobalConstant(CS->getOperand(1)); + } +} // EmitAlignment - Emit an alignment directive to the specified power of two. |