Improvements to int->float cast code for PPC-64
llvm-svn: 16105
This commit is contained in:
parent
50d140ee3d
commit
8cb6bd5f3c
|
@ -2315,68 +2315,60 @@ void ISel::emitCastOperation(MachineBasicBlock *MBB,
|
||||||
// Handle casts from integer to floating point now...
|
// Handle casts from integer to floating point now...
|
||||||
if (DestClass == cFP32 || DestClass == cFP64) {
|
if (DestClass == cFP32 || DestClass == cFP64) {
|
||||||
|
|
||||||
// Emit a library call for long to float conversion
|
|
||||||
if (SrcClass == cLong) {
|
|
||||||
std::vector<ValueRecord> Args;
|
|
||||||
Args.push_back(ValueRecord(SrcReg, SrcTy));
|
|
||||||
Function *floatFn = (DestClass == cFP32) ? __floatdisfFn : __floatdidfFn;
|
|
||||||
MachineInstr *TheCall =
|
|
||||||
BuildMI(PPC::CALLpcrel, 1).addGlobalAddress(floatFn, true);
|
|
||||||
doCall(ValueRecord(DestReg, DestTy), TheCall, Args, false);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Make sure we're dealing with a full 32 bits
|
|
||||||
unsigned TmpReg = makeAnotherReg(Type::IntTy);
|
|
||||||
promote32(TmpReg, ValueRecord(SrcReg, SrcTy));
|
|
||||||
|
|
||||||
SrcReg = TmpReg;
|
|
||||||
|
|
||||||
// Spill the integer to memory and reload it from there.
|
// Spill the integer to memory and reload it from there.
|
||||||
// Also spill room for a special conversion constant
|
unsigned TmpReg = makeAnotherReg(Type::DoubleTy);
|
||||||
int ConstantFrameIndex =
|
|
||||||
F->getFrameInfo()->CreateStackObject(Type::DoubleTy, TM.getTargetData());
|
|
||||||
int ValueFrameIdx =
|
int ValueFrameIdx =
|
||||||
F->getFrameInfo()->CreateStackObject(Type::DoubleTy, TM.getTargetData());
|
F->getFrameInfo()->CreateStackObject(Type::DoubleTy, TM.getTargetData());
|
||||||
|
|
||||||
unsigned constantHi = makeAnotherReg(Type::IntTy);
|
if (SrcClass == cLong) {
|
||||||
unsigned constantLo = makeAnotherReg(Type::IntTy);
|
if (SrcTy->isSigned()) {
|
||||||
unsigned ConstF = makeAnotherReg(Type::DoubleTy);
|
addFrameReference(BuildMI(*MBB, IP, PPC::STD, 3).addReg(SrcReg),
|
||||||
unsigned TempF = makeAnotherReg(Type::DoubleTy);
|
ValueFrameIdx);
|
||||||
|
addFrameReference(BuildMI(*MBB, IP, PPC::LFD, 2, TmpReg),
|
||||||
if (!SrcTy->isSigned()) {
|
ValueFrameIdx);
|
||||||
BuildMI(*BB, IP, PPC::LIS, 1, constantHi).addSImm(0x4330);
|
BuildMI(*MBB, IP, PPC::FCFID, 1, DestReg).addReg(TmpReg);
|
||||||
BuildMI(*BB, IP, PPC::LI, 1, constantLo).addSImm(0);
|
} else {
|
||||||
addFrameReference(BuildMI(*BB, IP, PPC::STW, 3).addReg(constantHi),
|
unsigned Scale = getReg(ConstantFP::get(Type::DoubleTy, 0x1p32));
|
||||||
ConstantFrameIndex);
|
unsigned TmpHi = makeAnotherReg(Type::IntTy);
|
||||||
addFrameReference(BuildMI(*BB, IP, PPC::STW, 3).addReg(constantLo),
|
unsigned TmpLo = makeAnotherReg(Type::IntTy);
|
||||||
ConstantFrameIndex, 4);
|
unsigned FPLow = makeAnotherReg(Type::DoubleTy);
|
||||||
addFrameReference(BuildMI(*BB, IP, PPC::STW, 3).addReg(constantHi),
|
unsigned FPTmpHi = makeAnotherReg(Type::DoubleTy);
|
||||||
ValueFrameIdx);
|
unsigned FPTmpLo = makeAnotherReg(Type::DoubleTy);
|
||||||
addFrameReference(BuildMI(*BB, IP, PPC::STW, 3).addReg(SrcReg),
|
int OtherFrameIdx = F->getFrameInfo()->CreateStackObject(Type::DoubleTy,
|
||||||
ValueFrameIdx, 4);
|
TM.getTargetData());
|
||||||
addFrameReference(BuildMI(*BB, IP, PPC::LFD, 2, ConstF),
|
BuildMI(*MBB, IP, PPC::RLDICL, 3, TmpHi).addReg(SrcReg).addImm(32)
|
||||||
ConstantFrameIndex);
|
.addImm(32);
|
||||||
addFrameReference(BuildMI(*BB, IP, PPC::LFD, 2, TempF), ValueFrameIdx);
|
BuildMI(*MBB, IP, PPC::RLDICL, 3, TmpLo).addReg(SrcReg).addImm(0)
|
||||||
BuildMI(*BB, IP, PPC::FSUB, 2, DestReg).addReg(TempF).addReg(ConstF);
|
.addImm(32);
|
||||||
} else {
|
addFrameReference(BuildMI(*MBB, IP, PPC::STD, 3).addReg(TmpHi),
|
||||||
unsigned TempLo = makeAnotherReg(Type::IntTy);
|
ValueFrameIdx);
|
||||||
BuildMI(*BB, IP, PPC::LIS, 1, constantHi).addSImm(0x4330);
|
addFrameReference(BuildMI(*MBB, IP, PPC::STD, 3).addReg(TmpLo),
|
||||||
BuildMI(*BB, IP, PPC::LIS, 1, constantLo).addSImm(0x8000);
|
OtherFrameIdx);
|
||||||
addFrameReference(BuildMI(*BB, IP, PPC::STW, 3).addReg(constantHi),
|
addFrameReference(BuildMI(*MBB, IP, PPC::LFD, 2, TmpReg),
|
||||||
ConstantFrameIndex);
|
ValueFrameIdx);
|
||||||
addFrameReference(BuildMI(*BB, IP, PPC::STW, 3).addReg(constantLo),
|
addFrameReference(BuildMI(*MBB, IP, PPC::LFD, 2, FPLow),
|
||||||
ConstantFrameIndex, 4);
|
OtherFrameIdx);
|
||||||
addFrameReference(BuildMI(*BB, IP, PPC::STW, 3).addReg(constantHi),
|
BuildMI(*MBB, IP, PPC::FCFID, 1, FPTmpHi).addReg(TmpReg);
|
||||||
ValueFrameIdx);
|
BuildMI(*MBB, IP, PPC::FCFID, 1, FPTmpLo).addReg(FPLow);
|
||||||
BuildMI(*BB, IP, PPC::XORIS, 2, TempLo).addReg(SrcReg).addImm(0x8000);
|
BuildMI(*MBB, IP, PPC::FMADD, 3, DestReg).addReg(Scale).addReg(FPTmpHi)
|
||||||
addFrameReference(BuildMI(*BB, IP, PPC::STW, 3).addReg(TempLo),
|
.addReg(FPTmpLo);
|
||||||
ValueFrameIdx, 4);
|
}
|
||||||
addFrameReference(BuildMI(*BB, IP, PPC::LFD, 2, ConstF),
|
return;
|
||||||
ConstantFrameIndex);
|
|
||||||
addFrameReference(BuildMI(*BB, IP, PPC::LFD, 2, TempF), ValueFrameIdx);
|
|
||||||
BuildMI(*BB, IP, PPC::FSUB, 2, DestReg).addReg(TempF).addReg(ConstF);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FIXME: really want a promote64
|
||||||
|
unsigned IntTmp = makeAnotherReg(Type::IntTy);
|
||||||
|
|
||||||
|
if (SrcTy->isSigned())
|
||||||
|
BuildMI(*MBB, IP, PPC::EXTSW, 1, IntTmp).addReg(SrcReg);
|
||||||
|
else
|
||||||
|
BuildMI(*MBB, IP, PPC::RLDICL, 3, IntTmp).addReg(SrcReg).addImm(0)
|
||||||
|
.addImm(32);
|
||||||
|
addFrameReference(BuildMI(*MBB, IP, PPC::STD, 3).addReg(IntTmp),
|
||||||
|
ValueFrameIdx);
|
||||||
|
addFrameReference(BuildMI(*MBB, IP, PPC::LFD, 2, TmpReg),
|
||||||
|
ValueFrameIdx);
|
||||||
|
BuildMI(*MBB, IP, PPC::FCFID, 1, DestReg).addReg(TmpReg);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -104,6 +104,7 @@ def FADD : AForm_2<"fadd", 63, 21, 0, 0, 0>;
|
||||||
def FADDS : AForm_2<"fadds", 59, 21, 0, 0, 0>;
|
def FADDS : AForm_2<"fadds", 59, 21, 0, 0, 0>;
|
||||||
def FSUB : AForm_2<"fsub", 63, 20, 0, 0, 0>;
|
def FSUB : AForm_2<"fsub", 63, 20, 0, 0, 0>;
|
||||||
def FSUBS : AForm_2<"fsubs", 59, 20, 0, 0, 0>;
|
def FSUBS : AForm_2<"fsubs", 59, 20, 0, 0, 0>;
|
||||||
|
def FMADD : AForm_2<"fmul", 63, 29, 0, 0, 0>;
|
||||||
def FMUL : AForm_3<"fmul", 63, 25, 0, 0, 0>;
|
def FMUL : AForm_3<"fmul", 63, 25, 0, 0, 0>;
|
||||||
def FMULS : AForm_3<"fmuls", 59, 25, 0, 0, 0>;
|
def FMULS : AForm_3<"fmuls", 59, 25, 0, 0, 0>;
|
||||||
def FDIV : AForm_2<"fdiv", 63, 18, 0, 0, 0>;
|
def FDIV : AForm_2<"fdiv", 63, 18, 0, 0, 0>;
|
||||||
|
@ -232,18 +233,24 @@ def EXTSB : XForm_11<31, 954, 0, 0, 0, (ops GPRC:$rA, GPRC:$rS),
|
||||||
"extsb $rA, $rS">;
|
"extsb $rA, $rS">;
|
||||||
def EXTSH : XForm_11<31, 922, 0, 0, 0, (ops GPRC:$rA, GPRC:$rS),
|
def EXTSH : XForm_11<31, 922, 0, 0, 0, (ops GPRC:$rA, GPRC:$rS),
|
||||||
"extsh $rA, $rS">;
|
"extsh $rA, $rS">;
|
||||||
|
def EXTSW : XForm_11<31, 986, 0, 1, 0, (ops GPRC:$rA, GPRC:$rS),
|
||||||
|
"extsw $rA, $rS">;
|
||||||
def LFSX : XForm_25<31, 535, 0, 0, (ops FPRC:$dst, GPRC:$base, GPRC:$index),
|
def LFSX : XForm_25<31, 535, 0, 0, (ops FPRC:$dst, GPRC:$base, GPRC:$index),
|
||||||
"lfsx $dst, $base, $index">;
|
"lfsx $dst, $base, $index">;
|
||||||
def LFDX : XForm_25<31, 599, 0, 0, (ops FPRC:$dst, GPRC:$base, GPRC:$index),
|
def LFDX : XForm_25<31, 599, 0, 0, (ops FPRC:$dst, GPRC:$base, GPRC:$index),
|
||||||
"lfdx $dst, $base, $index">;
|
"lfdx $dst, $base, $index">;
|
||||||
|
def FCFID : XForm_26<63, 846, 0, 1, 0, (ops FPRC:$frD, FPRC:$frB),
|
||||||
|
"fcfid $frD, $frB">;
|
||||||
|
def FCTIDZ : XForm_26<63, 815, 0, 1, 0, (ops FPRC:$frD, FPRC:$frB),
|
||||||
|
"fctidz $frD, $frB">;
|
||||||
|
def FCTIWZ : XForm_26<63, 15, 0, 0, 0, (ops FPRC:$frD, FPRC:$frB),
|
||||||
|
"fctiwz $frD, $frB">;
|
||||||
def FMR : XForm_26<63, 72, 0, 0, 0, (ops FPRC:$frD, FPRC:$frB),
|
def FMR : XForm_26<63, 72, 0, 0, 0, (ops FPRC:$frD, FPRC:$frB),
|
||||||
"fmr $frD, $frB">;
|
"fmr $frD, $frB">;
|
||||||
def FNEG : XForm_26<63, 80, 0, 0, 0, (ops FPRC:$frD, FPRC:$frB),
|
def FNEG : XForm_26<63, 80, 0, 0, 0, (ops FPRC:$frD, FPRC:$frB),
|
||||||
"fneg $frD, $frB">;
|
"fneg $frD, $frB">;
|
||||||
def FRSP : XForm_26<63, 12, 0, 0, 0, (ops FPRC:$frD, FPRC:$frB),
|
def FRSP : XForm_26<63, 12, 0, 0, 0, (ops FPRC:$frD, FPRC:$frB),
|
||||||
"frsp $frD, $frB">;
|
"frsp $frD, $frB">;
|
||||||
def FCTIWZ : XForm_26<63, 15, 0, 0, 0, (ops FPRC:$frD, FPRC:$frB),
|
|
||||||
"fctiwz $frD, $frB">;
|
|
||||||
def STFSX : XForm_28<31, 663, 0, 0, (ops FPRC:$frS, GPRC:$rA, GPRC:$rB),
|
def STFSX : XForm_28<31, 663, 0, 0, (ops FPRC:$frS, GPRC:$rA, GPRC:$rB),
|
||||||
"stfsx $frS, $rA, $rB">;
|
"stfsx $frS, $rA, $rB">;
|
||||||
def STFDX : XForm_28<31, 727, 0, 0, (ops FPRC:$frS, GPRC:$rA, GPRC:$rB),
|
def STFDX : XForm_28<31, 727, 0, 0, (ops FPRC:$frS, GPRC:$rA, GPRC:$rB),
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
TODO:
|
TODO:
|
||||||
* switch to auto-generated asm writer
|
* switch to auto-generated asm writer
|
||||||
* use stfiwx in float->int
|
* fix rlwimi generation to be use-and-def
|
||||||
* implement scheduling info
|
* implement scheduling info
|
||||||
* implement powerpc-64 for darwin
|
* implement powerpc-64 for darwin
|
||||||
* implement powerpc-64 for aix
|
* implement powerpc-64 for aix
|
||||||
* fix rlwimi generation to be use-and-def
|
* use stfiwx in float->int
|
||||||
* should hint to the branch select pass that it doesn't need to print the
|
* should hint to the branch select pass that it doesn't need to print the
|
||||||
second unconditional branch, so we don't end up with things like:
|
second unconditional branch, so we don't end up with things like:
|
||||||
b .LBBl42__2E_expand_function_8_674 ; loopentry.24
|
b .LBBl42__2E_expand_function_8_674 ; loopentry.24
|
||||||
|
|
Loading…
Reference in New Issue