Index: llvm/lib/Target/PowerPC/PPCFrameLowering.h =================================================================== --- llvm/lib/Target/PowerPC/PPCFrameLowering.h +++ llvm/lib/Target/PowerPC/PPCFrameLowering.h @@ -143,15 +143,15 @@ /// getTOCSaveOffset - Return the previous frame offset to save the /// TOC register -- 64-bit SVR4 ABI only. - unsigned getTOCSaveOffset() const { return TOCSaveOffset; } + unsigned getTOCSaveOffset() const; /// getFramePointerSaveOffset - Return the previous frame offset to save the /// frame pointer. - unsigned getFramePointerSaveOffset() const { return FramePointerSaveOffset; } + unsigned getFramePointerSaveOffset() const; /// getBasePointerSaveOffset - Return the previous frame offset to save the /// base pointer. - unsigned getBasePointerSaveOffset() const { return BasePointerSaveOffset; } + unsigned getBasePointerSaveOffset() const; /// getCRSaveOffset - Return the previous frame offset to save the /// CR register. Index: llvm/lib/Target/PowerPC/PPCFrameLowering.cpp =================================================================== --- llvm/lib/Target/PowerPC/PPCFrameLowering.cpp +++ llvm/lib/Target/PowerPC/PPCFrameLowering.cpp @@ -47,13 +47,15 @@ }; static unsigned computeReturnSaveOffset(const PPCSubtarget &STI) { - if (STI.isDarwinABI()) + if (STI.isDarwinABI() || STI.isAIXABI()) return STI.isPPC64() ? 16 : 8; // SVR4 ABI: return STI.isPPC64() ? 16 : 4; } static unsigned computeTOCSaveOffset(const PPCSubtarget &STI) { + if (STI.isAIXABI()) + return STI.isPPC64() ? 40 : 20; return STI.isELFv2ABI() ? 24 : 40; } @@ -787,15 +789,18 @@ bool isPPC64 = Subtarget.isPPC64(); // Get the ABI. bool isSVR4ABI = Subtarget.isSVR4ABI(); + bool isAIXABI = Subtarget.isAIXABI(); bool isELFv2ABI = Subtarget.isELFv2ABI(); - assert((Subtarget.isDarwinABI() || isSVR4ABI) && - "Currently only Darwin and SVR4 ABIs are supported for PowerPC."); + assert((Subtarget.isDarwinABI() || isSVR4ABI || isAIXABI) && + "Unsupported PPC ABI."); // Scan the prolog, looking for an UPDATE_VRSAVE instruction. If we find it, // process it. if (!isSVR4ABI) for (unsigned i = 0; MBBI != MBB.end(); ++i, ++MBBI) { - if (MBBI->getOpcode() == PPC::UPDATE_VRSAVE) { + if (MBBI->getOpcode() == PPC::UPDATE_VRSAVE) { + if (isAIXABI) + report_fatal_error("UPDATE_VRSAVE is unexpected on AIX."); HandleVRSaveUpdate(*MBBI, TII); break; } @@ -914,6 +919,9 @@ assert((isPPC64 || !MustSaveCR) && "Prologue CR saving supported only in 64-bit mode"); + if (MustSaveCR && isAIXABI) + report_fatal_error("Prologue CR saving is unimplemented on AIX."); + // Check if we can move the stack update instruction (stdu) down the prologue // past the callee saves. Hopefully this will avoid the situation where the // saves are waiting for the update on the store with update to complete. @@ -2434,6 +2442,26 @@ return true; } +unsigned PPCFrameLowering::getTOCSaveOffset() const { + if (Subtarget.isAIXABI()) + // TOC save/restore is normally handled by the linker. + // Indirect calls should hit this limitation. + report_fatal_error("TOC save is not implemented on AIX yet."); + return TOCSaveOffset; +} + +unsigned PPCFrameLowering::getFramePointerSaveOffset() const { + if (Subtarget.isAIXABI()) + report_fatal_error("FramePointer is not implemented on AIX yet."); + return FramePointerSaveOffset; +} + +unsigned PPCFrameLowering::getBasePointerSaveOffset() const { + if (Subtarget.isAIXABI()) + report_fatal_error("BasePointer is not implemented on AIX yet."); + return BasePointerSaveOffset; +} + bool PPCFrameLowering::enableShrinkWrapping(const MachineFunction &MF) const { if (MF.getInfo()->shrinkWrapDisabled()) return false; Index: llvm/test/CodeGen/PowerPC/aix-lr.ll =================================================================== --- /dev/null +++ llvm/test/CodeGen/PowerPC/aix-lr.ll @@ -0,0 +1,32 @@ +; RUN: llc -verify-machineinstrs -mtriple powerpc-ibm-aix-xcoff < %s | \ +; RUN: FileCheck --check-prefix=32BIT %s + +; RUN: llc -verify-machineinstrs -mtriple powerpc64-ibm-aix-xcoff < %s | \ +; RUN: FileCheck --check-prefix=64BIT %s + +define void @bar() { +entry: + +; 32BIT: mflr 0 +; 32BIT: stw 0, 8(1) +; 32BIT: stwu 1, -64(1) +; 32BIT: bl .foo +; 32BIT: nop +; 32BIT: addi 1, 1, 64 +; 32BIT: lwz 0, 8(1) +; 32BIT: mtlr 0 + +; 64BIT: mflr 0 +; 64BIT: std 0, 16(1) +; 64BIT: stdu 1, -112(1) +; 64BIT: bl .foo +; 64BIT: nop +; 64BIT: addi 1, 1, 112 +; 64BIT: ld 0, 16(1) +; 64BIT: mtlr 0 + + call void bitcast (void (...)* @foo to void ()*)() + ret void +} + +declare void @foo(...) Index: llvm/test/CodeGen/PowerPC/test_call_aix.ll =================================================================== --- llvm/test/CodeGen/PowerPC/test_call_aix.ll +++ llvm/test/CodeGen/PowerPC/test_call_aix.ll @@ -1,5 +1,3 @@ -; XFAIL: asserts - ; RUN: llc -mtriple powerpc-ibm-aix-xcoff -stop-after=machine-cp < %s | \ ; RUN: FileCheck --check-prefix=32BIT %s