From e682b80b8bf410abd9ee1040a643fd4e31413fa2 Mon Sep 17 00:00:00 2001 From: Strahinja Petrovic Date: Mon, 9 May 2016 12:27:39 +0000 Subject: [PowerPC] fix register alignment for long double type This patch fixes register alignment for long double type in soft float mode. Before this patch alignment was 8 and this patch changes it to 4. Differential Revision: http://reviews.llvm.org/D18034 llvm-svn: 268909 --- llvm/lib/Target/PowerPC/CMakeLists.txt | 1 + llvm/lib/Target/PowerPC/PPCCCState.cpp | 36 +++++++++++++++++++++++++ llvm/lib/Target/PowerPC/PPCCCState.h | 42 +++++++++++++++++++++++++++++ llvm/lib/Target/PowerPC/PPCCallingConv.td | 12 ++++++++- llvm/lib/Target/PowerPC/PPCFastISel.cpp | 1 + llvm/lib/Target/PowerPC/PPCISelLowering.cpp | 13 ++++++--- 6 files changed, 101 insertions(+), 4 deletions(-) create mode 100644 llvm/lib/Target/PowerPC/PPCCCState.cpp create mode 100644 llvm/lib/Target/PowerPC/PPCCCState.h (limited to 'llvm/lib/Target') 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 &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 &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 &Outs); + void + PreAnalyzeFormalArguments(const SmallVectorImpl &Ins); + +private: + + // Records whether the value has been lowered from an ppcf128. + SmallVector OriginalArgWasPPCF128; + +public: + PPCCCState(CallingConv::ID CC, bool isVarArg, MachineFunction &MF, + SmallVectorImpl &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 "(State.getMachineFunction().getSubtarget()).", F), A>; +class CCIfOrigArgWasNotPPCF128 + : CCIf<"!static_cast(&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>>, + CCIfType<[i32], + CCIfSplit>>>>, + + CCIfType<[i32], + CCIfSplit>>>, // The 'nest' parameter, if any, is passed in R11. CCIfNest>, 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 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 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 ByValArgLocs; CCState CCByValInfo(CallConv, isVarArg, DAG.getMachineFunction(), -- cgit v1.2.3