| Index: src/IceTargetLoweringMIPS32.cpp
|
| diff --git a/src/IceTargetLoweringMIPS32.cpp b/src/IceTargetLoweringMIPS32.cpp
|
| index 237eef46ca435632c96c83e6d002eca2c0f4141a..e4f2fd09e6e34acc2f975029f91c3cd053bc47d4 100644
|
| --- a/src/IceTargetLoweringMIPS32.cpp
|
| +++ b/src/IceTargetLoweringMIPS32.cpp
|
| @@ -1452,6 +1452,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());
|
| @@ -1469,22 +1532,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);
|
| - if (SrcTy == IceType_f32 && isSrcGPReg == true) {
|
| + const bool IsSrcGPReg = RegMIPS32::isGPRReg(SrcR->getRegNum());
|
| + 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);
|
| - }
|
| + } else if (SrcTy == IceType_f64 && IsSrcGPReg == true) {
|
| + 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>(
|
| @@ -2411,15 +2467,33 @@ void TargetMIPS32::lowerCast(const InstCast *Instr) {
|
| _mov(Dest, DestR);
|
| break;
|
| }
|
| - case InstCast::Fptosi: //
|
| - UnimplementedLoweringError(this, Instr);
|
| + case InstCast::Fptosi: {
|
| + if (Src0Ty == IceType_f32 && DestTy == IceType_i32) {
|
| + Variable *Src0R = legalizeToReg(Src0);
|
| + Variable *FTmp = makeReg(IceType_f32);
|
| + _trunc_w_s(FTmp, Src0R);
|
| + _mov(Dest, FTmp);
|
| + } 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;
|
|
|