mirror of
https://github.com/llvm/llvm-project.git
synced 2025-04-24 06:26:07 +00:00
[PPC] Include tablegenerated PPCGenCallingConv.inc once
Move the CC analysis implementation to its own .cpp file instead of duplicating it and artificually using functions in PPCISelLowering.cpp and PPCFastISel.cpp. Follow-up to the same change done for X86, ARM, and AArch64. llvm-svn: 352444
This commit is contained in:
parent
b72888647b
commit
85e72c3d56
@ -19,6 +19,7 @@ add_llvm_target(PowerPCCodeGen
|
||||
PPCAsmPrinter.cpp
|
||||
PPCBranchSelector.cpp
|
||||
PPCBranchCoalescing.cpp
|
||||
PPCCallingConv.cpp
|
||||
PPCCCState.cpp
|
||||
PPCCTRLoops.cpp
|
||||
PPCHazardRecognizers.cpp
|
||||
|
108
llvm/lib/Target/PowerPC/PPCCallingConv.cpp
Normal file
108
llvm/lib/Target/PowerPC/PPCCallingConv.cpp
Normal file
@ -0,0 +1,108 @@
|
||||
//===-- PPCCallingConv.h - --------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "PPCRegisterInfo.h"
|
||||
#include "PPCCallingConv.h"
|
||||
#include "PPCSubtarget.h"
|
||||
#include "PPCCCState.h"
|
||||
using namespace llvm;
|
||||
|
||||
inline bool CC_PPC_AnyReg_Error(unsigned &, MVT &, MVT &,
|
||||
CCValAssign::LocInfo &, ISD::ArgFlagsTy &,
|
||||
CCState &) {
|
||||
llvm_unreachable("The AnyReg calling convention is only supported by the " \
|
||||
"stackmap and patchpoint intrinsics.");
|
||||
// gracefully fallback to PPC C calling convention on Release builds.
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool CC_PPC32_SVR4_Custom_Dummy(unsigned &ValNo, MVT &ValVT, MVT &LocVT,
|
||||
CCValAssign::LocInfo &LocInfo,
|
||||
ISD::ArgFlagsTy &ArgFlags,
|
||||
CCState &State) {
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool CC_PPC32_SVR4_Custom_AlignArgRegs(unsigned &ValNo, MVT &ValVT,
|
||||
MVT &LocVT,
|
||||
CCValAssign::LocInfo &LocInfo,
|
||||
ISD::ArgFlagsTy &ArgFlags,
|
||||
CCState &State) {
|
||||
static const MCPhysReg ArgRegs[] = {
|
||||
PPC::R3, PPC::R4, PPC::R5, PPC::R6,
|
||||
PPC::R7, PPC::R8, PPC::R9, PPC::R10,
|
||||
};
|
||||
const unsigned NumArgRegs = array_lengthof(ArgRegs);
|
||||
|
||||
unsigned RegNum = State.getFirstUnallocated(ArgRegs);
|
||||
|
||||
// Skip one register if the first unallocated register has an even register
|
||||
// number and there are still argument registers available which have not been
|
||||
// allocated yet. RegNum is actually an index into ArgRegs, which means we
|
||||
// need to skip a register if RegNum is odd.
|
||||
if (RegNum != NumArgRegs && RegNum % 2 == 1) {
|
||||
State.AllocateReg(ArgRegs[RegNum]);
|
||||
}
|
||||
|
||||
// Always return false here, as this function only makes sure that the first
|
||||
// unallocated register has an odd register number and does not actually
|
||||
// allocate a register for the current argument.
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool CC_PPC32_SVR4_Custom_SkipLastArgRegsPPCF128(
|
||||
unsigned &ValNo, MVT &ValVT, MVT &LocVT, CCValAssign::LocInfo &LocInfo,
|
||||
ISD::ArgFlagsTy &ArgFlags, CCState &State) {
|
||||
static const MCPhysReg ArgRegs[] = {
|
||||
PPC::R3, PPC::R4, PPC::R5, PPC::R6,
|
||||
PPC::R7, PPC::R8, PPC::R9, PPC::R10,
|
||||
};
|
||||
const unsigned NumArgRegs = array_lengthof(ArgRegs);
|
||||
|
||||
unsigned RegNum = State.getFirstUnallocated(ArgRegs);
|
||||
int RegsLeft = NumArgRegs - RegNum;
|
||||
|
||||
// Skip if there is not enough registers left for long double type (4 gpr regs
|
||||
// in soft float mode) and put long double argument on the stack.
|
||||
if (RegNum != NumArgRegs && RegsLeft < 4) {
|
||||
for (int i = 0; i < RegsLeft; i++) {
|
||||
State.AllocateReg(ArgRegs[RegNum + i]);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool CC_PPC32_SVR4_Custom_AlignFPArgRegs(unsigned &ValNo, MVT &ValVT,
|
||||
MVT &LocVT,
|
||||
CCValAssign::LocInfo &LocInfo,
|
||||
ISD::ArgFlagsTy &ArgFlags,
|
||||
CCState &State) {
|
||||
static const MCPhysReg ArgRegs[] = {
|
||||
PPC::F1, PPC::F2, PPC::F3, PPC::F4, PPC::F5, PPC::F6, PPC::F7,
|
||||
PPC::F8
|
||||
};
|
||||
|
||||
const unsigned NumArgRegs = array_lengthof(ArgRegs);
|
||||
|
||||
unsigned RegNum = State.getFirstUnallocated(ArgRegs);
|
||||
|
||||
// If there is only one Floating-point register left we need to put both f64
|
||||
// values of a split ppc_fp128 value on the stack.
|
||||
if (RegNum != NumArgRegs && ArgRegs[RegNum] == PPC::F8) {
|
||||
State.AllocateReg(ArgRegs[RegNum]);
|
||||
}
|
||||
|
||||
// Always return false here, as this function only makes sure that the two f64
|
||||
// values a ppc_fp128 value is split into are both passed in registers or both
|
||||
// passed on the stack and does not actually allocate a register for the
|
||||
// current argument.
|
||||
return false;
|
||||
}
|
||||
|
||||
#include "PPCGenCallingConv.inc"
|
@ -19,14 +19,27 @@
|
||||
|
||||
namespace llvm {
|
||||
|
||||
inline bool CC_PPC_AnyReg_Error(unsigned &, MVT &, MVT &,
|
||||
CCValAssign::LocInfo &, ISD::ArgFlagsTy &,
|
||||
CCState &) {
|
||||
llvm_unreachable("The AnyReg calling convention is only supported by the " \
|
||||
"stackmap and patchpoint intrinsics.");
|
||||
// gracefully fallback to PPC C calling convention on Release builds.
|
||||
return false;
|
||||
}
|
||||
bool RetCC_PPC(unsigned ValNo, MVT ValVT, MVT LocVT,
|
||||
CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags,
|
||||
CCState &State);
|
||||
bool RetCC_PPC64_ELF_FIS(unsigned ValNo, MVT ValVT, MVT LocVT,
|
||||
CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags,
|
||||
CCState &State);
|
||||
bool RetCC_PPC_Cold(unsigned ValNo, MVT ValVT, MVT LocVT,
|
||||
CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags,
|
||||
CCState &State);
|
||||
bool CC_PPC32_SVR4(unsigned ValNo, MVT ValVT, MVT LocVT,
|
||||
CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags,
|
||||
CCState &State);
|
||||
bool CC_PPC64_ELF_FIS(unsigned ValNo, MVT ValVT, MVT LocVT,
|
||||
CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags,
|
||||
CCState &State);
|
||||
bool CC_PPC32_SVR4_ByVal(unsigned ValNo, MVT ValVT, MVT LocVT,
|
||||
CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags,
|
||||
CCState &State);
|
||||
bool CC_PPC32_SVR4_VarArg(unsigned ValNo, MVT ValVT, MVT LocVT,
|
||||
CCValAssign::LocInfo LocInfo,
|
||||
ISD::ArgFlagsTy ArgFlags, CCState &State);
|
||||
|
||||
} // End llvm namespace
|
||||
|
||||
|
@ -45,6 +45,7 @@ def RetCC_PPC64_AnyReg : CallingConv<[
|
||||
]>;
|
||||
|
||||
// Return-value convention for PowerPC coldcc.
|
||||
let Entry = 1 in
|
||||
def RetCC_PPC_Cold : CallingConv<[
|
||||
// Use the same return registers as RetCC_PPC, but limited to only
|
||||
// one return value. The remaining return values will be saved to
|
||||
@ -69,6 +70,7 @@ def RetCC_PPC_Cold : CallingConv<[
|
||||
]>;
|
||||
|
||||
// Return-value convention for PowerPC
|
||||
let Entry = 1 in
|
||||
def RetCC_PPC : CallingConv<[
|
||||
CCIfCC<"CallingConv::AnyReg", CCDelegateTo<RetCC_PPC64_AnyReg>>,
|
||||
|
||||
@ -125,6 +127,7 @@ def CC_PPC64_AnyReg : CallingConv<[
|
||||
// Simple calling convention for 64-bit ELF PowerPC fast isel.
|
||||
// Only handle ints and floats. All ints are promoted to i64.
|
||||
// Vector types and quadword ints are not handled.
|
||||
let Entry = 1 in
|
||||
def CC_PPC64_ELF_FIS : CallingConv<[
|
||||
CCIfCC<"CallingConv::AnyReg", CCDelegateTo<CC_PPC64_AnyReg>>,
|
||||
|
||||
@ -140,6 +143,7 @@ def CC_PPC64_ELF_FIS : CallingConv<[
|
||||
// All small ints are promoted to i64. Vector types, quadword ints,
|
||||
// and multiple register returns are "supported" to avoid compile
|
||||
// errors, but none are handled by the fast selector.
|
||||
let Entry = 1 in
|
||||
def RetCC_PPC64_ELF_FIS : CallingConv<[
|
||||
CCIfCC<"CallingConv::AnyReg", CCDelegateTo<RetCC_PPC64_AnyReg>>,
|
||||
|
||||
@ -227,12 +231,14 @@ def CC_PPC32_SVR4_Common : CallingConv<[
|
||||
// This calling convention puts vector arguments always on the stack. It is used
|
||||
// to assign vector arguments which belong to the variable portion of the
|
||||
// parameter list of a variable argument function.
|
||||
let Entry = 1 in
|
||||
def CC_PPC32_SVR4_VarArg : CallingConv<[
|
||||
CCDelegateTo<CC_PPC32_SVR4_Common>
|
||||
]>;
|
||||
|
||||
// In contrast to CC_PPC32_SVR4_VarArg, this calling convention first tries to
|
||||
// put vector arguments in vector registers before putting them on the stack.
|
||||
let Entry = 1 in
|
||||
def CC_PPC32_SVR4 : CallingConv<[
|
||||
// QPX vectors mirror the scalar FP convention.
|
||||
CCIfType<[v4f64, v4f32, v4i1], CCIfSubtarget<"hasQPX()",
|
||||
@ -264,6 +270,7 @@ def CC_PPC32_SVR4 : CallingConv<[
|
||||
// The only purpose of CC_PPC32_SVR4_Custom_Dummy is to skip arguments which are
|
||||
// not passed by value.
|
||||
|
||||
let Entry = 1 in
|
||||
def CC_PPC32_SVR4_ByVal : CallingConv<[
|
||||
CCIfByVal<CCPassByVal<4, 4>>,
|
||||
|
||||
|
@ -186,7 +186,6 @@ class PPCFastISel final : public FastISel {
|
||||
unsigned &NumBytes,
|
||||
bool IsVarArg);
|
||||
bool finishCall(MVT RetVT, CallLoweringInfo &CLI, unsigned &NumBytes);
|
||||
LLVM_ATTRIBUTE_UNUSED CCAssignFn *usePPC32CCs(unsigned Flag);
|
||||
|
||||
private:
|
||||
#include "PPCGenFastISel.inc"
|
||||
@ -195,23 +194,6 @@ class PPCFastISel final : public FastISel {
|
||||
|
||||
} // end anonymous namespace
|
||||
|
||||
#include "PPCGenCallingConv.inc"
|
||||
|
||||
// Function whose sole purpose is to kill compiler warnings
|
||||
// stemming from unused functions included from PPCGenCallingConv.inc.
|
||||
CCAssignFn *PPCFastISel::usePPC32CCs(unsigned Flag) {
|
||||
if (Flag == 1)
|
||||
return CC_PPC32_SVR4;
|
||||
else if (Flag == 2)
|
||||
return CC_PPC32_SVR4_ByVal;
|
||||
else if (Flag == 3)
|
||||
return CC_PPC32_SVR4_VarArg;
|
||||
else if (Flag == 4)
|
||||
return RetCC_PPC_Cold;
|
||||
else
|
||||
return RetCC_PPC;
|
||||
}
|
||||
|
||||
static Optional<PPC::Predicate> getComparePred(CmpInst::Predicate Pred) {
|
||||
switch (Pred) {
|
||||
// These are not representable with any single compare.
|
||||
|
@ -3146,101 +3146,6 @@ SDValue PPCTargetLowering::LowerVASTART(SDValue Op, SelectionDAG &DAG) const {
|
||||
MachinePointerInfo(SV, nextOffset));
|
||||
}
|
||||
|
||||
#include "PPCGenCallingConv.inc"
|
||||
|
||||
// Function whose sole purpose is to kill compiler warnings
|
||||
// stemming from unused functions included from PPCGenCallingConv.inc.
|
||||
CCAssignFn *PPCTargetLowering::useFastISelCCs(unsigned Flag) const {
|
||||
return Flag ? CC_PPC64_ELF_FIS : RetCC_PPC64_ELF_FIS;
|
||||
}
|
||||
|
||||
bool llvm::CC_PPC32_SVR4_Custom_Dummy(unsigned &ValNo, MVT &ValVT, MVT &LocVT,
|
||||
CCValAssign::LocInfo &LocInfo,
|
||||
ISD::ArgFlagsTy &ArgFlags,
|
||||
CCState &State) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool llvm::CC_PPC32_SVR4_Custom_AlignArgRegs(unsigned &ValNo, MVT &ValVT,
|
||||
MVT &LocVT,
|
||||
CCValAssign::LocInfo &LocInfo,
|
||||
ISD::ArgFlagsTy &ArgFlags,
|
||||
CCState &State) {
|
||||
static const MCPhysReg ArgRegs[] = {
|
||||
PPC::R3, PPC::R4, PPC::R5, PPC::R6,
|
||||
PPC::R7, PPC::R8, PPC::R9, PPC::R10,
|
||||
};
|
||||
const unsigned NumArgRegs = array_lengthof(ArgRegs);
|
||||
|
||||
unsigned RegNum = State.getFirstUnallocated(ArgRegs);
|
||||
|
||||
// Skip one register if the first unallocated register has an even register
|
||||
// number and there are still argument registers available which have not been
|
||||
// allocated yet. RegNum is actually an index into ArgRegs, which means we
|
||||
// need to skip a register if RegNum is odd.
|
||||
if (RegNum != NumArgRegs && RegNum % 2 == 1) {
|
||||
State.AllocateReg(ArgRegs[RegNum]);
|
||||
}
|
||||
|
||||
// Always return false here, as this function only makes sure that the first
|
||||
// unallocated register has an odd register number and does not actually
|
||||
// allocate a register for the current argument.
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
llvm::CC_PPC32_SVR4_Custom_SkipLastArgRegsPPCF128(unsigned &ValNo, MVT &ValVT,
|
||||
MVT &LocVT,
|
||||
CCValAssign::LocInfo &LocInfo,
|
||||
ISD::ArgFlagsTy &ArgFlags,
|
||||
CCState &State) {
|
||||
static const MCPhysReg ArgRegs[] = {
|
||||
PPC::R3, PPC::R4, PPC::R5, PPC::R6,
|
||||
PPC::R7, PPC::R8, PPC::R9, PPC::R10,
|
||||
};
|
||||
const unsigned NumArgRegs = array_lengthof(ArgRegs);
|
||||
|
||||
unsigned RegNum = State.getFirstUnallocated(ArgRegs);
|
||||
int RegsLeft = NumArgRegs - RegNum;
|
||||
|
||||
// Skip if there is not enough registers left for long double type (4 gpr regs
|
||||
// in soft float mode) and put long double argument on the stack.
|
||||
if (RegNum != NumArgRegs && RegsLeft < 4) {
|
||||
for (int i = 0; i < RegsLeft; i++) {
|
||||
State.AllocateReg(ArgRegs[RegNum + i]);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool llvm::CC_PPC32_SVR4_Custom_AlignFPArgRegs(unsigned &ValNo, MVT &ValVT,
|
||||
MVT &LocVT,
|
||||
CCValAssign::LocInfo &LocInfo,
|
||||
ISD::ArgFlagsTy &ArgFlags,
|
||||
CCState &State) {
|
||||
static const MCPhysReg ArgRegs[] = {
|
||||
PPC::F1, PPC::F2, PPC::F3, PPC::F4, PPC::F5, PPC::F6, PPC::F7,
|
||||
PPC::F8
|
||||
};
|
||||
|
||||
const unsigned NumArgRegs = array_lengthof(ArgRegs);
|
||||
|
||||
unsigned RegNum = State.getFirstUnallocated(ArgRegs);
|
||||
|
||||
// If there is only one Floating-point register left we need to put both f64
|
||||
// values of a split ppc_fp128 value on the stack.
|
||||
if (RegNum != NumArgRegs && ArgRegs[RegNum] == PPC::F8) {
|
||||
State.AllocateReg(ArgRegs[RegNum]);
|
||||
}
|
||||
|
||||
// Always return false here, as this function only makes sure that the two f64
|
||||
// values a ppc_fp128 value is split into are both passed in registers or both
|
||||
// passed on the stack and does not actually allocate a register for the
|
||||
// current argument.
|
||||
return false;
|
||||
}
|
||||
|
||||
/// FPR - The set of FP registers that should be allocated for arguments,
|
||||
/// on Darwin.
|
||||
static const MCPhysReg FPR[] = {PPC::F1, PPC::F2, PPC::F3, PPC::F4, PPC::F5,
|
||||
|
@ -1136,8 +1136,6 @@ namespace llvm {
|
||||
int &RefinementSteps) const override;
|
||||
unsigned combineRepeatedFPDivisors() const override;
|
||||
|
||||
CCAssignFn *useFastISelCCs(unsigned Flag) const;
|
||||
|
||||
SDValue
|
||||
combineElementTruncationToVectorTruncation(SDNode *N,
|
||||
DAGCombinerInfo &DCI) const;
|
||||
@ -1168,30 +1166,6 @@ namespace llvm {
|
||||
|
||||
} // end namespace PPC
|
||||
|
||||
bool CC_PPC32_SVR4_Custom_Dummy(unsigned &ValNo, MVT &ValVT, MVT &LocVT,
|
||||
CCValAssign::LocInfo &LocInfo,
|
||||
ISD::ArgFlagsTy &ArgFlags,
|
||||
CCState &State);
|
||||
|
||||
bool CC_PPC32_SVR4_Custom_AlignArgRegs(unsigned &ValNo, MVT &ValVT,
|
||||
MVT &LocVT,
|
||||
CCValAssign::LocInfo &LocInfo,
|
||||
ISD::ArgFlagsTy &ArgFlags,
|
||||
CCState &State);
|
||||
|
||||
bool
|
||||
CC_PPC32_SVR4_Custom_SkipLastArgRegsPPCF128(unsigned &ValNo, MVT &ValVT,
|
||||
MVT &LocVT,
|
||||
CCValAssign::LocInfo &LocInfo,
|
||||
ISD::ArgFlagsTy &ArgFlags,
|
||||
CCState &State);
|
||||
|
||||
bool CC_PPC32_SVR4_Custom_AlignFPArgRegs(unsigned &ValNo, MVT &ValVT,
|
||||
MVT &LocVT,
|
||||
CCValAssign::LocInfo &LocInfo,
|
||||
ISD::ArgFlagsTy &ArgFlags,
|
||||
CCState &State);
|
||||
|
||||
bool isIntS16Immediate(SDNode *N, int16_t &Imm);
|
||||
bool isIntS16Immediate(SDValue Op, int16_t &Imm);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user