Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 //===- subzero/src/IceTargetLoweringX8632.cpp - x86-32 lowering -----------===// | 1 //===- subzero/src/IceTargetLoweringX8632.cpp - x86-32 lowering -----------===// |
| 2 // | 2 // |
| 3 // The Subzero Code Generator | 3 // The Subzero Code Generator |
| 4 // | 4 // |
| 5 // This file is distributed under the University of Illinois Open Source | 5 // This file is distributed under the University of Illinois Open Source |
| 6 // License. See LICENSE.TXT for details. | 6 // License. See LICENSE.TXT for details. |
| 7 // | 7 // |
| 8 //===----------------------------------------------------------------------===// | 8 //===----------------------------------------------------------------------===// |
| 9 // | 9 // |
| 10 // This file implements the TargetLoweringX8632 class, which | 10 // This file implements the TargetLoweringX8632 class, which |
| (...skipping 1563 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1574 _mov(Dest, T); | 1574 _mov(Dest, T); |
| 1575 break; | 1575 break; |
| 1576 case InstArithmetic::Mul: | 1576 case InstArithmetic::Mul: |
| 1577 // TODO: Optimize for llvm::isa<Constant>(Src1) | 1577 // TODO: Optimize for llvm::isa<Constant>(Src1) |
| 1578 // TODO: Strength-reduce multiplications by a constant, | 1578 // TODO: Strength-reduce multiplications by a constant, |
| 1579 // particularly -1 and powers of 2. Advanced: use lea to | 1579 // particularly -1 and powers of 2. Advanced: use lea to |
| 1580 // multiply by 3, 5, 9. | 1580 // multiply by 3, 5, 9. |
| 1581 // | 1581 // |
| 1582 // The 8-bit version of imul only allows the form "imul r/m8" | 1582 // The 8-bit version of imul only allows the form "imul r/m8" |
| 1583 // where T must be in eax. | 1583 // where T must be in eax. |
| 1584 if (Dest->getType() == IceType_i8) | 1584 if (isByteSizedArithType(Dest->getType())) |
| 1585 _mov(T, Src0, RegX8632::Reg_eax); | 1585 _mov(T, Src0, RegX8632::Reg_eax); |
| 1586 else | 1586 else |
| 1587 _mov(T, Src0); | 1587 _mov(T, Src0); |
| 1588 _imul(T, Src1); | 1588 _imul(T, Src1); |
| 1589 _mov(Dest, T); | 1589 _mov(Dest, T); |
| 1590 break; | 1590 break; |
| 1591 case InstArithmetic::Shl: | 1591 case InstArithmetic::Shl: |
| 1592 _mov(T, Src0); | 1592 _mov(T, Src0); |
| 1593 if (!llvm::isa<Constant>(Src1)) | 1593 if (!llvm::isa<Constant>(Src1)) |
| 1594 Src1 = legalizeToVar(Src1, RegX8632::Reg_ecx); | 1594 Src1 = legalizeToVar(Src1, RegX8632::Reg_ecx); |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 1606 _mov(T, Src0); | 1606 _mov(T, Src0); |
| 1607 if (!llvm::isa<Constant>(Src1)) | 1607 if (!llvm::isa<Constant>(Src1)) |
| 1608 Src1 = legalizeToVar(Src1, RegX8632::Reg_ecx); | 1608 Src1 = legalizeToVar(Src1, RegX8632::Reg_ecx); |
| 1609 _sar(T, Src1); | 1609 _sar(T, Src1); |
| 1610 _mov(Dest, T); | 1610 _mov(Dest, T); |
| 1611 break; | 1611 break; |
| 1612 case InstArithmetic::Udiv: | 1612 case InstArithmetic::Udiv: |
| 1613 // div and idiv are the few arithmetic operators that do not allow | 1613 // div and idiv are the few arithmetic operators that do not allow |
| 1614 // immediates as the operand. | 1614 // immediates as the operand. |
| 1615 Src1 = legalize(Src1, Legal_Reg | Legal_Mem); | 1615 Src1 = legalize(Src1, Legal_Reg | Legal_Mem); |
| 1616 if (Dest->getType() == IceType_i8) { | 1616 if (isByteSizedArithType(Dest->getType())) { |
| 1617 Variable *T_ah = NULL; | 1617 Variable *T_ah = NULL; |
| 1618 Constant *Zero = Ctx->getConstantZero(IceType_i8); | 1618 Constant *Zero = Ctx->getConstantZero(IceType_i8); |
| 1619 _mov(T, Src0, RegX8632::Reg_eax); | 1619 _mov(T, Src0, RegX8632::Reg_eax); |
| 1620 _mov(T_ah, Zero, RegX8632::Reg_ah); | 1620 _mov(T_ah, Zero, RegX8632::Reg_ah); |
| 1621 _div(T, Src1, T_ah); | 1621 _div(T, Src1, T_ah); |
| 1622 _mov(Dest, T); | 1622 _mov(Dest, T); |
| 1623 } else { | 1623 } else { |
| 1624 Constant *Zero = Ctx->getConstantZero(IceType_i32); | 1624 Constant *Zero = Ctx->getConstantZero(IceType_i32); |
| 1625 _mov(T, Src0, RegX8632::Reg_eax); | 1625 _mov(T, Src0, RegX8632::Reg_eax); |
| 1626 _mov(T_edx, Zero, RegX8632::Reg_edx); | 1626 _mov(T_edx, Zero, RegX8632::Reg_edx); |
| 1627 _div(T, Src1, T_edx); | 1627 _div(T, Src1, T_edx); |
| 1628 _mov(Dest, T); | 1628 _mov(Dest, T); |
| 1629 } | 1629 } |
| 1630 break; | 1630 break; |
| 1631 case InstArithmetic::Sdiv: | 1631 case InstArithmetic::Sdiv: |
| 1632 Src1 = legalize(Src1, Legal_Reg | Legal_Mem); | 1632 Src1 = legalize(Src1, Legal_Reg | Legal_Mem); |
| 1633 if (Dest->getType() == IceType_i8) { | 1633 if (isByteSizedArithType(Dest->getType())) { |
| 1634 _mov(T, Src0, RegX8632::Reg_eax); | 1634 _mov(T, Src0, RegX8632::Reg_eax); |
| 1635 _cbwdq(T, T); | 1635 _cbwdq(T, T); |
| 1636 _idiv(T, Src1, T); | 1636 _idiv(T, Src1, T); |
| 1637 _mov(Dest, T); | 1637 _mov(Dest, T); |
| 1638 } else { | 1638 } else { |
| 1639 T_edx = makeReg(IceType_i32, RegX8632::Reg_edx); | 1639 T_edx = makeReg(IceType_i32, RegX8632::Reg_edx); |
| 1640 _mov(T, Src0, RegX8632::Reg_eax); | 1640 _mov(T, Src0, RegX8632::Reg_eax); |
| 1641 _cbwdq(T_edx, T); | 1641 _cbwdq(T_edx, T); |
| 1642 _idiv(T, Src1, T_edx); | 1642 _idiv(T, Src1, T_edx); |
| 1643 _mov(Dest, T); | 1643 _mov(Dest, T); |
| 1644 } | 1644 } |
| 1645 break; | 1645 break; |
| 1646 case InstArithmetic::Urem: | 1646 case InstArithmetic::Urem: |
| 1647 Src1 = legalize(Src1, Legal_Reg | Legal_Mem); | 1647 Src1 = legalize(Src1, Legal_Reg | Legal_Mem); |
| 1648 if (Dest->getType() == IceType_i8) { | 1648 if (isByteSizedArithType(Dest->getType())) { |
| 1649 Variable *T_ah = NULL; | 1649 Variable *T_ah = NULL; |
| 1650 Constant *Zero = Ctx->getConstantZero(IceType_i8); | 1650 Constant *Zero = Ctx->getConstantZero(IceType_i8); |
| 1651 _mov(T, Src0, RegX8632::Reg_eax); | 1651 _mov(T, Src0, RegX8632::Reg_eax); |
| 1652 _mov(T_ah, Zero, RegX8632::Reg_ah); | 1652 _mov(T_ah, Zero, RegX8632::Reg_ah); |
| 1653 _div(T_ah, Src1, T); | 1653 _div(T_ah, Src1, T); |
| 1654 _mov(Dest, T_ah); | 1654 _mov(Dest, T_ah); |
| 1655 } else { | 1655 } else { |
| 1656 Constant *Zero = Ctx->getConstantZero(IceType_i32); | 1656 Constant *Zero = Ctx->getConstantZero(IceType_i32); |
| 1657 _mov(T_edx, Zero, RegX8632::Reg_edx); | 1657 _mov(T_edx, Zero, RegX8632::Reg_edx); |
| 1658 _mov(T, Src0, RegX8632::Reg_eax); | 1658 _mov(T, Src0, RegX8632::Reg_eax); |
| 1659 _div(T_edx, Src1, T); | 1659 _div(T_edx, Src1, T); |
| 1660 _mov(Dest, T_edx); | 1660 _mov(Dest, T_edx); |
| 1661 } | 1661 } |
| 1662 break; | 1662 break; |
| 1663 case InstArithmetic::Srem: | 1663 case InstArithmetic::Srem: |
| 1664 Src1 = legalize(Src1, Legal_Reg | Legal_Mem); | 1664 Src1 = legalize(Src1, Legal_Reg | Legal_Mem); |
| 1665 if (Dest->getType() == IceType_i8) { | 1665 if (isByteSizedArithType(Dest->getType())) { |
| 1666 Variable *T_ah = makeReg(IceType_i8, RegX8632::Reg_ah); | 1666 Variable *T_ah = makeReg(IceType_i8, RegX8632::Reg_ah); |
| 1667 _mov(T, Src0, RegX8632::Reg_eax); | 1667 _mov(T, Src0, RegX8632::Reg_eax); |
| 1668 _cbwdq(T, T); | 1668 _cbwdq(T, T); |
| 1669 Context.insert(InstFakeDef::create(Func, T_ah)); | 1669 Context.insert(InstFakeDef::create(Func, T_ah)); |
| 1670 _idiv(T_ah, Src1, T); | 1670 _idiv(T_ah, Src1, T); |
| 1671 _mov(Dest, T_ah); | 1671 _mov(Dest, T_ah); |
| 1672 } else { | 1672 } else { |
| 1673 T_edx = makeReg(IceType_i32, RegX8632::Reg_edx); | 1673 T_edx = makeReg(IceType_i32, RegX8632::Reg_edx); |
| 1674 _mov(T, Src0, RegX8632::Reg_eax); | 1674 _mov(T, Src0, RegX8632::Reg_eax); |
| 1675 _cbwdq(T_edx, T); | 1675 _cbwdq(T_edx, T); |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 1693 _mov(Dest, T); | 1693 _mov(Dest, T); |
| 1694 break; | 1694 break; |
| 1695 case InstArithmetic::Fdiv: | 1695 case InstArithmetic::Fdiv: |
| 1696 _mov(T, Src0); | 1696 _mov(T, Src0); |
| 1697 _divss(T, Src1); | 1697 _divss(T, Src1); |
| 1698 _mov(Dest, T); | 1698 _mov(Dest, T); |
| 1699 break; | 1699 break; |
| 1700 case InstArithmetic::Frem: { | 1700 case InstArithmetic::Frem: { |
| 1701 const SizeT MaxSrcs = 2; | 1701 const SizeT MaxSrcs = 2; |
| 1702 Type Ty = Dest->getType(); | 1702 Type Ty = Dest->getType(); |
| 1703 InstCall *Call = | 1703 InstCall *Call = makeHelperCall( |
| 1704 makeHelperCall(Ty == IceType_f32 ? "fmodf" : "fmod", Dest, MaxSrcs); | 1704 isFloat32Asserting32Or64(Ty) ? "fmodf" : "fmod", Dest, MaxSrcs); |
| 1705 Call->addArg(Src0); | 1705 Call->addArg(Src0); |
| 1706 Call->addArg(Src1); | 1706 Call->addArg(Src1); |
| 1707 return lowerCall(Call); | 1707 return lowerCall(Call); |
| 1708 } break; | 1708 } break; |
| 1709 } | 1709 } |
| 1710 } | 1710 } |
| 1711 } | 1711 } |
| 1712 | 1712 |
| 1713 void TargetX8632::lowerAssign(const InstAssign *Inst) { | 1713 void TargetX8632::lowerAssign(const InstAssign *Inst) { |
| 1714 Variable *Dest = Inst->getDest(); | 1714 Variable *Dest = Inst->getDest(); |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1772 OperandList XmmArgs; | 1772 OperandList XmmArgs; |
| 1773 OperandList StackArgs, StackArgLocations; | 1773 OperandList StackArgs, StackArgLocations; |
| 1774 uint32_t ParameterAreaSizeBytes = 0; | 1774 uint32_t ParameterAreaSizeBytes = 0; |
| 1775 | 1775 |
| 1776 // Classify each argument operand according to the location where the | 1776 // Classify each argument operand according to the location where the |
| 1777 // argument is passed. | 1777 // argument is passed. |
| 1778 for (SizeT i = 0, NumArgs = Instr->getNumArgs(); i < NumArgs; ++i) { | 1778 for (SizeT i = 0, NumArgs = Instr->getNumArgs(); i < NumArgs; ++i) { |
| 1779 Operand *Arg = Instr->getArg(i); | 1779 Operand *Arg = Instr->getArg(i); |
| 1780 Type Ty = Arg->getType(); | 1780 Type Ty = Arg->getType(); |
| 1781 // The PNaCl ABI requires the width of arguments to be at least 32 bits. | 1781 // The PNaCl ABI requires the width of arguments to be at least 32 bits. |
| 1782 assert(Ty == IceType_i32 || Ty == IceType_f32 || Ty == IceType_i64 || | 1782 assert(typeWidthInBytes(Ty) >= 4); |
| 1783 Ty == IceType_f64 || isVectorType(Ty)); | |
| 1784 if (isVectorType(Ty) && XmmArgs.size() < X86_MAX_XMM_ARGS) { | 1783 if (isVectorType(Ty) && XmmArgs.size() < X86_MAX_XMM_ARGS) { |
| 1785 XmmArgs.push_back(Arg); | 1784 XmmArgs.push_back(Arg); |
| 1786 } else { | 1785 } else { |
| 1787 StackArgs.push_back(Arg); | 1786 StackArgs.push_back(Arg); |
| 1788 if (isVectorType(Arg->getType())) { | 1787 if (isVectorType(Arg->getType())) { |
| 1789 ParameterAreaSizeBytes = applyStackAlignment(ParameterAreaSizeBytes); | 1788 ParameterAreaSizeBytes = applyStackAlignment(ParameterAreaSizeBytes); |
| 1790 } | 1789 } |
| 1791 Variable *esp = Func->getTarget()->getPhysicalRegister(RegX8632::Reg_esp); | 1790 Variable *esp = Func->getTarget()->getPhysicalRegister(RegX8632::Reg_esp); |
| 1792 Constant *Loc = | 1791 Constant *Loc = |
| 1793 Ctx->getConstantInt32(IceType_i32, ParameterAreaSizeBytes); | 1792 Ctx->getConstantInt32(IceType_i32, ParameterAreaSizeBytes); |
| (...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1919 } else { | 1918 } else { |
| 1920 assert(Dest->getType() == IceType_i32 || Dest->getType() == IceType_i16 || | 1919 assert(Dest->getType() == IceType_i32 || Dest->getType() == IceType_i16 || |
| 1921 Dest->getType() == IceType_i8 || Dest->getType() == IceType_i1 || | 1920 Dest->getType() == IceType_i8 || Dest->getType() == IceType_i1 || |
| 1922 isVectorType(Dest->getType())); | 1921 isVectorType(Dest->getType())); |
| 1923 if (isVectorType(Dest->getType())) { | 1922 if (isVectorType(Dest->getType())) { |
| 1924 _movp(Dest, ReturnReg); | 1923 _movp(Dest, ReturnReg); |
| 1925 } else { | 1924 } else { |
| 1926 _mov(Dest, ReturnReg); | 1925 _mov(Dest, ReturnReg); |
| 1927 } | 1926 } |
| 1928 } | 1927 } |
| 1929 } else if (Dest->getType() == IceType_f32 || Dest->getType() == IceType_f64) { | 1928 } else if (isScalarFloatingType(Dest->getType())) { |
| 1930 // Special treatment for an FP function which returns its result in | 1929 // Special treatment for an FP function which returns its result in |
| 1931 // st(0). | 1930 // st(0). |
| 1932 // If Dest ends up being a physical xmm register, the fstp emit code | 1931 // If Dest ends up being a physical xmm register, the fstp emit code |
| 1933 // will route st(0) through a temporary stack slot. | 1932 // will route st(0) through a temporary stack slot. |
| 1934 _fstp(Dest); | 1933 _fstp(Dest); |
| 1935 // Create a fake use of Dest in case it actually isn't used, | 1934 // Create a fake use of Dest in case it actually isn't used, |
| 1936 // because st(0) still needs to be popped. | 1935 // because st(0) still needs to be popped. |
| 1937 Context.insert(InstFakeUse::create(Func, Dest)); | 1936 Context.insert(InstFakeUse::create(Func, Dest)); |
| 1938 } | 1937 } |
| 1939 } | 1938 } |
| (...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2113 // Use a helper for converting floating-point values to 64-bit | 2112 // Use a helper for converting floating-point values to 64-bit |
| 2114 // integers. SSE2 appears to have no way to convert from xmm | 2113 // integers. SSE2 appears to have no way to convert from xmm |
| 2115 // registers to something like the edx:eax register pair, and | 2114 // registers to something like the edx:eax register pair, and |
| 2116 // gcc and clang both want to use x87 instructions complete with | 2115 // gcc and clang both want to use x87 instructions complete with |
| 2117 // temporary manipulation of the status word. This helper is | 2116 // temporary manipulation of the status word. This helper is |
| 2118 // not needed for x86-64. | 2117 // not needed for x86-64. |
| 2119 split64(Dest); | 2118 split64(Dest); |
| 2120 const SizeT MaxSrcs = 1; | 2119 const SizeT MaxSrcs = 1; |
| 2121 Type SrcType = Inst->getSrc(0)->getType(); | 2120 Type SrcType = Inst->getSrc(0)->getType(); |
| 2122 InstCall *Call = makeHelperCall( | 2121 InstCall *Call = makeHelperCall( |
| 2123 SrcType == IceType_f32 ? "cvtftosi64" : "cvtdtosi64", Dest, MaxSrcs); | 2122 isFloat32Asserting32Or64(SrcType) ? "cvtftosi64" : "cvtdtosi64", Dest, |
| 2123 MaxSrcs); | |
| 2124 // TODO: Call the correct compiler-rt helper function. | 2124 // TODO: Call the correct compiler-rt helper function. |
| 2125 Call->addArg(Inst->getSrc(0)); | 2125 Call->addArg(Inst->getSrc(0)); |
| 2126 lowerCall(Call); | 2126 lowerCall(Call); |
| 2127 } else { | 2127 } else { |
| 2128 Operand *Src0RM = legalize(Inst->getSrc(0), Legal_Reg | Legal_Mem); | 2128 Operand *Src0RM = legalize(Inst->getSrc(0), Legal_Reg | Legal_Mem); |
| 2129 // t1.i32 = cvt Src0RM; t2.dest_type = t1; Dest = t2.dest_type | 2129 // t1.i32 = cvt Src0RM; t2.dest_type = t1; Dest = t2.dest_type |
| 2130 Variable *T_1 = makeReg(IceType_i32); | 2130 Variable *T_1 = makeReg(IceType_i32); |
| 2131 Variable *T_2 = makeReg(Dest->getType()); | 2131 Variable *T_2 = makeReg(Dest->getType()); |
| 2132 _cvtt(T_1, Src0RM); | 2132 _cvtt(T_1, Src0RM); |
| 2133 _mov(T_2, T_1); // T_1 and T_2 may have different integer types | 2133 _mov(T_2, T_1); // T_1 and T_2 may have different integer types |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 2144 InstCall *Call = makeHelperCall("Sz_fptoui_v4f32", Dest, MaxSrcs); | 2144 InstCall *Call = makeHelperCall("Sz_fptoui_v4f32", Dest, MaxSrcs); |
| 2145 Call->addArg(Inst->getSrc(0)); | 2145 Call->addArg(Inst->getSrc(0)); |
| 2146 lowerCall(Call); | 2146 lowerCall(Call); |
| 2147 } else if (Dest->getType() == IceType_i64 || | 2147 } else if (Dest->getType() == IceType_i64 || |
| 2148 Dest->getType() == IceType_i32) { | 2148 Dest->getType() == IceType_i32) { |
| 2149 // Use a helper for both x86-32 and x86-64. | 2149 // Use a helper for both x86-32 and x86-64. |
| 2150 split64(Dest); | 2150 split64(Dest); |
| 2151 const SizeT MaxSrcs = 1; | 2151 const SizeT MaxSrcs = 1; |
| 2152 Type DestType = Dest->getType(); | 2152 Type DestType = Dest->getType(); |
| 2153 Type SrcType = Inst->getSrc(0)->getType(); | 2153 Type SrcType = Inst->getSrc(0)->getType(); |
| 2154 IceString DstSubstring = (DestType == IceType_i64 ? "64" : "32"); | 2154 IceString DstSubstring = (isInt32Asserting32Or64(DestType) ? "32" : "64"); |
| 2155 IceString SrcSubstring = (SrcType == IceType_f32 ? "f" : "d"); | 2155 IceString SrcSubstring = (isFloat32Asserting32Or64(SrcType) ? "f" : "d"); |
| 2156 // Possibilities are cvtftoui32, cvtdtoui32, cvtftoui64, cvtdtoui64 | 2156 // Possibilities are cvtftoui32, cvtdtoui32, cvtftoui64, cvtdtoui64 |
| 2157 IceString TargetString = "cvt" + SrcSubstring + "toui" + DstSubstring; | 2157 IceString TargetString = "cvt" + SrcSubstring + "toui" + DstSubstring; |
| 2158 // TODO: Call the correct compiler-rt helper function. | 2158 // TODO: Call the correct compiler-rt helper function. |
| 2159 InstCall *Call = makeHelperCall(TargetString, Dest, MaxSrcs); | 2159 InstCall *Call = makeHelperCall(TargetString, Dest, MaxSrcs); |
| 2160 Call->addArg(Inst->getSrc(0)); | 2160 Call->addArg(Inst->getSrc(0)); |
| 2161 lowerCall(Call); | 2161 lowerCall(Call); |
| 2162 return; | 2162 return; |
| 2163 } else { | 2163 } else { |
| 2164 Operand *Src0RM = legalize(Inst->getSrc(0), Legal_Reg | Legal_Mem); | 2164 Operand *Src0RM = legalize(Inst->getSrc(0), Legal_Reg | Legal_Mem); |
| 2165 // t1.i32 = cvt Src0RM; t2.dest_type = t1; Dest = t2.dest_type | 2165 // t1.i32 = cvt Src0RM; t2.dest_type = t1; Dest = t2.dest_type |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 2178 Inst->getSrc(0)->getType() == IceType_v4i32); | 2178 Inst->getSrc(0)->getType() == IceType_v4i32); |
| 2179 Operand *Src0RM = legalize(Inst->getSrc(0), Legal_Reg | Legal_Mem); | 2179 Operand *Src0RM = legalize(Inst->getSrc(0), Legal_Reg | Legal_Mem); |
| 2180 Variable *T = makeReg(Dest->getType()); | 2180 Variable *T = makeReg(Dest->getType()); |
| 2181 _cvt(T, Src0RM); | 2181 _cvt(T, Src0RM); |
| 2182 _movp(Dest, T); | 2182 _movp(Dest, T); |
| 2183 } else if (Inst->getSrc(0)->getType() == IceType_i64) { | 2183 } else if (Inst->getSrc(0)->getType() == IceType_i64) { |
| 2184 // Use a helper for x86-32. | 2184 // Use a helper for x86-32. |
| 2185 const SizeT MaxSrcs = 1; | 2185 const SizeT MaxSrcs = 1; |
| 2186 Type DestType = Dest->getType(); | 2186 Type DestType = Dest->getType(); |
| 2187 InstCall *Call = makeHelperCall( | 2187 InstCall *Call = makeHelperCall( |
| 2188 DestType == IceType_f32 ? "cvtsi64tof" : "cvtsi64tod", Dest, MaxSrcs); | 2188 isFloat32Asserting32Or64(DestType) ? "cvtsi64tof" : "cvtsi64tod", |
|
Karl
2014/09/29 16:20:51
Mnior nit. This conditional and the one one for "f
jvoung (off chromium)
2014/09/29 16:57:49
I'm inclined to leave this alone for now if that's
| |
| 2189 Dest, MaxSrcs); | |
| 2189 // TODO: Call the correct compiler-rt helper function. | 2190 // TODO: Call the correct compiler-rt helper function. |
| 2190 Call->addArg(Inst->getSrc(0)); | 2191 Call->addArg(Inst->getSrc(0)); |
| 2191 lowerCall(Call); | 2192 lowerCall(Call); |
| 2192 return; | 2193 return; |
| 2193 } else { | 2194 } else { |
| 2194 Operand *Src0RM = legalize(Inst->getSrc(0), Legal_Reg | Legal_Mem); | 2195 Operand *Src0RM = legalize(Inst->getSrc(0), Legal_Reg | Legal_Mem); |
| 2195 // Sign-extend the operand. | 2196 // Sign-extend the operand. |
| 2196 // t1.i32 = movsx Src0RM; t2 = Cvt t1.i32; Dest = t2 | 2197 // t1.i32 = movsx Src0RM; t2 = Cvt t1.i32; Dest = t2 |
| 2197 Variable *T_1 = makeReg(IceType_i32); | 2198 Variable *T_1 = makeReg(IceType_i32); |
| 2198 Variable *T_2 = makeReg(Dest->getType()); | 2199 Variable *T_2 = makeReg(Dest->getType()); |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 2212 const SizeT MaxSrcs = 1; | 2213 const SizeT MaxSrcs = 1; |
| 2213 InstCall *Call = makeHelperCall("Sz_uitofp_v4i32", Dest, MaxSrcs); | 2214 InstCall *Call = makeHelperCall("Sz_uitofp_v4i32", Dest, MaxSrcs); |
| 2214 Call->addArg(Src0); | 2215 Call->addArg(Src0); |
| 2215 lowerCall(Call); | 2216 lowerCall(Call); |
| 2216 } else if (Src0->getType() == IceType_i64 || | 2217 } else if (Src0->getType() == IceType_i64 || |
| 2217 Src0->getType() == IceType_i32) { | 2218 Src0->getType() == IceType_i32) { |
| 2218 // Use a helper for x86-32 and x86-64. Also use a helper for | 2219 // Use a helper for x86-32 and x86-64. Also use a helper for |
| 2219 // i32 on x86-32. | 2220 // i32 on x86-32. |
| 2220 const SizeT MaxSrcs = 1; | 2221 const SizeT MaxSrcs = 1; |
| 2221 Type DestType = Dest->getType(); | 2222 Type DestType = Dest->getType(); |
| 2222 IceString SrcSubstring = (Src0->getType() == IceType_i64 ? "64" : "32"); | 2223 IceString SrcSubstring = |
| 2223 IceString DstSubstring = (DestType == IceType_f32 ? "f" : "d"); | 2224 (isInt32Asserting32Or64(Src0->getType()) ? "32" : "64"); |
| 2225 IceString DstSubstring = (isFloat32Asserting32Or64(DestType) ? "f" : "d"); | |
| 2224 // Possibilities are cvtui32tof, cvtui32tod, cvtui64tof, cvtui64tod | 2226 // Possibilities are cvtui32tof, cvtui32tod, cvtui64tof, cvtui64tod |
| 2225 IceString TargetString = "cvtui" + SrcSubstring + "to" + DstSubstring; | 2227 IceString TargetString = "cvtui" + SrcSubstring + "to" + DstSubstring; |
| 2226 // TODO: Call the correct compiler-rt helper function. | 2228 // TODO: Call the correct compiler-rt helper function. |
| 2227 InstCall *Call = makeHelperCall(TargetString, Dest, MaxSrcs); | 2229 InstCall *Call = makeHelperCall(TargetString, Dest, MaxSrcs); |
| 2228 Call->addArg(Src0); | 2230 Call->addArg(Src0); |
| 2229 lowerCall(Call); | 2231 lowerCall(Call); |
| 2230 return; | 2232 return; |
| 2231 } else { | 2233 } else { |
| 2232 Operand *Src0RM = legalize(Src0, Legal_Reg | Legal_Mem); | 2234 Operand *Src0RM = legalize(Src0, Legal_Reg | Legal_Mem); |
| 2233 // Zero-extend the operand. | 2235 // Zero-extend the operand. |
| (...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2406 // is not at the lowest index. | 2408 // is not at the lowest index. |
| 2407 Constant *Mask = Ctx->getConstantInt32(IceType_i8, Index); | 2409 Constant *Mask = Ctx->getConstantInt32(IceType_i8, Index); |
| 2408 T = makeReg(Ty); | 2410 T = makeReg(Ty); |
| 2409 _pshufd(T, legalize(SourceVectNotLegalized, Legal_Reg | Legal_Mem), Mask); | 2411 _pshufd(T, legalize(SourceVectNotLegalized, Legal_Reg | Legal_Mem), Mask); |
| 2410 } else { | 2412 } else { |
| 2411 T = legalizeToVar(SourceVectNotLegalized); | 2413 T = legalizeToVar(SourceVectNotLegalized); |
| 2412 } | 2414 } |
| 2413 | 2415 |
| 2414 if (InVectorElementTy == IceType_i32) { | 2416 if (InVectorElementTy == IceType_i32) { |
| 2415 _movd(ExtractedElementR, T); | 2417 _movd(ExtractedElementR, T); |
| 2416 } else { // Ty == Icetype_f32 | 2418 } else { // Ty == IceType_f32 |
| 2417 // TODO(wala): _movss is only used here because _mov does not | 2419 // TODO(wala): _movss is only used here because _mov does not |
| 2418 // allow a vector source and a scalar destination. _mov should be | 2420 // allow a vector source and a scalar destination. _mov should be |
| 2419 // able to be used here. | 2421 // able to be used here. |
| 2420 // _movss is a binary instruction, so the FakeDef is needed to | 2422 // _movss is a binary instruction, so the FakeDef is needed to |
| 2421 // keep the live range analysis consistent. | 2423 // keep the live range analysis consistent. |
| 2422 Context.insert(InstFakeDef::create(Func, ExtractedElementR)); | 2424 Context.insert(InstFakeDef::create(Func, ExtractedElementR)); |
| 2423 _movss(ExtractedElementR, T); | 2425 _movss(ExtractedElementR, T); |
| 2424 } | 2426 } |
| 2425 } else { | 2427 } else { |
| 2426 assert(Ty == IceType_v16i8 || Ty == IceType_v16i1); | 2428 assert(Ty == IceType_v16i8 || Ty == IceType_v16i1); |
| (...skipping 606 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3033 Variable *T = NULL; | 3035 Variable *T = NULL; |
| 3034 _mov(T, Val); | 3036 _mov(T, Val); |
| 3035 _rol(T, Eight); | 3037 _rol(T, Eight); |
| 3036 _mov(Dest, T); | 3038 _mov(Dest, T); |
| 3037 } | 3039 } |
| 3038 return; | 3040 return; |
| 3039 } | 3041 } |
| 3040 case Intrinsics::Ctpop: { | 3042 case Intrinsics::Ctpop: { |
| 3041 Variable *Dest = Instr->getDest(); | 3043 Variable *Dest = Instr->getDest(); |
| 3042 Operand *Val = Instr->getArg(0); | 3044 Operand *Val = Instr->getArg(0); |
| 3043 InstCall *Call = makeHelperCall(Val->getType() == IceType_i64 ? | 3045 InstCall *Call = |
| 3044 "__popcountdi2" : "__popcountsi2", Dest, 1); | 3046 makeHelperCall(isInt32Asserting32Or64(Val->getType()) ? "__popcountsi2" |
| 3047 : "__popcountdi2", | |
| 3048 Dest, 1); | |
| 3045 Call->addArg(Val); | 3049 Call->addArg(Val); |
| 3046 lowerCall(Call); | 3050 lowerCall(Call); |
| 3047 // The popcount helpers always return 32-bit values, while the intrinsic's | 3051 // The popcount helpers always return 32-bit values, while the intrinsic's |
| 3048 // signature matches the native POPCNT instruction and fills a 64-bit reg | 3052 // signature matches the native POPCNT instruction and fills a 64-bit reg |
| 3049 // (in 64-bit mode). Thus, clear the upper bits of the dest just in case | 3053 // (in 64-bit mode). Thus, clear the upper bits of the dest just in case |
| 3050 // the user doesn't do that in the IR. If the user does that in the IR, | 3054 // the user doesn't do that in the IR. If the user does that in the IR, |
| 3051 // then this zero'ing instruction is dead and gets optimized out. | 3055 // then this zero'ing instruction is dead and gets optimized out. |
| 3052 if (Val->getType() == IceType_i64) { | 3056 if (Val->getType() == IceType_i64) { |
| 3053 Variable *DestHi = llvm::cast<Variable>(hiOperand(Dest)); | 3057 Variable *DestHi = llvm::cast<Variable>(hiOperand(Dest)); |
| 3054 Constant *Zero = Ctx->getConstantZero(IceType_i32); | 3058 Constant *Zero = Ctx->getConstantZero(IceType_i32); |
| (...skipping 819 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3874 | 3878 |
| 3875 void TargetX8632::lowerRet(const InstRet *Inst) { | 3879 void TargetX8632::lowerRet(const InstRet *Inst) { |
| 3876 Variable *Reg = NULL; | 3880 Variable *Reg = NULL; |
| 3877 if (Inst->hasRetValue()) { | 3881 if (Inst->hasRetValue()) { |
| 3878 Operand *Src0 = legalize(Inst->getRetValue()); | 3882 Operand *Src0 = legalize(Inst->getRetValue()); |
| 3879 if (Src0->getType() == IceType_i64) { | 3883 if (Src0->getType() == IceType_i64) { |
| 3880 Variable *eax = legalizeToVar(loOperand(Src0), RegX8632::Reg_eax); | 3884 Variable *eax = legalizeToVar(loOperand(Src0), RegX8632::Reg_eax); |
| 3881 Variable *edx = legalizeToVar(hiOperand(Src0), RegX8632::Reg_edx); | 3885 Variable *edx = legalizeToVar(hiOperand(Src0), RegX8632::Reg_edx); |
| 3882 Reg = eax; | 3886 Reg = eax; |
| 3883 Context.insert(InstFakeUse::create(Func, edx)); | 3887 Context.insert(InstFakeUse::create(Func, edx)); |
| 3884 } else if (Src0->getType() == IceType_f32 || | 3888 } else if (isScalarFloatingType(Src0->getType())) { |
| 3885 Src0->getType() == IceType_f64) { | |
| 3886 _fld(Src0); | 3889 _fld(Src0); |
| 3887 } else if (isVectorType(Src0->getType())) { | 3890 } else if (isVectorType(Src0->getType())) { |
| 3888 Reg = legalizeToVar(Src0, RegX8632::Reg_xmm0); | 3891 Reg = legalizeToVar(Src0, RegX8632::Reg_xmm0); |
| 3889 } else { | 3892 } else { |
| 3890 _mov(Reg, Src0, RegX8632::Reg_eax); | 3893 _mov(Reg, Src0, RegX8632::Reg_eax); |
| 3891 } | 3894 } |
| 3892 } | 3895 } |
| 3893 _ret(Reg); | 3896 _ret(Reg); |
| 3894 // Add a fake use of esp to make sure esp stays alive for the entire | 3897 // Add a fake use of esp to make sure esp stays alive for the entire |
| 3895 // function. Otherwise post-call esp adjustments get dead-code | 3898 // function. Otherwise post-call esp adjustments get dead-code |
| (...skipping 368 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4264 assert(!isVectorType(From->getType())); | 4267 assert(!isVectorType(From->getType())); |
| 4265 bool NeedsReg = false; | 4268 bool NeedsReg = false; |
| 4266 if (!(Allowed & Legal_Imm)) | 4269 if (!(Allowed & Legal_Imm)) |
| 4267 // Immediate specifically not allowed | 4270 // Immediate specifically not allowed |
| 4268 NeedsReg = true; | 4271 NeedsReg = true; |
| 4269 // TODO(stichnot): LEAHACK: remove Legal_Reloc once a proper | 4272 // TODO(stichnot): LEAHACK: remove Legal_Reloc once a proper |
| 4270 // emitter is used. | 4273 // emitter is used. |
| 4271 if (!(Allowed & Legal_Reloc) && llvm::isa<ConstantRelocatable>(From)) | 4274 if (!(Allowed & Legal_Reloc) && llvm::isa<ConstantRelocatable>(From)) |
| 4272 // Relocatable specifically not allowed | 4275 // Relocatable specifically not allowed |
| 4273 NeedsReg = true; | 4276 NeedsReg = true; |
| 4274 if (!(Allowed & Legal_Mem) && | 4277 if (!(Allowed & Legal_Mem) && isScalarFloatingType(From->getType())) |
| 4275 (From->getType() == IceType_f32 || From->getType() == IceType_f64)) | |
| 4276 // On x86, FP constants are lowered to mem operands. | 4278 // On x86, FP constants are lowered to mem operands. |
| 4277 NeedsReg = true; | 4279 NeedsReg = true; |
| 4278 if (NeedsReg) { | 4280 if (NeedsReg) { |
| 4279 From = copyToReg(From, RegNum); | 4281 From = copyToReg(From, RegNum); |
| 4280 } | 4282 } |
| 4281 return From; | 4283 return From; |
| 4282 } | 4284 } |
| 4283 if (Variable *Var = llvm::dyn_cast<Variable>(From)) { | 4285 if (Variable *Var = llvm::dyn_cast<Variable>(From)) { |
| 4284 // Check if the variable is guaranteed a physical register. This | 4286 // Check if the variable is guaranteed a physical register. This |
| 4285 // can happen either when the variable is pre-colored or when it is | 4287 // can happen either when the variable is pre-colored or when it is |
| (...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4554 Str << "\t.align\t" << Align << "\n"; | 4556 Str << "\t.align\t" << Align << "\n"; |
| 4555 Str << MangledName << ":\n"; | 4557 Str << MangledName << ":\n"; |
| 4556 for (SizeT i = 0; i < Size; ++i) { | 4558 for (SizeT i = 0; i < Size; ++i) { |
| 4557 Str << "\t.byte\t" << (((unsigned)Data[i]) & 0xff) << "\n"; | 4559 Str << "\t.byte\t" << (((unsigned)Data[i]) & 0xff) << "\n"; |
| 4558 } | 4560 } |
| 4559 Str << "\t.size\t" << MangledName << ", " << Size << "\n"; | 4561 Str << "\t.size\t" << MangledName << ", " << Size << "\n"; |
| 4560 } | 4562 } |
| 4561 } | 4563 } |
| 4562 | 4564 |
| 4563 } // end of namespace Ice | 4565 } // end of namespace Ice |
| OLD | NEW |