Changeset 39540 in webkit for trunk/JavaScriptCore/jit
- Timestamp:
- Jan 1, 2009, 7:06:10 PM (16 years ago)
- Location:
- trunk/JavaScriptCore/jit
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JavaScriptCore/jit/JIT.cpp
r39524 r39540 228 228 229 229 // They are equal - set the result to true. (Or false, if negated). 230 move(Imm 32(asInteger(jsBoolean(!negated))), X86::eax);230 move(ImmPtr(jsBoolean(!negated)), X86::eax); 231 231 Jump bothWereImmediatesAndEqual = jump(); 232 232 … … 236 236 firstNotImmediate.link(this); 237 237 emitJumpSlowCaseIfJSCell(X86::edx); 238 addSlowCase(je 32(X86::edx, Imm32(asInteger(JSImmediate::zeroImmediate()))));238 addSlowCase(jePtr(X86::edx, ImmPtr(JSImmediate::zeroImmediate()))); 239 239 Jump firstWasNotImmediate = jump(); 240 240 … … 242 242 // If eax is 0 jump to a slow case, otherwise these values are not equal. 243 243 secondNotImmediate.link(this); 244 addSlowCase(je 32(X86::eax, Imm32(asInteger(JSImmediate::zeroImmediate()))));244 addSlowCase(jePtr(X86::eax, ImmPtr(JSImmediate::zeroImmediate()))); 245 245 246 246 // We get here if the two values are different immediates, or one is 0 and the other is a JSCell. … … 248 248 bothWereImmediatesButNotEqual.link(this); 249 249 firstWasNotImmediate.link(this); 250 move(Imm 32(asInteger(jsBoolean(negated))), X86::eax);250 move(ImmPtr(jsBoolean(negated)), X86::eax); 251 251 252 252 bothWereImmediatesAndEqual.link(this); … … 313 313 } 314 314 case op_add: { 315 unsigned dst = currentInstruction[1].u.operand; 316 unsigned src1 = currentInstruction[2].u.operand; 317 unsigned src2 = currentInstruction[3].u.operand; 318 319 if (JSValue* value = getConstantImmediateNumericArg(src1)) { 320 emitGetVirtualRegister(src2, X86::eax); 321 emitJumpSlowCaseIfNotImmNum(X86::eax); 322 addSlowCase(joAdd32(Imm32(getDeTaggedConstantImmediate(value)), X86::eax)); 323 signExtend32ToPtr(X86::eax, X86::eax); 324 emitPutVirtualRegister(dst); 325 } else if (JSValue* value = getConstantImmediateNumericArg(src2)) { 326 emitGetVirtualRegister(src1, X86::eax); 327 emitJumpSlowCaseIfNotImmNum(X86::eax); 328 addSlowCase(joAdd32(Imm32(getDeTaggedConstantImmediate(value)), X86::eax)); 329 signExtend32ToPtr(X86::eax, X86::eax); 330 emitPutVirtualRegister(dst); 331 } else { 332 OperandTypes types = OperandTypes::fromInt(currentInstruction[4].u.operand); 333 if (types.first().mightBeNumber() && types.second().mightBeNumber()) 334 compileBinaryArithOp(op_add, currentInstruction[1].u.operand, currentInstruction[2].u.operand, currentInstruction[3].u.operand, OperandTypes::fromInt(currentInstruction[4].u.operand)); 335 else { 336 emitPutJITStubArgFromVirtualRegister(currentInstruction[2].u.operand, 1, X86::ecx); 337 emitPutJITStubArgFromVirtualRegister(currentInstruction[3].u.operand, 2, X86::ecx); 338 emitCTICall(Interpreter::cti_op_add); 339 emitPutVirtualRegister(currentInstruction[1].u.operand); 340 } 341 } 315 compileFastArith_op_add(currentInstruction); 342 316 NEXT_OPCODE(op_add); 343 317 } … … 356 330 } 357 331 case op_pre_inc: { 358 int srcDst = currentInstruction[1].u.operand; 359 emitGetVirtualRegister(srcDst, X86::eax); 360 emitJumpSlowCaseIfNotImmNum(X86::eax); 361 addSlowCase(joAdd32(Imm32(getDeTaggedConstantImmediate(JSImmediate::oneImmediate())), X86::eax)); 362 signExtend32ToPtr(X86::eax, X86::eax); 363 emitPutVirtualRegister(srcDst); 332 compileFastArith_op_pre_inc(currentInstruction[1].u.operand); 364 333 NEXT_OPCODE(op_pre_inc); 365 334 } … … 374 343 emitSlowScriptCheck(); 375 344 345 unsigned op1 = currentInstruction[1].u.operand; 346 unsigned op2 = currentInstruction[2].u.operand; 376 347 unsigned target = currentInstruction[3].u.operand; 377 JSValue* src2imm = getConstantImmediateNumericArg(currentInstruction[2].u.operand); 378 if (src2imm) { 379 emitGetVirtualRegister(currentInstruction[1].u.operand, X86::eax); 348 if (isOperandConstantImmediateInt(op2)) { 349 emitGetVirtualRegister(op1, X86::eax); 380 350 emitJumpSlowCaseIfNotImmNum(X86::eax); 381 addJump(jl 32(X86::eax, Imm32(asInteger(src2imm))), target + 3);351 addJump(jlPtr(X86::eax, ImmPtr(getConstantOperand(op2))), target + 3); 382 352 } else { 383 emitGetVirtualRegisters( currentInstruction[1].u.operand, X86::eax, currentInstruction[2].u.operand, X86::edx);353 emitGetVirtualRegisters(op1, X86::eax, op2, X86::edx); 384 354 emitJumpSlowCaseIfNotImmNum(X86::eax); 385 355 emitJumpSlowCaseIfNotImmNum(X86::edx); 386 addJump(jl 32(X86::eax, X86::edx), target + 3);356 addJump(jlPtr(X86::eax, X86::edx), target + 3); 387 357 } 388 358 NEXT_OPCODE(op_loop_if_less); … … 391 361 emitSlowScriptCheck(); 392 362 363 unsigned op1 = currentInstruction[1].u.operand; 364 unsigned op2 = currentInstruction[2].u.operand; 393 365 unsigned target = currentInstruction[3].u.operand; 394 JSValue* src2imm = getConstantImmediateNumericArg(currentInstruction[2].u.operand); 395 if (src2imm) { 396 emitGetVirtualRegister(currentInstruction[1].u.operand, X86::eax); 366 if (isOperandConstantImmediateInt(op2)) { 367 emitGetVirtualRegister(op1, X86::eax); 397 368 emitJumpSlowCaseIfNotImmNum(X86::eax); 398 addJump(jle 32(X86::eax, Imm32(asInteger(src2imm))), target + 3);369 addJump(jlePtr(X86::eax, ImmPtr(getConstantOperand(op2))), target + 3); 399 370 } else { 400 emitGetVirtualRegisters( currentInstruction[1].u.operand, X86::eax, currentInstruction[2].u.operand, X86::edx);371 emitGetVirtualRegisters(op1, X86::eax, op2, X86::edx); 401 372 emitJumpSlowCaseIfNotImmNum(X86::eax); 402 373 emitJumpSlowCaseIfNotImmNum(X86::edx); 403 addJump(jle 32(X86::eax, X86::edx), target + 3);374 addJump(jlePtr(X86::eax, X86::edx), target + 3); 404 375 } 405 NEXT_OPCODE(op_loop_if_less eq);376 NEXT_OPCODE(op_loop_if_less); 406 377 } 407 378 case op_new_object: { … … 449 420 450 421 // optimistically load true result 451 move(Imm 32(asInteger(jsBoolean(true))), X86::eax);422 move(ImmPtr(jsBoolean(true)), X86::eax); 452 423 453 424 Label loop(this); … … 459 430 Jump exit = jePtr(X86::ecx, X86::edx); 460 431 461 jne 32(X86::ecx, Imm32(asInteger(jsNull())), loop);462 463 move(Imm 32(asInteger(jsBoolean(false))), X86::eax);432 jnePtr(X86::ecx, ImmPtr(jsNull()), loop); 433 434 move(ImmPtr(jsBoolean(false)), X86::eax); 464 435 465 436 exit.link(this); … … 478 449 } 479 450 case op_mul: { 480 unsigned dst = currentInstruction[1].u.operand; 481 unsigned src1 = currentInstruction[2].u.operand; 482 unsigned src2 = currentInstruction[3].u.operand; 483 484 // For now, only plant a fast int case if the constant operand is greater than zero. 485 JSValue* src1Value = getConstantImmediateNumericArg(src1); 486 JSValue* src2Value = getConstantImmediateNumericArg(src2); 487 int32_t value; 488 if (src1Value && ((value = JSImmediate::intValue(src1Value)) > 0)) { 489 emitGetVirtualRegister(src2, X86::eax); 490 emitJumpSlowCaseIfNotImmNum(X86::eax); 491 emitFastArithDeTagImmediate(X86::eax); 492 addSlowCase(joMul32(Imm32(value), X86::eax, X86::eax)); 493 emitFastArithReTagImmediate(X86::eax); 494 emitPutVirtualRegister(dst); 495 } else if (src2Value && ((value = JSImmediate::intValue(src2Value)) > 0)) { 496 emitGetVirtualRegister(src1, X86::eax); 497 emitJumpSlowCaseIfNotImmNum(X86::eax); 498 emitFastArithDeTagImmediate(X86::eax); 499 addSlowCase(joMul32(Imm32(value), X86::eax, X86::eax)); 500 emitFastArithReTagImmediate(X86::eax); 501 emitPutVirtualRegister(dst); 502 } else 503 compileBinaryArithOp(op_mul, currentInstruction[1].u.operand, currentInstruction[2].u.operand, currentInstruction[3].u.operand, OperandTypes::fromInt(currentInstruction[4].u.operand)); 504 451 compileFastArith_op_mul(currentInstruction); 505 452 NEXT_OPCODE(op_mul); 506 453 } … … 672 619 emitGetVirtualRegister(currentInstruction[1].u.operand, X86::eax); 673 620 674 Jump isZero = je 32(X86::eax, Imm32(asInteger(JSImmediate::zeroImmediate())));621 Jump isZero = jePtr(X86::eax, ImmPtr(JSImmediate::zeroImmediate())); 675 622 addJump(jnz32(X86::eax, Imm32(JSImmediate::TagBitTypeInteger)), target + 2); 676 623 677 addJump(je 32(X86::eax, Imm32(asInteger(JSImmediate::trueImmediate()))), target + 2);678 addSlowCase(jne 32(X86::eax, Imm32(asInteger(JSImmediate::falseImmediate()))));624 addJump(jePtr(X86::eax, ImmPtr(jsBoolean(true))), target + 2); 625 addSlowCase(jnePtr(X86::eax, ImmPtr(jsBoolean(false)))); 679 626 680 627 isZero.link(this); … … 735 682 CTI_COMPILE_BINARY_OP(op_div) 736 683 case op_pre_dec: { 737 int srcDst = currentInstruction[1].u.operand; 738 emitGetVirtualRegister(srcDst, X86::eax); 739 emitJumpSlowCaseIfNotImmNum(X86::eax); 740 addSlowCase(joSub32(Imm32(getDeTaggedConstantImmediate(JSImmediate::oneImmediate())), X86::eax)); 741 signExtend32ToPtr(X86::eax, X86::eax); 742 emitPutVirtualRegister(srcDst); 684 compileFastArith_op_pre_dec(currentInstruction[1].u.operand); 743 685 NEXT_OPCODE(op_pre_dec); 744 686 } 745 687 case op_jnless: { 688 unsigned op1 = currentInstruction[1].u.operand; 689 unsigned op2 = currentInstruction[2].u.operand; 746 690 unsigned target = currentInstruction[3].u.operand; 747 JSValue* src2imm = getConstantImmediateNumericArg(currentInstruction[2].u.operand); 748 if (src2imm) { 749 emitGetVirtualRegister(currentInstruction[1].u.operand, X86::edx); 750 emitJumpSlowCaseIfNotImmNum(X86::edx); 751 addJump(jge32(X86::edx, Imm32(asInteger(src2imm))), target + 3); 691 if (isOperandConstantImmediateInt(op2)) { 692 emitGetVirtualRegister(op1, X86::eax); 693 emitJumpSlowCaseIfNotImmNum(X86::eax); 694 addJump(jgePtr(X86::eax, ImmPtr(getConstantOperand(op2))), target + 3); 752 695 } else { 753 emitGetVirtualRegisters( currentInstruction[1].u.operand, X86::eax, currentInstruction[2].u.operand, X86::edx);696 emitGetVirtualRegisters(op1, X86::eax, op2, X86::edx); 754 697 emitJumpSlowCaseIfNotImmNum(X86::eax); 755 698 emitJumpSlowCaseIfNotImmNum(X86::edx); 756 addJump(jge 32(X86::eax, X86::edx), target + 3);699 addJump(jgePtr(X86::eax, X86::edx), target + 3); 757 700 } 758 701 NEXT_OPCODE(op_jnless); … … 770 713 emitGetVirtualRegister(currentInstruction[1].u.operand, X86::eax); 771 714 772 addJump(je 32(X86::eax, Imm32(asInteger(JSImmediate::zeroImmediate()))), target + 2);715 addJump(jePtr(X86::eax, ImmPtr(JSImmediate::zeroImmediate())), target + 2); 773 716 Jump isNonZero = jnz32(X86::eax, Imm32(JSImmediate::TagBitTypeInteger)); 774 717 775 addJump(je 32(X86::eax, Imm32(asInteger(JSImmediate::falseImmediate()))), target + 2);776 addSlowCase(jne 32(X86::eax, Imm32(asInteger(JSImmediate::trueImmediate()))));718 addJump(jePtr(X86::eax, ImmPtr(jsBoolean(false))), target + 2); 719 addSlowCase(jnePtr(X86::eax, ImmPtr(jsBoolean(true)))); 777 720 778 721 isNonZero.link(this); … … 794 737 isImmediate.link(this); 795 738 and32(Imm32(~JSImmediate::ExtendedTagBitUndefined), X86::eax); 796 addJump(je 32(X86::eax, Imm32(asInteger(jsNull()))), target + 2);739 addJump(jePtr(X86::eax, ImmPtr(jsNull())), target + 2); 797 740 798 741 wasNotImmediate.link(this); … … 814 757 isImmediate.link(this); 815 758 and32(Imm32(~JSImmediate::ExtendedTagBitUndefined), X86::eax); 816 addJump(jne 32(X86::eax, Imm32(asInteger(jsNull()))), target + 2);759 addJump(jnePtr(X86::eax, ImmPtr(jsNull())), target + 2); 817 760 818 761 wasNotImmediate.link(this); … … 820 763 } 821 764 case op_post_inc: { 822 int srcDst = currentInstruction[2].u.operand; 823 emitGetVirtualRegister(srcDst, X86::eax); 824 move(X86::eax, X86::edx); 825 emitJumpSlowCaseIfNotImmNum(X86::eax); 826 addSlowCase(joAdd32(Imm32(getDeTaggedConstantImmediate(JSImmediate::oneImmediate())), X86::edx)); 827 signExtend32ToPtr(X86::edx, X86::edx); 828 emitPutVirtualRegister(srcDst, X86::edx); 829 emitPutVirtualRegister(currentInstruction[1].u.operand); 765 compileFastArith_op_post_inc(currentInstruction[1].u.operand, currentInstruction[2].u.operand); 830 766 NEXT_OPCODE(op_post_inc); 831 767 } … … 857 793 } 858 794 case op_lshift: { 859 emitGetVirtualRegisters(currentInstruction[2].u.operand, X86::eax, currentInstruction[3].u.operand, X86::ecx); 860 emitJumpSlowCaseIfNotImmNum(X86::eax); 861 emitJumpSlowCaseIfNotImmNum(X86::ecx); 862 emitFastArithImmToInt(X86::eax); 863 emitFastArithImmToInt(X86::ecx); 864 lshift32(X86::ecx, X86::eax); 865 emitFastArithIntToImmOrSlowCase(X86::eax); 866 emitPutVirtualRegister(currentInstruction[1].u.operand); 795 compileFastArith_op_lshift(currentInstruction[1].u.operand, currentInstruction[2].u.operand, currentInstruction[3].u.operand); 867 796 NEXT_OPCODE(op_lshift); 868 797 } 869 798 case op_bitand: { 870 unsigned src1 = currentInstruction[2].u.operand; 871 unsigned src2 = currentInstruction[3].u.operand; 872 unsigned dst = currentInstruction[1].u.operand; 873 if (JSValue* value = getConstantImmediateNumericArg(src1)) { 874 emitGetVirtualRegister(src2, X86::eax); 875 emitJumpSlowCaseIfNotImmNum(X86::eax); 876 andPtr(Imm32(asInteger(value)), X86::eax); // FIXME: make it more obvious this is relying on the format of JSImmediate 877 emitPutVirtualRegister(dst); 878 } else if (JSValue* value = getConstantImmediateNumericArg(src2)) { 879 emitGetVirtualRegister(src1, X86::eax); 880 emitJumpSlowCaseIfNotImmNum(X86::eax); 881 andPtr(Imm32(asInteger(value)), X86::eax); 882 emitPutVirtualRegister(dst); 883 } else { 884 emitGetVirtualRegisters(src1, X86::eax, src2, X86::edx); 885 andPtr(X86::edx, X86::eax); 886 emitJumpSlowCaseIfNotImmNum(X86::eax); 887 emitPutVirtualRegister(dst); 888 } 799 compileFastArith_op_bitand(currentInstruction[1].u.operand, currentInstruction[2].u.operand, currentInstruction[3].u.operand); 889 800 NEXT_OPCODE(op_bitand); 890 801 } 891 802 case op_rshift: { 892 unsigned src1 = currentInstruction[2].u.operand; 893 unsigned src2 = currentInstruction[3].u.operand; 894 if (JSValue* value = getConstantImmediateNumericArg(src2)) { 895 emitGetVirtualRegister(src1, X86::eax); 896 emitJumpSlowCaseIfNotImmNum(X86::eax); 897 // Mask with 0x1f as per ecma-262 11.7.2 step 7. 898 rshift32(Imm32(JSImmediate::getTruncatedUInt32(value) & 0x1f), X86::eax); 899 } else { 900 emitGetVirtualRegisters(src1, X86::eax, src2, X86::ecx); 901 emitJumpSlowCaseIfNotImmNum(X86::eax); 902 emitJumpSlowCaseIfNotImmNum(X86::ecx); 903 emitFastArithImmToInt(X86::ecx); 904 rshift32(X86::ecx, X86::eax); 905 } 906 emitFastArithPotentiallyReTagImmediate(X86::eax); 907 emitPutVirtualRegister(currentInstruction[1].u.operand); 803 compileFastArith_op_rshift(currentInstruction[1].u.operand, currentInstruction[2].u.operand, currentInstruction[3].u.operand); 908 804 NEXT_OPCODE(op_rshift); 909 805 } … … 931 827 } 932 828 case op_mod: { 933 emitGetVirtualRegisters(currentInstruction[2].u.operand, X86::eax, currentInstruction[3].u.operand, X86::ecx); 934 emitJumpSlowCaseIfNotImmNum(X86::eax); 935 emitJumpSlowCaseIfNotImmNum(X86::ecx); 936 emitFastArithDeTagImmediate(X86::eax); 937 addSlowCase(emitFastArithDeTagImmediateJumpIfZero(X86::ecx)); 938 mod32(X86::ecx, X86::eax, X86::edx); 939 emitFastArithReTagImmediate(X86::edx); 940 move(X86::edx, X86::eax); 941 emitPutVirtualRegister(currentInstruction[1].u.operand); 829 compileFastArith_op_mod(currentInstruction[1].u.operand, currentInstruction[2].u.operand, currentInstruction[3].u.operand); 942 830 NEXT_OPCODE(op_mod); 943 831 } … … 946 834 emitGetVirtualRegister(currentInstruction[1].u.operand, X86::eax); 947 835 948 Jump isZero = je 32(X86::eax, Imm32(asInteger(JSImmediate::zeroImmediate())));836 Jump isZero = jePtr(X86::eax, ImmPtr(JSImmediate::zeroImmediate())); 949 837 addJump(jnz32(X86::eax, Imm32(JSImmediate::TagBitTypeInteger)), target + 2); 950 838 951 addJump(je 32(X86::eax, Imm32(asInteger(JSImmediate::trueImmediate()))), target + 2);952 addSlowCase(jne 32(X86::eax, Imm32(asInteger(JSImmediate::falseImmediate()))));839 addJump(jePtr(X86::eax, ImmPtr(jsBoolean(true))), target + 2); 840 addSlowCase(jnePtr(X86::eax, ImmPtr(jsBoolean(false)))); 953 841 954 842 isZero.link(this); … … 967 855 } 968 856 case op_post_dec: { 969 int srcDst = currentInstruction[2].u.operand; 970 emitGetVirtualRegister(srcDst, X86::eax); 971 move(X86::eax, X86::edx); 972 emitJumpSlowCaseIfNotImmNum(X86::eax); 973 addSlowCase(joSub32(Imm32(getDeTaggedConstantImmediate(JSImmediate::oneImmediate())), X86::edx)); 974 signExtend32ToPtr(X86::edx, X86::edx); 975 emitPutVirtualRegister(srcDst, X86::edx); 976 emitPutVirtualRegister(currentInstruction[1].u.operand); 857 compileFastArith_op_post_dec(currentInstruction[1].u.operand, currentInstruction[2].u.operand); 977 858 NEXT_OPCODE(op_post_dec); 978 859 } … … 981 862 emitGetVirtualRegisters(currentInstruction[2].u.operand, X86::eax, currentInstruction[3].u.operand, X86::edx); 982 863 emitJumpSlowCaseIfNotImmNums(X86::eax, X86::edx, X86::ecx); 983 xor 32(X86::edx, X86::eax);864 xorPtr(X86::edx, X86::eax); 984 865 emitFastArithReTagImmediate(X86::eax); 985 866 emitPutVirtualRegister(currentInstruction[1].u.operand); … … 1355 1236 } 1356 1237 case op_add: { 1357 unsigned dst = currentInstruction[1].u.operand; 1358 unsigned src1 = currentInstruction[2].u.operand; 1359 unsigned src2 = currentInstruction[3].u.operand; 1360 if (JSValue* value = getConstantImmediateNumericArg(src1)) { 1361 Jump notImm = getSlowCase(iter); 1362 linkSlowCase(iter); 1363 sub32(Imm32(getDeTaggedConstantImmediate(value)), X86::eax); 1364 notImm.link(this); 1365 emitPutJITStubArgFromVirtualRegister(src1, 1, X86::ecx); 1366 emitPutJITStubArg(X86::eax, 2); 1367 emitCTICall(Interpreter::cti_op_add); 1368 emitPutVirtualRegister(dst); 1369 } else if (JSValue* value = getConstantImmediateNumericArg(src2)) { 1370 Jump notImm = getSlowCase(iter); 1371 linkSlowCase(iter); 1372 sub32(Imm32(getDeTaggedConstantImmediate(value)), X86::eax); 1373 notImm.link(this); 1374 emitPutJITStubArg(X86::eax, 1); 1375 emitPutJITStubArgFromVirtualRegister(src2, 2, X86::ecx); 1376 emitCTICall(Interpreter::cti_op_add); 1377 emitPutVirtualRegister(dst); 1378 } else { 1379 OperandTypes types = OperandTypes::fromInt(currentInstruction[4].u.operand); 1380 ASSERT(types.first().mightBeNumber() && types.second().mightBeNumber()); 1381 compileBinaryArithOpSlowCase(op_add, iter, dst, src1, src2, types); 1382 } 1383 1238 compileFastArithSlow_op_add(currentInstruction, iter); 1384 1239 NEXT_OPCODE(op_add); 1385 1240 } … … 1426 1281 } 1427 1282 case op_rshift: { 1428 unsigned src2 = currentInstruction[3].u.operand; 1429 linkSlowCase(iter); 1430 if (getConstantImmediateNumericArg(src2)) 1431 emitPutJITStubArgFromVirtualRegister(src2, 2, X86::ecx); 1432 else { 1433 linkSlowCase(iter); 1434 emitPutJITStubArg(X86::ecx, 2); 1435 } 1436 1437 emitPutJITStubArg(X86::eax, 1); 1438 emitCTICall(Interpreter::cti_op_rshift); 1439 emitPutVirtualRegister(currentInstruction[1].u.operand); 1283 compileFastArithSlow_op_rshift(currentInstruction[1].u.operand, currentInstruction[2].u.operand, currentInstruction[3].u.operand, iter); 1440 1284 NEXT_OPCODE(op_rshift); 1441 1285 } 1442 1286 case op_lshift: { 1443 Jump notImm1 = getSlowCase(iter); 1444 Jump notImm2 = getSlowCase(iter); 1445 linkSlowCase(iter); 1446 emitGetVirtualRegisters(currentInstruction[2].u.operand, X86::eax, currentInstruction[3].u.operand, X86::ecx); 1447 notImm1.link(this); 1448 notImm2.link(this); 1449 emitPutJITStubArg(X86::eax, 1); 1450 emitPutJITStubArg(X86::ecx, 2); 1451 emitCTICall(Interpreter::cti_op_lshift); 1452 emitPutVirtualRegister(currentInstruction[1].u.operand); 1287 compileFastArithSlow_op_lshift(currentInstruction[1].u.operand, currentInstruction[2].u.operand, currentInstruction[3].u.operand, iter); 1453 1288 NEXT_OPCODE(op_lshift); 1454 1289 } … … 1500 1335 } 1501 1336 case op_pre_inc: { 1502 unsigned srcDst = currentInstruction[1].u.operand; 1503 Jump notImm = getSlowCase(iter); 1504 linkSlowCase(iter); 1505 sub32(Imm32(getDeTaggedConstantImmediate(JSImmediate::oneImmediate())), X86::eax); 1506 notImm.link(this); 1507 emitPutJITStubArg(X86::eax, 1); 1508 emitCTICall(Interpreter::cti_op_pre_inc); 1509 emitPutVirtualRegister(srcDst); 1337 compileFastArithSlow_op_pre_inc(currentInstruction[1].u.operand, iter); 1510 1338 NEXT_OPCODE(op_pre_inc); 1511 1339 } … … 1544 1372 } 1545 1373 case op_pre_dec: { 1546 unsigned srcDst = currentInstruction[1].u.operand; 1547 Jump notImm = getSlowCase(iter); 1548 linkSlowCase(iter); 1549 add32(Imm32(getDeTaggedConstantImmediate(JSImmediate::oneImmediate())), X86::eax); 1550 notImm.link(this); 1551 emitPutJITStubArg(X86::eax, 1); 1552 emitCTICall(Interpreter::cti_op_pre_dec); 1553 emitPutVirtualRegister(srcDst); 1374 compileFastArithSlow_op_pre_dec(currentInstruction[1].u.operand, iter); 1554 1375 NEXT_OPCODE(op_pre_dec); 1555 1376 } … … 1559 1380 if (src2imm) { 1560 1381 linkSlowCase(iter); 1561 emitPutJITStubArg(X86::e dx, 1);1382 emitPutJITStubArg(X86::eax, 1); 1562 1383 emitPutJITStubArgFromVirtualRegister(currentInstruction[2].u.operand, 2, X86::ecx); 1563 1384 emitCTICall(Interpreter::cti_op_jless); … … 1590 1411 } 1591 1412 case op_post_inc: { 1592 unsigned srcDst = currentInstruction[2].u.operand; 1593 linkSlowCase(iter); 1594 linkSlowCase(iter); 1595 emitPutJITStubArg(X86::eax, 1); 1596 emitCTICall(Interpreter::cti_op_post_inc); 1597 emitPutVirtualRegister(srcDst, X86::edx); 1598 emitPutVirtualRegister(currentInstruction[1].u.operand); 1413 compileFastArithSlow_op_post_inc(currentInstruction[1].u.operand, currentInstruction[2].u.operand, iter); 1599 1414 NEXT_OPCODE(op_post_inc); 1600 1415 } … … 1607 1422 } 1608 1423 case op_bitand: { 1609 linkSlowCase(iter); 1610 unsigned src1 = currentInstruction[2].u.operand; 1611 unsigned src2 = currentInstruction[3].u.operand; 1612 unsigned dst = currentInstruction[1].u.operand; 1613 if (getConstantImmediateNumericArg(src1)) { 1614 emitPutJITStubArgFromVirtualRegister(src1, 1, X86::ecx); 1615 emitPutJITStubArg(X86::eax, 2); 1616 emitCTICall(Interpreter::cti_op_bitand); 1617 emitPutVirtualRegister(dst); 1618 } else if (getConstantImmediateNumericArg(src2)) { 1619 emitPutJITStubArg(X86::eax, 1); 1620 emitPutJITStubArgFromVirtualRegister(src2, 2, X86::ecx); 1621 emitCTICall(Interpreter::cti_op_bitand); 1622 emitPutVirtualRegister(dst); 1623 } else { 1624 emitPutJITStubArgFromVirtualRegister(src1, 1, X86::ecx); 1625 emitPutJITStubArg(X86::edx, 2); 1626 emitCTICall(Interpreter::cti_op_bitand); 1627 emitPutVirtualRegister(dst); 1628 } 1424 compileFastArithSlow_op_bitand(currentInstruction[1].u.operand, currentInstruction[2].u.operand, currentInstruction[3].u.operand, iter); 1629 1425 NEXT_OPCODE(op_bitand); 1630 1426 } … … 1638 1434 } 1639 1435 case op_post_dec: { 1640 unsigned srcDst = currentInstruction[2].u.operand; 1641 linkSlowCase(iter); 1642 linkSlowCase(iter); 1643 emitPutJITStubArg(X86::eax, 1); 1644 emitCTICall(Interpreter::cti_op_post_dec); 1645 emitPutVirtualRegister(srcDst, X86::edx); 1646 emitPutVirtualRegister(currentInstruction[1].u.operand); 1436 compileFastArithSlow_op_post_dec(currentInstruction[1].u.operand, currentInstruction[2].u.operand, iter); 1647 1437 NEXT_OPCODE(op_post_dec); 1648 1438 } … … 1711 1501 } 1712 1502 case op_mod: { 1713 Jump notImm1 = getSlowCase(iter); 1714 Jump notImm2 = getSlowCase(iter); 1715 linkSlowCase(iter); 1716 emitFastArithReTagImmediate(X86::eax); 1717 emitFastArithReTagImmediate(X86::ecx); 1718 notImm1.link(this); 1719 notImm2.link(this); 1720 emitPutJITStubArg(X86::eax, 1); 1721 emitPutJITStubArg(X86::ecx, 2); 1722 emitCTICall(Interpreter::cti_op_mod); 1723 emitPutVirtualRegister(currentInstruction[1].u.operand); 1503 compileFastArithSlow_op_mod(currentInstruction[1].u.operand, currentInstruction[2].u.operand, currentInstruction[3].u.operand, iter); 1724 1504 NEXT_OPCODE(op_mod); 1725 1505 } 1726 1506 case op_mul: { 1727 int dst = currentInstruction[1].u.operand; 1728 int src1 = currentInstruction[2].u.operand; 1729 int src2 = currentInstruction[3].u.operand; 1730 JSValue* src1Value = getConstantImmediateNumericArg(src1); 1731 JSValue* src2Value = getConstantImmediateNumericArg(src2); 1732 int32_t value; 1733 if (src1Value && ((value = JSImmediate::intValue(src1Value)) > 0)) { 1734 linkSlowCase(iter); 1735 linkSlowCase(iter); 1736 // There is an extra slow case for (op1 * -N) or (-N * op2), to check for 0 since this should produce a result of -0. 1737 emitPutJITStubArgFromVirtualRegister(src1, 1, X86::ecx); 1738 emitPutJITStubArgFromVirtualRegister(src2, 2, X86::ecx); 1739 emitCTICall(Interpreter::cti_op_mul); 1740 emitPutVirtualRegister(dst); 1741 } else if (src2Value && ((value = JSImmediate::intValue(src2Value)) > 0)) { 1742 linkSlowCase(iter); 1743 linkSlowCase(iter); 1744 // There is an extra slow case for (op1 * -N) or (-N * op2), to check for 0 since this should produce a result of -0. 1745 emitPutJITStubArgFromVirtualRegister(src1, 1, X86::ecx); 1746 emitPutJITStubArgFromVirtualRegister(src2, 2, X86::ecx); 1747 emitCTICall(Interpreter::cti_op_mul); 1748 emitPutVirtualRegister(dst); 1749 } else 1750 compileBinaryArithOpSlowCase(op_mul, iter, dst, src1, src2, OperandTypes::fromInt(currentInstruction[4].u.operand)); 1507 compileFastArithSlow_op_mul(currentInstruction, iter); 1751 1508 NEXT_OPCODE(op_mul); 1752 1509 } … … 1933 1690 Jump array_failureCases3 = ja32(X86::eax, Imm32(JSImmediate::maxImmediateInt)); 1934 1691 1935 add32(X86::eax, X86::eax);1936 add32(Imm32(1),X86::eax);1937 1692 // X86::eax contains a 64 bit value (is signed, is zero extended) so we don't need sign extend here. 1693 emitFastArithIntToImmNoCheck(X86::eax); 1694 1938 1695 ret(); 1939 1696 … … 1951 1708 Jump string_failureCases3 = ja32(X86::eax, Imm32(JSImmediate::maxImmediateInt)); 1952 1709 1953 add32(X86::eax, X86::eax);1954 add32(Imm32(1),X86::eax);1710 // X86::eax contains a 64 bit value (is signed, is zero extended) so we don't need sign extend here. 1711 emitFastArithIntToImmNoCheck(X86::eax); 1955 1712 1956 1713 ret(); -
trunk/JavaScriptCore/jit/JIT.h
r39440 r39540 389 389 void compileOpStrictEq(Instruction* instruction, CompileOpStrictEqType type); 390 390 void putDoubleResultToJSNumberCellOrJSImmediate(X86Assembler::XMMRegisterID xmmSource, RegisterID jsNumberCell, unsigned dst, X86Assembler::JmpSrc* wroteJSNumberCell, X86Assembler::XMMRegisterID tempXmm, RegisterID tempReg1, RegisterID tempReg2); 391 392 void compileFastArith_op_add(Instruction*); 393 void compileFastArith_op_mul(Instruction*); 394 void compileFastArith_op_mod(unsigned result, unsigned op1, unsigned op2); 395 void compileFastArith_op_bitand(unsigned result, unsigned op1, unsigned op2); 396 void compileFastArith_op_lshift(unsigned result, unsigned op1, unsigned op2); 397 void compileFastArith_op_rshift(unsigned result, unsigned op1, unsigned op2); 398 void compileFastArith_op_pre_inc(unsigned srcDst); 399 void compileFastArith_op_pre_dec(unsigned srcDst); 400 void compileFastArith_op_post_inc(unsigned result, unsigned srcDst); 401 void compileFastArith_op_post_dec(unsigned result, unsigned srcDst); 402 void compileFastArithSlow_op_add(Instruction*, Vector<SlowCaseEntry>::iterator&); 403 void compileFastArithSlow_op_mul(Instruction*, Vector<SlowCaseEntry>::iterator&); 404 void compileFastArithSlow_op_mod(unsigned result, unsigned op1, unsigned op2, Vector<SlowCaseEntry>::iterator&); 405 void compileFastArithSlow_op_bitand(unsigned result, unsigned op1, unsigned op2, Vector<SlowCaseEntry>::iterator&); 406 void compileFastArithSlow_op_lshift(unsigned result, unsigned op1, unsigned op2, Vector<SlowCaseEntry>::iterator&); 407 void compileFastArithSlow_op_rshift(unsigned result, unsigned op1, unsigned op2, Vector<SlowCaseEntry>::iterator&); 408 void compileFastArithSlow_op_pre_inc(unsigned srcDst, Vector<SlowCaseEntry>::iterator&); 409 void compileFastArithSlow_op_pre_dec(unsigned srcDst, Vector<SlowCaseEntry>::iterator&); 410 void compileFastArithSlow_op_post_inc(unsigned result, unsigned srcDst, Vector<SlowCaseEntry>::iterator&); 411 void compileFastArithSlow_op_post_dec(unsigned result, unsigned srcDst, Vector<SlowCaseEntry>::iterator&); 391 412 void compileBinaryArithOp(OpcodeID, unsigned dst, unsigned src1, unsigned src2, OperandTypes opi); 392 void compileBinaryArithOpSlowCase(OpcodeID, Vector<SlowCaseEntry>::iterator& iter, unsigned dst, unsigned src1, unsigned src2, OperandTypes opi);413 void compileBinaryArithOpSlowCase(OpcodeID, Vector<SlowCaseEntry>::iterator&, unsigned dst, unsigned src1, unsigned src2, OperandTypes opi); 393 414 394 415 void emitGetVirtualRegister(int src, RegisterID dst); … … 413 434 414 435 JSValue* getConstantImmediateNumericArg(unsigned src); 415 unsigned getDeTaggedConstantImmediate(JSValue* imm); 436 JSValue* getConstantOperand(unsigned src); 437 int32_t getConstantOperandImmediateInt(unsigned src); 438 bool isOperandConstantImmediateInt(unsigned src); 439 bool isOperandConstant31BitImmediateInt(unsigned src); 416 440 417 441 Jump emitJumpIfJSCell(RegisterID); … … 440 464 Jump emitFastArithDeTagImmediateJumpIfZero(RegisterID); 441 465 void emitFastArithReTagImmediate(RegisterID); 442 void emitFastArithPotentiallyReTagImmediate(RegisterID);443 466 void emitFastArithImmToInt(RegisterID); 444 void emitFastArithIntToImmOrSlowCase(RegisterID);445 467 void emitFastArithIntToImmNoCheck(RegisterID); 446 468 -
trunk/JavaScriptCore/jit/JITArithmetic.cpp
r39316 r39540 47 47 namespace JSC { 48 48 49 void JIT::compileFastArith_op_lshift(unsigned result, unsigned op1, unsigned op2) 50 { 51 emitGetVirtualRegisters(op1, X86::eax, op2, X86::ecx); 52 // FIXME: would we be better using 'emitJumpSlowCaseIfNotImmNums'? - we *probably* ought to be consistent. 53 emitJumpSlowCaseIfNotImmNum(X86::eax); 54 emitJumpSlowCaseIfNotImmNum(X86::ecx); 55 emitFastArithImmToInt(X86::eax); 56 emitFastArithImmToInt(X86::ecx); 57 #if !PLATFORM(X86) 58 // Mask with 0x1f as per ecma-262 11.7.2 step 7. 59 // On 32-bit x86 this is not necessary, since the shift anount is implicitly masked in the instruction. 60 and32(Imm32(0x1f), X86::ecx); 61 #endif 62 lshift32(X86::ecx, X86::eax); 63 #if USE(ALTERNATE_JSIMMEDIATE) 64 emitFastArithIntToImmNoCheck(X86::eax); 65 #else 66 addSlowCase(joAdd32(X86::eax, X86::eax)); 67 signExtend32ToPtr(X86::eax, X86::eax); 68 emitFastArithReTagImmediate(X86::eax); 69 #endif 70 emitPutVirtualRegister(result); 71 } 72 void JIT::compileFastArithSlow_op_lshift(unsigned result, unsigned op1, unsigned op2, Vector<SlowCaseEntry>::iterator& iter) 73 { 74 #if USE(ALTERNATE_JSIMMEDIATE) 75 UNUSED_PARAM(op1); 76 UNUSED_PARAM(op2); 77 linkSlowCase(iter); 78 linkSlowCase(iter); 79 #else 80 // If we are limited to 32-bit immediates there is a third slow case, which required the operands to have been reloaded. 81 Jump notImm1 = getSlowCase(iter); 82 Jump notImm2 = getSlowCase(iter); 83 linkSlowCase(iter); 84 emitGetVirtualRegisters(op1, X86::eax, op2, X86::ecx); 85 notImm1.link(this); 86 notImm2.link(this); 87 #endif 88 emitPutJITStubArg(X86::eax, 1); 89 emitPutJITStubArg(X86::ecx, 2); 90 emitCTICall(Interpreter::cti_op_lshift); 91 emitPutVirtualRegister(result); 92 } 93 94 void JIT::compileFastArith_op_rshift(unsigned result, unsigned op1, unsigned op2) 95 { 96 if (JSValue* value = getConstantImmediateNumericArg(op2)) { 97 emitGetVirtualRegister(op1, X86::eax); 98 emitJumpSlowCaseIfNotImmNum(X86::eax); 99 // Mask with 0x1f as per ecma-262 11.7.2 step 7. 100 rshiftPtr(Imm32(JSImmediate::getTruncatedUInt32(value) & 0x1f), X86::eax); 101 } else { 102 emitGetVirtualRegisters(op1, X86::eax, op2, X86::ecx); 103 emitJumpSlowCaseIfNotImmNum(X86::eax); 104 emitJumpSlowCaseIfNotImmNum(X86::ecx); 105 emitFastArithImmToInt(X86::ecx); 106 #if !PLATFORM(X86) 107 // Mask with 0x1f as per ecma-262 11.7.2 step 7. 108 // On 32-bit x86 this is not necessary, since the shift anount is implicitly masked in the instruction. 109 and32(Imm32(0x1f), X86::ecx); 110 #endif 111 rshiftPtr(X86::ecx, X86::eax); 112 } 113 orPtr(Imm32(JSImmediate::TagBitTypeInteger), X86::eax); 114 emitPutVirtualRegister(result); 115 } 116 void JIT::compileFastArithSlow_op_rshift(unsigned result, unsigned, unsigned op2, Vector<SlowCaseEntry>::iterator& iter) 117 { 118 linkSlowCase(iter); 119 if (getConstantImmediateNumericArg(op2)) 120 emitPutJITStubArgFromVirtualRegister(op2, 2, X86::ecx); 121 else { 122 linkSlowCase(iter); 123 emitPutJITStubArg(X86::ecx, 2); 124 } 125 126 emitPutJITStubArg(X86::eax, 1); 127 emitCTICall(Interpreter::cti_op_rshift); 128 emitPutVirtualRegister(result); 129 } 130 131 void JIT::compileFastArith_op_bitand(unsigned result, unsigned op1, unsigned op2) 132 { 133 if (isOperandConstant31BitImmediateInt(op1)) { 134 emitGetVirtualRegister(op2, X86::eax); 135 emitJumpSlowCaseIfNotImmNum(X86::eax); 136 andPtr(Imm32(static_cast<int32_t>(JSImmediate::rawValue(getConstantOperand(op1)))), X86::eax); 137 } else if (isOperandConstant31BitImmediateInt(op2)) { 138 emitGetVirtualRegister(op1, X86::eax); 139 emitJumpSlowCaseIfNotImmNum(X86::eax); 140 andPtr(Imm32(static_cast<int32_t>(JSImmediate::rawValue(getConstantOperand(op2)))), X86::eax); 141 } else { 142 emitGetVirtualRegisters(op1, X86::eax, op2, X86::edx); 143 andPtr(X86::edx, X86::eax); 144 emitJumpSlowCaseIfNotImmNum(X86::eax); 145 } 146 emitPutVirtualRegister(result); 147 } 148 void JIT::compileFastArithSlow_op_bitand(unsigned result, unsigned op1, unsigned op2, Vector<SlowCaseEntry>::iterator& iter) 149 { 150 linkSlowCase(iter); 151 if (isOperandConstant31BitImmediateInt(op1)) { 152 emitPutJITStubArgFromVirtualRegister(op1, 1, X86::ecx); 153 emitPutJITStubArg(X86::eax, 2); 154 } else if (isOperandConstant31BitImmediateInt(op2)) { 155 emitPutJITStubArg(X86::eax, 1); 156 emitPutJITStubArgFromVirtualRegister(op2, 2, X86::ecx); 157 } else { 158 emitPutJITStubArgFromVirtualRegister(op1, 1, X86::ecx); 159 emitPutJITStubArg(X86::edx, 2); 160 } 161 emitCTICall(Interpreter::cti_op_bitand); 162 emitPutVirtualRegister(result); 163 } 164 165 void JIT::compileFastArith_op_mod(unsigned result, unsigned op1, unsigned op2) 166 { 167 emitGetVirtualRegisters(op1, X86::eax, op2, X86::ecx); 168 emitJumpSlowCaseIfNotImmNum(X86::eax); 169 emitJumpSlowCaseIfNotImmNum(X86::ecx); 170 #if USE(ALTERNATE_JSIMMEDIATE) 171 addSlowCase(jePtr(X86::ecx, ImmPtr(JSImmediate::zeroImmediate()))); 172 emitFastArithImmToInt(X86::eax); 173 emitFastArithImmToInt(X86::ecx); 174 mod32(X86::ecx, X86::eax, X86::edx); 175 emitFastArithIntToImmNoCheck(X86::edx); 176 #else 177 emitFastArithDeTagImmediate(X86::eax); 178 addSlowCase(emitFastArithDeTagImmediateJumpIfZero(X86::ecx)); 179 mod32(X86::ecx, X86::eax, X86::edx); 180 signExtend32ToPtr(X86::edx, X86::edx); 181 emitFastArithReTagImmediate(X86::edx); 182 #endif 183 move(X86::edx, X86::eax); 184 emitPutVirtualRegister(result); 185 } 186 void JIT::compileFastArithSlow_op_mod(unsigned result, unsigned, unsigned, Vector<SlowCaseEntry>::iterator& iter) 187 { 188 #if USE(ALTERNATE_JSIMMEDIATE) 189 linkSlowCase(iter); 190 linkSlowCase(iter); 191 linkSlowCase(iter); 192 #else 193 Jump notImm1 = getSlowCase(iter); 194 Jump notImm2 = getSlowCase(iter); 195 linkSlowCase(iter); 196 emitFastArithReTagImmediate(X86::eax); 197 emitFastArithReTagImmediate(X86::ecx); 198 notImm1.link(this); 199 notImm2.link(this); 200 #endif 201 emitPutJITStubArg(X86::eax, 1); 202 emitPutJITStubArg(X86::ecx, 2); 203 emitCTICall(Interpreter::cti_op_mod); 204 emitPutVirtualRegister(result); 205 } 206 207 void JIT::compileFastArith_op_add(Instruction* currentInstruction) 208 { 209 unsigned result = currentInstruction[1].u.operand; 210 unsigned op1 = currentInstruction[2].u.operand; 211 unsigned op2 = currentInstruction[3].u.operand; 212 213 if (isOperandConstantImmediateInt(op1)) { 214 emitGetVirtualRegister(op2, X86::eax); 215 emitJumpSlowCaseIfNotImmNum(X86::eax); 216 #if USE(ALTERNATE_JSIMMEDIATE) 217 // FIXME: investigate performing a 31-bit add here (can we preserve upper bit & detect overflow from low word to high?) 218 // (or, detect carry? - if const is positive, will only carry when overflowing from negative to positive?) 219 emitFastArithImmToInt(X86::eax); 220 addSlowCase(joAdd32(Imm32(getConstantOperandImmediateInt(op1)), X86::eax)); 221 emitFastArithIntToImmNoCheck(X86::eax); 222 #else 223 addSlowCase(joAdd32(Imm32(getConstantOperandImmediateInt(op1) << JSImmediate::IntegerPayloadShift), X86::eax)); 224 signExtend32ToPtr(X86::eax, X86::eax); 225 #endif 226 emitPutVirtualRegister(result); 227 } else if (isOperandConstantImmediateInt(op2)) { 228 emitGetVirtualRegister(op1, X86::eax); 229 emitJumpSlowCaseIfNotImmNum(X86::eax); 230 #if USE(ALTERNATE_JSIMMEDIATE) 231 emitFastArithImmToInt(X86::eax); 232 addSlowCase(joAdd32(Imm32(getConstantOperandImmediateInt(op2)), X86::eax)); 233 emitFastArithIntToImmNoCheck(X86::eax); 234 #else 235 addSlowCase(joAdd32(Imm32(getConstantOperandImmediateInt(op2) << JSImmediate::IntegerPayloadShift), X86::eax)); 236 signExtend32ToPtr(X86::eax, X86::eax); 237 #endif 238 emitPutVirtualRegister(result); 239 } else { 240 OperandTypes types = OperandTypes::fromInt(currentInstruction[4].u.operand); 241 if (types.first().mightBeNumber() && types.second().mightBeNumber()) 242 compileBinaryArithOp(op_add, result, op1, op2, OperandTypes::fromInt(currentInstruction[4].u.operand)); 243 else { 244 emitPutJITStubArgFromVirtualRegister(op1, 1, X86::ecx); 245 emitPutJITStubArgFromVirtualRegister(op2, 2, X86::ecx); 246 emitCTICall(Interpreter::cti_op_add); 247 emitPutVirtualRegister(result); 248 } 249 } 250 } 251 void JIT::compileFastArithSlow_op_add(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) 252 { 253 unsigned result = currentInstruction[1].u.operand; 254 unsigned op1 = currentInstruction[2].u.operand; 255 unsigned op2 = currentInstruction[3].u.operand; 256 257 if (isOperandConstantImmediateInt(op1)) { 258 #if USE(ALTERNATE_JSIMMEDIATE) 259 linkSlowCase(iter); 260 linkSlowCase(iter); 261 emitPutJITStubArgFromVirtualRegister(op1, 1, X86::ecx); 262 emitPutJITStubArgFromVirtualRegister(op2, 2, X86::ecx); 263 #else 264 Jump notImm = getSlowCase(iter); 265 linkSlowCase(iter); 266 sub32(Imm32(getConstantOperandImmediateInt(op1) << JSImmediate::IntegerPayloadShift), X86::eax); 267 notImm.link(this); 268 emitPutJITStubArgFromVirtualRegister(op1, 1, X86::ecx); 269 emitPutJITStubArg(X86::eax, 2); 270 #endif 271 emitCTICall(Interpreter::cti_op_add); 272 emitPutVirtualRegister(result); 273 } else if (isOperandConstantImmediateInt(op2)) { 274 #if USE(ALTERNATE_JSIMMEDIATE) 275 linkSlowCase(iter); 276 linkSlowCase(iter); 277 emitPutJITStubArgFromVirtualRegister(op1, 1, X86::ecx); 278 emitPutJITStubArgFromVirtualRegister(op2, 2, X86::ecx); 279 #else 280 Jump notImm = getSlowCase(iter); 281 linkSlowCase(iter); 282 sub32(Imm32(getConstantOperandImmediateInt(op2) << JSImmediate::IntegerPayloadShift), X86::eax); 283 notImm.link(this); 284 emitPutJITStubArg(X86::eax, 1); 285 emitPutJITStubArgFromVirtualRegister(op2, 2, X86::ecx); 286 #endif 287 emitCTICall(Interpreter::cti_op_add); 288 emitPutVirtualRegister(result); 289 } else { 290 OperandTypes types = OperandTypes::fromInt(currentInstruction[4].u.operand); 291 ASSERT(types.first().mightBeNumber() && types.second().mightBeNumber()); 292 compileBinaryArithOpSlowCase(op_add, iter, result, op1, op2, types); 293 } 294 } 295 296 void JIT::compileFastArith_op_mul(Instruction* currentInstruction) 297 { 298 unsigned result = currentInstruction[1].u.operand; 299 unsigned op1 = currentInstruction[2].u.operand; 300 unsigned op2 = currentInstruction[3].u.operand; 301 302 // For now, only plant a fast int case if the constant operand is greater than zero. 303 int32_t value; 304 if (isOperandConstantImmediateInt(op1) && ((value = getConstantOperandImmediateInt(op1)) > 0)) { 305 emitGetVirtualRegister(op2, X86::eax); 306 emitJumpSlowCaseIfNotImmNum(X86::eax); 307 #if USE(ALTERNATE_JSIMMEDIATE) 308 emitFastArithImmToInt(X86::eax); 309 addSlowCase(joMul32(Imm32(value), X86::eax, X86::eax)); 310 emitFastArithIntToImmNoCheck(X86::eax); 311 #else 312 emitFastArithDeTagImmediate(X86::eax); 313 addSlowCase(joMul32(Imm32(value), X86::eax, X86::eax)); 314 signExtend32ToPtr(X86::eax, X86::eax); 315 emitFastArithReTagImmediate(X86::eax); 316 #endif 317 emitPutVirtualRegister(result); 318 } else if (isOperandConstantImmediateInt(op2) && ((value = getConstantOperandImmediateInt(op2)) > 0)) { 319 emitGetVirtualRegister(op1, X86::eax); 320 emitJumpSlowCaseIfNotImmNum(X86::eax); 321 #if USE(ALTERNATE_JSIMMEDIATE) 322 emitFastArithImmToInt(X86::eax); 323 addSlowCase(joMul32(Imm32(value), X86::eax, X86::eax)); 324 emitFastArithIntToImmNoCheck(X86::eax); 325 #else 326 emitFastArithDeTagImmediate(X86::eax); 327 addSlowCase(joMul32(Imm32(value), X86::eax, X86::eax)); 328 signExtend32ToPtr(X86::eax, X86::eax); 329 emitFastArithReTagImmediate(X86::eax); 330 #endif 331 emitPutVirtualRegister(result); 332 } else 333 compileBinaryArithOp(op_mul, result, op1, op2, OperandTypes::fromInt(currentInstruction[4].u.operand)); 334 } 335 void JIT::compileFastArithSlow_op_mul(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) 336 { 337 int result = currentInstruction[1].u.operand; 338 int op1 = currentInstruction[2].u.operand; 339 int op2 = currentInstruction[3].u.operand; 340 341 if ((isOperandConstantImmediateInt(op1) && (getConstantOperandImmediateInt(op1) > 0)) 342 || (isOperandConstantImmediateInt(op2) && (getConstantOperandImmediateInt(op2) > 0))) { 343 linkSlowCase(iter); 344 linkSlowCase(iter); 345 // There is an extra slow case for (op1 * -N) or (-N * op2), to check for 0 since this should produce a result of -0. 346 emitPutJITStubArgFromVirtualRegister(op1, 1, X86::ecx); 347 emitPutJITStubArgFromVirtualRegister(op2, 2, X86::ecx); 348 emitCTICall(Interpreter::cti_op_mul); 349 emitPutVirtualRegister(result); 350 } else 351 compileBinaryArithOpSlowCase(op_mul, iter, result, op1, op2, OperandTypes::fromInt(currentInstruction[4].u.operand)); 352 } 353 354 void JIT::compileFastArith_op_post_inc(unsigned result, unsigned srcDst) 355 { 356 emitGetVirtualRegister(srcDst, X86::eax); 357 move(X86::eax, X86::edx); 358 emitJumpSlowCaseIfNotImmNum(X86::eax); 359 #if USE(ALTERNATE_JSIMMEDIATE) 360 emitFastArithImmToInt(X86::edx); 361 addSlowCase(joAdd32(Imm32(1), X86::edx)); 362 emitFastArithIntToImmNoCheck(X86::edx); 363 #else 364 addSlowCase(joAdd32(Imm32(1 << JSImmediate::IntegerPayloadShift), X86::edx)); 365 signExtend32ToPtr(X86::edx, X86::edx); 366 #endif 367 emitPutVirtualRegister(srcDst, X86::edx); 368 emitPutVirtualRegister(result); 369 } 370 void JIT::compileFastArithSlow_op_post_inc(unsigned result, unsigned srcDst, Vector<SlowCaseEntry>::iterator& iter) 371 { 372 linkSlowCase(iter); 373 linkSlowCase(iter); 374 emitPutJITStubArg(X86::eax, 1); 375 emitCTICall(Interpreter::cti_op_post_inc); 376 emitPutVirtualRegister(srcDst, X86::edx); 377 emitPutVirtualRegister(result); 378 } 379 380 void JIT::compileFastArith_op_post_dec(unsigned result, unsigned srcDst) 381 { 382 emitGetVirtualRegister(srcDst, X86::eax); 383 move(X86::eax, X86::edx); 384 emitJumpSlowCaseIfNotImmNum(X86::eax); 385 #if USE(ALTERNATE_JSIMMEDIATE) 386 emitFastArithImmToInt(X86::edx); 387 addSlowCase(joSub32(Imm32(1), X86::edx)); 388 emitFastArithIntToImmNoCheck(X86::edx); 389 #else 390 addSlowCase(joSub32(Imm32(1 << JSImmediate::IntegerPayloadShift), X86::edx)); 391 signExtend32ToPtr(X86::edx, X86::edx); 392 #endif 393 emitPutVirtualRegister(srcDst, X86::edx); 394 emitPutVirtualRegister(result); 395 } 396 void JIT::compileFastArithSlow_op_post_dec(unsigned result, unsigned srcDst, Vector<SlowCaseEntry>::iterator& iter) 397 { 398 linkSlowCase(iter); 399 linkSlowCase(iter); 400 emitPutJITStubArg(X86::eax, 1); 401 emitCTICall(Interpreter::cti_op_post_dec); 402 emitPutVirtualRegister(srcDst, X86::edx); 403 emitPutVirtualRegister(result); 404 } 405 406 void JIT::compileFastArith_op_pre_inc(unsigned srcDst) 407 { 408 emitGetVirtualRegister(srcDst, X86::eax); 409 emitJumpSlowCaseIfNotImmNum(X86::eax); 410 #if USE(ALTERNATE_JSIMMEDIATE) 411 emitFastArithImmToInt(X86::eax); 412 // FIXME: Could add ptr & specify int64; no need to re-sign-extend? 413 addSlowCase(joAdd32(Imm32(1), X86::eax)); 414 emitFastArithIntToImmNoCheck(X86::eax); 415 #else 416 addSlowCase(joAdd32(Imm32(1 << JSImmediate::IntegerPayloadShift), X86::eax)); 417 signExtend32ToPtr(X86::eax, X86::eax); 418 #endif 419 emitPutVirtualRegister(srcDst); 420 } 421 void JIT::compileFastArithSlow_op_pre_inc(unsigned srcDst, Vector<SlowCaseEntry>::iterator& iter) 422 { 423 Jump notImm = getSlowCase(iter); 424 linkSlowCase(iter); 425 emitGetVirtualRegister(srcDst, X86::eax); 426 notImm.link(this); 427 emitPutJITStubArg(X86::eax, 1); 428 emitCTICall(Interpreter::cti_op_pre_inc); 429 emitPutVirtualRegister(srcDst); 430 } 431 432 void JIT::compileFastArith_op_pre_dec(unsigned srcDst) 433 { 434 emitGetVirtualRegister(srcDst, X86::eax); 435 emitJumpSlowCaseIfNotImmNum(X86::eax); 436 #if USE(ALTERNATE_JSIMMEDIATE) 437 emitFastArithImmToInt(X86::eax); 438 addSlowCase(joSub32(Imm32(1), X86::eax)); 439 emitFastArithIntToImmNoCheck(X86::eax); 440 #else 441 addSlowCase(joSub32(Imm32(1 << JSImmediate::IntegerPayloadShift), X86::eax)); 442 signExtend32ToPtr(X86::eax, X86::eax); 443 #endif 444 emitPutVirtualRegister(srcDst); 445 } 446 void JIT::compileFastArithSlow_op_pre_dec(unsigned srcDst, Vector<SlowCaseEntry>::iterator& iter) 447 { 448 Jump notImm = getSlowCase(iter); 449 linkSlowCase(iter); 450 emitGetVirtualRegister(srcDst, X86::eax); 451 notImm.link(this); 452 emitPutJITStubArg(X86::eax, 1); 453 emitCTICall(Interpreter::cti_op_pre_dec); 454 emitPutVirtualRegister(srcDst); 455 } 456 457 49 458 #if !ENABLE(JIT_OPTIMIZE_ARITHMETIC) 50 459 … … 270 679 __ subl_rr(X86::edx, X86::eax); 271 680 addSlowCase(__ jo()); 681 signExtend32ToPtr(X86::eax, X86::eax); 272 682 emitFastArithReTagImmediate(X86::eax); 273 683 } else { … … 288 698 __ imull_rr(X86::edx, X86::eax); 289 699 addSlowCase(__ jo()); 700 signExtend32ToPtr(X86::eax, X86::eax); 290 701 emitFastArithReTagImmediate(X86::eax); 291 702 } -
trunk/JavaScriptCore/jit/JITInlineMethods.h
r39428 r39540 42 42 namespace JSC { 43 43 44 static ALWAYS_INLINE uintptr_t asInteger(JSValue* value)45 {46 return reinterpret_cast<uintptr_t>(value);47 }48 49 44 ALWAYS_INLINE void JIT::killLastResultRegister() 50 45 { … … 127 122 } 128 123 124 ALWAYS_INLINE JSValue* JIT::getConstantOperand(unsigned src) 125 { 126 ASSERT(m_codeBlock->isConstantRegisterIndex(src)); 127 return m_codeBlock->getConstant(src); 128 } 129 130 ALWAYS_INLINE int32_t JIT::getConstantOperandImmediateInt(unsigned src) 131 { 132 return static_cast<int32_t>(JSImmediate::intValue(getConstantOperand(src))); 133 } 134 135 ALWAYS_INLINE bool JIT::isOperandConstantImmediateInt(unsigned src) 136 { 137 return m_codeBlock->isConstantRegisterIndex(src) && JSImmediate::isNumber(getConstantOperand(src)); 138 } 139 140 ALWAYS_INLINE bool JIT::isOperandConstant31BitImmediateInt(unsigned src) 141 { 142 if (!m_codeBlock->isConstantRegisterIndex(src)) 143 return false; 144 145 JSValue* value = getConstantOperand(src); 146 147 #if USE(ALTERNATE_JSIMMEDIATE) 148 if (!JSImmediate::isNumber(value)) 149 return false; 150 151 int32_t imm = JSImmediate::intValue(value); 152 return (imm == ((imm << 1) >> 1)); 153 #else 154 return JSImmediate::isNumber(value); 155 #endif 156 } 157 129 158 // get arg puts an arg from the SF register array onto the stack, as an arg to a context threaded function. 130 159 ALWAYS_INLINE void JIT::emitPutJITStubArgFromVirtualRegister(unsigned src, unsigned argumentNumber, RegisterID scratch) … … 304 333 } 305 334 306 ALWAYS_INLINE unsigned JIT::getDeTaggedConstantImmediate(JSValue* imm)307 {308 ASSERT(JSImmediate::isNumber(imm));309 return asInteger(imm) & ~JSImmediate::TagBitTypeInteger;310 }311 312 335 ALWAYS_INLINE void JIT::emitFastArithDeTagImmediate(RegisterID reg) 313 336 { 314 sub 32(Imm32(JSImmediate::TagBitTypeInteger), reg);337 subPtr(Imm32(JSImmediate::TagBitTypeInteger), reg); 315 338 } 316 339 317 340 ALWAYS_INLINE JIT::Jump JIT::emitFastArithDeTagImmediateJumpIfZero(RegisterID reg) 318 341 { 319 return jzSub 32(Imm32(JSImmediate::TagBitTypeInteger), reg);342 return jzSubPtr(Imm32(JSImmediate::TagBitTypeInteger), reg); 320 343 } 321 344 322 345 ALWAYS_INLINE void JIT::emitFastArithReTagImmediate(RegisterID reg) 323 346 { 324 add32(Imm32(JSImmediate::TagBitTypeInteger), reg); 347 addPtr(Imm32(JSImmediate::TagBitTypeInteger), reg); 348 } 349 350 ALWAYS_INLINE void JIT::emitFastArithImmToInt(RegisterID reg) 351 { 352 rshiftPtr(Imm32(JSImmediate::IntegerPayloadShift), reg); 353 } 354 355 ALWAYS_INLINE void JIT::emitFastArithIntToImmNoCheck(RegisterID reg) 356 { 325 357 signExtend32ToPtr(reg, reg); 326 } 327 328 ALWAYS_INLINE void JIT::emitFastArithPotentiallyReTagImmediate(RegisterID reg) 329 { 330 or32(Imm32(JSImmediate::TagBitTypeInteger), reg); 331 signExtend32ToPtr(reg, reg); 332 } 333 334 ALWAYS_INLINE void JIT::emitFastArithImmToInt(RegisterID reg) 335 { 336 rshift32(Imm32(JSImmediate::IntegerPayloadShift), reg); 337 } 338 339 ALWAYS_INLINE void JIT::emitFastArithIntToImmOrSlowCase(RegisterID reg) 340 { 341 addSlowCase(joAdd32(reg, reg)); 342 emitFastArithReTagImmediate(reg); 343 } 344 345 ALWAYS_INLINE void JIT::emitFastArithIntToImmNoCheck(RegisterID reg) 346 { 347 add32(reg, reg); 358 addPtr(reg, reg); 348 359 emitFastArithReTagImmediate(reg); 349 360 }
Note:
See TracChangeset
for help on using the changeset viewer.