mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-08-26 23:29:22 +00:00
Make the x86 backend custom-lower UINT_TO_FP and FP_TO_UINT on 32-bit
systems instead of attempting to promote them to a 64-bit SINT_TO_FP or FP_TO_SINT. This is in preparation for removing the type legalization code from LegalizeDAG: once type legalization is gone from LegalizeDAG, it won't be able to handle the i64 operand/result correctly. This isn't quite ideal, but I don't think any other operation for any target ends up in this situation, so treating this case specially seems reasonable. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@72324 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
db917fe8aa
commit
948e95a381
@ -116,16 +116,14 @@ X86TargetLowering::X86TargetLowering(X86TargetMachine &TM)
|
|||||||
if (Subtarget->is64Bit()) {
|
if (Subtarget->is64Bit()) {
|
||||||
setOperationAction(ISD::UINT_TO_FP , MVT::i32 , Promote);
|
setOperationAction(ISD::UINT_TO_FP , MVT::i32 , Promote);
|
||||||
setOperationAction(ISD::UINT_TO_FP , MVT::i64 , Expand);
|
setOperationAction(ISD::UINT_TO_FP , MVT::i64 , Expand);
|
||||||
} else {
|
} else if (!UseSoftFloat) {
|
||||||
if (!UseSoftFloat && !NoImplicitFloat && X86ScalarSSEf64) {
|
if (X86ScalarSSEf64) {
|
||||||
// We have an impenetrably clever algorithm for ui64->double only.
|
// We have an impenetrably clever algorithm for ui64->double only.
|
||||||
setOperationAction(ISD::UINT_TO_FP , MVT::i64 , Custom);
|
setOperationAction(ISD::UINT_TO_FP , MVT::i64 , Custom);
|
||||||
|
|
||||||
// We have faster algorithm for ui32->single only.
|
|
||||||
setOperationAction(ISD::UINT_TO_FP , MVT::i32 , Custom);
|
|
||||||
} else {
|
|
||||||
setOperationAction(ISD::UINT_TO_FP , MVT::i32 , Promote);
|
|
||||||
}
|
}
|
||||||
|
// We have an algorithm for SSE2, and we turn this into a 64-bit
|
||||||
|
// FILD for other targets.
|
||||||
|
setOperationAction(ISD::UINT_TO_FP , MVT::i32 , Custom);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Promote i1/i8 SINT_TO_FP to larger SINT_TO_FP's, as X86 doesn't have
|
// Promote i1/i8 SINT_TO_FP to larger SINT_TO_FP's, as X86 doesn't have
|
||||||
@ -176,15 +174,16 @@ X86TargetLowering::X86TargetLowering(X86TargetMachine &TM)
|
|||||||
if (Subtarget->is64Bit()) {
|
if (Subtarget->is64Bit()) {
|
||||||
setOperationAction(ISD::FP_TO_UINT , MVT::i64 , Expand);
|
setOperationAction(ISD::FP_TO_UINT , MVT::i64 , Expand);
|
||||||
setOperationAction(ISD::FP_TO_UINT , MVT::i32 , Promote);
|
setOperationAction(ISD::FP_TO_UINT , MVT::i32 , Promote);
|
||||||
} else {
|
} else if (!UseSoftFloat) {
|
||||||
if (X86ScalarSSEf32 && !Subtarget->hasSSE3())
|
if (X86ScalarSSEf32 && !Subtarget->hasSSE3())
|
||||||
// Expand FP_TO_UINT into a select.
|
// Expand FP_TO_UINT into a select.
|
||||||
// FIXME: We would like to use a Custom expander here eventually to do
|
// FIXME: We would like to use a Custom expander here eventually to do
|
||||||
// the optimal thing for SSE vs. the default expansion in the legalizer.
|
// the optimal thing for SSE vs. the default expansion in the legalizer.
|
||||||
setOperationAction(ISD::FP_TO_UINT , MVT::i32 , Expand);
|
setOperationAction(ISD::FP_TO_UINT , MVT::i32 , Expand);
|
||||||
else
|
else
|
||||||
// With SSE3 we can use fisttpll to convert to a signed i64.
|
// With SSE3 we can use fisttpll to convert to a signed i64; without
|
||||||
setOperationAction(ISD::FP_TO_UINT , MVT::i32 , Promote);
|
// SSE, we're stuck with a fistpll.
|
||||||
|
setOperationAction(ISD::FP_TO_UINT , MVT::i32 , Custom);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: when we have SSE, these could be more efficient, by using movd/movq.
|
// TODO: when we have SSE, these could be more efficient, by using movd/movq.
|
||||||
@ -4608,8 +4607,14 @@ SDValue X86TargetLowering::LowerSINT_TO_FP(SDValue Op, SelectionDAG &DAG) {
|
|||||||
SDValue Chain = DAG.getStore(DAG.getEntryNode(), dl, Op.getOperand(0),
|
SDValue Chain = DAG.getStore(DAG.getEntryNode(), dl, Op.getOperand(0),
|
||||||
StackSlot,
|
StackSlot,
|
||||||
PseudoSourceValue::getFixedStack(SSFI), 0);
|
PseudoSourceValue::getFixedStack(SSFI), 0);
|
||||||
|
return BuildFILD(Op, SrcVT, Chain, StackSlot, DAG);
|
||||||
|
}
|
||||||
|
|
||||||
|
SDValue X86TargetLowering::BuildFILD(SDValue Op, MVT SrcVT, SDValue Chain,
|
||||||
|
SDValue StackSlot,
|
||||||
|
SelectionDAG &DAG) {
|
||||||
// Build the FILD
|
// Build the FILD
|
||||||
|
DebugLoc dl = Op.getDebugLoc();
|
||||||
SDVTList Tys;
|
SDVTList Tys;
|
||||||
bool useSSE = isScalarFPTypeInSSEReg(Op.getValueType());
|
bool useSSE = isScalarFPTypeInSSEReg(Op.getValueType());
|
||||||
if (useSSE)
|
if (useSSE)
|
||||||
@ -4792,38 +4797,57 @@ SDValue X86TargetLowering::LowerUINT_TO_FP(SDValue Op, SelectionDAG &DAG) {
|
|||||||
return SDValue();
|
return SDValue();
|
||||||
|
|
||||||
return LowerUINT_TO_FP_i64(Op, DAG);
|
return LowerUINT_TO_FP_i64(Op, DAG);
|
||||||
} else if (SrcVT == MVT::i32) {
|
} else if (SrcVT == MVT::i32 && X86ScalarSSEf64) {
|
||||||
return LowerUINT_TO_FP_i32(Op, DAG);
|
return LowerUINT_TO_FP_i32(Op, DAG);
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(0 && "Unknown UINT_TO_FP to lower!");
|
assert(SrcVT == MVT::i32 && "Unknown UINT_TO_FP to lower!");
|
||||||
return SDValue();
|
|
||||||
|
// Make a 64-bit buffer, and use it to build an FILD.
|
||||||
|
SDValue StackSlot = DAG.CreateStackTemporary(MVT::i64);
|
||||||
|
SDValue WordOff = DAG.getConstant(4, getPointerTy());
|
||||||
|
SDValue OffsetSlot = DAG.getNode(ISD::ADD, dl,
|
||||||
|
getPointerTy(), StackSlot, WordOff);
|
||||||
|
SDValue Store1 = DAG.getStore(DAG.getEntryNode(), dl, Op.getOperand(0),
|
||||||
|
StackSlot, NULL, 0);
|
||||||
|
SDValue Store2 = DAG.getStore(Store1, dl, DAG.getConstant(0, MVT::i32),
|
||||||
|
OffsetSlot, NULL, 0);
|
||||||
|
return BuildFILD(Op, MVT::i64, Store2, StackSlot, DAG);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::pair<SDValue,SDValue> X86TargetLowering::
|
std::pair<SDValue,SDValue> X86TargetLowering::
|
||||||
FP_TO_SINTHelper(SDValue Op, SelectionDAG &DAG) {
|
FP_TO_INTHelper(SDValue Op, SelectionDAG &DAG, bool IsSigned) {
|
||||||
DebugLoc dl = Op.getDebugLoc();
|
DebugLoc dl = Op.getDebugLoc();
|
||||||
assert(Op.getValueType().getSimpleVT() <= MVT::i64 &&
|
|
||||||
Op.getValueType().getSimpleVT() >= MVT::i16 &&
|
MVT DstTy = Op.getValueType();
|
||||||
|
|
||||||
|
if (!IsSigned) {
|
||||||
|
assert(DstTy == MVT::i32 && "Unexpected FP_TO_UINT");
|
||||||
|
DstTy = MVT::i64;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(DstTy.getSimpleVT() <= MVT::i64 &&
|
||||||
|
DstTy.getSimpleVT() >= MVT::i16 &&
|
||||||
"Unknown FP_TO_SINT to lower!");
|
"Unknown FP_TO_SINT to lower!");
|
||||||
|
|
||||||
// These are really Legal.
|
// These are really Legal.
|
||||||
if (Op.getValueType() == MVT::i32 &&
|
if (DstTy == MVT::i32 &&
|
||||||
isScalarFPTypeInSSEReg(Op.getOperand(0).getValueType()))
|
isScalarFPTypeInSSEReg(Op.getOperand(0).getValueType()))
|
||||||
return std::make_pair(SDValue(), SDValue());
|
return std::make_pair(SDValue(), SDValue());
|
||||||
if (Subtarget->is64Bit() &&
|
if (Subtarget->is64Bit() &&
|
||||||
Op.getValueType() == MVT::i64 &&
|
DstTy == MVT::i64 &&
|
||||||
Op.getOperand(0).getValueType() != MVT::f80)
|
Op.getOperand(0).getValueType() != MVT::f80)
|
||||||
return std::make_pair(SDValue(), SDValue());
|
return std::make_pair(SDValue(), SDValue());
|
||||||
|
|
||||||
// We lower FP->sint64 into FISTP64, followed by a load, all to a temporary
|
// We lower FP->sint64 into FISTP64, followed by a load, all to a temporary
|
||||||
// stack slot.
|
// stack slot.
|
||||||
MachineFunction &MF = DAG.getMachineFunction();
|
MachineFunction &MF = DAG.getMachineFunction();
|
||||||
unsigned MemSize = Op.getValueType().getSizeInBits()/8;
|
unsigned MemSize = DstTy.getSizeInBits()/8;
|
||||||
int SSFI = MF.getFrameInfo()->CreateStackObject(MemSize, MemSize);
|
int SSFI = MF.getFrameInfo()->CreateStackObject(MemSize, MemSize);
|
||||||
SDValue StackSlot = DAG.getFrameIndex(SSFI, getPointerTy());
|
SDValue StackSlot = DAG.getFrameIndex(SSFI, getPointerTy());
|
||||||
|
|
||||||
unsigned Opc;
|
unsigned Opc;
|
||||||
switch (Op.getValueType().getSimpleVT()) {
|
switch (DstTy.getSimpleVT()) {
|
||||||
default: assert(0 && "Invalid FP_TO_SINT to lower!");
|
default: assert(0 && "Invalid FP_TO_SINT to lower!");
|
||||||
case MVT::i16: Opc = X86ISD::FP_TO_INT16_IN_MEM; break;
|
case MVT::i16: Opc = X86ISD::FP_TO_INT16_IN_MEM; break;
|
||||||
case MVT::i32: Opc = X86ISD::FP_TO_INT32_IN_MEM; break;
|
case MVT::i32: Opc = X86ISD::FP_TO_INT32_IN_MEM; break;
|
||||||
@ -4833,7 +4857,7 @@ FP_TO_SINTHelper(SDValue Op, SelectionDAG &DAG) {
|
|||||||
SDValue Chain = DAG.getEntryNode();
|
SDValue Chain = DAG.getEntryNode();
|
||||||
SDValue Value = Op.getOperand(0);
|
SDValue Value = Op.getOperand(0);
|
||||||
if (isScalarFPTypeInSSEReg(Op.getOperand(0).getValueType())) {
|
if (isScalarFPTypeInSSEReg(Op.getOperand(0).getValueType())) {
|
||||||
assert(Op.getValueType() == MVT::i64 && "Invalid FP_TO_SINT to lower!");
|
assert(DstTy == MVT::i64 && "Invalid FP_TO_SINT to lower!");
|
||||||
Chain = DAG.getStore(Chain, dl, Value, StackSlot,
|
Chain = DAG.getStore(Chain, dl, Value, StackSlot,
|
||||||
PseudoSourceValue::getFixedStack(SSFI), 0);
|
PseudoSourceValue::getFixedStack(SSFI), 0);
|
||||||
SDVTList Tys = DAG.getVTList(Op.getOperand(0).getValueType(), MVT::Other);
|
SDVTList Tys = DAG.getVTList(Op.getOperand(0).getValueType(), MVT::Other);
|
||||||
@ -4854,7 +4878,7 @@ FP_TO_SINTHelper(SDValue Op, SelectionDAG &DAG) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
SDValue X86TargetLowering::LowerFP_TO_SINT(SDValue Op, SelectionDAG &DAG) {
|
SDValue X86TargetLowering::LowerFP_TO_SINT(SDValue Op, SelectionDAG &DAG) {
|
||||||
std::pair<SDValue,SDValue> Vals = FP_TO_SINTHelper(Op, DAG);
|
std::pair<SDValue,SDValue> Vals = FP_TO_INTHelper(Op, DAG, true);
|
||||||
SDValue FIST = Vals.first, StackSlot = Vals.second;
|
SDValue FIST = Vals.first, StackSlot = Vals.second;
|
||||||
if (FIST.getNode() == 0) return SDValue();
|
if (FIST.getNode() == 0) return SDValue();
|
||||||
|
|
||||||
@ -4863,6 +4887,16 @@ SDValue X86TargetLowering::LowerFP_TO_SINT(SDValue Op, SelectionDAG &DAG) {
|
|||||||
FIST, StackSlot, NULL, 0);
|
FIST, StackSlot, NULL, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SDValue X86TargetLowering::LowerFP_TO_UINT(SDValue Op, SelectionDAG &DAG) {
|
||||||
|
std::pair<SDValue,SDValue> Vals = FP_TO_INTHelper(Op, DAG, false);
|
||||||
|
SDValue FIST = Vals.first, StackSlot = Vals.second;
|
||||||
|
assert(FIST.getNode() && "Unexpected failure");
|
||||||
|
|
||||||
|
// Load the result.
|
||||||
|
return DAG.getLoad(Op.getValueType(), Op.getDebugLoc(),
|
||||||
|
FIST, StackSlot, NULL, 0);
|
||||||
|
}
|
||||||
|
|
||||||
SDValue X86TargetLowering::LowerFABS(SDValue Op, SelectionDAG &DAG) {
|
SDValue X86TargetLowering::LowerFABS(SDValue Op, SelectionDAG &DAG) {
|
||||||
DebugLoc dl = Op.getDebugLoc();
|
DebugLoc dl = Op.getDebugLoc();
|
||||||
MVT VT = Op.getValueType();
|
MVT VT = Op.getValueType();
|
||||||
@ -6555,6 +6589,7 @@ SDValue X86TargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) {
|
|||||||
case ISD::SINT_TO_FP: return LowerSINT_TO_FP(Op, DAG);
|
case ISD::SINT_TO_FP: return LowerSINT_TO_FP(Op, DAG);
|
||||||
case ISD::UINT_TO_FP: return LowerUINT_TO_FP(Op, DAG);
|
case ISD::UINT_TO_FP: return LowerUINT_TO_FP(Op, DAG);
|
||||||
case ISD::FP_TO_SINT: return LowerFP_TO_SINT(Op, DAG);
|
case ISD::FP_TO_SINT: return LowerFP_TO_SINT(Op, DAG);
|
||||||
|
case ISD::FP_TO_UINT: return LowerFP_TO_UINT(Op, DAG);
|
||||||
case ISD::FABS: return LowerFABS(Op, DAG);
|
case ISD::FABS: return LowerFABS(Op, DAG);
|
||||||
case ISD::FNEG: return LowerFNEG(Op, DAG);
|
case ISD::FNEG: return LowerFNEG(Op, DAG);
|
||||||
case ISD::FCOPYSIGN: return LowerFCOPYSIGN(Op, DAG);
|
case ISD::FCOPYSIGN: return LowerFCOPYSIGN(Op, DAG);
|
||||||
@ -6626,7 +6661,8 @@ void X86TargetLowering::ReplaceNodeResults(SDNode *N,
|
|||||||
assert(false && "Do not know how to custom type legalize this operation!");
|
assert(false && "Do not know how to custom type legalize this operation!");
|
||||||
return;
|
return;
|
||||||
case ISD::FP_TO_SINT: {
|
case ISD::FP_TO_SINT: {
|
||||||
std::pair<SDValue,SDValue> Vals = FP_TO_SINTHelper(SDValue(N, 0), DAG);
|
std::pair<SDValue,SDValue> Vals =
|
||||||
|
FP_TO_INTHelper(SDValue(N, 0), DAG, true);
|
||||||
SDValue FIST = Vals.first, StackSlot = Vals.second;
|
SDValue FIST = Vals.first, StackSlot = Vals.second;
|
||||||
if (FIST.getNode() != 0) {
|
if (FIST.getNode() != 0) {
|
||||||
MVT VT = N->getValueType(0);
|
MVT VT = N->getValueType(0);
|
||||||
|
@ -569,8 +569,8 @@ namespace llvm {
|
|||||||
NameDecorationStyle NameDecorationForFORMAL_ARGUMENTS(SDValue Op);
|
NameDecorationStyle NameDecorationForFORMAL_ARGUMENTS(SDValue Op);
|
||||||
unsigned GetAlignedArgumentStackSize(unsigned StackSize, SelectionDAG &DAG);
|
unsigned GetAlignedArgumentStackSize(unsigned StackSize, SelectionDAG &DAG);
|
||||||
|
|
||||||
std::pair<SDValue,SDValue> FP_TO_SINTHelper(SDValue Op,
|
std::pair<SDValue,SDValue> FP_TO_INTHelper(SDValue Op, SelectionDAG &DAG,
|
||||||
SelectionDAG &DAG);
|
bool isSigned);
|
||||||
|
|
||||||
SDValue LowerBUILD_VECTOR(SDValue Op, SelectionDAG &DAG);
|
SDValue LowerBUILD_VECTOR(SDValue Op, SelectionDAG &DAG);
|
||||||
SDValue LowerVECTOR_SHUFFLE(SDValue Op, SelectionDAG &DAG);
|
SDValue LowerVECTOR_SHUFFLE(SDValue Op, SelectionDAG &DAG);
|
||||||
@ -586,11 +586,14 @@ namespace llvm {
|
|||||||
SDValue LowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG);
|
SDValue LowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG);
|
||||||
SDValue LowerExternalSymbol(SDValue Op, SelectionDAG &DAG);
|
SDValue LowerExternalSymbol(SDValue Op, SelectionDAG &DAG);
|
||||||
SDValue LowerShift(SDValue Op, SelectionDAG &DAG);
|
SDValue LowerShift(SDValue Op, SelectionDAG &DAG);
|
||||||
|
SDValue BuildFILD(SDValue Op, MVT SrcVT, SDValue Chain, SDValue StackSlot,
|
||||||
|
SelectionDAG &DAG);
|
||||||
SDValue LowerSINT_TO_FP(SDValue Op, SelectionDAG &DAG);
|
SDValue LowerSINT_TO_FP(SDValue Op, SelectionDAG &DAG);
|
||||||
SDValue LowerUINT_TO_FP(SDValue Op, SelectionDAG &DAG);
|
SDValue LowerUINT_TO_FP(SDValue Op, SelectionDAG &DAG);
|
||||||
SDValue LowerUINT_TO_FP_i64(SDValue Op, SelectionDAG &DAG);
|
SDValue LowerUINT_TO_FP_i64(SDValue Op, SelectionDAG &DAG);
|
||||||
SDValue LowerUINT_TO_FP_i32(SDValue Op, SelectionDAG &DAG);
|
SDValue LowerUINT_TO_FP_i32(SDValue Op, SelectionDAG &DAG);
|
||||||
SDValue LowerFP_TO_SINT(SDValue Op, SelectionDAG &DAG);
|
SDValue LowerFP_TO_SINT(SDValue Op, SelectionDAG &DAG);
|
||||||
|
SDValue LowerFP_TO_UINT(SDValue Op, SelectionDAG &DAG);
|
||||||
SDValue LowerFABS(SDValue Op, SelectionDAG &DAG);
|
SDValue LowerFABS(SDValue Op, SelectionDAG &DAG);
|
||||||
SDValue LowerFNEG(SDValue Op, SelectionDAG &DAG);
|
SDValue LowerFNEG(SDValue Op, SelectionDAG &DAG);
|
||||||
SDValue LowerFCOPYSIGN(SDValue Op, SelectionDAG &DAG);
|
SDValue LowerFCOPYSIGN(SDValue Op, SelectionDAG &DAG);
|
||||||
|
Loading…
Reference in New Issue
Block a user