forked from OSchip/llvm-project
Split out some of the calling convention bits so that they can be
used for fast-isel. llvm-svn: 113652
This commit is contained in:
parent
8c35fb0739
commit
1c06917f15
|
@ -0,0 +1,160 @@
|
|||
//===-- ARMCallingConv.h - ARM Custom Calling Convention Routines ---------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file contains the custom routines for the ARM Calling Convention that
|
||||
// aren't done by tablegen.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef ARMCALLINGCONV_H
|
||||
#define ARMCALLINGCONV_H
|
||||
|
||||
#include "llvm/CallingConv.h"
|
||||
#include "llvm/CodeGen/CallingConvLower.h"
|
||||
#include "llvm/Target/TargetInstrInfo.h"
|
||||
#include "ARMBaseInstrInfo.h"
|
||||
#include "ARMRegisterInfo.h"
|
||||
#include "ARMSubtarget.h"
|
||||
#include "ARM.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
// APCS f64 is in register pairs, possibly split to stack
|
||||
static bool f64AssignAPCS(unsigned &ValNo, EVT &ValVT, EVT &LocVT,
|
||||
CCValAssign::LocInfo &LocInfo,
|
||||
CCState &State, bool CanFail) {
|
||||
static const unsigned RegList[] = { ARM::R0, ARM::R1, ARM::R2, ARM::R3 };
|
||||
|
||||
// Try to get the first register.
|
||||
if (unsigned Reg = State.AllocateReg(RegList, 4))
|
||||
State.addLoc(CCValAssign::getCustomReg(ValNo, ValVT, Reg, LocVT, LocInfo));
|
||||
else {
|
||||
// For the 2nd half of a v2f64, do not fail.
|
||||
if (CanFail)
|
||||
return false;
|
||||
|
||||
// Put the whole thing on the stack.
|
||||
State.addLoc(CCValAssign::getCustomMem(ValNo, ValVT,
|
||||
State.AllocateStack(8, 4),
|
||||
LocVT, LocInfo));
|
||||
return true;
|
||||
}
|
||||
|
||||
// Try to get the second register.
|
||||
if (unsigned Reg = State.AllocateReg(RegList, 4))
|
||||
State.addLoc(CCValAssign::getCustomReg(ValNo, ValVT, Reg, LocVT, LocInfo));
|
||||
else
|
||||
State.addLoc(CCValAssign::getCustomMem(ValNo, ValVT,
|
||||
State.AllocateStack(4, 4),
|
||||
LocVT, LocInfo));
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool CC_ARM_APCS_Custom_f64(unsigned &ValNo, EVT &ValVT, EVT &LocVT,
|
||||
CCValAssign::LocInfo &LocInfo,
|
||||
ISD::ArgFlagsTy &ArgFlags,
|
||||
CCState &State) {
|
||||
if (!f64AssignAPCS(ValNo, ValVT, LocVT, LocInfo, State, true))
|
||||
return false;
|
||||
if (LocVT == MVT::v2f64 &&
|
||||
!f64AssignAPCS(ValNo, ValVT, LocVT, LocInfo, State, false))
|
||||
return false;
|
||||
return true; // we handled it
|
||||
}
|
||||
|
||||
// AAPCS f64 is in aligned register pairs
|
||||
static bool f64AssignAAPCS(unsigned &ValNo, EVT &ValVT, EVT &LocVT,
|
||||
CCValAssign::LocInfo &LocInfo,
|
||||
CCState &State, bool CanFail) {
|
||||
static const unsigned HiRegList[] = { ARM::R0, ARM::R2 };
|
||||
static const unsigned LoRegList[] = { ARM::R1, ARM::R3 };
|
||||
static const unsigned ShadowRegList[] = { ARM::R0, ARM::R1 };
|
||||
|
||||
unsigned Reg = State.AllocateReg(HiRegList, ShadowRegList, 2);
|
||||
if (Reg == 0) {
|
||||
// For the 2nd half of a v2f64, do not just fail.
|
||||
if (CanFail)
|
||||
return false;
|
||||
|
||||
// Put the whole thing on the stack.
|
||||
State.addLoc(CCValAssign::getCustomMem(ValNo, ValVT,
|
||||
State.AllocateStack(8, 8),
|
||||
LocVT, LocInfo));
|
||||
return true;
|
||||
}
|
||||
|
||||
unsigned i;
|
||||
for (i = 0; i < 2; ++i)
|
||||
if (HiRegList[i] == Reg)
|
||||
break;
|
||||
|
||||
unsigned T = State.AllocateReg(LoRegList[i]);
|
||||
(void)T;
|
||||
assert(T == LoRegList[i] && "Could not allocate register");
|
||||
|
||||
State.addLoc(CCValAssign::getCustomReg(ValNo, ValVT, Reg, LocVT, LocInfo));
|
||||
State.addLoc(CCValAssign::getCustomReg(ValNo, ValVT, LoRegList[i],
|
||||
LocVT, LocInfo));
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool CC_ARM_AAPCS_Custom_f64(unsigned &ValNo, EVT &ValVT, EVT &LocVT,
|
||||
CCValAssign::LocInfo &LocInfo,
|
||||
ISD::ArgFlagsTy &ArgFlags,
|
||||
CCState &State) {
|
||||
if (!f64AssignAAPCS(ValNo, ValVT, LocVT, LocInfo, State, true))
|
||||
return false;
|
||||
if (LocVT == MVT::v2f64 &&
|
||||
!f64AssignAAPCS(ValNo, ValVT, LocVT, LocInfo, State, false))
|
||||
return false;
|
||||
return true; // we handled it
|
||||
}
|
||||
|
||||
static bool f64RetAssign(unsigned &ValNo, EVT &ValVT, EVT &LocVT,
|
||||
CCValAssign::LocInfo &LocInfo, CCState &State) {
|
||||
static const unsigned HiRegList[] = { ARM::R0, ARM::R2 };
|
||||
static const unsigned LoRegList[] = { ARM::R1, ARM::R3 };
|
||||
|
||||
unsigned Reg = State.AllocateReg(HiRegList, LoRegList, 2);
|
||||
if (Reg == 0)
|
||||
return false; // we didn't handle it
|
||||
|
||||
unsigned i;
|
||||
for (i = 0; i < 2; ++i)
|
||||
if (HiRegList[i] == Reg)
|
||||
break;
|
||||
|
||||
State.addLoc(CCValAssign::getCustomReg(ValNo, ValVT, Reg, LocVT, LocInfo));
|
||||
State.addLoc(CCValAssign::getCustomReg(ValNo, ValVT, LoRegList[i],
|
||||
LocVT, LocInfo));
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool RetCC_ARM_APCS_Custom_f64(unsigned &ValNo, EVT &ValVT, EVT &LocVT,
|
||||
CCValAssign::LocInfo &LocInfo,
|
||||
ISD::ArgFlagsTy &ArgFlags,
|
||||
CCState &State) {
|
||||
if (!f64RetAssign(ValNo, ValVT, LocVT, LocInfo, State))
|
||||
return false;
|
||||
if (LocVT == MVT::v2f64 && !f64RetAssign(ValNo, ValVT, LocVT, LocInfo, State))
|
||||
return false;
|
||||
return true; // we handled it
|
||||
}
|
||||
|
||||
static bool RetCC_ARM_AAPCS_Custom_f64(unsigned &ValNo, EVT &ValVT, EVT &LocVT,
|
||||
CCValAssign::LocInfo &LocInfo,
|
||||
ISD::ArgFlagsTy &ArgFlags,
|
||||
CCState &State) {
|
||||
return RetCC_ARM_APCS_Custom_f64(ValNo, ValVT, LocVT, LocInfo, ArgFlags,
|
||||
State);
|
||||
}
|
||||
|
||||
} // End llvm namespace
|
||||
|
||||
#endif
|
|
@ -15,6 +15,7 @@
|
|||
#define DEBUG_TYPE "arm-isel"
|
||||
#include "ARM.h"
|
||||
#include "ARMAddressingModes.h"
|
||||
#include "ARMCallingConv.h"
|
||||
#include "ARMConstantPoolValue.h"
|
||||
#include "ARMISelLowering.h"
|
||||
#include "ARMMachineFunctionInfo.h"
|
||||
|
@ -79,23 +80,6 @@ EnableARMCodePlacement("arm-code-placement", cl::Hidden,
|
|||
cl::desc("Enable code placement pass for ARM"),
|
||||
cl::init(false));
|
||||
|
||||
static bool CC_ARM_APCS_Custom_f64(unsigned &ValNo, EVT &ValVT, EVT &LocVT,
|
||||
CCValAssign::LocInfo &LocInfo,
|
||||
ISD::ArgFlagsTy &ArgFlags,
|
||||
CCState &State);
|
||||
static bool CC_ARM_AAPCS_Custom_f64(unsigned &ValNo, EVT &ValVT, EVT &LocVT,
|
||||
CCValAssign::LocInfo &LocInfo,
|
||||
ISD::ArgFlagsTy &ArgFlags,
|
||||
CCState &State);
|
||||
static bool RetCC_ARM_APCS_Custom_f64(unsigned &ValNo, EVT &ValVT, EVT &LocVT,
|
||||
CCValAssign::LocInfo &LocInfo,
|
||||
ISD::ArgFlagsTy &ArgFlags,
|
||||
CCState &State);
|
||||
static bool RetCC_ARM_AAPCS_Custom_f64(unsigned &ValNo, EVT &ValVT, EVT &LocVT,
|
||||
CCValAssign::LocInfo &LocInfo,
|
||||
ISD::ArgFlagsTy &ArgFlags,
|
||||
CCState &State);
|
||||
|
||||
void ARMTargetLowering::addTypeForNEON(EVT VT, EVT PromotedLdStVT,
|
||||
EVT PromotedBitwiseVT) {
|
||||
if (VT != PromotedLdStVT) {
|
||||
|
@ -829,136 +813,6 @@ static void FPCCToARMCC(ISD::CondCode CC, ARMCC::CondCodes &CondCode,
|
|||
|
||||
#include "ARMGenCallingConv.inc"
|
||||
|
||||
// APCS f64 is in register pairs, possibly split to stack
|
||||
static bool f64AssignAPCS(unsigned &ValNo, EVT &ValVT, EVT &LocVT,
|
||||
CCValAssign::LocInfo &LocInfo,
|
||||
CCState &State, bool CanFail) {
|
||||
static const unsigned RegList[] = { ARM::R0, ARM::R1, ARM::R2, ARM::R3 };
|
||||
|
||||
// Try to get the first register.
|
||||
if (unsigned Reg = State.AllocateReg(RegList, 4))
|
||||
State.addLoc(CCValAssign::getCustomReg(ValNo, ValVT, Reg, LocVT, LocInfo));
|
||||
else {
|
||||
// For the 2nd half of a v2f64, do not fail.
|
||||
if (CanFail)
|
||||
return false;
|
||||
|
||||
// Put the whole thing on the stack.
|
||||
State.addLoc(CCValAssign::getCustomMem(ValNo, ValVT,
|
||||
State.AllocateStack(8, 4),
|
||||
LocVT, LocInfo));
|
||||
return true;
|
||||
}
|
||||
|
||||
// Try to get the second register.
|
||||
if (unsigned Reg = State.AllocateReg(RegList, 4))
|
||||
State.addLoc(CCValAssign::getCustomReg(ValNo, ValVT, Reg, LocVT, LocInfo));
|
||||
else
|
||||
State.addLoc(CCValAssign::getCustomMem(ValNo, ValVT,
|
||||
State.AllocateStack(4, 4),
|
||||
LocVT, LocInfo));
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool CC_ARM_APCS_Custom_f64(unsigned &ValNo, EVT &ValVT, EVT &LocVT,
|
||||
CCValAssign::LocInfo &LocInfo,
|
||||
ISD::ArgFlagsTy &ArgFlags,
|
||||
CCState &State) {
|
||||
if (!f64AssignAPCS(ValNo, ValVT, LocVT, LocInfo, State, true))
|
||||
return false;
|
||||
if (LocVT == MVT::v2f64 &&
|
||||
!f64AssignAPCS(ValNo, ValVT, LocVT, LocInfo, State, false))
|
||||
return false;
|
||||
return true; // we handled it
|
||||
}
|
||||
|
||||
// AAPCS f64 is in aligned register pairs
|
||||
static bool f64AssignAAPCS(unsigned &ValNo, EVT &ValVT, EVT &LocVT,
|
||||
CCValAssign::LocInfo &LocInfo,
|
||||
CCState &State, bool CanFail) {
|
||||
static const unsigned HiRegList[] = { ARM::R0, ARM::R2 };
|
||||
static const unsigned LoRegList[] = { ARM::R1, ARM::R3 };
|
||||
static const unsigned ShadowRegList[] = { ARM::R0, ARM::R1 };
|
||||
|
||||
unsigned Reg = State.AllocateReg(HiRegList, ShadowRegList, 2);
|
||||
if (Reg == 0) {
|
||||
// For the 2nd half of a v2f64, do not just fail.
|
||||
if (CanFail)
|
||||
return false;
|
||||
|
||||
// Put the whole thing on the stack.
|
||||
State.addLoc(CCValAssign::getCustomMem(ValNo, ValVT,
|
||||
State.AllocateStack(8, 8),
|
||||
LocVT, LocInfo));
|
||||
return true;
|
||||
}
|
||||
|
||||
unsigned i;
|
||||
for (i = 0; i < 2; ++i)
|
||||
if (HiRegList[i] == Reg)
|
||||
break;
|
||||
|
||||
unsigned T = State.AllocateReg(LoRegList[i]);
|
||||
(void)T;
|
||||
assert(T == LoRegList[i] && "Could not allocate register");
|
||||
|
||||
State.addLoc(CCValAssign::getCustomReg(ValNo, ValVT, Reg, LocVT, LocInfo));
|
||||
State.addLoc(CCValAssign::getCustomReg(ValNo, ValVT, LoRegList[i],
|
||||
LocVT, LocInfo));
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool CC_ARM_AAPCS_Custom_f64(unsigned &ValNo, EVT &ValVT, EVT &LocVT,
|
||||
CCValAssign::LocInfo &LocInfo,
|
||||
ISD::ArgFlagsTy &ArgFlags,
|
||||
CCState &State) {
|
||||
if (!f64AssignAAPCS(ValNo, ValVT, LocVT, LocInfo, State, true))
|
||||
return false;
|
||||
if (LocVT == MVT::v2f64 &&
|
||||
!f64AssignAAPCS(ValNo, ValVT, LocVT, LocInfo, State, false))
|
||||
return false;
|
||||
return true; // we handled it
|
||||
}
|
||||
|
||||
static bool f64RetAssign(unsigned &ValNo, EVT &ValVT, EVT &LocVT,
|
||||
CCValAssign::LocInfo &LocInfo, CCState &State) {
|
||||
static const unsigned HiRegList[] = { ARM::R0, ARM::R2 };
|
||||
static const unsigned LoRegList[] = { ARM::R1, ARM::R3 };
|
||||
|
||||
unsigned Reg = State.AllocateReg(HiRegList, LoRegList, 2);
|
||||
if (Reg == 0)
|
||||
return false; // we didn't handle it
|
||||
|
||||
unsigned i;
|
||||
for (i = 0; i < 2; ++i)
|
||||
if (HiRegList[i] == Reg)
|
||||
break;
|
||||
|
||||
State.addLoc(CCValAssign::getCustomReg(ValNo, ValVT, Reg, LocVT, LocInfo));
|
||||
State.addLoc(CCValAssign::getCustomReg(ValNo, ValVT, LoRegList[i],
|
||||
LocVT, LocInfo));
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool RetCC_ARM_APCS_Custom_f64(unsigned &ValNo, EVT &ValVT, EVT &LocVT,
|
||||
CCValAssign::LocInfo &LocInfo,
|
||||
ISD::ArgFlagsTy &ArgFlags,
|
||||
CCState &State) {
|
||||
if (!f64RetAssign(ValNo, ValVT, LocVT, LocInfo, State))
|
||||
return false;
|
||||
if (LocVT == MVT::v2f64 && !f64RetAssign(ValNo, ValVT, LocVT, LocInfo, State))
|
||||
return false;
|
||||
return true; // we handled it
|
||||
}
|
||||
|
||||
static bool RetCC_ARM_AAPCS_Custom_f64(unsigned &ValNo, EVT &ValVT, EVT &LocVT,
|
||||
CCValAssign::LocInfo &LocInfo,
|
||||
ISD::ArgFlagsTy &ArgFlags,
|
||||
CCState &State) {
|
||||
return RetCC_ARM_APCS_Custom_f64(ValNo, ValVT, LocVT, LocInfo, ArgFlags,
|
||||
State);
|
||||
}
|
||||
|
||||
/// CCAssignFnForNode - Selects the correct CCAssignFn for a the
|
||||
/// given CallingConvention value.
|
||||
CCAssignFn *ARMTargetLowering::CCAssignFnForNode(CallingConv::ID CC,
|
||||
|
|
Loading…
Reference in New Issue