2008-06-17 14:27:01 +00:00
|
|
|
//===-------- LegalizeFloatTypes.cpp - Legalization of float types --------===//
|
Initial soft-float support for LegalizeTypes. I rewrote
the fcopysign expansion from LegalizeDAG to get rid of
what seems to be a bug: the use of sign extension means
that when copying the sign bit from an f32 to an f64,
the upper 32 bits of the f64 (now an i64) are set, not
just the top bit... I also generalized it to work for
any sized floating point types, and removed the bogosity:
SDOperand Mask1 = (SrcVT == MVT::f64)
? DAG.getConstantFP(BitsToDouble(1ULL << 63), SrcVT)
: DAG.getConstantFP(BitsToFloat(1U << 31), SrcVT);
Mask1 = DAG.getNode(ISD::BIT_CONVERT, SrcNVT, Mask1);
(here SrcNVT is an integer with the same size as SrcVT).
As far as I can see this takes a 1 << 63, converts to
a double, converts that to a floating point constant
then converts that to an integer constant, ending up
with... 1 << 63 as an integer constant! So I just
generate this integer constant directly.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@48305 91177308-0d34-0410-b5e6-96231b3b80d8
2008-03-12 21:27:04 +00:00
|
|
|
//
|
|
|
|
// The LLVM Compiler Infrastructure
|
|
|
|
//
|
|
|
|
// This file is distributed under the University of Illinois Open Source
|
|
|
|
// License. See LICENSE.TXT for details.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
//
|
2008-06-20 17:49:55 +00:00
|
|
|
// This file implements float type expansion and softening for LegalizeTypes.
|
|
|
|
// Softening is the act of turning a computation in an illegal floating point
|
|
|
|
// type into a computation in an integer type of the same size; also known as
|
|
|
|
// "soft float". For example, turning f32 arithmetic into operations using i32.
|
|
|
|
// The resulting integer value is the same as what you would get by performing
|
|
|
|
// the floating point operation and bitcasting the result to the integer type.
|
2008-06-17 14:27:01 +00:00
|
|
|
// Expansion is the act of changing a computation in an illegal type to be a
|
2008-06-20 18:40:50 +00:00
|
|
|
// computation in two identical registers of a smaller type. For example,
|
2008-06-17 14:27:01 +00:00
|
|
|
// implementing ppcf128 arithmetic in two f64 registers.
|
Initial soft-float support for LegalizeTypes. I rewrote
the fcopysign expansion from LegalizeDAG to get rid of
what seems to be a bug: the use of sign extension means
that when copying the sign bit from an f32 to an f64,
the upper 32 bits of the f64 (now an i64) are set, not
just the top bit... I also generalized it to work for
any sized floating point types, and removed the bogosity:
SDOperand Mask1 = (SrcVT == MVT::f64)
? DAG.getConstantFP(BitsToDouble(1ULL << 63), SrcVT)
: DAG.getConstantFP(BitsToFloat(1U << 31), SrcVT);
Mask1 = DAG.getNode(ISD::BIT_CONVERT, SrcNVT, Mask1);
(here SrcNVT is an integer with the same size as SrcVT).
As far as I can see this takes a 1 << 63, converts to
a double, converts that to a floating point constant
then converts that to an integer constant, ending up
with... 1 << 63 as an integer constant! So I just
generate this integer constant directly.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@48305 91177308-0d34-0410-b5e6-96231b3b80d8
2008-03-12 21:27:04 +00:00
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2008-06-17 14:27:01 +00:00
|
|
|
#include "LegalizeTypes.h"
|
2009-07-11 13:10:19 +00:00
|
|
|
#include "llvm/Support/ErrorHandling.h"
|
|
|
|
#include "llvm/Support/raw_ostream.h"
|
Initial soft-float support for LegalizeTypes. I rewrote
the fcopysign expansion from LegalizeDAG to get rid of
what seems to be a bug: the use of sign extension means
that when copying the sign bit from an f32 to an f64,
the upper 32 bits of the f64 (now an i64) are set, not
just the top bit... I also generalized it to work for
any sized floating point types, and removed the bogosity:
SDOperand Mask1 = (SrcVT == MVT::f64)
? DAG.getConstantFP(BitsToDouble(1ULL << 63), SrcVT)
: DAG.getConstantFP(BitsToFloat(1U << 31), SrcVT);
Mask1 = DAG.getNode(ISD::BIT_CONVERT, SrcNVT, Mask1);
(here SrcNVT is an integer with the same size as SrcVT).
As far as I can see this takes a 1 << 63, converts to
a double, converts that to a floating point constant
then converts that to an integer constant, ending up
with... 1 << 63 as an integer constant! So I just
generate this integer constant directly.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@48305 91177308-0d34-0410-b5e6-96231b3b80d8
2008-03-12 21:27:04 +00:00
|
|
|
using namespace llvm;
|
|
|
|
|
2008-04-18 20:56:03 +00:00
|
|
|
/// GetFPLibCall - Return the right libcall for the given floating point type.
|
2009-08-10 22:56:29 +00:00
|
|
|
static RTLIB::Libcall GetFPLibCall(EVT VT,
|
2008-04-18 20:56:03 +00:00
|
|
|
RTLIB::Libcall Call_F32,
|
|
|
|
RTLIB::Libcall Call_F64,
|
|
|
|
RTLIB::Libcall Call_F80,
|
|
|
|
RTLIB::Libcall Call_PPCF128) {
|
|
|
|
return
|
2009-08-11 20:47:22 +00:00
|
|
|
VT == MVT::f32 ? Call_F32 :
|
|
|
|
VT == MVT::f64 ? Call_F64 :
|
|
|
|
VT == MVT::f80 ? Call_F80 :
|
|
|
|
VT == MVT::ppcf128 ? Call_PPCF128 :
|
2008-04-18 20:56:03 +00:00
|
|
|
RTLIB::UNKNOWN_LIBCALL;
|
|
|
|
}
|
|
|
|
|
Initial soft-float support for LegalizeTypes. I rewrote
the fcopysign expansion from LegalizeDAG to get rid of
what seems to be a bug: the use of sign extension means
that when copying the sign bit from an f32 to an f64,
the upper 32 bits of the f64 (now an i64) are set, not
just the top bit... I also generalized it to work for
any sized floating point types, and removed the bogosity:
SDOperand Mask1 = (SrcVT == MVT::f64)
? DAG.getConstantFP(BitsToDouble(1ULL << 63), SrcVT)
: DAG.getConstantFP(BitsToFloat(1U << 31), SrcVT);
Mask1 = DAG.getNode(ISD::BIT_CONVERT, SrcNVT, Mask1);
(here SrcNVT is an integer with the same size as SrcVT).
As far as I can see this takes a 1 << 63, converts to
a double, converts that to a floating point constant
then converts that to an integer constant, ending up
with... 1 << 63 as an integer constant! So I just
generate this integer constant directly.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@48305 91177308-0d34-0410-b5e6-96231b3b80d8
2008-03-12 21:27:04 +00:00
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// Result Float to Integer Conversion.
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2008-06-20 17:49:55 +00:00
|
|
|
void DAGTypeLegalizer::SoftenFloatResult(SDNode *N, unsigned ResNo) {
|
2009-07-25 01:43:01 +00:00
|
|
|
DEBUG(errs() << "Soften float result " << ResNo << ": "; N->dump(&DAG);
|
|
|
|
errs() << "\n");
|
2008-07-27 21:46:04 +00:00
|
|
|
SDValue R = SDValue();
|
Initial soft-float support for LegalizeTypes. I rewrote
the fcopysign expansion from LegalizeDAG to get rid of
what seems to be a bug: the use of sign extension means
that when copying the sign bit from an f32 to an f64,
the upper 32 bits of the f64 (now an i64) are set, not
just the top bit... I also generalized it to work for
any sized floating point types, and removed the bogosity:
SDOperand Mask1 = (SrcVT == MVT::f64)
? DAG.getConstantFP(BitsToDouble(1ULL << 63), SrcVT)
: DAG.getConstantFP(BitsToFloat(1U << 31), SrcVT);
Mask1 = DAG.getNode(ISD::BIT_CONVERT, SrcNVT, Mask1);
(here SrcNVT is an integer with the same size as SrcVT).
As far as I can see this takes a 1 << 63, converts to
a double, converts that to a floating point constant
then converts that to an integer constant, ending up
with... 1 << 63 as an integer constant! So I just
generate this integer constant directly.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@48305 91177308-0d34-0410-b5e6-96231b3b80d8
2008-03-12 21:27:04 +00:00
|
|
|
|
|
|
|
switch (N->getOpcode()) {
|
|
|
|
default:
|
|
|
|
#ifndef NDEBUG
|
2009-07-25 01:43:01 +00:00
|
|
|
errs() << "SoftenFloatResult #" << ResNo << ": ";
|
|
|
|
N->dump(&DAG); errs() << "\n";
|
Initial soft-float support for LegalizeTypes. I rewrote
the fcopysign expansion from LegalizeDAG to get rid of
what seems to be a bug: the use of sign extension means
that when copying the sign bit from an f32 to an f64,
the upper 32 bits of the f64 (now an i64) are set, not
just the top bit... I also generalized it to work for
any sized floating point types, and removed the bogosity:
SDOperand Mask1 = (SrcVT == MVT::f64)
? DAG.getConstantFP(BitsToDouble(1ULL << 63), SrcVT)
: DAG.getConstantFP(BitsToFloat(1U << 31), SrcVT);
Mask1 = DAG.getNode(ISD::BIT_CONVERT, SrcNVT, Mask1);
(here SrcNVT is an integer with the same size as SrcVT).
As far as I can see this takes a 1 << 63, converts to
a double, converts that to a floating point constant
then converts that to an integer constant, ending up
with... 1 << 63 as an integer constant! So I just
generate this integer constant directly.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@48305 91177308-0d34-0410-b5e6-96231b3b80d8
2008-03-12 21:27:04 +00:00
|
|
|
#endif
|
2009-07-14 16:55:14 +00:00
|
|
|
llvm_unreachable("Do not know how to soften the result of this operator!");
|
Initial soft-float support for LegalizeTypes. I rewrote
the fcopysign expansion from LegalizeDAG to get rid of
what seems to be a bug: the use of sign extension means
that when copying the sign bit from an f32 to an f64,
the upper 32 bits of the f64 (now an i64) are set, not
just the top bit... I also generalized it to work for
any sized floating point types, and removed the bogosity:
SDOperand Mask1 = (SrcVT == MVT::f64)
? DAG.getConstantFP(BitsToDouble(1ULL << 63), SrcVT)
: DAG.getConstantFP(BitsToFloat(1U << 31), SrcVT);
Mask1 = DAG.getNode(ISD::BIT_CONVERT, SrcNVT, Mask1);
(here SrcNVT is an integer with the same size as SrcVT).
As far as I can see this takes a 1 << 63, converts to
a double, converts that to a floating point constant
then converts that to an integer constant, ending up
with... 1 << 63 as an integer constant! So I just
generate this integer constant directly.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@48305 91177308-0d34-0410-b5e6-96231b3b80d8
2008-03-12 21:27:04 +00:00
|
|
|
|
2008-06-20 17:49:55 +00:00
|
|
|
case ISD::BIT_CONVERT: R = SoftenFloatRes_BIT_CONVERT(N); break;
|
|
|
|
case ISD::BUILD_PAIR: R = SoftenFloatRes_BUILD_PAIR(N); break;
|
2008-04-18 20:56:03 +00:00
|
|
|
case ISD::ConstantFP:
|
2008-06-20 17:49:55 +00:00
|
|
|
R = SoftenFloatRes_ConstantFP(cast<ConstantFPSDNode>(N));
|
2008-04-18 20:56:03 +00:00
|
|
|
break;
|
2009-03-29 13:51:06 +00:00
|
|
|
case ISD::EXTRACT_VECTOR_ELT:
|
|
|
|
R = SoftenFloatRes_EXTRACT_VECTOR_ELT(N); break;
|
2008-08-07 19:01:24 +00:00
|
|
|
case ISD::FABS: R = SoftenFloatRes_FABS(N); break;
|
2008-07-16 11:41:33 +00:00
|
|
|
case ISD::FADD: R = SoftenFloatRes_FADD(N); break;
|
2008-11-18 09:15:03 +00:00
|
|
|
case ISD::FCEIL: R = SoftenFloatRes_FCEIL(N); break;
|
2008-06-20 17:49:55 +00:00
|
|
|
case ISD::FCOPYSIGN: R = SoftenFloatRes_FCOPYSIGN(N); break;
|
2008-11-18 09:15:03 +00:00
|
|
|
case ISD::FCOS: R = SoftenFloatRes_FCOS(N); break;
|
2008-07-18 21:18:48 +00:00
|
|
|
case ISD::FDIV: R = SoftenFloatRes_FDIV(N); break;
|
2008-11-18 09:15:03 +00:00
|
|
|
case ISD::FEXP: R = SoftenFloatRes_FEXP(N); break;
|
|
|
|
case ISD::FEXP2: R = SoftenFloatRes_FEXP2(N); break;
|
|
|
|
case ISD::FFLOOR: R = SoftenFloatRes_FFLOOR(N); break;
|
|
|
|
case ISD::FLOG: R = SoftenFloatRes_FLOG(N); break;
|
|
|
|
case ISD::FLOG2: R = SoftenFloatRes_FLOG2(N); break;
|
|
|
|
case ISD::FLOG10: R = SoftenFloatRes_FLOG10(N); break;
|
2008-07-16 11:41:33 +00:00
|
|
|
case ISD::FMUL: R = SoftenFloatRes_FMUL(N); break;
|
2008-11-18 09:15:03 +00:00
|
|
|
case ISD::FNEARBYINT: R = SoftenFloatRes_FNEARBYINT(N); break;
|
|
|
|
case ISD::FNEG: R = SoftenFloatRes_FNEG(N); break;
|
2008-07-08 10:50:55 +00:00
|
|
|
case ISD::FP_EXTEND: R = SoftenFloatRes_FP_EXTEND(N); break;
|
|
|
|
case ISD::FP_ROUND: R = SoftenFloatRes_FP_ROUND(N); break;
|
2008-10-22 11:49:09 +00:00
|
|
|
case ISD::FPOW: R = SoftenFloatRes_FPOW(N); break;
|
2008-07-16 11:41:33 +00:00
|
|
|
case ISD::FPOWI: R = SoftenFloatRes_FPOWI(N); break;
|
2009-04-08 16:20:57 +00:00
|
|
|
case ISD::FREM: R = SoftenFloatRes_FREM(N); break;
|
2008-11-18 09:15:03 +00:00
|
|
|
case ISD::FRINT: R = SoftenFloatRes_FRINT(N); break;
|
|
|
|
case ISD::FSIN: R = SoftenFloatRes_FSIN(N); break;
|
|
|
|
case ISD::FSQRT: R = SoftenFloatRes_FSQRT(N); break;
|
2008-07-16 11:41:33 +00:00
|
|
|
case ISD::FSUB: R = SoftenFloatRes_FSUB(N); break;
|
2008-11-18 09:15:03 +00:00
|
|
|
case ISD::FTRUNC: R = SoftenFloatRes_FTRUNC(N); break;
|
2008-06-20 17:49:55 +00:00
|
|
|
case ISD::LOAD: R = SoftenFloatRes_LOAD(N); break;
|
2008-07-08 20:03:24 +00:00
|
|
|
case ISD::SELECT: R = SoftenFloatRes_SELECT(N); break;
|
|
|
|
case ISD::SELECT_CC: R = SoftenFloatRes_SELECT_CC(N); break;
|
2008-11-10 17:36:26 +00:00
|
|
|
case ISD::SINT_TO_FP:
|
|
|
|
case ISD::UINT_TO_FP: R = SoftenFloatRes_XINT_TO_FP(N); break;
|
2009-04-08 13:33:37 +00:00
|
|
|
case ISD::UNDEF: R = SoftenFloatRes_UNDEF(N); break;
|
2009-02-21 19:11:18 +00:00
|
|
|
case ISD::VAARG: R = SoftenFloatRes_VAARG(N); break;
|
Initial soft-float support for LegalizeTypes. I rewrote
the fcopysign expansion from LegalizeDAG to get rid of
what seems to be a bug: the use of sign extension means
that when copying the sign bit from an f32 to an f64,
the upper 32 bits of the f64 (now an i64) are set, not
just the top bit... I also generalized it to work for
any sized floating point types, and removed the bogosity:
SDOperand Mask1 = (SrcVT == MVT::f64)
? DAG.getConstantFP(BitsToDouble(1ULL << 63), SrcVT)
: DAG.getConstantFP(BitsToFloat(1U << 31), SrcVT);
Mask1 = DAG.getNode(ISD::BIT_CONVERT, SrcNVT, Mask1);
(here SrcNVT is an integer with the same size as SrcVT).
As far as I can see this takes a 1 << 63, converts to
a double, converts that to a floating point constant
then converts that to an integer constant, ending up
with... 1 << 63 as an integer constant! So I just
generate this integer constant directly.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@48305 91177308-0d34-0410-b5e6-96231b3b80d8
2008-03-12 21:27:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// If R is null, the sub-method took care of registering the result.
|
2008-08-28 21:40:38 +00:00
|
|
|
if (R.getNode())
|
2008-07-27 21:46:04 +00:00
|
|
|
SetSoftenedFloat(SDValue(N, ResNo), R);
|
Initial soft-float support for LegalizeTypes. I rewrote
the fcopysign expansion from LegalizeDAG to get rid of
what seems to be a bug: the use of sign extension means
that when copying the sign bit from an f32 to an f64,
the upper 32 bits of the f64 (now an i64) are set, not
just the top bit... I also generalized it to work for
any sized floating point types, and removed the bogosity:
SDOperand Mask1 = (SrcVT == MVT::f64)
? DAG.getConstantFP(BitsToDouble(1ULL << 63), SrcVT)
: DAG.getConstantFP(BitsToFloat(1U << 31), SrcVT);
Mask1 = DAG.getNode(ISD::BIT_CONVERT, SrcNVT, Mask1);
(here SrcNVT is an integer with the same size as SrcVT).
As far as I can see this takes a 1 << 63, converts to
a double, converts that to a floating point constant
then converts that to an integer constant, ending up
with... 1 << 63 as an integer constant! So I just
generate this integer constant directly.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@48305 91177308-0d34-0410-b5e6-96231b3b80d8
2008-03-12 21:27:04 +00:00
|
|
|
}
|
|
|
|
|
2008-07-27 21:46:04 +00:00
|
|
|
SDValue DAGTypeLegalizer::SoftenFloatRes_BIT_CONVERT(SDNode *N) {
|
Initial soft-float support for LegalizeTypes. I rewrote
the fcopysign expansion from LegalizeDAG to get rid of
what seems to be a bug: the use of sign extension means
that when copying the sign bit from an f32 to an f64,
the upper 32 bits of the f64 (now an i64) are set, not
just the top bit... I also generalized it to work for
any sized floating point types, and removed the bogosity:
SDOperand Mask1 = (SrcVT == MVT::f64)
? DAG.getConstantFP(BitsToDouble(1ULL << 63), SrcVT)
: DAG.getConstantFP(BitsToFloat(1U << 31), SrcVT);
Mask1 = DAG.getNode(ISD::BIT_CONVERT, SrcNVT, Mask1);
(here SrcNVT is an integer with the same size as SrcVT).
As far as I can see this takes a 1 << 63, converts to
a double, converts that to a floating point constant
then converts that to an integer constant, ending up
with... 1 << 63 as an integer constant! So I just
generate this integer constant directly.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@48305 91177308-0d34-0410-b5e6-96231b3b80d8
2008-03-12 21:27:04 +00:00
|
|
|
return BitConvertToInteger(N->getOperand(0));
|
|
|
|
}
|
|
|
|
|
2008-07-27 21:46:04 +00:00
|
|
|
SDValue DAGTypeLegalizer::SoftenFloatRes_BUILD_PAIR(SDNode *N) {
|
Initial soft-float support for LegalizeTypes. I rewrote
the fcopysign expansion from LegalizeDAG to get rid of
what seems to be a bug: the use of sign extension means
that when copying the sign bit from an f32 to an f64,
the upper 32 bits of the f64 (now an i64) are set, not
just the top bit... I also generalized it to work for
any sized floating point types, and removed the bogosity:
SDOperand Mask1 = (SrcVT == MVT::f64)
? DAG.getConstantFP(BitsToDouble(1ULL << 63), SrcVT)
: DAG.getConstantFP(BitsToFloat(1U << 31), SrcVT);
Mask1 = DAG.getNode(ISD::BIT_CONVERT, SrcNVT, Mask1);
(here SrcNVT is an integer with the same size as SrcVT).
As far as I can see this takes a 1 << 63, converts to
a double, converts that to a floating point constant
then converts that to an integer constant, ending up
with... 1 << 63 as an integer constant! So I just
generate this integer constant directly.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@48305 91177308-0d34-0410-b5e6-96231b3b80d8
2008-03-12 21:27:04 +00:00
|
|
|
// Convert the inputs to integers, and build a new pair out of them.
|
2009-01-31 00:43:08 +00:00
|
|
|
return DAG.getNode(ISD::BUILD_PAIR, N->getDebugLoc(),
|
2009-08-12 00:36:31 +00:00
|
|
|
TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0)),
|
Initial soft-float support for LegalizeTypes. I rewrote
the fcopysign expansion from LegalizeDAG to get rid of
what seems to be a bug: the use of sign extension means
that when copying the sign bit from an f32 to an f64,
the upper 32 bits of the f64 (now an i64) are set, not
just the top bit... I also generalized it to work for
any sized floating point types, and removed the bogosity:
SDOperand Mask1 = (SrcVT == MVT::f64)
? DAG.getConstantFP(BitsToDouble(1ULL << 63), SrcVT)
: DAG.getConstantFP(BitsToFloat(1U << 31), SrcVT);
Mask1 = DAG.getNode(ISD::BIT_CONVERT, SrcNVT, Mask1);
(here SrcNVT is an integer with the same size as SrcVT).
As far as I can see this takes a 1 << 63, converts to
a double, converts that to a floating point constant
then converts that to an integer constant, ending up
with... 1 << 63 as an integer constant! So I just
generate this integer constant directly.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@48305 91177308-0d34-0410-b5e6-96231b3b80d8
2008-03-12 21:27:04 +00:00
|
|
|
BitConvertToInteger(N->getOperand(0)),
|
|
|
|
BitConvertToInteger(N->getOperand(1)));
|
|
|
|
}
|
|
|
|
|
2008-07-27 21:46:04 +00:00
|
|
|
SDValue DAGTypeLegalizer::SoftenFloatRes_ConstantFP(ConstantFPSDNode *N) {
|
2008-10-09 18:53:47 +00:00
|
|
|
return DAG.getConstant(N->getValueAPF().bitcastToAPInt(),
|
2009-08-12 00:36:31 +00:00
|
|
|
TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0)));
|
2008-04-18 20:56:03 +00:00
|
|
|
}
|
|
|
|
|
2009-03-29 13:51:06 +00:00
|
|
|
SDValue DAGTypeLegalizer::SoftenFloatRes_EXTRACT_VECTOR_ELT(SDNode *N) {
|
|
|
|
SDValue NewOp = BitConvertVectorToIntegerVector(N->getOperand(0));
|
|
|
|
return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, N->getDebugLoc(),
|
|
|
|
NewOp.getValueType().getVectorElementType(),
|
|
|
|
NewOp, N->getOperand(1));
|
|
|
|
}
|
|
|
|
|
2008-08-07 19:01:24 +00:00
|
|
|
SDValue DAGTypeLegalizer::SoftenFloatRes_FABS(SDNode *N) {
|
2009-08-12 00:36:31 +00:00
|
|
|
EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
|
2008-08-07 19:01:24 +00:00
|
|
|
unsigned Size = NVT.getSizeInBits();
|
|
|
|
|
|
|
|
// Mask = ~(1 << (Size-1))
|
2008-11-18 09:15:03 +00:00
|
|
|
SDValue Mask = DAG.getConstant(APInt::getAllOnesValue(Size).clear(Size-1),
|
2008-08-07 19:01:24 +00:00
|
|
|
NVT);
|
|
|
|
SDValue Op = GetSoftenedFloat(N->getOperand(0));
|
2009-01-31 00:43:08 +00:00
|
|
|
return DAG.getNode(ISD::AND, N->getDebugLoc(), NVT, Op, Mask);
|
2008-08-07 19:01:24 +00:00
|
|
|
}
|
|
|
|
|
2008-07-27 21:46:04 +00:00
|
|
|
SDValue DAGTypeLegalizer::SoftenFloatRes_FADD(SDNode *N) {
|
2009-08-12 00:36:31 +00:00
|
|
|
EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
|
2008-07-27 21:46:04 +00:00
|
|
|
SDValue Ops[2] = { GetSoftenedFloat(N->getOperand(0)),
|
2008-10-31 14:06:52 +00:00
|
|
|
GetSoftenedFloat(N->getOperand(1)) };
|
2008-04-18 20:56:03 +00:00
|
|
|
return MakeLibCall(GetFPLibCall(N->getValueType(0),
|
|
|
|
RTLIB::ADD_F32,
|
|
|
|
RTLIB::ADD_F64,
|
|
|
|
RTLIB::ADD_F80,
|
|
|
|
RTLIB::ADD_PPCF128),
|
2009-01-31 00:11:23 +00:00
|
|
|
NVT, Ops, 2, false, N->getDebugLoc());
|
2008-04-18 20:56:03 +00:00
|
|
|
}
|
|
|
|
|
2008-11-18 09:15:03 +00:00
|
|
|
SDValue DAGTypeLegalizer::SoftenFloatRes_FCEIL(SDNode *N) {
|
2009-08-12 00:36:31 +00:00
|
|
|
EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
|
2008-11-18 09:15:03 +00:00
|
|
|
SDValue Op = GetSoftenedFloat(N->getOperand(0));
|
|
|
|
return MakeLibCall(GetFPLibCall(N->getValueType(0),
|
|
|
|
RTLIB::CEIL_F32,
|
|
|
|
RTLIB::CEIL_F64,
|
|
|
|
RTLIB::CEIL_F80,
|
|
|
|
RTLIB::CEIL_PPCF128),
|
2009-01-31 00:11:23 +00:00
|
|
|
NVT, &Op, 1, false, N->getDebugLoc());
|
2008-11-18 09:15:03 +00:00
|
|
|
}
|
|
|
|
|
2008-07-27 21:46:04 +00:00
|
|
|
SDValue DAGTypeLegalizer::SoftenFloatRes_FCOPYSIGN(SDNode *N) {
|
|
|
|
SDValue LHS = GetSoftenedFloat(N->getOperand(0));
|
|
|
|
SDValue RHS = BitConvertToInteger(N->getOperand(1));
|
2009-01-31 00:43:08 +00:00
|
|
|
DebugLoc dl = N->getDebugLoc();
|
Initial soft-float support for LegalizeTypes. I rewrote
the fcopysign expansion from LegalizeDAG to get rid of
what seems to be a bug: the use of sign extension means
that when copying the sign bit from an f32 to an f64,
the upper 32 bits of the f64 (now an i64) are set, not
just the top bit... I also generalized it to work for
any sized floating point types, and removed the bogosity:
SDOperand Mask1 = (SrcVT == MVT::f64)
? DAG.getConstantFP(BitsToDouble(1ULL << 63), SrcVT)
: DAG.getConstantFP(BitsToFloat(1U << 31), SrcVT);
Mask1 = DAG.getNode(ISD::BIT_CONVERT, SrcNVT, Mask1);
(here SrcNVT is an integer with the same size as SrcVT).
As far as I can see this takes a 1 << 63, converts to
a double, converts that to a floating point constant
then converts that to an integer constant, ending up
with... 1 << 63 as an integer constant! So I just
generate this integer constant directly.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@48305 91177308-0d34-0410-b5e6-96231b3b80d8
2008-03-12 21:27:04 +00:00
|
|
|
|
2009-08-10 22:56:29 +00:00
|
|
|
EVT LVT = LHS.getValueType();
|
|
|
|
EVT RVT = RHS.getValueType();
|
Initial soft-float support for LegalizeTypes. I rewrote
the fcopysign expansion from LegalizeDAG to get rid of
what seems to be a bug: the use of sign extension means
that when copying the sign bit from an f32 to an f64,
the upper 32 bits of the f64 (now an i64) are set, not
just the top bit... I also generalized it to work for
any sized floating point types, and removed the bogosity:
SDOperand Mask1 = (SrcVT == MVT::f64)
? DAG.getConstantFP(BitsToDouble(1ULL << 63), SrcVT)
: DAG.getConstantFP(BitsToFloat(1U << 31), SrcVT);
Mask1 = DAG.getNode(ISD::BIT_CONVERT, SrcNVT, Mask1);
(here SrcNVT is an integer with the same size as SrcVT).
As far as I can see this takes a 1 << 63, converts to
a double, converts that to a floating point constant
then converts that to an integer constant, ending up
with... 1 << 63 as an integer constant! So I just
generate this integer constant directly.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@48305 91177308-0d34-0410-b5e6-96231b3b80d8
2008-03-12 21:27:04 +00:00
|
|
|
|
2008-06-06 12:08:01 +00:00
|
|
|
unsigned LSize = LVT.getSizeInBits();
|
|
|
|
unsigned RSize = RVT.getSizeInBits();
|
Initial soft-float support for LegalizeTypes. I rewrote
the fcopysign expansion from LegalizeDAG to get rid of
what seems to be a bug: the use of sign extension means
that when copying the sign bit from an f32 to an f64,
the upper 32 bits of the f64 (now an i64) are set, not
just the top bit... I also generalized it to work for
any sized floating point types, and removed the bogosity:
SDOperand Mask1 = (SrcVT == MVT::f64)
? DAG.getConstantFP(BitsToDouble(1ULL << 63), SrcVT)
: DAG.getConstantFP(BitsToFloat(1U << 31), SrcVT);
Mask1 = DAG.getNode(ISD::BIT_CONVERT, SrcNVT, Mask1);
(here SrcNVT is an integer with the same size as SrcVT).
As far as I can see this takes a 1 << 63, converts to
a double, converts that to a floating point constant
then converts that to an integer constant, ending up
with... 1 << 63 as an integer constant! So I just
generate this integer constant directly.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@48305 91177308-0d34-0410-b5e6-96231b3b80d8
2008-03-12 21:27:04 +00:00
|
|
|
|
|
|
|
// First get the sign bit of second operand.
|
2009-01-31 00:43:08 +00:00
|
|
|
SDValue SignBit = DAG.getNode(ISD::SHL, dl, RVT, DAG.getConstant(1, RVT),
|
Initial soft-float support for LegalizeTypes. I rewrote
the fcopysign expansion from LegalizeDAG to get rid of
what seems to be a bug: the use of sign extension means
that when copying the sign bit from an f32 to an f64,
the upper 32 bits of the f64 (now an i64) are set, not
just the top bit... I also generalized it to work for
any sized floating point types, and removed the bogosity:
SDOperand Mask1 = (SrcVT == MVT::f64)
? DAG.getConstantFP(BitsToDouble(1ULL << 63), SrcVT)
: DAG.getConstantFP(BitsToFloat(1U << 31), SrcVT);
Mask1 = DAG.getNode(ISD::BIT_CONVERT, SrcNVT, Mask1);
(here SrcNVT is an integer with the same size as SrcVT).
As far as I can see this takes a 1 << 63, converts to
a double, converts that to a floating point constant
then converts that to an integer constant, ending up
with... 1 << 63 as an integer constant! So I just
generate this integer constant directly.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@48305 91177308-0d34-0410-b5e6-96231b3b80d8
2008-03-12 21:27:04 +00:00
|
|
|
DAG.getConstant(RSize - 1,
|
|
|
|
TLI.getShiftAmountTy()));
|
2009-01-31 00:43:08 +00:00
|
|
|
SignBit = DAG.getNode(ISD::AND, dl, RVT, RHS, SignBit);
|
Initial soft-float support for LegalizeTypes. I rewrote
the fcopysign expansion from LegalizeDAG to get rid of
what seems to be a bug: the use of sign extension means
that when copying the sign bit from an f32 to an f64,
the upper 32 bits of the f64 (now an i64) are set, not
just the top bit... I also generalized it to work for
any sized floating point types, and removed the bogosity:
SDOperand Mask1 = (SrcVT == MVT::f64)
? DAG.getConstantFP(BitsToDouble(1ULL << 63), SrcVT)
: DAG.getConstantFP(BitsToFloat(1U << 31), SrcVT);
Mask1 = DAG.getNode(ISD::BIT_CONVERT, SrcNVT, Mask1);
(here SrcNVT is an integer with the same size as SrcVT).
As far as I can see this takes a 1 << 63, converts to
a double, converts that to a floating point constant
then converts that to an integer constant, ending up
with... 1 << 63 as an integer constant! So I just
generate this integer constant directly.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@48305 91177308-0d34-0410-b5e6-96231b3b80d8
2008-03-12 21:27:04 +00:00
|
|
|
|
|
|
|
// Shift right or sign-extend it if the two operands have different types.
|
2008-06-06 12:08:01 +00:00
|
|
|
int SizeDiff = RVT.getSizeInBits() - LVT.getSizeInBits();
|
Initial soft-float support for LegalizeTypes. I rewrote
the fcopysign expansion from LegalizeDAG to get rid of
what seems to be a bug: the use of sign extension means
that when copying the sign bit from an f32 to an f64,
the upper 32 bits of the f64 (now an i64) are set, not
just the top bit... I also generalized it to work for
any sized floating point types, and removed the bogosity:
SDOperand Mask1 = (SrcVT == MVT::f64)
? DAG.getConstantFP(BitsToDouble(1ULL << 63), SrcVT)
: DAG.getConstantFP(BitsToFloat(1U << 31), SrcVT);
Mask1 = DAG.getNode(ISD::BIT_CONVERT, SrcNVT, Mask1);
(here SrcNVT is an integer with the same size as SrcVT).
As far as I can see this takes a 1 << 63, converts to
a double, converts that to a floating point constant
then converts that to an integer constant, ending up
with... 1 << 63 as an integer constant! So I just
generate this integer constant directly.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@48305 91177308-0d34-0410-b5e6-96231b3b80d8
2008-03-12 21:27:04 +00:00
|
|
|
if (SizeDiff > 0) {
|
2009-01-31 00:43:08 +00:00
|
|
|
SignBit = DAG.getNode(ISD::SRL, dl, RVT, SignBit,
|
Initial soft-float support for LegalizeTypes. I rewrote
the fcopysign expansion from LegalizeDAG to get rid of
what seems to be a bug: the use of sign extension means
that when copying the sign bit from an f32 to an f64,
the upper 32 bits of the f64 (now an i64) are set, not
just the top bit... I also generalized it to work for
any sized floating point types, and removed the bogosity:
SDOperand Mask1 = (SrcVT == MVT::f64)
? DAG.getConstantFP(BitsToDouble(1ULL << 63), SrcVT)
: DAG.getConstantFP(BitsToFloat(1U << 31), SrcVT);
Mask1 = DAG.getNode(ISD::BIT_CONVERT, SrcNVT, Mask1);
(here SrcNVT is an integer with the same size as SrcVT).
As far as I can see this takes a 1 << 63, converts to
a double, converts that to a floating point constant
then converts that to an integer constant, ending up
with... 1 << 63 as an integer constant! So I just
generate this integer constant directly.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@48305 91177308-0d34-0410-b5e6-96231b3b80d8
2008-03-12 21:27:04 +00:00
|
|
|
DAG.getConstant(SizeDiff, TLI.getShiftAmountTy()));
|
2009-01-31 00:43:08 +00:00
|
|
|
SignBit = DAG.getNode(ISD::TRUNCATE, dl, LVT, SignBit);
|
Initial soft-float support for LegalizeTypes. I rewrote
the fcopysign expansion from LegalizeDAG to get rid of
what seems to be a bug: the use of sign extension means
that when copying the sign bit from an f32 to an f64,
the upper 32 bits of the f64 (now an i64) are set, not
just the top bit... I also generalized it to work for
any sized floating point types, and removed the bogosity:
SDOperand Mask1 = (SrcVT == MVT::f64)
? DAG.getConstantFP(BitsToDouble(1ULL << 63), SrcVT)
: DAG.getConstantFP(BitsToFloat(1U << 31), SrcVT);
Mask1 = DAG.getNode(ISD::BIT_CONVERT, SrcNVT, Mask1);
(here SrcNVT is an integer with the same size as SrcVT).
As far as I can see this takes a 1 << 63, converts to
a double, converts that to a floating point constant
then converts that to an integer constant, ending up
with... 1 << 63 as an integer constant! So I just
generate this integer constant directly.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@48305 91177308-0d34-0410-b5e6-96231b3b80d8
2008-03-12 21:27:04 +00:00
|
|
|
} else if (SizeDiff < 0) {
|
2009-01-31 00:43:08 +00:00
|
|
|
SignBit = DAG.getNode(ISD::ANY_EXTEND, dl, LVT, SignBit);
|
|
|
|
SignBit = DAG.getNode(ISD::SHL, dl, LVT, SignBit,
|
Initial soft-float support for LegalizeTypes. I rewrote
the fcopysign expansion from LegalizeDAG to get rid of
what seems to be a bug: the use of sign extension means
that when copying the sign bit from an f32 to an f64,
the upper 32 bits of the f64 (now an i64) are set, not
just the top bit... I also generalized it to work for
any sized floating point types, and removed the bogosity:
SDOperand Mask1 = (SrcVT == MVT::f64)
? DAG.getConstantFP(BitsToDouble(1ULL << 63), SrcVT)
: DAG.getConstantFP(BitsToFloat(1U << 31), SrcVT);
Mask1 = DAG.getNode(ISD::BIT_CONVERT, SrcNVT, Mask1);
(here SrcNVT is an integer with the same size as SrcVT).
As far as I can see this takes a 1 << 63, converts to
a double, converts that to a floating point constant
then converts that to an integer constant, ending up
with... 1 << 63 as an integer constant! So I just
generate this integer constant directly.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@48305 91177308-0d34-0410-b5e6-96231b3b80d8
2008-03-12 21:27:04 +00:00
|
|
|
DAG.getConstant(-SizeDiff, TLI.getShiftAmountTy()));
|
|
|
|
}
|
|
|
|
|
|
|
|
// Clear the sign bit of the first operand.
|
2009-01-31 00:43:08 +00:00
|
|
|
SDValue Mask = DAG.getNode(ISD::SHL, dl, LVT, DAG.getConstant(1, LVT),
|
Initial soft-float support for LegalizeTypes. I rewrote
the fcopysign expansion from LegalizeDAG to get rid of
what seems to be a bug: the use of sign extension means
that when copying the sign bit from an f32 to an f64,
the upper 32 bits of the f64 (now an i64) are set, not
just the top bit... I also generalized it to work for
any sized floating point types, and removed the bogosity:
SDOperand Mask1 = (SrcVT == MVT::f64)
? DAG.getConstantFP(BitsToDouble(1ULL << 63), SrcVT)
: DAG.getConstantFP(BitsToFloat(1U << 31), SrcVT);
Mask1 = DAG.getNode(ISD::BIT_CONVERT, SrcNVT, Mask1);
(here SrcNVT is an integer with the same size as SrcVT).
As far as I can see this takes a 1 << 63, converts to
a double, converts that to a floating point constant
then converts that to an integer constant, ending up
with... 1 << 63 as an integer constant! So I just
generate this integer constant directly.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@48305 91177308-0d34-0410-b5e6-96231b3b80d8
2008-03-12 21:27:04 +00:00
|
|
|
DAG.getConstant(LSize - 1,
|
|
|
|
TLI.getShiftAmountTy()));
|
2009-01-31 00:43:08 +00:00
|
|
|
Mask = DAG.getNode(ISD::SUB, dl, LVT, Mask, DAG.getConstant(1, LVT));
|
|
|
|
LHS = DAG.getNode(ISD::AND, dl, LVT, LHS, Mask);
|
Initial soft-float support for LegalizeTypes. I rewrote
the fcopysign expansion from LegalizeDAG to get rid of
what seems to be a bug: the use of sign extension means
that when copying the sign bit from an f32 to an f64,
the upper 32 bits of the f64 (now an i64) are set, not
just the top bit... I also generalized it to work for
any sized floating point types, and removed the bogosity:
SDOperand Mask1 = (SrcVT == MVT::f64)
? DAG.getConstantFP(BitsToDouble(1ULL << 63), SrcVT)
: DAG.getConstantFP(BitsToFloat(1U << 31), SrcVT);
Mask1 = DAG.getNode(ISD::BIT_CONVERT, SrcNVT, Mask1);
(here SrcNVT is an integer with the same size as SrcVT).
As far as I can see this takes a 1 << 63, converts to
a double, converts that to a floating point constant
then converts that to an integer constant, ending up
with... 1 << 63 as an integer constant! So I just
generate this integer constant directly.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@48305 91177308-0d34-0410-b5e6-96231b3b80d8
2008-03-12 21:27:04 +00:00
|
|
|
|
|
|
|
// Or the value with the sign bit.
|
2009-01-31 00:43:08 +00:00
|
|
|
return DAG.getNode(ISD::OR, dl, LVT, LHS, SignBit);
|
Initial soft-float support for LegalizeTypes. I rewrote
the fcopysign expansion from LegalizeDAG to get rid of
what seems to be a bug: the use of sign extension means
that when copying the sign bit from an f32 to an f64,
the upper 32 bits of the f64 (now an i64) are set, not
just the top bit... I also generalized it to work for
any sized floating point types, and removed the bogosity:
SDOperand Mask1 = (SrcVT == MVT::f64)
? DAG.getConstantFP(BitsToDouble(1ULL << 63), SrcVT)
: DAG.getConstantFP(BitsToFloat(1U << 31), SrcVT);
Mask1 = DAG.getNode(ISD::BIT_CONVERT, SrcNVT, Mask1);
(here SrcNVT is an integer with the same size as SrcVT).
As far as I can see this takes a 1 << 63, converts to
a double, converts that to a floating point constant
then converts that to an integer constant, ending up
with... 1 << 63 as an integer constant! So I just
generate this integer constant directly.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@48305 91177308-0d34-0410-b5e6-96231b3b80d8
2008-03-12 21:27:04 +00:00
|
|
|
}
|
|
|
|
|
2008-11-18 09:15:03 +00:00
|
|
|
SDValue DAGTypeLegalizer::SoftenFloatRes_FCOS(SDNode *N) {
|
2009-08-12 00:36:31 +00:00
|
|
|
EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
|
2008-11-18 09:15:03 +00:00
|
|
|
SDValue Op = GetSoftenedFloat(N->getOperand(0));
|
|
|
|
return MakeLibCall(GetFPLibCall(N->getValueType(0),
|
|
|
|
RTLIB::COS_F32,
|
|
|
|
RTLIB::COS_F64,
|
|
|
|
RTLIB::COS_F80,
|
|
|
|
RTLIB::COS_PPCF128),
|
2009-01-31 00:11:23 +00:00
|
|
|
NVT, &Op, 1, false, N->getDebugLoc());
|
2008-11-18 09:15:03 +00:00
|
|
|
}
|
|
|
|
|
2008-07-27 21:46:04 +00:00
|
|
|
SDValue DAGTypeLegalizer::SoftenFloatRes_FDIV(SDNode *N) {
|
2009-08-12 00:36:31 +00:00
|
|
|
EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
|
2008-07-27 21:46:04 +00:00
|
|
|
SDValue Ops[2] = { GetSoftenedFloat(N->getOperand(0)),
|
2008-10-22 11:49:09 +00:00
|
|
|
GetSoftenedFloat(N->getOperand(1)) };
|
2008-07-18 21:18:48 +00:00
|
|
|
return MakeLibCall(GetFPLibCall(N->getValueType(0),
|
|
|
|
RTLIB::DIV_F32,
|
|
|
|
RTLIB::DIV_F64,
|
|
|
|
RTLIB::DIV_F80,
|
|
|
|
RTLIB::DIV_PPCF128),
|
2009-01-31 00:11:23 +00:00
|
|
|
NVT, Ops, 2, false, N->getDebugLoc());
|
2008-07-18 21:18:48 +00:00
|
|
|
}
|
|
|
|
|
2008-11-18 09:15:03 +00:00
|
|
|
SDValue DAGTypeLegalizer::SoftenFloatRes_FEXP(SDNode *N) {
|
2009-08-12 00:36:31 +00:00
|
|
|
EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
|
2008-11-18 09:15:03 +00:00
|
|
|
SDValue Op = GetSoftenedFloat(N->getOperand(0));
|
|
|
|
return MakeLibCall(GetFPLibCall(N->getValueType(0),
|
|
|
|
RTLIB::EXP_F32,
|
|
|
|
RTLIB::EXP_F64,
|
|
|
|
RTLIB::EXP_F80,
|
|
|
|
RTLIB::EXP_PPCF128),
|
2009-01-31 00:11:23 +00:00
|
|
|
NVT, &Op, 1, false, N->getDebugLoc());
|
2008-11-18 09:15:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
SDValue DAGTypeLegalizer::SoftenFloatRes_FEXP2(SDNode *N) {
|
2009-08-12 00:36:31 +00:00
|
|
|
EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
|
2008-11-18 09:15:03 +00:00
|
|
|
SDValue Op = GetSoftenedFloat(N->getOperand(0));
|
|
|
|
return MakeLibCall(GetFPLibCall(N->getValueType(0),
|
|
|
|
RTLIB::EXP2_F32,
|
|
|
|
RTLIB::EXP2_F64,
|
|
|
|
RTLIB::EXP2_F80,
|
|
|
|
RTLIB::EXP2_PPCF128),
|
2009-01-31 00:11:23 +00:00
|
|
|
NVT, &Op, 1, false, N->getDebugLoc());
|
2008-11-18 09:15:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
SDValue DAGTypeLegalizer::SoftenFloatRes_FFLOOR(SDNode *N) {
|
2009-08-12 00:36:31 +00:00
|
|
|
EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
|
2008-11-18 09:15:03 +00:00
|
|
|
SDValue Op = GetSoftenedFloat(N->getOperand(0));
|
|
|
|
return MakeLibCall(GetFPLibCall(N->getValueType(0),
|
|
|
|
RTLIB::FLOOR_F32,
|
|
|
|
RTLIB::FLOOR_F64,
|
|
|
|
RTLIB::FLOOR_F80,
|
|
|
|
RTLIB::FLOOR_PPCF128),
|
2009-01-31 00:11:23 +00:00
|
|
|
NVT, &Op, 1, false, N->getDebugLoc());
|
2008-11-18 09:15:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
SDValue DAGTypeLegalizer::SoftenFloatRes_FLOG(SDNode *N) {
|
2009-08-12 00:36:31 +00:00
|
|
|
EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
|
2008-11-18 09:15:03 +00:00
|
|
|
SDValue Op = GetSoftenedFloat(N->getOperand(0));
|
|
|
|
return MakeLibCall(GetFPLibCall(N->getValueType(0),
|
|
|
|
RTLIB::LOG_F32,
|
|
|
|
RTLIB::LOG_F64,
|
|
|
|
RTLIB::LOG_F80,
|
|
|
|
RTLIB::LOG_PPCF128),
|
2009-01-31 00:11:23 +00:00
|
|
|
NVT, &Op, 1, false, N->getDebugLoc());
|
2008-11-18 09:15:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
SDValue DAGTypeLegalizer::SoftenFloatRes_FLOG2(SDNode *N) {
|
2009-08-12 00:36:31 +00:00
|
|
|
EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
|
2008-11-18 09:15:03 +00:00
|
|
|
SDValue Op = GetSoftenedFloat(N->getOperand(0));
|
|
|
|
return MakeLibCall(GetFPLibCall(N->getValueType(0),
|
|
|
|
RTLIB::LOG2_F32,
|
|
|
|
RTLIB::LOG2_F64,
|
|
|
|
RTLIB::LOG2_F80,
|
|
|
|
RTLIB::LOG2_PPCF128),
|
2009-01-31 00:11:23 +00:00
|
|
|
NVT, &Op, 1, false, N->getDebugLoc());
|
2008-11-18 09:15:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
SDValue DAGTypeLegalizer::SoftenFloatRes_FLOG10(SDNode *N) {
|
2009-08-12 00:36:31 +00:00
|
|
|
EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
|
2008-11-18 09:15:03 +00:00
|
|
|
SDValue Op = GetSoftenedFloat(N->getOperand(0));
|
|
|
|
return MakeLibCall(GetFPLibCall(N->getValueType(0),
|
|
|
|
RTLIB::LOG10_F32,
|
|
|
|
RTLIB::LOG10_F64,
|
|
|
|
RTLIB::LOG10_F80,
|
|
|
|
RTLIB::LOG10_PPCF128),
|
2009-01-31 00:11:23 +00:00
|
|
|
NVT, &Op, 1, false, N->getDebugLoc());
|
2008-11-18 09:15:03 +00:00
|
|
|
}
|
|
|
|
|
2008-07-27 21:46:04 +00:00
|
|
|
SDValue DAGTypeLegalizer::SoftenFloatRes_FMUL(SDNode *N) {
|
2009-08-12 00:36:31 +00:00
|
|
|
EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
|
2008-07-27 21:46:04 +00:00
|
|
|
SDValue Ops[2] = { GetSoftenedFloat(N->getOperand(0)),
|
2008-10-31 14:06:52 +00:00
|
|
|
GetSoftenedFloat(N->getOperand(1)) };
|
2008-04-18 20:56:03 +00:00
|
|
|
return MakeLibCall(GetFPLibCall(N->getValueType(0),
|
|
|
|
RTLIB::MUL_F32,
|
|
|
|
RTLIB::MUL_F64,
|
|
|
|
RTLIB::MUL_F80,
|
|
|
|
RTLIB::MUL_PPCF128),
|
2009-01-31 00:11:23 +00:00
|
|
|
NVT, Ops, 2, false, N->getDebugLoc());
|
2008-04-18 20:56:03 +00:00
|
|
|
}
|
|
|
|
|
2008-11-18 09:15:03 +00:00
|
|
|
SDValue DAGTypeLegalizer::SoftenFloatRes_FNEARBYINT(SDNode *N) {
|
2009-08-12 00:36:31 +00:00
|
|
|
EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
|
2008-11-18 09:15:03 +00:00
|
|
|
SDValue Op = GetSoftenedFloat(N->getOperand(0));
|
|
|
|
return MakeLibCall(GetFPLibCall(N->getValueType(0),
|
|
|
|
RTLIB::NEARBYINT_F32,
|
|
|
|
RTLIB::NEARBYINT_F64,
|
|
|
|
RTLIB::NEARBYINT_F80,
|
|
|
|
RTLIB::NEARBYINT_PPCF128),
|
2009-01-31 00:11:23 +00:00
|
|
|
NVT, &Op, 1, false, N->getDebugLoc());
|
2008-11-18 09:15:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
SDValue DAGTypeLegalizer::SoftenFloatRes_FNEG(SDNode *N) {
|
2009-08-12 00:36:31 +00:00
|
|
|
EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
|
2008-11-18 09:15:03 +00:00
|
|
|
// Expand Y = FNEG(X) -> Y = SUB -0.0, X
|
|
|
|
SDValue Ops[2] = { DAG.getConstantFP(-0.0, N->getValueType(0)),
|
|
|
|
GetSoftenedFloat(N->getOperand(0)) };
|
|
|
|
return MakeLibCall(GetFPLibCall(N->getValueType(0),
|
|
|
|
RTLIB::SUB_F32,
|
|
|
|
RTLIB::SUB_F64,
|
|
|
|
RTLIB::SUB_F80,
|
|
|
|
RTLIB::SUB_PPCF128),
|
2009-01-31 00:11:23 +00:00
|
|
|
NVT, Ops, 2, false, N->getDebugLoc());
|
2008-11-18 09:15:03 +00:00
|
|
|
}
|
|
|
|
|
2008-07-27 21:46:04 +00:00
|
|
|
SDValue DAGTypeLegalizer::SoftenFloatRes_FP_EXTEND(SDNode *N) {
|
2009-08-12 00:36:31 +00:00
|
|
|
EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
|
2008-07-27 21:46:04 +00:00
|
|
|
SDValue Op = N->getOperand(0);
|
2008-07-17 02:36:29 +00:00
|
|
|
RTLIB::Libcall LC = RTLIB::getFPEXT(Op.getValueType(), N->getValueType(0));
|
|
|
|
assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported FP_EXTEND!");
|
2009-01-31 00:11:23 +00:00
|
|
|
return MakeLibCall(LC, NVT, &Op, 1, false, N->getDebugLoc());
|
2008-07-08 10:50:55 +00:00
|
|
|
}
|
|
|
|
|
2008-07-27 21:46:04 +00:00
|
|
|
SDValue DAGTypeLegalizer::SoftenFloatRes_FP_ROUND(SDNode *N) {
|
2009-08-12 00:36:31 +00:00
|
|
|
EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
|
2008-07-27 21:46:04 +00:00
|
|
|
SDValue Op = N->getOperand(0);
|
2008-07-17 02:36:29 +00:00
|
|
|
RTLIB::Libcall LC = RTLIB::getFPROUND(Op.getValueType(), N->getValueType(0));
|
|
|
|
assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported FP_ROUND!");
|
2009-01-31 00:11:23 +00:00
|
|
|
return MakeLibCall(LC, NVT, &Op, 1, false, N->getDebugLoc());
|
2008-07-08 10:50:55 +00:00
|
|
|
}
|
|
|
|
|
2008-10-22 11:49:09 +00:00
|
|
|
SDValue DAGTypeLegalizer::SoftenFloatRes_FPOW(SDNode *N) {
|
2009-08-12 00:36:31 +00:00
|
|
|
EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
|
2008-10-22 11:49:09 +00:00
|
|
|
SDValue Ops[2] = { GetSoftenedFloat(N->getOperand(0)),
|
|
|
|
GetSoftenedFloat(N->getOperand(1)) };
|
|
|
|
return MakeLibCall(GetFPLibCall(N->getValueType(0),
|
|
|
|
RTLIB::POW_F32,
|
|
|
|
RTLIB::POW_F64,
|
|
|
|
RTLIB::POW_F80,
|
|
|
|
RTLIB::POW_PPCF128),
|
2009-01-31 00:11:23 +00:00
|
|
|
NVT, Ops, 2, false, N->getDebugLoc());
|
2008-10-22 11:49:09 +00:00
|
|
|
}
|
|
|
|
|
2008-07-27 21:46:04 +00:00
|
|
|
SDValue DAGTypeLegalizer::SoftenFloatRes_FPOWI(SDNode *N) {
|
2009-08-11 20:47:22 +00:00
|
|
|
assert(N->getOperand(1).getValueType() == MVT::i32 &&
|
2008-11-10 17:36:26 +00:00
|
|
|
"Unsupported power type!");
|
2009-08-12 00:36:31 +00:00
|
|
|
EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
|
2008-07-27 21:46:04 +00:00
|
|
|
SDValue Ops[2] = { GetSoftenedFloat(N->getOperand(0)), N->getOperand(1) };
|
2008-07-09 11:11:47 +00:00
|
|
|
return MakeLibCall(GetFPLibCall(N->getValueType(0),
|
|
|
|
RTLIB::POWI_F32,
|
|
|
|
RTLIB::POWI_F64,
|
|
|
|
RTLIB::POWI_F80,
|
|
|
|
RTLIB::POWI_PPCF128),
|
2009-01-31 00:11:23 +00:00
|
|
|
NVT, Ops, 2, false, N->getDebugLoc());
|
2008-07-09 11:11:47 +00:00
|
|
|
}
|
|
|
|
|
2009-04-08 16:20:57 +00:00
|
|
|
SDValue DAGTypeLegalizer::SoftenFloatRes_FREM(SDNode *N) {
|
2009-08-12 00:36:31 +00:00
|
|
|
EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
|
2009-04-08 16:20:57 +00:00
|
|
|
SDValue Ops[2] = { GetSoftenedFloat(N->getOperand(0)),
|
|
|
|
GetSoftenedFloat(N->getOperand(1)) };
|
|
|
|
return MakeLibCall(GetFPLibCall(N->getValueType(0),
|
|
|
|
RTLIB::REM_F32,
|
|
|
|
RTLIB::REM_F64,
|
|
|
|
RTLIB::REM_F80,
|
|
|
|
RTLIB::REM_PPCF128),
|
|
|
|
NVT, Ops, 2, false, N->getDebugLoc());
|
|
|
|
}
|
|
|
|
|
2008-11-18 09:15:03 +00:00
|
|
|
SDValue DAGTypeLegalizer::SoftenFloatRes_FRINT(SDNode *N) {
|
2009-08-12 00:36:31 +00:00
|
|
|
EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
|
2008-11-18 09:15:03 +00:00
|
|
|
SDValue Op = GetSoftenedFloat(N->getOperand(0));
|
|
|
|
return MakeLibCall(GetFPLibCall(N->getValueType(0),
|
|
|
|
RTLIB::RINT_F32,
|
|
|
|
RTLIB::RINT_F64,
|
|
|
|
RTLIB::RINT_F80,
|
|
|
|
RTLIB::RINT_PPCF128),
|
2009-01-31 00:11:23 +00:00
|
|
|
NVT, &Op, 1, false, N->getDebugLoc());
|
2008-11-18 09:15:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
SDValue DAGTypeLegalizer::SoftenFloatRes_FSIN(SDNode *N) {
|
2009-08-12 00:36:31 +00:00
|
|
|
EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
|
2008-11-18 09:15:03 +00:00
|
|
|
SDValue Op = GetSoftenedFloat(N->getOperand(0));
|
|
|
|
return MakeLibCall(GetFPLibCall(N->getValueType(0),
|
|
|
|
RTLIB::SIN_F32,
|
|
|
|
RTLIB::SIN_F64,
|
|
|
|
RTLIB::SIN_F80,
|
|
|
|
RTLIB::SIN_PPCF128),
|
2009-01-31 00:11:23 +00:00
|
|
|
NVT, &Op, 1, false, N->getDebugLoc());
|
2008-11-18 09:15:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
SDValue DAGTypeLegalizer::SoftenFloatRes_FSQRT(SDNode *N) {
|
2009-08-12 00:36:31 +00:00
|
|
|
EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
|
2008-11-18 09:15:03 +00:00
|
|
|
SDValue Op = GetSoftenedFloat(N->getOperand(0));
|
|
|
|
return MakeLibCall(GetFPLibCall(N->getValueType(0),
|
|
|
|
RTLIB::SQRT_F32,
|
|
|
|
RTLIB::SQRT_F64,
|
|
|
|
RTLIB::SQRT_F80,
|
|
|
|
RTLIB::SQRT_PPCF128),
|
2009-01-31 00:11:23 +00:00
|
|
|
NVT, &Op, 1, false, N->getDebugLoc());
|
2008-11-18 09:15:03 +00:00
|
|
|
}
|
|
|
|
|
2008-07-27 21:46:04 +00:00
|
|
|
SDValue DAGTypeLegalizer::SoftenFloatRes_FSUB(SDNode *N) {
|
2009-08-12 00:36:31 +00:00
|
|
|
EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
|
2008-07-27 21:46:04 +00:00
|
|
|
SDValue Ops[2] = { GetSoftenedFloat(N->getOperand(0)),
|
2008-10-31 14:06:52 +00:00
|
|
|
GetSoftenedFloat(N->getOperand(1)) };
|
2008-04-18 20:56:03 +00:00
|
|
|
return MakeLibCall(GetFPLibCall(N->getValueType(0),
|
|
|
|
RTLIB::SUB_F32,
|
|
|
|
RTLIB::SUB_F64,
|
|
|
|
RTLIB::SUB_F80,
|
|
|
|
RTLIB::SUB_PPCF128),
|
2009-01-31 00:11:23 +00:00
|
|
|
NVT, Ops, 2, false, N->getDebugLoc());
|
2008-04-18 20:56:03 +00:00
|
|
|
}
|
|
|
|
|
2008-11-18 09:15:03 +00:00
|
|
|
SDValue DAGTypeLegalizer::SoftenFloatRes_FTRUNC(SDNode *N) {
|
2009-08-12 00:36:31 +00:00
|
|
|
EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
|
2008-11-18 09:15:03 +00:00
|
|
|
SDValue Op = GetSoftenedFloat(N->getOperand(0));
|
|
|
|
return MakeLibCall(GetFPLibCall(N->getValueType(0),
|
|
|
|
RTLIB::TRUNC_F32,
|
|
|
|
RTLIB::TRUNC_F64,
|
|
|
|
RTLIB::TRUNC_F80,
|
|
|
|
RTLIB::TRUNC_PPCF128),
|
2009-01-31 00:11:23 +00:00
|
|
|
NVT, &Op, 1, false, N->getDebugLoc());
|
2008-11-18 09:15:03 +00:00
|
|
|
}
|
|
|
|
|
2008-07-27 21:46:04 +00:00
|
|
|
SDValue DAGTypeLegalizer::SoftenFloatRes_LOAD(SDNode *N) {
|
2008-03-27 20:23:40 +00:00
|
|
|
LoadSDNode *L = cast<LoadSDNode>(N);
|
2009-08-10 22:56:29 +00:00
|
|
|
EVT VT = N->getValueType(0);
|
2009-08-12 00:36:31 +00:00
|
|
|
EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
|
2009-01-31 00:43:08 +00:00
|
|
|
DebugLoc dl = N->getDebugLoc();
|
2008-04-18 20:56:03 +00:00
|
|
|
|
2008-07-27 21:46:04 +00:00
|
|
|
SDValue NewL;
|
2008-07-09 11:15:31 +00:00
|
|
|
if (L->getExtensionType() == ISD::NON_EXTLOAD) {
|
2009-01-31 00:43:08 +00:00
|
|
|
NewL = DAG.getLoad(L->getAddressingMode(), dl, L->getExtensionType(),
|
2008-07-09 11:15:31 +00:00
|
|
|
NVT, L->getChain(), L->getBasePtr(), L->getOffset(),
|
|
|
|
L->getSrcValue(), L->getSrcValueOffset(), NVT,
|
|
|
|
L->isVolatile(), L->getAlignment());
|
|
|
|
// Legalized the chain result - switch anything that used the old chain to
|
|
|
|
// use the new one.
|
2008-07-27 21:46:04 +00:00
|
|
|
ReplaceValueWith(SDValue(N, 1), NewL.getValue(1));
|
2008-07-09 11:15:31 +00:00
|
|
|
return NewL;
|
|
|
|
}
|
2008-04-18 20:56:03 +00:00
|
|
|
|
|
|
|
// Do a non-extending load followed by FP_EXTEND.
|
2009-01-31 00:43:08 +00:00
|
|
|
NewL = DAG.getLoad(L->getAddressingMode(), dl, ISD::NON_EXTLOAD,
|
2008-07-09 11:15:31 +00:00
|
|
|
L->getMemoryVT(), L->getChain(),
|
|
|
|
L->getBasePtr(), L->getOffset(),
|
|
|
|
L->getSrcValue(), L->getSrcValueOffset(),
|
|
|
|
L->getMemoryVT(),
|
|
|
|
L->isVolatile(), L->getAlignment());
|
|
|
|
// Legalized the chain result - switch anything that used the old chain to
|
|
|
|
// use the new one.
|
2008-07-27 21:46:04 +00:00
|
|
|
ReplaceValueWith(SDValue(N, 1), NewL.getValue(1));
|
2009-01-31 00:43:08 +00:00
|
|
|
return BitConvertToInteger(DAG.getNode(ISD::FP_EXTEND, dl, VT, NewL));
|
2008-04-18 20:56:03 +00:00
|
|
|
}
|
|
|
|
|
2008-07-27 21:46:04 +00:00
|
|
|
SDValue DAGTypeLegalizer::SoftenFloatRes_SELECT(SDNode *N) {
|
|
|
|
SDValue LHS = GetSoftenedFloat(N->getOperand(1));
|
|
|
|
SDValue RHS = GetSoftenedFloat(N->getOperand(2));
|
2009-01-31 00:43:08 +00:00
|
|
|
return DAG.getNode(ISD::SELECT, N->getDebugLoc(),
|
|
|
|
LHS.getValueType(), N->getOperand(0),LHS,RHS);
|
2008-07-08 20:03:24 +00:00
|
|
|
}
|
|
|
|
|
2008-07-27 21:46:04 +00:00
|
|
|
SDValue DAGTypeLegalizer::SoftenFloatRes_SELECT_CC(SDNode *N) {
|
|
|
|
SDValue LHS = GetSoftenedFloat(N->getOperand(2));
|
|
|
|
SDValue RHS = GetSoftenedFloat(N->getOperand(3));
|
2009-01-31 00:43:08 +00:00
|
|
|
return DAG.getNode(ISD::SELECT_CC, N->getDebugLoc(),
|
|
|
|
LHS.getValueType(), N->getOperand(0),
|
2008-07-08 20:03:24 +00:00
|
|
|
N->getOperand(1), LHS, RHS, N->getOperand(4));
|
|
|
|
}
|
|
|
|
|
2009-04-08 13:33:37 +00:00
|
|
|
SDValue DAGTypeLegalizer::SoftenFloatRes_UNDEF(SDNode *N) {
|
2009-08-12 00:36:31 +00:00
|
|
|
return DAG.getUNDEF(TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0)));
|
2009-04-08 13:33:37 +00:00
|
|
|
}
|
|
|
|
|
2009-02-21 19:11:18 +00:00
|
|
|
SDValue DAGTypeLegalizer::SoftenFloatRes_VAARG(SDNode *N) {
|
|
|
|
SDValue Chain = N->getOperand(0); // Get the chain.
|
|
|
|
SDValue Ptr = N->getOperand(1); // Get the pointer.
|
2009-08-10 22:56:29 +00:00
|
|
|
EVT VT = N->getValueType(0);
|
2009-08-12 00:36:31 +00:00
|
|
|
EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
|
2009-02-21 19:11:18 +00:00
|
|
|
DebugLoc dl = N->getDebugLoc();
|
|
|
|
|
|
|
|
SDValue NewVAARG;
|
|
|
|
NewVAARG = DAG.getVAArg(NVT, dl, Chain, Ptr, N->getOperand(2));
|
2009-07-08 11:36:39 +00:00
|
|
|
|
2009-02-21 19:11:18 +00:00
|
|
|
// Legalized the chain result - switch anything that used the old chain to
|
|
|
|
// use the new one.
|
|
|
|
ReplaceValueWith(SDValue(N, 1), NewVAARG.getValue(1));
|
|
|
|
return NewVAARG;
|
|
|
|
}
|
|
|
|
|
2008-11-10 17:36:26 +00:00
|
|
|
SDValue DAGTypeLegalizer::SoftenFloatRes_XINT_TO_FP(SDNode *N) {
|
|
|
|
bool Signed = N->getOpcode() == ISD::SINT_TO_FP;
|
2009-08-10 22:56:29 +00:00
|
|
|
EVT SVT = N->getOperand(0).getValueType();
|
|
|
|
EVT RVT = N->getValueType(0);
|
|
|
|
EVT NVT = EVT();
|
2009-01-31 00:11:23 +00:00
|
|
|
DebugLoc dl = N->getDebugLoc();
|
2008-11-10 17:36:26 +00:00
|
|
|
|
|
|
|
// If the input is not legal, eg: i1 -> fp, then it needs to be promoted to
|
|
|
|
// a larger type, eg: i8 -> fp. Even if it is legal, no libcall may exactly
|
|
|
|
// match. Look for an appropriate libcall.
|
|
|
|
RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL;
|
2009-08-11 20:47:22 +00:00
|
|
|
for (unsigned t = MVT::FIRST_INTEGER_VALUETYPE;
|
|
|
|
t <= MVT::LAST_INTEGER_VALUETYPE && LC == RTLIB::UNKNOWN_LIBCALL; ++t) {
|
|
|
|
NVT = (MVT::SimpleValueType)t;
|
2008-11-10 17:36:26 +00:00
|
|
|
// The source needs to big enough to hold the operand.
|
|
|
|
if (NVT.bitsGE(SVT))
|
|
|
|
LC = Signed ? RTLIB::getSINTTOFP(NVT, RVT):RTLIB::getUINTTOFP (NVT, RVT);
|
|
|
|
}
|
|
|
|
assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported XINT_TO_FP!");
|
2008-07-09 12:07:22 +00:00
|
|
|
|
2008-11-10 17:36:26 +00:00
|
|
|
// Sign/zero extend the argument if the libcall takes a larger type.
|
2009-01-31 00:43:08 +00:00
|
|
|
SDValue Op = DAG.getNode(Signed ? ISD::SIGN_EXTEND : ISD::ZERO_EXTEND, dl,
|
2008-11-10 17:36:26 +00:00
|
|
|
NVT, N->getOperand(0));
|
2009-08-12 00:36:31 +00:00
|
|
|
return MakeLibCall(LC, TLI.getTypeToTransformTo(*DAG.getContext(), RVT), &Op, 1, false, dl);
|
2008-03-27 20:23:40 +00:00
|
|
|
}
|
|
|
|
|
Initial soft-float support for LegalizeTypes. I rewrote
the fcopysign expansion from LegalizeDAG to get rid of
what seems to be a bug: the use of sign extension means
that when copying the sign bit from an f32 to an f64,
the upper 32 bits of the f64 (now an i64) are set, not
just the top bit... I also generalized it to work for
any sized floating point types, and removed the bogosity:
SDOperand Mask1 = (SrcVT == MVT::f64)
? DAG.getConstantFP(BitsToDouble(1ULL << 63), SrcVT)
: DAG.getConstantFP(BitsToFloat(1U << 31), SrcVT);
Mask1 = DAG.getNode(ISD::BIT_CONVERT, SrcNVT, Mask1);
(here SrcNVT is an integer with the same size as SrcVT).
As far as I can see this takes a 1 << 63, converts to
a double, converts that to a floating point constant
then converts that to an integer constant, ending up
with... 1 << 63 as an integer constant! So I just
generate this integer constant directly.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@48305 91177308-0d34-0410-b5e6-96231b3b80d8
2008-03-12 21:27:04 +00:00
|
|
|
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// Operand Float to Integer Conversion..
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2008-06-20 17:49:55 +00:00
|
|
|
bool DAGTypeLegalizer::SoftenFloatOperand(SDNode *N, unsigned OpNo) {
|
2009-07-25 01:43:01 +00:00
|
|
|
DEBUG(errs() << "Soften float operand " << OpNo << ": "; N->dump(&DAG);
|
|
|
|
errs() << "\n");
|
2008-07-27 21:46:04 +00:00
|
|
|
SDValue Res = SDValue();
|
Initial soft-float support for LegalizeTypes. I rewrote
the fcopysign expansion from LegalizeDAG to get rid of
what seems to be a bug: the use of sign extension means
that when copying the sign bit from an f32 to an f64,
the upper 32 bits of the f64 (now an i64) are set, not
just the top bit... I also generalized it to work for
any sized floating point types, and removed the bogosity:
SDOperand Mask1 = (SrcVT == MVT::f64)
? DAG.getConstantFP(BitsToDouble(1ULL << 63), SrcVT)
: DAG.getConstantFP(BitsToFloat(1U << 31), SrcVT);
Mask1 = DAG.getNode(ISD::BIT_CONVERT, SrcNVT, Mask1);
(here SrcNVT is an integer with the same size as SrcVT).
As far as I can see this takes a 1 << 63, converts to
a double, converts that to a floating point constant
then converts that to an integer constant, ending up
with... 1 << 63 as an integer constant! So I just
generate this integer constant directly.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@48305 91177308-0d34-0410-b5e6-96231b3b80d8
2008-03-12 21:27:04 +00:00
|
|
|
|
2008-07-08 20:03:24 +00:00
|
|
|
switch (N->getOpcode()) {
|
|
|
|
default:
|
Initial soft-float support for LegalizeTypes. I rewrote
the fcopysign expansion from LegalizeDAG to get rid of
what seems to be a bug: the use of sign extension means
that when copying the sign bit from an f32 to an f64,
the upper 32 bits of the f64 (now an i64) are set, not
just the top bit... I also generalized it to work for
any sized floating point types, and removed the bogosity:
SDOperand Mask1 = (SrcVT == MVT::f64)
? DAG.getConstantFP(BitsToDouble(1ULL << 63), SrcVT)
: DAG.getConstantFP(BitsToFloat(1U << 31), SrcVT);
Mask1 = DAG.getNode(ISD::BIT_CONVERT, SrcNVT, Mask1);
(here SrcNVT is an integer with the same size as SrcVT).
As far as I can see this takes a 1 << 63, converts to
a double, converts that to a floating point constant
then converts that to an integer constant, ending up
with... 1 << 63 as an integer constant! So I just
generate this integer constant directly.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@48305 91177308-0d34-0410-b5e6-96231b3b80d8
2008-03-12 21:27:04 +00:00
|
|
|
#ifndef NDEBUG
|
2009-07-25 01:43:01 +00:00
|
|
|
errs() << "SoftenFloatOperand Op #" << OpNo << ": ";
|
|
|
|
N->dump(&DAG); errs() << "\n";
|
Initial soft-float support for LegalizeTypes. I rewrote
the fcopysign expansion from LegalizeDAG to get rid of
what seems to be a bug: the use of sign extension means
that when copying the sign bit from an f32 to an f64,
the upper 32 bits of the f64 (now an i64) are set, not
just the top bit... I also generalized it to work for
any sized floating point types, and removed the bogosity:
SDOperand Mask1 = (SrcVT == MVT::f64)
? DAG.getConstantFP(BitsToDouble(1ULL << 63), SrcVT)
: DAG.getConstantFP(BitsToFloat(1U << 31), SrcVT);
Mask1 = DAG.getNode(ISD::BIT_CONVERT, SrcNVT, Mask1);
(here SrcNVT is an integer with the same size as SrcVT).
As far as I can see this takes a 1 << 63, converts to
a double, converts that to a floating point constant
then converts that to an integer constant, ending up
with... 1 << 63 as an integer constant! So I just
generate this integer constant directly.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@48305 91177308-0d34-0410-b5e6-96231b3b80d8
2008-03-12 21:27:04 +00:00
|
|
|
#endif
|
2009-07-14 16:55:14 +00:00
|
|
|
llvm_unreachable("Do not know how to soften this operator's operand!");
|
Initial soft-float support for LegalizeTypes. I rewrote
the fcopysign expansion from LegalizeDAG to get rid of
what seems to be a bug: the use of sign extension means
that when copying the sign bit from an f32 to an f64,
the upper 32 bits of the f64 (now an i64) are set, not
just the top bit... I also generalized it to work for
any sized floating point types, and removed the bogosity:
SDOperand Mask1 = (SrcVT == MVT::f64)
? DAG.getConstantFP(BitsToDouble(1ULL << 63), SrcVT)
: DAG.getConstantFP(BitsToFloat(1U << 31), SrcVT);
Mask1 = DAG.getNode(ISD::BIT_CONVERT, SrcNVT, Mask1);
(here SrcNVT is an integer with the same size as SrcVT).
As far as I can see this takes a 1 << 63, converts to
a double, converts that to a floating point constant
then converts that to an integer constant, ending up
with... 1 << 63 as an integer constant! So I just
generate this integer constant directly.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@48305 91177308-0d34-0410-b5e6-96231b3b80d8
2008-03-12 21:27:04 +00:00
|
|
|
|
2008-07-08 20:03:24 +00:00
|
|
|
case ISD::BIT_CONVERT: Res = SoftenFloatOp_BIT_CONVERT(N); break;
|
2008-07-16 11:41:33 +00:00
|
|
|
case ISD::BR_CC: Res = SoftenFloatOp_BR_CC(N); break;
|
2008-08-07 19:01:24 +00:00
|
|
|
case ISD::FP_ROUND: Res = SoftenFloatOp_FP_ROUND(N); break;
|
2008-07-16 11:41:33 +00:00
|
|
|
case ISD::FP_TO_SINT: Res = SoftenFloatOp_FP_TO_SINT(N); break;
|
|
|
|
case ISD::FP_TO_UINT: Res = SoftenFloatOp_FP_TO_UINT(N); break;
|
|
|
|
case ISD::SELECT_CC: Res = SoftenFloatOp_SELECT_CC(N); break;
|
|
|
|
case ISD::SETCC: Res = SoftenFloatOp_SETCC(N); break;
|
|
|
|
case ISD::STORE: Res = SoftenFloatOp_STORE(N, OpNo); break;
|
Initial soft-float support for LegalizeTypes. I rewrote
the fcopysign expansion from LegalizeDAG to get rid of
what seems to be a bug: the use of sign extension means
that when copying the sign bit from an f32 to an f64,
the upper 32 bits of the f64 (now an i64) are set, not
just the top bit... I also generalized it to work for
any sized floating point types, and removed the bogosity:
SDOperand Mask1 = (SrcVT == MVT::f64)
? DAG.getConstantFP(BitsToDouble(1ULL << 63), SrcVT)
: DAG.getConstantFP(BitsToFloat(1U << 31), SrcVT);
Mask1 = DAG.getNode(ISD::BIT_CONVERT, SrcNVT, Mask1);
(here SrcNVT is an integer with the same size as SrcVT).
As far as I can see this takes a 1 << 63, converts to
a double, converts that to a floating point constant
then converts that to an integer constant, ending up
with... 1 << 63 as an integer constant! So I just
generate this integer constant directly.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@48305 91177308-0d34-0410-b5e6-96231b3b80d8
2008-03-12 21:27:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// If the result is null, the sub-method took care of registering results etc.
|
2008-08-28 21:40:38 +00:00
|
|
|
if (!Res.getNode()) return false;
|
Initial soft-float support for LegalizeTypes. I rewrote
the fcopysign expansion from LegalizeDAG to get rid of
what seems to be a bug: the use of sign extension means
that when copying the sign bit from an f32 to an f64,
the upper 32 bits of the f64 (now an i64) are set, not
just the top bit... I also generalized it to work for
any sized floating point types, and removed the bogosity:
SDOperand Mask1 = (SrcVT == MVT::f64)
? DAG.getConstantFP(BitsToDouble(1ULL << 63), SrcVT)
: DAG.getConstantFP(BitsToFloat(1U << 31), SrcVT);
Mask1 = DAG.getNode(ISD::BIT_CONVERT, SrcNVT, Mask1);
(here SrcNVT is an integer with the same size as SrcVT).
As far as I can see this takes a 1 << 63, converts to
a double, converts that to a floating point constant
then converts that to an integer constant, ending up
with... 1 << 63 as an integer constant! So I just
generate this integer constant directly.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@48305 91177308-0d34-0410-b5e6-96231b3b80d8
2008-03-12 21:27:04 +00:00
|
|
|
|
2008-12-09 21:33:20 +00:00
|
|
|
// If the result is N, the sub-method updated N in place. Tell the legalizer
|
|
|
|
// core about this.
|
|
|
|
if (Res.getNode() == N)
|
Initial soft-float support for LegalizeTypes. I rewrote
the fcopysign expansion from LegalizeDAG to get rid of
what seems to be a bug: the use of sign extension means
that when copying the sign bit from an f32 to an f64,
the upper 32 bits of the f64 (now an i64) are set, not
just the top bit... I also generalized it to work for
any sized floating point types, and removed the bogosity:
SDOperand Mask1 = (SrcVT == MVT::f64)
? DAG.getConstantFP(BitsToDouble(1ULL << 63), SrcVT)
: DAG.getConstantFP(BitsToFloat(1U << 31), SrcVT);
Mask1 = DAG.getNode(ISD::BIT_CONVERT, SrcNVT, Mask1);
(here SrcNVT is an integer with the same size as SrcVT).
As far as I can see this takes a 1 << 63, converts to
a double, converts that to a floating point constant
then converts that to an integer constant, ending up
with... 1 << 63 as an integer constant! So I just
generate this integer constant directly.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@48305 91177308-0d34-0410-b5e6-96231b3b80d8
2008-03-12 21:27:04 +00:00
|
|
|
return true;
|
|
|
|
|
|
|
|
assert(Res.getValueType() == N->getValueType(0) && N->getNumValues() == 1 &&
|
|
|
|
"Invalid operand expansion");
|
|
|
|
|
2008-07-27 21:46:04 +00:00
|
|
|
ReplaceValueWith(SDValue(N, 0), Res);
|
Initial soft-float support for LegalizeTypes. I rewrote
the fcopysign expansion from LegalizeDAG to get rid of
what seems to be a bug: the use of sign extension means
that when copying the sign bit from an f32 to an f64,
the upper 32 bits of the f64 (now an i64) are set, not
just the top bit... I also generalized it to work for
any sized floating point types, and removed the bogosity:
SDOperand Mask1 = (SrcVT == MVT::f64)
? DAG.getConstantFP(BitsToDouble(1ULL << 63), SrcVT)
: DAG.getConstantFP(BitsToFloat(1U << 31), SrcVT);
Mask1 = DAG.getNode(ISD::BIT_CONVERT, SrcNVT, Mask1);
(here SrcNVT is an integer with the same size as SrcVT).
As far as I can see this takes a 1 << 63, converts to
a double, converts that to a floating point constant
then converts that to an integer constant, ending up
with... 1 << 63 as an integer constant! So I just
generate this integer constant directly.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@48305 91177308-0d34-0410-b5e6-96231b3b80d8
2008-03-12 21:27:04 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2008-06-25 16:34:21 +00:00
|
|
|
/// SoftenSetCCOperands - Soften the operands of a comparison. This code is
|
|
|
|
/// shared among BR_CC, SELECT_CC, and SETCC handlers.
|
2008-07-27 21:46:04 +00:00
|
|
|
void DAGTypeLegalizer::SoftenSetCCOperands(SDValue &NewLHS, SDValue &NewRHS,
|
2009-01-31 00:11:23 +00:00
|
|
|
ISD::CondCode &CCCode, DebugLoc dl) {
|
2008-07-27 21:46:04 +00:00
|
|
|
SDValue LHSInt = GetSoftenedFloat(NewLHS);
|
|
|
|
SDValue RHSInt = GetSoftenedFloat(NewRHS);
|
2009-08-10 22:56:29 +00:00
|
|
|
EVT VT = NewLHS.getValueType();
|
2008-06-25 16:34:21 +00:00
|
|
|
|
2009-08-11 20:47:22 +00:00
|
|
|
assert((VT == MVT::f32 || VT == MVT::f64) && "Unsupported setcc type!");
|
2008-06-25 16:34:21 +00:00
|
|
|
|
|
|
|
// Expand into one or more soft-fp libcall(s).
|
2008-06-30 22:33:56 +00:00
|
|
|
RTLIB::Libcall LC1 = RTLIB::UNKNOWN_LIBCALL, LC2 = RTLIB::UNKNOWN_LIBCALL;
|
2008-06-25 16:34:21 +00:00
|
|
|
switch (CCCode) {
|
|
|
|
case ISD::SETEQ:
|
|
|
|
case ISD::SETOEQ:
|
2009-08-11 20:47:22 +00:00
|
|
|
LC1 = (VT == MVT::f32) ? RTLIB::OEQ_F32 : RTLIB::OEQ_F64;
|
2008-06-25 16:34:21 +00:00
|
|
|
break;
|
|
|
|
case ISD::SETNE:
|
|
|
|
case ISD::SETUNE:
|
2009-08-11 20:47:22 +00:00
|
|
|
LC1 = (VT == MVT::f32) ? RTLIB::UNE_F32 : RTLIB::UNE_F64;
|
2008-06-25 16:34:21 +00:00
|
|
|
break;
|
|
|
|
case ISD::SETGE:
|
|
|
|
case ISD::SETOGE:
|
2009-08-11 20:47:22 +00:00
|
|
|
LC1 = (VT == MVT::f32) ? RTLIB::OGE_F32 : RTLIB::OGE_F64;
|
2008-06-25 16:34:21 +00:00
|
|
|
break;
|
|
|
|
case ISD::SETLT:
|
|
|
|
case ISD::SETOLT:
|
2009-08-11 20:47:22 +00:00
|
|
|
LC1 = (VT == MVT::f32) ? RTLIB::OLT_F32 : RTLIB::OLT_F64;
|
2008-06-25 16:34:21 +00:00
|
|
|
break;
|
|
|
|
case ISD::SETLE:
|
|
|
|
case ISD::SETOLE:
|
2009-08-11 20:47:22 +00:00
|
|
|
LC1 = (VT == MVT::f32) ? RTLIB::OLE_F32 : RTLIB::OLE_F64;
|
2008-06-25 16:34:21 +00:00
|
|
|
break;
|
|
|
|
case ISD::SETGT:
|
|
|
|
case ISD::SETOGT:
|
2009-08-11 20:47:22 +00:00
|
|
|
LC1 = (VT == MVT::f32) ? RTLIB::OGT_F32 : RTLIB::OGT_F64;
|
2008-06-25 16:34:21 +00:00
|
|
|
break;
|
|
|
|
case ISD::SETUO:
|
2009-08-11 20:47:22 +00:00
|
|
|
LC1 = (VT == MVT::f32) ? RTLIB::UO_F32 : RTLIB::UO_F64;
|
2008-06-25 16:34:21 +00:00
|
|
|
break;
|
|
|
|
case ISD::SETO:
|
2009-08-11 20:47:22 +00:00
|
|
|
LC1 = (VT == MVT::f32) ? RTLIB::O_F32 : RTLIB::O_F64;
|
2008-06-25 16:34:21 +00:00
|
|
|
break;
|
|
|
|
default:
|
2009-08-11 20:47:22 +00:00
|
|
|
LC1 = (VT == MVT::f32) ? RTLIB::UO_F32 : RTLIB::UO_F64;
|
2008-06-25 16:34:21 +00:00
|
|
|
switch (CCCode) {
|
|
|
|
case ISD::SETONE:
|
|
|
|
// SETONE = SETOLT | SETOGT
|
2009-08-11 20:47:22 +00:00
|
|
|
LC1 = (VT == MVT::f32) ? RTLIB::OLT_F32 : RTLIB::OLT_F64;
|
2008-06-25 16:34:21 +00:00
|
|
|
// Fallthrough
|
|
|
|
case ISD::SETUGT:
|
2009-08-11 20:47:22 +00:00
|
|
|
LC2 = (VT == MVT::f32) ? RTLIB::OGT_F32 : RTLIB::OGT_F64;
|
2008-06-25 16:34:21 +00:00
|
|
|
break;
|
|
|
|
case ISD::SETUGE:
|
2009-08-11 20:47:22 +00:00
|
|
|
LC2 = (VT == MVT::f32) ? RTLIB::OGE_F32 : RTLIB::OGE_F64;
|
2008-06-25 16:34:21 +00:00
|
|
|
break;
|
|
|
|
case ISD::SETULT:
|
2009-08-11 20:47:22 +00:00
|
|
|
LC2 = (VT == MVT::f32) ? RTLIB::OLT_F32 : RTLIB::OLT_F64;
|
2008-06-25 16:34:21 +00:00
|
|
|
break;
|
|
|
|
case ISD::SETULE:
|
2009-08-11 20:47:22 +00:00
|
|
|
LC2 = (VT == MVT::f32) ? RTLIB::OLE_F32 : RTLIB::OLE_F64;
|
2008-06-25 16:34:21 +00:00
|
|
|
break;
|
|
|
|
case ISD::SETUEQ:
|
2009-08-11 20:47:22 +00:00
|
|
|
LC2 = (VT == MVT::f32) ? RTLIB::OEQ_F32 : RTLIB::OEQ_F64;
|
2008-06-25 16:34:21 +00:00
|
|
|
break;
|
|
|
|
default: assert(false && "Do not know how to soften this setcc!");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-12-28 02:40:33 +00:00
|
|
|
// Use the target specific return value for comparions lib calls.
|
|
|
|
EVT RetVT = TLI.getCmpLibcallReturnType();
|
2008-07-27 21:46:04 +00:00
|
|
|
SDValue Ops[2] = { LHSInt, RHSInt };
|
2009-01-31 00:11:23 +00:00
|
|
|
NewLHS = MakeLibCall(LC1, RetVT, Ops, 2, false/*sign irrelevant*/, dl);
|
2008-07-09 08:07:41 +00:00
|
|
|
NewRHS = DAG.getConstant(0, RetVT);
|
2008-07-08 20:03:24 +00:00
|
|
|
CCCode = TLI.getCmpLibcallCC(LC1);
|
2008-06-25 16:34:21 +00:00
|
|
|
if (LC2 != RTLIB::UNKNOWN_LIBCALL) {
|
2009-01-31 00:43:08 +00:00
|
|
|
SDValue Tmp = DAG.getNode(ISD::SETCC, dl, TLI.getSetCCResultType(RetVT),
|
2008-07-08 20:03:24 +00:00
|
|
|
NewLHS, NewRHS, DAG.getCondCode(CCCode));
|
2009-01-31 00:11:23 +00:00
|
|
|
NewLHS = MakeLibCall(LC2, RetVT, Ops, 2, false/*sign irrelevant*/, dl);
|
2009-01-31 00:43:08 +00:00
|
|
|
NewLHS = DAG.getNode(ISD::SETCC, dl, TLI.getSetCCResultType(RetVT), NewLHS,
|
2008-06-25 16:34:21 +00:00
|
|
|
NewRHS, DAG.getCondCode(TLI.getCmpLibcallCC(LC2)));
|
2009-01-31 00:43:08 +00:00
|
|
|
NewLHS = DAG.getNode(ISD::OR, dl, Tmp.getValueType(), Tmp, NewLHS);
|
2008-07-27 21:46:04 +00:00
|
|
|
NewRHS = SDValue();
|
2008-06-25 16:34:21 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-07-27 21:46:04 +00:00
|
|
|
SDValue DAGTypeLegalizer::SoftenFloatOp_BIT_CONVERT(SDNode *N) {
|
2009-01-31 00:43:08 +00:00
|
|
|
return DAG.getNode(ISD::BIT_CONVERT, N->getDebugLoc(), N->getValueType(0),
|
2008-06-20 17:49:55 +00:00
|
|
|
GetSoftenedFloat(N->getOperand(0)));
|
2008-06-17 14:27:01 +00:00
|
|
|
}
|
|
|
|
|
2008-08-07 19:01:24 +00:00
|
|
|
SDValue DAGTypeLegalizer::SoftenFloatOp_FP_ROUND(SDNode *N) {
|
2009-08-10 22:56:29 +00:00
|
|
|
EVT SVT = N->getOperand(0).getValueType();
|
|
|
|
EVT RVT = N->getValueType(0);
|
2008-08-07 19:01:24 +00:00
|
|
|
|
|
|
|
RTLIB::Libcall LC = RTLIB::getFPROUND(SVT, RVT);
|
|
|
|
assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported FP_ROUND libcall");
|
|
|
|
|
|
|
|
SDValue Op = GetSoftenedFloat(N->getOperand(0));
|
2009-01-31 00:11:23 +00:00
|
|
|
return MakeLibCall(LC, RVT, &Op, 1, false, N->getDebugLoc());
|
2008-08-07 19:01:24 +00:00
|
|
|
}
|
|
|
|
|
2008-07-27 21:46:04 +00:00
|
|
|
SDValue DAGTypeLegalizer::SoftenFloatOp_BR_CC(SDNode *N) {
|
|
|
|
SDValue NewLHS = N->getOperand(2), NewRHS = N->getOperand(3);
|
2008-06-25 16:34:21 +00:00
|
|
|
ISD::CondCode CCCode = cast<CondCodeSDNode>(N->getOperand(1))->get();
|
2009-01-31 00:11:23 +00:00
|
|
|
SoftenSetCCOperands(NewLHS, NewRHS, CCCode, N->getDebugLoc());
|
2008-06-25 16:34:21 +00:00
|
|
|
|
|
|
|
// If SoftenSetCCOperands returned a scalar, we need to compare the result
|
|
|
|
// against zero to select between true and false values.
|
2008-08-28 21:40:38 +00:00
|
|
|
if (NewRHS.getNode() == 0) {
|
2008-06-25 16:34:21 +00:00
|
|
|
NewRHS = DAG.getConstant(0, NewLHS.getValueType());
|
|
|
|
CCCode = ISD::SETNE;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Update N to have the operands specified.
|
2008-07-27 21:46:04 +00:00
|
|
|
return DAG.UpdateNodeOperands(SDValue(N, 0), N->getOperand(0),
|
2008-06-25 16:34:21 +00:00
|
|
|
DAG.getCondCode(CCCode), NewLHS, NewRHS,
|
|
|
|
N->getOperand(4));
|
|
|
|
}
|
|
|
|
|
2008-07-27 21:46:04 +00:00
|
|
|
SDValue DAGTypeLegalizer::SoftenFloatOp_FP_TO_SINT(SDNode *N) {
|
2009-08-10 22:56:29 +00:00
|
|
|
EVT RVT = N->getValueType(0);
|
2008-07-17 02:36:29 +00:00
|
|
|
RTLIB::Libcall LC = RTLIB::getFPTOSINT(N->getOperand(0).getValueType(), RVT);
|
2008-07-09 11:13:46 +00:00
|
|
|
assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported FP_TO_SINT!");
|
2008-07-27 21:46:04 +00:00
|
|
|
SDValue Op = GetSoftenedFloat(N->getOperand(0));
|
2009-01-31 00:11:23 +00:00
|
|
|
return MakeLibCall(LC, RVT, &Op, 1, false, N->getDebugLoc());
|
2008-07-09 11:13:46 +00:00
|
|
|
}
|
|
|
|
|
2008-07-27 21:46:04 +00:00
|
|
|
SDValue DAGTypeLegalizer::SoftenFloatOp_FP_TO_UINT(SDNode *N) {
|
2009-08-10 22:56:29 +00:00
|
|
|
EVT RVT = N->getValueType(0);
|
2008-07-17 02:36:29 +00:00
|
|
|
RTLIB::Libcall LC = RTLIB::getFPTOUINT(N->getOperand(0).getValueType(), RVT);
|
2008-07-09 11:13:46 +00:00
|
|
|
assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported FP_TO_UINT!");
|
2008-07-27 21:46:04 +00:00
|
|
|
SDValue Op = GetSoftenedFloat(N->getOperand(0));
|
2009-01-31 00:11:23 +00:00
|
|
|
return MakeLibCall(LC, RVT, &Op, 1, false, N->getDebugLoc());
|
2008-07-09 11:13:46 +00:00
|
|
|
}
|
|
|
|
|
2008-07-27 21:46:04 +00:00
|
|
|
SDValue DAGTypeLegalizer::SoftenFloatOp_SELECT_CC(SDNode *N) {
|
|
|
|
SDValue NewLHS = N->getOperand(0), NewRHS = N->getOperand(1);
|
2008-06-25 16:34:21 +00:00
|
|
|
ISD::CondCode CCCode = cast<CondCodeSDNode>(N->getOperand(4))->get();
|
2009-01-31 00:11:23 +00:00
|
|
|
SoftenSetCCOperands(NewLHS, NewRHS, CCCode, N->getDebugLoc());
|
2008-06-25 16:34:21 +00:00
|
|
|
|
|
|
|
// If SoftenSetCCOperands returned a scalar, we need to compare the result
|
|
|
|
// against zero to select between true and false values.
|
2008-08-28 21:40:38 +00:00
|
|
|
if (NewRHS.getNode() == 0) {
|
2008-06-25 16:34:21 +00:00
|
|
|
NewRHS = DAG.getConstant(0, NewLHS.getValueType());
|
|
|
|
CCCode = ISD::SETNE;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Update N to have the operands specified.
|
2008-07-27 21:46:04 +00:00
|
|
|
return DAG.UpdateNodeOperands(SDValue(N, 0), NewLHS, NewRHS,
|
2008-06-25 16:34:21 +00:00
|
|
|
N->getOperand(2), N->getOperand(3),
|
|
|
|
DAG.getCondCode(CCCode));
|
|
|
|
}
|
|
|
|
|
2008-07-27 21:46:04 +00:00
|
|
|
SDValue DAGTypeLegalizer::SoftenFloatOp_SETCC(SDNode *N) {
|
|
|
|
SDValue NewLHS = N->getOperand(0), NewRHS = N->getOperand(1);
|
2008-06-25 16:34:21 +00:00
|
|
|
ISD::CondCode CCCode = cast<CondCodeSDNode>(N->getOperand(2))->get();
|
2009-01-31 00:11:23 +00:00
|
|
|
SoftenSetCCOperands(NewLHS, NewRHS, CCCode, N->getDebugLoc());
|
2008-06-25 16:34:21 +00:00
|
|
|
|
|
|
|
// If SoftenSetCCOperands returned a scalar, use it.
|
2008-08-28 21:40:38 +00:00
|
|
|
if (NewRHS.getNode() == 0) {
|
2008-06-25 16:34:21 +00:00
|
|
|
assert(NewLHS.getValueType() == N->getValueType(0) &&
|
|
|
|
"Unexpected setcc expansion!");
|
|
|
|
return NewLHS;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Otherwise, update N to have the operands specified.
|
2008-07-27 21:46:04 +00:00
|
|
|
return DAG.UpdateNodeOperands(SDValue(N, 0), NewLHS, NewRHS,
|
2008-06-25 16:34:21 +00:00
|
|
|
DAG.getCondCode(CCCode));
|
|
|
|
}
|
|
|
|
|
2008-07-27 21:46:04 +00:00
|
|
|
SDValue DAGTypeLegalizer::SoftenFloatOp_STORE(SDNode *N, unsigned OpNo) {
|
2008-07-07 00:08:12 +00:00
|
|
|
assert(ISD::isUNINDEXEDStore(N) && "Indexed store during type legalization!");
|
|
|
|
assert(OpNo == 1 && "Can only soften the stored value!");
|
|
|
|
StoreSDNode *ST = cast<StoreSDNode>(N);
|
2008-07-27 21:46:04 +00:00
|
|
|
SDValue Val = ST->getValue();
|
2009-01-31 00:43:08 +00:00
|
|
|
DebugLoc dl = N->getDebugLoc();
|
2008-07-07 00:08:12 +00:00
|
|
|
|
|
|
|
if (ST->isTruncatingStore())
|
|
|
|
// Do an FP_ROUND followed by a non-truncating store.
|
2009-01-31 00:43:08 +00:00
|
|
|
Val = BitConvertToInteger(DAG.getNode(ISD::FP_ROUND, dl, ST->getMemoryVT(),
|
2008-07-07 00:08:12 +00:00
|
|
|
Val, DAG.getIntPtrConstant(0)));
|
|
|
|
else
|
|
|
|
Val = GetSoftenedFloat(Val);
|
|
|
|
|
2009-01-31 00:43:08 +00:00
|
|
|
return DAG.getStore(ST->getChain(), dl, Val, ST->getBasePtr(),
|
2008-07-07 00:08:12 +00:00
|
|
|
ST->getSrcValue(), ST->getSrcValueOffset(),
|
|
|
|
ST->isVolatile(), ST->getAlignment());
|
|
|
|
}
|
|
|
|
|
2008-06-17 14:27:01 +00:00
|
|
|
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// Float Result Expansion
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
/// ExpandFloatResult - This method is called when the specified result of the
|
|
|
|
/// specified node is found to need expansion. At this point, the node may also
|
|
|
|
/// have invalid operands or may have other results that need promotion, we just
|
|
|
|
/// know that (at least) one result needs expansion.
|
|
|
|
void DAGTypeLegalizer::ExpandFloatResult(SDNode *N, unsigned ResNo) {
|
2009-07-25 01:43:01 +00:00
|
|
|
DEBUG(errs() << "Expand float result: "; N->dump(&DAG); errs() << "\n");
|
2008-07-27 21:46:04 +00:00
|
|
|
SDValue Lo, Hi;
|
|
|
|
Lo = Hi = SDValue();
|
2008-06-17 14:27:01 +00:00
|
|
|
|
|
|
|
// See if the target wants to custom expand this node.
|
2009-05-31 04:15:38 +00:00
|
|
|
if (CustomLowerNode(N, N->getValueType(ResNo), true))
|
2008-12-01 11:39:25 +00:00
|
|
|
return;
|
2008-06-17 14:27:01 +00:00
|
|
|
|
|
|
|
switch (N->getOpcode()) {
|
|
|
|
default:
|
|
|
|
#ifndef NDEBUG
|
2009-07-25 01:43:01 +00:00
|
|
|
errs() << "ExpandFloatResult #" << ResNo << ": ";
|
|
|
|
N->dump(&DAG); errs() << "\n";
|
2008-06-17 14:27:01 +00:00
|
|
|
#endif
|
2009-07-14 16:55:14 +00:00
|
|
|
llvm_unreachable("Do not know how to expand the result of this operator!");
|
2008-06-20 18:40:50 +00:00
|
|
|
|
|
|
|
case ISD::MERGE_VALUES: SplitRes_MERGE_VALUES(N, Lo, Hi); break;
|
|
|
|
case ISD::UNDEF: SplitRes_UNDEF(N, Lo, Hi); break;
|
|
|
|
case ISD::SELECT: SplitRes_SELECT(N, Lo, Hi); break;
|
|
|
|
case ISD::SELECT_CC: SplitRes_SELECT_CC(N, Lo, Hi); break;
|
|
|
|
|
|
|
|
case ISD::BIT_CONVERT: ExpandRes_BIT_CONVERT(N, Lo, Hi); break;
|
|
|
|
case ISD::BUILD_PAIR: ExpandRes_BUILD_PAIR(N, Lo, Hi); break;
|
2008-06-23 15:08:15 +00:00
|
|
|
case ISD::EXTRACT_ELEMENT: ExpandRes_EXTRACT_ELEMENT(N, Lo, Hi); break;
|
2008-06-20 18:40:50 +00:00
|
|
|
case ISD::EXTRACT_VECTOR_ELT: ExpandRes_EXTRACT_VECTOR_ELT(N, Lo, Hi); break;
|
2008-10-29 14:25:28 +00:00
|
|
|
case ISD::VAARG: ExpandRes_VAARG(N, Lo, Hi); break;
|
2008-06-21 17:00:47 +00:00
|
|
|
|
2008-06-25 20:24:48 +00:00
|
|
|
case ISD::ConstantFP: ExpandFloatRes_ConstantFP(N, Lo, Hi); break;
|
2008-07-15 15:02:44 +00:00
|
|
|
case ISD::FABS: ExpandFloatRes_FABS(N, Lo, Hi); break;
|
2008-06-25 20:24:48 +00:00
|
|
|
case ISD::FADD: ExpandFloatRes_FADD(N, Lo, Hi); break;
|
2008-10-31 14:06:52 +00:00
|
|
|
case ISD::FCEIL: ExpandFloatRes_FCEIL(N, Lo, Hi); break;
|
|
|
|
case ISD::FCOS: ExpandFloatRes_FCOS(N, Lo, Hi); break;
|
2008-06-25 20:24:48 +00:00
|
|
|
case ISD::FDIV: ExpandFloatRes_FDIV(N, Lo, Hi); break;
|
2008-10-31 14:06:52 +00:00
|
|
|
case ISD::FEXP: ExpandFloatRes_FEXP(N, Lo, Hi); break;
|
|
|
|
case ISD::FEXP2: ExpandFloatRes_FEXP2(N, Lo, Hi); break;
|
|
|
|
case ISD::FFLOOR: ExpandFloatRes_FFLOOR(N, Lo, Hi); break;
|
|
|
|
case ISD::FLOG: ExpandFloatRes_FLOG(N, Lo, Hi); break;
|
|
|
|
case ISD::FLOG2: ExpandFloatRes_FLOG2(N, Lo, Hi); break;
|
|
|
|
case ISD::FLOG10: ExpandFloatRes_FLOG10(N, Lo, Hi); break;
|
2008-06-25 20:24:48 +00:00
|
|
|
case ISD::FMUL: ExpandFloatRes_FMUL(N, Lo, Hi); break;
|
2008-10-31 14:06:52 +00:00
|
|
|
case ISD::FNEARBYINT: ExpandFloatRes_FNEARBYINT(N, Lo, Hi); break;
|
2008-07-17 17:35:14 +00:00
|
|
|
case ISD::FNEG: ExpandFloatRes_FNEG(N, Lo, Hi); break;
|
|
|
|
case ISD::FP_EXTEND: ExpandFloatRes_FP_EXTEND(N, Lo, Hi); break;
|
2008-10-31 14:06:52 +00:00
|
|
|
case ISD::FPOW: ExpandFloatRes_FPOW(N, Lo, Hi); break;
|
|
|
|
case ISD::FPOWI: ExpandFloatRes_FPOWI(N, Lo, Hi); break;
|
|
|
|
case ISD::FRINT: ExpandFloatRes_FRINT(N, Lo, Hi); break;
|
2008-11-18 09:15:03 +00:00
|
|
|
case ISD::FSIN: ExpandFloatRes_FSIN(N, Lo, Hi); break;
|
2008-10-31 14:06:52 +00:00
|
|
|
case ISD::FSQRT: ExpandFloatRes_FSQRT(N, Lo, Hi); break;
|
2008-06-25 20:24:48 +00:00
|
|
|
case ISD::FSUB: ExpandFloatRes_FSUB(N, Lo, Hi); break;
|
2008-10-31 14:06:52 +00:00
|
|
|
case ISD::FTRUNC: ExpandFloatRes_FTRUNC(N, Lo, Hi); break;
|
2008-06-25 20:24:48 +00:00
|
|
|
case ISD::LOAD: ExpandFloatRes_LOAD(N, Lo, Hi); break;
|
|
|
|
case ISD::SINT_TO_FP:
|
|
|
|
case ISD::UINT_TO_FP: ExpandFloatRes_XINT_TO_FP(N, Lo, Hi); break;
|
2008-06-17 14:27:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// If Lo/Hi is null, the sub-method took care of registering results etc.
|
2008-08-28 21:40:38 +00:00
|
|
|
if (Lo.getNode())
|
2008-07-27 21:46:04 +00:00
|
|
|
SetExpandedFloat(SDValue(N, ResNo), Lo, Hi);
|
2008-06-17 14:27:01 +00:00
|
|
|
}
|
|
|
|
|
2008-07-27 21:46:04 +00:00
|
|
|
void DAGTypeLegalizer::ExpandFloatRes_ConstantFP(SDNode *N, SDValue &Lo,
|
|
|
|
SDValue &Hi) {
|
2009-08-12 00:36:31 +00:00
|
|
|
EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
|
2008-06-25 20:24:48 +00:00
|
|
|
assert(NVT.getSizeInBits() == integerPartWidth &&
|
|
|
|
"Do not know how to expand this float constant!");
|
2008-10-09 18:53:47 +00:00
|
|
|
APInt C = cast<ConstantFPSDNode>(N)->getValueAPF().bitcastToAPInt();
|
2008-06-25 20:24:48 +00:00
|
|
|
Lo = DAG.getConstantFP(APFloat(APInt(integerPartWidth, 1,
|
|
|
|
&C.getRawData()[1])), NVT);
|
|
|
|
Hi = DAG.getConstantFP(APFloat(APInt(integerPartWidth, 1,
|
|
|
|
&C.getRawData()[0])), NVT);
|
|
|
|
}
|
|
|
|
|
2008-07-27 21:46:04 +00:00
|
|
|
void DAGTypeLegalizer::ExpandFloatRes_FABS(SDNode *N, SDValue &Lo,
|
|
|
|
SDValue &Hi) {
|
2009-08-11 20:47:22 +00:00
|
|
|
assert(N->getValueType(0) == MVT::ppcf128 &&
|
2008-07-15 15:02:44 +00:00
|
|
|
"Logic only correct for ppcf128!");
|
2009-01-31 00:43:08 +00:00
|
|
|
DebugLoc dl = N->getDebugLoc();
|
2008-07-27 21:46:04 +00:00
|
|
|
SDValue Tmp;
|
2008-07-15 15:02:44 +00:00
|
|
|
GetExpandedFloat(N->getOperand(0), Lo, Tmp);
|
2009-01-31 00:43:08 +00:00
|
|
|
Hi = DAG.getNode(ISD::FABS, dl, Tmp.getValueType(), Tmp);
|
2008-07-15 15:02:44 +00:00
|
|
|
// Lo = Hi==fabs(Hi) ? Lo : -Lo;
|
2009-01-31 00:43:08 +00:00
|
|
|
Lo = DAG.getNode(ISD::SELECT_CC, dl, Lo.getValueType(), Tmp, Hi, Lo,
|
|
|
|
DAG.getNode(ISD::FNEG, dl, Lo.getValueType(), Lo),
|
2008-07-15 15:02:44 +00:00
|
|
|
DAG.getCondCode(ISD::SETEQ));
|
|
|
|
}
|
|
|
|
|
2008-10-31 14:06:52 +00:00
|
|
|
void DAGTypeLegalizer::ExpandFloatRes_FADD(SDNode *N, SDValue &Lo,
|
|
|
|
SDValue &Hi) {
|
|
|
|
SDValue Call = LibCallify(GetFPLibCall(N->getValueType(0),
|
|
|
|
RTLIB::ADD_F32, RTLIB::ADD_F64,
|
|
|
|
RTLIB::ADD_F80, RTLIB::ADD_PPCF128),
|
|
|
|
N, false);
|
2009-04-25 17:55:53 +00:00
|
|
|
GetPairElements(Call, Lo, Hi);
|
2008-10-31 14:06:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void DAGTypeLegalizer::ExpandFloatRes_FCEIL(SDNode *N,
|
|
|
|
SDValue &Lo, SDValue &Hi) {
|
|
|
|
SDValue Call = LibCallify(GetFPLibCall(N->getValueType(0),
|
|
|
|
RTLIB::CEIL_F32, RTLIB::CEIL_F64,
|
|
|
|
RTLIB::CEIL_F80, RTLIB::CEIL_PPCF128),
|
|
|
|
N, false);
|
2009-04-25 17:55:53 +00:00
|
|
|
GetPairElements(Call, Lo, Hi);
|
2008-10-31 14:06:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void DAGTypeLegalizer::ExpandFloatRes_FCOS(SDNode *N,
|
|
|
|
SDValue &Lo, SDValue &Hi) {
|
|
|
|
SDValue Call = LibCallify(GetFPLibCall(N->getValueType(0),
|
|
|
|
RTLIB::COS_F32, RTLIB::COS_F64,
|
|
|
|
RTLIB::COS_F80, RTLIB::COS_PPCF128),
|
|
|
|
N, false);
|
2009-04-25 17:55:53 +00:00
|
|
|
GetPairElements(Call, Lo, Hi);
|
2008-10-31 14:06:52 +00:00
|
|
|
}
|
|
|
|
|
2008-07-27 21:46:04 +00:00
|
|
|
void DAGTypeLegalizer::ExpandFloatRes_FDIV(SDNode *N, SDValue &Lo,
|
|
|
|
SDValue &Hi) {
|
|
|
|
SDValue Ops[2] = { N->getOperand(0), N->getOperand(1) };
|
|
|
|
SDValue Call = MakeLibCall(GetFPLibCall(N->getValueType(0),
|
2008-10-31 14:06:52 +00:00
|
|
|
RTLIB::DIV_F32,
|
|
|
|
RTLIB::DIV_F64,
|
|
|
|
RTLIB::DIV_F80,
|
|
|
|
RTLIB::DIV_PPCF128),
|
2009-02-02 19:46:41 +00:00
|
|
|
N->getValueType(0), Ops, 2, false,
|
2009-01-31 00:11:23 +00:00
|
|
|
N->getDebugLoc());
|
2009-04-25 17:55:53 +00:00
|
|
|
GetPairElements(Call, Lo, Hi);
|
2008-10-31 14:06:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void DAGTypeLegalizer::ExpandFloatRes_FEXP(SDNode *N,
|
|
|
|
SDValue &Lo, SDValue &Hi) {
|
|
|
|
SDValue Call = LibCallify(GetFPLibCall(N->getValueType(0),
|
|
|
|
RTLIB::EXP_F32, RTLIB::EXP_F64,
|
|
|
|
RTLIB::EXP_F80, RTLIB::EXP_PPCF128),
|
|
|
|
N, false);
|
2009-04-25 17:55:53 +00:00
|
|
|
GetPairElements(Call, Lo, Hi);
|
2008-10-31 14:06:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void DAGTypeLegalizer::ExpandFloatRes_FEXP2(SDNode *N,
|
|
|
|
SDValue &Lo, SDValue &Hi) {
|
|
|
|
SDValue Call = LibCallify(GetFPLibCall(N->getValueType(0),
|
|
|
|
RTLIB::EXP2_F32, RTLIB::EXP2_F64,
|
|
|
|
RTLIB::EXP2_F80, RTLIB::EXP2_PPCF128),
|
|
|
|
N, false);
|
2009-04-25 17:55:53 +00:00
|
|
|
GetPairElements(Call, Lo, Hi);
|
2008-10-31 14:06:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void DAGTypeLegalizer::ExpandFloatRes_FFLOOR(SDNode *N,
|
|
|
|
SDValue &Lo, SDValue &Hi) {
|
|
|
|
SDValue Call = LibCallify(GetFPLibCall(N->getValueType(0),
|
|
|
|
RTLIB::FLOOR_F32,RTLIB::FLOOR_F64,
|
|
|
|
RTLIB::FLOOR_F80,RTLIB::FLOOR_PPCF128),
|
|
|
|
N, false);
|
2009-04-25 17:55:53 +00:00
|
|
|
GetPairElements(Call, Lo, Hi);
|
2008-10-31 14:06:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void DAGTypeLegalizer::ExpandFloatRes_FLOG(SDNode *N,
|
|
|
|
SDValue &Lo, SDValue &Hi) {
|
|
|
|
SDValue Call = LibCallify(GetFPLibCall(N->getValueType(0),
|
|
|
|
RTLIB::LOG_F32, RTLIB::LOG_F64,
|
|
|
|
RTLIB::LOG_F80, RTLIB::LOG_PPCF128),
|
|
|
|
N, false);
|
2009-04-25 17:55:53 +00:00
|
|
|
GetPairElements(Call, Lo, Hi);
|
2008-10-31 14:06:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void DAGTypeLegalizer::ExpandFloatRes_FLOG2(SDNode *N,
|
|
|
|
SDValue &Lo, SDValue &Hi) {
|
|
|
|
SDValue Call = LibCallify(GetFPLibCall(N->getValueType(0),
|
|
|
|
RTLIB::LOG2_F32, RTLIB::LOG2_F64,
|
|
|
|
RTLIB::LOG2_F80, RTLIB::LOG2_PPCF128),
|
|
|
|
N, false);
|
2009-04-25 17:55:53 +00:00
|
|
|
GetPairElements(Call, Lo, Hi);
|
2008-10-31 14:06:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void DAGTypeLegalizer::ExpandFloatRes_FLOG10(SDNode *N,
|
|
|
|
SDValue &Lo, SDValue &Hi) {
|
|
|
|
SDValue Call = LibCallify(GetFPLibCall(N->getValueType(0),
|
|
|
|
RTLIB::LOG10_F32,RTLIB::LOG10_F64,
|
|
|
|
RTLIB::LOG10_F80,RTLIB::LOG10_PPCF128),
|
|
|
|
N, false);
|
2009-04-25 17:55:53 +00:00
|
|
|
GetPairElements(Call, Lo, Hi);
|
2008-06-25 20:24:48 +00:00
|
|
|
}
|
|
|
|
|
2008-07-27 21:46:04 +00:00
|
|
|
void DAGTypeLegalizer::ExpandFloatRes_FMUL(SDNode *N, SDValue &Lo,
|
|
|
|
SDValue &Hi) {
|
|
|
|
SDValue Ops[2] = { N->getOperand(0), N->getOperand(1) };
|
|
|
|
SDValue Call = MakeLibCall(GetFPLibCall(N->getValueType(0),
|
2008-10-31 14:06:52 +00:00
|
|
|
RTLIB::MUL_F32,
|
|
|
|
RTLIB::MUL_F64,
|
|
|
|
RTLIB::MUL_F80,
|
|
|
|
RTLIB::MUL_PPCF128),
|
2009-02-02 19:46:41 +00:00
|
|
|
N->getValueType(0), Ops, 2, false,
|
2009-01-31 00:11:23 +00:00
|
|
|
N->getDebugLoc());
|
2009-04-25 17:55:53 +00:00
|
|
|
GetPairElements(Call, Lo, Hi);
|
2008-10-31 14:06:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void DAGTypeLegalizer::ExpandFloatRes_FNEARBYINT(SDNode *N,
|
|
|
|
SDValue &Lo, SDValue &Hi) {
|
|
|
|
SDValue Call = LibCallify(GetFPLibCall(N->getValueType(0),
|
|
|
|
RTLIB::NEARBYINT_F32,
|
|
|
|
RTLIB::NEARBYINT_F64,
|
|
|
|
RTLIB::NEARBYINT_F80,
|
|
|
|
RTLIB::NEARBYINT_PPCF128),
|
|
|
|
N, false);
|
2009-04-25 17:55:53 +00:00
|
|
|
GetPairElements(Call, Lo, Hi);
|
2008-06-25 20:24:48 +00:00
|
|
|
}
|
|
|
|
|
2008-07-27 21:46:04 +00:00
|
|
|
void DAGTypeLegalizer::ExpandFloatRes_FNEG(SDNode *N, SDValue &Lo,
|
|
|
|
SDValue &Hi) {
|
2009-01-31 00:43:08 +00:00
|
|
|
DebugLoc dl = N->getDebugLoc();
|
2008-07-17 17:35:14 +00:00
|
|
|
GetExpandedFloat(N->getOperand(0), Lo, Hi);
|
2009-01-31 00:43:08 +00:00
|
|
|
Lo = DAG.getNode(ISD::FNEG, dl, Lo.getValueType(), Lo);
|
|
|
|
Hi = DAG.getNode(ISD::FNEG, dl, Hi.getValueType(), Hi);
|
2008-07-17 17:35:14 +00:00
|
|
|
}
|
|
|
|
|
2008-07-27 21:46:04 +00:00
|
|
|
void DAGTypeLegalizer::ExpandFloatRes_FP_EXTEND(SDNode *N, SDValue &Lo,
|
|
|
|
SDValue &Hi) {
|
2009-08-12 00:36:31 +00:00
|
|
|
EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
|
2009-01-31 00:43:08 +00:00
|
|
|
Hi = DAG.getNode(ISD::FP_EXTEND, N->getDebugLoc(), NVT, N->getOperand(0));
|
2008-07-17 17:35:14 +00:00
|
|
|
Lo = DAG.getConstantFP(APFloat(APInt(NVT.getSizeInBits(), 0)), NVT);
|
|
|
|
}
|
|
|
|
|
2008-10-31 14:06:52 +00:00
|
|
|
void DAGTypeLegalizer::ExpandFloatRes_FPOW(SDNode *N,
|
|
|
|
SDValue &Lo, SDValue &Hi) {
|
|
|
|
SDValue Call = LibCallify(GetFPLibCall(N->getValueType(0),
|
|
|
|
RTLIB::POW_F32, RTLIB::POW_F64,
|
|
|
|
RTLIB::POW_F80, RTLIB::POW_PPCF128),
|
|
|
|
N, false);
|
2009-04-25 17:55:53 +00:00
|
|
|
GetPairElements(Call, Lo, Hi);
|
2008-10-31 14:06:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void DAGTypeLegalizer::ExpandFloatRes_FPOWI(SDNode *N,
|
|
|
|
SDValue &Lo, SDValue &Hi) {
|
|
|
|
SDValue Call = LibCallify(GetFPLibCall(N->getValueType(0),
|
|
|
|
RTLIB::POWI_F32, RTLIB::POWI_F64,
|
|
|
|
RTLIB::POWI_F80, RTLIB::POWI_PPCF128),
|
|
|
|
N, false);
|
2009-04-25 17:55:53 +00:00
|
|
|
GetPairElements(Call, Lo, Hi);
|
2008-10-31 14:06:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void DAGTypeLegalizer::ExpandFloatRes_FRINT(SDNode *N,
|
|
|
|
SDValue &Lo, SDValue &Hi) {
|
|
|
|
SDValue Call = LibCallify(GetFPLibCall(N->getValueType(0),
|
|
|
|
RTLIB::RINT_F32, RTLIB::RINT_F64,
|
|
|
|
RTLIB::RINT_F80, RTLIB::RINT_PPCF128),
|
|
|
|
N, false);
|
2009-04-25 17:55:53 +00:00
|
|
|
GetPairElements(Call, Lo, Hi);
|
2008-10-31 14:06:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void DAGTypeLegalizer::ExpandFloatRes_FSIN(SDNode *N,
|
|
|
|
SDValue &Lo, SDValue &Hi) {
|
|
|
|
SDValue Call = LibCallify(GetFPLibCall(N->getValueType(0),
|
|
|
|
RTLIB::SIN_F32, RTLIB::SIN_F64,
|
|
|
|
RTLIB::SIN_F80, RTLIB::SIN_PPCF128),
|
|
|
|
N, false);
|
2009-04-25 17:55:53 +00:00
|
|
|
GetPairElements(Call, Lo, Hi);
|
2008-10-31 14:06:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void DAGTypeLegalizer::ExpandFloatRes_FSQRT(SDNode *N,
|
|
|
|
SDValue &Lo, SDValue &Hi) {
|
|
|
|
SDValue Call = LibCallify(GetFPLibCall(N->getValueType(0),
|
|
|
|
RTLIB::SQRT_F32, RTLIB::SQRT_F64,
|
|
|
|
RTLIB::SQRT_F80, RTLIB::SQRT_PPCF128),
|
|
|
|
N, false);
|
2009-04-25 17:55:53 +00:00
|
|
|
GetPairElements(Call, Lo, Hi);
|
2008-10-31 14:06:52 +00:00
|
|
|
}
|
|
|
|
|
2008-07-27 21:46:04 +00:00
|
|
|
void DAGTypeLegalizer::ExpandFloatRes_FSUB(SDNode *N, SDValue &Lo,
|
|
|
|
SDValue &Hi) {
|
|
|
|
SDValue Ops[2] = { N->getOperand(0), N->getOperand(1) };
|
|
|
|
SDValue Call = MakeLibCall(GetFPLibCall(N->getValueType(0),
|
2008-10-31 14:06:52 +00:00
|
|
|
RTLIB::SUB_F32,
|
|
|
|
RTLIB::SUB_F64,
|
|
|
|
RTLIB::SUB_F80,
|
|
|
|
RTLIB::SUB_PPCF128),
|
2009-01-31 00:11:23 +00:00
|
|
|
N->getValueType(0), Ops, 2, false,
|
|
|
|
N->getDebugLoc());
|
2009-04-25 17:55:53 +00:00
|
|
|
GetPairElements(Call, Lo, Hi);
|
2008-10-31 14:06:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void DAGTypeLegalizer::ExpandFloatRes_FTRUNC(SDNode *N,
|
|
|
|
SDValue &Lo, SDValue &Hi) {
|
|
|
|
SDValue Call = LibCallify(GetFPLibCall(N->getValueType(0),
|
|
|
|
RTLIB::TRUNC_F32, RTLIB::TRUNC_F64,
|
|
|
|
RTLIB::TRUNC_F80, RTLIB::TRUNC_PPCF128),
|
|
|
|
N, false);
|
2009-04-25 17:55:53 +00:00
|
|
|
GetPairElements(Call, Lo, Hi);
|
2008-06-25 20:24:48 +00:00
|
|
|
}
|
|
|
|
|
2008-07-27 21:46:04 +00:00
|
|
|
void DAGTypeLegalizer::ExpandFloatRes_LOAD(SDNode *N, SDValue &Lo,
|
|
|
|
SDValue &Hi) {
|
2008-06-23 14:19:45 +00:00
|
|
|
if (ISD::isNormalLoad(N)) {
|
|
|
|
ExpandRes_NormalLoad(N, Lo, Hi);
|
2008-06-21 17:00:47 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
assert(ISD::isUNINDEXEDLoad(N) && "Indexed load during type legalization!");
|
|
|
|
LoadSDNode *LD = cast<LoadSDNode>(N);
|
2008-07-27 21:46:04 +00:00
|
|
|
SDValue Chain = LD->getChain();
|
|
|
|
SDValue Ptr = LD->getBasePtr();
|
2009-01-31 00:43:08 +00:00
|
|
|
DebugLoc dl = N->getDebugLoc();
|
2008-06-21 17:00:47 +00:00
|
|
|
|
2009-08-12 00:36:31 +00:00
|
|
|
EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), LD->getValueType(0));
|
2008-06-21 17:00:47 +00:00
|
|
|
assert(NVT.isByteSized() && "Expanded type not byte sized!");
|
|
|
|
assert(LD->getMemoryVT().bitsLE(NVT) && "Float type not round?");
|
|
|
|
|
2009-01-31 00:43:08 +00:00
|
|
|
Hi = DAG.getExtLoad(LD->getExtensionType(), dl, NVT, Chain, Ptr,
|
2008-06-21 17:00:47 +00:00
|
|
|
LD->getSrcValue(), LD->getSrcValueOffset(),
|
|
|
|
LD->getMemoryVT(),
|
|
|
|
LD->isVolatile(), LD->getAlignment());
|
|
|
|
|
|
|
|
// Remember the chain.
|
2008-11-03 20:47:45 +00:00
|
|
|
Chain = Hi.getValue(1);
|
2008-06-21 17:00:47 +00:00
|
|
|
|
2008-11-03 20:47:45 +00:00
|
|
|
// The low part is zero.
|
|
|
|
Lo = DAG.getConstantFP(APFloat(APInt(NVT.getSizeInBits(), 0)), NVT);
|
2008-06-21 17:00:47 +00:00
|
|
|
|
|
|
|
// Modified the chain - switch anything that used the old chain to use the
|
|
|
|
// new one.
|
2008-07-27 21:46:04 +00:00
|
|
|
ReplaceValueWith(SDValue(LD, 1), Chain);
|
2008-06-21 17:00:47 +00:00
|
|
|
}
|
|
|
|
|
2008-07-27 21:46:04 +00:00
|
|
|
void DAGTypeLegalizer::ExpandFloatRes_XINT_TO_FP(SDNode *N, SDValue &Lo,
|
|
|
|
SDValue &Hi) {
|
2009-08-11 20:47:22 +00:00
|
|
|
assert(N->getValueType(0) == MVT::ppcf128 && "Unsupported XINT_TO_FP!");
|
2009-08-10 22:56:29 +00:00
|
|
|
EVT VT = N->getValueType(0);
|
2009-08-12 00:36:31 +00:00
|
|
|
EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT);
|
2008-07-27 21:46:04 +00:00
|
|
|
SDValue Src = N->getOperand(0);
|
2009-08-10 22:56:29 +00:00
|
|
|
EVT SrcVT = Src.getValueType();
|
2008-11-12 18:38:44 +00:00
|
|
|
bool isSigned = N->getOpcode() == ISD::SINT_TO_FP;
|
2009-01-31 00:11:23 +00:00
|
|
|
DebugLoc dl = N->getDebugLoc();
|
2008-06-25 20:24:48 +00:00
|
|
|
|
|
|
|
// First do an SINT_TO_FP, whether the original was signed or unsigned.
|
2008-11-12 18:38:44 +00:00
|
|
|
// When promoting partial word types to i32 we must honor the signedness,
|
|
|
|
// though.
|
2009-08-11 20:47:22 +00:00
|
|
|
if (SrcVT.bitsLE(MVT::i32)) {
|
2008-06-25 20:24:48 +00:00
|
|
|
// The integer can be represented exactly in an f64.
|
2009-01-31 00:43:08 +00:00
|
|
|
Src = DAG.getNode(isSigned ? ISD::SIGN_EXTEND : ISD::ZERO_EXTEND, dl,
|
2009-08-11 20:47:22 +00:00
|
|
|
MVT::i32, Src);
|
2008-06-25 20:24:48 +00:00
|
|
|
Lo = DAG.getConstantFP(APFloat(APInt(NVT.getSizeInBits(), 0)), NVT);
|
2009-01-31 00:43:08 +00:00
|
|
|
Hi = DAG.getNode(ISD::SINT_TO_FP, dl, NVT, Src);
|
2008-06-25 20:24:48 +00:00
|
|
|
} else {
|
|
|
|
RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL;
|
2009-08-11 20:47:22 +00:00
|
|
|
if (SrcVT.bitsLE(MVT::i64)) {
|
2009-01-31 00:43:08 +00:00
|
|
|
Src = DAG.getNode(isSigned ? ISD::SIGN_EXTEND : ISD::ZERO_EXTEND, dl,
|
2009-08-11 20:47:22 +00:00
|
|
|
MVT::i64, Src);
|
2008-06-25 20:24:48 +00:00
|
|
|
LC = RTLIB::SINTTOFP_I64_PPCF128;
|
2009-08-11 20:47:22 +00:00
|
|
|
} else if (SrcVT.bitsLE(MVT::i128)) {
|
|
|
|
Src = DAG.getNode(ISD::SIGN_EXTEND, dl, MVT::i128, Src);
|
2008-06-25 20:24:48 +00:00
|
|
|
LC = RTLIB::SINTTOFP_I128_PPCF128;
|
|
|
|
}
|
|
|
|
assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported XINT_TO_FP!");
|
|
|
|
|
2009-01-31 00:11:23 +00:00
|
|
|
Hi = MakeLibCall(LC, VT, &Src, 1, true, dl);
|
2009-04-25 17:55:53 +00:00
|
|
|
GetPairElements(Hi, Lo, Hi);
|
2008-06-25 20:24:48 +00:00
|
|
|
}
|
|
|
|
|
2008-11-12 18:38:44 +00:00
|
|
|
if (isSigned)
|
2008-06-25 20:24:48 +00:00
|
|
|
return;
|
|
|
|
|
|
|
|
// Unsigned - fix up the SINT_TO_FP value just calculated.
|
2009-01-31 00:43:08 +00:00
|
|
|
Hi = DAG.getNode(ISD::BUILD_PAIR, dl, VT, Lo, Hi);
|
2008-06-25 20:24:48 +00:00
|
|
|
SrcVT = Src.getValueType();
|
|
|
|
|
|
|
|
// x>=0 ? (ppcf128)(iN)x : (ppcf128)(iN)x + 2^N; N=32,64,128.
|
|
|
|
static const uint64_t TwoE32[] = { 0x41f0000000000000LL, 0 };
|
|
|
|
static const uint64_t TwoE64[] = { 0x43f0000000000000LL, 0 };
|
|
|
|
static const uint64_t TwoE128[] = { 0x47f0000000000000LL, 0 };
|
|
|
|
const uint64_t *Parts = 0;
|
|
|
|
|
2009-08-11 20:47:22 +00:00
|
|
|
switch (SrcVT.getSimpleVT().SimpleTy) {
|
2008-06-25 20:24:48 +00:00
|
|
|
default:
|
|
|
|
assert(false && "Unsupported UINT_TO_FP!");
|
2009-08-11 20:47:22 +00:00
|
|
|
case MVT::i32:
|
2008-06-25 20:24:48 +00:00
|
|
|
Parts = TwoE32;
|
2008-11-07 19:11:43 +00:00
|
|
|
break;
|
2009-08-11 20:47:22 +00:00
|
|
|
case MVT::i64:
|
2008-06-25 20:24:48 +00:00
|
|
|
Parts = TwoE64;
|
2008-11-07 19:11:43 +00:00
|
|
|
break;
|
2009-08-11 20:47:22 +00:00
|
|
|
case MVT::i128:
|
2008-06-25 20:24:48 +00:00
|
|
|
Parts = TwoE128;
|
2008-11-07 19:11:43 +00:00
|
|
|
break;
|
2008-06-25 20:24:48 +00:00
|
|
|
}
|
|
|
|
|
2009-01-31 00:43:08 +00:00
|
|
|
Lo = DAG.getNode(ISD::FADD, dl, VT, Hi,
|
2008-06-25 20:24:48 +00:00
|
|
|
DAG.getConstantFP(APFloat(APInt(128, 2, Parts)),
|
2009-08-11 20:47:22 +00:00
|
|
|
MVT::ppcf128));
|
2009-02-02 19:46:41 +00:00
|
|
|
Lo = DAG.getNode(ISD::SELECT_CC, dl, VT, Src, DAG.getConstant(0, SrcVT),
|
2009-01-31 00:43:08 +00:00
|
|
|
Lo, Hi, DAG.getCondCode(ISD::SETLT));
|
2009-04-25 17:55:53 +00:00
|
|
|
GetPairElements(Lo, Lo, Hi);
|
2008-06-25 20:24:48 +00:00
|
|
|
}
|
|
|
|
|
2008-06-17 14:27:01 +00:00
|
|
|
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// Float Operand Expansion
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
/// ExpandFloatOperand - This method is called when the specified operand of the
|
|
|
|
/// specified node is found to need expansion. At this point, all of the result
|
|
|
|
/// types of the node are known to be legal, but other operands of the node may
|
|
|
|
/// need promotion or expansion as well as the specified one.
|
|
|
|
bool DAGTypeLegalizer::ExpandFloatOperand(SDNode *N, unsigned OpNo) {
|
2009-07-25 01:43:01 +00:00
|
|
|
DEBUG(errs() << "Expand float operand: "; N->dump(&DAG); errs() << "\n");
|
2008-07-27 21:46:04 +00:00
|
|
|
SDValue Res = SDValue();
|
2008-06-17 14:27:01 +00:00
|
|
|
|
|
|
|
if (TLI.getOperationAction(N->getOpcode(), N->getOperand(OpNo).getValueType())
|
|
|
|
== TargetLowering::Custom)
|
2008-10-23 19:34:23 +00:00
|
|
|
Res = TLI.LowerOperation(SDValue(N, 0), DAG);
|
2008-06-17 14:27:01 +00:00
|
|
|
|
2008-08-28 21:40:38 +00:00
|
|
|
if (Res.getNode() == 0) {
|
2008-06-17 14:27:01 +00:00
|
|
|
switch (N->getOpcode()) {
|
|
|
|
default:
|
|
|
|
#ifndef NDEBUG
|
2009-07-25 01:43:01 +00:00
|
|
|
errs() << "ExpandFloatOperand Op #" << OpNo << ": ";
|
|
|
|
N->dump(&DAG); errs() << "\n";
|
2008-06-17 14:27:01 +00:00
|
|
|
#endif
|
2009-07-14 16:55:14 +00:00
|
|
|
llvm_unreachable("Do not know how to expand this operator's operand!");
|
2008-06-20 18:40:50 +00:00
|
|
|
|
|
|
|
case ISD::BIT_CONVERT: Res = ExpandOp_BIT_CONVERT(N); break;
|
|
|
|
case ISD::BUILD_VECTOR: Res = ExpandOp_BUILD_VECTOR(N); break;
|
|
|
|
case ISD::EXTRACT_ELEMENT: Res = ExpandOp_EXTRACT_ELEMENT(N); break;
|
2008-06-21 17:00:47 +00:00
|
|
|
|
2008-07-16 11:41:33 +00:00
|
|
|
case ISD::BR_CC: Res = ExpandFloatOp_BR_CC(N); break;
|
2008-06-25 20:24:48 +00:00
|
|
|
case ISD::FP_ROUND: Res = ExpandFloatOp_FP_ROUND(N); break;
|
|
|
|
case ISD::FP_TO_SINT: Res = ExpandFloatOp_FP_TO_SINT(N); break;
|
|
|
|
case ISD::FP_TO_UINT: Res = ExpandFloatOp_FP_TO_UINT(N); break;
|
2008-07-16 11:41:33 +00:00
|
|
|
case ISD::SELECT_CC: Res = ExpandFloatOp_SELECT_CC(N); break;
|
|
|
|
case ISD::SETCC: Res = ExpandFloatOp_SETCC(N); break;
|
|
|
|
case ISD::STORE: Res = ExpandFloatOp_STORE(cast<StoreSDNode>(N),
|
|
|
|
OpNo); break;
|
2008-06-17 14:27:01 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// If the result is null, the sub-method took care of registering results etc.
|
2008-08-28 21:40:38 +00:00
|
|
|
if (!Res.getNode()) return false;
|
2008-12-09 21:33:20 +00:00
|
|
|
|
|
|
|
// If the result is N, the sub-method updated N in place. Tell the legalizer
|
|
|
|
// core about this.
|
|
|
|
if (Res.getNode() == N)
|
2008-06-17 14:27:01 +00:00
|
|
|
return true;
|
|
|
|
|
|
|
|
assert(Res.getValueType() == N->getValueType(0) && N->getNumValues() == 1 &&
|
|
|
|
"Invalid operand expansion");
|
|
|
|
|
2008-07-27 21:46:04 +00:00
|
|
|
ReplaceValueWith(SDValue(N, 0), Res);
|
2008-06-17 14:27:01 +00:00
|
|
|
return false;
|
Initial soft-float support for LegalizeTypes. I rewrote
the fcopysign expansion from LegalizeDAG to get rid of
what seems to be a bug: the use of sign extension means
that when copying the sign bit from an f32 to an f64,
the upper 32 bits of the f64 (now an i64) are set, not
just the top bit... I also generalized it to work for
any sized floating point types, and removed the bogosity:
SDOperand Mask1 = (SrcVT == MVT::f64)
? DAG.getConstantFP(BitsToDouble(1ULL << 63), SrcVT)
: DAG.getConstantFP(BitsToFloat(1U << 31), SrcVT);
Mask1 = DAG.getNode(ISD::BIT_CONVERT, SrcNVT, Mask1);
(here SrcNVT is an integer with the same size as SrcVT).
As far as I can see this takes a 1 << 63, converts to
a double, converts that to a floating point constant
then converts that to an integer constant, ending up
with... 1 << 63 as an integer constant! So I just
generate this integer constant directly.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@48305 91177308-0d34-0410-b5e6-96231b3b80d8
2008-03-12 21:27:04 +00:00
|
|
|
}
|
2008-06-21 17:00:47 +00:00
|
|
|
|
2008-06-25 16:34:21 +00:00
|
|
|
/// FloatExpandSetCCOperands - Expand the operands of a comparison. This code
|
|
|
|
/// is shared among BR_CC, SELECT_CC, and SETCC handlers.
|
2008-07-27 21:46:04 +00:00
|
|
|
void DAGTypeLegalizer::FloatExpandSetCCOperands(SDValue &NewLHS,
|
|
|
|
SDValue &NewRHS,
|
2009-01-31 00:43:08 +00:00
|
|
|
ISD::CondCode &CCCode,
|
|
|
|
DebugLoc dl) {
|
2008-07-27 21:46:04 +00:00
|
|
|
SDValue LHSLo, LHSHi, RHSLo, RHSHi;
|
2008-06-25 16:34:21 +00:00
|
|
|
GetExpandedFloat(NewLHS, LHSLo, LHSHi);
|
|
|
|
GetExpandedFloat(NewRHS, RHSLo, RHSHi);
|
|
|
|
|
2009-08-10 22:56:29 +00:00
|
|
|
EVT VT = NewLHS.getValueType();
|
2009-08-11 20:47:22 +00:00
|
|
|
assert(VT == MVT::ppcf128 && "Unsupported setcc type!");
|
2008-06-25 16:34:21 +00:00
|
|
|
|
|
|
|
// FIXME: This generated code sucks. We want to generate
|
2008-11-03 20:47:45 +00:00
|
|
|
// FCMPU crN, hi1, hi2
|
2008-06-25 16:34:21 +00:00
|
|
|
// BNE crN, L:
|
2008-11-03 20:47:45 +00:00
|
|
|
// FCMPU crN, lo1, lo2
|
2008-06-25 16:34:21 +00:00
|
|
|
// The following can be improved, but not that much.
|
2008-07-27 21:46:04 +00:00
|
|
|
SDValue Tmp1, Tmp2, Tmp3;
|
2009-01-31 00:43:08 +00:00
|
|
|
Tmp1 = DAG.getSetCC(dl, TLI.getSetCCResultType(LHSHi.getValueType()),
|
2009-01-01 15:52:00 +00:00
|
|
|
LHSHi, RHSHi, ISD::SETOEQ);
|
2009-01-31 00:43:08 +00:00
|
|
|
Tmp2 = DAG.getSetCC(dl, TLI.getSetCCResultType(LHSLo.getValueType()),
|
2009-01-01 15:52:00 +00:00
|
|
|
LHSLo, RHSLo, CCCode);
|
2009-01-31 00:43:08 +00:00
|
|
|
Tmp3 = DAG.getNode(ISD::AND, dl, Tmp1.getValueType(), Tmp1, Tmp2);
|
|
|
|
Tmp1 = DAG.getSetCC(dl, TLI.getSetCCResultType(LHSHi.getValueType()),
|
2009-01-01 15:52:00 +00:00
|
|
|
LHSHi, RHSHi, ISD::SETUNE);
|
2009-01-31 00:43:08 +00:00
|
|
|
Tmp2 = DAG.getSetCC(dl, TLI.getSetCCResultType(LHSHi.getValueType()),
|
2009-01-01 15:52:00 +00:00
|
|
|
LHSHi, RHSHi, CCCode);
|
2009-01-31 00:43:08 +00:00
|
|
|
Tmp1 = DAG.getNode(ISD::AND, dl, Tmp1.getValueType(), Tmp1, Tmp2);
|
|
|
|
NewLHS = DAG.getNode(ISD::OR, dl, Tmp1.getValueType(), Tmp1, Tmp3);
|
2008-07-27 21:46:04 +00:00
|
|
|
NewRHS = SDValue(); // LHS is the result, not a compare.
|
2008-06-25 16:34:21 +00:00
|
|
|
}
|
|
|
|
|
2008-07-27 21:46:04 +00:00
|
|
|
SDValue DAGTypeLegalizer::ExpandFloatOp_BR_CC(SDNode *N) {
|
|
|
|
SDValue NewLHS = N->getOperand(2), NewRHS = N->getOperand(3);
|
2008-06-25 16:34:21 +00:00
|
|
|
ISD::CondCode CCCode = cast<CondCodeSDNode>(N->getOperand(1))->get();
|
2009-01-31 00:43:08 +00:00
|
|
|
FloatExpandSetCCOperands(NewLHS, NewRHS, CCCode, N->getDebugLoc());
|
2008-06-25 16:34:21 +00:00
|
|
|
|
|
|
|
// If ExpandSetCCOperands returned a scalar, we need to compare the result
|
|
|
|
// against zero to select between true and false values.
|
2008-08-28 21:40:38 +00:00
|
|
|
if (NewRHS.getNode() == 0) {
|
2008-06-25 16:34:21 +00:00
|
|
|
NewRHS = DAG.getConstant(0, NewLHS.getValueType());
|
|
|
|
CCCode = ISD::SETNE;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Update N to have the operands specified.
|
2008-07-27 21:46:04 +00:00
|
|
|
return DAG.UpdateNodeOperands(SDValue(N, 0), N->getOperand(0),
|
2008-06-25 16:34:21 +00:00
|
|
|
DAG.getCondCode(CCCode), NewLHS, NewRHS,
|
|
|
|
N->getOperand(4));
|
|
|
|
}
|
|
|
|
|
2008-07-27 21:46:04 +00:00
|
|
|
SDValue DAGTypeLegalizer::ExpandFloatOp_FP_ROUND(SDNode *N) {
|
2009-08-11 20:47:22 +00:00
|
|
|
assert(N->getOperand(0).getValueType() == MVT::ppcf128 &&
|
2008-07-16 11:41:33 +00:00
|
|
|
"Logic only correct for ppcf128!");
|
2008-07-27 21:46:04 +00:00
|
|
|
SDValue Lo, Hi;
|
2008-07-16 11:41:33 +00:00
|
|
|
GetExpandedFloat(N->getOperand(0), Lo, Hi);
|
|
|
|
// Round it the rest of the way (e.g. to f32) if needed.
|
2009-01-31 00:43:08 +00:00
|
|
|
return DAG.getNode(ISD::FP_ROUND, N->getDebugLoc(),
|
|
|
|
N->getValueType(0), Hi, N->getOperand(1));
|
2008-06-25 16:34:21 +00:00
|
|
|
}
|
|
|
|
|
2008-07-27 21:46:04 +00:00
|
|
|
SDValue DAGTypeLegalizer::ExpandFloatOp_FP_TO_SINT(SDNode *N) {
|
2009-08-10 22:56:29 +00:00
|
|
|
EVT RVT = N->getValueType(0);
|
2009-01-31 00:11:23 +00:00
|
|
|
DebugLoc dl = N->getDebugLoc();
|
2009-02-02 19:46:41 +00:00
|
|
|
|
2008-10-28 15:00:32 +00:00
|
|
|
// Expand ppcf128 to i32 by hand for the benefit of llvm-gcc bootstrap on
|
|
|
|
// PPC (the libcall is not available). FIXME: Do this in a less hacky way.
|
2009-08-11 20:47:22 +00:00
|
|
|
if (RVT == MVT::i32) {
|
|
|
|
assert(N->getOperand(0).getValueType() == MVT::ppcf128 &&
|
2008-10-28 15:00:32 +00:00
|
|
|
"Logic only correct for ppcf128!");
|
2009-08-11 20:47:22 +00:00
|
|
|
SDValue Res = DAG.getNode(ISD::FP_ROUND_INREG, dl, MVT::ppcf128,
|
|
|
|
N->getOperand(0), DAG.getValueType(MVT::f64));
|
|
|
|
Res = DAG.getNode(ISD::FP_ROUND, dl, MVT::f64, Res,
|
2009-01-31 00:43:08 +00:00
|
|
|
DAG.getIntPtrConstant(1));
|
2009-08-11 20:47:22 +00:00
|
|
|
return DAG.getNode(ISD::FP_TO_SINT, dl, MVT::i32, Res);
|
2008-10-28 15:00:32 +00:00
|
|
|
}
|
|
|
|
|
2008-07-17 02:36:29 +00:00
|
|
|
RTLIB::Libcall LC = RTLIB::getFPTOSINT(N->getOperand(0).getValueType(), RVT);
|
|
|
|
assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported FP_TO_SINT!");
|
2009-01-31 00:11:23 +00:00
|
|
|
return MakeLibCall(LC, RVT, &N->getOperand(0), 1, false, dl);
|
2008-06-25 16:34:21 +00:00
|
|
|
}
|
|
|
|
|
2008-07-27 21:46:04 +00:00
|
|
|
SDValue DAGTypeLegalizer::ExpandFloatOp_FP_TO_UINT(SDNode *N) {
|
2009-08-10 22:56:29 +00:00
|
|
|
EVT RVT = N->getValueType(0);
|
2009-01-31 00:11:23 +00:00
|
|
|
DebugLoc dl = N->getDebugLoc();
|
2008-10-28 15:00:32 +00:00
|
|
|
|
|
|
|
// Expand ppcf128 to i32 by hand for the benefit of llvm-gcc bootstrap on
|
|
|
|
// PPC (the libcall is not available). FIXME: Do this in a less hacky way.
|
2009-08-11 20:47:22 +00:00
|
|
|
if (RVT == MVT::i32) {
|
|
|
|
assert(N->getOperand(0).getValueType() == MVT::ppcf128 &&
|
2008-10-28 15:00:32 +00:00
|
|
|
"Logic only correct for ppcf128!");
|
|
|
|
const uint64_t TwoE31[] = {0x41e0000000000000LL, 0};
|
|
|
|
APFloat APF = APFloat(APInt(128, 2, TwoE31));
|
2009-08-11 20:47:22 +00:00
|
|
|
SDValue Tmp = DAG.getConstantFP(APF, MVT::ppcf128);
|
2008-10-28 15:00:32 +00:00
|
|
|
// X>=2^31 ? (int)(X-2^31)+0x80000000 : (int)X
|
|
|
|
// FIXME: generated code sucks.
|
2009-08-11 20:47:22 +00:00
|
|
|
return DAG.getNode(ISD::SELECT_CC, dl, MVT::i32, N->getOperand(0), Tmp,
|
|
|
|
DAG.getNode(ISD::ADD, dl, MVT::i32,
|
|
|
|
DAG.getNode(ISD::FP_TO_SINT, dl, MVT::i32,
|
2009-01-31 00:43:08 +00:00
|
|
|
DAG.getNode(ISD::FSUB, dl,
|
2009-08-11 20:47:22 +00:00
|
|
|
MVT::ppcf128,
|
2008-10-28 15:00:32 +00:00
|
|
|
N->getOperand(0),
|
|
|
|
Tmp)),
|
2009-08-11 20:47:22 +00:00
|
|
|
DAG.getConstant(0x80000000, MVT::i32)),
|
2009-01-31 00:43:08 +00:00
|
|
|
DAG.getNode(ISD::FP_TO_SINT, dl,
|
2009-08-11 20:47:22 +00:00
|
|
|
MVT::i32, N->getOperand(0)),
|
2008-10-28 15:00:32 +00:00
|
|
|
DAG.getCondCode(ISD::SETGE));
|
|
|
|
}
|
|
|
|
|
2008-07-17 02:36:29 +00:00
|
|
|
RTLIB::Libcall LC = RTLIB::getFPTOUINT(N->getOperand(0).getValueType(), RVT);
|
|
|
|
assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported FP_TO_UINT!");
|
2009-01-31 00:11:23 +00:00
|
|
|
return MakeLibCall(LC, N->getValueType(0), &N->getOperand(0), 1, false, dl);
|
2008-06-25 20:24:48 +00:00
|
|
|
}
|
|
|
|
|
2008-07-27 21:46:04 +00:00
|
|
|
SDValue DAGTypeLegalizer::ExpandFloatOp_SELECT_CC(SDNode *N) {
|
|
|
|
SDValue NewLHS = N->getOperand(0), NewRHS = N->getOperand(1);
|
2008-07-16 11:41:33 +00:00
|
|
|
ISD::CondCode CCCode = cast<CondCodeSDNode>(N->getOperand(4))->get();
|
2009-01-31 00:43:08 +00:00
|
|
|
FloatExpandSetCCOperands(NewLHS, NewRHS, CCCode, N->getDebugLoc());
|
2008-06-25 20:24:48 +00:00
|
|
|
|
2008-07-16 11:41:33 +00:00
|
|
|
// If ExpandSetCCOperands returned a scalar, we need to compare the result
|
|
|
|
// against zero to select between true and false values.
|
2008-08-28 21:40:38 +00:00
|
|
|
if (NewRHS.getNode() == 0) {
|
2008-07-16 11:41:33 +00:00
|
|
|
NewRHS = DAG.getConstant(0, NewLHS.getValueType());
|
|
|
|
CCCode = ISD::SETNE;
|
2008-06-25 20:24:48 +00:00
|
|
|
}
|
|
|
|
|
2008-07-16 11:41:33 +00:00
|
|
|
// Update N to have the operands specified.
|
2008-07-27 21:46:04 +00:00
|
|
|
return DAG.UpdateNodeOperands(SDValue(N, 0), NewLHS, NewRHS,
|
2008-07-16 11:41:33 +00:00
|
|
|
N->getOperand(2), N->getOperand(3),
|
|
|
|
DAG.getCondCode(CCCode));
|
2008-06-25 20:24:48 +00:00
|
|
|
}
|
|
|
|
|
2008-07-27 21:46:04 +00:00
|
|
|
SDValue DAGTypeLegalizer::ExpandFloatOp_SETCC(SDNode *N) {
|
|
|
|
SDValue NewLHS = N->getOperand(0), NewRHS = N->getOperand(1);
|
2008-07-16 11:41:33 +00:00
|
|
|
ISD::CondCode CCCode = cast<CondCodeSDNode>(N->getOperand(2))->get();
|
2009-01-31 00:43:08 +00:00
|
|
|
FloatExpandSetCCOperands(NewLHS, NewRHS, CCCode, N->getDebugLoc());
|
2008-07-16 11:41:33 +00:00
|
|
|
|
|
|
|
// If ExpandSetCCOperands returned a scalar, use it.
|
2008-08-28 21:40:38 +00:00
|
|
|
if (NewRHS.getNode() == 0) {
|
2008-07-16 11:41:33 +00:00
|
|
|
assert(NewLHS.getValueType() == N->getValueType(0) &&
|
|
|
|
"Unexpected setcc expansion!");
|
|
|
|
return NewLHS;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Otherwise, update N to have the operands specified.
|
2008-07-27 21:46:04 +00:00
|
|
|
return DAG.UpdateNodeOperands(SDValue(N, 0), NewLHS, NewRHS,
|
2008-07-16 11:41:33 +00:00
|
|
|
DAG.getCondCode(CCCode));
|
2008-06-25 20:24:48 +00:00
|
|
|
}
|
|
|
|
|
2008-07-27 21:46:04 +00:00
|
|
|
SDValue DAGTypeLegalizer::ExpandFloatOp_STORE(SDNode *N, unsigned OpNo) {
|
2008-06-23 14:19:45 +00:00
|
|
|
if (ISD::isNormalStore(N))
|
|
|
|
return ExpandOp_NormalStore(N, OpNo);
|
2008-06-21 17:00:47 +00:00
|
|
|
|
|
|
|
assert(ISD::isUNINDEXEDStore(N) && "Indexed store during type legalization!");
|
|
|
|
assert(OpNo == 1 && "Can only expand the stored value so far");
|
|
|
|
StoreSDNode *ST = cast<StoreSDNode>(N);
|
|
|
|
|
2008-07-27 21:46:04 +00:00
|
|
|
SDValue Chain = ST->getChain();
|
|
|
|
SDValue Ptr = ST->getBasePtr();
|
2008-06-21 17:00:47 +00:00
|
|
|
|
2009-08-12 00:36:31 +00:00
|
|
|
EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), ST->getValue().getValueType());
|
2008-06-21 17:00:47 +00:00
|
|
|
assert(NVT.isByteSized() && "Expanded type not byte sized!");
|
|
|
|
assert(ST->getMemoryVT().bitsLE(NVT) && "Float type not round?");
|
|
|
|
|
2008-07-27 21:46:04 +00:00
|
|
|
SDValue Lo, Hi;
|
2008-06-21 17:00:47 +00:00
|
|
|
GetExpandedOp(ST->getValue(), Lo, Hi);
|
|
|
|
|
2009-01-31 00:43:08 +00:00
|
|
|
return DAG.getTruncStore(Chain, N->getDebugLoc(), Hi, Ptr,
|
2008-06-21 17:00:47 +00:00
|
|
|
ST->getSrcValue(), ST->getSrcValueOffset(),
|
|
|
|
ST->getMemoryVT(),
|
|
|
|
ST->isVolatile(), ST->getAlignment());
|
|
|
|
}
|