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 1544 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1555 // This might be a GP to/from FP move generated due to argument passing. | 1555 // This might be a GP to/from FP move generated due to argument passing. |
1556 // Use mtc1/mfc1 instead of mov.[s/d] if src and dst registers are of | 1556 // Use mtc1/mfc1 instead of mov.[s/d] if src and dst registers are of |
1557 // different types. | 1557 // different types. |
1558 const bool IsDstGPR = RegMIPS32::isGPRReg(Dest->getRegNum()); | 1558 const bool IsDstGPR = RegMIPS32::isGPRReg(Dest->getRegNum()); |
1559 const bool IsSrcGPR = RegMIPS32::isGPRReg(SrcR->getRegNum()); | 1559 const bool IsSrcGPR = RegMIPS32::isGPRReg(SrcR->getRegNum()); |
1560 const RegNumT SRegNum = SrcR->getRegNum(); | 1560 const RegNumT SRegNum = SrcR->getRegNum(); |
1561 const RegNumT DRegNum = Dest->getRegNum(); | 1561 const RegNumT DRegNum = Dest->getRegNum(); |
1562 if (IsDstGPR != IsSrcGPR) { | 1562 if (IsDstGPR != IsSrcGPR) { |
1563 if (IsDstGPR) { | 1563 if (IsDstGPR) { |
1564 // Dest is GPR and SrcR is FPR. Use mfc1. | 1564 // Dest is GPR and SrcR is FPR. Use mfc1. |
1565 if (typeWidthInBytes(Dest->getType()) == 8) { | 1565 int32_t typeWidth = typeWidthInBytes(Dest->getType()); |
Jim Stichnoth
2016/10/10 17:07:49
Capitalize TypeWidth variable per LLVM convention.
sagar.thakur
2016/10/12 06:07:06
Done.
| |
1566 if (MovInstr->getDestHi() != nullptr) | |
1567 typeWidth += typeWidthInBytes(MovInstr->getDestHi()->getType()); | |
1568 if (typeWidth == 8) { | |
1566 // Split it into two mfc1 instructions | 1569 // Split it into two mfc1 instructions |
1567 Variable *SrcGPRHi = Target->makeReg( | 1570 Variable *SrcGPRHi = Target->makeReg( |
1568 IceType_f32, RegMIPS32::get64PairFirstRegNum(SRegNum)); | 1571 IceType_f32, RegMIPS32::get64PairFirstRegNum(SRegNum)); |
1569 Variable *SrcGPRLo = Target->makeReg( | 1572 Variable *SrcGPRLo = Target->makeReg( |
1570 IceType_f32, RegMIPS32::get64PairSecondRegNum(SRegNum)); | 1573 IceType_f32, RegMIPS32::get64PairSecondRegNum(SRegNum)); |
1571 Variable *DstFPRHi = Target->makeReg( | 1574 Variable *DstFPRHi, *DstFPRLo; |
1572 IceType_i32, RegMIPS32::get64PairFirstRegNum(DRegNum)); | 1575 if (MovInstr->getDestHi() != nullptr && Dest != nullptr) { |
1573 Variable *DstFPRLo = Target->makeReg( | 1576 DstFPRHi = Target->makeReg(IceType_i32, |
1574 IceType_i32, RegMIPS32::get64PairSecondRegNum(DRegNum)); | 1577 MovInstr->getDestHi()->getRegNum()); |
1578 DstFPRLo = Target->makeReg(IceType_i32, Dest->getRegNum()); | |
1579 } else { | |
1580 DstFPRHi = Target->makeReg( | |
1581 IceType_i32, RegMIPS32::get64PairFirstRegNum(DRegNum)); | |
1582 DstFPRLo = Target->makeReg( | |
1583 IceType_i32, RegMIPS32::get64PairSecondRegNum(DRegNum)); | |
1584 } | |
1575 Target->_mov(DstFPRHi, SrcGPRLo); | 1585 Target->_mov(DstFPRHi, SrcGPRLo); |
1576 Target->_mov(DstFPRLo, SrcGPRHi); | 1586 Target->_mov(DstFPRLo, SrcGPRHi); |
1577 Legalized = true; | 1587 Legalized = true; |
1578 } else { | 1588 } else { |
1579 Variable *SrcGPR = Target->makeReg(IceType_f32, SRegNum); | 1589 Variable *SrcGPR = Target->makeReg(IceType_f32, SRegNum); |
1580 Variable *DstFPR = Target->makeReg(IceType_i32, DRegNum); | 1590 Variable *DstFPR = Target->makeReg(IceType_i32, DRegNum); |
1581 Target->_mov(DstFPR, SrcGPR); | 1591 Target->_mov(DstFPR, SrcGPR); |
1582 Legalized = true; | 1592 Legalized = true; |
1583 } | 1593 } |
1584 } else { | 1594 } else { |
1585 // Dest is FPR and SrcR is GPR. Use mtc1. | 1595 // Dest is FPR and SrcR is GPR. Use mtc1. |
1586 if (typeWidthInBytes(Dest->getType()) == 8) { | 1596 if (typeWidthInBytes(Dest->getType()) == 8) { |
1587 Variable *SrcGPRHi, *SrcGPRLo; | 1597 Variable *SrcGPRHi, *SrcGPRLo; |
1588 // SrcR could be $zero which is i32 | 1598 // SrcR could be $zero which is i32 |
1589 if (SRegNum == RegMIPS32::Reg_ZERO) { | 1599 if (SRegNum == RegMIPS32::Reg_ZERO) { |
1590 SrcGPRHi = Target->makeReg(IceType_i32, SRegNum); | 1600 SrcGPRHi = Target->makeReg(IceType_i32, SRegNum); |
1591 SrcGPRLo = SrcGPRHi; | 1601 SrcGPRLo = SrcGPRHi; |
1592 } else { | 1602 } else { |
1593 // Split it into two mtc1 instructions | 1603 // Split it into two mtc1 instructions |
1594 SrcGPRHi = Target->makeReg( | 1604 if (MovInstr->getSrcSize() == 2) { |
1595 IceType_i32, RegMIPS32::get64PairFirstRegNum(SRegNum)); | 1605 const auto FirstReg = |
1596 SrcGPRLo = Target->makeReg( | 1606 (llvm::cast<Variable>(MovInstr->getSrc(0)))->getRegNum(); |
1597 IceType_i32, RegMIPS32::get64PairSecondRegNum(SRegNum)); | 1607 const auto SecondReg = |
1608 (llvm::cast<Variable>(MovInstr->getSrc(1)))->getRegNum(); | |
1609 SrcGPRHi = Target->makeReg(IceType_i32, FirstReg); | |
1610 SrcGPRLo = Target->makeReg(IceType_i32, SecondReg); | |
1611 } else { | |
1612 SrcGPRHi = Target->makeReg( | |
1613 IceType_i32, RegMIPS32::get64PairFirstRegNum(SRegNum)); | |
1614 SrcGPRLo = Target->makeReg( | |
1615 IceType_i32, RegMIPS32::get64PairSecondRegNum(SRegNum)); | |
1616 } | |
1598 } | 1617 } |
1599 Variable *DstFPRHi = Target->makeReg( | 1618 Variable *DstFPRHi = Target->makeReg( |
1600 IceType_f32, RegMIPS32::get64PairFirstRegNum(DRegNum)); | 1619 IceType_f32, RegMIPS32::get64PairFirstRegNum(DRegNum)); |
1601 Variable *DstFPRLo = Target->makeReg( | 1620 Variable *DstFPRLo = Target->makeReg( |
1602 IceType_f32, RegMIPS32::get64PairSecondRegNum(DRegNum)); | 1621 IceType_f32, RegMIPS32::get64PairSecondRegNum(DRegNum)); |
1603 Target->_mov(DstFPRHi, SrcGPRLo); | 1622 Target->_mov(DstFPRHi, SrcGPRLo); |
1604 Target->_mov(DstFPRLo, SrcGPRHi); | 1623 Target->_mov(DstFPRLo, SrcGPRHi); |
1605 Legalized = true; | 1624 Legalized = true; |
1606 } else { | 1625 } else { |
1607 Variable *SrcGPR = Target->makeReg(IceType_i32, SRegNum); | 1626 Variable *SrcGPR = Target->makeReg(IceType_i32, SRegNum); |
1608 Variable *DstFPR = Target->makeReg(IceType_f32, DRegNum); | 1627 Variable *DstFPR = Target->makeReg(IceType_f32, DRegNum); |
1609 Target->_mov(DstFPR, SrcGPR); | 1628 Target->_mov(DstFPR, SrcGPR); |
1610 Legalized = true; | 1629 Legalized = true; |
1611 } | 1630 } |
1612 } | 1631 } |
1613 } | 1632 } |
1614 if (Legalized) { | 1633 if (Legalized) { |
1615 if (MovInstr->isDestRedefined()) { | 1634 if (MovInstr->isDestRedefined()) { |
1616 Target->_set_dest_redefined(); | 1635 Target->_set_dest_redefined(); |
1617 } | 1636 } |
1618 MovInstr->setDeleted(); | 1637 MovInstr->setDeleted(); |
1619 return; | 1638 return; |
1620 } | 1639 } |
1621 } | 1640 } |
1622 | 1641 |
1623 if (!Dest->hasReg()) { | 1642 if (!Dest->hasReg()) { |
1624 auto *SrcR = llvm::cast<Variable>(Src); | 1643 auto *SrcR = llvm::cast<Variable>(Src); |
1625 assert(SrcR->hasReg()); | 1644 assert(SrcR->hasReg()); |
1626 assert(!SrcR->isRematerializable()); | 1645 assert(!SrcR->isRematerializable()); |
1627 const int32_t Offset = Dest->getStackOffset(); | 1646 int32_t Offset = 0; |
1647 | |
1648 if (MovInstr->getDestHi() != nullptr) | |
1649 Offset = MovInstr->getDestHi()->getStackOffset(); | |
1650 else | |
1651 Offset = Dest->getStackOffset(); | |
1628 | 1652 |
1629 // This is a _mov(Mem(), Variable), i.e., a store. | 1653 // This is a _mov(Mem(), Variable), i.e., a store. |
1630 auto *Base = Target->getPhysicalRegister(Target->getFrameOrStackReg()); | 1654 auto *Base = Target->getPhysicalRegister(Target->getFrameOrStackReg()); |
1631 | 1655 |
1632 OperandMIPS32Mem *Addr = OperandMIPS32Mem::create( | 1656 OperandMIPS32Mem *Addr = OperandMIPS32Mem::create( |
1633 Target->Func, DestTy, Base, | 1657 Target->Func, DestTy, Base, |
1634 llvm::cast<ConstantInteger32>(Target->Ctx->getConstantInt32(Offset))); | 1658 llvm::cast<ConstantInteger32>(Target->Ctx->getConstantInt32(Offset))); |
1635 | 1659 |
1636 // FP arguments are passed in GP reg if first argument is in GP. In this | 1660 // FP arguments are passed in GP reg if first argument is in GP. In this |
1637 // case type of the SrcR is still FP thus we need to explicitly generate sw | 1661 // case type of the SrcR is still FP thus we need to explicitly generate sw |
1638 // instead of swc1. | 1662 // instead of swc1. |
1639 const RegNumT RegNum = SrcR->getRegNum(); | 1663 const RegNumT RegNum = SrcR->getRegNum(); |
1640 const bool IsSrcGPReg = RegMIPS32::isGPRReg(SrcR->getRegNum()); | 1664 const bool IsSrcGPReg = RegMIPS32::isGPRReg(SrcR->getRegNum()); |
1641 if (SrcTy == IceType_f32 && IsSrcGPReg == true) { | 1665 if (SrcTy == IceType_f32 && IsSrcGPReg == true) { |
1642 Variable *SrcGPR = Target->makeReg(IceType_i32, RegNum); | 1666 Variable *SrcGPR = Target->makeReg(IceType_i32, RegNum); |
1643 Target->_sw(SrcGPR, Addr); | 1667 Target->_sw(SrcGPR, Addr); |
1644 } else if (SrcTy == IceType_f64 && IsSrcGPReg == true) { | 1668 } else if (SrcTy == IceType_f64 && IsSrcGPReg == true) { |
1645 Variable *SrcGPRHi = | 1669 Variable *SrcGPRHi = |
1646 Target->makeReg(IceType_i32, RegMIPS32::get64PairFirstRegNum(RegNum)); | 1670 Target->makeReg(IceType_i32, RegMIPS32::get64PairFirstRegNum(RegNum)); |
1647 Variable *SrcGPRLo = Target->makeReg( | 1671 Variable *SrcGPRLo = Target->makeReg( |
1648 IceType_i32, RegMIPS32::get64PairSecondRegNum(RegNum)); | 1672 IceType_i32, RegMIPS32::get64PairSecondRegNum(RegNum)); |
1649 OperandMIPS32Mem *AddrHi = OperandMIPS32Mem::create( | 1673 OperandMIPS32Mem *AddrHi = OperandMIPS32Mem::create( |
1650 Target->Func, DestTy, Base, | 1674 Target->Func, DestTy, Base, |
1651 llvm::cast<ConstantInteger32>( | 1675 llvm::cast<ConstantInteger32>( |
1652 Target->Ctx->getConstantInt32(Offset + 4))); | 1676 Target->Ctx->getConstantInt32(Offset + 4))); |
1653 Target->_sw(SrcGPRLo, Addr); | 1677 Target->_sw(SrcGPRLo, Addr); |
1654 Target->_sw(SrcGPRHi, AddrHi); | 1678 Target->_sw(SrcGPRHi, AddrHi); |
1679 } else if (DestTy == IceType_f64 && IsSrcGPReg == true) { | |
Jim Stichnoth
2016/10/10 17:07:49
remove "== true"
sagar.thakur
2016/10/12 06:07:06
Done.
| |
1680 const auto FirstReg = | |
1681 (llvm::cast<Variable>(MovInstr->getSrc(0)))->getRegNum(); | |
1682 const auto SecondReg = | |
1683 (llvm::cast<Variable>(MovInstr->getSrc(1)))->getRegNum(); | |
1684 Variable *SrcGPRHi = Target->makeReg(IceType_i32, SecondReg); | |
1685 Variable *SrcGPRLo = Target->makeReg(IceType_i32, FirstReg); | |
1686 OperandMIPS32Mem *AddrHi = OperandMIPS32Mem::create( | |
1687 Target->Func, DestTy, Base, | |
1688 llvm::cast<ConstantInteger32>( | |
1689 Target->Ctx->getConstantInt32(Offset + 4))); | |
1690 Target->_sw(SrcGPRLo, Addr); | |
1691 Target->_sw(SrcGPRHi, AddrHi); | |
1655 } else { | 1692 } else { |
1656 Target->_sw(SrcR, Addr); | 1693 Target->_sw(SrcR, Addr); |
1657 } | 1694 } |
1658 | 1695 |
1659 Target->Context.insert<InstFakeDef>(Dest); | 1696 Target->Context.insert<InstFakeDef>(Dest); |
1660 Legalized = true; | 1697 Legalized = true; |
1661 } else if (auto *Var = llvm::dyn_cast<Variable>(Src)) { | 1698 } else if (auto *Var = llvm::dyn_cast<Variable>(Src)) { |
1662 if (Var->isRematerializable()) { | 1699 if (Var->isRematerializable()) { |
1663 // This is equivalent to an x86 _lea(RematOffset(%esp/%ebp), Variable). | 1700 // This is equivalent to an x86 _lea(RematOffset(%esp/%ebp), Variable). |
1664 | 1701 |
(...skipping 1440 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3105 case IceType_i8: | 3142 case IceType_i8: |
3106 assert(Src0->getType() == IceType_v8i1); | 3143 assert(Src0->getType() == IceType_v8i1); |
3107 llvm::report_fatal_error( | 3144 llvm::report_fatal_error( |
3108 "i8 to v8i1 conversion should have been prelowered."); | 3145 "i8 to v8i1 conversion should have been prelowered."); |
3109 break; | 3146 break; |
3110 case IceType_i16: | 3147 case IceType_i16: |
3111 assert(Src0->getType() == IceType_v16i1); | 3148 assert(Src0->getType() == IceType_v16i1); |
3112 llvm::report_fatal_error( | 3149 llvm::report_fatal_error( |
3113 "i16 to v16i1 conversion should have been prelowered."); | 3150 "i16 to v16i1 conversion should have been prelowered."); |
3114 break; | 3151 break; |
3152 case IceType_i32: | |
3153 case IceType_f32: { | |
3154 Variable *Src0R = legalizeToReg(Src0); | |
3155 _mov(Dest, Src0R); | |
3156 break; | |
3157 } | |
3158 case IceType_i64: { | |
3159 assert(Src0->getType() == IceType_f64); | |
3160 Variable *Src0R = legalizeToReg(Src0); | |
3161 auto *Dest64 = llvm::cast<Variable64On32>(Dest); | |
3162 _mov(Dest64, Src0R); | |
3163 Context.insert<InstFakeDef>(Dest64->getHi()); | |
3164 break; | |
3165 } | |
3166 case IceType_f64: { | |
3167 assert(Src0->getType() == IceType_i64); | |
3168 const uint32_t Mask = 0xFFFFFFFF; | |
3169 if (auto *C64 = llvm::dyn_cast<ConstantInteger64>(Src0)) { | |
3170 Variable *RegHi, *RegLo; | |
3171 const uint64_t Value = C64->getValue(); | |
3172 uint64_t Upper32Bits = (Value >> INT32_BITS) & Mask; | |
3173 uint64_t Lower32Bits = Value & Mask; | |
3174 RegLo = legalizeToReg(Ctx->getConstantInt32(Lower32Bits)); | |
3175 RegHi = legalizeToReg(Ctx->getConstantInt32(Upper32Bits)); | |
3176 _mov(Dest, RegHi, RegLo); | |
3177 } else { | |
3178 auto *Var64On32 = llvm::cast<Variable64On32>(Src0); | |
3179 auto *RegLo = legalizeToReg(loOperand(Var64On32)); | |
3180 auto *RegHi = legalizeToReg(hiOperand(Var64On32)); | |
3181 _mov(Dest, RegHi, RegLo); | |
3182 } | |
3183 break; | |
3184 } | |
3115 case IceType_v8i1: | 3185 case IceType_v8i1: |
3116 assert(Src0->getType() == IceType_i8); | 3186 assert(Src0->getType() == IceType_i8); |
3117 llvm::report_fatal_error( | 3187 llvm::report_fatal_error( |
3118 "v8i1 to i8 conversion should have been prelowered."); | 3188 "v8i1 to i8 conversion should have been prelowered."); |
3119 break; | 3189 break; |
3120 case IceType_v16i1: | 3190 case IceType_v16i1: |
3121 assert(Src0->getType() == IceType_i16); | 3191 assert(Src0->getType() == IceType_i16); |
3122 llvm::report_fatal_error( | 3192 llvm::report_fatal_error( |
3123 "v16i1 to i16 conversion should have been prelowered."); | 3193 "v16i1 to i16 conversion should have been prelowered."); |
3124 break; | 3194 break; |
(...skipping 1809 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4934 Str << "\t.set\t" | 5004 Str << "\t.set\t" |
4935 << "nomips16\n"; | 5005 << "nomips16\n"; |
4936 } | 5006 } |
4937 | 5007 |
4938 SmallBitVector TargetMIPS32::TypeToRegisterSet[RCMIPS32_NUM]; | 5008 SmallBitVector TargetMIPS32::TypeToRegisterSet[RCMIPS32_NUM]; |
4939 SmallBitVector TargetMIPS32::TypeToRegisterSetUnfiltered[RCMIPS32_NUM]; | 5009 SmallBitVector TargetMIPS32::TypeToRegisterSetUnfiltered[RCMIPS32_NUM]; |
4940 SmallBitVector TargetMIPS32::RegisterAliases[RegMIPS32::Reg_NUM]; | 5010 SmallBitVector TargetMIPS32::RegisterAliases[RegMIPS32::Reg_NUM]; |
4941 | 5011 |
4942 } // end of namespace MIPS32 | 5012 } // end of namespace MIPS32 |
4943 } // end of namespace Ice | 5013 } // end of namespace Ice |
OLD | NEW |