Changeset 36976 in webkit for trunk/JavaScriptCore/VM/CTI.cpp
- Timestamp:
- Sep 26, 2008, 6:44:15 PM (17 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JavaScriptCore/VM/CTI.cpp
r36972 r36976 33 33 #include "Machine.h" 34 34 #include "wrec/WREC.h" 35 #include "ResultType.h" 36 #if PLATFORM(MAC) 37 #include <sys/sysctl.h> 38 #endif 35 39 36 40 using namespace std; 37 41 38 42 namespace JSC { 43 44 #if PLATFORM(MAC) 45 bool isSSE3Present() 46 { 47 struct SSE3Check { 48 SSE3Check() 49 { 50 int hasSSE3 = 0; 51 size_t length = sizeof(hasSSE3); 52 int error = sysctlbyname("hw.optional.sse3", &hasSSE3, &length, NULL, 0); 53 present = hasSSE3 && !error; 54 } 55 bool present; 56 }; 57 static SSE3Check check; 58 return check.present; 59 } 60 #else 61 bool isSSE3Present() 62 { 63 return false; 64 } 65 #endif 39 66 40 67 #if COMPILER(GCC) && PLATFORM(X86) … … 602 629 } 603 630 631 /* 632 This is required since number representation is canonical - values representable as a JSImmediate should not be stored in a JSNumberCell. 633 634 In the common case, the double value from 'xmmSource' is written to the reusable JSNumberCell pointed to by 'jsNumberCell', then 'jsNumberCell' 635 is written to the output SF Register 'dst', and then a jump is planted (stored into *wroteJSNumberCell). 636 637 However if the value from xmmSource is representable as a JSImmediate, then the JSImmediate value will be written to the output, and flow 638 control will fall through from the code planted. 639 */ 640 void CTI::putDoubleResultToJSNumberCellOrJSImmediate(X86::XMMRegisterID xmmSource, X86::RegisterID jsNumberCell, unsigned dst, X86Assembler::JmpSrc* wroteJSNumberCell, X86::XMMRegisterID tempXmm, X86::RegisterID tempReg1, X86::RegisterID tempReg2) 641 { 642 // convert (double -> JSImmediate -> double), and check if the value is unchanged - in which case the value is representable as a JSImmediate. 643 m_jit.cvttsd2si_rr(xmmSource, tempReg1); 644 m_jit.addl_rr(tempReg1, tempReg1); 645 m_jit.sarl_i8r(1, tempReg1); 646 m_jit.cvtsi2sd_rr(tempReg1, tempXmm); 647 // Compare & branch if immediate. 648 m_jit.ucomis_rr(tempXmm, xmmSource); 649 X86Assembler::JmpSrc resultIsImm = m_jit.emitUnlinkedJe(); 650 X86Assembler::JmpDst resultLookedLikeImmButActuallyIsnt = m_jit.label(); 651 652 // Store the result to the JSNumberCell and jump. 653 m_jit.movsd_rm(xmmSource, OBJECT_OFFSET(JSNumberCell, m_value), jsNumberCell); 654 emitPutResult(dst, jsNumberCell); 655 *wroteJSNumberCell = m_jit.emitUnlinkedJmp(); 656 657 m_jit.link(resultIsImm, m_jit.label()); 658 // value == (double)(JSImmediate)value... or at least, it looks that way... 659 // ucomi will report that (0 == -0), and will report true if either input in NaN (result is unordered). 660 m_jit.link(m_jit.emitUnlinkedJp(), resultLookedLikeImmButActuallyIsnt); // Actually was a NaN 661 m_jit.pextrw_irr(3, xmmSource, tempReg2); 662 m_jit.cmpl_i32r(0x8000, tempReg2); 663 m_jit.link(m_jit.emitUnlinkedJe(), resultLookedLikeImmButActuallyIsnt); // Actually was -0 664 // Yes it really really really is representable as a JSImmediate. 665 emitFastArithIntToImmNoCheck(tempReg1); 666 emitPutResult(dst, X86::ecx); 667 } 668 669 void CTI::compileBinaryArithOp(OpcodeID opcodeID, unsigned dst, unsigned src1, unsigned src2, OperandTypes types, unsigned i) 670 { 671 StructureID* numberStructureID = m_exec->globalData().numberStructureID.get(); 672 X86Assembler::JmpSrc wasJSNumberCell1, wasJSNumberCell1b, wasJSNumberCell2, wasJSNumberCell2b; 673 674 emitGetArg(src1, X86::eax); 675 emitGetArg(src2, X86::edx); 676 677 if (types.second().isReusable() && isSSE3Present()) { 678 ASSERT(types.second().mightBeNumber()); 679 680 // Check op2 is a number 681 m_jit.testl_i32r(JSImmediate::TagBitTypeInteger, X86::edx); 682 X86Assembler::JmpSrc op2imm = m_jit.emitUnlinkedJne(); 683 if (!types.second().definitelyIsNumber()) { 684 emitJumpSlowCaseIfNotJSCell(X86::edx, i); 685 m_jit.cmpl_i32m(reinterpret_cast<unsigned>(numberStructureID), OBJECT_OFFSET(JSCell, m_structureID), X86::edx); 686 m_slowCases.append(SlowCaseEntry(m_jit.emitUnlinkedJne(), i)); 687 } 688 689 // (1) In this case src2 is a reusable number cell. 690 // Slow case if src1 is not a number type. 691 m_jit.testl_i32r(JSImmediate::TagBitTypeInteger, X86::eax); 692 X86Assembler::JmpSrc op1imm = m_jit.emitUnlinkedJne(); 693 if (!types.first().definitelyIsNumber()) { 694 emitJumpSlowCaseIfNotJSCell(X86::eax, i); 695 m_jit.cmpl_i32m(reinterpret_cast<unsigned>(numberStructureID), OBJECT_OFFSET(JSCell, m_structureID), X86::eax); 696 m_slowCases.append(SlowCaseEntry(m_jit.emitUnlinkedJne(), i)); 697 } 698 699 // (1a) if we get here, src1 is also a number cell 700 m_jit.movsd_mr(OBJECT_OFFSET(JSNumberCell, m_value), X86::eax, X86::xmm0); 701 X86Assembler::JmpSrc loadedDouble = m_jit.emitUnlinkedJmp(); 702 // (1b) if we get here, src1 is an immediate 703 m_jit.link(op1imm, m_jit.label()); 704 emitFastArithImmToInt(X86::eax); 705 m_jit.cvtsi2sd_rr(X86::eax, X86::xmm0); 706 // (1c) 707 m_jit.link(loadedDouble, m_jit.label()); 708 if (opcodeID == op_add) 709 m_jit.addsd_mr(OBJECT_OFFSET(JSNumberCell, m_value), X86::edx, X86::xmm0); 710 else if (opcodeID == op_sub) 711 m_jit.subsd_mr(OBJECT_OFFSET(JSNumberCell, m_value), X86::edx, X86::xmm0); 712 else { 713 ASSERT(opcodeID == op_mul); 714 m_jit.mulsd_mr(OBJECT_OFFSET(JSNumberCell, m_value), X86::edx, X86::xmm0); 715 } 716 717 putDoubleResultToJSNumberCellOrJSImmediate(X86::xmm0, X86::edx, dst, &wasJSNumberCell2, X86::xmm1, X86::ecx, X86::eax); 718 wasJSNumberCell2b = m_jit.emitUnlinkedJmp(); 719 720 // (2) This handles cases where src2 is an immediate number. 721 // Two slow cases - either src1 isn't an immediate, or the subtract overflows. 722 m_jit.link(op2imm, m_jit.label()); 723 emitJumpSlowCaseIfNotImmNum(X86::eax, i); 724 } else if (types.first().isReusable() && isSSE3Present()) { 725 ASSERT(types.first().mightBeNumber()); 726 727 // Check op1 is a number 728 m_jit.testl_i32r(JSImmediate::TagBitTypeInteger, X86::eax); 729 X86Assembler::JmpSrc op1imm = m_jit.emitUnlinkedJne(); 730 if (!types.first().definitelyIsNumber()) { 731 emitJumpSlowCaseIfNotJSCell(X86::eax, i); 732 m_jit.cmpl_i32m(reinterpret_cast<unsigned>(numberStructureID), OBJECT_OFFSET(JSCell, m_structureID), X86::eax); 733 m_slowCases.append(SlowCaseEntry(m_jit.emitUnlinkedJne(), i)); 734 } 735 736 // (1) In this case src1 is a reusable number cell. 737 // Slow case if src2 is not a number type. 738 m_jit.testl_i32r(JSImmediate::TagBitTypeInteger, X86::edx); 739 X86Assembler::JmpSrc op2imm = m_jit.emitUnlinkedJne(); 740 if (!types.second().definitelyIsNumber()) { 741 emitJumpSlowCaseIfNotJSCell(X86::edx, i); 742 m_jit.cmpl_i32m(reinterpret_cast<unsigned>(numberStructureID), OBJECT_OFFSET(JSCell, m_structureID), X86::edx); 743 m_slowCases.append(SlowCaseEntry(m_jit.emitUnlinkedJne(), i)); 744 } 745 746 // (1a) if we get here, src2 is also a number cell 747 m_jit.movsd_mr(OBJECT_OFFSET(JSNumberCell, m_value), X86::edx, X86::xmm1); 748 X86Assembler::JmpSrc loadedDouble = m_jit.emitUnlinkedJmp(); 749 // (1b) if we get here, src2 is an immediate 750 m_jit.link(op2imm, m_jit.label()); 751 emitFastArithImmToInt(X86::edx); 752 m_jit.cvtsi2sd_rr(X86::edx, X86::xmm1); 753 // (1c) 754 m_jit.link(loadedDouble, m_jit.label()); 755 m_jit.movsd_mr(OBJECT_OFFSET(JSNumberCell, m_value), X86::eax, X86::xmm0); 756 if (opcodeID == op_add) 757 m_jit.addsd_rr(X86::xmm1, X86::xmm0); 758 else if (opcodeID == op_sub) 759 m_jit.subsd_rr(X86::xmm1, X86::xmm0); 760 else { 761 ASSERT(opcodeID == op_mul); 762 m_jit.mulsd_rr(X86::xmm1, X86::xmm0); 763 } 764 m_jit.movsd_rm(X86::xmm0, OBJECT_OFFSET(JSNumberCell, m_value), X86::eax); 765 emitPutResult(dst); 766 767 putDoubleResultToJSNumberCellOrJSImmediate(X86::xmm0, X86::eax, dst, &wasJSNumberCell1, X86::xmm1, X86::ecx, X86::edx); 768 wasJSNumberCell1b = m_jit.emitUnlinkedJmp(); 769 770 // (2) This handles cases where src1 is an immediate number. 771 // Two slow cases - either src2 isn't an immediate, or the subtract overflows. 772 m_jit.link(op1imm, m_jit.label()); 773 emitJumpSlowCaseIfNotImmNum(X86::edx, i); 774 } else 775 emitJumpSlowCaseIfNotImmNums(X86::eax, X86::edx, i); 776 777 if (opcodeID == op_add) { 778 emitFastArithDeTagImmediate(X86::eax); 779 m_jit.addl_rr(X86::edx, X86::eax); 780 m_slowCases.append(SlowCaseEntry(m_jit.emitUnlinkedJo(), i)); 781 } else if (opcodeID == op_sub) { 782 m_jit.subl_rr(X86::edx, X86::eax); 783 m_slowCases.append(SlowCaseEntry(m_jit.emitUnlinkedJo(), i)); 784 emitFastArithReTagImmediate(X86::eax); 785 } else { 786 ASSERT(opcodeID == op_mul); 787 emitFastArithDeTagImmediate(X86::eax); 788 emitFastArithImmToInt(X86::edx); 789 m_jit.imull_rr(X86::edx, X86::eax); 790 m_slowCases.append(SlowCaseEntry(m_jit.emitUnlinkedJo(), i)); 791 emitFastArithReTagImmediate(X86::eax); 792 } 793 emitPutResult(dst); 794 795 if (types.second().isReusable() && isSSE3Present()) { 796 m_jit.link(wasJSNumberCell2, m_jit.label()); 797 m_jit.link(wasJSNumberCell2b, m_jit.label()); 798 } 799 else if (types.first().isReusable() && isSSE3Present()) { 800 m_jit.link(wasJSNumberCell1, m_jit.label()); 801 m_jit.link(wasJSNumberCell1b, m_jit.label()); 802 } 803 } 804 805 void CTI::compileBinaryArithOpSlowCase(OpcodeID opcodeID, Vector<SlowCaseEntry>::iterator& iter, unsigned dst, unsigned src1, unsigned src2, OperandTypes types, unsigned i) 806 { 807 X86Assembler::JmpDst here = m_jit.label(); 808 m_jit.link(iter->from, here); 809 if (types.second().isReusable() && isSSE3Present()) { 810 if (!types.first().definitelyIsNumber()) { 811 m_jit.link((++iter)->from, here); 812 m_jit.link((++iter)->from, here); 813 } 814 if (!types.second().definitelyIsNumber()) { 815 m_jit.link((++iter)->from, here); 816 m_jit.link((++iter)->from, here); 817 } 818 m_jit.link((++iter)->from, here); 819 } else if (types.first().isReusable() && isSSE3Present()) { 820 if (!types.first().definitelyIsNumber()) { 821 m_jit.link((++iter)->from, here); 822 m_jit.link((++iter)->from, here); 823 } 824 if (!types.second().definitelyIsNumber()) { 825 m_jit.link((++iter)->from, here); 826 m_jit.link((++iter)->from, here); 827 } 828 m_jit.link((++iter)->from, here); 829 } else 830 m_jit.link((++iter)->from, here); 831 832 emitGetPutArg(src1, 0, X86::ecx); 833 emitGetPutArg(src2, 4, X86::ecx); 834 if (opcodeID == op_add) 835 emitCall(i, Machine::cti_op_add); 836 else if (opcodeID == op_sub) 837 emitCall(i, Machine::cti_op_sub); 838 else { 839 ASSERT(opcodeID == op_mul); 840 emitCall(i, Machine::cti_op_mul); 841 } 842 emitPutResult(dst); 843 } 844 604 845 void CTI::privateCompileMainPass() 605 846 { … … 633 874 unsigned src1 = instruction[i + 2].u.operand; 634 875 unsigned src2 = instruction[i + 3].u.operand; 635 if (isConstant(src2)) { 636 JSValue* value = getConstant(m_exec, src2); 637 if (JSImmediate::isNumber(value)) { 638 emitGetArg(src1, X86::eax); 639 emitJumpSlowCaseIfNotImmNum(X86::eax, i); 640 m_jit.addl_i32r(getDeTaggedConstantImmediate(value), X86::eax); 641 m_slowCases.append(SlowCaseEntry(m_jit.emitUnlinkedJo(), i)); 642 emitPutResult(dst); 643 i += 4; 644 break; 645 } 646 } else if (!isConstant(src1)) { 876 877 if (JSValue* value = getConstantImmediateNumericArg(src1)) { 878 emitGetArg(src2, X86::edx); 879 emitJumpSlowCaseIfNotImmNum(X86::edx, i); 880 m_jit.addl_i32r(getDeTaggedConstantImmediate(value), X86::edx); 881 m_slowCases.append(SlowCaseEntry(m_jit.emitUnlinkedJo(), i)); 882 emitPutResult(dst, X86::edx); 883 } else if (JSValue* value = getConstantImmediateNumericArg(src2)) { 647 884 emitGetArg(src1, X86::eax); 648 emitGetArg(src2, X86::edx); 649 emitJumpSlowCaseIfNotImmNums(X86::eax, X86::edx, i); 650 emitFastArithDeTagImmediate(X86::eax); 651 m_jit.addl_rr(X86::edx, X86::eax); 885 emitJumpSlowCaseIfNotImmNum(X86::eax, i); 886 m_jit.addl_i32r(getDeTaggedConstantImmediate(value), X86::eax); 652 887 m_slowCases.append(SlowCaseEntry(m_jit.emitUnlinkedJo(), i)); 653 888 emitPutResult(dst); 654 i += 4; 655 break; 889 } else { 890 OperandTypes types = OperandTypes::fromInt(instruction[i + 4].u.operand); 891 if (types.first().mightBeNumber() && types.second().mightBeNumber()) 892 compileBinaryArithOp(op_add, instruction[i + 1].u.operand, instruction[i + 2].u.operand, instruction[i + 3].u.operand, OperandTypes::fromInt(instruction[i + 4].u.operand), i); 893 else { 894 emitGetPutArg(instruction[i + 2].u.operand, 0, X86::ecx); 895 emitGetPutArg(instruction[i + 3].u.operand, 4, X86::ecx); 896 emitCall(i, Machine::cti_op_add); 897 emitPutResult(instruction[i + 1].u.operand); 898 } 656 899 } 657 emitGetPutArg(instruction[i + 2].u.operand, 0, X86::ecx); 658 emitGetPutArg(instruction[i + 3].u.operand, 4, X86::ecx); 659 emitCall(i, Machine::cti_op_add); 660 emitPutResult(instruction[i + 1].u.operand); 661 i += 4; 900 901 i += 5; 662 902 break; 663 903 } … … 876 1116 unsigned src1 = instruction[i + 2].u.operand; 877 1117 unsigned src2 = instruction[i + 3].u.operand; 878 if (isConstant(src1) || isConstant(src2)) { 879 unsigned constant = src1; 880 unsigned nonconstant = src2; 881 if (!isConstant(src1)) { 882 constant = src2; 883 nonconstant = src1; 884 } 885 JSValue* value = getConstant(m_exec, constant); 886 if (JSImmediate::isNumber(value)) { 887 emitGetArg(nonconstant, X86::eax); 888 emitJumpSlowCaseIfNotImmNum(X86::eax, i); 889 emitFastArithImmToInt(X86::eax); 890 m_jit.imull_i32r( X86::eax, getDeTaggedConstantImmediate(value), X86::eax); 891 m_slowCases.append(SlowCaseEntry(m_jit.emitUnlinkedJo(), i)); 892 emitFastArithPotentiallyReTagImmediate(X86::eax); 893 emitPutResult(dst); 894 i += 4; 895 break; 896 } 897 } 898 899 emitGetArg(src1, X86::eax); 900 emitGetArg(src2, X86::edx); 901 emitJumpSlowCaseIfNotImmNums(X86::eax, X86::edx, i); 902 emitFastArithDeTagImmediate(X86::eax); 903 emitFastArithImmToInt(X86::edx); 904 m_jit.imull_rr(X86::edx, X86::eax); 905 m_slowCases.append(SlowCaseEntry(m_jit.emitUnlinkedJo(), i)); 906 emitFastArithPotentiallyReTagImmediate(X86::eax); 907 emitPutResult(dst); 908 i += 4; 1118 1119 if (JSValue* src1Value = getConstantImmediateNumericArg(src1)) { 1120 emitGetArg(src2, X86::eax); 1121 emitJumpSlowCaseIfNotImmNum(X86::eax, i); 1122 emitFastArithImmToInt(X86::eax); 1123 m_jit.imull_i32r(X86::eax, getDeTaggedConstantImmediate(src1Value), X86::eax); 1124 m_slowCases.append(SlowCaseEntry(m_jit.emitUnlinkedJo(), i)); 1125 emitFastArithReTagImmediate(X86::eax); 1126 emitPutResult(dst); 1127 } else if (JSValue* src2Value = getConstantImmediateNumericArg(src2)) { 1128 emitGetArg(src1, X86::eax); 1129 emitJumpSlowCaseIfNotImmNum(X86::eax, i); 1130 emitFastArithImmToInt(X86::eax); 1131 m_jit.imull_i32r(X86::eax, getDeTaggedConstantImmediate(src2Value), X86::eax); 1132 m_slowCases.append(SlowCaseEntry(m_jit.emitUnlinkedJo(), i)); 1133 emitFastArithReTagImmediate(X86::eax); 1134 emitPutResult(dst); 1135 } else 1136 compileBinaryArithOp(op_mul, instruction[i + 1].u.operand, instruction[i + 2].u.operand, instruction[i + 3].u.operand, OperandTypes::fromInt(instruction[i + 4].u.operand), i); 1137 1138 i += 5; 909 1139 break; 910 1140 } … … 1087 1317 } 1088 1318 case op_sub: { 1089 emitGetArg(instruction[i + 2].u.operand, X86::eax); 1090 emitGetArg(instruction[i + 3].u.operand, X86::edx); 1091 emitJumpSlowCaseIfNotImmNums(X86::eax, X86::edx, i); 1092 m_jit.subl_rr(X86::edx, X86::eax); 1093 m_slowCases.append(SlowCaseEntry(m_jit.emitUnlinkedJo(), i)); 1094 emitFastArithReTagImmediate(X86::eax); 1095 emitPutResult(instruction[i + 1].u.operand); 1096 i += 4; 1319 compileBinaryArithOp(op_sub, instruction[i + 1].u.operand, instruction[i + 2].u.operand, instruction[i + 3].u.operand, OperandTypes::fromInt(instruction[i + 4].u.operand), i); 1320 i += 5; 1097 1321 break; 1098 1322 } … … 1344 1568 emitPutResult(dst); 1345 1569 } 1346 i += 4;1570 i += 5; 1347 1571 break; 1348 1572 } … … 1455 1679 emitFastArithReTagImmediate(X86::eax); 1456 1680 emitPutResult(instruction[i + 1].u.operand); 1457 i += 4;1681 i += 5; 1458 1682 break; 1459 1683 } … … 1472 1696 m_jit.orl_rr(X86::edx, X86::eax); 1473 1697 emitPutResult(instruction[i + 1].u.operand); 1474 i += 4;1698 i += 5; 1475 1699 break; 1476 1700 } … … 1812 2036 case op_add: { 1813 2037 unsigned dst = instruction[i + 1].u.operand; 2038 unsigned src1 = instruction[i + 2].u.operand; 1814 2039 unsigned src2 = instruction[i + 3].u.operand; 1815 if (isConstant(src2)) { 1816 JSValue* value = getConstant(m_exec, src2); 1817 if (JSImmediate::isNumber(value)) { 1818 X86Assembler::JmpSrc notImm = iter->from; 1819 m_jit.link((++iter)->from, m_jit.label()); 1820 m_jit.subl_i32r(getDeTaggedConstantImmediate(value), X86::eax); 1821 m_jit.link(notImm, m_jit.label()); 1822 emitPutArg(X86::eax, 0); 1823 emitGetPutArg(src2, 4, X86::ecx); 1824 emitCall(i, Machine::cti_op_add); 1825 emitPutResult(dst); 1826 i += 4; 1827 break; 1828 } 2040 if (JSValue* value = getConstantImmediateNumericArg(src1)) { 2041 X86Assembler::JmpSrc notImm = iter->from; 2042 m_jit.link((++iter)->from, m_jit.label()); 2043 m_jit.subl_i32r(getDeTaggedConstantImmediate(value), X86::edx); 2044 m_jit.link(notImm, m_jit.label()); 2045 emitGetPutArg(src1, 0, X86::ecx); 2046 emitPutArg(X86::edx, 4); 2047 emitCall(i, Machine::cti_op_add); 2048 emitPutResult(dst); 2049 } else if (JSValue* value = getConstantImmediateNumericArg(src2)) { 2050 X86Assembler::JmpSrc notImm = iter->from; 2051 m_jit.link((++iter)->from, m_jit.label()); 2052 m_jit.subl_i32r(getDeTaggedConstantImmediate(value), X86::eax); 2053 m_jit.link(notImm, m_jit.label()); 2054 emitPutArg(X86::eax, 0); 2055 emitGetPutArg(src2, 4, X86::ecx); 2056 emitCall(i, Machine::cti_op_add); 2057 emitPutResult(dst); 2058 } else { 2059 OperandTypes types = OperandTypes::fromInt(instruction[i + 4].u.operand); 2060 if (types.first().mightBeNumber() && types.second().mightBeNumber()) 2061 compileBinaryArithOpSlowCase(op_add, iter, dst, src1, src2, types, i); 2062 else 2063 ASSERT_NOT_REACHED(); 1829 2064 } 1830 2065 1831 ASSERT(!isConstant(instruction[i + 2].u.operand)); 1832 1833 X86Assembler::JmpSrc notImm = iter->from; 1834 m_jit.link((++iter)->from, m_jit.label()); 1835 m_jit.subl_rr(X86::edx, X86::eax); 1836 emitFastArithReTagImmediate(X86::eax); 1837 m_jit.link(notImm, m_jit.label()); 1838 emitPutArg(X86::eax, 0); 1839 emitPutArg(X86::edx, 4); 1840 emitCall(i, Machine::cti_op_add); 1841 emitPutResult(dst); 1842 i += 4; 2066 i += 5; 1843 2067 break; 1844 2068 } … … 1875 2099 } 1876 2100 case op_sub: { 1877 X86Assembler::JmpSrc notImm = iter->from; 1878 m_jit.link((++iter)->from, m_jit.label()); 1879 m_jit.addl_rr(X86::edx, X86::eax); 1880 m_jit.link(notImm, m_jit.label()); 1881 emitPutArg(X86::eax, 0); 1882 emitPutArg(X86::edx, 4); 1883 emitCall(i, Machine::cti_op_sub); 1884 emitPutResult(instruction[i + 1].u.operand); 1885 i += 4; 2101 compileBinaryArithOpSlowCase(op_sub, iter, instruction[i + 1].u.operand, instruction[i + 2].u.operand, instruction[i + 3].u.operand, OperandTypes::fromInt(instruction[i + 4].u.operand), i); 2102 i += 5; 1886 2103 break; 1887 2104 } … … 1957 2174 // so that we only need track one pointer into the slow case code - we track a pointer to the location 1958 2175 // of the call (which we can use to look up the repatch information), but should a array-length or 1959 // prototype access tram opile fail we want to bail out back to here. To do so we can subtract back2176 // prototype access trampoline fail we want to bail out back to here. To do so we can subtract back 1960 2177 // the distance from the call to the head of the slow case. 1961 2178 … … 2156 2373 emitPutResult(dst); 2157 2374 } 2158 i += 4;2375 i += 5; 2159 2376 break; 2160 2377 } … … 2187 2404 emitCall(i, Machine::cti_op_bitxor); 2188 2405 emitPutResult(instruction[i + 1].u.operand); 2189 i += 4;2406 i += 5; 2190 2407 break; 2191 2408 } … … 2196 2413 emitCall(i, Machine::cti_op_bitor); 2197 2414 emitPutResult(instruction[i + 1].u.operand); 2198 i += 4;2415 i += 5; 2199 2416 break; 2200 2417 } … … 2244 2461 break; 2245 2462 } 2246 CTI_COMPILE_BINARY_OP_SLOW_CASE(op_mul); 2463 case op_mul: { 2464 int dst = instruction[i + 1].u.operand; 2465 int src1 = instruction[i + 2].u.operand; 2466 int src2 = instruction[i + 3].u.operand; 2467 if (getConstantImmediateNumericArg(src1) || getConstantImmediateNumericArg(src2)) { 2468 m_jit.link(iter->from, m_jit.label()); 2469 emitGetPutArg(src1, 0, X86::ecx); 2470 emitGetPutArg(src2, 4, X86::ecx); 2471 emitCall(i, Machine::cti_op_mul); 2472 emitPutResult(dst); 2473 } else 2474 compileBinaryArithOpSlowCase(op_mul, iter, dst, src1, src2, OperandTypes::fromInt(instruction[i + 4].u.operand), i); 2475 i += 5; 2476 break; 2477 } 2478 2247 2479 case op_call: 2248 2480 case op_call_eval:
Note:
See TracChangeset
for help on using the changeset viewer.