| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 761 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 772 if (!final_result_reg.is(result_reg)) { | 772 if (!final_result_reg.is(result_reg)) { |
| 773 ASSERT(final_result_reg.is(ecx)); | 773 ASSERT(final_result_reg.is(ecx)); |
| 774 __ mov(final_result_reg, result_reg); | 774 __ mov(final_result_reg, result_reg); |
| 775 } | 775 } |
| 776 __ pop(save_reg); | 776 __ pop(save_reg); |
| 777 __ pop(scratch1); | 777 __ pop(scratch1); |
| 778 __ ret(0); | 778 __ ret(0); |
| 779 } | 779 } |
| 780 | 780 |
| 781 | 781 |
| 782 // Uses SSE2 to convert the heap number in |source| to an integer. Jumps to | |
| 783 // |conversion_failure| if the heap number did not contain an int32 value. | |
| 784 // Result is in ecx. Trashes ebx, xmm0, and xmm1. | |
| 785 static void ConvertHeapNumberToInt32(MacroAssembler* masm, | |
| 786 Register source, | |
| 787 Label* conversion_failure) { | |
| 788 __ movdbl(xmm0, FieldOperand(source, HeapNumber::kValueOffset)); | |
| 789 FloatingPointHelper::CheckSSE2OperandIsInt32( | |
| 790 masm, conversion_failure, xmm0, ecx, ebx, xmm1); | |
| 791 } | |
| 792 | |
| 793 | |
| 794 void BinaryOpStub::Initialize() { | 782 void BinaryOpStub::Initialize() { |
| 795 platform_specific_bit_ = CpuFeatures::IsSupported(SSE3); | 783 platform_specific_bit_ = CpuFeatures::IsSupported(SSE3); |
| 796 } | 784 } |
| 797 | 785 |
| 798 | 786 |
| 799 void BinaryOpStub::GenerateTypeTransition(MacroAssembler* masm) { | 787 void BinaryOpStub::GenerateTypeTransition(MacroAssembler* masm) { |
| 800 __ pop(ecx); // Save return address. | 788 __ pop(ecx); // Save return address. |
| 801 __ push(edx); | 789 __ push(edx); |
| 802 __ push(eax); | 790 __ push(eax); |
| 803 // Left and right arguments are now on top. | 791 // Left and right arguments are now on top. |
| (...skipping 1580 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2384 __ cmp(edx, factory->undefined_value()); | 2372 __ cmp(edx, factory->undefined_value()); |
| 2385 __ j(not_equal, conversion_failure); | 2373 __ j(not_equal, conversion_failure); |
| 2386 __ mov(edx, Immediate(0)); | 2374 __ mov(edx, Immediate(0)); |
| 2387 __ jmp(&load_arg2); | 2375 __ jmp(&load_arg2); |
| 2388 | 2376 |
| 2389 __ bind(&arg1_is_object); | 2377 __ bind(&arg1_is_object); |
| 2390 __ mov(ebx, FieldOperand(edx, HeapObject::kMapOffset)); | 2378 __ mov(ebx, FieldOperand(edx, HeapObject::kMapOffset)); |
| 2391 __ cmp(ebx, factory->heap_number_map()); | 2379 __ cmp(ebx, factory->heap_number_map()); |
| 2392 __ j(not_equal, &check_undefined_arg1); | 2380 __ j(not_equal, &check_undefined_arg1); |
| 2393 | 2381 |
| 2394 // Get the untagged integer version of the edx heap number in ecx. | 2382 __ TruncateHeapNumberToI(edx, edx); |
| 2395 if (left_type == BinaryOpIC::INT32 && CpuFeatures::IsSupported(SSE2)) { | |
| 2396 CpuFeatureScope use_sse2(masm, SSE2); | |
| 2397 ConvertHeapNumberToInt32(masm, edx, conversion_failure); | |
| 2398 } else { | |
| 2399 DoubleToIStub stub(edx, ecx, HeapNumber::kValueOffset - kHeapObjectTag, | |
| 2400 true); | |
| 2401 __ call(stub.GetCode(masm->isolate()), RelocInfo::CODE_TARGET); | |
| 2402 } | |
| 2403 __ mov(edx, ecx); | |
| 2404 | 2383 |
| 2405 // Here edx has the untagged integer, eax has a Smi or a heap number. | 2384 // Here edx has the untagged integer, eax has a Smi or a heap number. |
| 2406 __ bind(&load_arg2); | 2385 __ bind(&load_arg2); |
| 2407 | 2386 |
| 2408 // Test if arg2 is a Smi. | 2387 // Test if arg2 is a Smi. |
| 2409 if (right_type == BinaryOpIC::SMI) { | 2388 if (right_type == BinaryOpIC::SMI) { |
| 2410 __ JumpIfNotSmi(eax, conversion_failure); | 2389 __ JumpIfNotSmi(eax, conversion_failure); |
| 2411 } else { | 2390 } else { |
| 2412 __ JumpIfNotSmi(eax, &arg2_is_object, Label::kNear); | 2391 __ JumpIfNotSmi(eax, &arg2_is_object, Label::kNear); |
| 2413 } | 2392 } |
| 2414 | 2393 |
| 2415 __ SmiUntag(eax); | 2394 __ SmiUntag(eax); |
| 2416 __ mov(ecx, eax); | 2395 __ mov(ecx, eax); |
| 2417 __ jmp(&done); | 2396 __ jmp(&done); |
| 2418 | 2397 |
| 2419 // If the argument is undefined it converts to zero (ECMA-262, section 9.5). | 2398 // If the argument is undefined it converts to zero (ECMA-262, section 9.5). |
| 2420 __ bind(&check_undefined_arg2); | 2399 __ bind(&check_undefined_arg2); |
| 2421 __ cmp(eax, factory->undefined_value()); | 2400 __ cmp(eax, factory->undefined_value()); |
| 2422 __ j(not_equal, conversion_failure); | 2401 __ j(not_equal, conversion_failure); |
| 2423 __ mov(ecx, Immediate(0)); | 2402 __ mov(ecx, Immediate(0)); |
| 2424 __ jmp(&done); | 2403 __ jmp(&done); |
| 2425 | 2404 |
| 2426 __ bind(&arg2_is_object); | 2405 __ bind(&arg2_is_object); |
| 2427 __ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset)); | 2406 __ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset)); |
| 2428 __ cmp(ebx, factory->heap_number_map()); | 2407 __ cmp(ebx, factory->heap_number_map()); |
| 2429 __ j(not_equal, &check_undefined_arg2); | 2408 __ j(not_equal, &check_undefined_arg2); |
| 2430 // Get the untagged integer version of the eax heap number in ecx. | 2409 // Get the untagged integer version of the eax heap number in ecx. |
| 2431 | 2410 |
| 2432 if (right_type == BinaryOpIC::INT32 && CpuFeatures::IsSupported(SSE2)) { | 2411 __ TruncateHeapNumberToI(ecx, eax); |
| 2433 CpuFeatureScope use_sse2(masm, SSE2); | |
| 2434 ConvertHeapNumberToInt32(masm, eax, conversion_failure); | |
| 2435 } else { | |
| 2436 DoubleToIStub stub(eax, ecx, HeapNumber::kValueOffset - kHeapObjectTag, | |
| 2437 true); | |
| 2438 __ call(stub.GetCode(masm->isolate()), RelocInfo::CODE_TARGET); | |
| 2439 } | |
| 2440 | 2412 |
| 2441 __ bind(&done); | 2413 __ bind(&done); |
| 2442 __ mov(eax, edx); | 2414 __ mov(eax, edx); |
| 2443 } | 2415 } |
| 2444 | 2416 |
| 2445 | 2417 |
| 2446 void FloatingPointHelper::LoadFloatOperand(MacroAssembler* masm, | 2418 void FloatingPointHelper::LoadFloatOperand(MacroAssembler* masm, |
| 2447 Register number) { | 2419 Register number) { |
| 2448 Label load_smi, done; | 2420 Label load_smi, done; |
| 2449 | 2421 |
| (...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2683 __ JumpIfNotSmi(exponent, &exponent_not_smi, Label::kNear); | 2655 __ JumpIfNotSmi(exponent, &exponent_not_smi, Label::kNear); |
| 2684 __ SmiUntag(exponent); | 2656 __ SmiUntag(exponent); |
| 2685 __ jmp(&int_exponent); | 2657 __ jmp(&int_exponent); |
| 2686 | 2658 |
| 2687 __ bind(&exponent_not_smi); | 2659 __ bind(&exponent_not_smi); |
| 2688 __ movdbl(double_exponent, | 2660 __ movdbl(double_exponent, |
| 2689 FieldOperand(exponent, HeapNumber::kValueOffset)); | 2661 FieldOperand(exponent, HeapNumber::kValueOffset)); |
| 2690 } | 2662 } |
| 2691 | 2663 |
| 2692 if (exponent_type_ != INTEGER) { | 2664 if (exponent_type_ != INTEGER) { |
| 2693 Label fast_power; | 2665 Label fast_power, try_arithmetic_simplification; |
| 2694 // Detect integer exponents stored as double. | 2666 __ DoubleToI(exponent, double_exponent, double_scratch, |
| 2667 TREAT_MINUS_ZERO_AS_ZERO, &try_arithmetic_simplification); |
| 2668 __ jmp(&int_exponent); |
| 2669 |
| 2670 __ bind(&try_arithmetic_simplification); |
| 2671 // Skip to runtime if possibly NaN (indicated by the indefinite integer). |
| 2695 __ cvttsd2si(exponent, Operand(double_exponent)); | 2672 __ cvttsd2si(exponent, Operand(double_exponent)); |
| 2696 // Skip to runtime if possibly NaN (indicated by the indefinite integer). | |
| 2697 __ cmp(exponent, Immediate(0x80000000u)); | 2673 __ cmp(exponent, Immediate(0x80000000u)); |
| 2698 __ j(equal, &call_runtime); | 2674 __ j(equal, &call_runtime); |
| 2699 __ cvtsi2sd(double_scratch, exponent); | |
| 2700 // Already ruled out NaNs for exponent. | |
| 2701 __ ucomisd(double_exponent, double_scratch); | |
| 2702 __ j(equal, &int_exponent); | |
| 2703 | 2675 |
| 2704 if (exponent_type_ == ON_STACK) { | 2676 if (exponent_type_ == ON_STACK) { |
| 2705 // Detect square root case. Crankshaft detects constant +/-0.5 at | 2677 // Detect square root case. Crankshaft detects constant +/-0.5 at |
| 2706 // compile time and uses DoMathPowHalf instead. We then skip this check | 2678 // compile time and uses DoMathPowHalf instead. We then skip this check |
| 2707 // for non-constant cases of +/-0.5 as these hardly occur. | 2679 // for non-constant cases of +/-0.5 as these hardly occur. |
| 2708 Label continue_sqrt, continue_rsqrt, not_plus_half; | 2680 Label continue_sqrt, continue_rsqrt, not_plus_half; |
| 2709 // Test for 0.5. | 2681 // Test for 0.5. |
| 2710 // Load double_scratch with 0.5. | 2682 // Load double_scratch with 0.5. |
| 2711 __ mov(scratch, Immediate(0x3F000000u)); | 2683 __ mov(scratch, Immediate(0x3F000000u)); |
| 2712 __ movd(double_scratch, scratch); | 2684 __ movd(double_scratch, scratch); |
| (...skipping 5001 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7714 __ bind(&fast_elements_case); | 7686 __ bind(&fast_elements_case); |
| 7715 GenerateCase(masm, FAST_ELEMENTS); | 7687 GenerateCase(masm, FAST_ELEMENTS); |
| 7716 } | 7688 } |
| 7717 | 7689 |
| 7718 | 7690 |
| 7719 #undef __ | 7691 #undef __ |
| 7720 | 7692 |
| 7721 } } // namespace v8::internal | 7693 } } // namespace v8::internal |
| 7722 | 7694 |
| 7723 #endif // V8_TARGET_ARCH_IA32 | 7695 #endif // V8_TARGET_ARCH_IA32 |
| OLD | NEW |