forked from OSchip/llvm-project
Use a custom expander to compile this:
long %test4(double %X) { %tmp.1 = cast double %X to long ; <long> [#uses=1] ret long %tmp.1 } to this: _test4: sub %ESP, 12 fld QWORD PTR [%ESP + 16] fistp QWORD PTR [%ESP] mov %EDX, DWORD PTR [%ESP + 4] mov %EAX, DWORD PTR [%ESP] add %ESP, 12 ret instead of this: _test4: sub %ESP, 28 fld QWORD PTR [%ESP + 32] fstp QWORD PTR [%ESP] call ___fixdfdi add %ESP, 28 ret llvm-svn: 22549
This commit is contained in:
parent
fe68d75aad
commit
67756e2e22
|
@ -54,6 +54,12 @@ namespace {
|
||||||
/// address) and two outputs (FP value and token chain).
|
/// address) and two outputs (FP value and token chain).
|
||||||
FILD64m,
|
FILD64m,
|
||||||
|
|
||||||
|
/// FISTP64m - This instruction implements FP_TO_SINT with a
|
||||||
|
/// 64-bit destination in memory and a FP reg source. This corresponds to
|
||||||
|
/// the X86::FISTP64m instruction. It has two inputs (token chain and
|
||||||
|
/// address) and two outputs (FP value and token chain).
|
||||||
|
FISTP64m,
|
||||||
|
|
||||||
/// CALL/TAILCALL - These operations represent an abstract X86 call
|
/// CALL/TAILCALL - These operations represent an abstract X86 call
|
||||||
/// instruction, which includes a bunch of information. In particular the
|
/// instruction, which includes a bunch of information. In particular the
|
||||||
/// operands of these node are:
|
/// operands of these node are:
|
||||||
|
@ -118,8 +124,12 @@ namespace {
|
||||||
setOperationAction(ISD::SINT_TO_FP , MVT::i1 , Promote);
|
setOperationAction(ISD::SINT_TO_FP , MVT::i1 , Promote);
|
||||||
setOperationAction(ISD::SINT_TO_FP , MVT::i8 , Promote);
|
setOperationAction(ISD::SINT_TO_FP , MVT::i8 , Promote);
|
||||||
|
|
||||||
// We can handle SINT_TO_FP from i64 even though i64 isn't legal.
|
if (!X86ScalarSSE) {
|
||||||
|
// We can handle SINT_TO_FP and FP_TO_SINT from/TO i64 even though i64
|
||||||
|
// isn't legal.
|
||||||
setOperationAction(ISD::SINT_TO_FP , MVT::i64 , Custom);
|
setOperationAction(ISD::SINT_TO_FP , MVT::i64 , Custom);
|
||||||
|
setOperationAction(ISD::FP_TO_SINT , MVT::i64 , Custom);
|
||||||
|
}
|
||||||
|
|
||||||
setOperationAction(ISD::BRCONDTWOWAY , MVT::Other, Expand);
|
setOperationAction(ISD::BRCONDTWOWAY , MVT::Other, Expand);
|
||||||
setOperationAction(ISD::MEMMOVE , MVT::Other, Expand);
|
setOperationAction(ISD::MEMMOVE , MVT::Other, Expand);
|
||||||
|
@ -944,7 +954,7 @@ LowerFrameReturnAddress(bool isFrameAddress, SDOperand Chain, unsigned Depth,
|
||||||
SDOperand X86TargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) {
|
SDOperand X86TargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) {
|
||||||
switch (Op.getOpcode()) {
|
switch (Op.getOpcode()) {
|
||||||
default: assert(0 && "Should not custom lower this!");
|
default: assert(0 && "Should not custom lower this!");
|
||||||
case ISD::SINT_TO_FP:
|
case ISD::SINT_TO_FP: {
|
||||||
assert(Op.getValueType() == MVT::f64 &&
|
assert(Op.getValueType() == MVT::f64 &&
|
||||||
Op.getOperand(0).getValueType() == MVT::i64 &&
|
Op.getOperand(0).getValueType() == MVT::i64 &&
|
||||||
"Unknown SINT_TO_FP to lower!");
|
"Unknown SINT_TO_FP to lower!");
|
||||||
|
@ -963,6 +973,27 @@ SDOperand X86TargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) {
|
||||||
Ops.push_back(StackSlot);
|
Ops.push_back(StackSlot);
|
||||||
return DAG.getNode(X86ISD::FILD64m, RTs, Ops);
|
return DAG.getNode(X86ISD::FILD64m, RTs, Ops);
|
||||||
}
|
}
|
||||||
|
case ISD::FP_TO_SINT: {
|
||||||
|
assert(Op.getValueType() == MVT::i64 &&
|
||||||
|
Op.getOperand(0).getValueType() == MVT::f64 &&
|
||||||
|
"Unknown FP_TO_SINT to lower!");
|
||||||
|
// We lower FP->sint64 into FISTP64, followed by a load, all to a temporary
|
||||||
|
// stack slot.
|
||||||
|
MachineFunction &MF = DAG.getMachineFunction();
|
||||||
|
int SSFI = MF.getFrameInfo()->CreateStackObject(8, 8);
|
||||||
|
SDOperand StackSlot = DAG.getFrameIndex(SSFI, getPointerTy());
|
||||||
|
|
||||||
|
// Build the FISTP64
|
||||||
|
std::vector<SDOperand> Ops;
|
||||||
|
Ops.push_back(DAG.getEntryNode());
|
||||||
|
Ops.push_back(Op.getOperand(0));
|
||||||
|
Ops.push_back(StackSlot);
|
||||||
|
SDOperand FISTP = DAG.getNode(X86ISD::FISTP64m, MVT::Other, Ops);
|
||||||
|
|
||||||
|
// Load the result.
|
||||||
|
return DAG.getLoad(MVT::i64, FISTP, StackSlot, DAG.getSrcValue(NULL));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -2475,7 +2506,8 @@ unsigned ISel::SelectExpr(SDOperand N) {
|
||||||
break;
|
break;
|
||||||
case MVT::i64:
|
case MVT::i64:
|
||||||
addFrameReference(BuildMI(BB, X86::FISTP64m, 5), FrameIdx).addReg(Tmp1);
|
addFrameReference(BuildMI(BB, X86::FISTP64m, 5), FrameIdx).addReg(Tmp1);
|
||||||
break; }
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
switch (Node->getValueType(0)) {
|
switch (Node->getValueType(0)) {
|
||||||
default:
|
default:
|
||||||
|
@ -3320,14 +3352,9 @@ unsigned ISel::SelectExpr(SDOperand N) {
|
||||||
SelectAddress(Address, AM);
|
SelectAddress(Address, AM);
|
||||||
Select(Chain);
|
Select(Chain);
|
||||||
}
|
}
|
||||||
if (X86ScalarSSE) {
|
|
||||||
addFullAddress(BuildMI(BB, X86::FILD64m, 4, X86::FP0), AM);
|
|
||||||
addFullAddress(BuildMI(BB, X86::FST64m, 5), AM).addReg(X86::FP0);
|
|
||||||
addFullAddress(BuildMI(BB, X86::MOVSDrm, 4, Result), AM);
|
|
||||||
} else {
|
|
||||||
addFullAddress(BuildMI(BB, X86::FILD64m, 4, Result), AM);
|
addFullAddress(BuildMI(BB, X86::FILD64m, 4, Result), AM);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return Result;
|
return Result;
|
||||||
|
|
||||||
case ISD::EXTLOAD: // Arbitrarily codegen extloads as MOVZX*
|
case ISD::EXTLOAD: // Arbitrarily codegen extloads as MOVZX*
|
||||||
|
@ -4329,6 +4356,23 @@ void ISel::Select(SDOperand N) {
|
||||||
SelectExpr(N.getValue(0));
|
SelectExpr(N.getValue(0));
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
case X86ISD::FISTP64m: {
|
||||||
|
assert(N.getOperand(1).getValueType() == MVT::f64);
|
||||||
|
X86AddressMode AM;
|
||||||
|
Select(N.getOperand(0)); // Select the token chain
|
||||||
|
|
||||||
|
unsigned ValReg;
|
||||||
|
if (getRegPressure(N.getOperand(1)) > getRegPressure(N.getOperand(2))) {
|
||||||
|
ValReg = SelectExpr(N.getOperand(1));
|
||||||
|
SelectAddress(N.getOperand(2), AM);
|
||||||
|
} else {
|
||||||
|
SelectAddress(N.getOperand(2), AM);
|
||||||
|
ValReg = SelectExpr(N.getOperand(1));
|
||||||
|
}
|
||||||
|
addFullAddress(BuildMI(BB, X86::FISTP64m, 5), AM).addReg(ValReg);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
case ISD::TRUNCSTORE: { // truncstore chain, val, ptr, SRCVALUE, storety
|
case ISD::TRUNCSTORE: { // truncstore chain, val, ptr, SRCVALUE, storety
|
||||||
X86AddressMode AM;
|
X86AddressMode AM;
|
||||||
MVT::ValueType StoredTy = cast<VTSDNode>(N.getOperand(4))->getVT();
|
MVT::ValueType StoredTy = cast<VTSDNode>(N.getOperand(4))->getVT();
|
||||||
|
|
Loading…
Reference in New Issue