forked from OSchip/llvm-project
Implement the following missing functionality in the PPC backend:
cast fp->bool cast ulong->fp algebraic right shift long by non-constant value These changes tested across most of the test suite. Fixes Regression/casts llvm-svn: 16081
This commit is contained in:
parent
023ff63545
commit
4483df8b63
|
@ -2324,12 +2324,43 @@ void ISel::emitShiftOperation(MachineBasicBlock *MBB,
|
||||||
BuildMI(*MBB, IP, PPC::SLW, 2, DestReg+1).addReg(SrcReg+1)
|
BuildMI(*MBB, IP, PPC::SLW, 2, DestReg+1).addReg(SrcReg+1)
|
||||||
.addReg(ShiftAmountReg);
|
.addReg(ShiftAmountReg);
|
||||||
} else {
|
} else {
|
||||||
if (isSigned) {
|
if (isSigned) { // shift right algebraic
|
||||||
// FIXME: Unimplemented
|
MachineBasicBlock *TmpMBB =new MachineBasicBlock(BB->getBasicBlock());
|
||||||
// Page C-3 of the PowerPC 32bit Programming Environments Manual
|
MachineBasicBlock *PhiMBB =new MachineBasicBlock(BB->getBasicBlock());
|
||||||
std::cerr << "ERROR: Unimplemented: signed right shift of long\n";
|
MachineBasicBlock *OldMBB = BB;
|
||||||
abort();
|
ilist<MachineBasicBlock>::iterator It = BB; ++It;
|
||||||
} else {
|
F->getBasicBlockList().insert(It, TmpMBB);
|
||||||
|
F->getBasicBlockList().insert(It, PhiMBB);
|
||||||
|
BB->addSuccessor(TmpMBB);
|
||||||
|
BB->addSuccessor(PhiMBB);
|
||||||
|
|
||||||
|
BuildMI(*MBB, IP, PPC::SUBFIC, 2, TmpReg1).addReg(ShiftAmountReg)
|
||||||
|
.addSImm(32);
|
||||||
|
BuildMI(*MBB, IP, PPC::SRW, 2, TmpReg2).addReg(SrcReg+1)
|
||||||
|
.addReg(ShiftAmountReg);
|
||||||
|
BuildMI(*MBB, IP, PPC::SLW, 2, TmpReg3).addReg(SrcReg)
|
||||||
|
.addReg(TmpReg1);
|
||||||
|
BuildMI(*MBB, IP, PPC::OR, 2, TmpReg4).addReg(TmpReg2)
|
||||||
|
.addReg(TmpReg3);
|
||||||
|
BuildMI(*MBB, IP, PPC::ADDICo, 2, TmpReg5).addReg(ShiftAmountReg)
|
||||||
|
.addSImm(-32);
|
||||||
|
BuildMI(*MBB, IP, PPC::SRAW, 2, TmpReg6).addReg(SrcReg)
|
||||||
|
.addReg(TmpReg5);
|
||||||
|
BuildMI(*MBB, IP, PPC::SRAW, 2, DestReg).addReg(SrcReg)
|
||||||
|
.addReg(ShiftAmountReg);
|
||||||
|
BuildMI(*MBB, IP, PPC::BLE, 2).addReg(PPC::CR0).addMBB(PhiMBB);
|
||||||
|
|
||||||
|
// OrMBB:
|
||||||
|
// Select correct least significant half if the shift amount > 32
|
||||||
|
BB = TmpMBB;
|
||||||
|
unsigned OrReg = makeAnotherReg(Type::IntTy);
|
||||||
|
BuildMI(BB, PPC::OR, 2, OrReg).addReg(TmpReg6).addImm(TmpReg6);
|
||||||
|
TmpMBB->addSuccessor(PhiMBB);
|
||||||
|
|
||||||
|
BB = PhiMBB;
|
||||||
|
BuildMI(BB, PPC::PHI, 4, DestReg+1).addReg(TmpReg4).addMBB(OldMBB)
|
||||||
|
.addReg(OrReg).addMBB(TmpMBB);
|
||||||
|
} else { // shift right logical
|
||||||
BuildMI(*MBB, IP, PPC::SUBFIC, 2, TmpReg1).addReg(ShiftAmountReg)
|
BuildMI(*MBB, IP, PPC::SUBFIC, 2, TmpReg1).addReg(ShiftAmountReg)
|
||||||
.addSImm(32);
|
.addSImm(32);
|
||||||
BuildMI(*MBB, IP, PPC::SRW, 2, TmpReg2).addReg(SrcReg+1)
|
BuildMI(*MBB, IP, PPC::SRW, 2, TmpReg2).addReg(SrcReg+1)
|
||||||
|
@ -2654,9 +2685,12 @@ void ISel::emitCastOperation(MachineBasicBlock *MBB,
|
||||||
}
|
}
|
||||||
case cFP32:
|
case cFP32:
|
||||||
case cFP64:
|
case cFP64:
|
||||||
// FSEL perhaps?
|
unsigned TmpReg = makeAnotherReg(Type::IntTy);
|
||||||
std::cerr << "ERROR: Cast fp-to-bool not implemented!\n";
|
unsigned ConstZero = getReg(ConstantFP::get(Type::DoubleTy, 0.0), BB, IP);
|
||||||
abort();
|
BuildMI(*MBB, IP, PPC::FCMPU, PPC::CR7).addReg(SrcReg).addReg(ConstZero);
|
||||||
|
BuildMI(*MBB, IP, PPC::MFCR, TmpReg);
|
||||||
|
BuildMI(*MBB, IP, PPC::RLWINM, DestReg).addReg(TmpReg).addImm(31)
|
||||||
|
.addImm(31).addImm(31);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -2678,13 +2712,70 @@ void ISel::emitCastOperation(MachineBasicBlock *MBB,
|
||||||
|
|
||||||
// Emit a library call for long to float conversion
|
// Emit a library call for long to float conversion
|
||||||
if (SrcClass == cLong) {
|
if (SrcClass == cLong) {
|
||||||
std::vector<ValueRecord> Args;
|
|
||||||
Args.push_back(ValueRecord(SrcReg, SrcTy));
|
|
||||||
Function *floatFn = (DestClass == cFP32) ? __floatdisfFn : __floatdidfFn;
|
Function *floatFn = (DestClass == cFP32) ? __floatdisfFn : __floatdidfFn;
|
||||||
MachineInstr *TheCall =
|
if (SrcTy->isSigned()) {
|
||||||
BuildMI(PPC::CALLpcrel, 1).addGlobalAddress(floatFn, true);
|
std::vector<ValueRecord> Args;
|
||||||
doCall(ValueRecord(DestReg, DestTy), TheCall, Args, false);
|
Args.push_back(ValueRecord(SrcReg, SrcTy));
|
||||||
TM.CalledFunctions.insert(floatFn);
|
MachineInstr *TheCall =
|
||||||
|
BuildMI(PPC::CALLpcrel, 1).addGlobalAddress(floatFn, true);
|
||||||
|
doCall(ValueRecord(DestReg, DestTy), TheCall, Args, false);
|
||||||
|
TM.CalledFunctions.insert(floatFn);
|
||||||
|
} else {
|
||||||
|
std::vector<ValueRecord> CmpArgs, ClrArgs, SetArgs;
|
||||||
|
unsigned ZeroLong = getReg(ConstantUInt::get(SrcTy, 0));
|
||||||
|
unsigned CondReg = makeAnotherReg(Type::IntTy);
|
||||||
|
|
||||||
|
// Update machine-CFG edges
|
||||||
|
MachineBasicBlock *ClrMBB = new MachineBasicBlock(BB->getBasicBlock());
|
||||||
|
MachineBasicBlock *SetMBB = new MachineBasicBlock(BB->getBasicBlock());
|
||||||
|
MachineBasicBlock *PhiMBB = new MachineBasicBlock(BB->getBasicBlock());
|
||||||
|
MachineBasicBlock *OldMBB = BB;
|
||||||
|
ilist<MachineBasicBlock>::iterator It = BB; ++It;
|
||||||
|
F->getBasicBlockList().insert(It, ClrMBB);
|
||||||
|
F->getBasicBlockList().insert(It, SetMBB);
|
||||||
|
F->getBasicBlockList().insert(It, PhiMBB);
|
||||||
|
BB->addSuccessor(ClrMBB);
|
||||||
|
BB->addSuccessor(SetMBB);
|
||||||
|
|
||||||
|
CmpArgs.push_back(ValueRecord(SrcReg, SrcTy));
|
||||||
|
CmpArgs.push_back(ValueRecord(ZeroLong, SrcTy));
|
||||||
|
MachineInstr *TheCall =
|
||||||
|
BuildMI(PPC::CALLpcrel, 1).addGlobalAddress(__cmpdi2Fn, true);
|
||||||
|
doCall(ValueRecord(CondReg, Type::IntTy), TheCall, CmpArgs, false);
|
||||||
|
TM.CalledFunctions.insert(__cmpdi2Fn);
|
||||||
|
BuildMI(*MBB, IP, PPC::CMPWI, 2, PPC::CR0).addReg(CondReg).addSImm(0);
|
||||||
|
BuildMI(*MBB, IP, PPC::BLE, 2).addReg(PPC::CR0).addMBB(SetMBB);
|
||||||
|
|
||||||
|
// ClrMBB
|
||||||
|
BB = ClrMBB;
|
||||||
|
unsigned ClrReg = makeAnotherReg(DestTy);
|
||||||
|
ClrArgs.push_back(ValueRecord(SrcReg, SrcTy));
|
||||||
|
TheCall = BuildMI(PPC::CALLpcrel, 1).addGlobalAddress(floatFn, true);
|
||||||
|
doCall(ValueRecord(ClrReg, DestTy), TheCall, ClrArgs, false);
|
||||||
|
TM.CalledFunctions.insert(floatFn);
|
||||||
|
BuildMI(BB, PPC::B, 1).addMBB(PhiMBB);
|
||||||
|
BB->addSuccessor(PhiMBB);
|
||||||
|
|
||||||
|
// SetMBB
|
||||||
|
BB = SetMBB;
|
||||||
|
unsigned SetReg = makeAnotherReg(DestTy);
|
||||||
|
unsigned CallReg = makeAnotherReg(DestTy);
|
||||||
|
unsigned ShiftedReg = makeAnotherReg(SrcTy);
|
||||||
|
ConstantSInt *Const1 = ConstantSInt::get(Type::IntTy, 1);
|
||||||
|
emitShiftOperation(BB, BB->end(), Src, Const1, false, SrcTy, ShiftedReg);
|
||||||
|
SetArgs.push_back(ValueRecord(ShiftedReg, SrcTy));
|
||||||
|
TheCall = BuildMI(PPC::CALLpcrel, 1).addGlobalAddress(floatFn, true);
|
||||||
|
doCall(ValueRecord(CallReg, DestTy), TheCall, SetArgs, false);
|
||||||
|
TM.CalledFunctions.insert(floatFn);
|
||||||
|
unsigned SetOpcode = (DestClass == cFP32) ? PPC::FADDS : PPC::FADD;
|
||||||
|
BuildMI(BB, SetOpcode, 2, SetReg).addReg(CallReg).addReg(CallReg);
|
||||||
|
BB->addSuccessor(PhiMBB);
|
||||||
|
|
||||||
|
// PhiMBB
|
||||||
|
BB = PhiMBB;
|
||||||
|
BuildMI(BB, PPC::PHI, 4, DestReg).addReg(ClrReg).addMBB(ClrMBB)
|
||||||
|
.addReg(SetReg).addMBB(SetMBB);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2706,25 +2797,25 @@ void ISel::emitCastOperation(MachineBasicBlock *MBB,
|
||||||
if (!SrcTy->isSigned()) {
|
if (!SrcTy->isSigned()) {
|
||||||
ConstantFP *CFP = ConstantFP::get(Type::DoubleTy, 0x1.000000p52);
|
ConstantFP *CFP = ConstantFP::get(Type::DoubleTy, 0x1.000000p52);
|
||||||
unsigned ConstF = getReg(CFP, BB, IP);
|
unsigned ConstF = getReg(CFP, BB, IP);
|
||||||
BuildMI(*BB, IP, PPC::LIS, 1, constantHi).addSImm(0x4330);
|
BuildMI(*MBB, IP, PPC::LIS, 1, constantHi).addSImm(0x4330);
|
||||||
addFrameReference(BuildMI(*BB, IP, PPC::STW, 3).addReg(constantHi),
|
addFrameReference(BuildMI(*MBB, IP, PPC::STW, 3).addReg(constantHi),
|
||||||
ValueFrameIdx);
|
ValueFrameIdx);
|
||||||
addFrameReference(BuildMI(*BB, IP, PPC::STW, 3).addReg(SrcReg),
|
addFrameReference(BuildMI(*MBB, IP, PPC::STW, 3).addReg(SrcReg),
|
||||||
ValueFrameIdx, 4);
|
ValueFrameIdx, 4);
|
||||||
addFrameReference(BuildMI(*BB, IP, PPC::LFD, 2, TempF), ValueFrameIdx);
|
addFrameReference(BuildMI(*MBB, IP, PPC::LFD, 2, TempF), ValueFrameIdx);
|
||||||
BuildMI(*BB, IP, PPC::FSUB, 2, DestReg).addReg(TempF).addReg(ConstF);
|
BuildMI(*MBB, IP, PPC::FSUB, 2, DestReg).addReg(TempF).addReg(ConstF);
|
||||||
} else {
|
} else {
|
||||||
ConstantFP *CFP = ConstantFP::get(Type::DoubleTy, 0x1.000008p52);
|
ConstantFP *CFP = ConstantFP::get(Type::DoubleTy, 0x1.000008p52);
|
||||||
unsigned ConstF = getReg(CFP, BB, IP);
|
unsigned ConstF = getReg(CFP, BB, IP);
|
||||||
unsigned TempLo = makeAnotherReg(Type::IntTy);
|
unsigned TempLo = makeAnotherReg(Type::IntTy);
|
||||||
BuildMI(*BB, IP, PPC::LIS, 1, constantHi).addSImm(0x4330);
|
BuildMI(*MBB, IP, PPC::LIS, 1, constantHi).addSImm(0x4330);
|
||||||
addFrameReference(BuildMI(*BB, IP, PPC::STW, 3).addReg(constantHi),
|
addFrameReference(BuildMI(*MBB, IP, PPC::STW, 3).addReg(constantHi),
|
||||||
ValueFrameIdx);
|
ValueFrameIdx);
|
||||||
BuildMI(*BB, IP, PPC::XORIS, 2, TempLo).addReg(SrcReg).addImm(0x8000);
|
BuildMI(*MBB, IP, PPC::XORIS, 2, TempLo).addReg(SrcReg).addImm(0x8000);
|
||||||
addFrameReference(BuildMI(*BB, IP, PPC::STW, 3).addReg(TempLo),
|
addFrameReference(BuildMI(*MBB, IP, PPC::STW, 3).addReg(TempLo),
|
||||||
ValueFrameIdx, 4);
|
ValueFrameIdx, 4);
|
||||||
addFrameReference(BuildMI(*BB, IP, PPC::LFD, 2, TempF), ValueFrameIdx);
|
addFrameReference(BuildMI(*MBB, IP, PPC::LFD, 2, TempF), ValueFrameIdx);
|
||||||
BuildMI(*BB, IP, PPC::FSUB, 2, DestReg).addReg(TempF).addReg(ConstF);
|
BuildMI(*MBB, IP, PPC::FSUB, 2, DestReg).addReg(TempF).addReg(ConstF);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -2754,8 +2845,8 @@ void ISel::emitCastOperation(MachineBasicBlock *MBB,
|
||||||
unsigned TempReg = makeAnotherReg(Type::DoubleTy);
|
unsigned TempReg = makeAnotherReg(Type::DoubleTy);
|
||||||
|
|
||||||
// Convert to integer in the FP reg and store it to a stack slot
|
// Convert to integer in the FP reg and store it to a stack slot
|
||||||
BuildMI(*BB, IP, PPC::FCTIWZ, 1, TempReg).addReg(SrcReg);
|
BuildMI(*MBB, IP, PPC::FCTIWZ, 1, TempReg).addReg(SrcReg);
|
||||||
addFrameReference(BuildMI(*BB, IP, PPC::STFD, 3)
|
addFrameReference(BuildMI(*MBB, IP, PPC::STFD, 3)
|
||||||
.addReg(TempReg), ValueFrameIdx);
|
.addReg(TempReg), ValueFrameIdx);
|
||||||
|
|
||||||
// There is no load signed byte opcode, so we must emit a sign extend for
|
// There is no load signed byte opcode, so we must emit a sign extend for
|
||||||
|
@ -2763,13 +2854,13 @@ void ISel::emitCastOperation(MachineBasicBlock *MBB,
|
||||||
// correct offset.
|
// correct offset.
|
||||||
if (DestClass == cByte) {
|
if (DestClass == cByte) {
|
||||||
unsigned TempReg2 = makeAnotherReg(DestTy);
|
unsigned TempReg2 = makeAnotherReg(DestTy);
|
||||||
addFrameReference(BuildMI(*BB, IP, PPC::LBZ, 2, TempReg2),
|
addFrameReference(BuildMI(*MBB, IP, PPC::LBZ, 2, TempReg2),
|
||||||
ValueFrameIdx, 7);
|
ValueFrameIdx, 7);
|
||||||
BuildMI(*BB, IP, PPC::EXTSB, 1, DestReg).addReg(TempReg2);
|
BuildMI(*MBB, IP, PPC::EXTSB, 1, DestReg).addReg(TempReg2);
|
||||||
} else {
|
} else {
|
||||||
int offset = (DestClass == cShort) ? 6 : 4;
|
int offset = (DestClass == cShort) ? 6 : 4;
|
||||||
unsigned LoadOp = (DestClass == cShort) ? PPC::LHA : PPC::LWZ;
|
unsigned LoadOp = (DestClass == cShort) ? PPC::LHA : PPC::LWZ;
|
||||||
addFrameReference(BuildMI(*BB, IP, LoadOp, 2, DestReg),
|
addFrameReference(BuildMI(*MBB, IP, LoadOp, 2, DestReg),
|
||||||
ValueFrameIdx, offset);
|
ValueFrameIdx, offset);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -2800,34 +2891,34 @@ void ISel::emitCastOperation(MachineBasicBlock *MBB,
|
||||||
|
|
||||||
// Convert from floating point to unsigned 32-bit value
|
// Convert from floating point to unsigned 32-bit value
|
||||||
// Use 0 if incoming value is < 0.0
|
// Use 0 if incoming value is < 0.0
|
||||||
BuildMI(*BB, IP, PPC::FSEL, 3, UseZero).addReg(SrcReg).addReg(SrcReg)
|
BuildMI(*MBB, IP, PPC::FSEL, 3, UseZero).addReg(SrcReg).addReg(SrcReg)
|
||||||
.addReg(Zero);
|
.addReg(Zero);
|
||||||
// Use 2**32 - 1 if incoming value is >= 2**32
|
// Use 2**32 - 1 if incoming value is >= 2**32
|
||||||
BuildMI(*BB, IP, PPC::FSUB, 2, UseMaxInt).addReg(MaxInt).addReg(SrcReg);
|
BuildMI(*MBB, IP, PPC::FSUB, 2, UseMaxInt).addReg(MaxInt).addReg(SrcReg);
|
||||||
BuildMI(*BB, IP, PPC::FSEL, 3, UseChoice).addReg(UseMaxInt)
|
BuildMI(*MBB, IP, PPC::FSEL, 3, UseChoice).addReg(UseMaxInt)
|
||||||
.addReg(UseZero).addReg(MaxInt);
|
.addReg(UseZero).addReg(MaxInt);
|
||||||
// Subtract 2**31
|
// Subtract 2**31
|
||||||
BuildMI(*BB, IP, PPC::FSUB, 2, TmpReg).addReg(UseChoice).addReg(Border);
|
BuildMI(*MBB, IP, PPC::FSUB, 2, TmpReg).addReg(UseChoice).addReg(Border);
|
||||||
// Use difference if >= 2**31
|
// Use difference if >= 2**31
|
||||||
BuildMI(*BB, IP, PPC::FCMPU, 2, PPC::CR0).addReg(UseChoice)
|
BuildMI(*MBB, IP, PPC::FCMPU, 2, PPC::CR0).addReg(UseChoice)
|
||||||
.addReg(Border);
|
.addReg(Border);
|
||||||
BuildMI(*BB, IP, PPC::FSEL, 3, TmpReg2).addReg(TmpReg).addReg(TmpReg)
|
BuildMI(*MBB, IP, PPC::FSEL, 3, TmpReg2).addReg(TmpReg).addReg(TmpReg)
|
||||||
.addReg(UseChoice);
|
.addReg(UseChoice);
|
||||||
// Convert to integer
|
// Convert to integer
|
||||||
BuildMI(*BB, IP, PPC::FCTIWZ, 1, ConvReg).addReg(TmpReg2);
|
BuildMI(*MBB, IP, PPC::FCTIWZ, 1, ConvReg).addReg(TmpReg2);
|
||||||
addFrameReference(BuildMI(*BB, IP, PPC::STFD, 3).addReg(ConvReg),
|
addFrameReference(BuildMI(*MBB, IP, PPC::STFD, 3).addReg(ConvReg),
|
||||||
FrameIdx);
|
FrameIdx);
|
||||||
if (DestClass == cByte) {
|
if (DestClass == cByte) {
|
||||||
addFrameReference(BuildMI(*BB, IP, PPC::LBZ, 2, DestReg),
|
addFrameReference(BuildMI(*MBB, IP, PPC::LBZ, 2, DestReg),
|
||||||
FrameIdx, 7);
|
FrameIdx, 7);
|
||||||
} else if (DestClass == cShort) {
|
} else if (DestClass == cShort) {
|
||||||
addFrameReference(BuildMI(*BB, IP, PPC::LHZ, 2, DestReg),
|
addFrameReference(BuildMI(*MBB, IP, PPC::LHZ, 2, DestReg),
|
||||||
FrameIdx, 6);
|
FrameIdx, 6);
|
||||||
} if (DestClass == cInt) {
|
} if (DestClass == cInt) {
|
||||||
addFrameReference(BuildMI(*BB, IP, PPC::LWZ, 2, IntTmp),
|
addFrameReference(BuildMI(*MBB, IP, PPC::LWZ, 2, IntTmp),
|
||||||
FrameIdx, 4);
|
FrameIdx, 4);
|
||||||
BuildMI(*BB, IP, PPC::BLT, 2).addReg(PPC::CR0).addMBB(PhiMBB);
|
BuildMI(*MBB, IP, PPC::BLT, 2).addReg(PPC::CR0).addMBB(PhiMBB);
|
||||||
BuildMI(*BB, IP, PPC::B, 1).addMBB(XorMBB);
|
BuildMI(*MBB, IP, PPC::B, 1).addMBB(XorMBB);
|
||||||
|
|
||||||
// XorMBB:
|
// XorMBB:
|
||||||
// add 2**31 if input was >= 2**31
|
// add 2**31 if input was >= 2**31
|
||||||
|
|
|
@ -47,6 +47,7 @@ def SUBI : DForm_2<"subi", 14, 0, 0>;
|
||||||
def LI : DForm_2_r0<"li", 14, 0, 0>;
|
def LI : DForm_2_r0<"li", 14, 0, 0>;
|
||||||
def LIS : DForm_2_r0<"lis", 15, 0, 0>;
|
def LIS : DForm_2_r0<"lis", 15, 0, 0>;
|
||||||
def ADDIC : DForm_2<"addic", 12, 0, 0>;
|
def ADDIC : DForm_2<"addic", 12, 0, 0>;
|
||||||
|
def ADDICo : DForm_2<"addic.", 13, 0, 0>;
|
||||||
def ADD : XOForm_1<"add", 31, 266, 0, 0, 0, 0>;
|
def ADD : XOForm_1<"add", 31, 266, 0, 0, 0, 0>;
|
||||||
def ADDC : XOForm_1<"addc", 31, 10, 0, 0, 0, 0>;
|
def ADDC : XOForm_1<"addc", 31, 10, 0, 0, 0, 0>;
|
||||||
def ADDE : XOForm_1<"adde", 31, 138, 0, 0, 0, 0>;
|
def ADDE : XOForm_1<"adde", 31, 138, 0, 0, 0, 0>;
|
||||||
|
|
|
@ -1,28 +1,10 @@
|
||||||
TODO:
|
TODO:
|
||||||
|
* switch to auto-generated asm writer
|
||||||
* use stfiwx in float->int
|
* use stfiwx in float->int
|
||||||
* implement cast fp to bool
|
|
||||||
* implement algebraic shift right long by reg
|
|
||||||
* 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
|
* fix rlwimi generation to be use-and-def
|
||||||
* fix ulong to double:
|
|
||||||
floatdidf assumes signed longs. so if the high but of a ulong
|
|
||||||
just happens to be set, you get the wrong sign. The fix for this
|
|
||||||
is to call cmpdi2 to compare against zero, if so shift right by one,
|
|
||||||
convert to fp, and multiply by (add to itself). the sequence would
|
|
||||||
look like:
|
|
||||||
{r3:r4} holds ulong a;
|
|
||||||
li r5, 0
|
|
||||||
li r6, 0 (set r5:r6 to ulong 0)
|
|
||||||
call cmpdi2 ==> sets r3 <, =, > 0
|
|
||||||
if r3 > 0
|
|
||||||
call floatdidf as usual
|
|
||||||
else
|
|
||||||
shift right ulong a, 1 (we could use emitShift)
|
|
||||||
call floatdidf
|
|
||||||
fadd f1, f1, f1 (fp left shift by 1)
|
|
||||||
* cast elimination pass (uint -> sbyte -> short, kill the byte -> short)
|
|
||||||
* 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
|
||||||
|
@ -30,9 +12,6 @@ TODO:
|
||||||
b .LBBl42__2E_expand_function_8_42 ; NewDefault
|
b .LBBl42__2E_expand_function_8_42 ; NewDefault
|
||||||
|
|
||||||
Currently failing tests that should pass:
|
Currently failing tests that should pass:
|
||||||
* SingleSource
|
|
||||||
`- Regression
|
|
||||||
| `- casts (ulong to fp failure)
|
|
||||||
* MultiSource
|
* MultiSource
|
||||||
|- Applications
|
|- Applications
|
||||||
| `- hbd: miscompilation
|
| `- hbd: miscompilation
|
||||||
|
|
Loading…
Reference in New Issue