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

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: 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 1544 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698