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 |