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 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
90 | 90 |
91 // Stack alignment | 91 // Stack alignment |
92 constexpr uint32_t MIPS32_STACK_ALIGNMENT_BYTES = 16; | 92 constexpr uint32_t MIPS32_STACK_ALIGNMENT_BYTES = 16; |
93 | 93 |
94 // Value is in bytes. Return Value adjusted to the next highest multiple of the | 94 // Value is in bytes. Return Value adjusted to the next highest multiple of the |
95 // stack alignment required for the given type. | 95 // stack alignment required for the given type. |
96 uint32_t applyStackAlignmentTy(uint32_t Value, Type Ty) { | 96 uint32_t applyStackAlignmentTy(uint32_t Value, Type Ty) { |
97 size_t typeAlignInBytes = typeWidthInBytes(Ty); | 97 size_t typeAlignInBytes = typeWidthInBytes(Ty); |
98 // Vectors are stored on stack with the same alignment as that of int type | 98 // Vectors are stored on stack with the same alignment as that of int type |
99 if (isVectorType(Ty)) | 99 if (isVectorType(Ty)) |
100 typeAlignInBytes = typeWidthInBytes(IceType_i32); | 100 typeAlignInBytes = typeWidthInBytes(IceType_i64); |
101 return Utils::applyAlignment(Value, typeAlignInBytes); | 101 return Utils::applyAlignment(Value, typeAlignInBytes); |
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 |
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
233 PartialOnStack = true; | 233 PartialOnStack = true; |
234 } | 234 } |
235 for (SizeT i = 0, NumArgs = Call->getNumArgs(); i < NumArgs; ++i) { | 235 for (SizeT i = 0, NumArgs = Call->getNumArgs(); i < NumArgs; ++i) { |
236 Operand *Arg = legalizeUndef(Call->getArg(i)); | 236 Operand *Arg = legalizeUndef(Call->getArg(i)); |
237 const Type Ty = Arg->getType(); | 237 const Type Ty = Arg->getType(); |
238 RegNumT RegNum; | 238 RegNumT RegNum; |
239 if (CC.argInReg(Ty, i, &RegNum)) { | 239 if (CC.argInReg(Ty, i, &RegNum)) { |
240 // If PartialOnStack is true and if this is a vector type then last two | 240 // If PartialOnStack is true and if this is a vector type then last two |
241 // elements are on stack | 241 // elements are on stack |
242 if (PartialOnStack && isVectorType(Ty)) { | 242 if (PartialOnStack && isVectorType(Ty)) { |
243 OutArgsSizeBytes = applyStackAlignmentTy(OutArgsSizeBytes, IceType_i32); | 243 OutArgsSizeBytes = applyStackAlignmentTy(OutArgsSizeBytes, IceType_i64); |
244 OutArgsSizeBytes += typeWidthInBytesOnStack(IceType_i32) * 2; | 244 OutArgsSizeBytes += typeWidthInBytesOnStack(IceType_i32) * 2; |
245 } | 245 } |
246 continue; | 246 continue; |
247 } | 247 } |
248 OutArgsSizeBytes = applyStackAlignmentTy(OutArgsSizeBytes, Ty); | 248 OutArgsSizeBytes = applyStackAlignmentTy(OutArgsSizeBytes, Ty); |
249 OutArgsSizeBytes += typeWidthInBytesOnStack(Ty); | 249 OutArgsSizeBytes += typeWidthInBytesOnStack(Ty); |
250 } | 250 } |
251 // Add size of argument save area | 251 // Add size of argument save area |
252 constexpr int BytesPerStackArg = 4; | 252 constexpr int BytesPerStackArg = 4; |
253 OutArgsSizeBytes += MIPS32_MAX_GPR_ARG * BytesPerStackArg; | 253 OutArgsSizeBytes += MIPS32_MAX_GPR_ARG * BytesPerStackArg; |
(...skipping 726 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
980 // Context.insert(InstFakeDef::create(Func, Reg)); | 980 // Context.insert(InstFakeDef::create(Func, Reg)); |
981 // This is in order to ensure that the live range of Reg is not | 981 // This is in order to ensure that the live range of Reg is not |
982 // overestimated. If the constant being lowered is a 64 bit value, | 982 // overestimated. If the constant being lowered is a 64 bit value, |
983 // then the result should be split and the lo and hi components will | 983 // then the result should be split and the lo and hi components will |
984 // need to go in uninitialized registers. | 984 // need to go in uninitialized registers. |
985 if (isVectorType(Ty)) { | 985 if (isVectorType(Ty)) { |
986 Variable *Var = makeReg(Ty, RegNum); | 986 Variable *Var = makeReg(Ty, RegNum); |
987 auto *Reg = llvm::cast<VariableVecOn32>(Var); | 987 auto *Reg = llvm::cast<VariableVecOn32>(Var); |
988 Reg->initVecElement(Func); | 988 Reg->initVecElement(Func); |
989 auto *Zero = getZero(); | 989 auto *Zero = getZero(); |
990 Context.insert<InstFakeDef>(Zero); | |
991 for (Variable *Var : Reg->getContainers()) { | 990 for (Variable *Var : Reg->getContainers()) { |
992 _mov(Var, Zero); | 991 _mov(Var, Zero); |
993 } | 992 } |
994 return Reg; | 993 return Reg; |
995 } | 994 } |
996 return Ctx->getConstantZero(Ty); | 995 return Ctx->getConstantZero(Ty); |
997 } | 996 } |
998 return From; | 997 return From; |
999 } | 998 } |
1000 | 999 |
(...skipping 467 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1468 | 1467 |
1469 // RegClasses is a tuple of | 1468 // RegClasses is a tuple of |
1470 // | 1469 // |
1471 // <First Register in Class, Last Register in Class, Vector of Save Registers> | 1470 // <First Register in Class, Last Register in Class, Vector of Save Registers> |
1472 // | 1471 // |
1473 // We use this tuple to figure out which register we should save/restore | 1472 // We use this tuple to figure out which register we should save/restore |
1474 // during | 1473 // during |
1475 // prolog/epilog. | 1474 // prolog/epilog. |
1476 using RegClassType = std::tuple<uint32_t, uint32_t, VarList *>; | 1475 using RegClassType = std::tuple<uint32_t, uint32_t, VarList *>; |
1477 const RegClassType RegClass = RegClassType( | 1476 const RegClassType RegClass = RegClassType( |
1478 RegMIPS32::Reg_GPR_First, RegMIPS32::Reg_GPR_Last, &PreservedGPRs); | 1477 RegMIPS32::Reg_GPR_First, RegMIPS32::Reg_FPR_Last, &PreservedGPRs); |
1479 const uint32_t FirstRegInClass = std::get<0>(RegClass); | 1478 const uint32_t FirstRegInClass = std::get<0>(RegClass); |
1480 const uint32_t LastRegInClass = std::get<1>(RegClass); | 1479 const uint32_t LastRegInClass = std::get<1>(RegClass); |
1481 VarList *const PreservedRegsInClass = std::get<2>(RegClass); | 1480 VarList *const PreservedRegsInClass = std::get<2>(RegClass); |
1482 for (uint32_t Reg = LastRegInClass; Reg > FirstRegInClass; Reg--) { | 1481 for (uint32_t Reg = LastRegInClass; Reg > FirstRegInClass; Reg--) { |
1483 if (!ToPreserve[Reg]) { | 1482 if (!ToPreserve[Reg]) { |
1484 continue; | 1483 continue; |
1485 } | 1484 } |
1486 ++NumCallee; | 1485 ++NumCallee; |
1487 Variable *PhysicalRegister = getPhysicalRegister(RegNumT::fromInt(Reg)); | 1486 Variable *PhysicalRegister = getPhysicalRegister(RegNumT::fromInt(Reg)); |
1488 PreservedRegsSizeBytes += | 1487 PreservedRegsSizeBytes += |
(...skipping 24 matching lines...) Expand all Loading... |
1513 SpillAreaSizeBytes += MaxOutArgsSizeBytes * (VariableAllocaUsed ? 0 : 1); | 1512 SpillAreaSizeBytes += MaxOutArgsSizeBytes * (VariableAllocaUsed ? 0 : 1); |
1514 } else { | 1513 } else { |
1515 SpillAreaSizeBytes = applyStackAlignment( | 1514 SpillAreaSizeBytes = applyStackAlignment( |
1516 SpillAreaSizeBytes + | 1515 SpillAreaSizeBytes + |
1517 (VariableAllocaUsed ? VariableAllocaAlignBytes : MaxOutArgsSizeBytes)); | 1516 (VariableAllocaUsed ? VariableAllocaAlignBytes : MaxOutArgsSizeBytes)); |
1518 } | 1517 } |
1519 | 1518 |
1520 // Combine fixed alloca with SpillAreaSize. | 1519 // Combine fixed alloca with SpillAreaSize. |
1521 SpillAreaSizeBytes += FixedAllocaSizeBytes; | 1520 SpillAreaSizeBytes += FixedAllocaSizeBytes; |
1522 | 1521 |
1523 TotalStackSizeBytes = PreservedRegsSizeBytes + SpillAreaSizeBytes; | 1522 TotalStackSizeBytes = |
| 1523 applyStackAlignment(PreservedRegsSizeBytes + SpillAreaSizeBytes); |
1524 | 1524 |
1525 // Generate "addiu sp, sp, -TotalStackSizeBytes" | 1525 // Generate "addiu sp, sp, -TotalStackSizeBytes" |
1526 if (TotalStackSizeBytes) { | 1526 if (TotalStackSizeBytes) { |
1527 // Use the scratch register if needed to legalize the immediate. | 1527 // Use the scratch register if needed to legalize the immediate. |
1528 Sandboxer(this).addiu_sp(-TotalStackSizeBytes); | 1528 Sandboxer(this).addiu_sp(-TotalStackSizeBytes); |
1529 } | 1529 } |
1530 | 1530 |
1531 Ctx->statsUpdateFrameBytes(TotalStackSizeBytes); | 1531 Ctx->statsUpdateFrameBytes(TotalStackSizeBytes); |
1532 | 1532 |
1533 if (!PreservedGPRs.empty()) { | 1533 if (!PreservedGPRs.empty()) { |
1534 uint32_t StackOffset = TotalStackSizeBytes; | 1534 uint32_t StackOffset = TotalStackSizeBytes; |
1535 for (Variable *Var : *PreservedRegsInClass) { | 1535 for (Variable *Var : *PreservedRegsInClass) { |
1536 Variable *PhysicalRegister = getPhysicalRegister(Var->getRegNum()); | 1536 Type RegType; |
1537 StackOffset -= typeWidthInBytesOnStack(PhysicalRegister->getType()); | 1537 if (RegMIPS32::isFPRReg(Var->getRegNum())) |
| 1538 RegType = IceType_f32; |
| 1539 else |
| 1540 RegType = IceType_i32; |
| 1541 auto *PhysicalRegister = makeReg(RegType, Var->getRegNum()); |
| 1542 StackOffset -= typeWidthInBytesOnStack(RegType); |
1538 Variable *SP = getPhysicalRegister(RegMIPS32::Reg_SP); | 1543 Variable *SP = getPhysicalRegister(RegMIPS32::Reg_SP); |
1539 OperandMIPS32Mem *MemoryLocation = OperandMIPS32Mem::create( | 1544 OperandMIPS32Mem *MemoryLocation = OperandMIPS32Mem::create( |
1540 Func, IceType_i32, SP, | 1545 Func, RegType, SP, |
1541 llvm::cast<ConstantInteger32>(Ctx->getConstantInt32(StackOffset))); | 1546 llvm::cast<ConstantInteger32>(Ctx->getConstantInt32(StackOffset))); |
1542 Sandboxer(this).sw(PhysicalRegister, MemoryLocation); | 1547 Sandboxer(this).sw(PhysicalRegister, MemoryLocation); |
1543 } | 1548 } |
1544 } | 1549 } |
1545 | 1550 |
1546 Variable *FP = getPhysicalRegister(RegMIPS32::Reg_FP); | 1551 Variable *FP = getPhysicalRegister(RegMIPS32::Reg_FP); |
1547 | 1552 |
1548 // Generate "mov FP, SP" if needed. | 1553 // Generate "mov FP, SP" if needed. |
1549 if (UsesFramePointer) { | 1554 if (UsesFramePointer) { |
1550 Variable *SP = getPhysicalRegister(RegMIPS32::Reg_SP); | 1555 Variable *SP = getPhysicalRegister(RegMIPS32::Reg_SP); |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1645 Context.insert<InstFakeUse>(SP); | 1650 Context.insert<InstFakeUse>(SP); |
1646 Sandboxer(this).reset_sp(FP); | 1651 Sandboxer(this).reset_sp(FP); |
1647 } | 1652 } |
1648 | 1653 |
1649 VarList::reverse_iterator RIter, END; | 1654 VarList::reverse_iterator RIter, END; |
1650 | 1655 |
1651 if (!PreservedGPRs.empty()) { | 1656 if (!PreservedGPRs.empty()) { |
1652 uint32_t StackOffset = TotalStackSizeBytes - PreservedRegsSizeBytes; | 1657 uint32_t StackOffset = TotalStackSizeBytes - PreservedRegsSizeBytes; |
1653 for (RIter = PreservedGPRs.rbegin(), END = PreservedGPRs.rend(); | 1658 for (RIter = PreservedGPRs.rbegin(), END = PreservedGPRs.rend(); |
1654 RIter != END; ++RIter) { | 1659 RIter != END; ++RIter) { |
1655 Variable *PhysicalRegister = getPhysicalRegister((*RIter)->getRegNum()); | 1660 Type RegType; |
| 1661 if (RegMIPS32::isFPRReg((*RIter)->getRegNum())) |
| 1662 RegType = IceType_f32; |
| 1663 else |
| 1664 RegType = IceType_i32; |
| 1665 auto *PhysicalRegister = makeReg(RegType, (*RIter)->getRegNum()); |
1656 Variable *SP = getPhysicalRegister(RegMIPS32::Reg_SP); | 1666 Variable *SP = getPhysicalRegister(RegMIPS32::Reg_SP); |
1657 OperandMIPS32Mem *MemoryLocation = OperandMIPS32Mem::create( | 1667 OperandMIPS32Mem *MemoryLocation = OperandMIPS32Mem::create( |
1658 Func, IceType_i32, SP, | 1668 Func, RegType, SP, |
1659 llvm::cast<ConstantInteger32>(Ctx->getConstantInt32(StackOffset))); | 1669 llvm::cast<ConstantInteger32>(Ctx->getConstantInt32(StackOffset))); |
1660 _lw(PhysicalRegister, MemoryLocation); | 1670 _lw(PhysicalRegister, MemoryLocation); |
1661 StackOffset += typeWidthInBytesOnStack(PhysicalRegister->getType()); | 1671 StackOffset += typeWidthInBytesOnStack(PhysicalRegister->getType()); |
1662 } | 1672 } |
1663 } | 1673 } |
1664 | 1674 |
1665 if (TotalStackSizeBytes) { | 1675 if (TotalStackSizeBytes) { |
1666 Sandboxer(this).addiu_sp(TotalStackSizeBytes); | 1676 Sandboxer(this).addiu_sp(TotalStackSizeBytes); |
1667 } | 1677 } |
1668 if (!getFlags().getUseSandboxing()) | 1678 if (!getFlags().getUseSandboxing()) |
(...skipping 27 matching lines...) Expand all Loading... |
1696 Target->_ori(ScratchReg, ScratchReg, LowerBits); | 1706 Target->_ori(ScratchReg, ScratchReg, LowerBits); |
1697 Target->_addu(ScratchReg, ScratchReg, Base); | 1707 Target->_addu(ScratchReg, ScratchReg, Base); |
1698 } else { | 1708 } else { |
1699 Target->_addiu(ScratchReg, Base, Offset); | 1709 Target->_addiu(ScratchReg, Base, Offset); |
1700 } | 1710 } |
1701 } | 1711 } |
1702 | 1712 |
1703 return ScratchReg; | 1713 return ScratchReg; |
1704 } | 1714 } |
1705 | 1715 |
| 1716 void TargetMIPS32::PostLoweringLegalizer::legalizeMovFp( |
| 1717 InstMIPS32MovFP64ToI64 *MovInstr) { |
| 1718 Variable *Dest = MovInstr->getDest(); |
| 1719 Operand *Src = MovInstr->getSrc(0); |
| 1720 const Type SrcTy = Src->getType(); |
| 1721 |
| 1722 if (Dest != nullptr && SrcTy == IceType_f64) { |
| 1723 int32_t Offset = Dest->getStackOffset(); |
| 1724 auto *Base = Target->getPhysicalRegister(Target->getFrameOrStackReg()); |
| 1725 OperandMIPS32Mem *TAddr = OperandMIPS32Mem::create( |
| 1726 Target->Func, IceType_f32, Base, |
| 1727 llvm::cast<ConstantInteger32>(Target->Ctx->getConstantInt32(Offset))); |
| 1728 OperandMIPS32Mem *Addr = legalizeMemOperand(TAddr); |
| 1729 auto *SrcV = llvm::cast<Variable>(Src); |
| 1730 Variable *SrcR; |
| 1731 if (MovInstr->getInt64Part() == Int64_Lo) { |
| 1732 SrcR = Target->makeReg( |
| 1733 IceType_f32, RegMIPS32::get64PairFirstRegNum(SrcV->getRegNum())); |
| 1734 } else { |
| 1735 SrcR = Target->makeReg( |
| 1736 IceType_f32, RegMIPS32::get64PairSecondRegNum(SrcV->getRegNum())); |
| 1737 } |
| 1738 Sandboxer(Target).sw(SrcR, Addr); |
| 1739 if (MovInstr->isDestRedefined()) { |
| 1740 Target->_set_dest_redefined(); |
| 1741 } |
| 1742 MovInstr->setDeleted(); |
| 1743 return; |
| 1744 } |
| 1745 |
| 1746 llvm::report_fatal_error("legalizeMovFp: Invalid operands"); |
| 1747 } |
| 1748 |
1706 void TargetMIPS32::PostLoweringLegalizer::legalizeMov(InstMIPS32Mov *MovInstr) { | 1749 void TargetMIPS32::PostLoweringLegalizer::legalizeMov(InstMIPS32Mov *MovInstr) { |
1707 Variable *Dest = MovInstr->getDest(); | 1750 Variable *Dest = MovInstr->getDest(); |
1708 assert(Dest != nullptr); | 1751 assert(Dest != nullptr); |
1709 const Type DestTy = Dest->getType(); | 1752 const Type DestTy = Dest->getType(); |
1710 assert(DestTy != IceType_i64); | 1753 assert(DestTy != IceType_i64); |
1711 | 1754 |
1712 Operand *Src = MovInstr->getSrc(0); | 1755 Operand *Src = MovInstr->getSrc(0); |
1713 const Type SrcTy = Src->getType(); | 1756 const Type SrcTy = Src->getType(); |
1714 (void)SrcTy; | 1757 (void)SrcTy; |
1715 assert(SrcTy != IceType_i64); | 1758 assert(SrcTy != IceType_i64); |
(...skipping 24 matching lines...) Expand all Loading... |
1740 if (MovInstr->getDestHi() != nullptr && Dest != nullptr) { | 1783 if (MovInstr->getDestHi() != nullptr && Dest != nullptr) { |
1741 DstFPRHi = Target->makeReg(IceType_i32, | 1784 DstFPRHi = Target->makeReg(IceType_i32, |
1742 MovInstr->getDestHi()->getRegNum()); | 1785 MovInstr->getDestHi()->getRegNum()); |
1743 DstFPRLo = Target->makeReg(IceType_i32, Dest->getRegNum()); | 1786 DstFPRLo = Target->makeReg(IceType_i32, Dest->getRegNum()); |
1744 } else { | 1787 } else { |
1745 DstFPRHi = Target->makeReg( | 1788 DstFPRHi = Target->makeReg( |
1746 IceType_i32, RegMIPS32::get64PairFirstRegNum(DRegNum)); | 1789 IceType_i32, RegMIPS32::get64PairFirstRegNum(DRegNum)); |
1747 DstFPRLo = Target->makeReg( | 1790 DstFPRLo = Target->makeReg( |
1748 IceType_i32, RegMIPS32::get64PairSecondRegNum(DRegNum)); | 1791 IceType_i32, RegMIPS32::get64PairSecondRegNum(DRegNum)); |
1749 } | 1792 } |
1750 Target->_mov(DstFPRHi, SrcGPRLo); | 1793 Target->_mov(DstFPRHi, SrcGPRHi); |
1751 Target->_mov(DstFPRLo, SrcGPRHi); | 1794 Target->_mov(DstFPRLo, SrcGPRLo); |
1752 Legalized = true; | 1795 Legalized = true; |
1753 } else { | 1796 } else { |
1754 Variable *SrcGPR = Target->makeReg(IceType_f32, SRegNum); | 1797 Variable *SrcGPR = Target->makeReg(IceType_f32, SRegNum); |
1755 Variable *DstFPR = Target->makeReg(IceType_i32, DRegNum); | 1798 Variable *DstFPR = Target->makeReg(IceType_i32, DRegNum); |
1756 Target->_mov(DstFPR, SrcGPR); | 1799 Target->_mov(DstFPR, SrcGPR); |
1757 Legalized = true; | 1800 Legalized = true; |
1758 } | 1801 } |
1759 } else { | 1802 } else { |
1760 // Dest is FPR and SrcR is GPR. Use mtc1. | 1803 // Dest is FPR and SrcR is GPR. Use mtc1. |
1761 if (typeWidthInBytes(Dest->getType()) == 8) { | 1804 if (typeWidthInBytes(Dest->getType()) == 8) { |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1853 } | 1896 } |
1854 | 1897 |
1855 Target->Context.insert<InstFakeDef>(Dest); | 1898 Target->Context.insert<InstFakeDef>(Dest); |
1856 Legalized = true; | 1899 Legalized = true; |
1857 } else if (auto *Var = llvm::dyn_cast<Variable>(Src)) { | 1900 } else if (auto *Var = llvm::dyn_cast<Variable>(Src)) { |
1858 if (Var->isRematerializable()) { | 1901 if (Var->isRematerializable()) { |
1859 // This is equivalent to an x86 _lea(RematOffset(%esp/%ebp), Variable). | 1902 // This is equivalent to an x86 _lea(RematOffset(%esp/%ebp), Variable). |
1860 | 1903 |
1861 // ExtraOffset is only needed for stack-pointer based frames as we have | 1904 // ExtraOffset is only needed for stack-pointer based frames as we have |
1862 // to account for spill storage. | 1905 // to account for spill storage. |
1863 const int32_t ExtraOffset = (Var->getRegNum() == Target->getStackReg()) | 1906 const int32_t ExtraOffset = |
1864 ? Target->getFrameFixedAllocaOffset() | 1907 (Var->getRegNum() == Target->getFrameOrStackReg()) |
1865 : 0; | 1908 ? Target->getFrameFixedAllocaOffset() |
| 1909 : 0; |
1866 | 1910 |
1867 const int32_t Offset = Var->getStackOffset() + ExtraOffset; | 1911 const int32_t Offset = Var->getStackOffset() + ExtraOffset; |
1868 Variable *Base = Target->getPhysicalRegister(Var->getRegNum()); | 1912 Variable *Base = Target->getPhysicalRegister(Var->getRegNum()); |
1869 Variable *T = newBaseRegister(Base, Offset, Dest->getRegNum()); | 1913 Variable *T = newBaseRegister(Base, Offset, Dest->getRegNum()); |
1870 Target->_mov(Dest, T); | 1914 Target->_mov(Dest, T); |
1871 Legalized = true; | 1915 Legalized = true; |
1872 } else { | 1916 } else { |
1873 if (!Var->hasReg()) { | 1917 if (!Var->hasReg()) { |
1874 // This is a _mov(Variable, Mem()), i.e., a load. | 1918 // This is a _mov(Variable, Mem()), i.e., a load. |
1875 const int32_t Offset = Var->getStackOffset(); | 1919 const int32_t Offset = Var->getStackOffset(); |
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2011 Operand *Src0 = NumSrcs < 1 ? nullptr : CurInstr->getSrc(0); | 2055 Operand *Src0 = NumSrcs < 1 ? nullptr : CurInstr->getSrc(0); |
2012 Operand *Src1 = NumSrcs < 2 ? nullptr : CurInstr->getSrc(1); | 2056 Operand *Src1 = NumSrcs < 2 ? nullptr : CurInstr->getSrc(1); |
2013 auto *Src0V = llvm::dyn_cast_or_null<Variable>(Src0); | 2057 auto *Src0V = llvm::dyn_cast_or_null<Variable>(Src0); |
2014 auto *Src0M = llvm::dyn_cast_or_null<OperandMIPS32Mem>(Src0); | 2058 auto *Src0M = llvm::dyn_cast_or_null<OperandMIPS32Mem>(Src0); |
2015 auto *Src1M = llvm::dyn_cast_or_null<OperandMIPS32Mem>(Src1); | 2059 auto *Src1M = llvm::dyn_cast_or_null<OperandMIPS32Mem>(Src1); |
2016 Variable *Dst = CurInstr->getDest(); | 2060 Variable *Dst = CurInstr->getDest(); |
2017 if (auto *MovInstr = llvm::dyn_cast<InstMIPS32Mov>(CurInstr)) { | 2061 if (auto *MovInstr = llvm::dyn_cast<InstMIPS32Mov>(CurInstr)) { |
2018 Legalizer.legalizeMov(MovInstr); | 2062 Legalizer.legalizeMov(MovInstr); |
2019 continue; | 2063 continue; |
2020 } | 2064 } |
| 2065 if (auto *MovInstr = llvm::dyn_cast<InstMIPS32MovFP64ToI64>(CurInstr)) { |
| 2066 Legalizer.legalizeMovFp(MovInstr); |
| 2067 continue; |
| 2068 } |
2021 if (llvm::isa<InstMIPS32Sw>(CurInstr)) { | 2069 if (llvm::isa<InstMIPS32Sw>(CurInstr)) { |
2022 if (auto *LegalMem = Legalizer.legalizeMemOperand(Src1M)) { | 2070 if (auto *LegalMem = Legalizer.legalizeMemOperand(Src1M)) { |
2023 Sandboxer(this).sw(Src0V, LegalMem); | 2071 Sandboxer(this).sw(Src0V, LegalMem); |
2024 CurInstr->setDeleted(); | 2072 CurInstr->setDeleted(); |
2025 } | 2073 } |
2026 continue; | 2074 continue; |
2027 } | 2075 } |
2028 if (llvm::isa<InstMIPS32Swc1>(CurInstr)) { | 2076 if (llvm::isa<InstMIPS32Swc1>(CurInstr)) { |
2029 if (auto *LegalMem = Legalizer.legalizeMemOperand(Src1M)) { | 2077 if (auto *LegalMem = Legalizer.legalizeMemOperand(Src1M)) { |
2030 _swc1(Src0V, LegalMem); | 2078 _swc1(Src0V, LegalMem); |
(...skipping 570 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2601 } | 2649 } |
2602 | 2650 |
2603 Variable *T = makeReg(Dest->getType()); | 2651 Variable *T = makeReg(Dest->getType()); |
2604 Variable *Src0R = legalizeToReg(Src0); | 2652 Variable *Src0R = legalizeToReg(Src0); |
2605 Variable *Src1R = nullptr; | 2653 Variable *Src1R = nullptr; |
2606 uint32_t Value = 0; | 2654 uint32_t Value = 0; |
2607 bool IsSrc1Imm16 = false; | 2655 bool IsSrc1Imm16 = false; |
2608 | 2656 |
2609 switch (Instr->getOp()) { | 2657 switch (Instr->getOp()) { |
2610 case InstArithmetic::Add: | 2658 case InstArithmetic::Add: |
2611 case InstArithmetic::And: | 2659 case InstArithmetic::Sub: { |
2612 case InstArithmetic::Or: | |
2613 case InstArithmetic::Xor: | |
2614 case InstArithmetic::Sub: | |
2615 case InstArithmetic::Shl: | |
2616 case InstArithmetic::Lshr: | |
2617 case InstArithmetic::Ashr: { | |
2618 auto *Const32 = llvm::dyn_cast<ConstantInteger32>(Src1); | 2660 auto *Const32 = llvm::dyn_cast<ConstantInteger32>(Src1); |
2619 if (Const32 != nullptr && isInt<16>(int32_t(Const32->getValue()))) { | 2661 if (Const32 != nullptr && isInt<16>(int32_t(Const32->getValue()))) { |
2620 IsSrc1Imm16 = true; | 2662 IsSrc1Imm16 = true; |
2621 Value = Const32->getValue(); | 2663 Value = Const32->getValue(); |
2622 } else { | 2664 } else { |
| 2665 Src1R = legalizeToReg(Src1); |
| 2666 } |
| 2667 break; |
| 2668 } |
| 2669 case InstArithmetic::And: |
| 2670 case InstArithmetic::Or: |
| 2671 case InstArithmetic::Xor: |
| 2672 case InstArithmetic::Shl: |
| 2673 case InstArithmetic::Lshr: |
| 2674 case InstArithmetic::Ashr: { |
| 2675 auto *Const32 = llvm::dyn_cast<ConstantInteger32>(Src1); |
| 2676 if (Const32 != nullptr && llvm::isUInt<16>(uint32_t(Const32->getValue()))) { |
| 2677 IsSrc1Imm16 = true; |
| 2678 Value = Const32->getValue(); |
| 2679 } else { |
2623 Src1R = legalizeToReg(Src1); | 2680 Src1R = legalizeToReg(Src1); |
2624 } | 2681 } |
2625 break; | 2682 break; |
2626 } | 2683 } |
2627 default: | 2684 default: |
2628 Src1R = legalizeToReg(Src1); | 2685 Src1R = legalizeToReg(Src1); |
2629 break; | 2686 break; |
2630 } | 2687 } |
2631 constexpr uint32_t DivideByZeroTrapCode = 7; | 2688 constexpr uint32_t DivideByZeroTrapCode = 7; |
2632 | 2689 |
2633 switch (Instr->getOp()) { | 2690 switch (Instr->getOp()) { |
2634 case InstArithmetic::_num: | 2691 case InstArithmetic::_num: |
2635 break; | 2692 break; |
2636 case InstArithmetic::Add: | 2693 case InstArithmetic::Add: { |
| 2694 auto *T0R = Src0R; |
| 2695 auto *T1R = Src1R; |
| 2696 if (Dest->getType() != IceType_i32) { |
| 2697 T0R = makeReg(IceType_i32); |
| 2698 lowerCast(InstCast::create(Func, InstCast::Sext, T0R, Src0R)); |
| 2699 if (!IsSrc1Imm16) { |
| 2700 T1R = makeReg(IceType_i32); |
| 2701 lowerCast(InstCast::create(Func, InstCast::Sext, T1R, Src1R)); |
| 2702 } |
| 2703 } |
2637 if (IsSrc1Imm16) { | 2704 if (IsSrc1Imm16) { |
2638 _addiu(T, Src0R, Value); | 2705 _addiu(T, T0R, Value); |
2639 } else { | 2706 } else { |
2640 _addu(T, Src0R, Src1R); | 2707 _addu(T, T0R, T1R); |
2641 } | 2708 } |
2642 _mov(Dest, T); | 2709 _mov(Dest, T); |
2643 return; | 2710 return; |
| 2711 } |
2644 case InstArithmetic::And: | 2712 case InstArithmetic::And: |
2645 if (IsSrc1Imm16) { | 2713 if (IsSrc1Imm16) { |
2646 _andi(T, Src0R, Value); | 2714 _andi(T, Src0R, Value); |
2647 } else { | 2715 } else { |
2648 _and(T, Src0R, Src1R); | 2716 _and(T, Src0R, Src1R); |
2649 } | 2717 } |
2650 _mov(Dest, T); | 2718 _mov(Dest, T); |
2651 return; | 2719 return; |
2652 case InstArithmetic::Or: | 2720 case InstArithmetic::Or: |
2653 if (IsSrc1Imm16) { | 2721 if (IsSrc1Imm16) { |
2654 _ori(T, Src0R, Value); | 2722 _ori(T, Src0R, Value); |
2655 } else { | 2723 } else { |
2656 _or(T, Src0R, Src1R); | 2724 _or(T, Src0R, Src1R); |
2657 } | 2725 } |
2658 _mov(Dest, T); | 2726 _mov(Dest, T); |
2659 return; | 2727 return; |
2660 case InstArithmetic::Xor: | 2728 case InstArithmetic::Xor: |
2661 if (IsSrc1Imm16) { | 2729 if (IsSrc1Imm16) { |
2662 _xori(T, Src0R, Value); | 2730 _xori(T, Src0R, Value); |
2663 } else { | 2731 } else { |
2664 _xor(T, Src0R, Src1R); | 2732 _xor(T, Src0R, Src1R); |
2665 } | 2733 } |
2666 _mov(Dest, T); | 2734 _mov(Dest, T); |
2667 return; | 2735 return; |
2668 case InstArithmetic::Sub: | 2736 case InstArithmetic::Sub: { |
| 2737 auto *T0R = Src0R; |
| 2738 auto *T1R = Src1R; |
| 2739 if (Dest->getType() != IceType_i32) { |
| 2740 T0R = makeReg(IceType_i32); |
| 2741 lowerCast(InstCast::create(Func, InstCast::Sext, T0R, Src0R)); |
| 2742 if (!IsSrc1Imm16) { |
| 2743 T1R = makeReg(IceType_i32); |
| 2744 lowerCast(InstCast::create(Func, InstCast::Sext, T1R, Src1R)); |
| 2745 } |
| 2746 } |
2669 if (IsSrc1Imm16) { | 2747 if (IsSrc1Imm16) { |
2670 _addiu(T, Src0R, -Value); | 2748 _addiu(T, T0R, -Value); |
2671 } else { | 2749 } else { |
2672 _subu(T, Src0R, Src1R); | 2750 _subu(T, T0R, T1R); |
2673 } | 2751 } |
2674 _mov(Dest, T); | 2752 _mov(Dest, T); |
2675 return; | 2753 return; |
| 2754 } |
2676 case InstArithmetic::Mul: { | 2755 case InstArithmetic::Mul: { |
2677 _mul(T, Src0R, Src1R); | 2756 _mul(T, Src0R, Src1R); |
2678 _mov(Dest, T); | 2757 _mov(Dest, T); |
2679 return; | 2758 return; |
2680 } | 2759 } |
2681 case InstArithmetic::Shl: { | 2760 case InstArithmetic::Shl: { |
2682 if (IsSrc1Imm16) { | 2761 if (IsSrc1Imm16) { |
2683 _sll(T, Src0R, Value); | 2762 _sll(T, Src0R, Value); |
2684 } else { | 2763 } else { |
2685 _sllv(T, Src0R, Src1R); | 2764 _sllv(T, Src0R, Src1R); |
(...skipping 14 matching lines...) Expand all Loading... |
2700 } | 2779 } |
2701 if (IsSrc1Imm16) { | 2780 if (IsSrc1Imm16) { |
2702 _srl(T, T0R, Value); | 2781 _srl(T, T0R, Value); |
2703 } else { | 2782 } else { |
2704 _srlv(T, T0R, T1R); | 2783 _srlv(T, T0R, T1R); |
2705 } | 2784 } |
2706 _mov(Dest, T); | 2785 _mov(Dest, T); |
2707 return; | 2786 return; |
2708 } | 2787 } |
2709 case InstArithmetic::Ashr: { | 2788 case InstArithmetic::Ashr: { |
| 2789 auto *T0R = Src0R; |
| 2790 auto *T1R = Src1R; |
| 2791 if (Dest->getType() != IceType_i32) { |
| 2792 T0R = makeReg(IceType_i32); |
| 2793 lowerCast(InstCast::create(Func, InstCast::Sext, T0R, Src0R)); |
| 2794 if (!IsSrc1Imm16) { |
| 2795 T1R = makeReg(IceType_i32); |
| 2796 lowerCast(InstCast::create(Func, InstCast::Sext, T1R, Src1R)); |
| 2797 } |
| 2798 } |
2710 if (IsSrc1Imm16) { | 2799 if (IsSrc1Imm16) { |
2711 _sra(T, Src0R, Value); | 2800 _sra(T, T0R, Value); |
2712 } else { | 2801 } else { |
2713 _srav(T, Src0R, Src1R); | 2802 _srav(T, T0R, T1R); |
2714 } | 2803 } |
2715 _mov(Dest, T); | 2804 _mov(Dest, T); |
2716 return; | 2805 return; |
2717 } | 2806 } |
2718 case InstArithmetic::Udiv: { | 2807 case InstArithmetic::Udiv: { |
2719 auto *T_Zero = I32Reg(RegMIPS32::Reg_ZERO); | 2808 auto *T_Zero = I32Reg(RegMIPS32::Reg_ZERO); |
2720 auto *T0R = Src0R; | 2809 auto *T0R = Src0R; |
2721 auto *T1R = Src1R; | 2810 auto *T1R = Src1R; |
2722 if (Dest->getType() != IceType_i32) { | 2811 if (Dest->getType() != IceType_i32) { |
2723 T0R = makeReg(IceType_i32); | 2812 T0R = makeReg(IceType_i32); |
2724 lowerCast(InstCast::create(Func, InstCast::Zext, T0R, Src0R)); | 2813 lowerCast(InstCast::create(Func, InstCast::Zext, T0R, Src0R)); |
2725 T1R = makeReg(IceType_i32); | 2814 T1R = makeReg(IceType_i32); |
2726 lowerCast(InstCast::create(Func, InstCast::Zext, T1R, Src1R)); | 2815 lowerCast(InstCast::create(Func, InstCast::Zext, T1R, Src1R)); |
2727 } | 2816 } |
2728 _divu(T_Zero, T0R, T1R); | 2817 _divu(T_Zero, T0R, T1R); |
2729 _teq(T1R, T_Zero, DivideByZeroTrapCode); // Trap if divide-by-zero | 2818 _teq(T1R, T_Zero, DivideByZeroTrapCode); // Trap if divide-by-zero |
2730 _mflo(T, T_Zero); | 2819 _mflo(T, T_Zero); |
2731 _mov(Dest, T); | 2820 _mov(Dest, T); |
2732 return; | 2821 return; |
2733 } | 2822 } |
2734 case InstArithmetic::Sdiv: { | 2823 case InstArithmetic::Sdiv: { |
2735 auto *T_Zero = I32Reg(RegMIPS32::Reg_ZERO); | 2824 auto *T_Zero = I32Reg(RegMIPS32::Reg_ZERO); |
2736 _div(T_Zero, Src0R, Src1R); | 2825 auto *T0R = Src0R; |
2737 _teq(Src1R, T_Zero, DivideByZeroTrapCode); // Trap if divide-by-zero | 2826 auto *T1R = Src1R; |
| 2827 if (Dest->getType() != IceType_i32) { |
| 2828 T0R = makeReg(IceType_i32); |
| 2829 lowerCast(InstCast::create(Func, InstCast::Sext, T0R, Src0R)); |
| 2830 T1R = makeReg(IceType_i32); |
| 2831 lowerCast(InstCast::create(Func, InstCast::Sext, T1R, Src1R)); |
| 2832 } |
| 2833 _div(T_Zero, T0R, T1R); |
| 2834 _teq(T1R, T_Zero, DivideByZeroTrapCode); // Trap if divide-by-zero |
2738 _mflo(T, T_Zero); | 2835 _mflo(T, T_Zero); |
2739 _mov(Dest, T); | 2836 _mov(Dest, T); |
2740 return; | 2837 return; |
2741 } | 2838 } |
2742 case InstArithmetic::Urem: { | 2839 case InstArithmetic::Urem: { |
2743 auto *T_Zero = I32Reg(RegMIPS32::Reg_ZERO); | 2840 auto *T_Zero = I32Reg(RegMIPS32::Reg_ZERO); |
2744 auto *T0R = Src0R; | 2841 auto *T0R = Src0R; |
2745 auto *T1R = Src1R; | 2842 auto *T1R = Src1R; |
2746 if (Dest->getType() != IceType_i32) { | 2843 if (Dest->getType() != IceType_i32) { |
2747 T0R = makeReg(IceType_i32); | 2844 T0R = makeReg(IceType_i32); |
2748 lowerCast(InstCast::create(Func, InstCast::Zext, T0R, Src0R)); | 2845 lowerCast(InstCast::create(Func, InstCast::Zext, T0R, Src0R)); |
2749 T1R = makeReg(IceType_i32); | 2846 T1R = makeReg(IceType_i32); |
2750 lowerCast(InstCast::create(Func, InstCast::Zext, T1R, Src1R)); | 2847 lowerCast(InstCast::create(Func, InstCast::Zext, T1R, Src1R)); |
2751 } | 2848 } |
2752 _divu(T_Zero, T0R, T1R); | 2849 _divu(T_Zero, T0R, T1R); |
2753 _teq(T1R, T_Zero, DivideByZeroTrapCode); // Trap if divide-by-zero | 2850 _teq(T1R, T_Zero, DivideByZeroTrapCode); // Trap if divide-by-zero |
2754 _mfhi(T, T_Zero); | 2851 _mfhi(T, T_Zero); |
2755 _mov(Dest, T); | 2852 _mov(Dest, T); |
2756 return; | 2853 return; |
2757 } | 2854 } |
2758 case InstArithmetic::Srem: { | 2855 case InstArithmetic::Srem: { |
2759 auto *T_Zero = I32Reg(RegMIPS32::Reg_ZERO); | 2856 auto *T_Zero = I32Reg(RegMIPS32::Reg_ZERO); |
2760 _div(T_Zero, Src0R, Src1R); | 2857 auto *T0R = Src0R; |
2761 _teq(Src1R, T_Zero, DivideByZeroTrapCode); // Trap if divide-by-zero | 2858 auto *T1R = Src1R; |
| 2859 if (Dest->getType() != IceType_i32) { |
| 2860 T0R = makeReg(IceType_i32); |
| 2861 lowerCast(InstCast::create(Func, InstCast::Sext, T0R, Src0R)); |
| 2862 T1R = makeReg(IceType_i32); |
| 2863 lowerCast(InstCast::create(Func, InstCast::Sext, T1R, Src1R)); |
| 2864 } |
| 2865 _div(T_Zero, T0R, T1R); |
| 2866 _teq(T1R, T_Zero, DivideByZeroTrapCode); // Trap if divide-by-zero |
2762 _mfhi(T, T_Zero); | 2867 _mfhi(T, T_Zero); |
2763 _mov(Dest, T); | 2868 _mov(Dest, T); |
2764 return; | 2869 return; |
2765 } | 2870 } |
2766 case InstArithmetic::Fadd: { | 2871 case InstArithmetic::Fadd: { |
2767 if (DestTy == IceType_f32) { | 2872 if (DestTy == IceType_f32) { |
2768 _add_s(T, Src0R, Src1R); | 2873 _add_s(T, Src0R, Src1R); |
2769 _mov(Dest, T); | 2874 _mov(Dest, T); |
2770 return; | 2875 return; |
2771 } | 2876 } |
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2898 Variable *Src0R = nullptr; | 3003 Variable *Src0R = nullptr; |
2899 Variable *Src1R = nullptr; | 3004 Variable *Src1R = nullptr; |
2900 Variable *Src0HiR = nullptr; | 3005 Variable *Src0HiR = nullptr; |
2901 Variable *Src1HiR = nullptr; | 3006 Variable *Src1HiR = nullptr; |
2902 if (Src0Ty == IceType_i64) { | 3007 if (Src0Ty == IceType_i64) { |
2903 Src0R = legalizeToReg(loOperand(Src0)); | 3008 Src0R = legalizeToReg(loOperand(Src0)); |
2904 Src1R = legalizeToReg(loOperand(Src1)); | 3009 Src1R = legalizeToReg(loOperand(Src1)); |
2905 Src0HiR = legalizeToReg(hiOperand(Src0)); | 3010 Src0HiR = legalizeToReg(hiOperand(Src0)); |
2906 Src1HiR = legalizeToReg(hiOperand(Src1)); | 3011 Src1HiR = legalizeToReg(hiOperand(Src1)); |
2907 } else { | 3012 } else { |
2908 Src0R = legalizeToReg(Src0); | 3013 auto *Src0RT = legalizeToReg(Src0); |
2909 Src1R = legalizeToReg(Src1); | 3014 auto *Src1RT = legalizeToReg(Src1); |
| 3015 // Sign/Zero extend the source operands |
| 3016 if (Src0Ty != IceType_i32) { |
| 3017 InstCast::OpKind CastKind; |
| 3018 switch (CompareInst->getCondition()) { |
| 3019 case InstIcmp::Eq: |
| 3020 case InstIcmp::Ne: |
| 3021 case InstIcmp::Sgt: |
| 3022 case InstIcmp::Sge: |
| 3023 case InstIcmp::Slt: |
| 3024 case InstIcmp::Sle: |
| 3025 CastKind = InstCast::Sext; |
| 3026 break; |
| 3027 default: |
| 3028 CastKind = InstCast::Zext; |
| 3029 break; |
| 3030 } |
| 3031 Src0R = makeReg(IceType_i32); |
| 3032 Src1R = makeReg(IceType_i32); |
| 3033 lowerCast(InstCast::create(Func, CastKind, Src0R, Src0RT)); |
| 3034 lowerCast(InstCast::create(Func, CastKind, Src1R, Src1RT)); |
| 3035 } else { |
| 3036 Src0R = Src0RT; |
| 3037 Src1R = Src1RT; |
| 3038 } |
2910 } | 3039 } |
2911 auto *DestT = makeReg(IceType_i32); | 3040 auto *DestT = makeReg(IceType_i32); |
2912 | 3041 |
2913 switch (CompareInst->getCondition()) { | 3042 switch (CompareInst->getCondition()) { |
2914 default: | 3043 default: |
2915 llvm_unreachable("unexpected condition"); | 3044 llvm_unreachable("unexpected condition"); |
2916 return; | 3045 return; |
2917 case InstIcmp::Eq: { | 3046 case InstIcmp::Eq: { |
2918 if (Src0Ty == IceType_i64) { | 3047 if (Src0Ty == IceType_i64) { |
2919 auto *T1 = I32Reg(); | 3048 auto *T1 = I32Reg(); |
(...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3137 Operand *Arg = legalizeUndef(Instr->getArg(i)); | 3266 Operand *Arg = legalizeUndef(Instr->getArg(i)); |
3138 const Type Ty = Arg->getType(); | 3267 const Type Ty = Arg->getType(); |
3139 bool InReg = false; | 3268 bool InReg = false; |
3140 RegNumT Reg; | 3269 RegNumT Reg; |
3141 | 3270 |
3142 InReg = CC.argInReg(Ty, i, &Reg); | 3271 InReg = CC.argInReg(Ty, i, &Reg); |
3143 | 3272 |
3144 if (!InReg) { | 3273 if (!InReg) { |
3145 if (isVectorType(Ty)) { | 3274 if (isVectorType(Ty)) { |
3146 auto *ArgVec = llvm::cast<VariableVecOn32>(Arg); | 3275 auto *ArgVec = llvm::cast<VariableVecOn32>(Arg); |
| 3276 ParameterAreaSizeBytes = |
| 3277 applyStackAlignmentTy(ParameterAreaSizeBytes, IceType_i64); |
3147 for (Variable *Elem : ArgVec->getContainers()) { | 3278 for (Variable *Elem : ArgVec->getContainers()) { |
3148 ParameterAreaSizeBytes = | |
3149 applyStackAlignmentTy(ParameterAreaSizeBytes, IceType_i32); | |
3150 StackArgs.push_back(std::make_pair(Elem, ParameterAreaSizeBytes)); | 3279 StackArgs.push_back(std::make_pair(Elem, ParameterAreaSizeBytes)); |
3151 ParameterAreaSizeBytes += typeWidthInBytesOnStack(IceType_i32); | 3280 ParameterAreaSizeBytes += typeWidthInBytesOnStack(IceType_i32); |
3152 } | 3281 } |
3153 } else { | 3282 } else { |
3154 ParameterAreaSizeBytes = | 3283 ParameterAreaSizeBytes = |
3155 applyStackAlignmentTy(ParameterAreaSizeBytes, Ty); | 3284 applyStackAlignmentTy(ParameterAreaSizeBytes, Ty); |
3156 StackArgs.push_back(std::make_pair(Arg, ParameterAreaSizeBytes)); | 3285 StackArgs.push_back(std::make_pair(Arg, ParameterAreaSizeBytes)); |
3157 ParameterAreaSizeBytes += typeWidthInBytesOnStack(Ty); | 3286 ParameterAreaSizeBytes += typeWidthInBytesOnStack(Ty); |
3158 } | 3287 } |
3159 ++ArgNum; | 3288 ++ArgNum; |
(...skipping 12 matching lines...) Expand all Loading... |
3172 Operand *Elem3 = ArgVec->getContainers()[3]; | 3301 Operand *Elem3 = ArgVec->getContainers()[3]; |
3173 // First argument is passed in $4:$5:$6:$7 | 3302 // First argument is passed in $4:$5:$6:$7 |
3174 // Second and rest arguments are passed in $6:$7:stack:stack | 3303 // Second and rest arguments are passed in $6:$7:stack:stack |
3175 if (ArgNum == 0) { | 3304 if (ArgNum == 0) { |
3176 GPRArgs.push_back( | 3305 GPRArgs.push_back( |
3177 std::make_pair(Elem2, RegNumT::fixme((unsigned)Reg + 2))); | 3306 std::make_pair(Elem2, RegNumT::fixme((unsigned)Reg + 2))); |
3178 GPRArgs.push_back( | 3307 GPRArgs.push_back( |
3179 std::make_pair(Elem3, RegNumT::fixme((unsigned)Reg + 3))); | 3308 std::make_pair(Elem3, RegNumT::fixme((unsigned)Reg + 3))); |
3180 } else { | 3309 } else { |
3181 ParameterAreaSizeBytes = | 3310 ParameterAreaSizeBytes = |
3182 applyStackAlignmentTy(ParameterAreaSizeBytes, IceType_i32); | 3311 applyStackAlignmentTy(ParameterAreaSizeBytes, IceType_i64); |
3183 StackArgs.push_back(std::make_pair(Elem2, ParameterAreaSizeBytes)); | 3312 StackArgs.push_back(std::make_pair(Elem2, ParameterAreaSizeBytes)); |
3184 ParameterAreaSizeBytes += typeWidthInBytesOnStack(IceType_i32); | 3313 ParameterAreaSizeBytes += typeWidthInBytesOnStack(IceType_i32); |
3185 ParameterAreaSizeBytes = | |
3186 applyStackAlignmentTy(ParameterAreaSizeBytes, IceType_i32); | |
3187 StackArgs.push_back(std::make_pair(Elem3, ParameterAreaSizeBytes)); | 3314 StackArgs.push_back(std::make_pair(Elem3, ParameterAreaSizeBytes)); |
3188 ParameterAreaSizeBytes += typeWidthInBytesOnStack(IceType_i32); | 3315 ParameterAreaSizeBytes += typeWidthInBytesOnStack(IceType_i32); |
3189 } | 3316 } |
3190 } else if (Ty == IceType_i64) { | 3317 } else if (Ty == IceType_i64) { |
3191 Operand *Lo = loOperand(Arg); | 3318 Operand *Lo = loOperand(Arg); |
3192 Operand *Hi = hiOperand(Arg); | 3319 Operand *Hi = hiOperand(Arg); |
3193 GPRArgs.push_back( | 3320 GPRArgs.push_back( |
3194 std::make_pair(Lo, RegMIPS32::get64PairFirstRegNum(Reg))); | 3321 std::make_pair(Lo, RegMIPS32::get64PairFirstRegNum(Reg))); |
3195 GPRArgs.push_back( | 3322 GPRArgs.push_back( |
3196 std::make_pair(Hi, RegMIPS32::get64PairSecondRegNum(Reg))); | 3323 std::make_pair(Hi, RegMIPS32::get64PairSecondRegNum(Reg))); |
(...skipping 280 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3477 _mov(Dest, T); | 3604 _mov(Dest, T); |
3478 } | 3605 } |
3479 } | 3606 } |
3480 break; | 3607 break; |
3481 } | 3608 } |
3482 case InstCast::Trunc: { | 3609 case InstCast::Trunc: { |
3483 if (Src0Ty == IceType_i64) | 3610 if (Src0Ty == IceType_i64) |
3484 Src0 = loOperand(Src0); | 3611 Src0 = loOperand(Src0); |
3485 Variable *Src0R = legalizeToReg(Src0); | 3612 Variable *Src0R = legalizeToReg(Src0); |
3486 Variable *T = makeReg(DestTy); | 3613 Variable *T = makeReg(DestTy); |
3487 _mov(T, Src0R); | 3614 switch (DestTy) { |
| 3615 case IceType_i1: |
| 3616 _andi(T, Src0R, 0x1); |
| 3617 break; |
| 3618 case IceType_i8: |
| 3619 _andi(T, Src0R, 0xff); |
| 3620 break; |
| 3621 case IceType_i16: |
| 3622 _andi(T, Src0R, 0xffff); |
| 3623 break; |
| 3624 default: |
| 3625 _mov(T, Src0R); |
| 3626 break; |
| 3627 } |
3488 _mov(Dest, T); | 3628 _mov(Dest, T); |
3489 break; | 3629 break; |
3490 } | 3630 } |
3491 case InstCast::Fptrunc: { | 3631 case InstCast::Fptrunc: { |
3492 assert(Dest->getType() == IceType_f32); | 3632 assert(Dest->getType() == IceType_f32); |
3493 assert(Src0->getType() == IceType_f64); | 3633 assert(Src0->getType() == IceType_f64); |
3494 auto *DestR = legalizeToReg(Dest); | 3634 auto *DestR = legalizeToReg(Dest); |
3495 auto *Src0R = legalizeToReg(Src0); | 3635 auto *Src0R = legalizeToReg(Src0); |
3496 _cvt_s_d(DestR, Src0R); | 3636 _cvt_s_d(DestR, Src0R); |
3497 _mov(Dest, DestR); | 3637 _mov(Dest, DestR); |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3533 } | 3673 } |
3534 case InstCast::Sitofp: | 3674 case InstCast::Sitofp: |
3535 case InstCast::Uitofp: { | 3675 case InstCast::Uitofp: { |
3536 if (llvm::isa<Variable64On32>(Dest)) { | 3676 if (llvm::isa<Variable64On32>(Dest)) { |
3537 llvm::report_fatal_error("i64-to-fp should have been prelowered."); | 3677 llvm::report_fatal_error("i64-to-fp should have been prelowered."); |
3538 return; | 3678 return; |
3539 } | 3679 } |
3540 if (Src0Ty != IceType_i64) { | 3680 if (Src0Ty != IceType_i64) { |
3541 Variable *Src0R = legalizeToReg(Src0); | 3681 Variable *Src0R = legalizeToReg(Src0); |
3542 auto *T0R = Src0R; | 3682 auto *T0R = Src0R; |
3543 if (Src0Ty != IceType_i32 && CastKind == InstCast::Uitofp) { | 3683 if (Src0Ty != IceType_i32) { |
3544 T0R = makeReg(IceType_i32); | 3684 T0R = makeReg(IceType_i32); |
3545 lowerCast(InstCast::create(Func, InstCast::Zext, T0R, Src0R)); | 3685 if (CastKind == InstCast::Uitofp) |
| 3686 lowerCast(InstCast::create(Func, InstCast::Zext, T0R, Src0R)); |
| 3687 else |
| 3688 lowerCast(InstCast::create(Func, InstCast::Sext, T0R, Src0R)); |
3546 } | 3689 } |
3547 if (isScalarIntegerType(Src0Ty) && DestTy == IceType_f32) { | 3690 if (isScalarIntegerType(Src0Ty) && DestTy == IceType_f32) { |
3548 Variable *FTmp1 = makeReg(IceType_f32); | 3691 Variable *FTmp1 = makeReg(IceType_f32); |
3549 Variable *FTmp2 = makeReg(IceType_f32); | 3692 Variable *FTmp2 = makeReg(IceType_f32); |
3550 _mtc1(FTmp1, T0R); | 3693 _mtc1(FTmp1, T0R); |
3551 _cvt_s_w(FTmp2, FTmp1); | 3694 _cvt_s_w(FTmp2, FTmp1); |
3552 _mov(Dest, FTmp2); | 3695 _mov(Dest, FTmp2); |
3553 return; | 3696 return; |
3554 } | 3697 } |
3555 if (isScalarIntegerType(Src0Ty) && DestTy == IceType_f64) { | 3698 if (isScalarIntegerType(Src0Ty) && DestTy == IceType_f64) { |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3597 case IceType_f32: { | 3740 case IceType_f32: { |
3598 Variable *Src0R = legalizeToReg(Src0); | 3741 Variable *Src0R = legalizeToReg(Src0); |
3599 _mov(Dest, Src0R); | 3742 _mov(Dest, Src0R); |
3600 break; | 3743 break; |
3601 } | 3744 } |
3602 case IceType_i64: { | 3745 case IceType_i64: { |
3603 assert(Src0->getType() == IceType_f64); | 3746 assert(Src0->getType() == IceType_f64); |
3604 Variable *Src0R = legalizeToReg(Src0); | 3747 Variable *Src0R = legalizeToReg(Src0); |
3605 auto *T = llvm::cast<Variable64On32>(Func->makeVariable(IceType_i64)); | 3748 auto *T = llvm::cast<Variable64On32>(Func->makeVariable(IceType_i64)); |
3606 T->initHiLo(Func); | 3749 T->initHiLo(Func); |
3607 T->getHi()->setMustHaveReg(); | 3750 T->getHi()->setMustNotHaveReg(); |
3608 T->getLo()->setMustHaveReg(); | 3751 T->getLo()->setMustNotHaveReg(); |
3609 _mov(T, Src0R); | 3752 Context.insert<InstFakeDef>(T->getHi()); |
| 3753 Context.insert<InstFakeDef>(T->getLo()); |
| 3754 _mov_fp64_to_i64(T->getHi(), Src0R, Int64_Hi); |
| 3755 _mov_fp64_to_i64(T->getLo(), Src0R, Int64_Lo); |
3610 lowerAssign(InstAssign::create(Func, Dest, T)); | 3756 lowerAssign(InstAssign::create(Func, Dest, T)); |
3611 break; | 3757 break; |
3612 } | 3758 } |
3613 case IceType_f64: { | 3759 case IceType_f64: { |
3614 assert(Src0->getType() == IceType_i64); | 3760 assert(Src0->getType() == IceType_i64); |
3615 const uint32_t Mask = 0xFFFFFFFF; | 3761 const uint32_t Mask = 0xFFFFFFFF; |
3616 if (auto *C64 = llvm::dyn_cast<ConstantInteger64>(Src0)) { | 3762 if (auto *C64 = llvm::dyn_cast<ConstantInteger64>(Src0)) { |
3617 Variable *RegHi, *RegLo; | 3763 Variable *RegHi, *RegLo; |
3618 const uint64_t Value = C64->getValue(); | 3764 const uint64_t Value = C64->getValue(); |
3619 uint64_t Upper32Bits = (Value >> INT32_BITS) & Mask; | 3765 uint64_t Upper32Bits = (Value >> INT32_BITS) & Mask; |
(...skipping 551 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4171 auto *VDest = llvm::dyn_cast<VariableVecOn32>(Dest); | 4317 auto *VDest = llvm::dyn_cast<VariableVecOn32>(Dest); |
4172 VDest->initVecElement(Func); | 4318 VDest->initVecElement(Func); |
4173 // Temp vector variable | 4319 // Temp vector variable |
4174 auto *TDest = makeReg(DestTy); | 4320 auto *TDest = makeReg(DestTy); |
4175 auto *TVDest = llvm::dyn_cast<VariableVecOn32>(TDest); | 4321 auto *TVDest = llvm::dyn_cast<VariableVecOn32>(TDest); |
4176 TVDest->initVecElement(Func); | 4322 TVDest->initVecElement(Func); |
4177 // Destination element | 4323 // Destination element |
4178 auto *DstE = TVDest->getContainers()[Index / ElemPerCont]; | 4324 auto *DstE = TVDest->getContainers()[Index / ElemPerCont]; |
4179 // Element to insert | 4325 // Element to insert |
4180 auto *Src1R = legalizeToReg(Instr->getSrc(1)); | 4326 auto *Src1R = legalizeToReg(Instr->getSrc(1)); |
4181 auto *TReg1 = makeReg(Src1R->getType()); | 4327 auto *TReg1 = makeReg(IceType_i32); |
4182 auto *TReg2 = makeReg(Src1R->getType()); | 4328 auto *TReg2 = makeReg(IceType_i32); |
4183 auto *TReg3 = makeReg(Src1R->getType()); | 4329 auto *TReg3 = makeReg(IceType_i32); |
4184 auto *TReg4 = makeReg(Src1R->getType()); | 4330 auto *TReg4 = makeReg(IceType_i32); |
4185 auto *TReg5 = makeReg(Src1R->getType()); | 4331 auto *TReg5 = makeReg(IceType_i32); |
4186 auto *TDReg = makeReg(Src1R->getType()); | 4332 auto *TDReg = makeReg(IceType_i32); |
4187 // Position of the element in the container | 4333 // Position of the element in the container |
4188 uint32_t PosInCont = Index % ElemPerCont; | 4334 uint32_t PosInCont = Index % ElemPerCont; |
4189 // Load source vector in a temporary vector | 4335 // Load source vector in a temporary vector |
4190 for (SizeT i = 0; i < TVDest->ContainersPerVector; ++i) { | 4336 for (SizeT i = 0; i < TVDest->ContainersPerVector; ++i) { |
4191 auto *DCont = TVDest->getContainers()[i]; | 4337 auto *DCont = TVDest->getContainers()[i]; |
4192 // Do not define DstE as we are going to redefine it | 4338 // Do not define DstE as we are going to redefine it |
4193 if (DCont == DstE) | 4339 if (DCont == DstE) |
4194 continue; | 4340 continue; |
4195 auto *SCont = Src0R->getContainers()[i]; | 4341 auto *SCont = Src0R->getContainers()[i]; |
4196 auto *TReg = makeReg(IceType_i32); | 4342 auto *TReg = makeReg(IceType_i32); |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4241 case 2: | 4387 case 2: |
4242 _andi(TReg1, Src1R, 0xff); // Clear bits[31:8] of source | 4388 _andi(TReg1, Src1R, 0xff); // Clear bits[31:8] of source |
4243 _sll(TReg5, TReg1, 16); // Position in the destination | 4389 _sll(TReg5, TReg1, 16); // Position in the destination |
4244 _lui(TReg2, Ctx->getConstantInt32(0xff00)); | 4390 _lui(TReg2, Ctx->getConstantInt32(0xff00)); |
4245 _ori(TReg3, TReg2, 0xffff); | 4391 _ori(TReg3, TReg2, 0xffff); |
4246 _and(TReg4, SrcE, TReg3); // Clear bits[15:8] of element | 4392 _and(TReg4, SrcE, TReg3); // Clear bits[15:8] of element |
4247 _or(TDReg, TReg5, TReg4); | 4393 _or(TDReg, TReg5, TReg4); |
4248 _mov(DstE, TDReg); | 4394 _mov(DstE, TDReg); |
4249 break; | 4395 break; |
4250 case 3: | 4396 case 3: |
4251 _srl(TReg1, Src1R, 24); // Position in the destination | 4397 _sll(TReg1, Src1R, 24); // Position in the destination |
4252 _sll(TReg2, SrcE, 8); | 4398 _sll(TReg2, SrcE, 8); |
4253 _srl(TReg3, TReg2, 8); // Clear bits[31:24] of element | 4399 _srl(TReg3, TReg2, 8); // Clear bits[31:24] of element |
4254 _or(TDReg, TReg1, TReg3); | 4400 _or(TDReg, TReg1, TReg3); |
4255 _mov(DstE, TDReg); | 4401 _mov(DstE, TDReg); |
4256 break; | 4402 break; |
4257 default: | 4403 default: |
4258 llvm::report_fatal_error("InsertElement: Invalid PosInCont"); | 4404 llvm::report_fatal_error("InsertElement: Invalid PosInCont"); |
4259 break; | 4405 break; |
4260 } | 4406 } |
4261 } | 4407 } |
(...skipping 1460 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5722 // Use addiu if the immediate is a 16bit value. Otherwise load it | 5868 // Use addiu if the immediate is a 16bit value. Otherwise load it |
5723 // using a lui-ori instructions. | 5869 // using a lui-ori instructions. |
5724 Variable *Reg = makeReg(Ty, RegNum); | 5870 Variable *Reg = makeReg(Ty, RegNum); |
5725 if (isInt<16>(int32_t(Value))) { | 5871 if (isInt<16>(int32_t(Value))) { |
5726 Variable *Zero = makeReg(Ty, RegMIPS32::Reg_ZERO); | 5872 Variable *Zero = makeReg(Ty, RegMIPS32::Reg_ZERO); |
5727 Context.insert<InstFakeDef>(Zero); | 5873 Context.insert<InstFakeDef>(Zero); |
5728 _addiu(Reg, Zero, Value); | 5874 _addiu(Reg, Zero, Value); |
5729 } else { | 5875 } else { |
5730 uint32_t UpperBits = (Value >> 16) & 0xFFFF; | 5876 uint32_t UpperBits = (Value >> 16) & 0xFFFF; |
5731 uint32_t LowerBits = Value & 0xFFFF; | 5877 uint32_t LowerBits = Value & 0xFFFF; |
5732 Variable *TReg = makeReg(Ty, RegNum); | |
5733 if (LowerBits) { | 5878 if (LowerBits) { |
| 5879 Variable *TReg = makeReg(Ty, RegNum); |
5734 _lui(TReg, Ctx->getConstantInt32(UpperBits)); | 5880 _lui(TReg, Ctx->getConstantInt32(UpperBits)); |
5735 _ori(Reg, TReg, LowerBits); | 5881 _ori(Reg, TReg, LowerBits); |
5736 } else { | 5882 } else { |
5737 _lui(Reg, Ctx->getConstantInt32(UpperBits)); | 5883 _lui(Reg, Ctx->getConstantInt32(UpperBits)); |
5738 } | 5884 } |
5739 } | 5885 } |
5740 return Reg; | 5886 return Reg; |
5741 } else if (isScalarFloatingType(Ty)) { | 5887 } else if (isScalarFloatingType(Ty)) { |
5742 auto *CFrom = llvm::cast<Constant>(From); | 5888 auto *CFrom = llvm::cast<Constant>(From); |
5743 Variable *TReg = makeReg(Ty); | 5889 Variable *TReg = makeReg(Ty); |
(...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5976 if (auto *CallTargetR = llvm::dyn_cast<Variable>(CallTarget)) { | 6122 if (auto *CallTargetR = llvm::dyn_cast<Variable>(CallTarget)) { |
5977 Variable *T6 = Target->getPhysicalRegister(RegMIPS32::Reg_T6); | 6123 Variable *T6 = Target->getPhysicalRegister(RegMIPS32::Reg_T6); |
5978 Target->_and(CallTargetR, CallTargetR, T6); | 6124 Target->_and(CallTargetR, CallTargetR, T6); |
5979 } | 6125 } |
5980 } | 6126 } |
5981 return Target->Context.insert<InstMIPS32Call>(ReturnReg, CallTarget); | 6127 return Target->Context.insert<InstMIPS32Call>(ReturnReg, CallTarget); |
5982 } | 6128 } |
5983 | 6129 |
5984 } // end of namespace MIPS32 | 6130 } // end of namespace MIPS32 |
5985 } // end of namespace Ice | 6131 } // end of namespace Ice |
OLD | NEW |