mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-24 11:42:57 +01:00
Break the code for expanding UINT_TO_FP operations out into its own
SelectionDAGLegalize::ExpandLegalUINT_TO_FP method. Add a new method, PromoteLegalUINT_TO_FP, which allows targets to request that UINT_TO_FP operations be promoted to a larger input type. This is useful for targets that have some UINT_TO_FP or SINT_TO_FP operations but not all of them (like X86). The same should be done with SINT_TO_FP, but this patch does not do that yet. llvm-svn: 22447
This commit is contained in:
parent
94e486c56e
commit
10da57bfed
@ -124,6 +124,10 @@ private:
|
|||||||
SDOperand &Hi);
|
SDOperand &Hi);
|
||||||
SDOperand ExpandIntToFP(bool isSigned, MVT::ValueType DestTy,
|
SDOperand ExpandIntToFP(bool isSigned, MVT::ValueType DestTy,
|
||||||
SDOperand Source);
|
SDOperand Source);
|
||||||
|
|
||||||
|
SDOperand ExpandLegalUINT_TO_FP(SDOperand LegalOp, MVT::ValueType DestVT);
|
||||||
|
SDOperand PromoteLegalUINT_TO_FP(SDOperand LegalOp, MVT::ValueType DestVT);
|
||||||
|
|
||||||
bool ExpandShift(unsigned Opc, SDOperand Op, SDOperand Amt,
|
bool ExpandShift(unsigned Opc, SDOperand Op, SDOperand Amt,
|
||||||
SDOperand &Lo, SDOperand &Hi);
|
SDOperand &Lo, SDOperand &Hi);
|
||||||
void ExpandShiftParts(unsigned NodeOp, SDOperand Op, SDOperand Amt,
|
void ExpandShiftParts(unsigned NodeOp, SDOperand Op, SDOperand Amt,
|
||||||
@ -147,6 +151,102 @@ SelectionDAGLegalize::SelectionDAGLegalize(SelectionDAG &dag)
|
|||||||
"Too many value types for ValueTypeActions to hold!");
|
"Too many value types for ValueTypeActions to hold!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// ExpandLegalUINT_TO_FP - This function is responsible for legalizing a
|
||||||
|
/// UINT_TO_FP operation of the specified operand when the target requests that
|
||||||
|
/// we expand it. At this point, we know that the result and operand types are
|
||||||
|
/// legal for the target.
|
||||||
|
SDOperand SelectionDAGLegalize::ExpandLegalUINT_TO_FP(SDOperand Op0,
|
||||||
|
MVT::ValueType DestVT) {
|
||||||
|
assert(Op0.getValueType() == MVT::i32 &&
|
||||||
|
"This code only works for i32 input: extend in the future");
|
||||||
|
SDOperand Tmp1 = DAG.getNode(ISD::SINT_TO_FP, DestVT, Op0);
|
||||||
|
|
||||||
|
SDOperand SignSet = DAG.getSetCC(ISD::SETLT, TLI.getSetCCResultTy(),
|
||||||
|
Op0,
|
||||||
|
DAG.getConstant(0,
|
||||||
|
Op0.getValueType()));
|
||||||
|
SDOperand Zero = getIntPtrConstant(0), Four = getIntPtrConstant(4);
|
||||||
|
SDOperand CstOffset = DAG.getNode(ISD::SELECT, Zero.getValueType(),
|
||||||
|
SignSet, Four, Zero);
|
||||||
|
|
||||||
|
uint64_t FF = 0x5f800000ULL;
|
||||||
|
if (TLI.isLittleEndian()) FF <<= 32;
|
||||||
|
static Constant *FudgeFactor = ConstantUInt::get(Type::ULongTy, FF);
|
||||||
|
|
||||||
|
MachineConstantPool *CP = DAG.getMachineFunction().getConstantPool();
|
||||||
|
SDOperand CPIdx = DAG.getConstantPool(CP->getConstantPoolIndex(FudgeFactor),
|
||||||
|
TLI.getPointerTy());
|
||||||
|
CPIdx = DAG.getNode(ISD::ADD, TLI.getPointerTy(), CPIdx, CstOffset);
|
||||||
|
SDOperand FudgeInReg;
|
||||||
|
if (DestVT == MVT::f32)
|
||||||
|
FudgeInReg = DAG.getLoad(MVT::f32, DAG.getEntryNode(), CPIdx,
|
||||||
|
DAG.getSrcValue(NULL));
|
||||||
|
else {
|
||||||
|
assert(DestVT == MVT::f64 && "Unexpected conversion");
|
||||||
|
FudgeInReg = LegalizeOp(DAG.getExtLoad(ISD::EXTLOAD, MVT::f64,
|
||||||
|
DAG.getEntryNode(), CPIdx,
|
||||||
|
DAG.getSrcValue(NULL), MVT::f32));
|
||||||
|
}
|
||||||
|
|
||||||
|
NeedsAnotherIteration = true;
|
||||||
|
return DAG.getNode(ISD::ADD, DestVT, Tmp1, FudgeInReg);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// PromoteLegalUINT_TO_FP - This function is responsible for legalizing a
|
||||||
|
/// UINT_TO_FP operation of the specified operand when the target requests that
|
||||||
|
/// we promote it. At this point, we know that the result and operand types are
|
||||||
|
/// legal for the target, and that there is a legal UINT_TO_FP or SINT_TO_FP
|
||||||
|
/// operation that takes a larger input.
|
||||||
|
SDOperand SelectionDAGLegalize::PromoteLegalUINT_TO_FP(SDOperand LegalOp,
|
||||||
|
MVT::ValueType DestVT) {
|
||||||
|
// First step, figure out the appropriate *INT_TO_FP operation to use.
|
||||||
|
MVT::ValueType NewInTy = LegalOp.getValueType();
|
||||||
|
|
||||||
|
unsigned OpToUse = 0;
|
||||||
|
|
||||||
|
// Scan for the appropriate larger type to use.
|
||||||
|
while (1) {
|
||||||
|
NewInTy = (MVT::ValueType)(NewInTy+1);
|
||||||
|
assert(MVT::isInteger(NewInTy) && "Ran out of possibilities!");
|
||||||
|
|
||||||
|
// If the target supports SINT_TO_FP of this type, use it.
|
||||||
|
switch (TLI.getOperationAction(ISD::SINT_TO_FP, NewInTy)) {
|
||||||
|
default: break;
|
||||||
|
case TargetLowering::Legal:
|
||||||
|
if (!TLI.hasNativeSupportFor(NewInTy))
|
||||||
|
break; // Can't use this datatype.
|
||||||
|
// FALL THROUGH.
|
||||||
|
case TargetLowering::Custom:
|
||||||
|
OpToUse = ISD::SINT_TO_FP;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (OpToUse) break;
|
||||||
|
|
||||||
|
// If the target supports UINT_TO_FP of this type, use it.
|
||||||
|
switch (TLI.getOperationAction(ISD::UINT_TO_FP, NewInTy)) {
|
||||||
|
default: break;
|
||||||
|
case TargetLowering::Legal:
|
||||||
|
if (!TLI.hasNativeSupportFor(NewInTy))
|
||||||
|
break; // Can't use this datatype.
|
||||||
|
// FALL THROUGH.
|
||||||
|
case TargetLowering::Custom:
|
||||||
|
OpToUse = ISD::UINT_TO_FP;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (OpToUse) break;
|
||||||
|
|
||||||
|
// Otherwise, try a larger type.
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make sure to legalize any nodes we create here in the next pass.
|
||||||
|
NeedsAnotherIteration = true;
|
||||||
|
|
||||||
|
// Okay, we found the operation and type to use. Zero extend our input to the
|
||||||
|
// desired type then run the operation on it.
|
||||||
|
return DAG.getNode(OpToUse, DestVT,
|
||||||
|
DAG.getNode(ISD::ZERO_EXTEND, NewInTy, LegalOp));
|
||||||
|
}
|
||||||
|
|
||||||
void SelectionDAGLegalize::LegalizeDAG() {
|
void SelectionDAGLegalize::LegalizeDAG() {
|
||||||
SDOperand OldRoot = DAG.getRoot();
|
SDOperand OldRoot = DAG.getRoot();
|
||||||
SDOperand NewRoot = LegalizeOp(OldRoot);
|
SDOperand NewRoot = LegalizeOp(OldRoot);
|
||||||
@ -1338,43 +1438,24 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
|
|||||||
switch (getTypeAction(Node->getOperand(0).getValueType())) {
|
switch (getTypeAction(Node->getOperand(0).getValueType())) {
|
||||||
case Legal:
|
case Legal:
|
||||||
//still made need to expand if the op is illegal, but the types are legal
|
//still made need to expand if the op is illegal, but the types are legal
|
||||||
if (Node->getOpcode() == ISD::UINT_TO_FP &&
|
if (Node->getOpcode() == ISD::UINT_TO_FP) {
|
||||||
TLI.getOperationAction(Node->getOpcode(),
|
switch (TLI.getOperationAction(Node->getOpcode(),
|
||||||
Node->getOperand(0).getValueType())
|
Node->getOperand(0).getValueType())) {
|
||||||
== TargetLowering::Expand) {
|
default: assert(0 && "Unknown operation action!");
|
||||||
SDOperand Op0 = LegalizeOp(Node->getOperand(0));
|
case TargetLowering::Expand:
|
||||||
Tmp1 = DAG.getNode(ISD::SINT_TO_FP, Node->getValueType(0),
|
Result = ExpandLegalUINT_TO_FP(LegalizeOp(Node->getOperand(0)),
|
||||||
Op0);
|
Node->getValueType(0));
|
||||||
|
AddLegalizedOperand(Op, Result);
|
||||||
SDOperand SignSet = DAG.getSetCC(ISD::SETLT, TLI.getSetCCResultTy(),
|
return Result;
|
||||||
Op0,
|
case TargetLowering::Promote:
|
||||||
DAG.getConstant(0,
|
Result = PromoteLegalUINT_TO_FP(LegalizeOp(Node->getOperand(0)),
|
||||||
Op0.getValueType()));
|
Node->getValueType(0));
|
||||||
SDOperand Zero = getIntPtrConstant(0), Four = getIntPtrConstant(4);
|
AddLegalizedOperand(Op, Result);
|
||||||
SDOperand CstOffset = DAG.getNode(ISD::SELECT, Zero.getValueType(),
|
return Result;
|
||||||
SignSet, Four, Zero);
|
case TargetLowering::Legal:
|
||||||
uint64_t FF = 0x5f800000ULL;
|
|
||||||
if (TLI.isLittleEndian()) FF <<= 32;
|
|
||||||
static Constant *FudgeFactor = ConstantUInt::get(Type::ULongTy, FF);
|
|
||||||
|
|
||||||
MachineConstantPool *CP = DAG.getMachineFunction().getConstantPool();
|
|
||||||
SDOperand CPIdx = DAG.getConstantPool(CP->getConstantPoolIndex(FudgeFactor),
|
|
||||||
TLI.getPointerTy());
|
|
||||||
CPIdx = DAG.getNode(ISD::ADD, TLI.getPointerTy(), CPIdx, CstOffset);
|
|
||||||
SDOperand FudgeInReg;
|
|
||||||
if (Node->getValueType(0) == MVT::f32)
|
|
||||||
FudgeInReg = DAG.getLoad(MVT::f32, DAG.getEntryNode(), CPIdx,
|
|
||||||
DAG.getSrcValue(NULL));
|
|
||||||
else {
|
|
||||||
assert(Node->getValueType(0) == MVT::f64 && "Unexpected conversion");
|
|
||||||
FudgeInReg =
|
|
||||||
LegalizeOp(DAG.getExtLoad(ISD::EXTLOAD, MVT::f64,
|
|
||||||
DAG.getEntryNode(), CPIdx,
|
|
||||||
DAG.getSrcValue(NULL), MVT::f32));
|
|
||||||
}
|
|
||||||
Result = DAG.getNode(ISD::ADD, Node->getValueType(0), Tmp1, FudgeInReg);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
Tmp1 = LegalizeOp(Node->getOperand(0));
|
Tmp1 = LegalizeOp(Node->getOperand(0));
|
||||||
if (Tmp1 != Node->getOperand(0))
|
if (Tmp1 != Node->getOperand(0))
|
||||||
Result = DAG.getNode(Node->getOpcode(), Node->getValueType(0), Tmp1);
|
Result = DAG.getNode(Node->getOpcode(), Node->getValueType(0), Tmp1);
|
||||||
|
Loading…
Reference in New Issue
Block a user