Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1210)

Side by Side Diff: src/IceTargetLoweringMIPS32.cpp

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

Powered by Google App Engine
This is Rietveld 408576698