Change RET node to include signness information of the return values. e.g.

RET chain, value1, sign1, value2, sign2


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@28509 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Evan Cheng 2006-05-26 23:09:09 +00:00
parent 22cf8b118e
commit 8e7d056bc5
3 changed files with 20 additions and 11 deletions

View File

@ -414,8 +414,9 @@ namespace ISD {
BR_CC, BR_CC,
// RET - Return from function. The first operand is the chain, // RET - Return from function. The first operand is the chain,
// and any subsequent operands are the return values for the // and any subsequent operands are pairs of return value and return value
// function. This operation can have variable number of operands. // signness for the function. This operation can have variable number of
// operands.
RET, RET,
// INLINEASM - Represents an inline asm block. This node always has two // INLINEASM - Represents an inline asm block. This node always has two

View File

@ -1453,17 +1453,18 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
LastCALLSEQ_END = DAG.getEntryNode(); LastCALLSEQ_END = DAG.getEntryNode();
switch (Node->getNumOperands()) { switch (Node->getNumOperands()) {
case 2: // ret val case 3: // ret val
Tmp2 = Node->getOperand(1); Tmp2 = Node->getOperand(1);
Tmp3 = Node->getOperand(2); // Signness
switch (getTypeAction(Tmp2.getValueType())) { switch (getTypeAction(Tmp2.getValueType())) {
case Legal: case Legal:
Result = DAG.UpdateNodeOperands(Result, Tmp1, LegalizeOp(Tmp2)); Result = DAG.UpdateNodeOperands(Result, Tmp1, LegalizeOp(Tmp2), Tmp3);
break; break;
case Expand: case Expand:
if (Tmp2.getValueType() != MVT::Vector) { if (Tmp2.getValueType() != MVT::Vector) {
SDOperand Lo, Hi; SDOperand Lo, Hi;
ExpandOp(Tmp2, Lo, Hi); ExpandOp(Tmp2, Lo, Hi);
Result = DAG.getNode(ISD::RET, MVT::Other, Tmp1, Lo, Hi); Result = DAG.getNode(ISD::RET, MVT::Other, Tmp1, Lo, Tmp3, Hi, Tmp3);
} else { } else {
SDNode *InVal = Tmp2.Val; SDNode *InVal = Tmp2.Val;
unsigned NumElems = unsigned NumElems =
@ -1476,11 +1477,11 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
if (TVT != MVT::Other && TLI.isTypeLegal(TVT)) { if (TVT != MVT::Other && TLI.isTypeLegal(TVT)) {
// Turn this into a return of the packed type. // Turn this into a return of the packed type.
Tmp2 = PackVectorOp(Tmp2, TVT); Tmp2 = PackVectorOp(Tmp2, TVT);
Result = DAG.UpdateNodeOperands(Result, Tmp1, Tmp2); Result = DAG.UpdateNodeOperands(Result, Tmp1, Tmp2, Tmp3);
} else if (NumElems == 1) { } else if (NumElems == 1) {
// Turn this into a return of the scalar type. // Turn this into a return of the scalar type.
Tmp2 = PackVectorOp(Tmp2, EVT); Tmp2 = PackVectorOp(Tmp2, EVT);
Result = DAG.UpdateNodeOperands(Result, Tmp1, Tmp2); Result = DAG.UpdateNodeOperands(Result, Tmp1, Tmp2, Tmp3);
// FIXME: Returns of gcc generic vectors smaller than a legal type // FIXME: Returns of gcc generic vectors smaller than a legal type
// should be returned in integer registers! // should be returned in integer registers!
@ -1493,14 +1494,14 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
// type should be returned by reference! // type should be returned by reference!
SDOperand Lo, Hi; SDOperand Lo, Hi;
SplitVectorOp(Tmp2, Lo, Hi); SplitVectorOp(Tmp2, Lo, Hi);
Result = DAG.getNode(ISD::RET, MVT::Other, Tmp1, Lo, Hi); Result = DAG.getNode(ISD::RET, MVT::Other, Tmp1, Lo, Tmp3, Hi, Tmp3);
Result = LegalizeOp(Result); Result = LegalizeOp(Result);
} }
} }
break; break;
case Promote: case Promote:
Tmp2 = PromoteOp(Node->getOperand(1)); Tmp2 = PromoteOp(Node->getOperand(1));
Result = DAG.UpdateNodeOperands(Result, Tmp1, Tmp2); Result = DAG.UpdateNodeOperands(Result, Tmp1, Tmp2, Tmp3);
Result = LegalizeOp(Result); Result = LegalizeOp(Result);
break; break;
} }
@ -1511,10 +1512,11 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
default: { // ret <values> default: { // ret <values>
std::vector<SDOperand> NewValues; std::vector<SDOperand> NewValues;
NewValues.push_back(Tmp1); NewValues.push_back(Tmp1);
for (unsigned i = 1, e = Node->getNumOperands(); i != e; ++i) for (unsigned i = 1, e = Node->getNumOperands(); i < e; i += 2)
switch (getTypeAction(Node->getOperand(i).getValueType())) { switch (getTypeAction(Node->getOperand(i).getValueType())) {
case Legal: case Legal:
NewValues.push_back(LegalizeOp(Node->getOperand(i))); NewValues.push_back(LegalizeOp(Node->getOperand(i)));
NewValues.push_back(Node->getOperand(i+1));
break; break;
case Expand: { case Expand: {
SDOperand Lo, Hi; SDOperand Lo, Hi;
@ -1522,7 +1524,9 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
"FIXME: TODO: implement returning non-legal vector types!"); "FIXME: TODO: implement returning non-legal vector types!");
ExpandOp(Node->getOperand(i), Lo, Hi); ExpandOp(Node->getOperand(i), Lo, Hi);
NewValues.push_back(Lo); NewValues.push_back(Lo);
NewValues.push_back(Node->getOperand(i+1));
NewValues.push_back(Hi); NewValues.push_back(Hi);
NewValues.push_back(Node->getOperand(i+1));
break; break;
} }
case Promote: case Promote:

View File

@ -722,10 +722,13 @@ void SelectionDAGLowering::visitRet(ReturnInst &I) {
NewValues.push_back(getRoot()); NewValues.push_back(getRoot());
for (unsigned i = 0, e = I.getNumOperands(); i != e; ++i) { for (unsigned i = 0, e = I.getNumOperands(); i != e; ++i) {
SDOperand RetOp = getValue(I.getOperand(i)); SDOperand RetOp = getValue(I.getOperand(i));
bool isSigned = I.getOperand(i)->getType()->isSigned();
// If this is an integer return value, we need to promote it ourselves to // If this is an integer return value, we need to promote it ourselves to
// the full width of a register, since LegalizeOp will use ANY_EXTEND rather // the full width of a register, since LegalizeOp will use ANY_EXTEND rather
// than sign/zero. // than sign/zero.
// FIXME: C calling convention requires the return type to be promoted to
// at least 32-bit. But this is not necessary for non-C calling conventions.
if (MVT::isInteger(RetOp.getValueType()) && if (MVT::isInteger(RetOp.getValueType()) &&
RetOp.getValueType() < MVT::i64) { RetOp.getValueType() < MVT::i64) {
MVT::ValueType TmpVT; MVT::ValueType TmpVT;
@ -734,12 +737,13 @@ void SelectionDAGLowering::visitRet(ReturnInst &I) {
else else
TmpVT = MVT::i32; TmpVT = MVT::i32;
if (I.getOperand(i)->getType()->isSigned()) if (isSigned)
RetOp = DAG.getNode(ISD::SIGN_EXTEND, TmpVT, RetOp); RetOp = DAG.getNode(ISD::SIGN_EXTEND, TmpVT, RetOp);
else else
RetOp = DAG.getNode(ISD::ZERO_EXTEND, TmpVT, RetOp); RetOp = DAG.getNode(ISD::ZERO_EXTEND, TmpVT, RetOp);
} }
NewValues.push_back(RetOp); NewValues.push_back(RetOp);
NewValues.push_back(DAG.getConstant(isSigned, MVT::i32));
} }
DAG.setRoot(DAG.getNode(ISD::RET, MVT::Other, NewValues)); DAG.setRoot(DAG.getNode(ISD::RET, MVT::Other, NewValues));
} }