summaryrefslogtreecommitdiff
path: root/lib/Target/Sparc/AsmPrinter/SparcAsmPrinter.cpp
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2009-09-15 17:46:24 +0000
committerChris Lattner <sabre@nondot.org>2009-09-15 17:46:24 +0000
commitdb486a6d5311944f61b92db9f6074944dbbdb242 (patch)
treec6ea58f21ac327940105e66d47fc76a3736459ad /lib/Target/Sparc/AsmPrinter/SparcAsmPrinter.cpp
parent307a7c48f15b087663b60d600d23afffb9e211e6 (diff)
downloadllvm-db486a6d5311944f61b92db9f6074944dbbdb242.tar.gz
llvm-db486a6d5311944f61b92db9f6074944dbbdb242.tar.bz2
llvm-db486a6d5311944f61b92db9f6074944dbbdb242.tar.xz
several major improvements to the sparc backend: support for weak linkage
and PIC codegen. Patch by Venkatraman Govindaraju! git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@81877 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target/Sparc/AsmPrinter/SparcAsmPrinter.cpp')
-rw-r--r--lib/Target/Sparc/AsmPrinter/SparcAsmPrinter.cpp82
1 files changed, 70 insertions, 12 deletions
diff --git a/lib/Target/Sparc/AsmPrinter/SparcAsmPrinter.cpp b/lib/Target/Sparc/AsmPrinter/SparcAsmPrinter.cpp
index e8aef4bb65..81ac5324c1 100644
--- a/lib/Target/Sparc/AsmPrinter/SparcAsmPrinter.cpp
+++ b/lib/Target/Sparc/AsmPrinter/SparcAsmPrinter.cpp
@@ -75,12 +75,14 @@ namespace {
unsigned AsmVariant, const char *ExtraCode);
bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo,
unsigned AsmVariant, const char *ExtraCode);
+
+ void emitFunctionHeader(const MachineFunction &MF);
+ bool printGetPCX(const MachineInstr *MI, unsigned OpNo);
};
} // end of anonymous namespace
#include "SparcGenAsmWriter.inc"
-
/// runOnMachineFunction - This uses the printInstruction()
/// method to print assembly for each instruction.
///
@@ -96,17 +98,9 @@ bool SparcAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
// BBs the same name. (If you have a better way, please let me know!)
O << "\n\n";
-
- // Print out the label for the function.
- const Function *F = MF.getFunction();
- OutStreamer.SwitchSection(getObjFileLowering().SectionForGlobal(F, Mang, TM));
- EmitAlignment(MF.getAlignment(), F);
- O << "\t.globl\t" << CurrentFnName << '\n';
-
- printVisibility(CurrentFnName, F->getVisibility());
-
- O << "\t.type\t" << CurrentFnName << ", #function\n";
- O << CurrentFnName << ":\n";
+ emitFunctionHeader(MF);
+
+
// Emit pre-function debug information.
DW->BeginFunction(&MF);
@@ -145,9 +139,43 @@ bool SparcAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
DW->EndFunction(&MF);
// We didn't modify anything.
+ O << "\t.size\t" << CurrentFnName << ", .-" << CurrentFnName << '\n';
return false;
}
+void SparcAsmPrinter::emitFunctionHeader(const MachineFunction &MF) {
+ const Function *F = MF.getFunction();
+ OutStreamer.SwitchSection(getObjFileLowering().SectionForGlobal(F, Mang, TM));
+ EmitAlignment(MF.getAlignment(), F);
+
+ switch (F->getLinkage()) {
+ default: llvm_unreachable("Unknown linkage type");
+ case Function::PrivateLinkage:
+ case Function::InternalLinkage:
+ // Function is internal.
+ break;
+ case Function::DLLExportLinkage:
+ case Function::ExternalLinkage:
+ // Function is externally visible
+ O << "\t.global\t" << CurrentFnName << '\n';
+ break;
+ case Function::LinkerPrivateLinkage:
+ case Function::LinkOnceAnyLinkage:
+ case Function::LinkOnceODRLinkage:
+ case Function::WeakAnyLinkage:
+ case Function::WeakODRLinkage:
+ // Function is weak
+ O << "\t.weak\t" << CurrentFnName << '\n' ;
+ break;
+ }
+
+ printVisibility(CurrentFnName, F->getVisibility());
+
+ O << "\t.type\t" << CurrentFnName << ", #function\n";
+ O << CurrentFnName << ":\n";
+}
+
+
void SparcAsmPrinter::printOperand(const MachineInstr *MI, int opNum) {
const MachineOperand &MO = MI->getOperand (opNum);
bool CloseParen = false;
@@ -215,6 +243,36 @@ void SparcAsmPrinter::printMemOperand(const MachineInstr *MI, int opNum,
}
}
+bool SparcAsmPrinter::printGetPCX(const MachineInstr *MI, unsigned opNum) {
+ std::string operand = "";
+ const MachineOperand &MO = MI->getOperand(opNum);
+ switch (MO.getType()) {
+ default: assert(0 && "Operand is not a register ");
+ case MachineOperand::MO_Register:
+ assert(TargetRegisterInfo::isPhysicalRegister(MO.getReg()) &&
+ "Operand is not a physical register ");
+ operand = "%" + LowercaseString(getRegisterName(MO.getReg()));
+ break;
+ }
+
+ unsigned bbNum = NumberForBB[MI->getParent()->getBasicBlock()];
+
+ O << '\n' << ".LLGETPCH" << bbNum << ":\n";
+ O << "\tcall\t.LLGETPC" << bbNum << '\n' ;
+
+ O << "\t sethi\t"
+ << "%hi(_GLOBAL_OFFSET_TABLE_+(.-.LLGETPCH" << bbNum << ")), "
+ << operand << '\n' ;
+
+ O << ".LLGETPC" << bbNum << ":\n" ;
+ O << "\tor\t" << operand
+ << ", %lo(_GLOBAL_OFFSET_TABLE_+(.-.LLGETPCH" << bbNum << ")), "
+ << operand << '\n';
+ O << "\tadd\t" << operand << ", %o7, " << operand << '\n';
+
+ return true;
+}
+
void SparcAsmPrinter::printCCOperand(const MachineInstr *MI, int opNum) {
int CC = (int)MI->getOperand(opNum).getImm();
O << SPARCCondCodeToString((SPCC::CondCodes)CC);