mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-10-19 19:12:56 +02:00
SPARC backend fix: correctly passing arguments through stack
llvm-svn: 122626
This commit is contained in:
parent
292870da06
commit
1f9ecea940
@ -365,20 +365,24 @@ SparcTargetLowering::LowerCall(SDValue Chain, SDValue Callee,
|
|||||||
SDValue Val = OutVals[i];
|
SDValue Val = OutVals[i];
|
||||||
EVT ObjectVT = Outs[i].VT;
|
EVT ObjectVT = Outs[i].VT;
|
||||||
SDValue ValToStore(0, 0);
|
SDValue ValToStore(0, 0);
|
||||||
unsigned ObjSize;
|
SDValue ValToStore2(0, 0);
|
||||||
|
unsigned ArgOffset1 = 0, ArgOffset2 = 0;
|
||||||
switch (ObjectVT.getSimpleVT().SimpleTy) {
|
switch (ObjectVT.getSimpleVT().SimpleTy) {
|
||||||
default: llvm_unreachable("Unhandled argument type!");
|
default: llvm_unreachable("Unhandled argument type!");
|
||||||
case MVT::i32:
|
case MVT::i32:
|
||||||
ObjSize = 4;
|
ArgOffset1 = ArgOffset;
|
||||||
|
ArgOffset += 4;
|
||||||
|
|
||||||
if (RegsToPass.size() >= 6) {
|
if (RegsToPass.size() >= 6) {
|
||||||
ValToStore = Val;
|
ValToStore = Val;
|
||||||
} else {
|
} else {
|
||||||
RegsToPass.push_back(std::make_pair(ArgRegs[RegsToPass.size()], Val));
|
RegsToPass.push_back(std::make_pair(ArgRegs[RegsToPass.size()], Val));
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case MVT::f32:
|
case MVT::f32:
|
||||||
ObjSize = 4;
|
ArgOffset1 = ArgOffset;
|
||||||
|
ArgOffset += 4;
|
||||||
if (RegsToPass.size() >= 6) {
|
if (RegsToPass.size() >= 6) {
|
||||||
ValToStore = Val;
|
ValToStore = Val;
|
||||||
} else {
|
} else {
|
||||||
@ -388,14 +392,17 @@ SparcTargetLowering::LowerCall(SDValue Chain, SDValue Callee,
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case MVT::f64: {
|
case MVT::f64: {
|
||||||
ObjSize = 8;
|
|
||||||
if (RegsToPass.size() >= 6) {
|
|
||||||
ValToStore = Val; // Whole thing is passed in memory.
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if (RegsToPass.size() >= 6) {
|
||||||
|
if (ArgOffset % 8 == 0) {
|
||||||
|
ArgOffset1 = ArgOffset;
|
||||||
|
ArgOffset += 8;
|
||||||
|
ValToStore = Val; // Whole thing is passed in memory.
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
// Break into top and bottom parts by storing to the stack and loading
|
// Break into top and bottom parts by storing to the stack and loading
|
||||||
// out the parts as integers. Top part goes in a reg.
|
// out the parts as integers.
|
||||||
SDValue StackPtr = DAG.CreateStackTemporary(MVT::f64, MVT::i32);
|
SDValue StackPtr = DAG.CreateStackTemporary(MVT::f64, MVT::i32);
|
||||||
SDValue Store = DAG.getStore(DAG.getEntryNode(), dl,
|
SDValue Store = DAG.getStore(DAG.getEntryNode(), dl,
|
||||||
Val, StackPtr, MachinePointerInfo(),
|
Val, StackPtr, MachinePointerInfo(),
|
||||||
@ -410,22 +417,31 @@ SparcTargetLowering::LowerCall(SDValue Chain, SDValue Callee,
|
|||||||
SDValue Lo = DAG.getLoad(MVT::i32, dl, Store, StackPtr,
|
SDValue Lo = DAG.getLoad(MVT::i32, dl, Store, StackPtr,
|
||||||
MachinePointerInfo(), false, false, 0);
|
MachinePointerInfo(), false, false, 0);
|
||||||
|
|
||||||
RegsToPass.push_back(std::make_pair(ArgRegs[RegsToPass.size()], Hi));
|
|
||||||
|
|
||||||
if (RegsToPass.size() >= 6) {
|
if (RegsToPass.size() >= 6) {
|
||||||
ValToStore = Lo;
|
ArgOffset1 = ArgOffset;
|
||||||
ArgOffset += 4;
|
ValToStore = Hi;
|
||||||
ObjSize = 4;
|
} else {
|
||||||
|
RegsToPass.push_back(std::make_pair(ArgRegs[RegsToPass.size()], Hi));
|
||||||
|
}
|
||||||
|
ArgOffset += 4;
|
||||||
|
if (RegsToPass.size() >= 6) {
|
||||||
|
ArgOffset2 = ArgOffset;
|
||||||
|
ValToStore2 = Lo;
|
||||||
} else {
|
} else {
|
||||||
RegsToPass.push_back(std::make_pair(ArgRegs[RegsToPass.size()], Lo));
|
RegsToPass.push_back(std::make_pair(ArgRegs[RegsToPass.size()], Lo));
|
||||||
}
|
}
|
||||||
|
ArgOffset += 4;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case MVT::i64: {
|
case MVT::i64: {
|
||||||
ObjSize = 8;
|
|
||||||
if (RegsToPass.size() >= 6) {
|
if (RegsToPass.size() >= 6) {
|
||||||
ValToStore = Val; // Whole thing is passed in memory.
|
if (ArgOffset % 8 == 0) {
|
||||||
break;
|
ArgOffset1 = ArgOffset;
|
||||||
|
ArgOffset += 8;
|
||||||
|
ValToStore = Val; // Whole thing is passed in memory.
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Split the value into top and bottom part. Top part goes in a reg.
|
// Split the value into top and bottom part. Top part goes in a reg.
|
||||||
@ -433,28 +449,40 @@ SparcTargetLowering::LowerCall(SDValue Chain, SDValue Callee,
|
|||||||
DAG.getConstant(1, MVT::i32));
|
DAG.getConstant(1, MVT::i32));
|
||||||
SDValue Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, MVT::i32, Val,
|
SDValue Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, MVT::i32, Val,
|
||||||
DAG.getConstant(0, MVT::i32));
|
DAG.getConstant(0, MVT::i32));
|
||||||
RegsToPass.push_back(std::make_pair(ArgRegs[RegsToPass.size()], Hi));
|
|
||||||
|
|
||||||
if (RegsToPass.size() >= 6) {
|
if (RegsToPass.size() >= 6) {
|
||||||
ValToStore = Lo;
|
ArgOffset1 = ArgOffset;
|
||||||
ArgOffset += 4;
|
ValToStore = Hi;
|
||||||
ObjSize = 4;
|
} else {
|
||||||
|
RegsToPass.push_back(std::make_pair(ArgRegs[RegsToPass.size()], Hi));
|
||||||
|
}
|
||||||
|
ArgOffset += 4;
|
||||||
|
if (RegsToPass.size() >= 6) {
|
||||||
|
ArgOffset2 = ArgOffset;
|
||||||
|
ValToStore2 = Lo;
|
||||||
} else {
|
} else {
|
||||||
RegsToPass.push_back(std::make_pair(ArgRegs[RegsToPass.size()], Lo));
|
RegsToPass.push_back(std::make_pair(ArgRegs[RegsToPass.size()], Lo));
|
||||||
}
|
}
|
||||||
|
ArgOffset += 4;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ValToStore.getNode()) {
|
if (ValToStore.getNode()) {
|
||||||
SDValue StackPtr = DAG.getRegister(SP::O6, MVT::i32);
|
SDValue StackPtr = DAG.getRegister(SP::O6, MVT::i32);
|
||||||
SDValue PtrOff = DAG.getConstant(ArgOffset, MVT::i32);
|
SDValue PtrOff = DAG.getConstant(ArgOffset1, MVT::i32);
|
||||||
PtrOff = DAG.getNode(ISD::ADD, dl, MVT::i32, StackPtr, PtrOff);
|
PtrOff = DAG.getNode(ISD::ADD, dl, MVT::i32, StackPtr, PtrOff);
|
||||||
MemOpChains.push_back(DAG.getStore(Chain, dl, ValToStore,
|
MemOpChains.push_back(DAG.getStore(Chain, dl, ValToStore,
|
||||||
PtrOff, MachinePointerInfo(),
|
PtrOff, MachinePointerInfo(),
|
||||||
false, false, 0));
|
false, false, 0));
|
||||||
}
|
}
|
||||||
ArgOffset += ObjSize;
|
if (ValToStore2.getNode()) {
|
||||||
|
SDValue StackPtr = DAG.getRegister(SP::O6, MVT::i32);
|
||||||
|
SDValue PtrOff = DAG.getConstant(ArgOffset2, MVT::i32);
|
||||||
|
PtrOff = DAG.getNode(ISD::ADD, dl, MVT::i32, StackPtr, PtrOff);
|
||||||
|
MemOpChains.push_back(DAG.getStore(Chain, dl, ValToStore2,
|
||||||
|
PtrOff, MachinePointerInfo(),
|
||||||
|
false, false, 0));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user