Skip to content

Commit

Permalink
[tablegen] Add CustomCallingConv and use it to tablegen-erate the out…
Browse files Browse the repository at this point in the history
…ermost parts of the Mips O32 implementation

Summary:
CustomCallingConv is simply a CallingConv that tablegen should not generate the
implementation for. It allows regular CallingConv's to delegate to these custom
functions. This is (currently) necessary for Mips and we cannot use CCCustom
without having to adapt to the different API that CCCustom uses.

This brings us a bit closer to being able to remove
MipsCC::analyzeCallOperands and MipsCC::analyzeFormalArguments in favour of
the common implementation.

No functional change to the targets.

Reviewers: vmedic

Reviewed By: vmedic

Subscribers: vmedic, llvm-commits

Differential Revision: http://reviews.llvm.org/D5965

llvm-svn: 223031
  • Loading branch information
dsandersllvm committed Dec 1, 2014
1 parent 728f55c commit 1486635
Show file tree
Hide file tree
Showing 5 changed files with 53 additions and 31 deletions.
7 changes: 7 additions & 0 deletions llvm/include/llvm/Target/TargetCallingConv.td
Expand Up @@ -147,6 +147,13 @@ class CCDelegateTo<CallingConv cc> : CCAction {
/// that the target supports.
class CallingConv<list<CCAction> actions> {
list<CCAction> Actions = actions;
bit Custom = 0;
}

/// CustomCallingConv - An instance of this is used to declare calling
/// conventions that are implemented using a custom function of the same name.
class CustomCallingConv : CallingConv<[]> {
let Custom = 1;
}

/// CalleeSavedRegs - A list of callee saved registers for a given calling
Expand Down
24 changes: 24 additions & 0 deletions llvm/lib/Target/Mips/MipsCallingConv.td
Expand Up @@ -66,6 +66,14 @@ def RetCC_MipsO32 : CallingConv<[
CCIfType<[f64], CCIfSubtargetNot<"isFP64bit()", CCAssignToReg<[D0, D1]>>>
]>;

def CC_MipsO32_FP32 : CustomCallingConv;
def CC_MipsO32_FP64 : CustomCallingConv;

def CC_MipsO32_FP : CallingConv<[
CCIfSubtargetNot<"isFP64bit()", CCDelegateTo<CC_MipsO32_FP32>>,
CCIfSubtarget<"isFP64bit()", CCDelegateTo<CC_MipsO32_FP64>>
]>;

//===----------------------------------------------------------------------===//
// Mips N32/64 Calling Convention
//===----------------------------------------------------------------------===//
Expand Down Expand Up @@ -289,6 +297,22 @@ def RetCC_Mips : CallingConv<[
CCDelegateTo<RetCC_MipsO32>
]>;

def CC_Mips_FixedArg : CallingConv<[
CCIfCC<"CallingConv::Fast", CCDelegateTo<CC_Mips_FastCC>>,

// FIXME: There wasn't an EABI case in the original code and it seems unlikely
// that it's the same as CC_MipsN
CCIfSubtarget<"isABI_O32()", CCDelegateTo<CC_MipsO32_FP>>,
CCDelegateTo<CC_MipsN>
]>;

def CC_Mips_VarArg : CallingConv<[
// FIXME: There wasn't an EABI case in the original code and it seems unlikely
// that it's the same as CC_MipsN_VarArg
CCIfSubtarget<"isABI_O32()", CCDelegateTo<CC_MipsO32_FP>>,
CCDelegateTo<CC_MipsN_VarArg>
]>;

//===----------------------------------------------------------------------===//
// Callee-saved register lists.
//===----------------------------------------------------------------------===//
Expand Down
19 changes: 5 additions & 14 deletions llvm/lib/Target/Mips/MipsISelLowering.cpp
Expand Up @@ -3528,7 +3528,7 @@ analyzeCallOperands(const SmallVectorImpl<ISD::OutputArg> &Args,
"CallingConv::Fast shouldn't be used for vararg functions.");

unsigned NumOpnds = Args.size();
llvm::CCAssignFn *FixedFn = fixedArgFn(), *VarFn = varArgFn();
llvm::CCAssignFn *FixedFn = fixedArgFn();

for (unsigned I = 0; I != NumOpnds; ++I) {
MVT ArgVT = Args[I].VT;
Expand All @@ -3541,7 +3541,7 @@ analyzeCallOperands(const SmallVectorImpl<ISD::OutputArg> &Args,
}

if (IsVarArg && !Args[I].IsFixed)
R = VarFn(I, ArgVT, ArgVT, CCValAssign::Full, ArgFlags, CCInfo);
R = CC_Mips_VarArg(I, ArgVT, ArgVT, CCValAssign::Full, ArgFlags, CCInfo);
else {
MVT RegVT = getRegVT(ArgVT, FuncArgs[Args[I].OrigArgIndex].Ty, CallNode,
IsSoftFloat);
Expand Down Expand Up @@ -3624,20 +3624,11 @@ const ArrayRef<MCPhysReg> MipsTargetLowering::MipsCC::intArgRegs() const {
}

llvm::CCAssignFn *MipsTargetLowering::MipsCC::fixedArgFn() const {
if (CallConv == CallingConv::Fast)
return CC_Mips_FastCC;

if (SpecialCallingConv == Mips16RetHelperConv)
if (CallConv != CallingConv::Fast &&
SpecialCallingConv == Mips16RetHelperConv)
return CC_Mips16RetHelper;
return Subtarget.isABI_O32()
? (Subtarget.isFP64bit() ? CC_MipsO32_FP64 : CC_MipsO32_FP32)
: CC_MipsN;
}

llvm::CCAssignFn *MipsTargetLowering::MipsCC::varArgFn() const {
return Subtarget.isABI_O32()
? (Subtarget.isFP64bit() ? CC_MipsO32_FP64 : CC_MipsO32_FP32)
: CC_MipsN_VarArg;
return CC_Mips_FixedArg;
}

const MCPhysReg *MipsTargetLowering::MipsCC::shadowRegs() const {
Expand Down
3 changes: 0 additions & 3 deletions llvm/lib/Target/Mips/MipsISelLowering.h
Expand Up @@ -395,9 +395,6 @@ namespace llvm {
/// Return the function that analyzes fixed argument list functions.
llvm::CCAssignFn *fixedArgFn() const;

/// Return the function that analyzes variable argument list functions.
llvm::CCAssignFn *varArgFn() const;

const MCPhysReg *shadowRegs() const;

void allocateRegs(ByValArgInfo &ByVal, unsigned ByValSize,
Expand Down
31 changes: 17 additions & 14 deletions llvm/utils/TableGen/CallingConvEmitter.cpp
Expand Up @@ -35,23 +35,26 @@ class CallingConvEmitter {
} // End anonymous namespace

void CallingConvEmitter::run(raw_ostream &O) {

std::vector<Record*> CCs = Records.getAllDerivedDefinitions("CallingConv");

// Emit prototypes for all of the CC's so that they can forward ref each
// other.

// Emit prototypes for all of the non-custom CC's so that they can forward ref
// each other.
for (unsigned i = 0, e = CCs.size(); i != e; ++i) {
if (!CCs[i]->getValueAsBit("Custom")) {
O << "static bool " << CCs[i]->getName()
<< "(unsigned ValNo, MVT ValVT,\n"
<< std::string(CCs[i]->getName().size() + 13, ' ')
<< "MVT LocVT, CCValAssign::LocInfo LocInfo,\n"
<< std::string(CCs[i]->getName().size() + 13, ' ')
<< "ISD::ArgFlagsTy ArgFlags, CCState &State);\n";
}
}

// Emit each non-custom calling convention description in full.
for (unsigned i = 0, e = CCs.size(); i != e; ++i) {
O << "static bool " << CCs[i]->getName()
<< "(unsigned ValNo, MVT ValVT,\n"
<< std::string(CCs[i]->getName().size()+13, ' ')
<< "MVT LocVT, CCValAssign::LocInfo LocInfo,\n"
<< std::string(CCs[i]->getName().size()+13, ' ')
<< "ISD::ArgFlagsTy ArgFlags, CCState &State);\n";
if (!CCs[i]->getValueAsBit("Custom"))
EmitCallingConv(CCs[i], O);
}

// Emit each calling convention description in full.
for (unsigned i = 0, e = CCs.size(); i != e; ++i)
EmitCallingConv(CCs[i], O);
}


Expand Down

0 comments on commit 1486635

Please sign in to comment.