mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-02-07 14:33:15 +00:00
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:
parent
22cf8b118e
commit
8e7d056bc5
@ -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
|
||||||
|
@ -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:
|
||||||
|
@ -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));
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user