mirror of
https://github.com/RPCS3/llvm.git
synced 2025-04-03 05:41:42 +00:00
Pull out Call, reducing stack frame size from 6032 bytes to 5184 bytes.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@23650 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
222adac30a
commit
6a16f6a14f
@ -97,6 +97,7 @@ private:
|
|||||||
SDOperand SelectADD_PARTS(SDOperand Op);
|
SDOperand SelectADD_PARTS(SDOperand Op);
|
||||||
SDOperand SelectSUB_PARTS(SDOperand Op);
|
SDOperand SelectSUB_PARTS(SDOperand Op);
|
||||||
SDOperand SelectSETCC(SDOperand Op);
|
SDOperand SelectSETCC(SDOperand Op);
|
||||||
|
SDOperand SelectCALL(SDOperand Op);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -884,6 +885,113 @@ SDOperand PPC32DAGToDAGISel::SelectSETCC(SDOperand Op) {
|
|||||||
return SDOperand(N, 0);
|
return SDOperand(N, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SDOperand PPC32DAGToDAGISel::SelectCALL(SDOperand Op) {
|
||||||
|
SDNode *N = Op.Val;
|
||||||
|
SDOperand Chain = Select(N->getOperand(0));
|
||||||
|
|
||||||
|
unsigned CallOpcode;
|
||||||
|
std::vector<SDOperand> CallOperands;
|
||||||
|
|
||||||
|
if (GlobalAddressSDNode *GASD =
|
||||||
|
dyn_cast<GlobalAddressSDNode>(N->getOperand(1))) {
|
||||||
|
CallOpcode = PPC::CALLpcrel;
|
||||||
|
CallOperands.push_back(CurDAG->getTargetGlobalAddress(GASD->getGlobal(),
|
||||||
|
MVT::i32));
|
||||||
|
} else if (ExternalSymbolSDNode *ESSDN =
|
||||||
|
dyn_cast<ExternalSymbolSDNode>(N->getOperand(1))) {
|
||||||
|
CallOpcode = PPC::CALLpcrel;
|
||||||
|
CallOperands.push_back(N->getOperand(1));
|
||||||
|
} else {
|
||||||
|
// Copy the callee address into the CTR register.
|
||||||
|
SDOperand Callee = Select(N->getOperand(1));
|
||||||
|
Chain = CurDAG->getTargetNode(PPC::MTCTR, MVT::Other, Callee, Chain);
|
||||||
|
|
||||||
|
// Copy the callee address into R12 on darwin.
|
||||||
|
SDOperand R12 = CurDAG->getRegister(PPC::R12, MVT::i32);
|
||||||
|
Chain = CurDAG->getNode(ISD::CopyToReg, MVT::Other, Chain, R12, Callee);
|
||||||
|
|
||||||
|
CallOperands.push_back(getI32Imm(20)); // Information to encode indcall
|
||||||
|
CallOperands.push_back(getI32Imm(0)); // Information to encode indcall
|
||||||
|
CallOperands.push_back(R12);
|
||||||
|
CallOpcode = PPC::CALLindirect;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned GPR_idx = 0, FPR_idx = 0;
|
||||||
|
static const unsigned GPR[] = {
|
||||||
|
PPC::R3, PPC::R4, PPC::R5, PPC::R6,
|
||||||
|
PPC::R7, PPC::R8, PPC::R9, PPC::R10,
|
||||||
|
};
|
||||||
|
static const unsigned FPR[] = {
|
||||||
|
PPC::F1, PPC::F2, PPC::F3, PPC::F4, PPC::F5, PPC::F6, PPC::F7,
|
||||||
|
PPC::F8, PPC::F9, PPC::F10, PPC::F11, PPC::F12, PPC::F13
|
||||||
|
};
|
||||||
|
|
||||||
|
SDOperand InFlag; // Null incoming flag value.
|
||||||
|
|
||||||
|
for (unsigned i = 2, e = N->getNumOperands(); i != e; ++i) {
|
||||||
|
unsigned DestReg = 0;
|
||||||
|
MVT::ValueType RegTy = N->getOperand(i).getValueType();
|
||||||
|
if (RegTy == MVT::i32) {
|
||||||
|
assert(GPR_idx < 8 && "Too many int args");
|
||||||
|
DestReg = GPR[GPR_idx++];
|
||||||
|
} else {
|
||||||
|
assert(MVT::isFloatingPoint(N->getOperand(i).getValueType()) &&
|
||||||
|
"Unpromoted integer arg?");
|
||||||
|
assert(FPR_idx < 13 && "Too many fp args");
|
||||||
|
DestReg = FPR[FPR_idx++];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (N->getOperand(i).getOpcode() != ISD::UNDEF) {
|
||||||
|
SDOperand Val = Select(N->getOperand(i));
|
||||||
|
Chain = CurDAG->getCopyToReg(Chain, DestReg, Val, InFlag);
|
||||||
|
InFlag = Chain.getValue(1);
|
||||||
|
CallOperands.push_back(CurDAG->getRegister(DestReg, RegTy));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Finally, once everything is in registers to pass to the call, emit the
|
||||||
|
// call itself.
|
||||||
|
if (InFlag.Val)
|
||||||
|
CallOperands.push_back(InFlag); // Strong dep on register copies.
|
||||||
|
else
|
||||||
|
CallOperands.push_back(Chain); // Weak dep on whatever occurs before
|
||||||
|
Chain = CurDAG->getTargetNode(CallOpcode, MVT::Other, MVT::Flag,
|
||||||
|
CallOperands);
|
||||||
|
|
||||||
|
std::vector<SDOperand> CallResults;
|
||||||
|
|
||||||
|
// If the call has results, copy the values out of the ret val registers.
|
||||||
|
switch (N->getValueType(0)) {
|
||||||
|
default: assert(0 && "Unexpected ret value!");
|
||||||
|
case MVT::Other: break;
|
||||||
|
case MVT::i32:
|
||||||
|
if (N->getValueType(1) == MVT::i32) {
|
||||||
|
Chain = CurDAG->getCopyFromReg(Chain, PPC::R4, MVT::i32,
|
||||||
|
Chain.getValue(1)).getValue(1);
|
||||||
|
CallResults.push_back(Chain.getValue(0));
|
||||||
|
Chain = CurDAG->getCopyFromReg(Chain, PPC::R3, MVT::i32,
|
||||||
|
Chain.getValue(2)).getValue(1);
|
||||||
|
CallResults.push_back(Chain.getValue(0));
|
||||||
|
} else {
|
||||||
|
Chain = CurDAG->getCopyFromReg(Chain, PPC::R3, MVT::i32,
|
||||||
|
Chain.getValue(1)).getValue(1);
|
||||||
|
CallResults.push_back(Chain.getValue(0));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case MVT::f32:
|
||||||
|
case MVT::f64:
|
||||||
|
Chain = CurDAG->getCopyFromReg(Chain, PPC::F1, N->getValueType(0),
|
||||||
|
Chain.getValue(1)).getValue(1);
|
||||||
|
CallResults.push_back(Chain.getValue(0));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
CallResults.push_back(Chain);
|
||||||
|
for (unsigned i = 0, e = CallResults.size(); i != e; ++i)
|
||||||
|
CodeGenMap[Op.getValue(i)] = CallResults[i];
|
||||||
|
return CallResults[Op.ResNo];
|
||||||
|
}
|
||||||
|
|
||||||
// Select - Convert the specified operand from a target-independent to a
|
// Select - Convert the specified operand from a target-independent to a
|
||||||
// target-specific node if it hasn't already been changed.
|
// target-specific node if it hasn't already been changed.
|
||||||
SDOperand PPC32DAGToDAGISel::Select(SDOperand Op) {
|
SDOperand PPC32DAGToDAGISel::Select(SDOperand Op) {
|
||||||
@ -902,6 +1010,9 @@ SDOperand PPC32DAGToDAGISel::Select(SDOperand Op) {
|
|||||||
case ISD::ADD_PARTS: return SelectADD_PARTS(Op);
|
case ISD::ADD_PARTS: return SelectADD_PARTS(Op);
|
||||||
case ISD::SUB_PARTS: return SelectSUB_PARTS(Op);
|
case ISD::SUB_PARTS: return SelectSUB_PARTS(Op);
|
||||||
case ISD::SETCC: return SelectSETCC(Op);
|
case ISD::SETCC: return SelectSETCC(Op);
|
||||||
|
case ISD::CALL: return SelectCALL(Op);
|
||||||
|
case ISD::TAILCALL: return SelectCALL(Op);
|
||||||
|
|
||||||
case ISD::TokenFactor: {
|
case ISD::TokenFactor: {
|
||||||
SDOperand New;
|
SDOperand New;
|
||||||
if (N->getNumOperands() == 2) {
|
if (N->getNumOperands() == 2) {
|
||||||
@ -1362,112 +1473,6 @@ SDOperand PPC32DAGToDAGISel::Select(SDOperand Op) {
|
|||||||
getI32Imm(Amt), Select(N->getOperand(0)));
|
getI32Imm(Amt), Select(N->getOperand(0)));
|
||||||
return SDOperand(N, 0);
|
return SDOperand(N, 0);
|
||||||
}
|
}
|
||||||
case ISD::CALL:
|
|
||||||
case ISD::TAILCALL: {
|
|
||||||
SDOperand Chain = Select(N->getOperand(0));
|
|
||||||
|
|
||||||
unsigned CallOpcode;
|
|
||||||
std::vector<SDOperand> CallOperands;
|
|
||||||
|
|
||||||
if (GlobalAddressSDNode *GASD =
|
|
||||||
dyn_cast<GlobalAddressSDNode>(N->getOperand(1))) {
|
|
||||||
CallOpcode = PPC::CALLpcrel;
|
|
||||||
CallOperands.push_back(CurDAG->getTargetGlobalAddress(GASD->getGlobal(),
|
|
||||||
MVT::i32));
|
|
||||||
} else if (ExternalSymbolSDNode *ESSDN =
|
|
||||||
dyn_cast<ExternalSymbolSDNode>(N->getOperand(1))) {
|
|
||||||
CallOpcode = PPC::CALLpcrel;
|
|
||||||
CallOperands.push_back(N->getOperand(1));
|
|
||||||
} else {
|
|
||||||
// Copy the callee address into the CTR register.
|
|
||||||
SDOperand Callee = Select(N->getOperand(1));
|
|
||||||
Chain = CurDAG->getTargetNode(PPC::MTCTR, MVT::Other, Callee, Chain);
|
|
||||||
|
|
||||||
// Copy the callee address into R12 on darwin.
|
|
||||||
SDOperand R12 = CurDAG->getRegister(PPC::R12, MVT::i32);
|
|
||||||
Chain = CurDAG->getNode(ISD::CopyToReg, MVT::Other, Chain, R12, Callee);
|
|
||||||
|
|
||||||
CallOperands.push_back(getI32Imm(20)); // Information to encode indcall
|
|
||||||
CallOperands.push_back(getI32Imm(0)); // Information to encode indcall
|
|
||||||
CallOperands.push_back(R12);
|
|
||||||
CallOpcode = PPC::CALLindirect;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned GPR_idx = 0, FPR_idx = 0;
|
|
||||||
static const unsigned GPR[] = {
|
|
||||||
PPC::R3, PPC::R4, PPC::R5, PPC::R6,
|
|
||||||
PPC::R7, PPC::R8, PPC::R9, PPC::R10,
|
|
||||||
};
|
|
||||||
static const unsigned FPR[] = {
|
|
||||||
PPC::F1, PPC::F2, PPC::F3, PPC::F4, PPC::F5, PPC::F6, PPC::F7,
|
|
||||||
PPC::F8, PPC::F9, PPC::F10, PPC::F11, PPC::F12, PPC::F13
|
|
||||||
};
|
|
||||||
|
|
||||||
SDOperand InFlag; // Null incoming flag value.
|
|
||||||
|
|
||||||
for (unsigned i = 2, e = N->getNumOperands(); i != e; ++i) {
|
|
||||||
unsigned DestReg = 0;
|
|
||||||
MVT::ValueType RegTy = N->getOperand(i).getValueType();
|
|
||||||
if (RegTy == MVT::i32) {
|
|
||||||
assert(GPR_idx < 8 && "Too many int args");
|
|
||||||
DestReg = GPR[GPR_idx++];
|
|
||||||
} else {
|
|
||||||
assert(MVT::isFloatingPoint(N->getOperand(i).getValueType()) &&
|
|
||||||
"Unpromoted integer arg?");
|
|
||||||
assert(FPR_idx < 13 && "Too many fp args");
|
|
||||||
DestReg = FPR[FPR_idx++];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (N->getOperand(i).getOpcode() != ISD::UNDEF) {
|
|
||||||
SDOperand Val = Select(N->getOperand(i));
|
|
||||||
Chain = CurDAG->getCopyToReg(Chain, DestReg, Val, InFlag);
|
|
||||||
InFlag = Chain.getValue(1);
|
|
||||||
CallOperands.push_back(CurDAG->getRegister(DestReg, RegTy));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Finally, once everything is in registers to pass to the call, emit the
|
|
||||||
// call itself.
|
|
||||||
if (InFlag.Val)
|
|
||||||
CallOperands.push_back(InFlag); // Strong dep on register copies.
|
|
||||||
else
|
|
||||||
CallOperands.push_back(Chain); // Weak dep on whatever occurs before
|
|
||||||
Chain = CurDAG->getTargetNode(CallOpcode, MVT::Other, MVT::Flag,
|
|
||||||
CallOperands);
|
|
||||||
|
|
||||||
std::vector<SDOperand> CallResults;
|
|
||||||
|
|
||||||
// If the call has results, copy the values out of the ret val registers.
|
|
||||||
switch (N->getValueType(0)) {
|
|
||||||
default: assert(0 && "Unexpected ret value!");
|
|
||||||
case MVT::Other: break;
|
|
||||||
case MVT::i32:
|
|
||||||
if (N->getValueType(1) == MVT::i32) {
|
|
||||||
Chain = CurDAG->getCopyFromReg(Chain, PPC::R4, MVT::i32,
|
|
||||||
Chain.getValue(1)).getValue(1);
|
|
||||||
CallResults.push_back(Chain.getValue(0));
|
|
||||||
Chain = CurDAG->getCopyFromReg(Chain, PPC::R3, MVT::i32,
|
|
||||||
Chain.getValue(2)).getValue(1);
|
|
||||||
CallResults.push_back(Chain.getValue(0));
|
|
||||||
} else {
|
|
||||||
Chain = CurDAG->getCopyFromReg(Chain, PPC::R3, MVT::i32,
|
|
||||||
Chain.getValue(1)).getValue(1);
|
|
||||||
CallResults.push_back(Chain.getValue(0));
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case MVT::f32:
|
|
||||||
case MVT::f64:
|
|
||||||
Chain = CurDAG->getCopyFromReg(Chain, PPC::F1, N->getValueType(0),
|
|
||||||
Chain.getValue(1)).getValue(1);
|
|
||||||
CallResults.push_back(Chain.getValue(0));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
CallResults.push_back(Chain);
|
|
||||||
for (unsigned i = 0, e = CallResults.size(); i != e; ++i)
|
|
||||||
CodeGenMap[Op.getValue(i)] = CallResults[i];
|
|
||||||
return CallResults[Op.ResNo];
|
|
||||||
}
|
|
||||||
case ISD::RET: {
|
case ISD::RET: {
|
||||||
SDOperand Chain = Select(N->getOperand(0)); // Token chain.
|
SDOperand Chain = Select(N->getOperand(0)); // Token chain.
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user