Chromium Code Reviews| 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 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 108 | 108 |
| 109 void TargetMIPS32::assignVarStackSlots(VarList &SortedSpilledVariables, | 109 void TargetMIPS32::assignVarStackSlots(VarList &SortedSpilledVariables, |
| 110 size_t SpillAreaPaddingBytes, | 110 size_t SpillAreaPaddingBytes, |
| 111 size_t SpillAreaSizeBytes, | 111 size_t SpillAreaSizeBytes, |
| 112 size_t GlobalsAndSubsequentPaddingSize) { | 112 size_t GlobalsAndSubsequentPaddingSize) { |
| 113 const VariablesMetadata *VMetadata = Func->getVMetadata(); | 113 const VariablesMetadata *VMetadata = Func->getVMetadata(); |
| 114 size_t GlobalsSpaceUsed = SpillAreaPaddingBytes; | 114 size_t GlobalsSpaceUsed = SpillAreaPaddingBytes; |
| 115 size_t NextStackOffset = SpillAreaPaddingBytes; | 115 size_t NextStackOffset = SpillAreaPaddingBytes; |
| 116 CfgVector<size_t> LocalsSize(Func->getNumNodes()); | 116 CfgVector<size_t> LocalsSize(Func->getNumNodes()); |
| 117 const bool SimpleCoalescing = !callsReturnsTwice(); | 117 const bool SimpleCoalescing = !callsReturnsTwice(); |
| 118 | |
| 119 for (Variable *Var : SortedSpilledVariables) { | 118 for (Variable *Var : SortedSpilledVariables) { |
| 120 size_t Increment = typeWidthInBytesOnStack(Var->getType()); | 119 size_t Increment = typeWidthInBytesOnStack(Var->getType()); |
| 121 if (SimpleCoalescing && VMetadata->isTracked(Var)) { | 120 if (SimpleCoalescing && VMetadata->isTracked(Var)) { |
| 122 if (VMetadata->isMultiBlock(Var)) { | 121 if (VMetadata->isMultiBlock(Var)) { |
| 123 GlobalsSpaceUsed += Increment; | 122 GlobalsSpaceUsed += Increment; |
| 124 NextStackOffset = GlobalsSpaceUsed; | 123 NextStackOffset = GlobalsSpaceUsed; |
| 125 } else { | 124 } else { |
| 126 SizeT NodeIndex = VMetadata->getLocalUseNode(Var)->getIndex(); | 125 SizeT NodeIndex = VMetadata->getLocalUseNode(Var)->getIndex(); |
| 127 LocalsSize[NodeIndex] += Increment; | 126 LocalsSize[NodeIndex] += Increment; |
| 128 NextStackOffset = SpillAreaPaddingBytes + | 127 NextStackOffset = SpillAreaPaddingBytes + |
| (...skipping 1605 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1734 } else { | 1733 } else { |
| 1735 // Split it into two mtc1 instructions | 1734 // Split it into two mtc1 instructions |
| 1736 if (MovInstr->getSrcSize() == 2) { | 1735 if (MovInstr->getSrcSize() == 2) { |
| 1737 const auto FirstReg = | 1736 const auto FirstReg = |
| 1738 (llvm::cast<Variable>(MovInstr->getSrc(0)))->getRegNum(); | 1737 (llvm::cast<Variable>(MovInstr->getSrc(0)))->getRegNum(); |
| 1739 const auto SecondReg = | 1738 const auto SecondReg = |
| 1740 (llvm::cast<Variable>(MovInstr->getSrc(1)))->getRegNum(); | 1739 (llvm::cast<Variable>(MovInstr->getSrc(1)))->getRegNum(); |
| 1741 SrcGPRHi = Target->makeReg(IceType_i32, FirstReg); | 1740 SrcGPRHi = Target->makeReg(IceType_i32, FirstReg); |
| 1742 SrcGPRLo = Target->makeReg(IceType_i32, SecondReg); | 1741 SrcGPRLo = Target->makeReg(IceType_i32, SecondReg); |
| 1743 } else { | 1742 } else { |
| 1743 SrcGPRLo = Target->makeReg( | |
| 1744 IceType_i32, RegMIPS32::get64PairFirstRegNum(SRegNum)); | |
| 1744 SrcGPRHi = Target->makeReg( | 1745 SrcGPRHi = Target->makeReg( |
| 1745 IceType_i32, RegMIPS32::get64PairFirstRegNum(SRegNum)); | |
| 1746 SrcGPRLo = Target->makeReg( | |
| 1747 IceType_i32, RegMIPS32::get64PairSecondRegNum(SRegNum)); | 1746 IceType_i32, RegMIPS32::get64PairSecondRegNum(SRegNum)); |
| 1748 } | 1747 } |
| 1749 } | 1748 } |
| 1750 Variable *DstFPRHi = Target->makeReg( | 1749 Variable *DstFPRHi = Target->makeReg( |
| 1751 IceType_f32, RegMIPS32::get64PairFirstRegNum(DRegNum)); | 1750 IceType_f32, RegMIPS32::get64PairFirstRegNum(DRegNum)); |
| 1752 Variable *DstFPRLo = Target->makeReg( | 1751 Variable *DstFPRLo = Target->makeReg( |
| 1753 IceType_f32, RegMIPS32::get64PairSecondRegNum(DRegNum)); | 1752 IceType_f32, RegMIPS32::get64PairSecondRegNum(DRegNum)); |
| 1754 Target->_mov(DstFPRHi, SrcGPRLo); | 1753 Target->_mov(DstFPRHi, SrcGPRLo); |
| 1755 Target->_mov(DstFPRLo, SrcGPRHi); | 1754 Target->_mov(DstFPRLo, SrcGPRHi); |
| 1756 Legalized = true; | 1755 Legalized = true; |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 1768 } | 1767 } |
| 1769 MovInstr->setDeleted(); | 1768 MovInstr->setDeleted(); |
| 1770 return; | 1769 return; |
| 1771 } | 1770 } |
| 1772 } | 1771 } |
| 1773 | 1772 |
| 1774 if (!Dest->hasReg()) { | 1773 if (!Dest->hasReg()) { |
| 1775 auto *SrcR = llvm::cast<Variable>(Src); | 1774 auto *SrcR = llvm::cast<Variable>(Src); |
| 1776 assert(SrcR->hasReg()); | 1775 assert(SrcR->hasReg()); |
| 1777 assert(!SrcR->isRematerializable()); | 1776 assert(!SrcR->isRematerializable()); |
| 1778 int32_t Offset = 0; | 1777 int32_t Offset = Dest->getStackOffset(); |
| 1779 | |
| 1780 if (MovInstr->getDestHi() != nullptr) | |
| 1781 Offset = MovInstr->getDestHi()->getStackOffset(); | |
| 1782 else | |
| 1783 Offset = Dest->getStackOffset(); | |
| 1784 | 1778 |
| 1785 // This is a _mov(Mem(), Variable), i.e., a store. | 1779 // This is a _mov(Mem(), Variable), i.e., a store. |
| 1786 auto *Base = Target->getPhysicalRegister(Target->getFrameOrStackReg()); | 1780 auto *Base = Target->getPhysicalRegister(Target->getFrameOrStackReg()); |
| 1787 | 1781 |
| 1788 OperandMIPS32Mem *Addr = OperandMIPS32Mem::create( | 1782 OperandMIPS32Mem *TAddr = OperandMIPS32Mem::create( |
| 1789 Target->Func, DestTy, Base, | 1783 Target->Func, DestTy, Base, |
| 1790 llvm::cast<ConstantInteger32>(Target->Ctx->getConstantInt32(Offset))); | 1784 llvm::cast<ConstantInteger32>(Target->Ctx->getConstantInt32(Offset))); |
| 1785 OperandMIPS32Mem *TAddrHi = OperandMIPS32Mem::create( | |
| 1786 Target->Func, DestTy, Base, | |
| 1787 llvm::cast<ConstantInteger32>( | |
| 1788 Target->Ctx->getConstantInt32(Offset + 4))); | |
| 1789 OperandMIPS32Mem *Addr = legalizeMemOperand(TAddr); | |
| 1791 | 1790 |
| 1792 // FP arguments are passed in GP reg if first argument is in GP. In this | 1791 // FP arguments are passed in GP reg if first argument is in GP. In this |
| 1793 // case type of the SrcR is still FP thus we need to explicitly generate sw | 1792 // case type of the SrcR is still FP thus we need to explicitly generate sw |
| 1794 // instead of swc1. | 1793 // instead of swc1. |
| 1795 const RegNumT RegNum = SrcR->getRegNum(); | 1794 const RegNumT RegNum = SrcR->getRegNum(); |
| 1796 const bool IsSrcGPReg = RegMIPS32::isGPRReg(SrcR->getRegNum()); | 1795 const bool IsSrcGPReg = RegMIPS32::isGPRReg(SrcR->getRegNum()); |
| 1797 if (SrcTy == IceType_f32 && IsSrcGPReg) { | 1796 if (SrcTy == IceType_f32 && IsSrcGPReg) { |
| 1798 Variable *SrcGPR = Target->makeReg(IceType_i32, RegNum); | 1797 Variable *SrcGPR = Target->makeReg(IceType_i32, RegNum); |
| 1799 Target->_sw(SrcGPR, Addr); | 1798 Target->_sw(SrcGPR, Addr); |
| 1800 } else if (SrcTy == IceType_f64 && IsSrcGPReg) { | 1799 } else if (SrcTy == IceType_f64 && IsSrcGPReg) { |
| 1801 Variable *SrcGPRHi = | 1800 Variable *SrcGPRHi = |
| 1802 Target->makeReg(IceType_i32, RegMIPS32::get64PairFirstRegNum(RegNum)); | 1801 Target->makeReg(IceType_i32, RegMIPS32::get64PairFirstRegNum(RegNum)); |
| 1803 Variable *SrcGPRLo = Target->makeReg( | 1802 Variable *SrcGPRLo = Target->makeReg( |
| 1804 IceType_i32, RegMIPS32::get64PairSecondRegNum(RegNum)); | 1803 IceType_i32, RegMIPS32::get64PairSecondRegNum(RegNum)); |
| 1805 OperandMIPS32Mem *AddrHi = OperandMIPS32Mem::create( | 1804 Target->_sw(SrcGPRHi, Addr); |
| 1806 Target->Func, DestTy, Base, | 1805 OperandMIPS32Mem *AddrHi = legalizeMemOperand(TAddrHi); |
| 1807 llvm::cast<ConstantInteger32>( | 1806 Target->_sw(SrcGPRLo, AddrHi); |
| 1808 Target->Ctx->getConstantInt32(Offset + 4))); | |
| 1809 Target->_sw(SrcGPRLo, Addr); | |
| 1810 Target->_sw(SrcGPRHi, AddrHi); | |
| 1811 } else if (DestTy == IceType_f64 && IsSrcGPReg) { | 1807 } else if (DestTy == IceType_f64 && IsSrcGPReg) { |
| 1812 const auto FirstReg = | 1808 const auto FirstReg = |
| 1813 (llvm::cast<Variable>(MovInstr->getSrc(0)))->getRegNum(); | 1809 (llvm::cast<Variable>(MovInstr->getSrc(0)))->getRegNum(); |
| 1814 const auto SecondReg = | 1810 const auto SecondReg = |
| 1815 (llvm::cast<Variable>(MovInstr->getSrc(1)))->getRegNum(); | 1811 (llvm::cast<Variable>(MovInstr->getSrc(1)))->getRegNum(); |
| 1816 Variable *SrcGPRHi = Target->makeReg(IceType_i32, SecondReg); | 1812 Variable *SrcGPRHi = Target->makeReg(IceType_i32, FirstReg); |
| 1817 Variable *SrcGPRLo = Target->makeReg(IceType_i32, FirstReg); | 1813 Variable *SrcGPRLo = Target->makeReg(IceType_i32, SecondReg); |
| 1818 OperandMIPS32Mem *AddrHi = OperandMIPS32Mem::create( | |
| 1819 Target->Func, DestTy, Base, | |
| 1820 llvm::cast<ConstantInteger32>( | |
| 1821 Target->Ctx->getConstantInt32(Offset + 4))); | |
| 1822 Target->_sw(SrcGPRLo, Addr); | 1814 Target->_sw(SrcGPRLo, Addr); |
| 1815 OperandMIPS32Mem *AddrHi = legalizeMemOperand(TAddrHi); | |
| 1823 Target->_sw(SrcGPRHi, AddrHi); | 1816 Target->_sw(SrcGPRHi, AddrHi); |
| 1824 } else { | 1817 } else { |
| 1825 Target->_sw(SrcR, Addr); | 1818 Target->_sw(SrcR, Addr); |
| 1826 } | 1819 } |
| 1827 | 1820 |
| 1828 Target->Context.insert<InstFakeDef>(Dest); | 1821 Target->Context.insert<InstFakeDef>(Dest); |
| 1829 Legalized = true; | 1822 Legalized = true; |
| 1830 } else if (auto *Var = llvm::dyn_cast<Variable>(Src)) { | 1823 } else if (auto *Var = llvm::dyn_cast<Variable>(Src)) { |
| 1831 if (Var->isRematerializable()) { | 1824 if (Var->isRematerializable()) { |
| 1832 // This is equivalent to an x86 _lea(RematOffset(%esp/%ebp), Variable). | 1825 // This is equivalent to an x86 _lea(RematOffset(%esp/%ebp), Variable). |
| 1833 | 1826 |
| 1834 // ExtraOffset is only needed for stack-pointer based frames as we have | 1827 // ExtraOffset is only needed for stack-pointer based frames as we have |
| 1835 // to account for spill storage. | 1828 // to account for spill storage. |
| 1836 const int32_t ExtraOffset = (Var->getRegNum() == Target->getStackReg()) | 1829 const int32_t ExtraOffset = (Var->getRegNum() == Target->getStackReg()) |
| 1837 ? Target->getFrameFixedAllocaOffset() | 1830 ? Target->getFrameFixedAllocaOffset() |
| 1838 : 0; | 1831 : 0; |
| 1839 | 1832 |
| 1840 const int32_t Offset = Var->getStackOffset() + ExtraOffset; | 1833 const int32_t Offset = Var->getStackOffset() + ExtraOffset; |
| 1841 Variable *Base = Target->getPhysicalRegister(Var->getRegNum()); | 1834 Variable *Base = Target->getPhysicalRegister(Var->getRegNum()); |
| 1842 Variable *T = newBaseRegister(Base, Offset, Dest->getRegNum()); | 1835 Variable *T = newBaseRegister(Base, Offset, Dest->getRegNum()); |
| 1843 Target->_mov(Dest, T); | 1836 Target->_mov(Dest, T); |
| 1844 Legalized = true; | 1837 Legalized = true; |
| 1845 } else { | 1838 } else { |
| 1846 if (!Var->hasReg()) { | 1839 if (!Var->hasReg()) { |
| 1847 // This is a _mov(Variable, Mem()), i.e., a load. | 1840 // This is a _mov(Variable, Mem()), i.e., a load. |
| 1848 const int32_t Offset = Var->getStackOffset(); | 1841 const int32_t Offset = Var->getStackOffset(); |
| 1849 auto *Base = Target->getPhysicalRegister(Target->getFrameOrStackReg()); | 1842 auto *Base = Target->getPhysicalRegister(Target->getFrameOrStackReg()); |
| 1850 OperandMIPS32Mem *Addr; | 1843 const RegNumT RegNum = Dest->getRegNum(); |
| 1851 Addr = OperandMIPS32Mem::create( | 1844 const bool IsDstGPReg = RegMIPS32::isGPRReg(Dest->getRegNum()); |
| 1852 Target->Func, DestTy, Base, | 1845 // If we are moving i64 to a double using stack then the address may |
| 1853 llvm::cast<ConstantInteger32>( | 1846 // not be aligned to 8-byte boundary as we split i64 into Hi-Lo parts |
| 1854 Target->Ctx->getConstantInt32(Offset))); | 1847 // and store them individually with 4-byte alignment. Load the Hi-Lo |
| 1855 Target->_lw(Dest, Addr); | 1848 // parts in TmpReg and move them to the dest using mtc1. |
| 1849 if (DestTy == IceType_f64 && (Offset & 7) && IsDstGPReg == false) { | |
|
Jim Stichnoth
2016/10/21 14:18:56
Can you use Utils::IsAligned() for the alignment c
Jim Stichnoth
2016/10/21 14:18:56
"!IsDstGPReg" instead of "IsDstGPReg == false"
jaydeep.patil
2016/10/26 07:47:31
Done.
jaydeep.patil
2016/10/26 07:47:31
Done.
| |
| 1850 auto *Reg = Target->makeReg(IceType_i32, Target->getReservedTmpReg()); | |
| 1851 const RegNumT RegNum = Dest->getRegNum(); | |
| 1852 Variable *DestLo = Target->makeReg( | |
| 1853 IceType_f32, RegMIPS32::get64PairFirstRegNum(RegNum)); | |
| 1854 Variable *DestHi = Target->makeReg( | |
| 1855 IceType_f32, RegMIPS32::get64PairSecondRegNum(RegNum)); | |
| 1856 OperandMIPS32Mem *AddrLo = OperandMIPS32Mem::create( | |
| 1857 Target->Func, IceType_i32, Base, | |
| 1858 llvm::cast<ConstantInteger32>( | |
| 1859 Target->Ctx->getConstantInt32(Offset))); | |
| 1860 OperandMIPS32Mem *AddrHi = OperandMIPS32Mem::create( | |
| 1861 Target->Func, IceType_i32, Base, | |
| 1862 llvm::cast<ConstantInteger32>( | |
| 1863 Target->Ctx->getConstantInt32(Offset + 4))); | |
| 1864 Target->_lw(Reg, AddrLo); | |
| 1865 Target->_mov(DestLo, Reg); | |
| 1866 Target->_lw(Reg, AddrHi); | |
| 1867 Target->_mov(DestHi, Reg); | |
| 1868 } else { | |
| 1869 OperandMIPS32Mem *TAddr = OperandMIPS32Mem::create( | |
| 1870 Target->Func, DestTy, Base, llvm::cast<ConstantInteger32>( | |
| 1871 Target->Ctx->getConstantInt32(Offset))); | |
| 1872 OperandMIPS32Mem *Addr = legalizeMemOperand(TAddr); | |
| 1873 OperandMIPS32Mem *TAddrHi = OperandMIPS32Mem::create( | |
| 1874 Target->Func, DestTy, Base, llvm::cast<ConstantInteger32>( | |
| 1875 Target->Ctx->getConstantInt32(Offset + 4))); | |
| 1876 // FP arguments are passed in GP reg if first argument is in GP. | |
| 1877 // In this case type of the Dest is still FP thus we need to | |
| 1878 // explicitly generate lw instead of lwc1. | |
| 1879 if (DestTy == IceType_f32 && IsDstGPReg) { | |
| 1880 Variable *DstGPR = Target->makeReg(IceType_i32, RegNum); | |
| 1881 Target->_lw(DstGPR, Addr); | |
| 1882 } else if (DestTy == IceType_f64 && IsDstGPReg) { | |
| 1883 Variable *DstGPRHi = Target->makeReg( | |
| 1884 IceType_i32, RegMIPS32::get64PairFirstRegNum(RegNum)); | |
| 1885 Variable *DstGPRLo = Target->makeReg( | |
| 1886 IceType_i32, RegMIPS32::get64PairSecondRegNum(RegNum)); | |
| 1887 Target->_lw(DstGPRHi, Addr); | |
| 1888 OperandMIPS32Mem *AddrHi = legalizeMemOperand(TAddrHi); | |
| 1889 Target->_lw(DstGPRLo, AddrHi); | |
| 1890 } else if (DestTy == IceType_f64 && IsDstGPReg) { | |
| 1891 const auto FirstReg = | |
| 1892 (llvm::cast<Variable>(MovInstr->getSrc(0)))->getRegNum(); | |
| 1893 const auto SecondReg = | |
| 1894 (llvm::cast<Variable>(MovInstr->getSrc(1)))->getRegNum(); | |
| 1895 Variable *DstGPRHi = Target->makeReg(IceType_i32, FirstReg); | |
| 1896 Variable *DstGPRLo = Target->makeReg(IceType_i32, SecondReg); | |
| 1897 Target->_lw(DstGPRLo, Addr); | |
| 1898 OperandMIPS32Mem *AddrHi = legalizeMemOperand(TAddrHi); | |
| 1899 Target->_lw(DstGPRHi, AddrHi); | |
| 1900 } else { | |
| 1901 Target->_lw(Dest, Addr); | |
| 1902 } | |
| 1903 } | |
| 1856 Legalized = true; | 1904 Legalized = true; |
| 1857 } | 1905 } |
| 1858 } | 1906 } |
| 1859 } | 1907 } |
| 1860 | 1908 |
| 1861 if (Legalized) { | 1909 if (Legalized) { |
| 1862 if (MovInstr->isDestRedefined()) { | 1910 if (MovInstr->isDestRedefined()) { |
| 1863 Target->_set_dest_redefined(); | 1911 Target->_set_dest_redefined(); |
| 1864 } | 1912 } |
| 1865 MovInstr->setDeleted(); | 1913 MovInstr->setDeleted(); |
| (...skipping 663 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2529 _mul(T, Src0R, Src1R); | 2577 _mul(T, Src0R, Src1R); |
| 2530 _mov(Dest, T); | 2578 _mov(Dest, T); |
| 2531 return; | 2579 return; |
| 2532 } | 2580 } |
| 2533 case InstArithmetic::Shl: { | 2581 case InstArithmetic::Shl: { |
| 2534 _sllv(T, Src0R, Src1R); | 2582 _sllv(T, Src0R, Src1R); |
| 2535 _mov(Dest, T); | 2583 _mov(Dest, T); |
| 2536 return; | 2584 return; |
| 2537 } | 2585 } |
| 2538 case InstArithmetic::Lshr: { | 2586 case InstArithmetic::Lshr: { |
| 2539 _srlv(T, Src0R, Src1R); | 2587 auto *T0R = Src0R; |
| 2588 auto *T1R = Src1R; | |
| 2589 if (Dest->getType() != IceType_i32) { | |
| 2590 T0R = makeReg(IceType_i32); | |
| 2591 lowerCast(InstCast::create(Func, InstCast::Zext, T0R, Src0R)); | |
| 2592 T1R = makeReg(IceType_i32); | |
| 2593 lowerCast(InstCast::create(Func, InstCast::Zext, T1R, Src1R)); | |
| 2594 } | |
| 2595 _srlv(T, T0R, T1R); | |
| 2540 _mov(Dest, T); | 2596 _mov(Dest, T); |
| 2541 return; | 2597 return; |
| 2542 } | 2598 } |
| 2543 case InstArithmetic::Ashr: { | 2599 case InstArithmetic::Ashr: { |
| 2544 _srav(T, Src0R, Src1R); | 2600 _srav(T, Src0R, Src1R); |
| 2545 _mov(Dest, T); | 2601 _mov(Dest, T); |
| 2546 return; | 2602 return; |
| 2547 } | 2603 } |
| 2548 case InstArithmetic::Udiv: { | 2604 case InstArithmetic::Udiv: { |
| 2549 auto *T_Zero = I32Reg(RegMIPS32::Reg_ZERO); | 2605 auto *T_Zero = I32Reg(RegMIPS32::Reg_ZERO); |
| 2550 _divu(T_Zero, Src0R, Src1R); | 2606 auto *T0R = Src0R; |
| 2551 _teq(Src1R, T_Zero, DivideByZeroTrapCode); // Trap if divide-by-zero | 2607 auto *T1R = Src1R; |
| 2608 if (Dest->getType() != IceType_i32) { | |
| 2609 T0R = makeReg(IceType_i32); | |
| 2610 lowerCast(InstCast::create(Func, InstCast::Zext, T0R, Src0R)); | |
| 2611 T1R = makeReg(IceType_i32); | |
| 2612 lowerCast(InstCast::create(Func, InstCast::Zext, T1R, Src1R)); | |
| 2613 } | |
| 2614 _divu(T_Zero, T0R, T1R); | |
| 2615 _teq(T1R, T_Zero, DivideByZeroTrapCode); // Trap if divide-by-zero | |
| 2552 _mflo(T, T_Zero); | 2616 _mflo(T, T_Zero); |
| 2553 _mov(Dest, T); | 2617 _mov(Dest, T); |
| 2554 return; | 2618 return; |
| 2555 } | 2619 } |
| 2556 case InstArithmetic::Sdiv: { | 2620 case InstArithmetic::Sdiv: { |
| 2557 auto *T_Zero = I32Reg(RegMIPS32::Reg_ZERO); | 2621 auto *T_Zero = I32Reg(RegMIPS32::Reg_ZERO); |
| 2558 _div(T_Zero, Src0R, Src1R); | 2622 _div(T_Zero, Src0R, Src1R); |
| 2559 _teq(Src1R, T_Zero, DivideByZeroTrapCode); // Trap if divide-by-zero | 2623 _teq(Src1R, T_Zero, DivideByZeroTrapCode); // Trap if divide-by-zero |
| 2560 _mflo(T, T_Zero); | 2624 _mflo(T, T_Zero); |
| 2561 _mov(Dest, T); | 2625 _mov(Dest, T); |
| 2562 return; | 2626 return; |
| 2563 } | 2627 } |
| 2564 case InstArithmetic::Urem: { | 2628 case InstArithmetic::Urem: { |
| 2565 auto *T_Zero = I32Reg(RegMIPS32::Reg_ZERO); | 2629 auto *T_Zero = I32Reg(RegMIPS32::Reg_ZERO); |
| 2566 _divu(T_Zero, Src0R, Src1R); | 2630 auto *T0R = Src0R; |
| 2567 _teq(Src1R, T_Zero, DivideByZeroTrapCode); // Trap if divide-by-zero | 2631 auto *T1R = Src1R; |
| 2632 if (Dest->getType() != IceType_i32) { | |
| 2633 T0R = makeReg(IceType_i32); | |
| 2634 lowerCast(InstCast::create(Func, InstCast::Zext, T0R, Src0R)); | |
| 2635 T1R = makeReg(IceType_i32); | |
| 2636 lowerCast(InstCast::create(Func, InstCast::Zext, T1R, Src1R)); | |
| 2637 } | |
| 2638 _divu(T_Zero, T0R, T1R); | |
| 2639 _teq(T1R, T_Zero, DivideByZeroTrapCode); // Trap if divide-by-zero | |
| 2568 _mfhi(T, T_Zero); | 2640 _mfhi(T, T_Zero); |
| 2569 _mov(Dest, T); | 2641 _mov(Dest, T); |
| 2570 return; | 2642 return; |
| 2571 } | 2643 } |
| 2572 case InstArithmetic::Srem: { | 2644 case InstArithmetic::Srem: { |
| 2573 auto *T_Zero = I32Reg(RegMIPS32::Reg_ZERO); | 2645 auto *T_Zero = I32Reg(RegMIPS32::Reg_ZERO); |
| 2574 _div(T_Zero, Src0R, Src1R); | 2646 _div(T_Zero, Src0R, Src1R); |
| 2575 _teq(Src1R, T_Zero, DivideByZeroTrapCode); // Trap if divide-by-zero | 2647 _teq(Src1R, T_Zero, DivideByZeroTrapCode); // Trap if divide-by-zero |
| 2576 _mfhi(T, T_Zero); | 2648 _mfhi(T, T_Zero); |
| 2577 _mov(Dest, T); | 2649 _mov(Dest, T); |
| (...skipping 763 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3341 UnimplementedLoweringError(this, Instr); | 3413 UnimplementedLoweringError(this, Instr); |
| 3342 break; | 3414 break; |
| 3343 } | 3415 } |
| 3344 case InstCast::Sitofp: | 3416 case InstCast::Sitofp: |
| 3345 case InstCast::Uitofp: { | 3417 case InstCast::Uitofp: { |
| 3346 if (llvm::isa<Variable64On32>(Dest)) { | 3418 if (llvm::isa<Variable64On32>(Dest)) { |
| 3347 llvm::report_fatal_error("i64-to-fp should have been prelowered."); | 3419 llvm::report_fatal_error("i64-to-fp should have been prelowered."); |
| 3348 return; | 3420 return; |
| 3349 } | 3421 } |
| 3350 if (Src0Ty != IceType_i64) { | 3422 if (Src0Ty != IceType_i64) { |
| 3423 Variable *Src0R = legalizeToReg(Src0); | |
| 3424 auto *T0R = Src0R; | |
| 3425 if (Src0Ty != IceType_i32 && CastKind == InstCast::Uitofp) { | |
| 3426 T0R = makeReg(IceType_i32); | |
| 3427 lowerCast(InstCast::create(Func, InstCast::Zext, T0R, Src0R)); | |
| 3428 } | |
| 3351 if (isScalarIntegerType(Src0Ty) && DestTy == IceType_f32) { | 3429 if (isScalarIntegerType(Src0Ty) && DestTy == IceType_f32) { |
| 3352 Variable *Src0R = legalizeToReg(Src0); | |
| 3353 Variable *FTmp1 = makeReg(IceType_f32); | 3430 Variable *FTmp1 = makeReg(IceType_f32); |
| 3354 Variable *FTmp2 = makeReg(IceType_f32); | 3431 Variable *FTmp2 = makeReg(IceType_f32); |
| 3355 _mtc1(FTmp1, Src0R); | 3432 _mtc1(FTmp1, T0R); |
| 3356 _cvt_s_w(FTmp2, FTmp1); | 3433 _cvt_s_w(FTmp2, FTmp1); |
| 3357 _mov(Dest, FTmp2); | 3434 _mov(Dest, FTmp2); |
| 3358 return; | 3435 return; |
| 3359 } | 3436 } |
| 3360 if (isScalarIntegerType(Src0Ty) && DestTy == IceType_f64) { | 3437 if (isScalarIntegerType(Src0Ty) && DestTy == IceType_f64) { |
| 3361 Variable *Src0R = legalizeToReg(Src0); | |
| 3362 Variable *FTmp1 = makeReg(IceType_f64); | 3438 Variable *FTmp1 = makeReg(IceType_f64); |
| 3363 Variable *FTmp2 = makeReg(IceType_f64); | 3439 Variable *FTmp2 = makeReg(IceType_f64); |
| 3364 _mtc1(FTmp1, Src0R); | 3440 _mtc1(FTmp1, T0R); |
| 3365 _cvt_d_w(FTmp2, FTmp1); | 3441 _cvt_d_w(FTmp2, FTmp1); |
| 3366 _mov(Dest, FTmp2); | 3442 _mov(Dest, FTmp2); |
| 3367 return; | 3443 return; |
| 3368 } | 3444 } |
| 3369 } | 3445 } |
| 3370 UnimplementedLoweringError(this, Instr); | 3446 UnimplementedLoweringError(this, Instr); |
| 3371 break; | 3447 break; |
| 3372 } | 3448 } |
| 3373 case InstCast::Bitcast: { | 3449 case InstCast::Bitcast: { |
| 3374 Operand *Src0 = Instr->getSrc(0); | 3450 Operand *Src0 = Instr->getSrc(0); |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 3401 break; | 3477 break; |
| 3402 case IceType_i32: | 3478 case IceType_i32: |
| 3403 case IceType_f32: { | 3479 case IceType_f32: { |
| 3404 Variable *Src0R = legalizeToReg(Src0); | 3480 Variable *Src0R = legalizeToReg(Src0); |
| 3405 _mov(Dest, Src0R); | 3481 _mov(Dest, Src0R); |
| 3406 break; | 3482 break; |
| 3407 } | 3483 } |
| 3408 case IceType_i64: { | 3484 case IceType_i64: { |
| 3409 assert(Src0->getType() == IceType_f64); | 3485 assert(Src0->getType() == IceType_f64); |
| 3410 Variable *Src0R = legalizeToReg(Src0); | 3486 Variable *Src0R = legalizeToReg(Src0); |
| 3411 auto *Dest64 = llvm::cast<Variable64On32>(Dest); | 3487 auto *T = llvm::cast<Variable64On32>(Func->makeVariable(IceType_i64)); |
| 3412 _mov(Dest64, Src0R); | 3488 T->initHiLo(Func); |
| 3489 T->getHi()->setMustHaveReg(); | |
| 3490 T->getLo()->setMustHaveReg(); | |
| 3491 _mov(T, Src0R); | |
| 3492 lowerAssign(InstAssign::create(Func, Dest, T)); | |
| 3413 break; | 3493 break; |
| 3414 } | 3494 } |
| 3415 case IceType_f64: { | 3495 case IceType_f64: { |
| 3416 assert(Src0->getType() == IceType_i64); | 3496 assert(Src0->getType() == IceType_i64); |
| 3417 const uint32_t Mask = 0xFFFFFFFF; | 3497 const uint32_t Mask = 0xFFFFFFFF; |
| 3418 if (auto *C64 = llvm::dyn_cast<ConstantInteger64>(Src0)) { | 3498 if (auto *C64 = llvm::dyn_cast<ConstantInteger64>(Src0)) { |
| 3419 Variable *RegHi, *RegLo; | 3499 Variable *RegHi, *RegLo; |
| 3420 const uint64_t Value = C64->getValue(); | 3500 const uint64_t Value = C64->getValue(); |
| 3421 uint64_t Upper32Bits = (Value >> INT32_BITS) & Mask; | 3501 uint64_t Upper32Bits = (Value >> INT32_BITS) & Mask; |
| 3422 uint64_t Lower32Bits = Value & Mask; | 3502 uint64_t Lower32Bits = Value & Mask; |
| (...skipping 1811 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5234 TargetHeaderMIPS32::TargetHeaderMIPS32(GlobalContext *Ctx) | 5314 TargetHeaderMIPS32::TargetHeaderMIPS32(GlobalContext *Ctx) |
| 5235 : TargetHeaderLowering(Ctx) {} | 5315 : TargetHeaderLowering(Ctx) {} |
| 5236 | 5316 |
| 5237 void TargetHeaderMIPS32::lower() { | 5317 void TargetHeaderMIPS32::lower() { |
| 5238 OstreamLocker L(Ctx); | 5318 OstreamLocker L(Ctx); |
| 5239 Ostream &Str = Ctx->getStrEmit(); | 5319 Ostream &Str = Ctx->getStrEmit(); |
| 5240 Str << "\t.set\t" | 5320 Str << "\t.set\t" |
| 5241 << "nomicromips\n"; | 5321 << "nomicromips\n"; |
| 5242 Str << "\t.set\t" | 5322 Str << "\t.set\t" |
| 5243 << "nomips16\n"; | 5323 << "nomips16\n"; |
| 5324 Str << "\t.set\t" | |
| 5325 << "noat\n"; | |
| 5244 } | 5326 } |
| 5245 | 5327 |
| 5246 SmallBitVector TargetMIPS32::TypeToRegisterSet[RCMIPS32_NUM]; | 5328 SmallBitVector TargetMIPS32::TypeToRegisterSet[RCMIPS32_NUM]; |
| 5247 SmallBitVector TargetMIPS32::TypeToRegisterSetUnfiltered[RCMIPS32_NUM]; | 5329 SmallBitVector TargetMIPS32::TypeToRegisterSetUnfiltered[RCMIPS32_NUM]; |
| 5248 SmallBitVector TargetMIPS32::RegisterAliases[RegMIPS32::Reg_NUM]; | 5330 SmallBitVector TargetMIPS32::RegisterAliases[RegMIPS32::Reg_NUM]; |
| 5249 | 5331 |
| 5250 } // end of namespace MIPS32 | 5332 } // end of namespace MIPS32 |
| 5251 } // end of namespace Ice | 5333 } // end of namespace Ice |
| OLD | NEW |