OLD | NEW |
1 // | 1 // |
2 // The Subzero Code Generator | 2 // The Subzero Code Generator |
3 // | 3 // |
4 // This file is distributed under the University of Illinois Open Source | 4 // This file is distributed under the University of Illinois Open Source |
5 // License. See LICENSE.TXT for details. | 5 // License. See LICENSE.TXT for details. |
6 // | 6 // |
7 //===----------------------------------------------------------------------===// | 7 //===----------------------------------------------------------------------===// |
8 /// | 8 /// |
9 /// \file | 9 /// \file |
10 /// \brief Implements the TargetLoweringMIPS32 class, which consists almost | 10 /// \brief Implements the TargetLoweringMIPS32 class, which consists almost |
(...skipping 1511 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1522 Variable *Base, int32_t Offset, RegNumT ScratchRegNum) { | 1522 Variable *Base, int32_t Offset, RegNumT ScratchRegNum) { |
1523 // Legalize will likely need a lui/ori combination, but if the top bits are | 1523 // Legalize will likely need a lui/ori combination, but if the top bits are |
1524 // all 0 from negating the offset and subtracting, we could use that instead. | 1524 // all 0 from negating the offset and subtracting, we could use that instead. |
1525 const bool ShouldSub = Offset != 0 && (-Offset & 0xFFFF0000) == 0; | 1525 const bool ShouldSub = Offset != 0 && (-Offset & 0xFFFF0000) == 0; |
1526 Variable *ScratchReg = Target->makeReg(IceType_i32, ScratchRegNum); | 1526 Variable *ScratchReg = Target->makeReg(IceType_i32, ScratchRegNum); |
1527 if (ShouldSub) { | 1527 if (ShouldSub) { |
1528 Variable *OffsetVal = Target->legalizeToReg( | 1528 Variable *OffsetVal = Target->legalizeToReg( |
1529 Target->Ctx->getConstantInt32(-Offset), ScratchRegNum); | 1529 Target->Ctx->getConstantInt32(-Offset), ScratchRegNum); |
1530 Target->_sub(ScratchReg, Base, OffsetVal); | 1530 Target->_sub(ScratchReg, Base, OffsetVal); |
1531 } else { | 1531 } else { |
1532 Target->_addiu(ScratchReg, Base, Offset); | 1532 constexpr bool SignExt = true; |
| 1533 if (!OperandMIPS32Mem::canHoldOffset(Base->getType(), SignExt, Offset)) { |
| 1534 const uint32_t UpperBits = (Offset >> 16) & 0xFFFF; |
| 1535 const uint32_t LowerBits = Offset & 0xFFFF; |
| 1536 Target->_lui(ScratchReg, Target->Ctx->getConstantInt32(UpperBits)); |
| 1537 if (LowerBits) |
| 1538 Target->_ori(ScratchReg, ScratchReg, LowerBits); |
| 1539 Target->_addu(ScratchReg, ScratchReg, Base); |
| 1540 } else { |
| 1541 Target->_addiu(ScratchReg, Base, Offset); |
| 1542 } |
1533 } | 1543 } |
1534 | 1544 |
1535 return ScratchReg; | 1545 return ScratchReg; |
1536 } | 1546 } |
1537 | 1547 |
1538 void TargetMIPS32::PostLoweringLegalizer::legalizeMov(InstMIPS32Mov *MovInstr) { | 1548 void TargetMIPS32::PostLoweringLegalizer::legalizeMov(InstMIPS32Mov *MovInstr) { |
1539 Variable *Dest = MovInstr->getDest(); | 1549 Variable *Dest = MovInstr->getDest(); |
1540 assert(Dest != nullptr); | 1550 assert(Dest != nullptr); |
1541 const Type DestTy = Dest->getType(); | 1551 const Type DestTy = Dest->getType(); |
1542 assert(DestTy != IceType_i64); | 1552 assert(DestTy != IceType_i64); |
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1724 } | 1734 } |
1725 | 1735 |
1726 if (Legalized) { | 1736 if (Legalized) { |
1727 if (MovInstr->isDestRedefined()) { | 1737 if (MovInstr->isDestRedefined()) { |
1728 Target->_set_dest_redefined(); | 1738 Target->_set_dest_redefined(); |
1729 } | 1739 } |
1730 MovInstr->setDeleted(); | 1740 MovInstr->setDeleted(); |
1731 } | 1741 } |
1732 } | 1742 } |
1733 | 1743 |
| 1744 OperandMIPS32Mem * |
| 1745 TargetMIPS32::PostLoweringLegalizer::legalizeMemOperand(OperandMIPS32Mem *Mem) { |
| 1746 if (llvm::isa<ConstantRelocatable>(Mem->getOffset())) { |
| 1747 return nullptr; |
| 1748 } |
| 1749 Variable *Base = Mem->getBase(); |
| 1750 auto *Ci32 = llvm::cast<ConstantInteger32>(Mem->getOffset()); |
| 1751 int32_t Offset = Ci32->getValue(); |
| 1752 |
| 1753 if (Base->isRematerializable()) { |
| 1754 const int32_t ExtraOffset = |
| 1755 (Base->getRegNum() == Target->getFrameOrStackReg()) |
| 1756 ? Target->getFrameFixedAllocaOffset() |
| 1757 : 0; |
| 1758 Offset += Base->getStackOffset() + ExtraOffset; |
| 1759 Base = Target->getPhysicalRegister(Base->getRegNum()); |
| 1760 } |
| 1761 |
| 1762 constexpr bool SignExt = true; |
| 1763 if (!OperandMIPS32Mem::canHoldOffset(Mem->getType(), SignExt, Offset)) { |
| 1764 Base = newBaseRegister(Base, Offset, Target->getReservedTmpReg()); |
| 1765 Offset = 0; |
| 1766 } |
| 1767 |
| 1768 return OperandMIPS32Mem::create( |
| 1769 Target->Func, Mem->getType(), Base, |
| 1770 llvm::cast<ConstantInteger32>(Target->Ctx->getConstantInt32(Offset))); |
| 1771 } |
| 1772 |
1734 void TargetMIPS32::postLowerLegalization() { | 1773 void TargetMIPS32::postLowerLegalization() { |
1735 Func->dump("Before postLowerLegalization"); | 1774 Func->dump("Before postLowerLegalization"); |
1736 assert(hasComputedFrame()); | 1775 assert(hasComputedFrame()); |
1737 for (CfgNode *Node : Func->getNodes()) { | 1776 for (CfgNode *Node : Func->getNodes()) { |
1738 Context.init(Node); | 1777 Context.init(Node); |
1739 PostLoweringLegalizer Legalizer(this); | 1778 PostLoweringLegalizer Legalizer(this); |
1740 while (!Context.atEnd()) { | 1779 while (!Context.atEnd()) { |
1741 PostIncrLoweringContext PostIncrement(Context); | 1780 PostIncrLoweringContext PostIncrement(Context); |
1742 Inst *CurInstr = iteratorToInst(Context.getCur()); | 1781 Inst *CurInstr = iteratorToInst(Context.getCur()); |
1743 | 1782 const SizeT NumSrcs = CurInstr->getSrcSize(); |
1744 // TODO(sagar.thakur): Add remaining cases of legalization. | 1783 Operand *Src0 = NumSrcs < 1 ? nullptr : CurInstr->getSrc(0); |
1745 | 1784 Operand *Src1 = NumSrcs < 2 ? nullptr : CurInstr->getSrc(1); |
| 1785 auto *Src0V = llvm::dyn_cast_or_null<Variable>(Src0); |
| 1786 auto *Src0M = llvm::dyn_cast_or_null<OperandMIPS32Mem>(Src0); |
| 1787 auto *Src1M = llvm::dyn_cast_or_null<OperandMIPS32Mem>(Src1); |
| 1788 Variable *Dst = CurInstr->getDest(); |
1746 if (auto *MovInstr = llvm::dyn_cast<InstMIPS32Mov>(CurInstr)) { | 1789 if (auto *MovInstr = llvm::dyn_cast<InstMIPS32Mov>(CurInstr)) { |
1747 Legalizer.legalizeMov(MovInstr); | 1790 Legalizer.legalizeMov(MovInstr); |
| 1791 continue; |
| 1792 } |
| 1793 if (llvm::isa<InstMIPS32Sw>(CurInstr)) { |
| 1794 if (auto *LegalMem = Legalizer.legalizeMemOperand(Src1M)) { |
| 1795 _sw(Src0V, LegalMem); |
| 1796 CurInstr->setDeleted(); |
| 1797 } |
| 1798 continue; |
| 1799 } |
| 1800 if (llvm::isa<InstMIPS32Swc1>(CurInstr)) { |
| 1801 if (auto *LegalMem = Legalizer.legalizeMemOperand(Src1M)) { |
| 1802 _swc1(Src0V, LegalMem); |
| 1803 CurInstr->setDeleted(); |
| 1804 } |
| 1805 continue; |
| 1806 } |
| 1807 if (llvm::isa<InstMIPS32Sdc1>(CurInstr)) { |
| 1808 if (auto *LegalMem = Legalizer.legalizeMemOperand(Src1M)) { |
| 1809 _sdc1(Src0V, LegalMem); |
| 1810 CurInstr->setDeleted(); |
| 1811 } |
| 1812 continue; |
| 1813 } |
| 1814 if (llvm::isa<InstMIPS32Lw>(CurInstr)) { |
| 1815 if (auto *LegalMem = Legalizer.legalizeMemOperand(Src0M)) { |
| 1816 _lw(Dst, LegalMem); |
| 1817 CurInstr->setDeleted(); |
| 1818 } |
| 1819 continue; |
| 1820 } |
| 1821 if (llvm::isa<InstMIPS32Lwc1>(CurInstr)) { |
| 1822 if (auto *LegalMem = Legalizer.legalizeMemOperand(Src0M)) { |
| 1823 _lwc1(Dst, LegalMem); |
| 1824 CurInstr->setDeleted(); |
| 1825 } |
| 1826 continue; |
| 1827 } |
| 1828 if (llvm::isa<InstMIPS32Ldc1>(CurInstr)) { |
| 1829 if (auto *LegalMem = Legalizer.legalizeMemOperand(Src0M)) { |
| 1830 _ldc1(Dst, LegalMem); |
| 1831 CurInstr->setDeleted(); |
| 1832 } |
| 1833 continue; |
1748 } | 1834 } |
1749 } | 1835 } |
1750 } | 1836 } |
1751 } | 1837 } |
1752 | 1838 |
1753 Operand *TargetMIPS32::loOperand(Operand *Operand) { | 1839 Operand *TargetMIPS32::loOperand(Operand *Operand) { |
1754 assert(Operand->getType() == IceType_i64); | 1840 assert(Operand->getType() == IceType_i64); |
1755 if (auto *Var64On32 = llvm::dyn_cast<Variable64On32>(Operand)) | 1841 if (auto *Var64On32 = llvm::dyn_cast<Variable64On32>(Operand)) |
1756 return Var64On32->getLo(); | 1842 return Var64On32->getLo(); |
1757 if (auto *Const = llvm::dyn_cast<ConstantInteger64>(Operand)) { | 1843 if (auto *Const = llvm::dyn_cast<ConstantInteger64>(Operand)) { |
(...skipping 3242 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5000 Str << "\t.set\t" | 5086 Str << "\t.set\t" |
5001 << "nomips16\n"; | 5087 << "nomips16\n"; |
5002 } | 5088 } |
5003 | 5089 |
5004 SmallBitVector TargetMIPS32::TypeToRegisterSet[RCMIPS32_NUM]; | 5090 SmallBitVector TargetMIPS32::TypeToRegisterSet[RCMIPS32_NUM]; |
5005 SmallBitVector TargetMIPS32::TypeToRegisterSetUnfiltered[RCMIPS32_NUM]; | 5091 SmallBitVector TargetMIPS32::TypeToRegisterSetUnfiltered[RCMIPS32_NUM]; |
5006 SmallBitVector TargetMIPS32::RegisterAliases[RegMIPS32::Reg_NUM]; | 5092 SmallBitVector TargetMIPS32::RegisterAliases[RegMIPS32::Reg_NUM]; |
5007 | 5093 |
5008 } // end of namespace MIPS32 | 5094 } // end of namespace MIPS32 |
5009 } // end of namespace Ice | 5095 } // end of namespace Ice |
OLD | NEW |