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 | ec4db6ab5f64318b1aa2351f7e710569869193e9 (patch) | |
tree | be4c14d2e226a3fb22433a0b012f0f38d25f804b | |
parent | 50f02f9d21f3d3558249910b4e05abb49e8c6f50 (diff) | |
download | external_llvm-ec4db6ab5f64318b1aa2351f7e710569869193e9.zip external_llvm-ec4db6ab5f64318b1aa2351f7e710569869193e9.tar.gz external_llvm-ec4db6ab5f64318b1aa2351f7e710569869193e9.tar.bz2 |
[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.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@182042 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/Target/Mips/MipsInstrFPU.td | 18 | ||||
-rw-r--r-- | lib/Target/Mips/MipsSEInstrInfo.cpp | 37 | ||||
-rw-r--r-- | lib/Target/Mips/MipsSEInstrInfo.h | 3 |
3 files changed, 53 insertions, 5 deletions
diff --git a/lib/Target/Mips/MipsInstrFPU.td b/lib/Target/Mips/MipsInstrFPU.td index a558139..6dc57e0 100644 --- a/lib/Target/Mips/MipsInstrFPU.td +++ b/lib/Target/Mips/MipsInstrFPU.td @@ -260,6 +260,14 @@ let Predicates = [IsFP64bit, HasStdEnc], DecoderNamespace = "Mips64" in { def CVT_D64_L : ABSS_FT<"cvt.d.l", FGR64, FGR64, IIFcvt>, ABSS_FM<0x21, 21>; } +let isPseudo = 1, isCodeGenOnly = 1 in { + def PseudoCVT_S_W : ABSS_FT<"", FGR32, CPURegs, IIFcvt>; + def PseudoCVT_D32_W : ABSS_FT<"", AFGR64, CPURegs, IIFcvt>; + def PseudoCVT_S_L : ABSS_FT<"", FGR64, CPU64Regs, IIFcvt>; + def PseudoCVT_D64_W : ABSS_FT<"", FGR64, CPURegs, IIFcvt>; + def PseudoCVT_D64_L : ABSS_FT<"", FGR64, CPU64Regs, IIFcvt>; +} + let Predicates = [NoNaNsFPMath, HasStdEnc] in { def FABS_S : ABSS_FT<"abs.s", FGR32, FGR32, IIFcvt, fabs>, ABSS_FM<0x5, 16>; def FNEG_S : ABSS_FT<"neg.s", FGR32, FGR32, IIFcvt, fneg>, ABSS_FM<0x7, 16>; @@ -476,12 +484,12 @@ def ExtractElementF64 : def : MipsPat<(f32 fpimm0), (MTC1 ZERO)>; def : MipsPat<(f32 fpimm0neg), (FNEG_S (MTC1 ZERO))>; -def : MipsPat<(f32 (sint_to_fp CPURegs:$src)), (CVT_S_W (MTC1 CPURegs:$src))>; +def : MipsPat<(f32 (sint_to_fp CPURegs:$src)), (PseudoCVT_S_W CPURegs:$src)>; def : MipsPat<(i32 (fp_to_sint FGR32:$src)), (MFC1 (TRUNC_W_S FGR32:$src))>; let Predicates = [NotFP64bit, HasStdEnc] in { def : MipsPat<(f64 (sint_to_fp CPURegs:$src)), - (CVT_D32_W (MTC1 CPURegs:$src))>; + (PseudoCVT_D32_W CPURegs:$src)>; def : MipsPat<(i32 (fp_to_sint AFGR64:$src)), (MFC1 (TRUNC_W_D32 AFGR64:$src))>; def : MipsPat<(f32 (fround AFGR64:$src)), (CVT_S_D32 AFGR64:$src)>; @@ -493,11 +501,11 @@ let Predicates = [IsFP64bit, HasStdEnc] in { def : MipsPat<(f64 fpimm0neg), (FNEG_D64 (DMTC1 ZERO_64))>; def : MipsPat<(f64 (sint_to_fp CPURegs:$src)), - (CVT_D64_W (MTC1 CPURegs:$src))>; + (PseudoCVT_D64_W CPURegs:$src)>; def : MipsPat<(f32 (sint_to_fp CPU64Regs:$src)), - (CVT_S_L (DMTC1 CPU64Regs:$src))>; + (EXTRACT_SUBREG (PseudoCVT_S_L CPU64Regs:$src), sub_32)>; def : MipsPat<(f64 (sint_to_fp CPU64Regs:$src)), - (CVT_D64_L (DMTC1 CPU64Regs:$src))>; + (PseudoCVT_D64_L CPU64Regs:$src)>; def : MipsPat<(i32 (fp_to_sint FGR64:$src)), (MFC1 (TRUNC_W_D64 FGR64:$src))>; diff --git a/lib/Target/Mips/MipsSEInstrInfo.cpp b/lib/Target/Mips/MipsSEInstrInfo.cpp index 12ed1bc..7a8ed7a 100644 --- a/lib/Target/Mips/MipsSEInstrInfo.cpp +++ b/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(); diff --git a/lib/Target/Mips/MipsSEInstrInfo.h b/lib/Target/Mips/MipsSEInstrInfo.h index 416fff8..f4c29b1 100644 --- a/lib/Target/Mips/MipsSEInstrInfo.h +++ b/lib/Target/Mips/MipsSEInstrInfo.h @@ -83,6 +83,9 @@ private: void expandRetRA(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, unsigned Opc) const; + void expandCvtFPInt(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, + unsigned CvtOpc, unsigned MovOpc, bool DstIsLarger, + bool SrcIsLarger, bool IsI64) const; void expandExtractElementF64(MachineBasicBlock &MBB, MachineBasicBlock::iterator I) const; void expandBuildPairF64(MachineBasicBlock &MBB, |