mirror of
https://github.com/RPCSX/llvm.git
synced 2024-12-10 13:15:47 +00:00
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
This commit is contained in:
parent
a046e0d79f
commit
ed13893ff7
@ -22,6 +22,7 @@
|
||||
namespace llvm {
|
||||
class Constant;
|
||||
class Mangler;
|
||||
class GlobalVariable;
|
||||
|
||||
class AsmPrinter : public MachineFunctionPass {
|
||||
/// CurrentSection - The current section we are emitting to. This is
|
||||
@ -134,6 +135,16 @@ namespace llvm {
|
||||
/// before emitting the constant pool for a function.
|
||||
const char *ConstantPoolSection; // Defaults to "\t.section .rodata\n"
|
||||
|
||||
/// StaticCtorsSection - This is the directive that is emitted to switch to
|
||||
/// a section to emit the static constructor list.
|
||||
/// Defaults to "\t.section .ctors,\"aw\",@progbits".
|
||||
const char *StaticCtorsSection;
|
||||
|
||||
/// StaticDtorsSection - This is the directive that is emitted to switch to
|
||||
/// a section to emit the static destructor list.
|
||||
/// Defaults to "\t.section .dtors,\"aw\",@progbits".
|
||||
const char *StaticDtorsSection;
|
||||
|
||||
//===--- Global Variable Emission Directives --------------------------===//
|
||||
|
||||
/// LCOMMDirective - This is the name of a directive (if supported) that can
|
||||
@ -152,31 +163,7 @@ namespace llvm {
|
||||
/// directives, this is true for most ELF targets.
|
||||
bool HasDotTypeDotSizeDirective; // Defaults to true.
|
||||
|
||||
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"),
|
||||
LCOMMDirective(0),
|
||||
COMMDirective("\t.comm\t"),
|
||||
COMMDirectiveTakesAlignment(true),
|
||||
HasDotTypeDotSizeDirective(true) {
|
||||
}
|
||||
AsmPrinter(std::ostream &o, TargetMachine &TM);
|
||||
|
||||
/// SwitchSection - Switch to the specified section of the executable if we
|
||||
/// are not already in it! If GV is non-null and if the global has an
|
||||
@ -210,8 +197,18 @@ namespace llvm {
|
||||
/// is being processed from runOnMachineFunction.
|
||||
void SetupMachineFunction(MachineFunction &MF);
|
||||
|
||||
/// EmitConstantPool - Print to the current output stream assembly
|
||||
/// representations of the constants in the constant pool MCP. This is
|
||||
/// used to print out constants which have been "spilled to memory" by
|
||||
/// the code generator.
|
||||
///
|
||||
void 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 EmitSpecialLLVMGlobal(const GlobalVariable *GV);
|
||||
|
||||
/// EmitAlignment - Emit an alignment directive to the specified power of
|
||||
/// two boundary. For example, if you pass in 3 here, you will get an 8
|
||||
/// byte alignment. If a global value is specified, and if that global has
|
||||
@ -229,6 +226,9 @@ namespace llvm {
|
||||
/// EmitGlobalConstant - Print a general LLVM constant to the .s file.
|
||||
///
|
||||
void EmitGlobalConstant(const Constant* CV);
|
||||
|
||||
private:
|
||||
void EmitXXStructorList(Constant *List);
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -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.
|
||||
|
Loading…
Reference in New Issue
Block a user