mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-28 21:34:23 +00:00
CodeGen support for aggregate-value function arguments.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@52156 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
98301c0774
commit
f5025cfa68
@ -4573,47 +4573,53 @@ TargetLowering::LowerArguments(Function &F, SelectionDAG &DAG) {
|
|||||||
unsigned j = 1;
|
unsigned j = 1;
|
||||||
for (Function::arg_iterator I = F.arg_begin(), E = F.arg_end();
|
for (Function::arg_iterator I = F.arg_begin(), E = F.arg_end();
|
||||||
I != E; ++I, ++j) {
|
I != E; ++I, ++j) {
|
||||||
MVT VT = getValueType(I->getType());
|
SmallVector<MVT, 4> ValueVTs;
|
||||||
ISD::ArgFlagsTy Flags;
|
ComputeValueVTs(*this, I->getType(), ValueVTs);
|
||||||
unsigned OriginalAlignment =
|
for (unsigned Value = 0, NumValues = ValueVTs.size();
|
||||||
getTargetData()->getABITypeAlignment(I->getType());
|
Value != NumValues; ++Value) {
|
||||||
|
MVT VT = ValueVTs[Value];
|
||||||
|
const Type *ArgTy = VT.getTypeForMVT();
|
||||||
|
ISD::ArgFlagsTy Flags;
|
||||||
|
unsigned OriginalAlignment =
|
||||||
|
getTargetData()->getABITypeAlignment(ArgTy);
|
||||||
|
|
||||||
if (F.paramHasAttr(j, ParamAttr::ZExt))
|
if (F.paramHasAttr(j, ParamAttr::ZExt))
|
||||||
Flags.setZExt();
|
Flags.setZExt();
|
||||||
if (F.paramHasAttr(j, ParamAttr::SExt))
|
if (F.paramHasAttr(j, ParamAttr::SExt))
|
||||||
Flags.setSExt();
|
Flags.setSExt();
|
||||||
if (F.paramHasAttr(j, ParamAttr::InReg))
|
if (F.paramHasAttr(j, ParamAttr::InReg))
|
||||||
Flags.setInReg();
|
Flags.setInReg();
|
||||||
if (F.paramHasAttr(j, ParamAttr::StructRet))
|
if (F.paramHasAttr(j, ParamAttr::StructRet))
|
||||||
Flags.setSRet();
|
Flags.setSRet();
|
||||||
if (F.paramHasAttr(j, ParamAttr::ByVal)) {
|
if (F.paramHasAttr(j, ParamAttr::ByVal)) {
|
||||||
Flags.setByVal();
|
Flags.setByVal();
|
||||||
const PointerType *Ty = cast<PointerType>(I->getType());
|
const PointerType *Ty = cast<PointerType>(I->getType());
|
||||||
const Type *ElementTy = Ty->getElementType();
|
const Type *ElementTy = Ty->getElementType();
|
||||||
unsigned FrameAlign = getByValTypeAlignment(ElementTy);
|
unsigned FrameAlign = getByValTypeAlignment(ElementTy);
|
||||||
unsigned FrameSize = getTargetData()->getABITypeSize(ElementTy);
|
unsigned FrameSize = getTargetData()->getABITypeSize(ElementTy);
|
||||||
// For ByVal, alignment should be passed from FE. BE will guess if
|
// For ByVal, alignment should be passed from FE. BE will guess if
|
||||||
// this info is not there but there are cases it cannot get right.
|
// this info is not there but there are cases it cannot get right.
|
||||||
if (F.getParamAlignment(j))
|
if (F.getParamAlignment(j))
|
||||||
FrameAlign = F.getParamAlignment(j);
|
FrameAlign = F.getParamAlignment(j);
|
||||||
Flags.setByValAlign(FrameAlign);
|
Flags.setByValAlign(FrameAlign);
|
||||||
Flags.setByValSize(FrameSize);
|
Flags.setByValSize(FrameSize);
|
||||||
}
|
}
|
||||||
if (F.paramHasAttr(j, ParamAttr::Nest))
|
if (F.paramHasAttr(j, ParamAttr::Nest))
|
||||||
Flags.setNest();
|
Flags.setNest();
|
||||||
Flags.setOrigAlign(OriginalAlignment);
|
Flags.setOrigAlign(OriginalAlignment);
|
||||||
|
|
||||||
MVT RegisterVT = getRegisterType(VT);
|
MVT RegisterVT = getRegisterType(VT);
|
||||||
unsigned NumRegs = getNumRegisters(VT);
|
unsigned NumRegs = getNumRegisters(VT);
|
||||||
for (unsigned i = 0; i != NumRegs; ++i) {
|
for (unsigned i = 0; i != NumRegs; ++i) {
|
||||||
RetVals.push_back(RegisterVT);
|
RetVals.push_back(RegisterVT);
|
||||||
ISD::ArgFlagsTy MyFlags = Flags;
|
ISD::ArgFlagsTy MyFlags = Flags;
|
||||||
if (NumRegs > 1 && i == 0)
|
if (NumRegs > 1 && i == 0)
|
||||||
MyFlags.setSplit();
|
MyFlags.setSplit();
|
||||||
// if it isn't first piece, alignment must be 1
|
// if it isn't first piece, alignment must be 1
|
||||||
else if (i > 0)
|
else if (i > 0)
|
||||||
MyFlags.setOrigAlign(1);
|
MyFlags.setOrigAlign(1);
|
||||||
Ops.push_back(DAG.getArgFlags(MyFlags));
|
Ops.push_back(DAG.getArgFlags(MyFlags));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4646,22 +4652,27 @@ TargetLowering::LowerArguments(Function &F, SelectionDAG &DAG) {
|
|||||||
unsigned Idx = 1;
|
unsigned Idx = 1;
|
||||||
for (Function::arg_iterator I = F.arg_begin(), E = F.arg_end(); I != E;
|
for (Function::arg_iterator I = F.arg_begin(), E = F.arg_end(); I != E;
|
||||||
++I, ++Idx) {
|
++I, ++Idx) {
|
||||||
MVT VT = getValueType(I->getType());
|
SmallVector<MVT, 4> ValueVTs;
|
||||||
MVT PartVT = getRegisterType(VT);
|
ComputeValueVTs(*this, I->getType(), ValueVTs);
|
||||||
|
for (unsigned Value = 0, NumValues = ValueVTs.size();
|
||||||
|
Value != NumValues; ++Value) {
|
||||||
|
MVT VT = ValueVTs[Value];
|
||||||
|
MVT PartVT = getRegisterType(VT);
|
||||||
|
|
||||||
unsigned NumParts = getNumRegisters(VT);
|
unsigned NumParts = getNumRegisters(VT);
|
||||||
SmallVector<SDOperand, 4> Parts(NumParts);
|
SmallVector<SDOperand, 4> Parts(NumParts);
|
||||||
for (unsigned j = 0; j != NumParts; ++j)
|
for (unsigned j = 0; j != NumParts; ++j)
|
||||||
Parts[j] = SDOperand(Result, i++);
|
Parts[j] = SDOperand(Result, i++);
|
||||||
|
|
||||||
ISD::NodeType AssertOp = ISD::DELETED_NODE;
|
ISD::NodeType AssertOp = ISD::DELETED_NODE;
|
||||||
if (F.paramHasAttr(Idx, ParamAttr::SExt))
|
if (F.paramHasAttr(Idx, ParamAttr::SExt))
|
||||||
AssertOp = ISD::AssertSext;
|
AssertOp = ISD::AssertSext;
|
||||||
else if (F.paramHasAttr(Idx, ParamAttr::ZExt))
|
else if (F.paramHasAttr(Idx, ParamAttr::ZExt))
|
||||||
AssertOp = ISD::AssertZext;
|
AssertOp = ISD::AssertZext;
|
||||||
|
|
||||||
Ops.push_back(getCopyFromParts(DAG, &Parts[0], NumParts, PartVT, VT,
|
Ops.push_back(getCopyFromParts(DAG, &Parts[0], NumParts, PartVT, VT,
|
||||||
AssertOp));
|
AssertOp));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
assert(i == NumArgRegs && "Argument register count mismatch!");
|
assert(i == NumArgRegs && "Argument register count mismatch!");
|
||||||
return Ops;
|
return Ops;
|
||||||
@ -4687,59 +4698,65 @@ TargetLowering::LowerCallTo(SDOperand Chain, const Type *RetTy,
|
|||||||
|
|
||||||
// Handle all of the outgoing arguments.
|
// Handle all of the outgoing arguments.
|
||||||
for (unsigned i = 0, e = Args.size(); i != e; ++i) {
|
for (unsigned i = 0, e = Args.size(); i != e; ++i) {
|
||||||
MVT VT = getValueType(Args[i].Ty);
|
SmallVector<MVT, 4> ValueVTs;
|
||||||
SDOperand Op = Args[i].Node;
|
ComputeValueVTs(*this, Args[i].Ty, ValueVTs);
|
||||||
ISD::ArgFlagsTy Flags;
|
for (unsigned Value = 0, NumValues = ValueVTs.size();
|
||||||
unsigned OriginalAlignment =
|
Value != NumValues; ++Value) {
|
||||||
getTargetData()->getABITypeAlignment(Args[i].Ty);
|
MVT VT = ValueVTs[Value];
|
||||||
|
const Type *ArgTy = VT.getTypeForMVT();
|
||||||
|
SDOperand Op = SDOperand(Args[i].Node.Val, Args[i].Node.ResNo + Value);
|
||||||
|
ISD::ArgFlagsTy Flags;
|
||||||
|
unsigned OriginalAlignment =
|
||||||
|
getTargetData()->getABITypeAlignment(ArgTy);
|
||||||
|
|
||||||
if (Args[i].isZExt)
|
if (Args[i].isZExt)
|
||||||
Flags.setZExt();
|
Flags.setZExt();
|
||||||
if (Args[i].isSExt)
|
if (Args[i].isSExt)
|
||||||
Flags.setSExt();
|
Flags.setSExt();
|
||||||
if (Args[i].isInReg)
|
if (Args[i].isInReg)
|
||||||
Flags.setInReg();
|
Flags.setInReg();
|
||||||
if (Args[i].isSRet)
|
if (Args[i].isSRet)
|
||||||
Flags.setSRet();
|
Flags.setSRet();
|
||||||
if (Args[i].isByVal) {
|
if (Args[i].isByVal) {
|
||||||
Flags.setByVal();
|
Flags.setByVal();
|
||||||
const PointerType *Ty = cast<PointerType>(Args[i].Ty);
|
const PointerType *Ty = cast<PointerType>(Args[i].Ty);
|
||||||
const Type *ElementTy = Ty->getElementType();
|
const Type *ElementTy = Ty->getElementType();
|
||||||
unsigned FrameAlign = getByValTypeAlignment(ElementTy);
|
unsigned FrameAlign = getByValTypeAlignment(ElementTy);
|
||||||
unsigned FrameSize = getTargetData()->getABITypeSize(ElementTy);
|
unsigned FrameSize = getTargetData()->getABITypeSize(ElementTy);
|
||||||
// For ByVal, alignment should come from FE. BE will guess if this
|
// For ByVal, alignment should come from FE. BE will guess if this
|
||||||
// info is not there but there are cases it cannot get right.
|
// info is not there but there are cases it cannot get right.
|
||||||
if (Args[i].Alignment)
|
if (Args[i].Alignment)
|
||||||
FrameAlign = Args[i].Alignment;
|
FrameAlign = Args[i].Alignment;
|
||||||
Flags.setByValAlign(FrameAlign);
|
Flags.setByValAlign(FrameAlign);
|
||||||
Flags.setByValSize(FrameSize);
|
Flags.setByValSize(FrameSize);
|
||||||
}
|
}
|
||||||
if (Args[i].isNest)
|
if (Args[i].isNest)
|
||||||
Flags.setNest();
|
Flags.setNest();
|
||||||
Flags.setOrigAlign(OriginalAlignment);
|
Flags.setOrigAlign(OriginalAlignment);
|
||||||
|
|
||||||
MVT PartVT = getRegisterType(VT);
|
MVT PartVT = getRegisterType(VT);
|
||||||
unsigned NumParts = getNumRegisters(VT);
|
unsigned NumParts = getNumRegisters(VT);
|
||||||
SmallVector<SDOperand, 4> Parts(NumParts);
|
SmallVector<SDOperand, 4> Parts(NumParts);
|
||||||
ISD::NodeType ExtendKind = ISD::ANY_EXTEND;
|
ISD::NodeType ExtendKind = ISD::ANY_EXTEND;
|
||||||
|
|
||||||
if (Args[i].isSExt)
|
if (Args[i].isSExt)
|
||||||
ExtendKind = ISD::SIGN_EXTEND;
|
ExtendKind = ISD::SIGN_EXTEND;
|
||||||
else if (Args[i].isZExt)
|
else if (Args[i].isZExt)
|
||||||
ExtendKind = ISD::ZERO_EXTEND;
|
ExtendKind = ISD::ZERO_EXTEND;
|
||||||
|
|
||||||
getCopyToParts(DAG, Op, &Parts[0], NumParts, PartVT, ExtendKind);
|
getCopyToParts(DAG, Op, &Parts[0], NumParts, PartVT, ExtendKind);
|
||||||
|
|
||||||
for (unsigned i = 0; i != NumParts; ++i) {
|
for (unsigned i = 0; i != NumParts; ++i) {
|
||||||
// if it isn't first piece, alignment must be 1
|
// if it isn't first piece, alignment must be 1
|
||||||
ISD::ArgFlagsTy MyFlags = Flags;
|
ISD::ArgFlagsTy MyFlags = Flags;
|
||||||
if (NumParts > 1 && i == 0)
|
if (NumParts > 1 && i == 0)
|
||||||
MyFlags.setSplit();
|
MyFlags.setSplit();
|
||||||
else if (i != 0)
|
else if (i != 0)
|
||||||
MyFlags.setOrigAlign(1);
|
MyFlags.setOrigAlign(1);
|
||||||
|
|
||||||
Ops.push_back(Parts[i]);
|
Ops.push_back(Parts[i]);
|
||||||
Ops.push_back(DAG.getArgFlags(MyFlags));
|
Ops.push_back(DAG.getArgFlags(MyFlags));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4888,10 +4905,18 @@ LowerArguments(BasicBlock *LLVMBB, SelectionDAGLowering &SDL) {
|
|||||||
|
|
||||||
unsigned a = 0;
|
unsigned a = 0;
|
||||||
for (Function::arg_iterator AI = F.arg_begin(), E = F.arg_end();
|
for (Function::arg_iterator AI = F.arg_begin(), E = F.arg_end();
|
||||||
AI != E; ++AI, ++a)
|
AI != E; ++AI) {
|
||||||
|
SmallVector<MVT, 4> ValueVTs;
|
||||||
|
ComputeValueVTs(TLI, AI->getType(), ValueVTs);
|
||||||
|
unsigned NumValues = ValueVTs.size();
|
||||||
if (!AI->use_empty()) {
|
if (!AI->use_empty()) {
|
||||||
SDL.setValue(AI, Args[a]);
|
SmallVector<MVT, 4> LegalValueVTs(NumValues);
|
||||||
|
for (unsigned VI = 0; VI != NumValues; ++VI)
|
||||||
|
LegalValueVTs[VI] = Args[a + VI].getValueType();
|
||||||
|
SDL.setValue(AI, SDL.DAG.getNode(ISD::MERGE_VALUES,
|
||||||
|
SDL.DAG.getVTList(&LegalValueVTs[0],
|
||||||
|
NumValues),
|
||||||
|
&Args[a], NumValues));
|
||||||
// If this argument is live outside of the entry block, insert a copy from
|
// If this argument is live outside of the entry block, insert a copy from
|
||||||
// whereever we got it to the vreg that other BB's will reference it as.
|
// whereever we got it to the vreg that other BB's will reference it as.
|
||||||
DenseMap<const Value*, unsigned>::iterator VMI=FuncInfo.ValueMap.find(AI);
|
DenseMap<const Value*, unsigned>::iterator VMI=FuncInfo.ValueMap.find(AI);
|
||||||
@ -4899,6 +4924,8 @@ LowerArguments(BasicBlock *LLVMBB, SelectionDAGLowering &SDL) {
|
|||||||
SDL.CopyValueToVirtualRegister(AI, VMI->second);
|
SDL.CopyValueToVirtualRegister(AI, VMI->second);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
a += NumValues;
|
||||||
|
}
|
||||||
|
|
||||||
// Finally, if the target has anything special to do, allow it to do so.
|
// Finally, if the target has anything special to do, allow it to do so.
|
||||||
// FIXME: this should insert code into the DAG!
|
// FIXME: this should insert code into the DAG!
|
||||||
|
Loading…
x
Reference in New Issue
Block a user