Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // | 1 // |
| 2 // The Subzero Code Generator | 2 // The Subzero Code Generator |
| 3 // | 3 // |
| 4 // This file is distributed under the University of Illinois Open Source | 4 // This file is distributed under the University of Illinois Open Source |
| 5 // License. See LICENSE.TXT for details. | 5 // License. See LICENSE.TXT for details. |
| 6 // | 6 // |
| 7 //===----------------------------------------------------------------------===// | 7 //===----------------------------------------------------------------------===// |
| 8 /// | 8 /// |
| 9 /// \file | 9 /// \file |
| 10 /// \brief Implements the TargetLoweringMIPS32 class, which consists almost | 10 /// \brief Implements the TargetLoweringMIPS32 class, which consists almost |
| (...skipping 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 |