mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-13 20:32:21 +00:00
Add support for 64-bit calling convention.
This is far from complete, but it is enough to make it possible to write test cases using i64 arguments. Missing features: - Floating point arguments. - Receiving arguments on the stack. - Calls. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@178523 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
fcb25e60f5
commit
f37812e906
@ -22,6 +22,14 @@ def RetCC_Sparc32 : CallingConv<[
|
||||
CCIfType<[f64], CCAssignToReg<[D0, D1]>>
|
||||
]>;
|
||||
|
||||
// Sparc 64-bit C return-value convention.
|
||||
def RetCC_Sparc64 : CallingConv<[
|
||||
CCIfType<[i32], CCPromoteToType<i64>>,
|
||||
CCIfType<[i64], CCAssignToReg<[I0, I1, I2, I3, I4, I5]>>,
|
||||
CCIfType<[f32], CCAssignToReg<[F0, F1, F2, F3]>>,
|
||||
CCIfType<[f64], CCAssignToReg<[D0, D1]>>
|
||||
]>;
|
||||
|
||||
// Sparc 32-bit C Calling convention.
|
||||
def CC_Sparc32 : CallingConv<[
|
||||
//Custom assign SRet to [sp+64].
|
||||
@ -34,3 +42,15 @@ def CC_Sparc32 : CallingConv<[
|
||||
// Alternatively, they are assigned to the stack in 4-byte aligned units.
|
||||
CCAssignToStack<4, 4>
|
||||
]>;
|
||||
|
||||
// Sparc 64-bit C Calling convention.
|
||||
def CC_Sparc64 : CallingConv<[
|
||||
// All integers are promoted to i64 by the caller.
|
||||
CCIfType<[i32], CCPromoteToType<i64>>,
|
||||
// Integer arguments get passed in integer registers if there is space.
|
||||
CCIfType<[i64], CCAssignToReg<[I0, I1, I2, I3, I4, I5]>>,
|
||||
// FIXME: Floating point arguments.
|
||||
|
||||
// Alternatively, they are assigned to the stack in 8-byte aligned units.
|
||||
CCAssignToStack<8, 8>
|
||||
]>;
|
||||
|
@ -93,7 +93,8 @@ SparcTargetLowering::LowerReturn(SDValue Chain,
|
||||
DAG.getTarget(), RVLocs, *DAG.getContext());
|
||||
|
||||
// Analize return values.
|
||||
CCInfo.AnalyzeReturn(Outs, RetCC_Sparc32);
|
||||
CCInfo.AnalyzeReturn(Outs, Subtarget->is64Bit() ?
|
||||
RetCC_Sparc64 : RetCC_Sparc32);
|
||||
|
||||
SDValue Flag;
|
||||
SmallVector<SDValue, 4> RetOps(1, Chain);
|
||||
@ -138,18 +139,32 @@ SparcTargetLowering::LowerReturn(SDValue Chain,
|
||||
&RetOps[0], RetOps.size());
|
||||
}
|
||||
|
||||
/// LowerFormalArguments - V8 uses a very simple ABI, where all values are
|
||||
SDValue SparcTargetLowering::
|
||||
LowerFormalArguments(SDValue Chain,
|
||||
CallingConv::ID CallConv,
|
||||
bool IsVarArg,
|
||||
const SmallVectorImpl<ISD::InputArg> &Ins,
|
||||
DebugLoc DL,
|
||||
SelectionDAG &DAG,
|
||||
SmallVectorImpl<SDValue> &InVals) const {
|
||||
if (Subtarget->is64Bit())
|
||||
return LowerFormalArguments_64(Chain, CallConv, IsVarArg, Ins,
|
||||
DL, DAG, InVals);
|
||||
return LowerFormalArguments_32(Chain, CallConv, IsVarArg, Ins,
|
||||
DL, DAG, InVals);
|
||||
}
|
||||
|
||||
/// LowerFormalArguments32 - V8 uses a very simple ABI, where all values are
|
||||
/// passed in either one or two GPRs, including FP values. TODO: we should
|
||||
/// pass FP values in FP registers for fastcc functions.
|
||||
SDValue
|
||||
SparcTargetLowering::LowerFormalArguments(SDValue Chain,
|
||||
CallingConv::ID CallConv, bool isVarArg,
|
||||
const SmallVectorImpl<ISD::InputArg>
|
||||
&Ins,
|
||||
DebugLoc dl, SelectionDAG &DAG,
|
||||
SmallVectorImpl<SDValue> &InVals)
|
||||
const {
|
||||
|
||||
SDValue SparcTargetLowering::
|
||||
LowerFormalArguments_32(SDValue Chain,
|
||||
CallingConv::ID CallConv,
|
||||
bool isVarArg,
|
||||
const SmallVectorImpl<ISD::InputArg> &Ins,
|
||||
DebugLoc dl,
|
||||
SelectionDAG &DAG,
|
||||
SmallVectorImpl<SDValue> &InVals) const {
|
||||
MachineFunction &MF = DAG.getMachineFunction();
|
||||
MachineRegisterInfo &RegInfo = MF.getRegInfo();
|
||||
SparcMachineFunctionInfo *FuncInfo = MF.getInfo<SparcMachineFunctionInfo>();
|
||||
@ -341,6 +356,63 @@ SparcTargetLowering::LowerFormalArguments(SDValue Chain,
|
||||
return Chain;
|
||||
}
|
||||
|
||||
// Lower formal arguments for the 64 bit ABI.
|
||||
SDValue SparcTargetLowering::
|
||||
LowerFormalArguments_64(SDValue Chain,
|
||||
CallingConv::ID CallConv,
|
||||
bool IsVarArg,
|
||||
const SmallVectorImpl<ISD::InputArg> &Ins,
|
||||
DebugLoc DL,
|
||||
SelectionDAG &DAG,
|
||||
SmallVectorImpl<SDValue> &InVals) const {
|
||||
MachineFunction &MF = DAG.getMachineFunction();
|
||||
|
||||
// Analyze arguments according to CC_Sparc64.
|
||||
SmallVector<CCValAssign, 16> ArgLocs;
|
||||
CCState CCInfo(CallConv, IsVarArg, DAG.getMachineFunction(),
|
||||
getTargetMachine(), ArgLocs, *DAG.getContext());
|
||||
CCInfo.AnalyzeFormalArguments(Ins, CC_Sparc64);
|
||||
|
||||
for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
|
||||
CCValAssign &VA = ArgLocs[i];
|
||||
if (VA.isRegLoc()) {
|
||||
// This argument is passed in a register.
|
||||
// All integer register arguments are promoted by the caller to i64.
|
||||
|
||||
// Create a virtual register for the promoted live-in value.
|
||||
unsigned VReg = MF.addLiveIn(VA.getLocReg(),
|
||||
getRegClassFor(VA.getLocVT()));
|
||||
SDValue Arg = DAG.getCopyFromReg(Chain, DL, VReg, VA.getLocVT());
|
||||
|
||||
// The caller promoted the argument, so insert an Assert?ext SDNode so we
|
||||
// won't promote the value again in this function.
|
||||
switch (VA.getLocInfo()) {
|
||||
case CCValAssign::SExt:
|
||||
Arg = DAG.getNode(ISD::AssertSext, DL, VA.getLocVT(), Arg,
|
||||
DAG.getValueType(VA.getValVT()));
|
||||
break;
|
||||
case CCValAssign::ZExt:
|
||||
Arg = DAG.getNode(ISD::AssertZext, DL, VA.getLocVT(), Arg,
|
||||
DAG.getValueType(VA.getValVT()));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// Truncate the register down to the argument type.
|
||||
if (VA.isExtInLoc())
|
||||
Arg = DAG.getNode(ISD::TRUNCATE, DL, VA.getValVT(), Arg);
|
||||
|
||||
InVals.push_back(Arg);
|
||||
continue;
|
||||
}
|
||||
|
||||
// The registers are exhausted. This argument was passed on the stack.
|
||||
assert(VA.isMemLoc());
|
||||
}
|
||||
return Chain;
|
||||
}
|
||||
|
||||
SDValue
|
||||
SparcTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
|
||||
SmallVectorImpl<SDValue> &InVals) const {
|
||||
|
@ -77,6 +77,18 @@ namespace llvm {
|
||||
const SmallVectorImpl<ISD::InputArg> &Ins,
|
||||
DebugLoc dl, SelectionDAG &DAG,
|
||||
SmallVectorImpl<SDValue> &InVals) const;
|
||||
SDValue LowerFormalArguments_32(SDValue Chain,
|
||||
CallingConv::ID CallConv,
|
||||
bool isVarArg,
|
||||
const SmallVectorImpl<ISD::InputArg> &Ins,
|
||||
DebugLoc dl, SelectionDAG &DAG,
|
||||
SmallVectorImpl<SDValue> &InVals) const;
|
||||
SDValue LowerFormalArguments_64(SDValue Chain,
|
||||
CallingConv::ID CallConv,
|
||||
bool isVarArg,
|
||||
const SmallVectorImpl<ISD::InputArg> &Ins,
|
||||
DebugLoc dl, SelectionDAG &DAG,
|
||||
SmallVectorImpl<SDValue> &InVals) const;
|
||||
|
||||
virtual SDValue
|
||||
LowerCall(TargetLowering::CallLoweringInfo &CLI,
|
||||
|
7
test/CodeGen/SPARC/64bit.ll
Normal file
7
test/CodeGen/SPARC/64bit.ll
Normal file
@ -0,0 +1,7 @@
|
||||
; RUN: llc < %s -march=sparcv9 | FileCheck %s
|
||||
|
||||
; CHECK: ret2:
|
||||
; CHECK: or %g0, %i1, %i0
|
||||
define i64 @ret2(i64 %a, i64 %b) {
|
||||
ret i64 %b
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
; RUN: llc < %s -march=sparc -mattr=-v9 | not grep popc
|
||||
; RUN: llc < %s -march=sparcv9 -mattr=v9 | grep popc
|
||||
; RUN: llc < %s -march=sparc -mattr=+v9 | grep popc
|
||||
|
||||
declare i32 @llvm.ctpop.i32(i32)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user