Preliminary asmprinting of globals

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@75975 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Anton Korobeynikov 2009-07-16 14:04:22 +00:00
parent ed00212f43
commit 70f717f0b7
4 changed files with 131 additions and 3 deletions

View File

@ -68,6 +68,7 @@ namespace {
bool runOnMachineFunction(MachineFunction &F);
bool doInitialization(Module &M);
bool doFinalization(Module &M);
void printModuleLevelGV(const GlobalVariable* GVar);
void getAnalysisUsage(AnalysisUsage &AU) const {
AsmPrinter::getAnalysisUsage(AU);
@ -97,6 +98,31 @@ bool SystemZAsmPrinter::doInitialization(Module &M) {
bool SystemZAsmPrinter::doFinalization(Module &M) {
// Print out module-level global variables here.
for (Module::const_global_iterator I = M.global_begin(), E = M.global_end();
I != E; ++I) {
printModuleLevelGV(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);
}
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);
}
return AsmPrinter::doFinalization(M);
}
@ -204,11 +230,16 @@ void SystemZAsmPrinter::printOperand(const MachineInstr *MI, int OpNum,
printBasicBlockLabel(MO.getMBB());
return;
case MachineOperand::MO_GlobalAddress: {
std::string Name = Mang->getValueName(MO.getGlobal());
const GlobalValue *GV = MO.getGlobal();
std::string Name = Mang->getValueName(GV);
assert(MO.getOffset() == 0 && "No offsets allowed!");
O << Name;
if (GV->hasExternalWeakLinkage())
ExtWeakSymbols.insert(GV);
return;
}
case MachineOperand::MO_ExternalSymbol: {
@ -258,3 +289,91 @@ void SystemZAsmPrinter::printRRIAddrOperand(const MachineInstr *MI, int OpNum,
assert(!Index.getReg() && "Should allocate base register first!");
}
/// 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;
}
void SystemZAsmPrinter::printModuleLevelGV(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;
std::string name = Mang->getValueName(GVar);
Constant *C = GVar->getInitializer();
const Type *Type = C->getType();
unsigned Size = TD->getTypeAllocSize(Type);
unsigned Align = std::max(1U, TD->getPreferredAlignmentLog(GVar));
printVisibility(name, GVar->getVisibility());
O << "\t.type\t" << name << ",@object\n";
SwitchToSection(TAI->SectionForGlobal(GVar));
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" << name << '\n';
O << TAI->getCOMMDirective() << name << ',' << Size;
if (TAI->getCOMMDirectiveTakesAlignment())
O << ',' << (TAI->getAlignmentIsInBytes() ? (1 << Align) : Align);
if (VerboseAsm) {
O << "\t\t" << TAI->getCommentString() << ' ';
PrintUnmangledNameSafely(GVar, O);
}
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" << name << '\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 " << name << '\n';
// FALL THROUGH
case GlobalValue::PrivateLinkage:
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 << name << ":";
if (VerboseAsm) {
O << "\t\t\t\t" << TAI->getCommentString() << ' ';
PrintUnmangledNameSafely(GVar, O);
}
O << '\n';
if (TAI->hasDotTypeDotSizeDirective())
O << "\t.size\t" << name << ", " << Size << '\n';
EmitGlobalConstant(C);
}

View File

@ -343,6 +343,7 @@ let isCall = 1 in
let isReMaterializable = 1 in
// FIXME: Provide imm12 variant
// FIXME: Address should be halfword aligned...
def LA64r : Pseudo<(outs GR64:$dst), (ins laaddr:$src),
"lay\t{$dst, $src}",
[(set GR64:$dst, laaddr:$src)]>;

View File

@ -18,5 +18,13 @@ using namespace llvm;
SystemZTargetAsmInfo::SystemZTargetAsmInfo(const SystemZTargetMachine &TM)
: ELFTargetAsmInfo(TM) {
AlignmentIsInBytes = false;
AlignmentIsInBytes = true;
CStringSection = ".rodata.str";
PrivateGlobalPrefix = ".L";
WeakRefDirective = "\t.weak\t";
SetDirective = "\t.set\t";
PCSymbol = ".";
NonexecutableStackDirective = "\t.section\t.note.GNU-stack,\"\",@progbits";
}

View File

@ -39,7 +39,7 @@ const TargetAsmInfo *SystemZTargetMachine::createTargetAsmInfo() const {
///
SystemZTargetMachine::SystemZTargetMachine(const Module &M, const std::string &FS)
: Subtarget(*this, M, FS),
DataLayout("E-p:64:64:64-i1:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-f128:128:128"),
DataLayout("E-p:64:64:64-i8:8:16-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-f128:128:128-a0:16:16"),
InstrInfo(*this), TLInfo(*this),
FrameInfo(TargetFrameInfo::StackGrowsDown, 8, -160) {
}