Index: src/IceTargetLoweringMIPS32.cpp |
diff --git a/src/IceTargetLoweringMIPS32.cpp b/src/IceTargetLoweringMIPS32.cpp |
index 331f1ed4c99b6a82b3c3682f1a40810004cf6baa..c0c00a9521d31e5df2cd3e94abb15fcb8be84de5 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)) { |
+ uint32_t UpperBits = (Offset >> 16) & 0xFFFF; |
Jim Stichnoth
2016/10/12 13:52:52
const uint32_t for these?
jaydeep.patil
2016/10/13 04:36:35
Done.
|
+ 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) { |
Jim Stichnoth
2016/10/12 13:52:52
It would be nice (though I won't insist) if this C
jaydeep.patil
2016/10/13 04:36:35
Done.
|
+ if (llvm::isa<ConstantRelocatable>(Mem->getOffset())) { |
+ return nullptr; |
+ } |
+ Variable *Base = Mem->getBase(); |
+ ConstantInteger32 *Ci32 = llvm::cast<ConstantInteger32>(Mem->getOffset()); |
Jim Stichnoth
2016/10/12 13:52:52
auto *Ci32
jaydeep.patil
2016/10/13 04:36:35
Done.
|
+ 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,50 @@ void TargetMIPS32::postLowerLegalization() { |
while (!Context.atEnd()) { |
PostIncrLoweringContext PostIncrement(Context); |
Inst *CurInstr = iteratorToInst(Context.getCur()); |
- |
- // TODO(sagar.thakur): Add remaining cases of legalization. |
- |
if (auto *MovInstr = llvm::dyn_cast<InstMIPS32Mov>(CurInstr)) { |
Jim Stichnoth
2016/10/12 13:52:52
This loop body has become kind of hard to read. I
jaydeep.patil
2016/10/13 04:36:35
Done.
|
Legalizer.legalizeMov(MovInstr); |
+ } else if (auto *SwInstr = llvm::dyn_cast<InstMIPS32Sw>(CurInstr)) { |
+ if (OperandMIPS32Mem *LegalMem = Legalizer.legalizeMemOperand( |
+ llvm::cast<OperandMIPS32Mem>(SwInstr->getSrc(1)))) { |
+ auto *Src = llvm::cast<Variable>(SwInstr->getSrc(0)); |
+ _sw(Src, LegalMem); |
+ CurInstr->setDeleted(); |
+ } |
+ } else if (auto *Swc1Instr = llvm::dyn_cast<InstMIPS32Swc1>(CurInstr)) { |
+ if (OperandMIPS32Mem *LegalMem = Legalizer.legalizeMemOperand( |
+ llvm::cast<OperandMIPS32Mem>(Swc1Instr->getSrc(1)))) { |
+ auto *Src = llvm::cast<Variable>(Swc1Instr->getSrc(0)); |
+ _swc1(Src, LegalMem); |
+ CurInstr->setDeleted(); |
+ } |
+ } else if (auto *Sdc1Instr = llvm::dyn_cast<InstMIPS32Sdc1>(CurInstr)) { |
+ if (OperandMIPS32Mem *LegalMem = Legalizer.legalizeMemOperand( |
+ llvm::cast<OperandMIPS32Mem>(Sdc1Instr->getSrc(1)))) { |
+ auto *Src = llvm::cast<Variable>(Sdc1Instr->getSrc(0)); |
+ _sdc1(Src, LegalMem); |
+ CurInstr->setDeleted(); |
+ } |
+ } else if (auto *LwInstr = llvm::dyn_cast<InstMIPS32Lw>(CurInstr)) { |
+ if (OperandMIPS32Mem *LegalMem = Legalizer.legalizeMemOperand( |
+ llvm::cast<OperandMIPS32Mem>(LwInstr->getSrc(0)))) { |
+ auto *Dst = llvm::cast<Variable>(LwInstr->getDest()); |
+ _lw(Dst, LegalMem); |
+ CurInstr->setDeleted(); |
+ } |
+ } else if (auto *Lwc1Instr = llvm::dyn_cast<InstMIPS32Lwc1>(CurInstr)) { |
+ if (OperandMIPS32Mem *LegalMem = Legalizer.legalizeMemOperand( |
+ llvm::cast<OperandMIPS32Mem>(Lwc1Instr->getSrc(0)))) { |
+ auto *Dst = llvm::cast<Variable>(Lwc1Instr->getDest()); |
+ _lwc1(Dst, LegalMem); |
+ CurInstr->setDeleted(); |
+ } |
+ } else if (auto *Ldc1Instr = llvm::dyn_cast<InstMIPS32Ldc1>(CurInstr)) { |
+ if (OperandMIPS32Mem *LegalMem = Legalizer.legalizeMemOperand( |
+ llvm::cast<OperandMIPS32Mem>(Ldc1Instr->getSrc(0)))) { |
+ auto *Dst = llvm::cast<Variable>(Ldc1Instr->getDest()); |
+ _ldc1(Dst, LegalMem); |
+ CurInstr->setDeleted(); |
+ } |
} |
} |
} |