| 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; |
| 1646 | 1648 |
| 1647 return; | 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(); |
| 1648 } | 1657 } |
| 1649 | 1658 |
| 1650 Variable *TargetMIPS32::PostLoweringLegalizer::newBaseRegister( | 1659 Variable *TargetMIPS32::PostLoweringLegalizer::newBaseRegister( |
| 1651 Variable *Base, int32_t Offset, RegNumT ScratchRegNum) { | 1660 Variable *Base, int32_t Offset, RegNumT ScratchRegNum) { |
| 1652 // Legalize will likely need a lui/ori combination, but if the top bits are | 1661 // 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. | 1662 // all 0 from negating the offset and subtracting, we could use that instead. |
| 1654 const bool ShouldSub = Offset != 0 && (-Offset & 0xFFFF0000) == 0; | 1663 const bool ShouldSub = Offset != 0 && (-Offset & 0xFFFF0000) == 0; |
| 1655 Variable *ScratchReg = Target->makeReg(IceType_i32, ScratchRegNum); | 1664 Variable *ScratchReg = Target->makeReg(IceType_i32, ScratchRegNum); |
| 1656 if (ShouldSub) { | 1665 if (ShouldSub) { |
| 1657 Target->_addi(ScratchReg, Base, -Offset); | 1666 Target->_addi(ScratchReg, Base, -Offset); |
| (...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1791 Target->Ctx->getConstantInt32(Offset + 4))); | 1800 Target->Ctx->getConstantInt32(Offset + 4))); |
| 1792 OperandMIPS32Mem *Addr = legalizeMemOperand(TAddr); | 1801 OperandMIPS32Mem *Addr = legalizeMemOperand(TAddr); |
| 1793 | 1802 |
| 1794 // FP arguments are passed in GP reg if first argument is in GP. In this | 1803 // 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 | 1804 // case type of the SrcR is still FP thus we need to explicitly generate sw |
| 1796 // instead of swc1. | 1805 // instead of swc1. |
| 1797 const RegNumT RegNum = SrcR->getRegNum(); | 1806 const RegNumT RegNum = SrcR->getRegNum(); |
| 1798 const bool IsSrcGPReg = RegMIPS32::isGPRReg(SrcR->getRegNum()); | 1807 const bool IsSrcGPReg = RegMIPS32::isGPRReg(SrcR->getRegNum()); |
| 1799 if (SrcTy == IceType_f32 && IsSrcGPReg) { | 1808 if (SrcTy == IceType_f32 && IsSrcGPReg) { |
| 1800 Variable *SrcGPR = Target->makeReg(IceType_i32, RegNum); | 1809 Variable *SrcGPR = Target->makeReg(IceType_i32, RegNum); |
| 1801 Target->_sw(SrcGPR, Addr); | 1810 Sandboxer(Target).sw(SrcGPR, Addr); |
| 1802 } else if (SrcTy == IceType_f64 && IsSrcGPReg) { | 1811 } else if (SrcTy == IceType_f64 && IsSrcGPReg) { |
| 1803 Variable *SrcGPRHi = | 1812 Variable *SrcGPRHi = |
| 1804 Target->makeReg(IceType_i32, RegMIPS32::get64PairFirstRegNum(RegNum)); | 1813 Target->makeReg(IceType_i32, RegMIPS32::get64PairFirstRegNum(RegNum)); |
| 1805 Variable *SrcGPRLo = Target->makeReg( | 1814 Variable *SrcGPRLo = Target->makeReg( |
| 1806 IceType_i32, RegMIPS32::get64PairSecondRegNum(RegNum)); | 1815 IceType_i32, RegMIPS32::get64PairSecondRegNum(RegNum)); |
| 1807 Target->_sw(SrcGPRHi, Addr); | 1816 Sandboxer(Target).sw(SrcGPRHi, Addr); |
| 1808 OperandMIPS32Mem *AddrHi = legalizeMemOperand(TAddrHi); | 1817 OperandMIPS32Mem *AddrHi = legalizeMemOperand(TAddrHi); |
| 1809 Target->_sw(SrcGPRLo, AddrHi); | 1818 Sandboxer(Target).sw(SrcGPRLo, AddrHi); |
| 1810 } else if (DestTy == IceType_f64 && IsSrcGPReg) { | 1819 } else if (DestTy == IceType_f64 && IsSrcGPReg) { |
| 1811 const auto FirstReg = | 1820 const auto FirstReg = |
| 1812 (llvm::cast<Variable>(MovInstr->getSrc(0)))->getRegNum(); | 1821 (llvm::cast<Variable>(MovInstr->getSrc(0)))->getRegNum(); |
| 1813 const auto SecondReg = | 1822 const auto SecondReg = |
| 1814 (llvm::cast<Variable>(MovInstr->getSrc(1)))->getRegNum(); | 1823 (llvm::cast<Variable>(MovInstr->getSrc(1)))->getRegNum(); |
| 1815 Variable *SrcGPRHi = Target->makeReg(IceType_i32, FirstReg); | 1824 Variable *SrcGPRHi = Target->makeReg(IceType_i32, FirstReg); |
| 1816 Variable *SrcGPRLo = Target->makeReg(IceType_i32, SecondReg); | 1825 Variable *SrcGPRLo = Target->makeReg(IceType_i32, SecondReg); |
| 1817 Target->_sw(SrcGPRLo, Addr); | 1826 Sandboxer(Target).sw(SrcGPRLo, Addr); |
| 1818 OperandMIPS32Mem *AddrHi = legalizeMemOperand(TAddrHi); | 1827 OperandMIPS32Mem *AddrHi = legalizeMemOperand(TAddrHi); |
| 1819 Target->_sw(SrcGPRHi, AddrHi); | 1828 Sandboxer(Target).sw(SrcGPRHi, AddrHi); |
| 1820 } else { | 1829 } else { |
| 1821 Target->_sw(SrcR, Addr); | 1830 Sandboxer(Target).sw(SrcR, Addr); |
| 1822 } | 1831 } |
| 1823 | 1832 |
| 1824 Target->Context.insert<InstFakeDef>(Dest); | 1833 Target->Context.insert<InstFakeDef>(Dest); |
| 1825 Legalized = true; | 1834 Legalized = true; |
| 1826 } else if (auto *Var = llvm::dyn_cast<Variable>(Src)) { | 1835 } else if (auto *Var = llvm::dyn_cast<Variable>(Src)) { |
| 1827 if (Var->isRematerializable()) { | 1836 if (Var->isRematerializable()) { |
| 1828 // This is equivalent to an x86 _lea(RematOffset(%esp/%ebp), Variable). | 1837 // This is equivalent to an x86 _lea(RematOffset(%esp/%ebp), Variable). |
| 1829 | 1838 |
| 1830 // ExtraOffset is only needed for stack-pointer based frames as we have | 1839 // ExtraOffset is only needed for stack-pointer based frames as we have |
| 1831 // to account for spill storage. | 1840 // to account for spill storage. |
| (...skipping 26 matching lines...) Expand all Loading... |
| 1858 Variable *DestHi = Target->makeReg( | 1867 Variable *DestHi = Target->makeReg( |
| 1859 IceType_f32, RegMIPS32::get64PairSecondRegNum(RegNum)); | 1868 IceType_f32, RegMIPS32::get64PairSecondRegNum(RegNum)); |
| 1860 OperandMIPS32Mem *AddrLo = OperandMIPS32Mem::create( | 1869 OperandMIPS32Mem *AddrLo = OperandMIPS32Mem::create( |
| 1861 Target->Func, IceType_i32, Base, | 1870 Target->Func, IceType_i32, Base, |
| 1862 llvm::cast<ConstantInteger32>( | 1871 llvm::cast<ConstantInteger32>( |
| 1863 Target->Ctx->getConstantInt32(Offset))); | 1872 Target->Ctx->getConstantInt32(Offset))); |
| 1864 OperandMIPS32Mem *AddrHi = OperandMIPS32Mem::create( | 1873 OperandMIPS32Mem *AddrHi = OperandMIPS32Mem::create( |
| 1865 Target->Func, IceType_i32, Base, | 1874 Target->Func, IceType_i32, Base, |
| 1866 llvm::cast<ConstantInteger32>( | 1875 llvm::cast<ConstantInteger32>( |
| 1867 Target->Ctx->getConstantInt32(Offset + 4))); | 1876 Target->Ctx->getConstantInt32(Offset + 4))); |
| 1868 Target->_lw(Reg, AddrLo); | 1877 Sandboxer(Target).lw(Reg, AddrLo); |
| 1869 Target->_mov(DestLo, Reg); | 1878 Target->_mov(DestLo, Reg); |
| 1870 Target->_lw(Reg, AddrHi); | 1879 Sandboxer(Target).lw(Reg, AddrHi); |
| 1871 Target->_mov(DestHi, Reg); | 1880 Target->_mov(DestHi, Reg); |
| 1872 } else { | 1881 } else { |
| 1873 OperandMIPS32Mem *TAddr = OperandMIPS32Mem::create( | 1882 OperandMIPS32Mem *TAddr = OperandMIPS32Mem::create( |
| 1874 Target->Func, DestTy, Base, | 1883 Target->Func, DestTy, Base, |
| 1875 llvm::cast<ConstantInteger32>( | 1884 llvm::cast<ConstantInteger32>( |
| 1876 Target->Ctx->getConstantInt32(Offset))); | 1885 Target->Ctx->getConstantInt32(Offset))); |
| 1877 OperandMIPS32Mem *Addr = legalizeMemOperand(TAddr); | 1886 OperandMIPS32Mem *Addr = legalizeMemOperand(TAddr); |
| 1878 OperandMIPS32Mem *TAddrHi = OperandMIPS32Mem::create( | 1887 OperandMIPS32Mem *TAddrHi = OperandMIPS32Mem::create( |
| 1879 Target->Func, DestTy, Base, | 1888 Target->Func, DestTy, Base, |
| 1880 llvm::cast<ConstantInteger32>( | 1889 llvm::cast<ConstantInteger32>( |
| 1881 Target->Ctx->getConstantInt32(Offset + 4))); | 1890 Target->Ctx->getConstantInt32(Offset + 4))); |
| 1882 // FP arguments are passed in GP reg if first argument is in GP. | 1891 // 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 | 1892 // In this case type of the Dest is still FP thus we need to |
| 1884 // explicitly generate lw instead of lwc1. | 1893 // explicitly generate lw instead of lwc1. |
| 1885 if (DestTy == IceType_f32 && IsDstGPReg) { | 1894 if (DestTy == IceType_f32 && IsDstGPReg) { |
| 1886 Variable *DstGPR = Target->makeReg(IceType_i32, RegNum); | 1895 Variable *DstGPR = Target->makeReg(IceType_i32, RegNum); |
| 1887 Target->_lw(DstGPR, Addr); | 1896 Sandboxer(Target).lw(DstGPR, Addr); |
| 1888 } else if (DestTy == IceType_f64 && IsDstGPReg) { | 1897 } else if (DestTy == IceType_f64 && IsDstGPReg) { |
| 1889 Variable *DstGPRHi = Target->makeReg( | 1898 Variable *DstGPRHi = Target->makeReg( |
| 1890 IceType_i32, RegMIPS32::get64PairFirstRegNum(RegNum)); | 1899 IceType_i32, RegMIPS32::get64PairFirstRegNum(RegNum)); |
| 1891 Variable *DstGPRLo = Target->makeReg( | 1900 Variable *DstGPRLo = Target->makeReg( |
| 1892 IceType_i32, RegMIPS32::get64PairSecondRegNum(RegNum)); | 1901 IceType_i32, RegMIPS32::get64PairSecondRegNum(RegNum)); |
| 1893 Target->_lw(DstGPRHi, Addr); | 1902 Sandboxer(Target).lw(DstGPRHi, Addr); |
| 1894 OperandMIPS32Mem *AddrHi = legalizeMemOperand(TAddrHi); | 1903 OperandMIPS32Mem *AddrHi = legalizeMemOperand(TAddrHi); |
| 1895 Target->_lw(DstGPRLo, AddrHi); | 1904 Sandboxer(Target).lw(DstGPRLo, AddrHi); |
| 1896 } else if (DestTy == IceType_f64 && IsDstGPReg) { | 1905 } else if (DestTy == IceType_f64 && IsDstGPReg) { |
| 1897 const auto FirstReg = | 1906 const auto FirstReg = |
| 1898 (llvm::cast<Variable>(MovInstr->getSrc(0)))->getRegNum(); | 1907 (llvm::cast<Variable>(MovInstr->getSrc(0)))->getRegNum(); |
| 1899 const auto SecondReg = | 1908 const auto SecondReg = |
| 1900 (llvm::cast<Variable>(MovInstr->getSrc(1)))->getRegNum(); | 1909 (llvm::cast<Variable>(MovInstr->getSrc(1)))->getRegNum(); |
| 1901 Variable *DstGPRHi = Target->makeReg(IceType_i32, FirstReg); | 1910 Variable *DstGPRHi = Target->makeReg(IceType_i32, FirstReg); |
| 1902 Variable *DstGPRLo = Target->makeReg(IceType_i32, SecondReg); | 1911 Variable *DstGPRLo = Target->makeReg(IceType_i32, SecondReg); |
| 1903 Target->_lw(DstGPRLo, Addr); | 1912 Sandboxer(Target).lw(DstGPRLo, Addr); |
| 1904 OperandMIPS32Mem *AddrHi = legalizeMemOperand(TAddrHi); | 1913 OperandMIPS32Mem *AddrHi = legalizeMemOperand(TAddrHi); |
| 1905 Target->_lw(DstGPRHi, AddrHi); | 1914 Sandboxer(Target).lw(DstGPRHi, AddrHi); |
| 1906 } else { | 1915 } else { |
| 1907 Target->_lw(Dest, Addr); | 1916 Sandboxer(Target).lw(Dest, Addr); |
| 1908 } | 1917 } |
| 1909 } | 1918 } |
| 1910 Legalized = true; | 1919 Legalized = true; |
| 1911 } | 1920 } |
| 1912 } | 1921 } |
| 1913 } | 1922 } |
| 1914 | 1923 |
| 1915 if (Legalized) { | 1924 if (Legalized) { |
| 1916 if (MovInstr->isDestRedefined()) { | 1925 if (MovInstr->isDestRedefined()) { |
| 1917 Target->_set_dest_redefined(); | 1926 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); | 1991 auto *Src0V = llvm::dyn_cast_or_null<Variable>(Src0); |
| 1983 auto *Src0M = llvm::dyn_cast_or_null<OperandMIPS32Mem>(Src0); | 1992 auto *Src0M = llvm::dyn_cast_or_null<OperandMIPS32Mem>(Src0); |
| 1984 auto *Src1M = llvm::dyn_cast_or_null<OperandMIPS32Mem>(Src1); | 1993 auto *Src1M = llvm::dyn_cast_or_null<OperandMIPS32Mem>(Src1); |
| 1985 Variable *Dst = CurInstr->getDest(); | 1994 Variable *Dst = CurInstr->getDest(); |
| 1986 if (auto *MovInstr = llvm::dyn_cast<InstMIPS32Mov>(CurInstr)) { | 1995 if (auto *MovInstr = llvm::dyn_cast<InstMIPS32Mov>(CurInstr)) { |
| 1987 Legalizer.legalizeMov(MovInstr); | 1996 Legalizer.legalizeMov(MovInstr); |
| 1988 continue; | 1997 continue; |
| 1989 } | 1998 } |
| 1990 if (llvm::isa<InstMIPS32Sw>(CurInstr)) { | 1999 if (llvm::isa<InstMIPS32Sw>(CurInstr)) { |
| 1991 if (auto *LegalMem = Legalizer.legalizeMemOperand(Src1M)) { | 2000 if (auto *LegalMem = Legalizer.legalizeMemOperand(Src1M)) { |
| 1992 _sw(Src0V, LegalMem); | 2001 Sandboxer(this).sw(Src0V, LegalMem); |
| 1993 CurInstr->setDeleted(); | 2002 CurInstr->setDeleted(); |
| 1994 } | 2003 } |
| 1995 continue; | 2004 continue; |
| 1996 } | 2005 } |
| 1997 if (llvm::isa<InstMIPS32Swc1>(CurInstr)) { | 2006 if (llvm::isa<InstMIPS32Swc1>(CurInstr)) { |
| 1998 if (auto *LegalMem = Legalizer.legalizeMemOperand(Src1M)) { | 2007 if (auto *LegalMem = Legalizer.legalizeMemOperand(Src1M)) { |
| 1999 _swc1(Src0V, LegalMem); | 2008 _swc1(Src0V, LegalMem); |
| 2000 CurInstr->setDeleted(); | 2009 CurInstr->setDeleted(); |
| 2001 } | 2010 } |
| 2002 continue; | 2011 continue; |
| 2003 } | 2012 } |
| 2004 if (llvm::isa<InstMIPS32Sdc1>(CurInstr)) { | 2013 if (llvm::isa<InstMIPS32Sdc1>(CurInstr)) { |
| 2005 if (auto *LegalMem = Legalizer.legalizeMemOperand(Src1M)) { | 2014 if (auto *LegalMem = Legalizer.legalizeMemOperand(Src1M)) { |
| 2006 _sdc1(Src0V, LegalMem); | 2015 _sdc1(Src0V, LegalMem); |
| 2007 CurInstr->setDeleted(); | 2016 CurInstr->setDeleted(); |
| 2008 } | 2017 } |
| 2009 continue; | 2018 continue; |
| 2010 } | 2019 } |
| 2011 if (llvm::isa<InstMIPS32Lw>(CurInstr)) { | 2020 if (llvm::isa<InstMIPS32Lw>(CurInstr)) { |
| 2012 if (auto *LegalMem = Legalizer.legalizeMemOperand(Src0M)) { | 2021 if (auto *LegalMem = Legalizer.legalizeMemOperand(Src0M)) { |
| 2013 _lw(Dst, LegalMem); | 2022 Sandboxer(this).lw(Dst, LegalMem); |
| 2014 CurInstr->setDeleted(); | 2023 CurInstr->setDeleted(); |
| 2015 } | 2024 } |
| 2016 continue; | 2025 continue; |
| 2017 } | 2026 } |
| 2018 if (llvm::isa<InstMIPS32Lwc1>(CurInstr)) { | 2027 if (llvm::isa<InstMIPS32Lwc1>(CurInstr)) { |
| 2019 if (auto *LegalMem = Legalizer.legalizeMemOperand(Src0M)) { | 2028 if (auto *LegalMem = Legalizer.legalizeMemOperand(Src0M)) { |
| 2020 _lwc1(Dst, LegalMem); | 2029 _lwc1(Dst, LegalMem); |
| 2021 CurInstr->setDeleted(); | 2030 CurInstr->setDeleted(); |
| 2022 } | 2031 } |
| 2023 continue; | 2032 continue; |
| (...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2157 Registers[RegMIPS32::val] = false; \ | 2166 Registers[RegMIPS32::val] = false; \ |
| 2158 if (stackptr && (Exclude & RegSet_StackPointer)) \ | 2167 if (stackptr && (Exclude & RegSet_StackPointer)) \ |
| 2159 Registers[RegMIPS32::val] = false; \ | 2168 Registers[RegMIPS32::val] = false; \ |
| 2160 if (frameptr && (Exclude & RegSet_FramePointer)) \ | 2169 if (frameptr && (Exclude & RegSet_FramePointer)) \ |
| 2161 Registers[RegMIPS32::val] = false; | 2170 Registers[RegMIPS32::val] = false; |
| 2162 | 2171 |
| 2163 REGMIPS32_TABLE | 2172 REGMIPS32_TABLE |
| 2164 | 2173 |
| 2165 #undef X | 2174 #undef X |
| 2166 | 2175 |
| 2176 if (NeedSandboxing) { |
| 2177 Registers[RegMIPS32::Reg_T6] = false; |
| 2178 Registers[RegMIPS32::Reg_T7] = false; |
| 2179 Registers[RegMIPS32::Reg_T8] = false; |
| 2180 } |
| 2167 return Registers; | 2181 return Registers; |
| 2168 } | 2182 } |
| 2169 | 2183 |
| 2170 void TargetMIPS32::lowerAlloca(const InstAlloca *Instr) { | 2184 void TargetMIPS32::lowerAlloca(const InstAlloca *Instr) { |
| 2171 // Conservatively require the stack to be aligned. Some stack adjustment | 2185 // Conservatively require the stack to be aligned. Some stack adjustment |
| 2172 // operations implemented below assume that the stack is aligned before the | 2186 // operations implemented below assume that the stack is aligned before the |
| 2173 // alloca. All the alloca code ensures that the stack alignment is preserved | 2187 // alloca. All the alloca code ensures that the stack alignment is preserved |
| 2174 // after the alloca. The stack alignment restriction can be relaxed in some | 2188 // after the alloca. The stack alignment restriction can be relaxed in some |
| 2175 // cases. | 2189 // cases. |
| 2176 NeedsStackAlignment = true; | 2190 NeedsStackAlignment = true; |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2241 _and(T3, T1, T2); | 2255 _and(T3, T1, T2); |
| 2242 _subu(T4, SP, T3); | 2256 _subu(T4, SP, T3); |
| 2243 if (Instr->getAlignInBytes()) { | 2257 if (Instr->getAlignInBytes()) { |
| 2244 AlignAmount = | 2258 AlignAmount = |
| 2245 legalizeToReg(Ctx->getConstantInt32(-AlignmentParam), Legal_Reg); | 2259 legalizeToReg(Ctx->getConstantInt32(-AlignmentParam), Legal_Reg); |
| 2246 _and(T5, T4, AlignAmount); | 2260 _and(T5, T4, AlignAmount); |
| 2247 _mov(Dest, T5); | 2261 _mov(Dest, T5); |
| 2248 } else { | 2262 } else { |
| 2249 _mov(Dest, T4); | 2263 _mov(Dest, T4); |
| 2250 } | 2264 } |
| 2251 _mov(SP, Dest); | 2265 if (OptM1) |
| 2266 _mov(SP, Dest); |
| 2267 else |
| 2268 Sandboxer(this).reset_sp(Dest); |
| 2252 return; | 2269 return; |
| 2253 } | 2270 } |
| 2254 } | 2271 } |
| 2255 | 2272 |
| 2256 void TargetMIPS32::lowerInt64Arithmetic(const InstArithmetic *Instr, | 2273 void TargetMIPS32::lowerInt64Arithmetic(const InstArithmetic *Instr, |
| 2257 Variable *Dest, Operand *Src0, | 2274 Variable *Dest, Operand *Src0, |
| 2258 Operand *Src1) { | 2275 Operand *Src1) { |
| 2259 InstArithmetic::OpKind Op = Instr->getOp(); | 2276 InstArithmetic::OpKind Op = Instr->getOp(); |
| 2260 auto *DestLo = llvm::cast<Variable>(loOperand(Dest)); | 2277 auto *DestLo = llvm::cast<Variable>(loOperand(Dest)); |
| 2261 auto *DestHi = llvm::cast<Variable>(hiOperand(Dest)); | 2278 auto *DestHi = llvm::cast<Variable>(hiOperand(Dest)); |
| (...skipping 984 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. | 3263 // 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 | 3264 // These fake-uses need to be placed here to avoid argument registers from |
| 3248 // being used during the legalizeToReg() calls above. | 3265 // being used during the legalizeToReg() calls above. |
| 3249 for (auto *RegArg : RegArgs) { | 3266 for (auto *RegArg : RegArgs) { |
| 3250 Context.insert<InstFakeUse>(RegArg); | 3267 Context.insert<InstFakeUse>(RegArg); |
| 3251 } | 3268 } |
| 3252 | 3269 |
| 3253 // If variable alloca is used the extra 16 bytes for argument build area | 3270 // If variable alloca is used the extra 16 bytes for argument build area |
| 3254 // will be allocated on stack before a call. | 3271 // will be allocated on stack before a call. |
| 3255 if (VariableAllocaUsed) | 3272 if (VariableAllocaUsed) |
| 3256 _addiu(SP, SP, -MaxOutArgsSizeBytes); | 3273 Sandboxer(this).addiu_sp(-MaxOutArgsSizeBytes); |
| 3257 | 3274 |
| 3258 Inst *NewCall; | 3275 Inst *NewCall; |
| 3259 | 3276 |
| 3260 // We don't need to define the return register if it is a vector. | 3277 // 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. | 3278 // We have inserted fake defs of it just after the call. |
| 3262 if (ReturnReg && isVectorIntegerType(ReturnReg->getType())) { | 3279 if (ReturnReg && isVectorIntegerType(ReturnReg->getType())) { |
| 3263 Variable *RetReg = nullptr; | 3280 Variable *RetReg = nullptr; |
| 3264 NewCall = InstMIPS32Call::create(Func, RetReg, CallTarget); | 3281 NewCall = InstMIPS32Call::create(Func, RetReg, CallTarget); |
| 3282 Context.insert(NewCall); |
| 3265 } else { | 3283 } else { |
| 3266 NewCall = InstMIPS32Call::create(Func, ReturnReg, CallTarget); | 3284 NewCall = Sandboxer(this, InstBundleLock::Opt_AlignToEnd) |
| 3285 .jal(ReturnReg, CallTarget); |
| 3267 } | 3286 } |
| 3268 Context.insert(NewCall); | |
| 3269 | 3287 |
| 3270 if (VariableAllocaUsed) | 3288 if (VariableAllocaUsed) |
| 3271 _addiu(SP, SP, MaxOutArgsSizeBytes); | 3289 Sandboxer(this).addiu_sp(MaxOutArgsSizeBytes); |
| 3272 | 3290 |
| 3273 // Insert a fake use of stack pointer to avoid dead code elimination of addiu | 3291 // Insert a fake use of stack pointer to avoid dead code elimination of addiu |
| 3274 // instruction. | 3292 // instruction. |
| 3275 Context.insert<InstFakeUse>(SP); | 3293 Context.insert<InstFakeUse>(SP); |
| 3276 | 3294 |
| 3277 if (ReturnRegHi) | 3295 if (ReturnRegHi) |
| 3278 Context.insert(InstFakeDef::create(Func, ReturnRegHi)); | 3296 Context.insert(InstFakeDef::create(Func, ReturnRegHi)); |
| 3279 | 3297 |
| 3280 if (ReturnReg) { | 3298 if (ReturnReg) { |
| 3281 if (auto *RetVec = llvm::dyn_cast<VariableVecOn32>(ReturnReg)) { | 3299 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 | 4518 UnimplementedLoweringError(this, Instr); // Not required for PNaCl |
| 4501 } | 4519 } |
| 4502 return; | 4520 return; |
| 4503 } | 4521 } |
| 4504 case Intrinsics::Stacksave: { | 4522 case Intrinsics::Stacksave: { |
| 4505 Variable *SP = getPhysicalRegister(RegMIPS32::Reg_SP); | 4523 Variable *SP = getPhysicalRegister(RegMIPS32::Reg_SP); |
| 4506 _mov(Dest, SP); | 4524 _mov(Dest, SP); |
| 4507 return; | 4525 return; |
| 4508 } | 4526 } |
| 4509 case Intrinsics::Stackrestore: { | 4527 case Intrinsics::Stackrestore: { |
| 4510 if (getFlags().getUseSandboxing()) { | |
| 4511 UnimplementedLoweringError(this, Instr); | |
| 4512 return; | |
| 4513 } | |
| 4514 Variable *Val = legalizeToReg(Instr->getArg(0)); | 4528 Variable *Val = legalizeToReg(Instr->getArg(0)); |
| 4515 Variable *SP = getPhysicalRegister(RegMIPS32::Reg_SP); | 4529 Sandboxer(this).reset_sp(Val); |
| 4516 _mov_redefined(SP, Val); | |
| 4517 return; | 4530 return; |
| 4518 } | 4531 } |
| 4519 case Intrinsics::Trap: { | 4532 case Intrinsics::Trap: { |
| 4520 const uint32_t TrapCodeZero = 0; | 4533 const uint32_t TrapCodeZero = 0; |
| 4521 _teq(getZero(), getZero(), TrapCodeZero); | 4534 _teq(getZero(), getZero(), TrapCodeZero); |
| 4522 return; | 4535 return; |
| 4523 } | 4536 } |
| 4524 case Intrinsics::LoadSubVector: { | 4537 case Intrinsics::LoadSubVector: { |
| 4525 UnimplementedLoweringError(this, Instr); // Not required for PNaCl | 4538 UnimplementedLoweringError(this, Instr); // Not required for PNaCl |
| 4526 return; | 4539 return; |
| (...skipping 780 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5307 Context.insert<InstFakeDef>(TReg); | 5320 Context.insert<InstFakeDef>(TReg); |
| 5308 _mov(TReg, getZero()); | 5321 _mov(TReg, getZero()); |
| 5309 } else { | 5322 } else { |
| 5310 // Load floats/doubles from literal pool. | 5323 // Load floats/doubles from literal pool. |
| 5311 Constant *Offset = Ctx->getConstantSym(0, CFrom->getLabelName()); | 5324 Constant *Offset = Ctx->getConstantSym(0, CFrom->getLabelName()); |
| 5312 Variable *TReg1 = makeReg(getPointerType()); | 5325 Variable *TReg1 = makeReg(getPointerType()); |
| 5313 _lui(TReg1, Offset, RO_Hi); | 5326 _lui(TReg1, Offset, RO_Hi); |
| 5314 OperandMIPS32Mem *Addr = | 5327 OperandMIPS32Mem *Addr = |
| 5315 OperandMIPS32Mem::create(Func, Ty, TReg1, Offset); | 5328 OperandMIPS32Mem::create(Func, Ty, TReg1, Offset); |
| 5316 if (Ty == IceType_f32) | 5329 if (Ty == IceType_f32) |
| 5317 _lwc1(TReg, Addr, RO_Lo); | 5330 Sandboxer(this).lwc1(TReg, Addr, RO_Lo); |
| 5318 else | 5331 else |
| 5319 _ldc1(TReg, Addr, RO_Lo); | 5332 Sandboxer(this).ldc1(TReg, Addr, RO_Lo); |
| 5320 } | 5333 } |
| 5321 return copyToReg(TReg, RegNum); | 5334 return copyToReg(TReg, RegNum); |
| 5322 } | 5335 } |
| 5323 } | 5336 } |
| 5324 | 5337 |
| 5325 if (auto *Var = llvm::dyn_cast<Variable>(From)) { | 5338 if (auto *Var = llvm::dyn_cast<Variable>(From)) { |
| 5326 if (Var->isRematerializable()) { | 5339 if (Var->isRematerializable()) { |
| 5327 if (Allowed & Legal_Rematerializable) { | 5340 if (Allowed & Legal_Rematerializable) { |
| 5328 return From; | 5341 return From; |
| 5329 } | 5342 } |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5426 Str << "\t.set\t" | 5439 Str << "\t.set\t" |
| 5427 << "nomips16\n"; | 5440 << "nomips16\n"; |
| 5428 Str << "\t.set\t" | 5441 Str << "\t.set\t" |
| 5429 << "noat\n"; | 5442 << "noat\n"; |
| 5430 } | 5443 } |
| 5431 | 5444 |
| 5432 SmallBitVector TargetMIPS32::TypeToRegisterSet[RCMIPS32_NUM]; | 5445 SmallBitVector TargetMIPS32::TypeToRegisterSet[RCMIPS32_NUM]; |
| 5433 SmallBitVector TargetMIPS32::TypeToRegisterSetUnfiltered[RCMIPS32_NUM]; | 5446 SmallBitVector TargetMIPS32::TypeToRegisterSetUnfiltered[RCMIPS32_NUM]; |
| 5434 SmallBitVector TargetMIPS32::RegisterAliases[RegMIPS32::Reg_NUM]; | 5447 SmallBitVector TargetMIPS32::RegisterAliases[RegMIPS32::Reg_NUM]; |
| 5435 | 5448 |
| 5449 TargetMIPS32::Sandboxer::Sandboxer(TargetMIPS32 *Target, |
| 5450 InstBundleLock::Option BundleOption) |
| 5451 : Target(Target), BundleOption(BundleOption) {} |
| 5452 |
| 5453 TargetMIPS32::Sandboxer::~Sandboxer() {} |
| 5454 |
| 5455 void TargetMIPS32::Sandboxer::createAutoBundle() { |
| 5456 Bundler = makeUnique<AutoBundle>(Target, BundleOption); |
| 5457 } |
| 5458 |
| 5459 void TargetMIPS32::Sandboxer::addiu_sp(uint32_t StackOffset) { |
| 5460 Variable *SP = Target->getPhysicalRegister(RegMIPS32::Reg_SP); |
| 5461 if (!Target->NeedSandboxing) { |
| 5462 Target->_addiu(SP, SP, StackOffset); |
| 5463 return; |
| 5464 } |
| 5465 Variable *T7 = Target->getPhysicalRegister(RegMIPS32::Reg_T7); |
| 5466 createAutoBundle(); |
| 5467 Target->_addiu(SP, SP, StackOffset); |
| 5468 Target->_and(SP, SP, T7); |
| 5469 } |
| 5470 |
| 5471 void TargetMIPS32::Sandboxer::lw(Variable *Dest, OperandMIPS32Mem *Mem) { |
| 5472 Variable *Base = Mem->getBase(); |
| 5473 Variable *T7 = Target->getPhysicalRegister(RegMIPS32::Reg_T7); |
| 5474 if (Target->NeedSandboxing && (Target->getStackReg() != Base->getRegNum())) { |
| 5475 createAutoBundle(); |
| 5476 Target->_and(Base, Base, T7); |
| 5477 } |
| 5478 Target->_lw(Dest, Mem); |
| 5479 if (Target->NeedSandboxing && (Dest->getRegNum() == Target->getStackReg())) |
| 5480 Target->_and(Dest, Dest, T7); |
| 5481 } |
| 5482 |
| 5483 void TargetMIPS32::Sandboxer::sw(Variable *Dest, OperandMIPS32Mem *Mem) { |
| 5484 Variable *Base = Mem->getBase(); |
| 5485 Variable *T7 = Target->getPhysicalRegister(RegMIPS32::Reg_T7); |
| 5486 if (Target->NeedSandboxing && (Target->getStackReg() != Base->getRegNum())) { |
| 5487 createAutoBundle(); |
| 5488 Target->_and(Base, Base, T7); |
| 5489 } |
| 5490 Target->_sw(Dest, Mem); |
| 5491 } |
| 5492 |
| 5493 void TargetMIPS32::Sandboxer::lwc1(Variable *Dest, OperandMIPS32Mem *Mem, |
| 5494 RelocOp Reloc) { |
| 5495 Variable *Base = Mem->getBase(); |
| 5496 Variable *T7 = Target->getPhysicalRegister(RegMIPS32::Reg_T7); |
| 5497 if (Target->NeedSandboxing && (Target->getStackReg() != Base->getRegNum())) { |
| 5498 createAutoBundle(); |
| 5499 Target->_and(Base, Base, T7); |
| 5500 } |
| 5501 Target->_lwc1(Dest, Mem, Reloc); |
| 5502 if (Target->NeedSandboxing && (Dest->getRegNum() == Target->getStackReg())) |
| 5503 Target->_and(Dest, Dest, T7); |
| 5504 } |
| 5505 |
| 5506 void TargetMIPS32::Sandboxer::ldc1(Variable *Dest, OperandMIPS32Mem *Mem, |
| 5507 RelocOp Reloc) { |
| 5508 Variable *Base = Mem->getBase(); |
| 5509 Variable *T7 = Target->getPhysicalRegister(RegMIPS32::Reg_T7); |
| 5510 if (Target->NeedSandboxing && (Target->getStackReg() != Base->getRegNum())) { |
| 5511 createAutoBundle(); |
| 5512 Target->_and(Base, Base, T7); |
| 5513 } |
| 5514 Target->_ldc1(Dest, Mem, Reloc); |
| 5515 if (Target->NeedSandboxing && (Dest->getRegNum() == Target->getStackReg())) |
| 5516 Target->_and(Dest, Dest, T7); |
| 5517 } |
| 5518 |
| 5519 void TargetMIPS32::Sandboxer::ret(Variable *RetAddr, Variable *RetValue) { |
| 5520 if (!Target->NeedSandboxing) { |
| 5521 Target->_ret(RetAddr, RetValue); |
| 5522 } |
| 5523 Variable *T6 = Target->getPhysicalRegister(RegMIPS32::Reg_T6); |
| 5524 createAutoBundle(); |
| 5525 Target->_and(RetAddr, RetAddr, T6); |
| 5526 Target->_ret(RetAddr, RetValue); |
| 5527 } |
| 5528 |
| 5529 void TargetMIPS32::Sandboxer::reset_sp(Variable *Src) { |
| 5530 Variable *SP = Target->getPhysicalRegister(RegMIPS32::Reg_SP); |
| 5531 if (!Target->NeedSandboxing) { |
| 5532 Target->_mov(SP, Src); |
| 5533 return; |
| 5534 } |
| 5535 Variable *T7 = Target->getPhysicalRegister(RegMIPS32::Reg_T7); |
| 5536 createAutoBundle(); |
| 5537 Target->_mov(SP, Src); |
| 5538 Target->_and(SP, SP, T7); |
| 5539 } |
| 5540 |
| 5541 InstMIPS32Call *TargetMIPS32::Sandboxer::jal(Variable *ReturnReg, |
| 5542 Operand *CallTarget) { |
| 5543 if (Target->NeedSandboxing) |
| 5544 createAutoBundle(); |
| 5545 return Target->Context.insert<InstMIPS32Call>(ReturnReg, CallTarget); |
| 5546 } |
| 5547 |
| 5436 } // end of namespace MIPS32 | 5548 } // end of namespace MIPS32 |
| 5437 } // end of namespace Ice | 5549 } // end of namespace Ice |
| OLD | NEW |