From 09967050098ea75a3b331c1d6ab21df7b2e2b4df Mon Sep 17 00:00:00 2001 From: Hubert Tong Date: Tue, 13 Aug 2019 17:05:53 +0000 Subject: [PATCH] Reland r368691: "[AIX] Implement LR prolog/epilog save/restore" Trying again with the code changes (and not just the new test). Summary: This patch fixes the offsets of fields in the stack frame linkage save area for AIX. Reviewers: sfertile, hubert.reinterpretcast, jasonliu, Xiangling_L, xingxue, ZarkoCA, daltenty Reviewed By: hubert.reinterpretcast Subscribers: wuzish, nemanjai, hiraditya, kbarton, MaskRay, jsji, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D64424 Patch by Chris Bowler! llvm-svn: 368721 --- llvm/lib/Target/PowerPC/PPCFrameLowering.cpp | 34 ++++++++++++++++++-- llvm/lib/Target/PowerPC/PPCFrameLowering.h | 6 ++-- llvm/test/CodeGen/PowerPC/aix-lr.ll | 32 ++++++++++++++++++ llvm/test/CodeGen/PowerPC/test_call_aix.ll | 2 -- 4 files changed, 66 insertions(+), 8 deletions(-) create mode 100644 llvm/test/CodeGen/PowerPC/aix-lr.ll diff --git a/llvm/lib/Target/PowerPC/PPCFrameLowering.cpp b/llvm/lib/Target/PowerPC/PPCFrameLowering.cpp index 5aead5e4e80b3..e3e295ff5995e 100644 --- a/llvm/lib/Target/PowerPC/PPCFrameLowering.cpp +++ b/llvm/lib/Target/PowerPC/PPCFrameLowering.cpp @@ -47,13 +47,15 @@ static const MCPhysReg VRRegNo[] = { }; 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 @@ void PPCFrameLowering::emitPrologue(MachineFunction &MF, 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 (isAIXABI) + report_fatal_error("UPDATE_VRSAVE is unexpected on AIX."); HandleVRSaveUpdate(*MBBI, TII); break; } @@ -914,6 +919,9 @@ void PPCFrameLowering::emitPrologue(MachineFunction &MF, 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 @@ PPCFrameLowering::restoreCalleeSavedRegisters(MachineBasicBlock &MBB, 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; diff --git a/llvm/lib/Target/PowerPC/PPCFrameLowering.h b/llvm/lib/Target/PowerPC/PPCFrameLowering.h index 7783a05e83770..a5fbc9acbb28c 100644 --- a/llvm/lib/Target/PowerPC/PPCFrameLowering.h +++ b/llvm/lib/Target/PowerPC/PPCFrameLowering.h @@ -143,15 +143,15 @@ class PPCFrameLowering: public TargetFrameLowering { /// 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. diff --git a/llvm/test/CodeGen/PowerPC/aix-lr.ll b/llvm/test/CodeGen/PowerPC/aix-lr.ll new file mode 100644 index 0000000000000..ea92daf04f07a --- /dev/null +++ b/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(...) diff --git a/llvm/test/CodeGen/PowerPC/test_call_aix.ll b/llvm/test/CodeGen/PowerPC/test_call_aix.ll index 81133a5b529c6..ba363b75b3de9 100644 --- a/llvm/test/CodeGen/PowerPC/test_call_aix.ll +++ b/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