diff options
| author | Evan Cheng <evan.cheng@apple.com> | 2006-01-05 00:27:02 +0000 |
|---|---|---|
| committer | Evan Cheng <evan.cheng@apple.com> | 2006-01-05 00:27:02 +0000 |
| commit | 45e19098a6a723bd4b5d66ef56f32798f0fafa95 (patch) | |
| tree | 0999b48b8a27c73e16d65e5c745d37c9eb493f9d /llvm/lib/Target/X86/X86ISelLowering.cpp | |
| parent | 779dd947218aa7446a62daf827f25d1c0fd07008 (diff) | |
| download | bcm5719-llvm-45e19098a6a723bd4b5d66ef56f32798f0fafa95.tar.gz bcm5719-llvm-45e19098a6a723bd4b5d66ef56f32798f0fafa95.zip | |
DAG based isel call support.
llvm-svn: 25103
Diffstat (limited to 'llvm/lib/Target/X86/X86ISelLowering.cpp')
| -rw-r--r-- | llvm/lib/Target/X86/X86ISelLowering.cpp | 141 |
1 files changed, 111 insertions, 30 deletions
diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp index a5b261c8374..1811f62b0b0 100644 --- a/llvm/lib/Target/X86/X86ISelLowering.cpp +++ b/llvm/lib/Target/X86/X86ISelLowering.cpp @@ -457,38 +457,117 @@ X86TargetLowering::LowerCCCCallTo(SDOperand Chain, const Type *RetTy, RetVals.push_back(MVT::i32); break; } - std::vector<SDOperand> Ops; - Ops.push_back(Chain); - Ops.push_back(Callee); - Ops.push_back(DAG.getConstant(NumBytes, getPointerTy())); - Ops.push_back(DAG.getConstant(0, getPointerTy())); - SDOperand TheCall = DAG.getNode(isTailCall ? X86ISD::TAILCALL : X86ISD::CALL, - RetVals, Ops); - Chain = DAG.getNode(ISD::CALLSEQ_END, MVT::Other, TheCall); - SDOperand ResultVal; - switch (RetTyVT) { - case MVT::isVoid: break; - default: - ResultVal = TheCall.getValue(1); - break; - case MVT::i1: - case MVT::i8: - case MVT::i16: - ResultVal = DAG.getNode(ISD::TRUNCATE, RetTyVT, TheCall.getValue(1)); - break; - case MVT::f32: - // FIXME: we would really like to remember that this FP_ROUND operation is - // okay to eliminate if we allow excess FP precision. - ResultVal = DAG.getNode(ISD::FP_ROUND, MVT::f32, TheCall.getValue(1)); - break; - case MVT::i64: - ResultVal = DAG.getNode(ISD::BUILD_PAIR, MVT::i64, TheCall.getValue(1), - TheCall.getValue(2)); - break; - } + if (X86DAGIsel) { + std::vector<MVT::ValueType> NodeTys; + NodeTys.push_back(MVT::Other); // Returns a chain + NodeTys.push_back(MVT::Flag); // Returns a flag for retval copy to use. - return std::make_pair(ResultVal, Chain); + std::vector<SDOperand> Ops; + Ops.push_back(Chain); + Ops.push_back(Callee); + + Chain = DAG.getNode(isTailCall ? X86ISD::TAILCALL : X86ISD::CALL, + NodeTys, Ops); + SDOperand InFlag = Chain.getValue(1); + + SDOperand RetVal; + if (RetTyVT != MVT::isVoid) { + switch (RetTyVT) { + default: assert(0 && "Unknown value type to return!"); + case MVT::i1: + case MVT::i8: + RetVal = DAG.getCopyFromReg(Chain, X86::AL, MVT::i8, InFlag); + Chain = RetVal.getValue(1); + break; + case MVT::i16: + RetVal = DAG.getCopyFromReg(Chain, X86::AX, MVT::i16, InFlag); + Chain = RetVal.getValue(1); + break; + case MVT::i32: + RetVal = DAG.getCopyFromReg(Chain, X86::EAX, MVT::i32, InFlag); + Chain = RetVal.getValue(1); + break; + case MVT::i64: { + SDOperand Lo = DAG.getCopyFromReg(Chain, X86::EAX, MVT::i32, InFlag); + SDOperand Hi = DAG.getCopyFromReg(Lo.getValue(1), X86::EDX, MVT::i32, + Lo.getValue(2)); + RetVal = DAG.getNode(ISD::BUILD_PAIR, MVT::i64, Lo, Hi); + Chain = Hi.getValue(1); + break; + } + case MVT::f32: + case MVT::f64: { + std::vector<MVT::ValueType> Tys; + Tys.push_back(MVT::f64); + Tys.push_back(MVT::Other); + std::vector<SDOperand> Ops; + Ops.push_back(Chain); + Ops.push_back(InFlag); + RetVal = DAG.getNode(X86ISD::FP_GET_RESULT, Tys, Ops); + Chain = RetVal.getValue(1); + if (X86ScalarSSE) { + unsigned Size = MVT::getSizeInBits(MVT::f64)/8; + MachineFunction &MF = DAG.getMachineFunction(); + int SSFI = MF.getFrameInfo()->CreateStackObject(Size, Size); + SDOperand StackSlot = DAG.getFrameIndex(SSFI, getPointerTy()); + Tys.clear(); + Tys.push_back(MVT::Other); + Ops.clear(); + Ops.push_back(Chain); + Ops.push_back(RetVal); + Ops.push_back(StackSlot); + Ops.push_back(DAG.getValueType(RetTyVT)); + Chain = DAG.getNode(X86ISD::FST, Tys, Ops); + RetVal = DAG.getLoad(RetTyVT, Chain, StackSlot, + DAG.getSrcValue(NULL)); + Chain = RetVal.getValue(1); + } else if (RetTyVT == MVT::f32) + RetVal = DAG.getNode(ISD::FP_ROUND, MVT::f32, RetVal); + break; + } + } + } + + Chain = DAG.getNode(ISD::CALLSEQ_END, MVT::Other, Chain, + DAG.getConstant(NumBytes, getPointerTy()), + DAG.getConstant(0, getPointerTy())); + return std::make_pair(RetVal, Chain); + } else { + std::vector<SDOperand> Ops; + Ops.push_back(Chain); + Ops.push_back(Callee); + Ops.push_back(DAG.getConstant(NumBytes, getPointerTy())); + Ops.push_back(DAG.getConstant(0, getPointerTy())); + + SDOperand TheCall = DAG.getNode(isTailCall ? X86ISD::TAILCALL : X86ISD::CALL, + RetVals, Ops); + + SDOperand ResultVal; + switch (RetTyVT) { + case MVT::isVoid: break; + default: + ResultVal = TheCall.getValue(1); + break; + case MVT::i1: + case MVT::i8: + case MVT::i16: + ResultVal = DAG.getNode(ISD::TRUNCATE, RetTyVT, TheCall.getValue(1)); + break; + case MVT::f32: + // FIXME: we would really like to remember that this FP_ROUND operation is + // okay to eliminate if we allow excess FP precision. + ResultVal = DAG.getNode(ISD::FP_ROUND, MVT::f32, TheCall.getValue(1)); + break; + case MVT::i64: + ResultVal = DAG.getNode(ISD::BUILD_PAIR, MVT::i64, TheCall.getValue(1), + TheCall.getValue(2)); + break; + } + + Chain = DAG.getNode(ISD::CALLSEQ_END, MVT::Other, TheCall); + return std::make_pair(ResultVal, Chain); + } } SDOperand @@ -1085,6 +1164,8 @@ const char *X86TargetLowering::getTargetNodeName(unsigned Opcode) const { case X86ISD::FP_TO_INT32_IN_MEM: return "X86ISD::FP_TO_INT32_IN_MEM"; case X86ISD::FP_TO_INT64_IN_MEM: return "X86ISD::FP_TO_INT64_IN_MEM"; case X86ISD::FLD: return "X86ISD::FLD"; + case X86ISD::FST: return "X86ISD::FST"; + case X86ISD::FP_GET_RESULT: return "X86ISD::FP_GET_RESULT"; case X86ISD::FP_SET_RESULT: return "X86ISD::FP_SET_RESULT"; case X86ISD::CALL: return "X86ISD::CALL"; case X86ISD::TAILCALL: return "X86ISD::TAILCALL"; |

