diff options
author | Chris Lattner <sabre@nondot.org> | 2005-12-18 21:03:04 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2005-12-18 21:03:04 +0000 |
commit | dab05f0e194ac06c2c733f18a698b707dfa99ec3 (patch) | |
tree | bd943e958a40c97ef42bfd04cac05bd47c302fff /lib/Target/Sparc | |
parent | bc149b2c98755a874348505d4750c31354cea558 (diff) |
Change return lowering so that we can autogen the matching code.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@24832 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target/Sparc')
-rw-r--r-- | lib/Target/Sparc/SparcISelDAGToDAG.cpp | 49 | ||||
-rw-r--r-- | lib/Target/Sparc/SparcInstrInfo.td | 6 |
2 files changed, 25 insertions, 30 deletions
diff --git a/lib/Target/Sparc/SparcISelDAGToDAG.cpp b/lib/Target/Sparc/SparcISelDAGToDAG.cpp index c121cf1fbd..a6d2f06a44 100644 --- a/lib/Target/Sparc/SparcISelDAGToDAG.cpp +++ b/lib/Target/Sparc/SparcISelDAGToDAG.cpp @@ -45,6 +45,8 @@ namespace V8ISD { SELECT_ICC, // Select between two values using the current ICC flags. SELECT_FCC, // Select between two values using the current FCC flags. + + RET_FLAG, // Return with a flag operand. }; } @@ -534,15 +536,28 @@ SparcV8TargetLowering::LowerCallTo(SDOperand Chain, const Type *RetTy, SDOperand SparcV8TargetLowering::LowerReturnTo(SDOperand Chain, SDOperand Op, SelectionDAG &DAG) { - if (Op.getValueType() == MVT::i64) { + SDOperand Copy; + switch (Op.getValueType()) { + default: assert(0 && "Unknown type to return!"); + case MVT::i32: + Copy = DAG.getCopyToReg(Chain, V8::I0, Op, SDOperand()); + break; + case MVT::f32: + Copy = DAG.getCopyToReg(Chain, V8::F0, Op, SDOperand()); + break; + case MVT::f64: + Copy = DAG.getCopyToReg(Chain, V8::D0, Op, SDOperand()); + break; + case MVT::i64: SDOperand Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, Op, DAG.getConstant(1, MVT::i32)); SDOperand Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, Op, DAG.getConstant(0, MVT::i32)); - return DAG.getNode(ISD::RET, MVT::Other, Chain, Lo, Hi); - } else { - return DAG.getNode(ISD::RET, MVT::Other, Chain, Op); + Copy = DAG.getCopyToReg(Chain, V8::I0, Hi, SDOperand()); + Copy = DAG.getCopyToReg(Copy, V8::I1, Lo, Copy.getValue(1)); + break; } + return DAG.getNode(V8ISD::RET_FLAG, MVT::Other, Copy, Copy.getValue(1)); } SDOperand SparcV8TargetLowering:: @@ -935,32 +950,6 @@ SDOperand SparcV8DAGToDAGISel::Select(SDOperand Op) { // The high part is in the Y register. return CurDAG->SelectNodeTo(N, V8::RDY, MVT::i32, Mul.getValue(1)); } - - case ISD::RET: { - // FIXME: change this to use flag operands to allow autogen of ret. - if (N->getNumOperands() == 2) { - SDOperand Chain = Select(N->getOperand(0)); // Token chain. - SDOperand Val = Select(N->getOperand(1)); - if (N->getOperand(1).getValueType() == MVT::i32) { - Chain = CurDAG->getCopyToReg(Chain, V8::I0, Val); - } else if (N->getOperand(1).getValueType() == MVT::f32) { - Chain = CurDAG->getCopyToReg(Chain, V8::F0, Val); - } else { - assert(N->getOperand(1).getValueType() == MVT::f64); - Chain = CurDAG->getCopyToReg(Chain, V8::D0, Val); - } - return CurDAG->SelectNodeTo(N, V8::RETL, MVT::Other, Chain); - } else if (N->getNumOperands() > 1) { - SDOperand Chain = Select(N->getOperand(0)); // Token chain. - assert(N->getOperand(1).getValueType() == MVT::i32 && - N->getOperand(2).getValueType() == MVT::i32 && - N->getNumOperands() == 3 && "Unknown two-register ret value!"); - Chain = CurDAG->getCopyToReg(Chain, V8::I1, Select(N->getOperand(1))); - Chain = CurDAG->getCopyToReg(Chain, V8::I0, Select(N->getOperand(2))); - return CurDAG->SelectNodeTo(N, V8::RETL, MVT::Other, Chain); - } - break; // Generated code handles the void case. - } case ISD::CALL: // FIXME: This is a workaround for a bug in tblgen. { // Pattern #47: (call:Flag (tglobaladdr:i32):$dst, ICC:Flag) diff --git a/lib/Target/Sparc/SparcInstrInfo.td b/lib/Target/Sparc/SparcInstrInfo.td index c9777b9348..377543b091 100644 --- a/lib/Target/Sparc/SparcInstrInfo.td +++ b/lib/Target/Sparc/SparcInstrInfo.td @@ -93,6 +93,9 @@ def SDT_V8Call : SDTypeProfile<1, 2, [SDTCisVT<0, FlagVT>, SDTCisVT<1, i32>, SDTCisVT<2, FlagVT>]>; def call : SDNode<"ISD::CALL", SDT_V8Call, [SDNPHasChain]>; +def SDT_V8RetFlag : SDTypeProfile<0, 1, [ SDTCisVT<0, FlagVT>]>; +def retflag : SDNode<"V8ISD::RET_FLAG", SDT_V8RetFlag, [SDNPHasChain]>; + //===----------------------------------------------------------------------===// // Instructions //===----------------------------------------------------------------------===// @@ -701,3 +704,6 @@ def : Pat<(V8hi tglobaladdr:$in), (SETHIi tglobaladdr:$in)>; def : Pat<(V8lo tglobaladdr:$in), (ORri G0, tglobaladdr:$in)>; def : Pat<(V8hi tconstpool:$in), (SETHIi tconstpool:$in)>; def : Pat<(V8lo tconstpool:$in), (ORri G0, tconstpool:$in)>; + +// Return of a value, which has an input flag. +def : Pat<(retflag ICC/*HACK*/), (RETL)>; |