mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-03-01 01:30:36 +00:00
Implement casting a floating point to 32-bit unsigned value
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@15143 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
204fa53528
commit
b160d1f9f7
@ -2672,8 +2672,67 @@ void ISel::emitCastOperation(MachineBasicBlock *MBB,
|
|||||||
ValueFrameIdx, 4);
|
ValueFrameIdx, 4);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
std::cerr << "ERROR: Cast fp-to-unsigned not implemented!\n";
|
unsigned Zero = getReg(ConstantFP::get(Type::DoubleTy, 0.0f));
|
||||||
abort();
|
double maxInt = (1LL << 32) - 1;
|
||||||
|
unsigned MaxInt = getReg(ConstantFP::get(Type::DoubleTy, maxInt));
|
||||||
|
double border = 1LL << 31;
|
||||||
|
unsigned Border = getReg(ConstantFP::get(Type::DoubleTy, border));
|
||||||
|
unsigned UseZero = makeAnotherReg(Type::DoubleTy);
|
||||||
|
unsigned UseMaxInt = makeAnotherReg(Type::DoubleTy);
|
||||||
|
unsigned UseChoice = makeAnotherReg(Type::DoubleTy);
|
||||||
|
unsigned TmpReg = makeAnotherReg(Type::DoubleTy);
|
||||||
|
unsigned TmpReg2 = makeAnotherReg(Type::DoubleTy);
|
||||||
|
unsigned ConvReg = makeAnotherReg(Type::DoubleTy);
|
||||||
|
unsigned IntTmp = makeAnotherReg(Type::IntTy);
|
||||||
|
unsigned XorReg = makeAnotherReg(Type::IntTy);
|
||||||
|
int FrameIdx =
|
||||||
|
F->getFrameInfo()->CreateStackObject(SrcTy, TM.getTargetData());
|
||||||
|
// Update machine-CFG edges
|
||||||
|
MachineBasicBlock *XorMBB = new MachineBasicBlock(BB->getBasicBlock());
|
||||||
|
MachineBasicBlock *PhiMBB = new MachineBasicBlock(BB->getBasicBlock());
|
||||||
|
MachineBasicBlock *OldMBB = BB;
|
||||||
|
ilist<MachineBasicBlock>::iterator It = BB; ++It;
|
||||||
|
F->getBasicBlockList().insert(It, XorMBB);
|
||||||
|
F->getBasicBlockList().insert(It, PhiMBB);
|
||||||
|
BB->addSuccessor(XorMBB);
|
||||||
|
BB->addSuccessor(PhiMBB);
|
||||||
|
|
||||||
|
// Convert from floating point to unsigned 32-bit value
|
||||||
|
// Use 0 if incoming value is < 0.0
|
||||||
|
BuildMI(*BB, IP, PPC32::FSEL, 3, UseZero).addReg(SrcReg).addReg(SrcReg)
|
||||||
|
.addReg(Zero);
|
||||||
|
// Use 2**32 - 1 if incoming value is >= 2**32
|
||||||
|
BuildMI(*BB, IP, PPC32::FSUB, 2, UseMaxInt).addReg(MaxInt).addReg(SrcReg);
|
||||||
|
BuildMI(*BB, IP, PPC32::FSEL, 3, UseChoice).addReg(UseMaxInt)
|
||||||
|
.addReg(UseZero).addReg(MaxInt);
|
||||||
|
// Subtract 2**31
|
||||||
|
BuildMI(*BB, IP, PPC32::FSUB, 2, TmpReg).addReg(UseChoice).addReg(Border);
|
||||||
|
// Use difference if >= 2**31
|
||||||
|
BuildMI(*BB, IP, PPC32::FCMPU, 2, PPC32::CR0).addReg(UseChoice)
|
||||||
|
.addReg(Border);
|
||||||
|
BuildMI(*BB, IP, PPC32::FSEL, 3, TmpReg2).addReg(TmpReg).addReg(TmpReg)
|
||||||
|
.addReg(UseChoice);
|
||||||
|
// Convert to integer
|
||||||
|
BuildMI(*BB, IP, PPC32::FCTIWZ, 1, ConvReg).addReg(TmpReg2);
|
||||||
|
addFrameReference(BuildMI(*BB, IP, PPC32::STFD, 3).addReg(ConvReg),
|
||||||
|
FrameIdx);
|
||||||
|
addFrameReference(BuildMI(*BB, IP, PPC32::LWZ, 2, IntTmp),
|
||||||
|
FrameIdx, 4);
|
||||||
|
BuildMI(*BB, IP, PPC32::BLT, 2).addReg(PPC32::CR0).addMBB(PhiMBB);
|
||||||
|
BuildMI(*BB, IP, PPC32::B, 1).addMBB(XorMBB);
|
||||||
|
|
||||||
|
// XorMBB:
|
||||||
|
// add 2**31 if input was >= 2**31
|
||||||
|
BB = XorMBB;
|
||||||
|
BuildMI(BB, PPC32::XORIS, 2, XorReg).addReg(IntTmp).addImm(0x8000);
|
||||||
|
BuildMI(BB, PPC32::B, 1).addMBB(PhiMBB);
|
||||||
|
XorMBB->addSuccessor(PhiMBB);
|
||||||
|
|
||||||
|
// PhiMBB:
|
||||||
|
// DestReg = phi [ IntTmp, OldMBB ], [ XorReg, XorMBB ]
|
||||||
|
BB = PhiMBB;
|
||||||
|
BuildMI(BB, PPC32::PHI, 2, DestReg).addReg(IntTmp).addMBB(OldMBB)
|
||||||
|
.addReg(XorReg).addMBB(XorMBB);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -2672,8 +2672,67 @@ void ISel::emitCastOperation(MachineBasicBlock *MBB,
|
|||||||
ValueFrameIdx, 4);
|
ValueFrameIdx, 4);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
std::cerr << "ERROR: Cast fp-to-unsigned not implemented!\n";
|
unsigned Zero = getReg(ConstantFP::get(Type::DoubleTy, 0.0f));
|
||||||
abort();
|
double maxInt = (1LL << 32) - 1;
|
||||||
|
unsigned MaxInt = getReg(ConstantFP::get(Type::DoubleTy, maxInt));
|
||||||
|
double border = 1LL << 31;
|
||||||
|
unsigned Border = getReg(ConstantFP::get(Type::DoubleTy, border));
|
||||||
|
unsigned UseZero = makeAnotherReg(Type::DoubleTy);
|
||||||
|
unsigned UseMaxInt = makeAnotherReg(Type::DoubleTy);
|
||||||
|
unsigned UseChoice = makeAnotherReg(Type::DoubleTy);
|
||||||
|
unsigned TmpReg = makeAnotherReg(Type::DoubleTy);
|
||||||
|
unsigned TmpReg2 = makeAnotherReg(Type::DoubleTy);
|
||||||
|
unsigned ConvReg = makeAnotherReg(Type::DoubleTy);
|
||||||
|
unsigned IntTmp = makeAnotherReg(Type::IntTy);
|
||||||
|
unsigned XorReg = makeAnotherReg(Type::IntTy);
|
||||||
|
int FrameIdx =
|
||||||
|
F->getFrameInfo()->CreateStackObject(SrcTy, TM.getTargetData());
|
||||||
|
// Update machine-CFG edges
|
||||||
|
MachineBasicBlock *XorMBB = new MachineBasicBlock(BB->getBasicBlock());
|
||||||
|
MachineBasicBlock *PhiMBB = new MachineBasicBlock(BB->getBasicBlock());
|
||||||
|
MachineBasicBlock *OldMBB = BB;
|
||||||
|
ilist<MachineBasicBlock>::iterator It = BB; ++It;
|
||||||
|
F->getBasicBlockList().insert(It, XorMBB);
|
||||||
|
F->getBasicBlockList().insert(It, PhiMBB);
|
||||||
|
BB->addSuccessor(XorMBB);
|
||||||
|
BB->addSuccessor(PhiMBB);
|
||||||
|
|
||||||
|
// Convert from floating point to unsigned 32-bit value
|
||||||
|
// Use 0 if incoming value is < 0.0
|
||||||
|
BuildMI(*BB, IP, PPC32::FSEL, 3, UseZero).addReg(SrcReg).addReg(SrcReg)
|
||||||
|
.addReg(Zero);
|
||||||
|
// Use 2**32 - 1 if incoming value is >= 2**32
|
||||||
|
BuildMI(*BB, IP, PPC32::FSUB, 2, UseMaxInt).addReg(MaxInt).addReg(SrcReg);
|
||||||
|
BuildMI(*BB, IP, PPC32::FSEL, 3, UseChoice).addReg(UseMaxInt)
|
||||||
|
.addReg(UseZero).addReg(MaxInt);
|
||||||
|
// Subtract 2**31
|
||||||
|
BuildMI(*BB, IP, PPC32::FSUB, 2, TmpReg).addReg(UseChoice).addReg(Border);
|
||||||
|
// Use difference if >= 2**31
|
||||||
|
BuildMI(*BB, IP, PPC32::FCMPU, 2, PPC32::CR0).addReg(UseChoice)
|
||||||
|
.addReg(Border);
|
||||||
|
BuildMI(*BB, IP, PPC32::FSEL, 3, TmpReg2).addReg(TmpReg).addReg(TmpReg)
|
||||||
|
.addReg(UseChoice);
|
||||||
|
// Convert to integer
|
||||||
|
BuildMI(*BB, IP, PPC32::FCTIWZ, 1, ConvReg).addReg(TmpReg2);
|
||||||
|
addFrameReference(BuildMI(*BB, IP, PPC32::STFD, 3).addReg(ConvReg),
|
||||||
|
FrameIdx);
|
||||||
|
addFrameReference(BuildMI(*BB, IP, PPC32::LWZ, 2, IntTmp),
|
||||||
|
FrameIdx, 4);
|
||||||
|
BuildMI(*BB, IP, PPC32::BLT, 2).addReg(PPC32::CR0).addMBB(PhiMBB);
|
||||||
|
BuildMI(*BB, IP, PPC32::B, 1).addMBB(XorMBB);
|
||||||
|
|
||||||
|
// XorMBB:
|
||||||
|
// add 2**31 if input was >= 2**31
|
||||||
|
BB = XorMBB;
|
||||||
|
BuildMI(BB, PPC32::XORIS, 2, XorReg).addReg(IntTmp).addImm(0x8000);
|
||||||
|
BuildMI(BB, PPC32::B, 1).addMBB(PhiMBB);
|
||||||
|
XorMBB->addSuccessor(PhiMBB);
|
||||||
|
|
||||||
|
// PhiMBB:
|
||||||
|
// DestReg = phi [ IntTmp, OldMBB ], [ XorReg, XorMBB ]
|
||||||
|
BB = PhiMBB;
|
||||||
|
BuildMI(BB, PPC32::PHI, 2, DestReg).addReg(IntTmp).addMBB(OldMBB)
|
||||||
|
.addReg(XorReg).addMBB(XorMBB);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user