Changeset 196799 in webkit
- Timestamp:
- Feb 18, 2016 10:42:06 PM (8 years ago)
- Location:
- trunk/Source/JavaScriptCore
- Files:
-
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/ChangeLog
r196796 r196799 1 2016-02-18 Benjamin Poulain <bpoulain@apple.com> 2 3 [JSC] Improve the instruction selection of Select 4 https://bugs.webkit.org/show_bug.cgi?id=154432 5 6 Reviewed by Filip Pizlo. 7 8 Plenty of code but this patch is pretty dumb: 9 -On ARM64: use the 3 operand form of CSEL instead of forcing a source 10 to be alised to the destination. This gives more freedom to the register 11 allocator and it is one less Move to process per Select. 12 -On x86, introduce a fake 3 operands form and use aggressive aliasing 13 to try to alias both sources to the destination. 14 15 If aliasing succeed on the "elseCase", the condition of the Select 16 is reverted in the MacroAssembler. 17 18 If no aliasing is possible and we end up with 3 registers, the missing 19 move instruction is generated by the MacroAssembler. 20 21 The missing move is generated after testing the values because the destination 22 can use the same register as one of the test operand. 23 Experimental testing seems to indicate there is no macro-fusion on CMOV, 24 there is no measurable cost to having the move there. 25 26 * assembler/MacroAssembler.h: 27 (JSC::MacroAssembler::isInvertible): 28 (JSC::MacroAssembler::invert): 29 * assembler/MacroAssemblerARM64.h: 30 (JSC::MacroAssemblerARM64::moveConditionallyDouble): 31 (JSC::MacroAssemblerARM64::moveConditionallyFloat): 32 (JSC::MacroAssemblerARM64::moveConditionallyAfterFloatingPointCompare): 33 (JSC::MacroAssemblerARM64::moveConditionally32): 34 (JSC::MacroAssemblerARM64::moveConditionally64): 35 (JSC::MacroAssemblerARM64::moveConditionallyTest32): 36 (JSC::MacroAssemblerARM64::moveConditionallyTest64): 37 * assembler/MacroAssemblerX86Common.h: 38 (JSC::MacroAssemblerX86Common::moveConditionallyDouble): 39 (JSC::MacroAssemblerX86Common::moveConditionallyFloat): 40 (JSC::MacroAssemblerX86Common::moveConditionally32): 41 (JSC::MacroAssemblerX86Common::moveConditionallyTest32): 42 (JSC::MacroAssemblerX86Common::invert): 43 (JSC::MacroAssemblerX86Common::isInvertible): 44 * assembler/MacroAssemblerX86_64.h: 45 (JSC::MacroAssemblerX86_64::moveConditionally64): 46 (JSC::MacroAssemblerX86_64::moveConditionallyTest64): 47 * b3/B3LowerToAir.cpp: 48 (JSC::B3::Air::LowerToAir::createSelect): 49 (JSC::B3::Air::LowerToAir::lower): 50 * b3/air/AirInstInlines.h: 51 (JSC::B3::Air::Inst::shouldTryAliasingDef): 52 * b3/air/AirOpcode.opcodes: 53 1 54 2016-02-18 Gyuyoung Kim <gyuyoung.kim@webkit.org> 2 55 -
trunk/Source/JavaScriptCore/assembler/MacroAssembler.h
r194628 r196799 178 178 case Zero: 179 179 case NonZero: 180 case Signed: 181 case PositiveOrZero: 180 182 return true; 181 183 default: … … 191 193 case NonZero: 192 194 return Zero; 195 case Signed: 196 return PositiveOrZero; 197 case PositiveOrZero: 198 return Signed; 193 199 default: 194 200 RELEASE_ASSERT_NOT_REACHED(); -
trunk/Source/JavaScriptCore/assembler/MacroAssemblerARM64.h
r196736 r196799 1602 1602 } 1603 1603 1604 void moveConditionallyDouble(DoubleCondition cond, FPRegisterID left, FPRegisterID right, RegisterID thenCase, RegisterID elseCase, RegisterID dest) 1605 { 1606 m_assembler.fcmp<64>(left, right); 1607 moveConditionallyAfterFloatingPointCompare<64>(cond, thenCase, elseCase, dest); 1608 } 1609 1604 1610 void moveConditionallyFloat(DoubleCondition cond, FPRegisterID left, FPRegisterID right, RegisterID src, RegisterID dest) 1605 1611 { 1606 1612 m_assembler.fcmp<32>(left, right); 1607 1613 moveConditionallyAfterFloatingPointCompare<64>(cond, src, dest); 1614 } 1615 1616 void moveConditionallyFloat(DoubleCondition cond, FPRegisterID left, FPRegisterID right, RegisterID thenCase, RegisterID elseCase, RegisterID dest) 1617 { 1618 m_assembler.fcmp<32>(left, right); 1619 moveConditionallyAfterFloatingPointCompare<64>(cond, thenCase, elseCase, dest); 1608 1620 } 1609 1621 … … 1627 1639 } 1628 1640 m_assembler.csel<datasize>(dest, src, dest, ARM64Condition(cond)); 1641 } 1642 1643 template<int datasize> 1644 void moveConditionallyAfterFloatingPointCompare(DoubleCondition cond, RegisterID thenCase, RegisterID elseCase, RegisterID dest) 1645 { 1646 if (cond == DoubleNotEqual) { 1647 Jump unordered = makeBranch(ARM64Assembler::ConditionVS); 1648 m_assembler.csel<datasize>(dest, thenCase, elseCase, ARM64Assembler::ConditionNE); 1649 unordered.link(this); 1650 return; 1651 } 1652 if (cond == DoubleEqualOrUnordered) { 1653 // If the compare is unordered, thenCase is copied to dest and the 1654 // next csel has all arguments equal to thenCase. 1655 // If the compare is ordered, dest is unchanged and EQ decides 1656 // what value to set. 1657 m_assembler.csel<datasize>(dest, thenCase, elseCase, ARM64Assembler::ConditionVS); 1658 m_assembler.csel<datasize>(dest, thenCase, dest, ARM64Assembler::ConditionEQ); 1659 return; 1660 } 1661 m_assembler.csel<datasize>(dest, thenCase, elseCase, ARM64Condition(cond)); 1629 1662 } 1630 1663 … … 1895 1928 } 1896 1929 1930 void moveConditionally32(RelationalCondition cond, RegisterID left, RegisterID right, RegisterID thenCase, RegisterID elseCase, RegisterID dest) 1931 { 1932 m_assembler.cmp<32>(left, right); 1933 m_assembler.csel<32>(dest, thenCase, elseCase, ARM64Condition(cond)); 1934 } 1935 1897 1936 void moveConditionally64(RelationalCondition cond, RegisterID left, RegisterID right, RegisterID src, RegisterID dest) 1898 1937 { … … 1901 1940 } 1902 1941 1942 void moveConditionally64(RelationalCondition cond, RegisterID left, RegisterID right, RegisterID thenCase, RegisterID elseCase, RegisterID dest) 1943 { 1944 m_assembler.cmp<64>(left, right); 1945 m_assembler.csel<64>(dest, thenCase, elseCase, ARM64Condition(cond)); 1946 } 1947 1903 1948 void moveConditionallyTest32(ResultCondition cond, RegisterID testReg, RegisterID mask, RegisterID src, RegisterID dest) 1904 1949 { … … 1907 1952 } 1908 1953 1954 void moveConditionallyTest32(ResultCondition cond, RegisterID left, RegisterID right, RegisterID thenCase, RegisterID elseCase, RegisterID dest) 1955 { 1956 m_assembler.tst<32>(left, right); 1957 m_assembler.csel<32>(dest, thenCase, elseCase, ARM64Condition(cond)); 1958 } 1959 1909 1960 void moveConditionallyTest64(ResultCondition cond, RegisterID testReg, RegisterID mask, RegisterID src, RegisterID dest) 1910 1961 { 1911 1962 m_assembler.tst<64>(testReg, mask); 1912 1963 m_assembler.csel<64>(dest, src, dest, ARM64Condition(cond)); 1964 } 1965 1966 void moveConditionallyTest64(ResultCondition cond, RegisterID left, RegisterID right, RegisterID thenCase, RegisterID elseCase, RegisterID dest) 1967 { 1968 m_assembler.tst<64>(left, right); 1969 m_assembler.csel<64>(dest, thenCase, elseCase, ARM64Condition(cond)); 1913 1970 } 1914 1971 -
trunk/Source/JavaScriptCore/assembler/MacroAssemblerX86Common.h
r196513 r196799 1578 1578 } 1579 1579 1580 void moveConditionallyDouble(DoubleCondition cond, FPRegisterID left, FPRegisterID right, RegisterID thenCase, RegisterID elseCase, RegisterID dest) 1581 { 1582 ASSERT(isSSE2Present()); 1583 1584 if (thenCase != dest && elseCase != dest) { 1585 move(elseCase, dest); 1586 elseCase = dest; 1587 } 1588 1589 RegisterID src; 1590 if (elseCase == dest) 1591 src = thenCase; 1592 else { 1593 cond = invert(cond); 1594 src = elseCase; 1595 } 1596 1597 if (cond & DoubleConditionBitInvert) 1598 m_assembler.ucomisd_rr(left, right); 1599 else 1600 m_assembler.ucomisd_rr(right, left); 1601 moveConditionallyAfterFloatingPointCompare(cond, left, right, src, dest); 1602 } 1603 1580 1604 void moveConditionallyFloat(DoubleCondition cond, FPRegisterID left, FPRegisterID right, RegisterID src, RegisterID dest) 1581 1605 { … … 1588 1612 moveConditionallyAfterFloatingPointCompare(cond, left, right, src, dest); 1589 1613 } 1614 1615 void moveConditionallyFloat(DoubleCondition cond, FPRegisterID left, FPRegisterID right, RegisterID thenCase, RegisterID elseCase, RegisterID dest) 1616 { 1617 ASSERT(isSSE2Present()); 1618 1619 if (thenCase != dest && elseCase != dest) { 1620 move(elseCase, dest); 1621 elseCase = dest; 1622 } 1623 1624 RegisterID src; 1625 if (elseCase == dest) 1626 src = thenCase; 1627 else { 1628 cond = invert(cond); 1629 src = elseCase; 1630 } 1631 1632 if (cond & DoubleConditionBitInvert) 1633 m_assembler.ucomiss_rr(left, right); 1634 else 1635 m_assembler.ucomiss_rr(right, left); 1636 moveConditionallyAfterFloatingPointCompare(cond, left, right, src, dest); 1637 } 1590 1638 1591 1639 void swap(RegisterID reg1, RegisterID reg2) … … 1701 1749 } 1702 1750 1751 void moveConditionally32(RelationalCondition cond, RegisterID left, RegisterID right, RegisterID thenCase, RegisterID elseCase, RegisterID dest) 1752 { 1753 m_assembler.cmpl_rr(right, left); 1754 1755 if (thenCase != dest && elseCase != dest) { 1756 move(elseCase, dest); 1757 elseCase = dest; 1758 } 1759 1760 if (elseCase == dest) 1761 cmov(x86Condition(cond), thenCase, dest); 1762 else 1763 cmov(x86Condition(invert(cond)), elseCase, dest); 1764 } 1765 1703 1766 void moveConditionallyTest32(ResultCondition cond, RegisterID testReg, RegisterID mask, RegisterID src, RegisterID dest) 1704 1767 { … … 1706 1769 cmov(x86Condition(cond), src, dest); 1707 1770 } 1708 1771 1772 void moveConditionallyTest32(ResultCondition cond, RegisterID left, RegisterID right, RegisterID thenCase, RegisterID elseCase, RegisterID dest) 1773 { 1774 ASSERT(isInvertible(cond)); 1775 ASSERT_WITH_MESSAGE(cond != Overflow, "TEST does not set the Overflow Flag."); 1776 1777 m_assembler.testl_rr(right, left); 1778 1779 if (thenCase != dest && elseCase != dest) { 1780 move(elseCase, dest); 1781 elseCase = dest; 1782 } 1783 1784 if (elseCase == dest) 1785 cmov(x86Condition(cond), thenCase, dest); 1786 else 1787 cmov(x86Condition(invert(cond)), elseCase, dest); 1788 } 1789 1709 1790 void moveConditionallyTest32(ResultCondition cond, RegisterID testReg, TrustedImm32 mask, RegisterID src, RegisterID dest) 1710 1791 { … … 1712 1793 cmov(x86Condition(cond), src, dest); 1713 1794 } 1714 1795 1796 void moveConditionallyTest32(ResultCondition cond, RegisterID testReg, TrustedImm32 mask, RegisterID thenCase, RegisterID elseCase, RegisterID dest) 1797 { 1798 ASSERT(isInvertible(cond)); 1799 ASSERT_WITH_MESSAGE(cond != Overflow, "TEST does not set the Overflow Flag."); 1800 1801 test32(cond, testReg, mask); 1802 1803 if (thenCase != dest && elseCase != dest) { 1804 move(elseCase, dest); 1805 elseCase = dest; 1806 } 1807 1808 if (elseCase == dest) 1809 cmov(x86Condition(cond), thenCase, dest); 1810 else 1811 cmov(x86Condition(invert(cond)), elseCase, dest); 1812 } 1715 1813 1716 1814 // Forwards / external control flow operations: … … 2119 2217 { 2120 2218 return static_cast<RelationalCondition>(cond ^ 1); 2219 } 2220 2221 static DoubleCondition invert(DoubleCondition cond) 2222 { 2223 switch (cond) { 2224 case DoubleEqual: 2225 return DoubleNotEqualOrUnordered; 2226 case DoubleNotEqual: 2227 return DoubleEqualOrUnordered; 2228 case DoubleGreaterThan: 2229 return DoubleLessThanOrEqualOrUnordered; 2230 case DoubleGreaterThanOrEqual: 2231 return DoubleLessThanOrUnordered; 2232 case DoubleLessThan: 2233 return DoubleGreaterThanOrEqualOrUnordered; 2234 case DoubleLessThanOrEqual: 2235 return DoubleGreaterThanOrUnordered; 2236 case DoubleEqualOrUnordered: 2237 return DoubleNotEqual; 2238 case DoubleNotEqualOrUnordered: 2239 return DoubleEqual; 2240 case DoubleGreaterThanOrUnordered: 2241 return DoubleLessThanOrEqual; 2242 case DoubleGreaterThanOrEqualOrUnordered: 2243 return DoubleLessThan; 2244 case DoubleLessThanOrUnordered: 2245 return DoubleGreaterThanOrEqual; 2246 case DoubleLessThanOrEqualOrUnordered: 2247 return DoubleGreaterThan; 2248 } 2249 RELEASE_ASSERT_NOT_REACHED(); 2250 return DoubleEqual; // make compiler happy 2251 } 2252 2253 static bool isInvertible(ResultCondition cond) 2254 { 2255 switch (cond) { 2256 case Zero: 2257 case NonZero: 2258 case Signed: 2259 case PositiveOrZero: 2260 return true; 2261 default: 2262 return false; 2263 } 2264 } 2265 2266 static ResultCondition invert(ResultCondition cond) 2267 { 2268 switch (cond) { 2269 case Zero: 2270 return NonZero; 2271 case NonZero: 2272 return Zero; 2273 case Signed: 2274 return PositiveOrZero; 2275 case PositiveOrZero: 2276 return Signed; 2277 default: 2278 RELEASE_ASSERT_NOT_REACHED(); 2279 return Zero; // Make compiler happy for release builds. 2280 } 2121 2281 } 2122 2282 -
trunk/Source/JavaScriptCore/assembler/MacroAssemblerX86_64.h
r196513 r196799 980 980 } 981 981 982 void moveConditionally64(RelationalCondition cond, RegisterID left, RegisterID right, RegisterID thenCase, RegisterID elseCase, RegisterID dest) 983 { 984 m_assembler.cmpq_rr(right, left); 985 986 if (thenCase != dest && elseCase != dest) { 987 move(elseCase, dest); 988 elseCase = dest; 989 } 990 991 if (elseCase == dest) 992 cmov(x86Condition(cond), thenCase, dest); 993 else 994 cmov(x86Condition(invert(cond)), elseCase, dest); 995 } 996 982 997 void moveConditionallyTest64(ResultCondition cond, RegisterID testReg, RegisterID mask, RegisterID src, RegisterID dest) 983 998 { 984 999 m_assembler.testq_rr(testReg, mask); 985 1000 cmov(x86Condition(cond), src, dest); 1001 } 1002 1003 void moveConditionallyTest64(ResultCondition cond, RegisterID left, RegisterID right, RegisterID thenCase, RegisterID elseCase, RegisterID dest) 1004 { 1005 ASSERT(isInvertible(cond)); 1006 ASSERT_WITH_MESSAGE(cond != Overflow, "TEST does not set the Overflow Flag."); 1007 1008 m_assembler.testq_rr(right, left); 1009 1010 if (thenCase != dest && elseCase != dest) { 1011 move(elseCase, dest); 1012 elseCase = dest; 1013 } 1014 1015 if (elseCase == dest) 1016 cmov(x86Condition(cond), thenCase, dest); 1017 else 1018 cmov(x86Condition(invert(cond)), elseCase, dest); 986 1019 } 987 1020 … … 996 1029 m_assembler.testq_i32r(mask.m_value, testReg); 997 1030 cmov(x86Condition(cond), src, dest); 1031 } 1032 1033 void moveConditionallyTest64(ResultCondition cond, RegisterID testReg, TrustedImm32 mask, RegisterID thenCase, RegisterID elseCase, RegisterID dest) 1034 { 1035 ASSERT(isInvertible(cond)); 1036 ASSERT_WITH_MESSAGE(cond != Overflow, "TEST does not set the Overflow Flag."); 1037 1038 if (mask.m_value == -1) 1039 m_assembler.testq_rr(testReg, testReg); 1040 else if (!(mask.m_value & ~0x7f)) 1041 m_assembler.testb_i8r(mask.m_value, testReg); 1042 else 1043 m_assembler.testq_i32r(mask.m_value, testReg); 1044 1045 if (thenCase != dest && elseCase != dest) { 1046 move(elseCase, dest); 1047 elseCase = dest; 1048 } 1049 1050 if (elseCase == dest) 1051 cmov(x86Condition(cond), thenCase, dest); 1052 else 1053 cmov(x86Condition(invert(cond)), elseCase, dest); 998 1054 } 999 1055 -
trunk/Source/JavaScriptCore/b3/B3LowerToAir.cpp
r196736 r196799 1600 1600 Air::Opcode moveConditionallyDouble; 1601 1601 Air::Opcode moveConditionallyFloat; 1602 Tmp source;1603 Tmp destination;1604 1602 }; 1605 Inst createSelect(Value* value, const MoveConditionallyConfig& config, bool inverted = false) 1606 { 1603 Inst createSelect(const MoveConditionallyConfig& config) 1604 { 1605 auto createSelectInstruction = [&] (Air::Opcode opcode, const Arg& condition, const ArgPromise& left, const ArgPromise& right) -> Inst { 1606 if (isValidForm(opcode, condition.kind(), left.kind(), right.kind(), Arg::Tmp, Arg::Tmp, Arg::Tmp)) { 1607 Tmp result = tmp(m_value); 1608 Tmp thenCase = tmp(m_value->child(1)); 1609 Tmp elseCase = tmp(m_value->child(2)); 1610 append(relaxedMoveForType(m_value->type()), tmp(m_value->child(2)), result); 1611 return Inst( 1612 opcode, m_value, condition, 1613 left.consume(*this), right.consume(*this), thenCase, elseCase, result); 1614 } 1615 if (isValidForm(opcode, condition.kind(), left.kind(), right.kind(), Arg::Tmp, Arg::Tmp)) { 1616 Tmp result = tmp(m_value); 1617 Tmp source = tmp(m_value->child(1)); 1618 append(relaxedMoveForType(m_value->type()), tmp(m_value->child(2)), result); 1619 return Inst( 1620 opcode, m_value, condition, 1621 left.consume(*this), right.consume(*this), source, result); 1622 } 1623 return Inst(); 1624 }; 1625 1607 1626 return createGenericCompare( 1608 value,1627 m_value->child(0), 1609 1628 [&] ( 1610 1629 Arg::Width width, const Arg& relCond, … … 1618 1637 return Inst(); 1619 1638 case Arg::Width32: 1620 if (isValidForm(config.moveConditionally32, Arg::RelCond, left.kind(), right.kind(), Arg::Tmp, Arg::Tmp)) { 1621 return Inst( 1622 config.moveConditionally32, m_value, relCond, 1623 left.consume(*this), right.consume(*this), config.source, config.destination); 1624 } 1625 return Inst(); 1639 return createSelectInstruction(config.moveConditionally32, relCond, left, right); 1626 1640 case Arg::Width64: 1627 if (isValidForm(config.moveConditionally64, Arg::RelCond, left.kind(), right.kind(), Arg::Tmp, Arg::Tmp)) { 1628 return Inst( 1629 config.moveConditionally64, m_value, relCond, 1630 left.consume(*this), right.consume(*this), config.source, config.destination); 1631 } 1632 return Inst(); 1641 return createSelectInstruction(config.moveConditionally64, relCond, left, right); 1633 1642 } 1634 1643 ASSERT_NOT_REACHED(); … … 1645 1654 return Inst(); 1646 1655 case Arg::Width32: 1647 if (isValidForm(config.moveConditionallyTest32, Arg::ResCond, left.kind(), right.kind(), Arg::Tmp, Arg::Tmp)) { 1648 return Inst( 1649 config.moveConditionallyTest32, m_value, resCond, 1650 left.consume(*this), right.consume(*this), config.source, config.destination); 1651 } 1652 return Inst(); 1656 return createSelectInstruction(config.moveConditionallyTest32, resCond, left, right); 1653 1657 case Arg::Width64: 1654 if (isValidForm(config.moveConditionallyTest64, Arg::ResCond, left.kind(), right.kind(), Arg::Tmp, Arg::Tmp)) { 1655 return Inst( 1656 config.moveConditionallyTest64, m_value, resCond, 1657 left.consume(*this), right.consume(*this), config.source, config.destination); 1658 } 1659 return Inst(); 1658 return createSelectInstruction(config.moveConditionallyTest64, resCond, left, right); 1660 1659 } 1661 1660 ASSERT_NOT_REACHED(); 1662 1661 }, 1663 1662 [&] (Arg doubleCond, const ArgPromise& left, const ArgPromise& right) -> Inst { 1664 if (isValidForm(config.moveConditionallyDouble, Arg::DoubleCond, left.kind(), right.kind(), Arg::Tmp, Arg::Tmp)) { 1665 return Inst( 1666 config.moveConditionallyDouble, m_value, doubleCond, 1667 left.consume(*this), right.consume(*this), config.source, config.destination); 1668 } 1669 return Inst(); 1663 return createSelectInstruction(config.moveConditionallyDouble, doubleCond, left, right); 1670 1664 }, 1671 1665 [&] (Arg doubleCond, const ArgPromise& left, const ArgPromise& right) -> Inst { 1672 if (isValidForm(config.moveConditionallyFloat, Arg::DoubleCond, left.kind(), right.kind(), Arg::Tmp, Arg::Tmp)) { 1673 return Inst( 1674 config.moveConditionallyFloat, m_value, doubleCond, 1675 left.consume(*this), right.consume(*this), config.source, config.destination); 1676 } 1677 return Inst(); 1666 return createSelectInstruction(config.moveConditionallyFloat, doubleCond, left, right); 1678 1667 }, 1679 inverted);1668 false); 1680 1669 } 1681 1670 … … 2028 2017 2029 2018 case Select: { 2030 Tmp result = tmp(m_value);2031 append(relaxedMoveForType(m_value->type()), tmp(m_value->child(2)), result);2032 2033 2019 MoveConditionallyConfig config; 2034 config.source = tmp(m_value->child(1));2035 config.destination = result;2036 2037 2020 if (isInt(m_value->type())) { 2038 2021 config.moveConditionally32 = MoveConditionally32; … … 2052 2035 } 2053 2036 2054 m_insts.last().append(createSelect( m_value->child(0),config));2037 m_insts.last().append(createSelect(config)); 2055 2038 return; 2056 2039 } -
trunk/Source/JavaScriptCore/b3/air/AirInstInlines.h
r196573 r196799 197 197 return 3; 198 198 break; 199 case MoveConditionally32: 200 case MoveConditionally64: 201 case MoveConditionallyTest32: 202 case MoveConditionallyTest64: 203 case MoveConditionallyDouble: 204 case MoveConditionallyFloat: 205 if (args.size() == 6) 206 return 5; 207 break; 208 break; 199 209 case Patch: 200 210 return PatchCustom::shouldTryAliasingDef(*this); -
trunk/Source/JavaScriptCore/b3/air/AirOpcode.opcodes
r196736 r196799 714 714 RelCond, Tmp, Tmp, Tmp, Tmp 715 715 716 MoveConditionally32 U:G:32, U:G:32, U:G:32, U:G:Ptr, U:G:Ptr, D:G:Ptr 717 RelCond, Tmp, Tmp, Tmp, Tmp, Tmp 718 716 719 64: MoveConditionally64 U:G:32, U:G:64, U:G:64, U:G:Ptr, UD:G:Ptr 717 720 RelCond, Tmp, Tmp, Tmp, Tmp 721 722 64: MoveConditionally64 U:G:32, U:G:64, U:G:64, U:G:Ptr, U:G:Ptr, D:G:Ptr 723 RelCond, Tmp, Tmp, Tmp, Tmp, Tmp 718 724 719 725 MoveConditionallyTest32 U:G:32, U:G:32, U:G:32, U:G:Ptr, UD:G:Ptr … … 721 727 x86: ResCond, Tmp, Imm, Tmp, Tmp 722 728 729 MoveConditionallyTest32 U:G:32, U:G:32, U:G:32, U:G:Ptr, U:G:Ptr, D:G:Ptr 730 ResCond, Tmp, Tmp, Tmp, Tmp, Tmp 731 x86: ResCond, Tmp, Imm, Tmp, Tmp, Tmp 732 723 733 64: MoveConditionallyTest64 U:G:32, U:G:64, U:G:64, U:G:Ptr, UD:G:Ptr 724 734 ResCond, Tmp, Tmp, Tmp, Tmp 725 735 x86: ResCond, Tmp, Imm, Tmp, Tmp 726 736 737 64: MoveConditionallyTest64 U:G:32, U:G:32, U:G:32, U:G:Ptr, U:G:Ptr, D:G:Ptr 738 ResCond, Tmp, Tmp, Tmp, Tmp, Tmp 739 x86_64: ResCond, Tmp, Imm, Tmp, Tmp, Tmp 740 741 MoveConditionallyDouble U:G:32, U:F:64, U:F:64, U:G:Ptr, U:G:Ptr, D:G:Ptr 742 DoubleCond, Tmp, Tmp, Tmp, Tmp, Tmp 743 727 744 MoveConditionallyDouble U:G:32, U:F:64, U:F:64, U:G:Ptr, UD:G:Ptr 728 745 DoubleCond, Tmp, Tmp, Tmp, Tmp 746 747 MoveConditionallyFloat U:G:32, U:F:32, U:F:32, U:G:Ptr, U:G:Ptr, D:G:Ptr 748 DoubleCond, Tmp, Tmp, Tmp, Tmp, Tmp 729 749 730 750 MoveConditionallyFloat U:G:32, U:F:32, U:F:32, U:G:Ptr, UD:G:Ptr
Note: See TracChangeset
for help on using the changeset viewer.