diff options
| -rw-r--r-- | llvm/lib/Target/PowerPC/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | llvm/lib/Target/PowerPC/PPCCCState.cpp | 36 | ||||
| -rw-r--r-- | llvm/lib/Target/PowerPC/PPCCCState.h | 42 | ||||
| -rw-r--r-- | llvm/lib/Target/PowerPC/PPCCallingConv.td | 12 | ||||
| -rw-r--r-- | llvm/lib/Target/PowerPC/PPCFastISel.cpp | 1 | ||||
| -rw-r--r-- | llvm/lib/Target/PowerPC/PPCISelLowering.cpp | 13 | ||||
| -rw-r--r-- | llvm/test/CodeGen/PowerPC/ppc32-align-long-double-sf.ll | 21 | 
7 files changed, 122 insertions, 4 deletions
diff --git a/llvm/lib/Target/PowerPC/CMakeLists.txt b/llvm/lib/Target/PowerPC/CMakeLists.txt index 53c2ed3d51e..4842c3b7a65 100644 --- a/llvm/lib/Target/PowerPC/CMakeLists.txt +++ b/llvm/lib/Target/PowerPC/CMakeLists.txt @@ -16,6 +16,7 @@ add_llvm_target(PowerPCCodeGen    PPCBoolRetToInt.cpp    PPCAsmPrinter.cpp    PPCBranchSelector.cpp +  PPCCCState.cpp    PPCCTRLoops.cpp    PPCHazardRecognizers.cpp    PPCInstrInfo.cpp diff --git a/llvm/lib/Target/PowerPC/PPCCCState.cpp b/llvm/lib/Target/PowerPC/PPCCCState.cpp new file mode 100644 index 00000000000..5510a95430f --- /dev/null +++ b/llvm/lib/Target/PowerPC/PPCCCState.cpp @@ -0,0 +1,36 @@ +//===---- PPCCCState.cpp - CCState with PowerPC specific extensions ---------===// +// +//                     The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "PPCCCState.h" +#include "PPCSubtarget.h" +#include "llvm/IR/Module.h" +using namespace llvm; + +// Identify lowered values that originated from ppcf128 arguments and record +// this. +void PPCCCState::PreAnalyzeCallOperands( +    const SmallVectorImpl<ISD::OutputArg> &Outs) { +  for (const auto &I : Outs) { +    if (I.ArgVT == llvm::MVT::ppcf128) +      OriginalArgWasPPCF128.push_back(true); +    else +      OriginalArgWasPPCF128.push_back(false); +  } +} + +void PPCCCState::PreAnalyzeFormalArguments( +    const SmallVectorImpl<ISD::InputArg> &Ins) { +  for (const auto &I : Ins) { +    if (I.ArgVT == llvm::MVT::ppcf128) { +      OriginalArgWasPPCF128.push_back(true); +    } else { +      OriginalArgWasPPCF128.push_back(false); +    } +  } +}
\ No newline at end of file diff --git a/llvm/lib/Target/PowerPC/PPCCCState.h b/llvm/lib/Target/PowerPC/PPCCCState.h new file mode 100644 index 00000000000..9be9f11dbea --- /dev/null +++ b/llvm/lib/Target/PowerPC/PPCCCState.h @@ -0,0 +1,42 @@ +//===---- PPCCCState.h - CCState with PowerPC specific extensions -----------===// +// +//                     The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef PPCCCSTATE_H +#define PPCCCSTATE_H + +#include "PPCISelLowering.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/CodeGen/CallingConvLower.h" + +namespace llvm { + +class PPCCCState : public CCState { +public: + +  void +  PreAnalyzeCallOperands(const SmallVectorImpl<ISD::OutputArg> &Outs); +  void +  PreAnalyzeFormalArguments(const SmallVectorImpl<ISD::InputArg> &Ins); + +private: + +  // Records whether the value has been lowered from an ppcf128. +  SmallVector<bool, 4> OriginalArgWasPPCF128; + +public: +  PPCCCState(CallingConv::ID CC, bool isVarArg, MachineFunction &MF, +             SmallVectorImpl<CCValAssign> &locs, LLVMContext &C) +        : CCState(CC, isVarArg, MF, locs, C) {} + +  bool WasOriginalArgPPCF128(unsigned ValNo) { return OriginalArgWasPPCF128[ValNo]; } +  void clearWasPPCF128() { OriginalArgWasPPCF128.clear(); } +}; +} + +#endif diff --git a/llvm/lib/Target/PowerPC/PPCCallingConv.td b/llvm/lib/Target/PowerPC/PPCCallingConv.td index 2fd3ab67297..92c51e5fc5e 100644 --- a/llvm/lib/Target/PowerPC/PPCCallingConv.td +++ b/llvm/lib/Target/PowerPC/PPCCallingConv.td @@ -23,6 +23,9 @@ class CCIfNotSubtarget<string F, CCAction A>                         "(State.getMachineFunction().getSubtarget()).",                       F),            A>; +class CCIfOrigArgWasNotPPCF128<CCAction A> +    : CCIf<"!static_cast<PPCCCState *>(&State)->WasOriginalArgPPCF128(ValNo)", +           A>;  //===----------------------------------------------------------------------===//  // Return Value Calling Convention @@ -131,7 +134,14 @@ def CC_PPC32_SVR4_Common : CallingConv<[    // The ABI requires i64 to be passed in two adjacent registers with the first    // register having an odd register number. -  CCIfType<[i32], CCIfSplit<CCCustom<"CC_PPC32_SVR4_Custom_AlignArgRegs">>>, +  CCIfType<[i32], +  CCIfSplit<CCIfSubtarget<"useSoftFloat()",  +            CCIfOrigArgWasNotPPCF128< +            CCCustom<"CC_PPC32_SVR4_Custom_AlignArgRegs">>>>>, +   +  CCIfType<[i32], +  CCIfSplit<CCIfNotSubtarget<"useSoftFloat()",  +                            CCCustom<"CC_PPC32_SVR4_Custom_AlignArgRegs">>>>,    // The 'nest' parameter, if any, is passed in R11.    CCIfNest<CCAssignToReg<[R11]>>, diff --git a/llvm/lib/Target/PowerPC/PPCFastISel.cpp b/llvm/lib/Target/PowerPC/PPCFastISel.cpp index 7ff7e48795d..cccc75faf26 100644 --- a/llvm/lib/Target/PowerPC/PPCFastISel.cpp +++ b/llvm/lib/Target/PowerPC/PPCFastISel.cpp @@ -16,6 +16,7 @@  #include "PPC.h"  #include "MCTargetDesc/PPCPredicates.h"  #include "PPCCallingConv.h" +#include "PPCCCState.h"  #include "PPCISelLowering.h"  #include "PPCMachineFunctionInfo.h"  #include "PPCSubtarget.h" diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp index e5cd3e30afb..813bf27f009 100644 --- a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp +++ b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp @@ -14,6 +14,7 @@  #include "PPCISelLowering.h"  #include "MCTargetDesc/PPCPredicates.h"  #include "PPCCallingConv.h" +#include "PPCCCState.h"  #include "PPCMachineFunctionInfo.h"  #include "PPCPerfectShuffle.h"  #include "PPCTargetMachine.h" @@ -2842,14 +2843,17 @@ PPCTargetLowering::LowerFormalArguments_32SVR4(    // Assign locations to all of the incoming arguments.    SmallVector<CCValAssign, 16> ArgLocs; -  CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(), ArgLocs, +  PPCCCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(), ArgLocs,                   *DAG.getContext());    // Reserve space for the linkage area on the stack.    unsigned LinkageSize = Subtarget.getFrameLowering()->getLinkageSize();    CCInfo.AllocateStack(LinkageSize, PtrByteSize); +  if (Subtarget.useSoftFloat()) +    CCInfo.PreAnalyzeFormalArguments(Ins);    CCInfo.AnalyzeFormalArguments(Ins, CC_PPC32_SVR4); +  CCInfo.clearWasPPCF128();    for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {      CCValAssign &VA = ArgLocs[i]; @@ -4736,12 +4740,14 @@ PPCTargetLowering::LowerCall_32SVR4(SDValue Chain, SDValue Callee,    // Assign locations to all of the outgoing arguments.    SmallVector<CCValAssign, 16> ArgLocs; -  CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(), ArgLocs, +  PPCCCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(), ArgLocs,                   *DAG.getContext());    // Reserve space for the linkage area on the stack.    CCInfo.AllocateStack(Subtarget.getFrameLowering()->getLinkageSize(),                         PtrByteSize); +  if (Subtarget.useSoftFloat()) +    CCInfo.PreAnalyzeCallOperands(Outs);    if (isVarArg) {      // Handle fixed and variable vector arguments differently. @@ -4774,7 +4780,8 @@ PPCTargetLowering::LowerCall_32SVR4(SDValue Chain, SDValue Callee,      // All arguments are treated the same.      CCInfo.AnalyzeCallOperands(Outs, CC_PPC32_SVR4);    } - +  CCInfo.clearWasPPCF128(); +      // Assign locations to all of the outgoing aggregate by value arguments.    SmallVector<CCValAssign, 16> ByValArgLocs;    CCState CCByValInfo(CallConv, isVarArg, DAG.getMachineFunction(), diff --git a/llvm/test/CodeGen/PowerPC/ppc32-align-long-double-sf.ll b/llvm/test/CodeGen/PowerPC/ppc32-align-long-double-sf.ll new file mode 100644 index 00000000000..f8a6d071cfe --- /dev/null +++ b/llvm/test/CodeGen/PowerPC/ppc32-align-long-double-sf.ll @@ -0,0 +1,21 @@ +; RUN: llc -O2 -mtriple=powerpc-unknown-linux-gnu < %s | FileCheck %s + +@x = global ppc_fp128 0xM405EDA5E353F7CEE0000000000000000, align 16 +@.str = private unnamed_addr constant [5 x i8] c"%Lf\0A\00", align 1 + + +define void @foo() #0 { +entry: +  %0 = load ppc_fp128, ppc_fp128* @x, align 16 +  %call = tail call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([5 x i8], [5 x i8]* @.str, i32 0, i32 0), ppc_fp128 %0) +  ret void +} +; Do not skip register r4 because of register alignment in soft float mode. Instead skipping  +; put in r4 part of first argument for printf function (long double). +; CHECK: lwzu 4, x@l({{[0-9]+}}) + +declare i32 @printf(i8* nocapture readonly, ...) #0 + +attributes #0 = { "use-soft-float"="true" } + +                        
\ No newline at end of file  | 

