diff options
author | Akira Hatanaka <ahatanaka@mips.com> | 2013-05-16 19:48:37 +0000 |
---|---|---|
committer | Akira Hatanaka <ahatanaka@mips.com> | 2013-05-16 19:48:37 +0000 |
commit | 39d40f7baf48e10010f421f8eda791c18090a3d8 (patch) | |
tree | f4201d4bc242e16ffb037ed5e8b132b791391aba /llvm/lib/Target/Mips/MipsSEInstrInfo.cpp | |
parent | 81250934d7d318ccf8e61dd4f592ad6b20b4a8a5 (diff) | |
download | bcm5719-llvm-39d40f7baf48e10010f421f8eda791c18090a3d8.tar.gz bcm5719-llvm-39d40f7baf48e10010f421f8eda791c18090a3d8.zip |
[mips] Fix instruction selection pattern for sint_to_fp node to avoid emitting an
invalid instruction sequence.
Rather than emitting an int-to-FP move instruction and an int-to-FP conversion
instruction during instruction selection, we emit a pseudo instruction which gets
expanded post-RA. Without this change, register allocation can possibly insert a
floating point register move instruction between the two instructions, which is not
valid according to the ISA manual.
mtc1 $f4, $4 # int-to-fp move instruction.
mov.s $f2, $f4 # move contents of $f4 to $f2.
cvt.s.w $f0, $f2 # int-to-fp conversion.
llvm-svn: 182042
Diffstat (limited to 'llvm/lib/Target/Mips/MipsSEInstrInfo.cpp')
-rw-r--r-- | llvm/lib/Target/Mips/MipsSEInstrInfo.cpp | 37 |
1 files changed, 37 insertions, 0 deletions
diff --git a/llvm/lib/Target/Mips/MipsSEInstrInfo.cpp b/llvm/lib/Target/Mips/MipsSEInstrInfo.cpp index 12ed1bc1865..7a8ed7a1e97 100644 --- a/llvm/lib/Target/Mips/MipsSEInstrInfo.cpp +++ b/llvm/lib/Target/Mips/MipsSEInstrInfo.cpp @@ -253,6 +253,21 @@ bool MipsSEInstrInfo::expandPostRAPseudo(MachineBasicBlock::iterator MI) const { case Mips::RetRA: expandRetRA(MBB, MI, Mips::RET); break; + case Mips::PseudoCVT_S_W: + expandCvtFPInt(MBB, MI, Mips::CVT_S_W, Mips::MTC1, false, false, false); + break; + case Mips::PseudoCVT_D32_W: + expandCvtFPInt(MBB, MI, Mips::CVT_D32_W, Mips::MTC1, true, false, false); + break; + case Mips::PseudoCVT_S_L: + expandCvtFPInt(MBB, MI, Mips::CVT_S_L, Mips::DMTC1, false, true, true); + break; + case Mips::PseudoCVT_D64_W: + expandCvtFPInt(MBB, MI, Mips::CVT_D64_W, Mips::MTC1, true, false, true); + break; + case Mips::PseudoCVT_D64_L: + expandCvtFPInt(MBB, MI, Mips::CVT_D64_L, Mips::DMTC1, false, false, true); + break; case Mips::BuildPairF64: expandBuildPairF64(MBB, MI); break; @@ -374,6 +389,28 @@ void MipsSEInstrInfo::expandRetRA(MachineBasicBlock &MBB, BuildMI(MBB, I, I->getDebugLoc(), get(Opc)).addReg(Mips::RA); } +void MipsSEInstrInfo::expandCvtFPInt(MachineBasicBlock &MBB, + MachineBasicBlock::iterator I, + unsigned CvtOpc, unsigned MovOpc, + bool DstIsLarger, bool SrcIsLarger, + bool IsI64) const { + const MCInstrDesc &CvtDesc = get(CvtOpc), &MovDesc = get(MovOpc); + const MachineOperand &Dst = I->getOperand(0), &Src = I->getOperand(1); + unsigned DstReg = Dst.getReg(), SrcReg = Src.getReg(), TmpReg = DstReg; + unsigned KillSrc = getKillRegState(Src.isKill()); + DebugLoc DL = I->getDebugLoc(); + unsigned SubIdx = (IsI64 ? Mips::sub_32 : Mips::sub_fpeven); + + if (DstIsLarger) + TmpReg = getRegisterInfo().getSubReg(DstReg, SubIdx); + + if (SrcIsLarger) + DstReg = getRegisterInfo().getSubReg(DstReg, SubIdx); + + BuildMI(MBB, I, DL, MovDesc, TmpReg).addReg(SrcReg, KillSrc); + BuildMI(MBB, I, DL, CvtDesc, DstReg).addReg(TmpReg, RegState::Kill); +} + void MipsSEInstrInfo::expandExtractElementF64(MachineBasicBlock &MBB, MachineBasicBlock::iterator I) const { unsigned DstReg = I->getOperand(0).getReg(); |