Chromium Code Reviews| Index: src/IceTargetLoweringMIPS32.cpp |
| diff --git a/src/IceTargetLoweringMIPS32.cpp b/src/IceTargetLoweringMIPS32.cpp |
| index 7bdf723d3796b4da898c12e1f0a54380a7fbff89..ee819482338524a2390cce10abaea0c1e68b9c17 100644 |
| --- a/src/IceTargetLoweringMIPS32.cpp |
| +++ b/src/IceTargetLoweringMIPS32.cpp |
| @@ -1077,6 +1077,69 @@ void TargetMIPS32::PostLoweringLegalizer::legalizeMov(InstMIPS32Mov *MovInstr) { |
| return; |
| bool Legalized = false; |
| + auto *SrcR = llvm::cast<Variable>(Src); |
| + if (Dest->hasReg() && SrcR->hasReg()) { |
| + // This might be a GP to/from FP move generated due to argument passing. |
| + // Use mtc1/mfc1 instead of mov.[s/d] if src and dst registers are of |
| + // different types. |
| + const bool IsDstGPR = RegMIPS32::isGPRReg(Dest->getRegNum()); |
| + const bool IsSrcGPR = RegMIPS32::isGPRReg(SrcR->getRegNum()); |
| + const RegNumT SRegNum = SrcR->getRegNum(); |
| + const RegNumT DRegNum = Dest->getRegNum(); |
| + if (IsDstGPR != IsSrcGPR) { |
| + if (IsDstGPR) { |
| + // Dest is GPR and SrcR is FPR. Use mfc1. |
| + if (typeWidthInBytes(Dest->getType()) == 8) { |
| + // Split it into two mfc1 instructions |
| + Variable *SrcGPRHi = Target->makeReg( |
| + IceType_f32, RegMIPS32::get64PairFirstRegNum(SRegNum)); |
| + Variable *SrcGPRLo = Target->makeReg( |
| + IceType_f32, RegMIPS32::get64PairSecondRegNum(SRegNum)); |
| + Variable *DstFPRHi = Target->makeReg( |
| + IceType_i32, RegMIPS32::get64PairFirstRegNum(DRegNum)); |
| + Variable *DstFPRLo = Target->makeReg( |
| + IceType_i32, RegMIPS32::get64PairSecondRegNum(DRegNum)); |
| + Target->_mov(DstFPRHi, SrcGPRLo); |
| + Target->_mov(DstFPRLo, SrcGPRHi); |
| + Legalized = true; |
| + } else { |
| + Variable *SrcGPR = Target->makeReg(IceType_f32, SRegNum); |
| + Variable *DstFPR = Target->makeReg(IceType_i32, DRegNum); |
| + Target->_mov(DstFPR, SrcGPR); |
| + Legalized = true; |
| + } |
| + } else { |
| + // Dest is FPR and SrcR is GPR. Use mtc1. |
| + if (typeWidthInBytes(SrcR->getType()) == 8) { |
| + // Split it into two mtc1 instructions |
| + Variable *SrcGPRHi = Target->makeReg( |
| + IceType_i32, RegMIPS32::get64PairFirstRegNum(SRegNum)); |
| + Variable *SrcGPRLo = Target->makeReg( |
| + IceType_i32, RegMIPS32::get64PairSecondRegNum(SRegNum)); |
| + Variable *DstFPRHi = Target->makeReg( |
| + IceType_f32, RegMIPS32::get64PairFirstRegNum(DRegNum)); |
| + Variable *DstFPRLo = Target->makeReg( |
| + IceType_f32, RegMIPS32::get64PairSecondRegNum(DRegNum)); |
| + Target->_mov(DstFPRHi, SrcGPRLo); |
| + Target->_mov(DstFPRLo, SrcGPRHi); |
| + Legalized = true; |
| + } else { |
| + Variable *SrcGPR = Target->makeReg(IceType_i32, SRegNum); |
| + Variable *DstFPR = Target->makeReg(IceType_f32, DRegNum); |
| + Target->_mov(DstFPR, SrcGPR); |
| + Legalized = true; |
| + } |
| + } |
| + } |
| + if (Legalized) { |
| + if (MovInstr->isDestRedefined()) { |
| + Target->_set_dest_redefined(); |
| + } |
| + MovInstr->setDeleted(); |
| + return; |
| + } |
| + } |
| + |
| if (!Dest->hasReg()) { |
| auto *SrcR = llvm::cast<Variable>(Src); |
| assert(SrcR->hasReg()); |
| @@ -1094,22 +1157,15 @@ void TargetMIPS32::PostLoweringLegalizer::legalizeMov(InstMIPS32Mov *MovInstr) { |
| // case type of the SrcR is still FP thus we need to explicitly generate sw |
| // instead of swc1. |
| const RegNumT RegNum = SrcR->getRegNum(); |
| - const bool isSrcGPReg = ((unsigned)RegNum >= RegMIPS32::Reg_A0 && |
| - (unsigned)RegNum <= RegMIPS32::Reg_A3) || |
| - ((unsigned)RegNum >= RegMIPS32::Reg_A0A1 && |
| - (unsigned)RegNum <= RegMIPS32::Reg_A2A3); |
| + const bool isSrcGPReg = RegMIPS32::isGPRReg(SrcR->getRegNum()); |
|
Jim Stichnoth
2016/09/07 15:39:31
capitalize IsSrcGPReg per LLVM coding style
jaydeep.patil
2016/09/13 06:18:36
Done.
|
| if (SrcTy == IceType_f32 && isSrcGPReg == true) { |
| Variable *SrcGPR = Target->makeReg(IceType_i32, RegNum); |
| Target->_sw(SrcGPR, Addr); |
| } else if (SrcTy == IceType_f64 && isSrcGPReg == true) { |
| - Variable *SrcGPRHi, *SrcGPRLo; |
| - if (RegNum == RegMIPS32::Reg_A0A1) { |
| - SrcGPRLo = Target->makeReg(IceType_i32, RegMIPS32::Reg_A0); |
| - SrcGPRHi = Target->makeReg(IceType_i32, RegMIPS32::Reg_A1); |
| - } else { |
| - SrcGPRLo = Target->makeReg(IceType_i32, RegMIPS32::Reg_A2); |
| - SrcGPRHi = Target->makeReg(IceType_i32, RegMIPS32::Reg_A3); |
| - } |
| + Variable *SrcGPRHi = |
| + Target->makeReg(IceType_i32, RegMIPS32::get64PairFirstRegNum(RegNum)); |
| + Variable *SrcGPRLo = Target->makeReg( |
| + IceType_i32, RegMIPS32::get64PairSecondRegNum(RegNum)); |
| OperandMIPS32Mem *AddrHi = OperandMIPS32Mem::create( |
| Target->Func, DestTy, Base, |
| llvm::cast<ConstantInteger32>( |
| @@ -2027,15 +2083,35 @@ void TargetMIPS32::lowerCast(const InstCast *Instr) { |
| UnimplementedLoweringError(this, Instr); |
| break; |
| } |
| - case InstCast::Fptosi: |
| - UnimplementedLoweringError(this, Instr); |
| + case InstCast::Fptosi: { |
| + if (Src0Ty == IceType_f32 && DestTy == IceType_i32) { |
| + Variable *Src0R = legalizeToReg(Src0); |
| + Variable *FTmp1 = makeReg(IceType_f32); |
| + Variable *FTmp2 = makeReg(IceType_f32); |
| + _mov(FTmp1, Src0R); |
|
Jim Stichnoth
2016/09/07 15:39:31
Is it really necessary to copy Src0R through a tem
jaydeep.patil
2016/09/13 06:18:36
Done.
|
| + _trunc_w_s(FTmp2, FTmp1); |
| + _mov(Dest, FTmp2); |
| + } else { |
| + UnimplementedLoweringError(this, Instr); |
| + } |
| break; |
| + } |
| case InstCast::Fptoui: |
| UnimplementedLoweringError(this, Instr); |
| break; |
| - case InstCast::Sitofp: |
| - UnimplementedLoweringError(this, Instr); |
| + case InstCast::Sitofp: { |
| + if (Src0Ty == IceType_i32 && DestTy == IceType_f32) { |
| + Variable *Src0R = legalizeToReg(Src0); |
| + Variable *FTmp1 = makeReg(IceType_f32); |
| + Variable *FTmp2 = makeReg(IceType_f32); |
| + _mov(FTmp1, Src0R); |
| + _cvt_s_w(FTmp2, FTmp1); |
| + _mov(Dest, FTmp2); |
| + } else { |
| + UnimplementedLoweringError(this, Instr); |
| + } |
| break; |
| + } |
| case InstCast::Uitofp: { |
| UnimplementedLoweringError(this, Instr); |
| break; |