Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(39)

Side by Side Diff: src/ia32/code-stubs-ia32.cc

Issue 22290005: Move ToI conversions to the MacroAssembler (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: address review Created 7 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/ia32/assembler-ia32.h ('k') | src/ia32/lithium-codegen-ia32.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/ia32/assembler-ia32.h ('k') | src/ia32/lithium-codegen-ia32.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698