Index: src/IceTargetLoweringMIPS32.cpp |
diff --git a/src/IceTargetLoweringMIPS32.cpp b/src/IceTargetLoweringMIPS32.cpp |
index 56e0679a2de4cb89ee3b0cda4d02064992ebe3bf..b93472365d20d8a746a270e661686d871ff89342 100644 |
--- a/src/IceTargetLoweringMIPS32.cpp |
+++ b/src/IceTargetLoweringMIPS32.cpp |
@@ -1562,16 +1562,26 @@ void TargetMIPS32::PostLoweringLegalizer::legalizeMov(InstMIPS32Mov *MovInstr) { |
if (IsDstGPR != IsSrcGPR) { |
if (IsDstGPR) { |
// Dest is GPR and SrcR is FPR. Use mfc1. |
- if (typeWidthInBytes(Dest->getType()) == 8) { |
+ int32_t typeWidth = typeWidthInBytes(Dest->getType()); |
Jim Stichnoth
2016/10/10 17:07:49
Capitalize TypeWidth variable per LLVM convention.
sagar.thakur
2016/10/12 06:07:06
Done.
|
+ if (MovInstr->getDestHi() != nullptr) |
+ typeWidth += typeWidthInBytes(MovInstr->getDestHi()->getType()); |
+ if (typeWidth == 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)); |
+ Variable *DstFPRHi, *DstFPRLo; |
+ if (MovInstr->getDestHi() != nullptr && Dest != nullptr) { |
+ DstFPRHi = Target->makeReg(IceType_i32, |
+ MovInstr->getDestHi()->getRegNum()); |
+ DstFPRLo = Target->makeReg(IceType_i32, Dest->getRegNum()); |
+ } else { |
+ DstFPRHi = Target->makeReg( |
+ IceType_i32, RegMIPS32::get64PairFirstRegNum(DRegNum)); |
+ DstFPRLo = Target->makeReg( |
+ IceType_i32, RegMIPS32::get64PairSecondRegNum(DRegNum)); |
+ } |
Target->_mov(DstFPRHi, SrcGPRLo); |
Target->_mov(DstFPRLo, SrcGPRHi); |
Legalized = true; |
@@ -1591,10 +1601,19 @@ void TargetMIPS32::PostLoweringLegalizer::legalizeMov(InstMIPS32Mov *MovInstr) { |
SrcGPRLo = SrcGPRHi; |
} else { |
// Split it into two mtc1 instructions |
- SrcGPRHi = Target->makeReg( |
- IceType_i32, RegMIPS32::get64PairFirstRegNum(SRegNum)); |
- SrcGPRLo = Target->makeReg( |
- IceType_i32, RegMIPS32::get64PairSecondRegNum(SRegNum)); |
+ if (MovInstr->getSrcSize() == 2) { |
+ const auto FirstReg = |
+ (llvm::cast<Variable>(MovInstr->getSrc(0)))->getRegNum(); |
+ const auto SecondReg = |
+ (llvm::cast<Variable>(MovInstr->getSrc(1)))->getRegNum(); |
+ SrcGPRHi = Target->makeReg(IceType_i32, FirstReg); |
+ SrcGPRLo = Target->makeReg(IceType_i32, SecondReg); |
+ } else { |
+ SrcGPRHi = Target->makeReg( |
+ IceType_i32, RegMIPS32::get64PairFirstRegNum(SRegNum)); |
+ SrcGPRLo = Target->makeReg( |
+ IceType_i32, RegMIPS32::get64PairSecondRegNum(SRegNum)); |
+ } |
} |
Variable *DstFPRHi = Target->makeReg( |
IceType_f32, RegMIPS32::get64PairFirstRegNum(DRegNum)); |
@@ -1624,7 +1643,12 @@ void TargetMIPS32::PostLoweringLegalizer::legalizeMov(InstMIPS32Mov *MovInstr) { |
auto *SrcR = llvm::cast<Variable>(Src); |
assert(SrcR->hasReg()); |
assert(!SrcR->isRematerializable()); |
- const int32_t Offset = Dest->getStackOffset(); |
+ int32_t Offset = 0; |
+ |
+ if (MovInstr->getDestHi() != nullptr) |
+ Offset = MovInstr->getDestHi()->getStackOffset(); |
+ else |
+ Offset = Dest->getStackOffset(); |
// This is a _mov(Mem(), Variable), i.e., a store. |
auto *Base = Target->getPhysicalRegister(Target->getFrameOrStackReg()); |
@@ -1652,6 +1676,19 @@ void TargetMIPS32::PostLoweringLegalizer::legalizeMov(InstMIPS32Mov *MovInstr) { |
Target->Ctx->getConstantInt32(Offset + 4))); |
Target->_sw(SrcGPRLo, Addr); |
Target->_sw(SrcGPRHi, AddrHi); |
+ } else if (DestTy == IceType_f64 && IsSrcGPReg == true) { |
Jim Stichnoth
2016/10/10 17:07:49
remove "== true"
sagar.thakur
2016/10/12 06:07:06
Done.
|
+ const auto FirstReg = |
+ (llvm::cast<Variable>(MovInstr->getSrc(0)))->getRegNum(); |
+ const auto SecondReg = |
+ (llvm::cast<Variable>(MovInstr->getSrc(1)))->getRegNum(); |
+ Variable *SrcGPRHi = Target->makeReg(IceType_i32, SecondReg); |
+ Variable *SrcGPRLo = Target->makeReg(IceType_i32, FirstReg); |
+ OperandMIPS32Mem *AddrHi = OperandMIPS32Mem::create( |
+ Target->Func, DestTy, Base, |
+ llvm::cast<ConstantInteger32>( |
+ Target->Ctx->getConstantInt32(Offset + 4))); |
+ Target->_sw(SrcGPRLo, Addr); |
+ Target->_sw(SrcGPRHi, AddrHi); |
} else { |
Target->_sw(SrcR, Addr); |
} |
@@ -3112,6 +3149,39 @@ void TargetMIPS32::lowerCast(const InstCast *Instr) { |
llvm::report_fatal_error( |
"i16 to v16i1 conversion should have been prelowered."); |
break; |
+ case IceType_i32: |
+ case IceType_f32: { |
+ Variable *Src0R = legalizeToReg(Src0); |
+ _mov(Dest, Src0R); |
+ break; |
+ } |
+ case IceType_i64: { |
+ assert(Src0->getType() == IceType_f64); |
+ Variable *Src0R = legalizeToReg(Src0); |
+ auto *Dest64 = llvm::cast<Variable64On32>(Dest); |
+ _mov(Dest64, Src0R); |
+ Context.insert<InstFakeDef>(Dest64->getHi()); |
+ break; |
+ } |
+ case IceType_f64: { |
+ assert(Src0->getType() == IceType_i64); |
+ const uint32_t Mask = 0xFFFFFFFF; |
+ if (auto *C64 = llvm::dyn_cast<ConstantInteger64>(Src0)) { |
+ Variable *RegHi, *RegLo; |
+ const uint64_t Value = C64->getValue(); |
+ uint64_t Upper32Bits = (Value >> INT32_BITS) & Mask; |
+ uint64_t Lower32Bits = Value & Mask; |
+ RegLo = legalizeToReg(Ctx->getConstantInt32(Lower32Bits)); |
+ RegHi = legalizeToReg(Ctx->getConstantInt32(Upper32Bits)); |
+ _mov(Dest, RegHi, RegLo); |
+ } else { |
+ auto *Var64On32 = llvm::cast<Variable64On32>(Src0); |
+ auto *RegLo = legalizeToReg(loOperand(Var64On32)); |
+ auto *RegHi = legalizeToReg(hiOperand(Var64On32)); |
+ _mov(Dest, RegHi, RegLo); |
+ } |
+ break; |
+ } |
case IceType_v8i1: |
assert(Src0->getType() == IceType_i8); |
llvm::report_fatal_error( |