From 70f717f0b769eccda6bc0832320e8e2cb7564b07 Mon Sep 17 00:00:00 2001 From: Anton Korobeynikov Date: Thu, 16 Jul 2009 14:04:22 +0000 Subject: [PATCH] Preliminary asmprinting of globals git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@75975 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../SystemZ/AsmPrinter/SystemZAsmPrinter.cpp | 121 +++++++++++++++++- lib/Target/SystemZ/SystemZInstrInfo.td | 1 + lib/Target/SystemZ/SystemZTargetAsmInfo.cpp | 10 +- lib/Target/SystemZ/SystemZTargetMachine.cpp | 2 +- 4 files changed, 131 insertions(+), 3 deletions(-) diff --git a/lib/Target/SystemZ/AsmPrinter/SystemZAsmPrinter.cpp b/lib/Target/SystemZ/AsmPrinter/SystemZAsmPrinter.cpp index f98d4ed7156..d08727724c0 100644 --- a/lib/Target/SystemZ/AsmPrinter/SystemZAsmPrinter.cpp +++ b/lib/Target/SystemZ/AsmPrinter/SystemZAsmPrinter.cpp @@ -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); +} diff --git a/lib/Target/SystemZ/SystemZInstrInfo.td b/lib/Target/SystemZ/SystemZInstrInfo.td index 6055b00eaa3..740ac42124e 100644 --- a/lib/Target/SystemZ/SystemZInstrInfo.td +++ b/lib/Target/SystemZ/SystemZInstrInfo.td @@ -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)]>; diff --git a/lib/Target/SystemZ/SystemZTargetAsmInfo.cpp b/lib/Target/SystemZ/SystemZTargetAsmInfo.cpp index c841a0e4930..25048b81bc4 100644 --- a/lib/Target/SystemZ/SystemZTargetAsmInfo.cpp +++ b/lib/Target/SystemZ/SystemZTargetAsmInfo.cpp @@ -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"; } diff --git a/lib/Target/SystemZ/SystemZTargetMachine.cpp b/lib/Target/SystemZ/SystemZTargetMachine.cpp index 81609534549..e8aa6b573b3 100644 --- a/lib/Target/SystemZ/SystemZTargetMachine.cpp +++ b/lib/Target/SystemZ/SystemZTargetMachine.cpp @@ -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) { }