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 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 102 } | 102 } |
| 103 | 103 |
| 104 // Value is in bytes. Return Value adjusted to the next highest multiple of the | 104 // Value is in bytes. Return Value adjusted to the next highest multiple of the |
| 105 // stack alignment. | 105 // stack alignment. |
| 106 uint32_t applyStackAlignment(uint32_t Value) { | 106 uint32_t applyStackAlignment(uint32_t Value) { |
| 107 return Utils::applyAlignment(Value, MIPS32_STACK_ALIGNMENT_BYTES); | 107 return Utils::applyAlignment(Value, MIPS32_STACK_ALIGNMENT_BYTES); |
| 108 } | 108 } |
| 109 | 109 |
| 110 } // end of anonymous namespace | 110 } // end of anonymous namespace |
| 111 | 111 |
| 112 TargetMIPS32::TargetMIPS32(Cfg *Func) : TargetLowering(Func) {} | 112 TargetMIPS32::TargetMIPS32(Cfg *Func) |
| 113 : TargetLowering(Func), NeedSandboxing(SandboxingType == ST_NaCl) {} | |
| 113 | 114 |
| 114 void TargetMIPS32::assignVarStackSlots(VarList &SortedSpilledVariables, | 115 void TargetMIPS32::assignVarStackSlots(VarList &SortedSpilledVariables, |
| 115 size_t SpillAreaPaddingBytes, | 116 size_t SpillAreaPaddingBytes, |
| 116 size_t SpillAreaSizeBytes, | 117 size_t SpillAreaSizeBytes, |
| 117 size_t GlobalsAndSubsequentPaddingSize) { | 118 size_t GlobalsAndSubsequentPaddingSize) { |
| 118 const VariablesMetadata *VMetadata = Func->getVMetadata(); | 119 const VariablesMetadata *VMetadata = Func->getVMetadata(); |
| 119 size_t GlobalsSpaceUsed = SpillAreaPaddingBytes; | 120 size_t GlobalsSpaceUsed = SpillAreaPaddingBytes; |
| 120 size_t NextStackOffset = SpillAreaPaddingBytes; | 121 size_t NextStackOffset = SpillAreaPaddingBytes; |
| 121 CfgVector<size_t> LocalsSize(Func->getNumNodes()); | 122 CfgVector<size_t> LocalsSize(Func->getNumNodes()); |
| 122 const bool SimpleCoalescing = !callsReturnsTwice(); | 123 const bool SimpleCoalescing = !callsReturnsTwice(); |
| (...skipping 1372 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1495 } | 1496 } |
| 1496 | 1497 |
| 1497 // Combine fixed alloca with SpillAreaSize. | 1498 // Combine fixed alloca with SpillAreaSize. |
| 1498 SpillAreaSizeBytes += FixedAllocaSizeBytes; | 1499 SpillAreaSizeBytes += FixedAllocaSizeBytes; |
| 1499 | 1500 |
| 1500 TotalStackSizeBytes = PreservedRegsSizeBytes + SpillAreaSizeBytes; | 1501 TotalStackSizeBytes = PreservedRegsSizeBytes + SpillAreaSizeBytes; |
| 1501 | 1502 |
| 1502 // Generate "addiu sp, sp, -TotalStackSizeBytes" | 1503 // Generate "addiu sp, sp, -TotalStackSizeBytes" |
| 1503 if (TotalStackSizeBytes) { | 1504 if (TotalStackSizeBytes) { |
| 1504 // Use the scratch register if needed to legalize the immediate. | 1505 // Use the scratch register if needed to legalize the immediate. |
| 1505 Variable *SP = getPhysicalRegister(RegMIPS32::Reg_SP); | 1506 Sandboxer(this).addiu_sp(-TotalStackSizeBytes); |
| 1506 _addiu(SP, SP, -(TotalStackSizeBytes)); | |
| 1507 } | 1507 } |
| 1508 | 1508 |
| 1509 Ctx->statsUpdateFrameBytes(TotalStackSizeBytes); | 1509 Ctx->statsUpdateFrameBytes(TotalStackSizeBytes); |
| 1510 | 1510 |
| 1511 if (!PreservedGPRs.empty()) { | 1511 if (!PreservedGPRs.empty()) { |
| 1512 uint32_t StackOffset = TotalStackSizeBytes; | 1512 uint32_t StackOffset = TotalStackSizeBytes; |
| 1513 for (Variable *Var : *PreservedRegsInClass) { | 1513 for (Variable *Var : *PreservedRegsInClass) { |
| 1514 Variable *PhysicalRegister = getPhysicalRegister(Var->getRegNum()); | 1514 Variable *PhysicalRegister = getPhysicalRegister(Var->getRegNum()); |
| 1515 StackOffset -= typeWidthInBytesOnStack(PhysicalRegister->getType()); | 1515 StackOffset -= typeWidthInBytesOnStack(PhysicalRegister->getType()); |
| 1516 Variable *SP = getPhysicalRegister(RegMIPS32::Reg_SP); | 1516 Variable *SP = getPhysicalRegister(RegMIPS32::Reg_SP); |
| 1517 OperandMIPS32Mem *MemoryLocation = OperandMIPS32Mem::create( | 1517 OperandMIPS32Mem *MemoryLocation = OperandMIPS32Mem::create( |
| 1518 Func, IceType_i32, SP, | 1518 Func, IceType_i32, SP, |
| 1519 llvm::cast<ConstantInteger32>(Ctx->getConstantInt32(StackOffset))); | 1519 llvm::cast<ConstantInteger32>(Ctx->getConstantInt32(StackOffset))); |
| 1520 _sw(PhysicalRegister, MemoryLocation); | 1520 Sandboxer(this).sw(PhysicalRegister, MemoryLocation); |
| 1521 } | 1521 } |
| 1522 } | 1522 } |
| 1523 | 1523 |
| 1524 Variable *FP = getPhysicalRegister(RegMIPS32::Reg_FP); | 1524 Variable *FP = getPhysicalRegister(RegMIPS32::Reg_FP); |
| 1525 | 1525 |
| 1526 // Generate "mov FP, SP" if needed. | 1526 // Generate "mov FP, SP" if needed. |
| 1527 if (UsesFramePointer) { | 1527 if (UsesFramePointer) { |
| 1528 Variable *SP = getPhysicalRegister(RegMIPS32::Reg_SP); | 1528 Variable *SP = getPhysicalRegister(RegMIPS32::Reg_SP); |
| 1529 _mov(FP, SP); | 1529 _mov(FP, SP); |
| 1530 // Keep FP live for late-stage liveness analysis (e.g. asm-verbose mode). | 1530 // Keep FP live for late-stage liveness analysis (e.g. asm-verbose mode). |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1614 Context.init(Node); | 1614 Context.init(Node); |
| 1615 Context.setInsertPoint(InsertPoint); | 1615 Context.setInsertPoint(InsertPoint); |
| 1616 | 1616 |
| 1617 Variable *SP = getPhysicalRegister(RegMIPS32::Reg_SP); | 1617 Variable *SP = getPhysicalRegister(RegMIPS32::Reg_SP); |
| 1618 if (UsesFramePointer) { | 1618 if (UsesFramePointer) { |
| 1619 Variable *FP = getPhysicalRegister(RegMIPS32::Reg_FP); | 1619 Variable *FP = getPhysicalRegister(RegMIPS32::Reg_FP); |
| 1620 // For late-stage liveness analysis (e.g. asm-verbose mode), adding a fake | 1620 // For late-stage liveness analysis (e.g. asm-verbose mode), adding a fake |
| 1621 // use of SP before the assignment of SP=FP keeps previous SP adjustments | 1621 // use of SP before the assignment of SP=FP keeps previous SP adjustments |
| 1622 // from being dead-code eliminated. | 1622 // from being dead-code eliminated. |
| 1623 Context.insert<InstFakeUse>(SP); | 1623 Context.insert<InstFakeUse>(SP); |
| 1624 _mov(SP, FP); | 1624 Sandboxer(this).reset_sp(FP); |
| 1625 } | 1625 } |
| 1626 | 1626 |
| 1627 VarList::reverse_iterator RIter, END; | 1627 VarList::reverse_iterator RIter, END; |
| 1628 | 1628 |
| 1629 if (!PreservedGPRs.empty()) { | 1629 if (!PreservedGPRs.empty()) { |
| 1630 uint32_t StackOffset = TotalStackSizeBytes - PreservedRegsSizeBytes; | 1630 uint32_t StackOffset = TotalStackSizeBytes - PreservedRegsSizeBytes; |
| 1631 for (RIter = PreservedGPRs.rbegin(), END = PreservedGPRs.rend(); | 1631 for (RIter = PreservedGPRs.rbegin(), END = PreservedGPRs.rend(); |
| 1632 RIter != END; ++RIter) { | 1632 RIter != END; ++RIter) { |
| 1633 Variable *PhysicalRegister = getPhysicalRegister((*RIter)->getRegNum()); | 1633 Variable *PhysicalRegister = getPhysicalRegister((*RIter)->getRegNum()); |
| 1634 Variable *SP = getPhysicalRegister(RegMIPS32::Reg_SP); | 1634 Variable *SP = getPhysicalRegister(RegMIPS32::Reg_SP); |
| 1635 OperandMIPS32Mem *MemoryLocation = OperandMIPS32Mem::create( | 1635 OperandMIPS32Mem *MemoryLocation = OperandMIPS32Mem::create( |
| 1636 Func, IceType_i32, SP, | 1636 Func, IceType_i32, SP, |
| 1637 llvm::cast<ConstantInteger32>(Ctx->getConstantInt32(StackOffset))); | 1637 llvm::cast<ConstantInteger32>(Ctx->getConstantInt32(StackOffset))); |
| 1638 _lw(PhysicalRegister, MemoryLocation); | 1638 _lw(PhysicalRegister, MemoryLocation); |
| 1639 StackOffset += typeWidthInBytesOnStack(PhysicalRegister->getType()); | 1639 StackOffset += typeWidthInBytesOnStack(PhysicalRegister->getType()); |
| 1640 } | 1640 } |
| 1641 } | 1641 } |
| 1642 | 1642 |
| 1643 if (TotalStackSizeBytes) { | 1643 if (TotalStackSizeBytes) { |
| 1644 _addiu(SP, SP, TotalStackSizeBytes); | 1644 Sandboxer(this).addiu_sp(TotalStackSizeBytes); |
| 1645 } | 1645 } |
| 1646 if (!getFlags().getUseSandboxing()) | |
| 1647 return; | |
| 1648 | |
| 1649 Variable *RA = getPhysicalRegister(RegMIPS32::Reg_RA); | |
| 1650 Variable *RetValue = nullptr; | |
| 1651 if (RI->getSrcSize()) | |
| 1652 RetValue = llvm::cast<Variable>(RI->getSrc(0)); | |
| 1653 | |
| 1654 Sandboxer(this).ret(RA, RetValue); | |
| 1655 | |
| 1656 RI->setDeleted(); | |
| 1646 | 1657 |
| 1647 return; | 1658 return; |
|
Jim Stichnoth
2016/11/08 13:36:31
Remove this unnecessary return statement.
Stefan Maksimovic
2016/11/08 14:59:55
Done.
| |
| 1648 } | 1659 } |
| 1649 | 1660 |
| 1650 Variable *TargetMIPS32::PostLoweringLegalizer::newBaseRegister( | 1661 Variable *TargetMIPS32::PostLoweringLegalizer::newBaseRegister( |
| 1651 Variable *Base, int32_t Offset, RegNumT ScratchRegNum) { | 1662 Variable *Base, int32_t Offset, RegNumT ScratchRegNum) { |
| 1652 // Legalize will likely need a lui/ori combination, but if the top bits are | 1663 // Legalize will likely need a lui/ori combination, but if the top bits are |
| 1653 // all 0 from negating the offset and subtracting, we could use that instead. | 1664 // all 0 from negating the offset and subtracting, we could use that instead. |
| 1654 const bool ShouldSub = Offset != 0 && (-Offset & 0xFFFF0000) == 0; | 1665 const bool ShouldSub = Offset != 0 && (-Offset & 0xFFFF0000) == 0; |
| 1655 Variable *ScratchReg = Target->makeReg(IceType_i32, ScratchRegNum); | 1666 Variable *ScratchReg = Target->makeReg(IceType_i32, ScratchRegNum); |
| 1656 if (ShouldSub) { | 1667 if (ShouldSub) { |
| 1657 Target->_addi(ScratchReg, Base, -Offset); | 1668 Target->_addi(ScratchReg, Base, -Offset); |
| (...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1791 Target->Ctx->getConstantInt32(Offset + 4))); | 1802 Target->Ctx->getConstantInt32(Offset + 4))); |
| 1792 OperandMIPS32Mem *Addr = legalizeMemOperand(TAddr); | 1803 OperandMIPS32Mem *Addr = legalizeMemOperand(TAddr); |
| 1793 | 1804 |
| 1794 // FP arguments are passed in GP reg if first argument is in GP. In this | 1805 // FP arguments are passed in GP reg if first argument is in GP. In this |
| 1795 // case type of the SrcR is still FP thus we need to explicitly generate sw | 1806 // case type of the SrcR is still FP thus we need to explicitly generate sw |
| 1796 // instead of swc1. | 1807 // instead of swc1. |
| 1797 const RegNumT RegNum = SrcR->getRegNum(); | 1808 const RegNumT RegNum = SrcR->getRegNum(); |
| 1798 const bool IsSrcGPReg = RegMIPS32::isGPRReg(SrcR->getRegNum()); | 1809 const bool IsSrcGPReg = RegMIPS32::isGPRReg(SrcR->getRegNum()); |
| 1799 if (SrcTy == IceType_f32 && IsSrcGPReg) { | 1810 if (SrcTy == IceType_f32 && IsSrcGPReg) { |
| 1800 Variable *SrcGPR = Target->makeReg(IceType_i32, RegNum); | 1811 Variable *SrcGPR = Target->makeReg(IceType_i32, RegNum); |
| 1801 Target->_sw(SrcGPR, Addr); | 1812 Sandboxer(Target).sw(SrcGPR, Addr); |
| 1802 } else if (SrcTy == IceType_f64 && IsSrcGPReg) { | 1813 } else if (SrcTy == IceType_f64 && IsSrcGPReg) { |
| 1803 Variable *SrcGPRHi = | 1814 Variable *SrcGPRHi = |
| 1804 Target->makeReg(IceType_i32, RegMIPS32::get64PairFirstRegNum(RegNum)); | 1815 Target->makeReg(IceType_i32, RegMIPS32::get64PairFirstRegNum(RegNum)); |
| 1805 Variable *SrcGPRLo = Target->makeReg( | 1816 Variable *SrcGPRLo = Target->makeReg( |
| 1806 IceType_i32, RegMIPS32::get64PairSecondRegNum(RegNum)); | 1817 IceType_i32, RegMIPS32::get64PairSecondRegNum(RegNum)); |
| 1807 Target->_sw(SrcGPRHi, Addr); | 1818 Sandboxer(Target).sw(SrcGPRHi, Addr); |
| 1808 OperandMIPS32Mem *AddrHi = legalizeMemOperand(TAddrHi); | 1819 OperandMIPS32Mem *AddrHi = legalizeMemOperand(TAddrHi); |
| 1809 Target->_sw(SrcGPRLo, AddrHi); | 1820 Sandboxer(Target).sw(SrcGPRLo, AddrHi); |
| 1810 } else if (DestTy == IceType_f64 && IsSrcGPReg) { | 1821 } else if (DestTy == IceType_f64 && IsSrcGPReg) { |
| 1811 const auto FirstReg = | 1822 const auto FirstReg = |
| 1812 (llvm::cast<Variable>(MovInstr->getSrc(0)))->getRegNum(); | 1823 (llvm::cast<Variable>(MovInstr->getSrc(0)))->getRegNum(); |
| 1813 const auto SecondReg = | 1824 const auto SecondReg = |
| 1814 (llvm::cast<Variable>(MovInstr->getSrc(1)))->getRegNum(); | 1825 (llvm::cast<Variable>(MovInstr->getSrc(1)))->getRegNum(); |
| 1815 Variable *SrcGPRHi = Target->makeReg(IceType_i32, FirstReg); | 1826 Variable *SrcGPRHi = Target->makeReg(IceType_i32, FirstReg); |
| 1816 Variable *SrcGPRLo = Target->makeReg(IceType_i32, SecondReg); | 1827 Variable *SrcGPRLo = Target->makeReg(IceType_i32, SecondReg); |
| 1817 Target->_sw(SrcGPRLo, Addr); | 1828 Sandboxer(Target).sw(SrcGPRLo, Addr); |
| 1818 OperandMIPS32Mem *AddrHi = legalizeMemOperand(TAddrHi); | 1829 OperandMIPS32Mem *AddrHi = legalizeMemOperand(TAddrHi); |
| 1819 Target->_sw(SrcGPRHi, AddrHi); | 1830 Sandboxer(Target).sw(SrcGPRHi, AddrHi); |
| 1820 } else { | 1831 } else { |
| 1821 Target->_sw(SrcR, Addr); | 1832 Sandboxer(Target).sw(SrcR, Addr); |
| 1822 } | 1833 } |
| 1823 | 1834 |
| 1824 Target->Context.insert<InstFakeDef>(Dest); | 1835 Target->Context.insert<InstFakeDef>(Dest); |
| 1825 Legalized = true; | 1836 Legalized = true; |
| 1826 } else if (auto *Var = llvm::dyn_cast<Variable>(Src)) { | 1837 } else if (auto *Var = llvm::dyn_cast<Variable>(Src)) { |
| 1827 if (Var->isRematerializable()) { | 1838 if (Var->isRematerializable()) { |
| 1828 // This is equivalent to an x86 _lea(RematOffset(%esp/%ebp), Variable). | 1839 // This is equivalent to an x86 _lea(RematOffset(%esp/%ebp), Variable). |
| 1829 | 1840 |
| 1830 // ExtraOffset is only needed for stack-pointer based frames as we have | 1841 // ExtraOffset is only needed for stack-pointer based frames as we have |
| 1831 // to account for spill storage. | 1842 // to account for spill storage. |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 1858 Variable *DestHi = Target->makeReg( | 1869 Variable *DestHi = Target->makeReg( |
| 1859 IceType_f32, RegMIPS32::get64PairSecondRegNum(RegNum)); | 1870 IceType_f32, RegMIPS32::get64PairSecondRegNum(RegNum)); |
| 1860 OperandMIPS32Mem *AddrLo = OperandMIPS32Mem::create( | 1871 OperandMIPS32Mem *AddrLo = OperandMIPS32Mem::create( |
| 1861 Target->Func, IceType_i32, Base, | 1872 Target->Func, IceType_i32, Base, |
| 1862 llvm::cast<ConstantInteger32>( | 1873 llvm::cast<ConstantInteger32>( |
| 1863 Target->Ctx->getConstantInt32(Offset))); | 1874 Target->Ctx->getConstantInt32(Offset))); |
| 1864 OperandMIPS32Mem *AddrHi = OperandMIPS32Mem::create( | 1875 OperandMIPS32Mem *AddrHi = OperandMIPS32Mem::create( |
| 1865 Target->Func, IceType_i32, Base, | 1876 Target->Func, IceType_i32, Base, |
| 1866 llvm::cast<ConstantInteger32>( | 1877 llvm::cast<ConstantInteger32>( |
| 1867 Target->Ctx->getConstantInt32(Offset + 4))); | 1878 Target->Ctx->getConstantInt32(Offset + 4))); |
| 1868 Target->_lw(Reg, AddrLo); | 1879 Sandboxer(Target).lw(Reg, AddrLo); |
| 1869 Target->_mov(DestLo, Reg); | 1880 Target->_mov(DestLo, Reg); |
| 1870 Target->_lw(Reg, AddrHi); | 1881 Sandboxer(Target).lw(Reg, AddrHi); |
| 1871 Target->_mov(DestHi, Reg); | 1882 Target->_mov(DestHi, Reg); |
| 1872 } else { | 1883 } else { |
| 1873 OperandMIPS32Mem *TAddr = OperandMIPS32Mem::create( | 1884 OperandMIPS32Mem *TAddr = OperandMIPS32Mem::create( |
| 1874 Target->Func, DestTy, Base, | 1885 Target->Func, DestTy, Base, |
| 1875 llvm::cast<ConstantInteger32>( | 1886 llvm::cast<ConstantInteger32>( |
| 1876 Target->Ctx->getConstantInt32(Offset))); | 1887 Target->Ctx->getConstantInt32(Offset))); |
| 1877 OperandMIPS32Mem *Addr = legalizeMemOperand(TAddr); | 1888 OperandMIPS32Mem *Addr = legalizeMemOperand(TAddr); |
| 1878 OperandMIPS32Mem *TAddrHi = OperandMIPS32Mem::create( | 1889 OperandMIPS32Mem *TAddrHi = OperandMIPS32Mem::create( |
| 1879 Target->Func, DestTy, Base, | 1890 Target->Func, DestTy, Base, |
| 1880 llvm::cast<ConstantInteger32>( | 1891 llvm::cast<ConstantInteger32>( |
| 1881 Target->Ctx->getConstantInt32(Offset + 4))); | 1892 Target->Ctx->getConstantInt32(Offset + 4))); |
| 1882 // FP arguments are passed in GP reg if first argument is in GP. | 1893 // FP arguments are passed in GP reg if first argument is in GP. |
| 1883 // In this case type of the Dest is still FP thus we need to | 1894 // In this case type of the Dest is still FP thus we need to |
| 1884 // explicitly generate lw instead of lwc1. | 1895 // explicitly generate lw instead of lwc1. |
| 1885 if (DestTy == IceType_f32 && IsDstGPReg) { | 1896 if (DestTy == IceType_f32 && IsDstGPReg) { |
| 1886 Variable *DstGPR = Target->makeReg(IceType_i32, RegNum); | 1897 Variable *DstGPR = Target->makeReg(IceType_i32, RegNum); |
| 1887 Target->_lw(DstGPR, Addr); | 1898 Sandboxer(Target).lw(DstGPR, Addr); |
| 1888 } else if (DestTy == IceType_f64 && IsDstGPReg) { | 1899 } else if (DestTy == IceType_f64 && IsDstGPReg) { |
| 1889 Variable *DstGPRHi = Target->makeReg( | 1900 Variable *DstGPRHi = Target->makeReg( |
| 1890 IceType_i32, RegMIPS32::get64PairFirstRegNum(RegNum)); | 1901 IceType_i32, RegMIPS32::get64PairFirstRegNum(RegNum)); |
| 1891 Variable *DstGPRLo = Target->makeReg( | 1902 Variable *DstGPRLo = Target->makeReg( |
| 1892 IceType_i32, RegMIPS32::get64PairSecondRegNum(RegNum)); | 1903 IceType_i32, RegMIPS32::get64PairSecondRegNum(RegNum)); |
| 1893 Target->_lw(DstGPRHi, Addr); | 1904 Sandboxer(Target).lw(DstGPRHi, Addr); |
| 1894 OperandMIPS32Mem *AddrHi = legalizeMemOperand(TAddrHi); | 1905 OperandMIPS32Mem *AddrHi = legalizeMemOperand(TAddrHi); |
| 1895 Target->_lw(DstGPRLo, AddrHi); | 1906 Sandboxer(Target).lw(DstGPRLo, AddrHi); |
| 1896 } else if (DestTy == IceType_f64 && IsDstGPReg) { | 1907 } else if (DestTy == IceType_f64 && IsDstGPReg) { |
| 1897 const auto FirstReg = | 1908 const auto FirstReg = |
| 1898 (llvm::cast<Variable>(MovInstr->getSrc(0)))->getRegNum(); | 1909 (llvm::cast<Variable>(MovInstr->getSrc(0)))->getRegNum(); |
| 1899 const auto SecondReg = | 1910 const auto SecondReg = |
| 1900 (llvm::cast<Variable>(MovInstr->getSrc(1)))->getRegNum(); | 1911 (llvm::cast<Variable>(MovInstr->getSrc(1)))->getRegNum(); |
| 1901 Variable *DstGPRHi = Target->makeReg(IceType_i32, FirstReg); | 1912 Variable *DstGPRHi = Target->makeReg(IceType_i32, FirstReg); |
| 1902 Variable *DstGPRLo = Target->makeReg(IceType_i32, SecondReg); | 1913 Variable *DstGPRLo = Target->makeReg(IceType_i32, SecondReg); |
| 1903 Target->_lw(DstGPRLo, Addr); | 1914 Sandboxer(Target).lw(DstGPRLo, Addr); |
| 1904 OperandMIPS32Mem *AddrHi = legalizeMemOperand(TAddrHi); | 1915 OperandMIPS32Mem *AddrHi = legalizeMemOperand(TAddrHi); |
| 1905 Target->_lw(DstGPRHi, AddrHi); | 1916 Sandboxer(Target).lw(DstGPRHi, AddrHi); |
| 1906 } else { | 1917 } else { |
| 1907 Target->_lw(Dest, Addr); | 1918 Sandboxer(Target).lw(Dest, Addr); |
| 1908 } | 1919 } |
| 1909 } | 1920 } |
| 1910 Legalized = true; | 1921 Legalized = true; |
| 1911 } | 1922 } |
| 1912 } | 1923 } |
| 1913 } | 1924 } |
| 1914 | 1925 |
| 1915 if (Legalized) { | 1926 if (Legalized) { |
| 1916 if (MovInstr->isDestRedefined()) { | 1927 if (MovInstr->isDestRedefined()) { |
| 1917 Target->_set_dest_redefined(); | 1928 Target->_set_dest_redefined(); |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1982 auto *Src0V = llvm::dyn_cast_or_null<Variable>(Src0); | 1993 auto *Src0V = llvm::dyn_cast_or_null<Variable>(Src0); |
| 1983 auto *Src0M = llvm::dyn_cast_or_null<OperandMIPS32Mem>(Src0); | 1994 auto *Src0M = llvm::dyn_cast_or_null<OperandMIPS32Mem>(Src0); |
| 1984 auto *Src1M = llvm::dyn_cast_or_null<OperandMIPS32Mem>(Src1); | 1995 auto *Src1M = llvm::dyn_cast_or_null<OperandMIPS32Mem>(Src1); |
| 1985 Variable *Dst = CurInstr->getDest(); | 1996 Variable *Dst = CurInstr->getDest(); |
| 1986 if (auto *MovInstr = llvm::dyn_cast<InstMIPS32Mov>(CurInstr)) { | 1997 if (auto *MovInstr = llvm::dyn_cast<InstMIPS32Mov>(CurInstr)) { |
| 1987 Legalizer.legalizeMov(MovInstr); | 1998 Legalizer.legalizeMov(MovInstr); |
| 1988 continue; | 1999 continue; |
| 1989 } | 2000 } |
| 1990 if (llvm::isa<InstMIPS32Sw>(CurInstr)) { | 2001 if (llvm::isa<InstMIPS32Sw>(CurInstr)) { |
| 1991 if (auto *LegalMem = Legalizer.legalizeMemOperand(Src1M)) { | 2002 if (auto *LegalMem = Legalizer.legalizeMemOperand(Src1M)) { |
| 1992 _sw(Src0V, LegalMem); | 2003 Sandboxer(this).sw(Src0V, LegalMem); |
| 1993 CurInstr->setDeleted(); | 2004 CurInstr->setDeleted(); |
| 1994 } | 2005 } |
| 1995 continue; | 2006 continue; |
| 1996 } | 2007 } |
| 1997 if (llvm::isa<InstMIPS32Swc1>(CurInstr)) { | 2008 if (llvm::isa<InstMIPS32Swc1>(CurInstr)) { |
| 1998 if (auto *LegalMem = Legalizer.legalizeMemOperand(Src1M)) { | 2009 if (auto *LegalMem = Legalizer.legalizeMemOperand(Src1M)) { |
| 1999 _swc1(Src0V, LegalMem); | 2010 _swc1(Src0V, LegalMem); |
| 2000 CurInstr->setDeleted(); | 2011 CurInstr->setDeleted(); |
| 2001 } | 2012 } |
| 2002 continue; | 2013 continue; |
| 2003 } | 2014 } |
| 2004 if (llvm::isa<InstMIPS32Sdc1>(CurInstr)) { | 2015 if (llvm::isa<InstMIPS32Sdc1>(CurInstr)) { |
| 2005 if (auto *LegalMem = Legalizer.legalizeMemOperand(Src1M)) { | 2016 if (auto *LegalMem = Legalizer.legalizeMemOperand(Src1M)) { |
| 2006 _sdc1(Src0V, LegalMem); | 2017 _sdc1(Src0V, LegalMem); |
| 2007 CurInstr->setDeleted(); | 2018 CurInstr->setDeleted(); |
| 2008 } | 2019 } |
| 2009 continue; | 2020 continue; |
| 2010 } | 2021 } |
| 2011 if (llvm::isa<InstMIPS32Lw>(CurInstr)) { | 2022 if (llvm::isa<InstMIPS32Lw>(CurInstr)) { |
| 2012 if (auto *LegalMem = Legalizer.legalizeMemOperand(Src0M)) { | 2023 if (auto *LegalMem = Legalizer.legalizeMemOperand(Src0M)) { |
| 2013 _lw(Dst, LegalMem); | 2024 Sandboxer(this).lw(Dst, LegalMem); |
| 2014 CurInstr->setDeleted(); | 2025 CurInstr->setDeleted(); |
| 2015 } | 2026 } |
| 2016 continue; | 2027 continue; |
| 2017 } | 2028 } |
| 2018 if (llvm::isa<InstMIPS32Lwc1>(CurInstr)) { | 2029 if (llvm::isa<InstMIPS32Lwc1>(CurInstr)) { |
| 2019 if (auto *LegalMem = Legalizer.legalizeMemOperand(Src0M)) { | 2030 if (auto *LegalMem = Legalizer.legalizeMemOperand(Src0M)) { |
| 2020 _lwc1(Dst, LegalMem); | 2031 _lwc1(Dst, LegalMem); |
| 2021 CurInstr->setDeleted(); | 2032 CurInstr->setDeleted(); |
| 2022 } | 2033 } |
| 2023 continue; | 2034 continue; |
| (...skipping 1222 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3246 // eliminated as a result of the FakeKill of scratch registers after the call. | 3257 // eliminated as a result of the FakeKill of scratch registers after the call. |
| 3247 // These fake-uses need to be placed here to avoid argument registers from | 3258 // These fake-uses need to be placed here to avoid argument registers from |
| 3248 // being used during the legalizeToReg() calls above. | 3259 // being used during the legalizeToReg() calls above. |
| 3249 for (auto *RegArg : RegArgs) { | 3260 for (auto *RegArg : RegArgs) { |
| 3250 Context.insert<InstFakeUse>(RegArg); | 3261 Context.insert<InstFakeUse>(RegArg); |
| 3251 } | 3262 } |
| 3252 | 3263 |
| 3253 // If variable alloca is used the extra 16 bytes for argument build area | 3264 // If variable alloca is used the extra 16 bytes for argument build area |
| 3254 // will be allocated on stack before a call. | 3265 // will be allocated on stack before a call. |
| 3255 if (VariableAllocaUsed) | 3266 if (VariableAllocaUsed) |
| 3256 _addiu(SP, SP, -MaxOutArgsSizeBytes); | 3267 Sandboxer(this).addiu_sp(-MaxOutArgsSizeBytes); |
| 3257 | 3268 |
| 3258 Inst *NewCall; | 3269 Inst *NewCall; |
| 3259 | 3270 |
| 3260 // We don't need to define the return register if it is a vector. | 3271 // We don't need to define the return register if it is a vector. |
| 3261 // We have inserted fake defs of it just after the call. | 3272 // We have inserted fake defs of it just after the call. |
| 3262 if (ReturnReg && isVectorIntegerType(ReturnReg->getType())) { | 3273 if (ReturnReg && isVectorIntegerType(ReturnReg->getType())) { |
| 3263 Variable *RetReg = nullptr; | 3274 Variable *RetReg = nullptr; |
| 3264 NewCall = InstMIPS32Call::create(Func, RetReg, CallTarget); | 3275 NewCall = InstMIPS32Call::create(Func, RetReg, CallTarget); |
| 3276 Context.insert(NewCall); | |
| 3265 } else { | 3277 } else { |
| 3266 NewCall = InstMIPS32Call::create(Func, ReturnReg, CallTarget); | 3278 NewCall = Sandboxer(this, InstBundleLock::Opt_AlignToEnd) |
| 3279 .jal(ReturnReg, CallTarget); | |
| 3267 } | 3280 } |
| 3268 Context.insert(NewCall); | |
| 3269 | 3281 |
| 3270 if (VariableAllocaUsed) | 3282 if (VariableAllocaUsed) |
| 3271 _addiu(SP, SP, MaxOutArgsSizeBytes); | 3283 Sandboxer(this).addiu_sp(MaxOutArgsSizeBytes); |
| 3272 | 3284 |
| 3273 // Insert a fake use of stack pointer to avoid dead code elimination of addiu | 3285 // Insert a fake use of stack pointer to avoid dead code elimination of addiu |
| 3274 // instruction. | 3286 // instruction. |
| 3275 Context.insert<InstFakeUse>(SP); | 3287 Context.insert<InstFakeUse>(SP); |
| 3276 | 3288 |
| 3277 if (ReturnRegHi) | 3289 if (ReturnRegHi) |
| 3278 Context.insert(InstFakeDef::create(Func, ReturnRegHi)); | 3290 Context.insert(InstFakeDef::create(Func, ReturnRegHi)); |
| 3279 | 3291 |
| 3280 if (ReturnReg) { | 3292 if (ReturnReg) { |
| 3281 if (auto *RetVec = llvm::dyn_cast<VariableVecOn32>(ReturnReg)) { | 3293 if (auto *RetVec = llvm::dyn_cast<VariableVecOn32>(ReturnReg)) { |
| (...skipping 1218 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4500 UnimplementedLoweringError(this, Instr); // Not required for PNaCl | 4512 UnimplementedLoweringError(this, Instr); // Not required for PNaCl |
| 4501 } | 4513 } |
| 4502 return; | 4514 return; |
| 4503 } | 4515 } |
| 4504 case Intrinsics::Stacksave: { | 4516 case Intrinsics::Stacksave: { |
| 4505 Variable *SP = getPhysicalRegister(RegMIPS32::Reg_SP); | 4517 Variable *SP = getPhysicalRegister(RegMIPS32::Reg_SP); |
| 4506 _mov(Dest, SP); | 4518 _mov(Dest, SP); |
| 4507 return; | 4519 return; |
| 4508 } | 4520 } |
| 4509 case Intrinsics::Stackrestore: { | 4521 case Intrinsics::Stackrestore: { |
| 4510 if (getFlags().getUseSandboxing()) { | |
| 4511 UnimplementedLoweringError(this, Instr); | |
| 4512 return; | |
| 4513 } | |
| 4514 Variable *Val = legalizeToReg(Instr->getArg(0)); | 4522 Variable *Val = legalizeToReg(Instr->getArg(0)); |
| 4515 Variable *SP = getPhysicalRegister(RegMIPS32::Reg_SP); | 4523 Sandboxer(this).reset_sp(Val); |
| 4516 _mov_redefined(SP, Val); | |
| 4517 return; | 4524 return; |
| 4518 } | 4525 } |
| 4519 case Intrinsics::Trap: { | 4526 case Intrinsics::Trap: { |
| 4520 const uint32_t TrapCodeZero = 0; | 4527 const uint32_t TrapCodeZero = 0; |
| 4521 _teq(getZero(), getZero(), TrapCodeZero); | 4528 _teq(getZero(), getZero(), TrapCodeZero); |
| 4522 return; | 4529 return; |
| 4523 } | 4530 } |
| 4524 case Intrinsics::LoadSubVector: { | 4531 case Intrinsics::LoadSubVector: { |
| 4525 UnimplementedLoweringError(this, Instr); // Not required for PNaCl | 4532 UnimplementedLoweringError(this, Instr); // Not required for PNaCl |
| 4526 return; | 4533 return; |
| (...skipping 899 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5426 Str << "\t.set\t" | 5433 Str << "\t.set\t" |
| 5427 << "nomips16\n"; | 5434 << "nomips16\n"; |
| 5428 Str << "\t.set\t" | 5435 Str << "\t.set\t" |
| 5429 << "noat\n"; | 5436 << "noat\n"; |
| 5430 } | 5437 } |
| 5431 | 5438 |
| 5432 SmallBitVector TargetMIPS32::TypeToRegisterSet[RCMIPS32_NUM]; | 5439 SmallBitVector TargetMIPS32::TypeToRegisterSet[RCMIPS32_NUM]; |
| 5433 SmallBitVector TargetMIPS32::TypeToRegisterSetUnfiltered[RCMIPS32_NUM]; | 5440 SmallBitVector TargetMIPS32::TypeToRegisterSetUnfiltered[RCMIPS32_NUM]; |
| 5434 SmallBitVector TargetMIPS32::RegisterAliases[RegMIPS32::Reg_NUM]; | 5441 SmallBitVector TargetMIPS32::RegisterAliases[RegMIPS32::Reg_NUM]; |
| 5435 | 5442 |
| 5443 TargetMIPS32::Sandboxer::Sandboxer(TargetMIPS32 *Target, | |
| 5444 InstBundleLock::Option BundleOption) | |
| 5445 : Target(Target), BundleOption(BundleOption) {} | |
| 5446 | |
| 5447 TargetMIPS32::Sandboxer::~Sandboxer() {} | |
| 5448 | |
| 5449 void TargetMIPS32::Sandboxer::createAutoBundle() { | |
| 5450 Bundler = makeUnique<AutoBundle>(Target, BundleOption); | |
| 5451 } | |
| 5452 | |
| 5453 void TargetMIPS32::Sandboxer::addiu_sp(uint32_t StackOffset) { | |
| 5454 Variable *SP = Target->getPhysicalRegister(RegMIPS32::Reg_SP); | |
| 5455 if (!Target->NeedSandboxing) { | |
| 5456 Target->_addiu(SP, SP, StackOffset); | |
| 5457 return; | |
| 5458 } | |
| 5459 Variable *T7 = Target->getPhysicalRegister(RegMIPS32::Reg_T7); | |
| 5460 createAutoBundle(); | |
| 5461 Target->_addiu(SP, SP, StackOffset); | |
| 5462 Target->_and(SP, SP, T7); | |
| 5463 | |
| 5464 return; | |
|
Jim Stichnoth
2016/11/08 13:36:31
Remove this return statement
Stefan Maksimovic
2016/11/08 14:59:55
Done.
| |
| 5465 } | |
| 5466 | |
| 5467 void TargetMIPS32::Sandboxer::lw(Variable *Dest, OperandMIPS32Mem *Mem) { | |
| 5468 Variable *Base = Mem->getBase(); | |
| 5469 Variable *T7 = Target->getPhysicalRegister(RegMIPS32::Reg_T7); | |
| 5470 if (Target->NeedSandboxing && (Target->getStackReg() != Base->getRegNum())) { | |
| 5471 createAutoBundle(); | |
| 5472 Target->_and(Base, Base, T7); | |
| 5473 } | |
| 5474 Target->_lw(Dest, Mem); | |
| 5475 } | |
| 5476 | |
| 5477 void TargetMIPS32::Sandboxer::sw(Variable *Dest, OperandMIPS32Mem *Mem) { | |
| 5478 Variable *Base = Mem->getBase(); | |
| 5479 Variable *T7 = Target->getPhysicalRegister(RegMIPS32::Reg_T7); | |
| 5480 if (Target->NeedSandboxing && (Target->getStackReg() != Base->getRegNum())) { | |
| 5481 createAutoBundle(); | |
| 5482 Target->_and(Base, Base, T7); | |
| 5483 } | |
| 5484 Target->_sw(Dest, Mem); | |
| 5485 } | |
| 5486 | |
| 5487 void TargetMIPS32::Sandboxer::ret(Variable *RetAddr, Variable *RetValue) { | |
| 5488 if (!Target->NeedSandboxing) { | |
| 5489 Target->_ret(RetAddr, RetValue); | |
| 5490 } | |
| 5491 Variable *T6 = Target->getPhysicalRegister(RegMIPS32::Reg_T6); | |
| 5492 createAutoBundle(); | |
| 5493 Target->_and(RetAddr, RetAddr, T6); | |
| 5494 Target->_ret(RetAddr, RetValue); | |
| 5495 } | |
| 5496 | |
| 5497 void TargetMIPS32::Sandboxer::reset_sp(Variable *Src) { | |
| 5498 Variable *SP = Target->getPhysicalRegister(RegMIPS32::Reg_SP); | |
| 5499 if (!Target->NeedSandboxing) { | |
| 5500 Target->_mov(SP, Src); | |
| 5501 return; | |
| 5502 } | |
| 5503 Variable *T7 = Target->getPhysicalRegister(RegMIPS32::Reg_T7); | |
| 5504 createAutoBundle(); | |
| 5505 Target->_mov(SP, Src); | |
| 5506 Target->_and(SP, SP, T7); | |
| 5507 } | |
| 5508 | |
| 5509 InstMIPS32Call *TargetMIPS32::Sandboxer::jal(Variable *ReturnReg, | |
| 5510 Operand *CallTarget) { | |
| 5511 if (Target->NeedSandboxing) | |
| 5512 createAutoBundle(); | |
| 5513 return Target->Context.insert<InstMIPS32Call>(ReturnReg, CallTarget); | |
| 5514 } | |
| 5515 | |
| 5436 } // end of namespace MIPS32 | 5516 } // end of namespace MIPS32 |
| 5437 } // end of namespace Ice | 5517 } // end of namespace Ice |
| OLD | NEW |