Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(447)

Side by Side Diff: src/IceTargetLoweringMIPS32.cpp

Issue 2432373002: [SubZero] Fix f64 to/from i64 moves (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Addressed review comments Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698