Chromium Code Reviews| Index: src/IceTargetLoweringMIPS32.cpp |
| diff --git a/src/IceTargetLoweringMIPS32.cpp b/src/IceTargetLoweringMIPS32.cpp |
| index f0118feab347143a1378cc54408d7eaa8a609697..7f1565d612b3a700db3a45ad32326566d607a555 100644 |
| --- a/src/IceTargetLoweringMIPS32.cpp |
| +++ b/src/IceTargetLoweringMIPS32.cpp |
| @@ -295,6 +295,11 @@ void TargetMIPS32::translateO2() { |
| return; |
| Func->dump("After stack frame mapping"); |
| + postLowerLegalization(); |
| + if (Func->hasError()) |
| + return; |
| + Func->dump("After postLowerLegalization"); |
| + |
| Func->contractEmptyNodes(); |
| Func->reorderNodes(); |
| @@ -989,6 +994,91 @@ void TargetMIPS32::addEpilog(CfgNode *Node) { |
| return; |
| } |
| +Variable *TargetMIPS32::PostLoweringLegalizer::newBaseRegister( |
| + Variable *Base, int32_t Offset, RegNumT ScratchRegNum) { |
| + // Legalize will likely need a lui/ori combination, but if the top bits are |
| + // all 0 from negating the offset and subtracting, we could use that instead. |
| + const bool ShouldSub = Offset != 0 && (-Offset & 0xFFFF0000) == 0; |
| + Variable *ScratchReg = Target->makeReg(IceType_i32, ScratchRegNum); |
| + if (ShouldSub) { |
| + Variable *OffsetVal = |
| + Target->legalizeToReg(Target->Ctx->getConstantInt32(-Offset)); |
| + Target->_sub(ScratchReg, Base, OffsetVal); |
| + } else { |
| + Target->_addiu(ScratchReg, Base, Offset); |
| + } |
| + |
| + return ScratchReg; |
| +} |
| + |
| +void TargetMIPS32::PostLoweringLegalizer::legalizeMov(InstMIPS32Mov *MovInstr) { |
| + Variable *Dest = MovInstr->getDest(); |
| + assert(Dest != nullptr); |
| + Type DestTy = Dest->getType(); |
|
Jim Stichnoth
2016/07/14 00:34:45
const Type ...
sagar.thakur
2016/07/14 11:57:00
Done.
|
| + assert(DestTy != IceType_i64); |
|
Jim Stichnoth
2016/07/14 00:34:45
Also add "(void)DestTy;" to avoid a compiler warni
sagar.thakur
2016/07/14 11:57:00
Done.
|
| + |
| + Operand *Src = MovInstr->getSrc(0); |
| + Type SrcTy = Src->getType(); |
|
Jim Stichnoth
2016/07/14 00:34:45
const Type ...
sagar.thakur
2016/07/14 11:57:00
Done.
|
| + (void)SrcTy; |
| + assert(SrcTy != IceType_i64); |
| + |
| + if (MovInstr->isMultiDest() || MovInstr->isMultiSource()) |
| + return; |
| + |
| + bool Legalized = false; |
| + if (!Dest->hasReg()) { |
| + UnimplementedError(getFlags()); |
|
Jim Stichnoth
2016/07/14 00:34:45
Is this case (dest variable without a register) go
sagar.thakur
2016/07/14 11:57:00
Yes, this case is possible. I have structured the
|
| + return; |
| + } else if (auto *Var = llvm::dyn_cast<Variable>(Src)) { |
| + if (Var->isRematerializable()) { |
| + // This is equivalent to an x86 _lea(RematOffset(%esp/%ebp), Variable). |
| + |
| + // ExtraOffset is only needed for frame-pointer based frames as we have |
| + // to account for spill storage. |
| + const int32_t ExtraOffset = (Var->getRegNum() == Target->getFrameReg()) |
| + ? Target->getFrameFixedAllocaOffset() |
| + : 0; |
| + |
| + const int32_t Offset = Var->getStackOffset() + ExtraOffset; |
| + Variable *Base = Target->getPhysicalRegister(Var->getRegNum()); |
| + Variable *T = newBaseRegister(Base, Offset, Dest->getRegNum()); |
| + Target->_mov(Dest, T); |
| + Legalized = true; |
| + } else { |
| + if (!Var->hasReg()) { |
| + UnimplementedError(getFlags()); |
| + return; |
| + } |
| + } |
| + } |
| + |
| + if (Legalized) { |
| + if (MovInstr->isDestRedefined()) { |
| + Target->_set_dest_redefined(); |
| + } |
| + MovInstr->setDeleted(); |
| + } |
| +} |
| + |
| +void TargetMIPS32::postLowerLegalization() { |
| + Func->dump("Before postLowerLegalization"); |
| + assert(hasComputedFrame()); |
| + for (CfgNode *Node : Func->getNodes()) { |
| + Context.init(Node); |
| + PostLoweringLegalizer Legalizer(this); |
| + 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)) { |
| + Legalizer.legalizeMov(MovInstr); |
| + } |
| + } |
| + } |
| +} |
| + |
| Operand *TargetMIPS32::loOperand(Operand *Operand) { |
| assert(Operand->getType() == IceType_i64); |
| if (auto *Var64On32 = llvm::dyn_cast<Variable64On32>(Operand)) |
| @@ -1417,6 +1507,12 @@ void TargetMIPS32::lowerArithmetic(const InstArithmetic *Instr) { |
| void TargetMIPS32::lowerAssign(const InstAssign *Instr) { |
| Variable *Dest = Instr->getDest(); |
| + |
| + if (Dest->isRematerializable()) { |
| + Context.insert<InstFakeDef>(Dest); |
| + return; |
| + } |
| + |
| Operand *Src0 = Instr->getSrc(0); |
| assert(Dest->getType() == Src0->getType()); |
| if (Dest->getType() == IceType_i64) { |