mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-02-01 05:01:59 +01:00
Implement i64<->fp using the fctidz/fcfid instructions on PowerPC when we
are allowed to generate 64-bit-only PowerPC instructions for 32 bit hosts, such as the PowerPC 970. This speeds up 189.lucas from 81.99 to 32.64 seconds. llvm-svn: 23250
This commit is contained in:
parent
f12074e8f6
commit
718cae4eba
@ -817,6 +817,14 @@ unsigned ISel::SelectExpr(SDOperand N, bool Recording) {
|
||||
Tmp3 = SelectExpr(N.getOperand(2));
|
||||
BuildMI(BB, PPC::FSEL, 3, Result).addReg(Tmp1).addReg(Tmp2).addReg(Tmp3);
|
||||
return Result;
|
||||
case PPCISD::FCFID:
|
||||
Tmp1 = SelectExpr(N.getOperand(0));
|
||||
BuildMI(BB, PPC::FCFID, 1, Result).addReg(Tmp1);
|
||||
return Result;
|
||||
case PPCISD::FCTIDZ:
|
||||
Tmp1 = SelectExpr(N.getOperand(0));
|
||||
BuildMI(BB, PPC::FCTIDZ, 1, Result).addReg(Tmp1);
|
||||
return Result;
|
||||
case PPCISD::FCTIWZ:
|
||||
Tmp1 = SelectExpr(N.getOperand(0));
|
||||
BuildMI(BB, PPC::FCTIWZ, 1, Result).addReg(Tmp1);
|
||||
@ -1084,13 +1092,13 @@ unsigned ISel::SelectExpr(SDOperand N, bool Recording) {
|
||||
if (isOpcWithIntImmediate(N.getOperand(0), ISD::AND, Tmp3) &&
|
||||
isRotateAndMask(ISD::SRL, Tmp2, Tmp3, true, SH, MB, ME)) {
|
||||
Tmp1 = SelectExpr(N.getOperand(0).getOperand(0));
|
||||
BuildMI(BB, PPC::RLWINM, 4, Result).addReg(Tmp1).addImm(SH)
|
||||
BuildMI(BB, PPC::RLWINM, 4, Result).addReg(Tmp1).addImm(SH & 0x1F)
|
||||
.addImm(MB).addImm(ME);
|
||||
return Result;
|
||||
}
|
||||
Tmp1 = SelectExpr(N.getOperand(0));
|
||||
Tmp2 &= 0x1F;
|
||||
BuildMI(BB, PPC::RLWINM, 4, Result).addReg(Tmp1).addImm(32-Tmp2)
|
||||
BuildMI(BB, PPC::RLWINM, 4, Result).addReg(Tmp1).addImm((32-Tmp2) & 0x1F)
|
||||
.addImm(Tmp2).addImm(31);
|
||||
} else {
|
||||
Tmp1 = SelectExpr(N.getOperand(0));
|
||||
|
@ -795,6 +795,14 @@ SDOperand PPC32DAGToDAGISel::Select(SDOperand Op) {
|
||||
Select(N->getOperand(1)),
|
||||
Select(N->getOperand(2)));
|
||||
return SDOperand(N, 0);
|
||||
case PPCISD::FCFID:
|
||||
CurDAG->SelectNodeTo(N, PPC::FCFID, N->getValueType(0),
|
||||
Select(N->getOperand(0)));
|
||||
return SDOperand(N, 0);
|
||||
case PPCISD::FCTIDZ:
|
||||
CurDAG->SelectNodeTo(N, PPC::FCTIDZ, N->getValueType(0),
|
||||
Select(N->getOperand(0)));
|
||||
return SDOperand(N, 0);
|
||||
case PPCISD::FCTIWZ:
|
||||
CurDAG->SelectNodeTo(N, PPC::FCTIWZ, N->getValueType(0),
|
||||
Select(N->getOperand(0)));
|
||||
@ -1085,10 +1093,11 @@ SDOperand PPC32DAGToDAGISel::Select(SDOperand Op) {
|
||||
isRotateAndMask(N, Imm, true, SH, MB, ME))
|
||||
CurDAG->SelectNodeTo(N, PPC::RLWINM, MVT::i32,
|
||||
Select(N->getOperand(0).getOperand(0)),
|
||||
getI32Imm(SH), getI32Imm(MB), getI32Imm(ME));
|
||||
getI32Imm(SH & 0x1F), getI32Imm(MB), getI32Imm(ME));
|
||||
else if (isIntImmediate(N->getOperand(1), Imm))
|
||||
CurDAG->SelectNodeTo(N, PPC::RLWINM, MVT::i32, Select(N->getOperand(0)),
|
||||
getI32Imm(32-Imm), getI32Imm(Imm), getI32Imm(31));
|
||||
getI32Imm((32-Imm) & 0x1F), getI32Imm(Imm),
|
||||
getI32Imm(31));
|
||||
else
|
||||
CurDAG->SelectNodeTo(N, PPC::SRW, MVT::i32, Select(N->getOperand(0)),
|
||||
Select(N->getOperand(1)));
|
||||
|
@ -91,6 +91,13 @@ PPC32TargetLowering::PPC32TargetLowering(TargetMachine &TM)
|
||||
setOperationAction(ISD::SINT_TO_FP, MVT::i32, Expand);
|
||||
setOperationAction(ISD::UINT_TO_FP, MVT::i32, Expand);
|
||||
|
||||
// 64 bit PowerPC implementations have instructions to facilitate conversion
|
||||
// between i64 and fp.
|
||||
if (TM.getSubtarget<PPCSubtarget>().is64Bit()) {
|
||||
setOperationAction(ISD::FP_TO_SINT, MVT::i64, Custom);
|
||||
setOperationAction(ISD::SINT_TO_FP, MVT::i64, Custom);
|
||||
}
|
||||
|
||||
setSetCCResultContents(ZeroOrOneSetCCResult);
|
||||
|
||||
computeRegisterProperties();
|
||||
@ -115,17 +122,43 @@ SDOperand PPC32TargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) {
|
||||
switch (Op.getOpcode()) {
|
||||
default: assert(0 && "Wasn't expecting to be able to lower this!");
|
||||
case ISD::FP_TO_SINT: {
|
||||
assert(Op.getValueType() == MVT::i32 &&
|
||||
MVT::isFloatingPoint(Op.getOperand(0).getValueType()));
|
||||
Op = DAG.getNode(PPCISD::FCTIWZ, MVT::f64, Op.getOperand(0));
|
||||
assert(MVT::isFloatingPoint(Op.getOperand(0).getValueType()));
|
||||
switch (Op.getValueType()) {
|
||||
default: assert(0 && "Unhandled FP_TO_SINT type in custom expander!");
|
||||
case MVT::i32:
|
||||
Op = DAG.getNode(PPCISD::FCTIWZ, MVT::f64, Op.getOperand(0));
|
||||
break;
|
||||
case MVT::i64:
|
||||
Op = DAG.getNode(PPCISD::FCTIDZ, MVT::f64, Op.getOperand(0));
|
||||
break;
|
||||
}
|
||||
|
||||
int FrameIdx =
|
||||
DAG.getMachineFunction().getFrameInfo()->CreateStackObject(8, 8);
|
||||
SDOperand FI = DAG.getFrameIndex(FrameIdx, MVT::i32);
|
||||
SDOperand ST = DAG.getNode(ISD::STORE, MVT::Other, DAG.getEntryNode(),
|
||||
Op, FI, DAG.getSrcValue(0));
|
||||
FI = DAG.getNode(ISD::ADD, MVT::i32, FI, DAG.getConstant(4, MVT::i32));
|
||||
return DAG.getLoad(MVT::i32, ST, FI, DAG.getSrcValue(0));
|
||||
if (Op.getOpcode() == PPCISD::FCTIDZ) {
|
||||
Op = DAG.getLoad(MVT::i64, ST, FI, DAG.getSrcValue(0));
|
||||
} else {
|
||||
FI = DAG.getNode(ISD::ADD, MVT::i32, FI, DAG.getConstant(4, MVT::i32));
|
||||
Op = DAG.getLoad(MVT::i32, ST, FI, DAG.getSrcValue(0));
|
||||
}
|
||||
return Op;
|
||||
}
|
||||
case ISD::SINT_TO_FP: {
|
||||
assert(MVT::i64 == Op.getOperand(0).getValueType() &&
|
||||
"Unhandled SINT_TO_FP type in custom expander!");
|
||||
int FrameIdx =
|
||||
DAG.getMachineFunction().getFrameInfo()->CreateStackObject(8, 8);
|
||||
SDOperand FI = DAG.getFrameIndex(FrameIdx, MVT::i32);
|
||||
SDOperand ST = DAG.getNode(ISD::STORE, MVT::Other, DAG.getEntryNode(),
|
||||
Op.getOperand(0), FI, DAG.getSrcValue(0));
|
||||
SDOperand LD = DAG.getLoad(MVT::f64, ST, FI, DAG.getSrcValue(0));
|
||||
SDOperand FP = DAG.getNode(PPCISD::FCFID, MVT::f64, LD);
|
||||
if (MVT::f32 == Op.getValueType())
|
||||
FP = DAG.getNode(ISD::FP_ROUND, MVT::f32, FP);
|
||||
return FP;
|
||||
}
|
||||
case ISD::SELECT_CC: {
|
||||
// Turn FP only select_cc's into fsel instructions.
|
||||
|
@ -29,9 +29,15 @@ namespace llvm {
|
||||
///
|
||||
FSEL,
|
||||
|
||||
/// FCTIWZ - The FCTIWZ instruction, taking an f32 or f64 operand,
|
||||
/// producing an f64 value.
|
||||
FCTIWZ,
|
||||
/// FCFID - The FCFID instruction, taking an f64 operand and producing
|
||||
/// and f64 value containing the FP representation of the integer that
|
||||
/// was temporarily in the f64 operand.
|
||||
FCFID,
|
||||
|
||||
/// FCTI[D,W]Z - The FCTIDZ and FCTIWZ instructions, taking an f32 or f64
|
||||
/// operand, producing an f64 value containing the integer representation
|
||||
/// of that FP value.
|
||||
FCTIDZ, FCTIWZ,
|
||||
};
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user