| 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 |