Index: src/IceTargetLoweringMIPS32.cpp |
diff --git a/src/IceTargetLoweringMIPS32.cpp b/src/IceTargetLoweringMIPS32.cpp |
index 331f1ed4c99b6a82b3c3682f1a40810004cf6baa..7f501efbcd1a87c22d6758b6a802d3726798ff56 100644 |
--- a/src/IceTargetLoweringMIPS32.cpp |
+++ b/src/IceTargetLoweringMIPS32.cpp |
@@ -1529,7 +1529,17 @@ Variable *TargetMIPS32::PostLoweringLegalizer::newBaseRegister( |
Target->Ctx->getConstantInt32(-Offset), ScratchRegNum); |
Target->_sub(ScratchReg, Base, OffsetVal); |
} else { |
- Target->_addiu(ScratchReg, Base, Offset); |
+ constexpr bool SignExt = true; |
+ if (!OperandMIPS32Mem::canHoldOffset(Base->getType(), SignExt, Offset)) { |
+ const uint32_t UpperBits = (Offset >> 16) & 0xFFFF; |
+ const uint32_t LowerBits = Offset & 0xFFFF; |
+ Target->_lui(ScratchReg, Target->Ctx->getConstantInt32(UpperBits)); |
+ if (LowerBits) |
+ Target->_ori(ScratchReg, ScratchReg, LowerBits); |
+ Target->_addu(ScratchReg, ScratchReg, Base); |
+ } else { |
+ Target->_addiu(ScratchReg, Base, Offset); |
+ } |
} |
return ScratchReg; |
@@ -1731,6 +1741,35 @@ void TargetMIPS32::PostLoweringLegalizer::legalizeMov(InstMIPS32Mov *MovInstr) { |
} |
} |
+OperandMIPS32Mem * |
+TargetMIPS32::PostLoweringLegalizer::legalizeMemOperand(OperandMIPS32Mem *Mem) { |
+ if (llvm::isa<ConstantRelocatable>(Mem->getOffset())) { |
+ return nullptr; |
+ } |
+ Variable *Base = Mem->getBase(); |
+ auto *Ci32 = llvm::cast<ConstantInteger32>(Mem->getOffset()); |
+ int32_t Offset = Ci32->getValue(); |
+ |
+ if (Base->isRematerializable()) { |
+ const int32_t ExtraOffset = |
+ (Base->getRegNum() == Target->getFrameOrStackReg()) |
+ ? Target->getFrameFixedAllocaOffset() |
+ : 0; |
+ Offset += Base->getStackOffset() + ExtraOffset; |
+ Base = Target->getPhysicalRegister(Base->getRegNum()); |
+ } |
+ |
+ constexpr bool SignExt = true; |
+ if (!OperandMIPS32Mem::canHoldOffset(Mem->getType(), SignExt, Offset)) { |
+ Base = newBaseRegister(Base, Offset, Target->getReservedTmpReg()); |
+ Offset = 0; |
+ } |
+ |
+ return OperandMIPS32Mem::create( |
+ Target->Func, Mem->getType(), Base, |
+ llvm::cast<ConstantInteger32>(Target->Ctx->getConstantInt32(Offset))); |
+} |
+ |
void TargetMIPS32::postLowerLegalization() { |
Func->dump("Before postLowerLegalization"); |
assert(hasComputedFrame()); |
@@ -1740,11 +1779,58 @@ void TargetMIPS32::postLowerLegalization() { |
while (!Context.atEnd()) { |
PostIncrLoweringContext PostIncrement(Context); |
Inst *CurInstr = iteratorToInst(Context.getCur()); |
- |
- // TODO(sagar.thakur): Add remaining cases of legalization. |
- |
+ const SizeT NumSrcs = CurInstr->getSrcSize(); |
+ Operand *Src0 = NumSrcs < 1 ? nullptr : CurInstr->getSrc(0); |
+ Operand *Src1 = NumSrcs < 2 ? nullptr : CurInstr->getSrc(1); |
+ auto *Src0V = llvm::dyn_cast_or_null<Variable>(Src0); |
+ auto *Src0M = llvm::dyn_cast_or_null<OperandMIPS32Mem>(Src0); |
+ auto *Src1M = llvm::dyn_cast_or_null<OperandMIPS32Mem>(Src1); |
+ Variable *Dst = CurInstr->getDest(); |
if (auto *MovInstr = llvm::dyn_cast<InstMIPS32Mov>(CurInstr)) { |
Legalizer.legalizeMov(MovInstr); |
+ continue; |
+ } |
+ if (llvm::isa<InstMIPS32Sw>(CurInstr)) { |
+ if (auto *LegalMem = Legalizer.legalizeMemOperand(Src1M)) { |
+ _sw(Src0V, LegalMem); |
+ CurInstr->setDeleted(); |
+ } |
+ continue; |
+ } |
+ if (llvm::isa<InstMIPS32Swc1>(CurInstr)) { |
+ if (auto *LegalMem = Legalizer.legalizeMemOperand(Src1M)) { |
+ _swc1(Src0V, LegalMem); |
+ CurInstr->setDeleted(); |
+ } |
+ continue; |
+ } |
+ if (llvm::isa<InstMIPS32Sdc1>(CurInstr)) { |
+ if (auto *LegalMem = Legalizer.legalizeMemOperand(Src1M)) { |
+ _sdc1(Src0V, LegalMem); |
+ CurInstr->setDeleted(); |
+ } |
+ continue; |
+ } |
+ if (llvm::isa<InstMIPS32Lw>(CurInstr)) { |
+ if (auto *LegalMem = Legalizer.legalizeMemOperand(Src0M)) { |
+ _lw(Dst, LegalMem); |
+ CurInstr->setDeleted(); |
+ } |
+ continue; |
+ } |
+ if (llvm::isa<InstMIPS32Lwc1>(CurInstr)) { |
+ if (auto *LegalMem = Legalizer.legalizeMemOperand(Src0M)) { |
+ _lwc1(Dst, LegalMem); |
+ CurInstr->setDeleted(); |
+ } |
+ continue; |
+ } |
+ if (llvm::isa<InstMIPS32Ldc1>(CurInstr)) { |
+ if (auto *LegalMem = Legalizer.legalizeMemOperand(Src0M)) { |
+ _ldc1(Dst, LegalMem); |
+ CurInstr->setDeleted(); |
+ } |
+ continue; |
} |
} |
} |