From: Anton Korobeynikov Date: Tue, 11 Nov 2008 16:42:57 +0000 (+0000) Subject: Separate sparc asmprinter. This should unbreak the native build X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=3bd86aac994d5d68797c98b53b3ef892df1e99f6;p=oota-llvm.git Separate sparc asmprinter. This should unbreak the native build git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@59047 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Target/Sparc/AsmPrinter/CMakeLists.txt b/lib/Target/Sparc/AsmPrinter/CMakeLists.txt new file mode 100644 index 00000000000..394b4cd40e7 --- /dev/null +++ b/lib/Target/Sparc/AsmPrinter/CMakeLists.txt @@ -0,0 +1,9 @@ +include_directories( ${CMAKE_CURRENT_BINARY_DIR}/.. ${CMAKE_CURRENT_SOURCE_DIR}/.. ) + +add_partially_linked_object(LLVMSparcAsmPrinter + SparcAsmPrinter.cpp + ) + +target_name_of_partially_linked_object(LLVMSparcCodeGen n) + +add_dependencies(LLVMSparcAsmPrinter ${n}) diff --git a/lib/Target/Sparc/AsmPrinter/Makefile b/lib/Target/Sparc/AsmPrinter/Makefile new file mode 100644 index 00000000000..e71527d0243 --- /dev/null +++ b/lib/Target/Sparc/AsmPrinter/Makefile @@ -0,0 +1,15 @@ +##===- lib/Target/Sparc/Makefile ---------------------------*- Makefile -*-===## +# +# The LLVM Compiler Infrastructure +# +# This file is distributed under the University of Illinois Open Source +# License. See LICENSE.TXT for details. +# +##===----------------------------------------------------------------------===## +LEVEL = ../../../.. +LIBRARYNAME = LLVMSparcAsmPrinter + +# Hack: we need to include 'main' Sparc target directory to grab private headers +CPPFLAGS = -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/.. + +include $(LEVEL)/Makefile.common diff --git a/lib/Target/Sparc/AsmPrinter/SparcAsmPrinter.cpp b/lib/Target/Sparc/AsmPrinter/SparcAsmPrinter.cpp new file mode 100644 index 00000000000..703a54eacd5 --- /dev/null +++ b/lib/Target/Sparc/AsmPrinter/SparcAsmPrinter.cpp @@ -0,0 +1,345 @@ +//===-- SparcAsmPrinter.cpp - Sparc LLVM assembly writer ------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file contains a printer that converts from our internal representation +// of machine-dependent LLVM code to GAS-format SPARC assembly language. +// +//===----------------------------------------------------------------------===// + +#define DEBUG_TYPE "asm-printer" +#include "Sparc.h" +#include "SparcInstrInfo.h" +#include "llvm/Constants.h" +#include "llvm/DerivedTypes.h" +#include "llvm/Module.h" +#include "llvm/CodeGen/AsmPrinter.h" +#include "llvm/CodeGen/MachineFunctionPass.h" +#include "llvm/CodeGen/MachineConstantPool.h" +#include "llvm/CodeGen/MachineInstr.h" +#include "llvm/Target/TargetAsmInfo.h" +#include "llvm/Target/TargetData.h" +#include "llvm/Target/TargetMachine.h" +#include "llvm/Support/Mangler.h" +#include "llvm/Support/raw_ostream.h" +#include "llvm/ADT/Statistic.h" +#include "llvm/ADT/StringExtras.h" +#include "llvm/Support/CommandLine.h" +#include "llvm/Support/MathExtras.h" +#include +#include +#include +using namespace llvm; + +STATISTIC(EmittedInsts, "Number of machine instrs printed"); + +namespace { + struct VISIBILITY_HIDDEN SparcAsmPrinter : public AsmPrinter { + SparcAsmPrinter(raw_ostream &O, TargetMachine &TM, const TargetAsmInfo *T) + : AsmPrinter(O, TM, T) { + } + + /// We name each basic block in a Function with a unique number, so + /// that we can consistently refer to them later. This is cleared + /// at the beginning of each call to runOnMachineFunction(). + /// + typedef std::map ValueMapTy; + ValueMapTy NumberForBB; + + virtual const char *getPassName() const { + return "Sparc Assembly Printer"; + } + + void printModuleLevelGV(const GlobalVariable* GVar); + void printOperand(const MachineInstr *MI, int opNum); + void printMemOperand(const MachineInstr *MI, int opNum, + const char *Modifier = 0); + void printCCOperand(const MachineInstr *MI, int opNum); + + bool printInstruction(const MachineInstr *MI); // autogenerated. + bool runOnMachineFunction(MachineFunction &F); + bool doInitialization(Module &M); + bool doFinalization(Module &M); + bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, + unsigned AsmVariant, const char *ExtraCode); + bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo, + unsigned AsmVariant, const char *ExtraCode); + }; +} // end of anonymous namespace + +#include "SparcGenAsmWriter.inc" + +/// createSparcCodePrinterPass - Returns a pass that prints the SPARC +/// assembly code for a MachineFunction to the given output stream, +/// using the given target machine description. This should work +/// regardless of whether the function is in SSA form. +/// +FunctionPass *llvm::createSparcCodePrinterPass(raw_ostream &o, + TargetMachine &tm) { + return new SparcAsmPrinter(o, tm, tm.getTargetAsmInfo()); +} + +/// runOnMachineFunction - This uses the printInstruction() +/// method to print assembly for each instruction. +/// +bool SparcAsmPrinter::runOnMachineFunction(MachineFunction &MF) { + SetupMachineFunction(MF); + + // Print out constants referenced by the function + EmitConstantPool(MF.getConstantPool()); + + // BBNumber is used here so that a given Printer will never give two + // BBs the same name. (If you have a better way, please let me know!) + static unsigned BBNumber = 0; + + O << "\n\n"; + // What's my mangled name? + CurrentFnName = Mang->getValueName(MF.getFunction()); + + // Print out the label for the function. + const Function *F = MF.getFunction(); + SwitchToSection(TAI->SectionForGlobal(F)); + EmitAlignment(4, F); + O << "\t.globl\t" << CurrentFnName << '\n'; + + printVisibility(CurrentFnName, F->getVisibility()); + + O << "\t.type\t" << CurrentFnName << ", #function\n"; + O << CurrentFnName << ":\n"; + + // Number each basic block so that we can consistently refer to them + // in PC-relative references. + // FIXME: Why not use the MBB numbers? + NumberForBB.clear(); + for (MachineFunction::const_iterator I = MF.begin(), E = MF.end(); + I != E; ++I) { + NumberForBB[I->getBasicBlock()] = BBNumber++; + } + + // Print out code for the function. + for (MachineFunction::const_iterator I = MF.begin(), E = MF.end(); + I != E; ++I) { + // Print a label for the basic block. + if (I != MF.begin()) { + printBasicBlockLabel(I, true, true); + O << '\n'; + } + for (MachineBasicBlock::const_iterator II = I->begin(), E = I->end(); + II != E; ++II) { + // Print the assembly for the instruction. + printInstruction(II); + ++EmittedInsts; + } + } + + // We didn't modify anything. + return false; +} + +void SparcAsmPrinter::printOperand(const MachineInstr *MI, int opNum) { + const MachineOperand &MO = MI->getOperand (opNum); + const TargetRegisterInfo &RI = *TM.getRegisterInfo(); + bool CloseParen = false; + if (MI->getOpcode() == SP::SETHIi && !MO.isReg() && !MO.isImm()) { + O << "%hi("; + CloseParen = true; + } else if ((MI->getOpcode() == SP::ORri || MI->getOpcode() == SP::ADDri) && + !MO.isReg() && !MO.isImm()) { + O << "%lo("; + CloseParen = true; + } + switch (MO.getType()) { + case MachineOperand::MO_Register: + if (TargetRegisterInfo::isPhysicalRegister(MO.getReg())) + O << "%" << LowercaseString (RI.get(MO.getReg()).AsmName); + else + O << "%reg" << MO.getReg(); + break; + + case MachineOperand::MO_Immediate: + O << (int)MO.getImm(); + break; + case MachineOperand::MO_MachineBasicBlock: + printBasicBlockLabel(MO.getMBB()); + return; + case MachineOperand::MO_GlobalAddress: + O << Mang->getValueName(MO.getGlobal()); + break; + case MachineOperand::MO_ExternalSymbol: + O << MO.getSymbolName(); + break; + case MachineOperand::MO_ConstantPoolIndex: + O << TAI->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber() << "_" + << MO.getIndex(); + break; + default: + O << ""; abort (); break; + } + if (CloseParen) O << ")"; +} + +void SparcAsmPrinter::printMemOperand(const MachineInstr *MI, int opNum, + const char *Modifier) { + printOperand(MI, opNum); + + // If this is an ADD operand, emit it like normal operands. + if (Modifier && !strcmp(Modifier, "arith")) { + O << ", "; + printOperand(MI, opNum+1); + return; + } + + if (MI->getOperand(opNum+1).isReg() && + MI->getOperand(opNum+1).getReg() == SP::G0) + return; // don't print "+%g0" + if (MI->getOperand(opNum+1).isImm() && + MI->getOperand(opNum+1).getImm() == 0) + return; // don't print "+0" + + O << "+"; + if (MI->getOperand(opNum+1).isGlobal() || + MI->getOperand(opNum+1).isCPI()) { + O << "%lo("; + printOperand(MI, opNum+1); + O << ")"; + } else { + printOperand(MI, opNum+1); + } +} + +void SparcAsmPrinter::printCCOperand(const MachineInstr *MI, int opNum) { + int CC = (int)MI->getOperand(opNum).getImm(); + O << SPARCCondCodeToString((SPCC::CondCodes)CC); +} + +bool SparcAsmPrinter::doInitialization(Module &M) { + Mang = new Mangler(M); + return false; // success +} + +bool SparcAsmPrinter::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); + + O << '\n'; + + return AsmPrinter::doFinalization(M); +} + +void SparcAsmPrinter::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; + + O << "\n\n"; + std::string name = Mang->getValueName(GVar); + Constant *C = GVar->getInitializer(); + unsigned Size = TD->getABITypeSize(C->getType()); + unsigned Align = TD->getPreferredAlignment(GVar); + + printVisibility(name, GVar->getVisibility()); + + SwitchToSection(TAI->SectionForGlobal(GVar)); + + if (C->isNullValue() && !GVar->hasSection()) { + if (!GVar->isThreadLocal() && + (GVar->hasInternalLinkage() || GVar->mayBeOverridden())) { + if (Size == 0) Size = 1; // .comm Foo, 0 is undefined, avoid it. + + if (GVar->hasInternalLinkage()) + O << "\t.local " << name << '\n'; + + O << TAI->getCOMMDirective() << name << ',' << Size; + if (TAI->getCOMMDirectiveTakesAlignment()) + O << ',' << (1 << Align); + + O << '\n'; + return; + } + } + + switch (GVar->getLinkage()) { + case GlobalValue::CommonLinkage: + case GlobalValue::LinkOnceLinkage: + case GlobalValue::WeakLinkage: // FIXME: Verify correct for weak. + // Nonnull linkonce -> weak + O << "\t.weak " << name << '\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 << TAI->getGlobalDirective() << name << '\n'; + // FALL THROUGH + case GlobalValue::InternalLinkage: + break; + case GlobalValue::GhostLinkage: + cerr << "Should not have any unmaterialized functions!\n"; + abort(); + case GlobalValue::DLLImportLinkage: + cerr << "DLLImport linkage is not supported by this target!\n"; + abort(); + case GlobalValue::DLLExportLinkage: + cerr << "DLLExport linkage is not supported by this target!\n"; + abort(); + default: + assert(0 && "Unknown linkage type!"); + } + + EmitAlignment(Align, GVar); + + if (TAI->hasDotTypeDotSizeDirective()) { + O << "\t.type " << name << ",#object\n"; + O << "\t.size " << name << ',' << Size << '\n'; + } + + O << name << ":\n"; + EmitGlobalConstant(C); +} + +/// PrintAsmOperand - Print out an operand for an inline asm expression. +/// +bool SparcAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, + unsigned AsmVariant, + const char *ExtraCode) { + if (ExtraCode && ExtraCode[0]) { + if (ExtraCode[1] != 0) return true; // Unknown modifier. + + switch (ExtraCode[0]) { + default: return true; // Unknown modifier. + case 'r': + break; + } + } + + printOperand(MI, OpNo); + + return false; +} + +bool SparcAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, + unsigned OpNo, + unsigned AsmVariant, + const char *ExtraCode) { + if (ExtraCode && ExtraCode[0]) + return true; // Unknown modifier + + O << '['; + printMemOperand(MI, OpNo); + O << ']'; + + return false; +} diff --git a/lib/Target/Sparc/Makefile b/lib/Target/Sparc/Makefile index 69a4cf2e8a9..876eb40b8a8 100644 --- a/lib/Target/Sparc/Makefile +++ b/lib/Target/Sparc/Makefile @@ -7,7 +7,7 @@ # ##===----------------------------------------------------------------------===## LEVEL = ../../.. -LIBRARYNAME = LLVMSparc +LIBRARYNAME = LLVMSparcCodeGen TARGET = Sparc # Make sure that tblgen is run, first thing. @@ -16,5 +16,7 @@ BUILT_SOURCES = SparcGenRegisterInfo.h.inc SparcGenRegisterNames.inc \ SparcGenInstrInfo.inc SparcGenAsmWriter.inc \ SparcGenDAGISel.inc SparcGenSubtarget.inc SparcGenCallingConv.inc +DIRS = AsmPrinter + include $(LEVEL)/Makefile.common diff --git a/lib/Target/Sparc/SparcAsmPrinter.cpp b/lib/Target/Sparc/SparcAsmPrinter.cpp deleted file mode 100644 index 703a54eacd5..00000000000 --- a/lib/Target/Sparc/SparcAsmPrinter.cpp +++ /dev/null @@ -1,345 +0,0 @@ -//===-- SparcAsmPrinter.cpp - Sparc LLVM assembly writer ------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file contains a printer that converts from our internal representation -// of machine-dependent LLVM code to GAS-format SPARC assembly language. -// -//===----------------------------------------------------------------------===// - -#define DEBUG_TYPE "asm-printer" -#include "Sparc.h" -#include "SparcInstrInfo.h" -#include "llvm/Constants.h" -#include "llvm/DerivedTypes.h" -#include "llvm/Module.h" -#include "llvm/CodeGen/AsmPrinter.h" -#include "llvm/CodeGen/MachineFunctionPass.h" -#include "llvm/CodeGen/MachineConstantPool.h" -#include "llvm/CodeGen/MachineInstr.h" -#include "llvm/Target/TargetAsmInfo.h" -#include "llvm/Target/TargetData.h" -#include "llvm/Target/TargetMachine.h" -#include "llvm/Support/Mangler.h" -#include "llvm/Support/raw_ostream.h" -#include "llvm/ADT/Statistic.h" -#include "llvm/ADT/StringExtras.h" -#include "llvm/Support/CommandLine.h" -#include "llvm/Support/MathExtras.h" -#include -#include -#include -using namespace llvm; - -STATISTIC(EmittedInsts, "Number of machine instrs printed"); - -namespace { - struct VISIBILITY_HIDDEN SparcAsmPrinter : public AsmPrinter { - SparcAsmPrinter(raw_ostream &O, TargetMachine &TM, const TargetAsmInfo *T) - : AsmPrinter(O, TM, T) { - } - - /// We name each basic block in a Function with a unique number, so - /// that we can consistently refer to them later. This is cleared - /// at the beginning of each call to runOnMachineFunction(). - /// - typedef std::map ValueMapTy; - ValueMapTy NumberForBB; - - virtual const char *getPassName() const { - return "Sparc Assembly Printer"; - } - - void printModuleLevelGV(const GlobalVariable* GVar); - void printOperand(const MachineInstr *MI, int opNum); - void printMemOperand(const MachineInstr *MI, int opNum, - const char *Modifier = 0); - void printCCOperand(const MachineInstr *MI, int opNum); - - bool printInstruction(const MachineInstr *MI); // autogenerated. - bool runOnMachineFunction(MachineFunction &F); - bool doInitialization(Module &M); - bool doFinalization(Module &M); - bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, - unsigned AsmVariant, const char *ExtraCode); - bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo, - unsigned AsmVariant, const char *ExtraCode); - }; -} // end of anonymous namespace - -#include "SparcGenAsmWriter.inc" - -/// createSparcCodePrinterPass - Returns a pass that prints the SPARC -/// assembly code for a MachineFunction to the given output stream, -/// using the given target machine description. This should work -/// regardless of whether the function is in SSA form. -/// -FunctionPass *llvm::createSparcCodePrinterPass(raw_ostream &o, - TargetMachine &tm) { - return new SparcAsmPrinter(o, tm, tm.getTargetAsmInfo()); -} - -/// runOnMachineFunction - This uses the printInstruction() -/// method to print assembly for each instruction. -/// -bool SparcAsmPrinter::runOnMachineFunction(MachineFunction &MF) { - SetupMachineFunction(MF); - - // Print out constants referenced by the function - EmitConstantPool(MF.getConstantPool()); - - // BBNumber is used here so that a given Printer will never give two - // BBs the same name. (If you have a better way, please let me know!) - static unsigned BBNumber = 0; - - O << "\n\n"; - // What's my mangled name? - CurrentFnName = Mang->getValueName(MF.getFunction()); - - // Print out the label for the function. - const Function *F = MF.getFunction(); - SwitchToSection(TAI->SectionForGlobal(F)); - EmitAlignment(4, F); - O << "\t.globl\t" << CurrentFnName << '\n'; - - printVisibility(CurrentFnName, F->getVisibility()); - - O << "\t.type\t" << CurrentFnName << ", #function\n"; - O << CurrentFnName << ":\n"; - - // Number each basic block so that we can consistently refer to them - // in PC-relative references. - // FIXME: Why not use the MBB numbers? - NumberForBB.clear(); - for (MachineFunction::const_iterator I = MF.begin(), E = MF.end(); - I != E; ++I) { - NumberForBB[I->getBasicBlock()] = BBNumber++; - } - - // Print out code for the function. - for (MachineFunction::const_iterator I = MF.begin(), E = MF.end(); - I != E; ++I) { - // Print a label for the basic block. - if (I != MF.begin()) { - printBasicBlockLabel(I, true, true); - O << '\n'; - } - for (MachineBasicBlock::const_iterator II = I->begin(), E = I->end(); - II != E; ++II) { - // Print the assembly for the instruction. - printInstruction(II); - ++EmittedInsts; - } - } - - // We didn't modify anything. - return false; -} - -void SparcAsmPrinter::printOperand(const MachineInstr *MI, int opNum) { - const MachineOperand &MO = MI->getOperand (opNum); - const TargetRegisterInfo &RI = *TM.getRegisterInfo(); - bool CloseParen = false; - if (MI->getOpcode() == SP::SETHIi && !MO.isReg() && !MO.isImm()) { - O << "%hi("; - CloseParen = true; - } else if ((MI->getOpcode() == SP::ORri || MI->getOpcode() == SP::ADDri) && - !MO.isReg() && !MO.isImm()) { - O << "%lo("; - CloseParen = true; - } - switch (MO.getType()) { - case MachineOperand::MO_Register: - if (TargetRegisterInfo::isPhysicalRegister(MO.getReg())) - O << "%" << LowercaseString (RI.get(MO.getReg()).AsmName); - else - O << "%reg" << MO.getReg(); - break; - - case MachineOperand::MO_Immediate: - O << (int)MO.getImm(); - break; - case MachineOperand::MO_MachineBasicBlock: - printBasicBlockLabel(MO.getMBB()); - return; - case MachineOperand::MO_GlobalAddress: - O << Mang->getValueName(MO.getGlobal()); - break; - case MachineOperand::MO_ExternalSymbol: - O << MO.getSymbolName(); - break; - case MachineOperand::MO_ConstantPoolIndex: - O << TAI->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber() << "_" - << MO.getIndex(); - break; - default: - O << ""; abort (); break; - } - if (CloseParen) O << ")"; -} - -void SparcAsmPrinter::printMemOperand(const MachineInstr *MI, int opNum, - const char *Modifier) { - printOperand(MI, opNum); - - // If this is an ADD operand, emit it like normal operands. - if (Modifier && !strcmp(Modifier, "arith")) { - O << ", "; - printOperand(MI, opNum+1); - return; - } - - if (MI->getOperand(opNum+1).isReg() && - MI->getOperand(opNum+1).getReg() == SP::G0) - return; // don't print "+%g0" - if (MI->getOperand(opNum+1).isImm() && - MI->getOperand(opNum+1).getImm() == 0) - return; // don't print "+0" - - O << "+"; - if (MI->getOperand(opNum+1).isGlobal() || - MI->getOperand(opNum+1).isCPI()) { - O << "%lo("; - printOperand(MI, opNum+1); - O << ")"; - } else { - printOperand(MI, opNum+1); - } -} - -void SparcAsmPrinter::printCCOperand(const MachineInstr *MI, int opNum) { - int CC = (int)MI->getOperand(opNum).getImm(); - O << SPARCCondCodeToString((SPCC::CondCodes)CC); -} - -bool SparcAsmPrinter::doInitialization(Module &M) { - Mang = new Mangler(M); - return false; // success -} - -bool SparcAsmPrinter::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); - - O << '\n'; - - return AsmPrinter::doFinalization(M); -} - -void SparcAsmPrinter::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; - - O << "\n\n"; - std::string name = Mang->getValueName(GVar); - Constant *C = GVar->getInitializer(); - unsigned Size = TD->getABITypeSize(C->getType()); - unsigned Align = TD->getPreferredAlignment(GVar); - - printVisibility(name, GVar->getVisibility()); - - SwitchToSection(TAI->SectionForGlobal(GVar)); - - if (C->isNullValue() && !GVar->hasSection()) { - if (!GVar->isThreadLocal() && - (GVar->hasInternalLinkage() || GVar->mayBeOverridden())) { - if (Size == 0) Size = 1; // .comm Foo, 0 is undefined, avoid it. - - if (GVar->hasInternalLinkage()) - O << "\t.local " << name << '\n'; - - O << TAI->getCOMMDirective() << name << ',' << Size; - if (TAI->getCOMMDirectiveTakesAlignment()) - O << ',' << (1 << Align); - - O << '\n'; - return; - } - } - - switch (GVar->getLinkage()) { - case GlobalValue::CommonLinkage: - case GlobalValue::LinkOnceLinkage: - case GlobalValue::WeakLinkage: // FIXME: Verify correct for weak. - // Nonnull linkonce -> weak - O << "\t.weak " << name << '\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 << TAI->getGlobalDirective() << name << '\n'; - // FALL THROUGH - case GlobalValue::InternalLinkage: - break; - case GlobalValue::GhostLinkage: - cerr << "Should not have any unmaterialized functions!\n"; - abort(); - case GlobalValue::DLLImportLinkage: - cerr << "DLLImport linkage is not supported by this target!\n"; - abort(); - case GlobalValue::DLLExportLinkage: - cerr << "DLLExport linkage is not supported by this target!\n"; - abort(); - default: - assert(0 && "Unknown linkage type!"); - } - - EmitAlignment(Align, GVar); - - if (TAI->hasDotTypeDotSizeDirective()) { - O << "\t.type " << name << ",#object\n"; - O << "\t.size " << name << ',' << Size << '\n'; - } - - O << name << ":\n"; - EmitGlobalConstant(C); -} - -/// PrintAsmOperand - Print out an operand for an inline asm expression. -/// -bool SparcAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, - unsigned AsmVariant, - const char *ExtraCode) { - if (ExtraCode && ExtraCode[0]) { - if (ExtraCode[1] != 0) return true; // Unknown modifier. - - switch (ExtraCode[0]) { - default: return true; // Unknown modifier. - case 'r': - break; - } - } - - printOperand(MI, OpNo); - - return false; -} - -bool SparcAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, - unsigned OpNo, - unsigned AsmVariant, - const char *ExtraCode) { - if (ExtraCode && ExtraCode[0]) - return true; // Unknown modifier - - O << '['; - printMemOperand(MI, OpNo); - O << ']'; - - return false; -}