Add support for the PowerPC 64-bit SVR4 ABI.

The Link Register is volatile when using the 32-bit SVR4 ABI.
Make it possible to use the 64-bit SVR4 ABI.
Add non-volatile registers for the 64-bit SVR4 ABI.
Make sure r2 is a reserved register when using the 64-bit SVR4 ABI.
Update PPCFrameInfo for the 64-bit SVR4 ABI.
Add FIXME for 64-bit Darwin PPC.
Insert NOP instruction after direct function calls.
Emit official procedure descriptors.
Create TOC entries for GlobalAddress references.
Spill 64-bit non-volatile registers to the correct slots.
Only custom lower VAARG when using the 32-bit SVR4 ABI.
Use simple VASTART lowering for the 64-bit SVR4 ABI.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@79091 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Tilmann Scheller
2009-08-15 11:54:46 +00:00
parent 7a1e872564
commit 6b16eff207
9 changed files with 361 additions and 72 deletions

View File

@@ -81,13 +81,14 @@ namespace {
};
StringMap<FnStubInfo> FnStubs;
StringMap<std::string> GVStubs, HiddenGVStubs;
StringMap<std::string> GVStubs, HiddenGVStubs, TOC;
const PPCSubtarget &Subtarget;
uint64_t LabelID;
public:
explicit PPCAsmPrinter(formatted_raw_ostream &O, TargetMachine &TM,
const TargetAsmInfo *T, bool V)
: AsmPrinter(O, TM, T, V),
Subtarget(TM.getSubtarget<PPCSubtarget>()) {}
Subtarget(TM.getSubtarget<PPCSubtarget>()), LabelID(0) {}
virtual const char *getPassName() const {
return "PowerPC Assembly Printer";
@@ -310,6 +311,28 @@ namespace {
printOperand(MI, OpNo+1);
}
void printTOCEntryLabel(const MachineInstr *MI, unsigned OpNo) {
const MachineOperand &MO = MI->getOperand(OpNo);
assert(MO.getType() == MachineOperand::MO_GlobalAddress);
GlobalValue *GV = MO.getGlobal();
std::string Name = Mang->getMangledName(GV);
// Map symbol -> label of TOC entry.
if (TOC.count(Name) == 0) {
std::string Label;
Label += TAI->getPrivateGlobalPrefix();
Label += "C";
Label += utostr(LabelID++);
TOC[Name] = Label;
}
O << TOC[Name] << "@toc";
}
void printPredicateOperand(const MachineInstr *MI, unsigned OpNo,
const char *Modifier);
@@ -330,6 +353,7 @@ namespace {
}
bool runOnMachineFunction(MachineFunction &F);
bool doFinalization(Module &M);
void getAnalysisUsage(AnalysisUsage &AU) const {
AU.setPreservesAll();
@@ -612,7 +636,19 @@ bool PPCLinuxAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
printVisibility(CurrentFnName, F->getVisibility());
EmitAlignment(MF.getAlignment(), F);
O << CurrentFnName << ":\n";
if (Subtarget.isPPC64()) {
// Emit an official procedure descriptor.
// FIXME 64-bit SVR4: Use MCSection here?
O << "\t.section\t\".opd\",\"aw\"\n";
O << "\t.align 3\n";
O << CurrentFnName << ":\n";
O << "\t.quad .L." << CurrentFnName << ",.TOC.@tocbase\n";
O << "\t.previous\n";
O << ".L." << CurrentFnName << ":\n";
} else {
O << CurrentFnName << ":\n";
}
// Emit pre-function debug information.
DW->BeginFunction(&MF);
@@ -731,6 +767,24 @@ void PPCLinuxAsmPrinter::PrintGlobalVariable(const GlobalVariable *GVar) {
O << '\n';
}
bool PPCLinuxAsmPrinter::doFinalization(Module &M) {
const TargetData *TD = TM.getTargetData();
bool isPPC64 = TD->getPointerSizeInBits() == 64;
if (isPPC64 && !TOC.empty()) {
// FIXME 64-bit SVR4: Use MCSection here?
O << "\t.section\t\".toc\",\"aw\"\n";
for (StringMap<std::string>::iterator I = TOC.begin(), E = TOC.end();
I != E; ++I) {
O << I->second << ":\n";
O << "\t.tc " << I->getKeyData() << "[TC]," << I->getKeyData() << '\n';
}
}
return AsmPrinter::doFinalization(M);
}
/// runOnMachineFunction - This uses the printMachineInstruction()
/// method to print assembly for each instruction.