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

Side by Side Diff: src/ia32/ic-ia32.cc

Issue 608031: Change KeyedStoreIC interface to take value, key, and receiver in registers. (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 10 years, 9 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/full-codegen-ia32.cc ('k') | src/ia32/stub-cache-ia32.cc » ('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 2006-2008 the V8 project authors. All rights reserved. 1 // Copyright 2006-2008 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 604 matching lines...) Expand 10 before | Expand all | Expand 10 after
615 __ TailCallExternalReference(ref, 2, 1); 615 __ TailCallExternalReference(ref, 2, 1);
616 616
617 __ bind(&slow); 617 __ bind(&slow);
618 GenerateMiss(masm); 618 GenerateMiss(masm);
619 } 619 }
620 620
621 621
622 void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm) { 622 void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm) {
623 // ----------- S t a t e ------------- 623 // ----------- S t a t e -------------
624 // -- eax : value 624 // -- eax : value
625 // -- ecx : key
626 // -- edx : receiver
625 // -- esp[0] : return address 627 // -- esp[0] : return address
626 // -- esp[4] : key
627 // -- esp[8] : receiver
628 // ----------------------------------- 628 // -----------------------------------
629 Label slow, fast, array, extra, check_pixel_array; 629 Label slow, fast, array, extra, check_pixel_array;
630 630
631 // Get the receiver from the stack.
632 __ mov(edx, Operand(esp, 2 * kPointerSize)); // 2 ~ return address, key
633 // Check that the object isn't a smi. 631 // Check that the object isn't a smi.
634 __ test(edx, Immediate(kSmiTagMask)); 632 __ test(edx, Immediate(kSmiTagMask));
635 __ j(zero, &slow, not_taken); 633 __ j(zero, &slow, not_taken);
636 // Get the map from the receiver. 634 // Get the map from the receiver.
637 __ mov(ecx, FieldOperand(edx, HeapObject::kMapOffset)); 635 __ mov(edi, FieldOperand(edx, HeapObject::kMapOffset));
638 // Check that the receiver does not require access checks. We need 636 // Check that the receiver does not require access checks. We need
639 // to do this because this generic stub does not perform map checks. 637 // to do this because this generic stub does not perform map checks.
640 __ movzx_b(ebx, FieldOperand(ecx, Map::kBitFieldOffset)); 638 __ movzx_b(ebx, FieldOperand(edi, Map::kBitFieldOffset));
641 __ test(ebx, Immediate(1 << Map::kIsAccessCheckNeeded)); 639 __ test(ebx, Immediate(1 << Map::kIsAccessCheckNeeded));
642 __ j(not_zero, &slow, not_taken); 640 __ j(not_zero, &slow, not_taken);
643 // Get the key from the stack.
644 __ mov(ebx, Operand(esp, 1 * kPointerSize)); // 1 ~ return address
645 // Check that the key is a smi. 641 // Check that the key is a smi.
646 __ test(ebx, Immediate(kSmiTagMask)); 642 __ test(ecx, Immediate(kSmiTagMask));
647 __ j(not_zero, &slow, not_taken); 643 __ j(not_zero, &slow, not_taken);
648 // Get the instance type from the map of the receiver. 644 __ CmpInstanceType(edi, JS_ARRAY_TYPE);
649 __ movzx_b(ecx, FieldOperand(ecx, Map::kInstanceTypeOffset));
650 // Check if the object is a JS array or not.
651 __ cmp(ecx, JS_ARRAY_TYPE);
652 __ j(equal, &array); 645 __ j(equal, &array);
653 // Check that the object is some kind of JS object. 646 // Check that the object is some kind of JS object.
654 __ cmp(ecx, FIRST_JS_OBJECT_TYPE); 647 __ CmpInstanceType(edi, FIRST_JS_OBJECT_TYPE);
655 __ j(less, &slow, not_taken); 648 __ j(below, &slow, not_taken);
656 649
657 // Object case: Check key against length in the elements array. 650 // Object case: Check key against length in the elements array.
658 // eax: value 651 // eax: value
659 // edx: JSObject 652 // edx: JSObject
660 // ebx: index (as a smi) 653 // ecx: key (a smi)
661 __ mov(ecx, FieldOperand(edx, JSObject::kElementsOffset)); 654 __ mov(edi, FieldOperand(edx, JSObject::kElementsOffset));
662 // Check that the object is in fast mode (not dictionary). 655 // Check that the object is in fast mode (not dictionary).
663 __ cmp(FieldOperand(ecx, HeapObject::kMapOffset), 656 __ CheckMap(edi, Factory::fixed_array_map(), &check_pixel_array, true);
664 Immediate(Factory::fixed_array_map())); 657 __ mov(ebx, Operand(ecx));
665 __ j(not_equal, &check_pixel_array, not_taken); 658 __ SmiUntag(ebx);
666 // Untag the key (for checking against untagged length in the fixed array). 659 __ cmp(ebx, FieldOperand(edi, Array::kLengthOffset));
667 __ mov(edx, Operand(ebx));
668 __ sar(edx, kSmiTagSize); // untag the index and use it for the comparison
669 __ cmp(edx, FieldOperand(ecx, Array::kLengthOffset));
670 // eax: value
671 // ecx: FixedArray
672 // ebx: index (as a smi)
673 __ j(below, &fast, taken); 660 __ j(below, &fast, taken);
674 661
675 // Slow case: call runtime. 662 // Slow case: call runtime.
676 __ bind(&slow); 663 __ bind(&slow);
677 GenerateRuntimeSetProperty(masm); 664 GenerateRuntimeSetProperty(masm);
678 665
679 // Check whether the elements is a pixel array. 666 // Check whether the elements is a pixel array.
667 __ bind(&check_pixel_array);
680 // eax: value 668 // eax: value
681 // ecx: elements array 669 // ecx: key
682 // ebx: index (as a smi) 670 // edx: receiver
683 __ bind(&check_pixel_array); 671 // edi: elements array
684 __ cmp(FieldOperand(ecx, HeapObject::kMapOffset), 672 __ CheckMap(edi, Factory::pixel_array_map(), &slow, true);
685 Immediate(Factory::pixel_array_map()));
686 __ j(not_equal, &slow);
687 // Check that the value is a smi. If a conversion is needed call into the 673 // Check that the value is a smi. If a conversion is needed call into the
688 // runtime to convert and clamp. 674 // runtime to convert and clamp.
689 __ test(eax, Immediate(kSmiTagMask)); 675 __ test(eax, Immediate(kSmiTagMask));
690 __ j(not_zero, &slow); 676 __ j(not_zero, &slow);
691 __ sar(ebx, kSmiTagSize); // Untag the index. 677 __ mov(ebx, ecx);
692 __ cmp(ebx, FieldOperand(ecx, PixelArray::kLengthOffset)); 678 __ SmiUntag(ebx);
679 __ cmp(ebx, FieldOperand(edi, PixelArray::kLengthOffset));
693 __ j(above_equal, &slow); 680 __ j(above_equal, &slow);
694 __ mov(edx, eax); // Save the value. 681 __ mov(ecx, eax); // Save the value. Key is not longer needed.
695 __ sar(eax, kSmiTagSize); // Untag the value. 682 __ SmiUntag(ecx);
696 { // Clamp the value to [0..255]. 683 { // Clamp the value to [0..255].
697 Label done; 684 Label done;
698 __ test(eax, Immediate(0xFFFFFF00)); 685 __ test(ecx, Immediate(0xFFFFFF00));
699 __ j(zero, &done); 686 __ j(zero, &done);
700 __ setcc(negative, eax); // 1 if negative, 0 if positive. 687 __ setcc(negative, ecx); // 1 if negative, 0 if positive.
701 __ dec_b(eax); // 0 if negative, 255 if positive. 688 __ dec_b(ecx); // 0 if negative, 255 if positive.
702 __ bind(&done); 689 __ bind(&done);
703 } 690 }
704 __ mov(ecx, FieldOperand(ecx, PixelArray::kExternalPointerOffset)); 691 __ mov(edi, FieldOperand(edi, PixelArray::kExternalPointerOffset));
705 __ mov_b(Operand(ecx, ebx, times_1, 0), eax); 692 __ mov_b(Operand(edi, ebx, times_1, 0), ecx);
706 __ mov(eax, edx); // Return the original value. 693 __ ret(0); // Return value in eax.
707 __ ret(0);
708 694
709 // Extra capacity case: Check if there is extra capacity to 695 // Extra capacity case: Check if there is extra capacity to
710 // perform the store and update the length. Used for adding one 696 // perform the store and update the length. Used for adding one
711 // element to the array by writing to array[array.length]. 697 // element to the array by writing to array[array.length].
712 __ bind(&extra); 698 __ bind(&extra);
713 // eax: value 699 // eax: value
714 // edx: JSArray 700 // edx: receiver, a JSArray
715 // ecx: FixedArray 701 // ecx: key, a smi.
716 // ebx: index (as a smi) 702 // edi: receiver->elements, a FixedArray
717 // flags: compare (ebx, edx.length()) 703 // flags: compare (ecx, edx.length())
718 __ j(not_equal, &slow, not_taken); // do not leave holes in the array 704 __ j(not_equal, &slow, not_taken); // do not leave holes in the array
719 __ sar(ebx, kSmiTagSize); // untag 705 __ mov(ebx, ecx);
720 __ cmp(ebx, FieldOperand(ecx, Array::kLengthOffset)); 706 __ SmiUntag(ebx); // untag
707 __ cmp(ebx, FieldOperand(edi, Array::kLengthOffset));
721 __ j(above_equal, &slow, not_taken); 708 __ j(above_equal, &slow, not_taken);
722 // Restore tag and increment. 709 // Add 1 to receiver->length, and go to fast array write.
723 __ lea(ebx, Operand(ebx, times_2, 1 << kSmiTagSize)); 710 __ add(FieldOperand(edx, JSArray::kLengthOffset),
724 __ mov(FieldOperand(edx, JSArray::kLengthOffset), ebx); 711 Immediate(1 << kSmiTagSize));
725 __ sub(Operand(ebx), Immediate(1 << kSmiTagSize)); // decrement ebx again
726 __ jmp(&fast); 712 __ jmp(&fast);
727 713
728 // Array case: Get the length and the elements array from the JS 714 // Array case: Get the length and the elements array from the JS
729 // array. Check that the array is in fast mode; if it is the 715 // array. Check that the array is in fast mode; if it is the
730 // length is always a smi. 716 // length is always a smi.
731 __ bind(&array); 717 __ bind(&array);
732 // eax: value 718 // eax: value
733 // edx: JSArray 719 // edx: receiver, a JSArray
734 // ebx: index (as a smi) 720 // ecx: key, a smi.
735 __ mov(ecx, FieldOperand(edx, JSObject::kElementsOffset)); 721 __ mov(edi, FieldOperand(edx, JSObject::kElementsOffset));
736 __ cmp(FieldOperand(ecx, HeapObject::kMapOffset), 722 __ CheckMap(edi, Factory::fixed_array_map(), &check_pixel_array, true);
737 Immediate(Factory::fixed_array_map()));
738 __ j(not_equal, &check_pixel_array);
739 723
740 // Check the key against the length in the array, compute the 724 // Check the key against the length in the array, compute the
741 // address to store into and fall through to fast case. 725 // address to store into and fall through to fast case.
742 __ cmp(ebx, FieldOperand(edx, JSArray::kLengthOffset)); 726 __ cmp(ecx, FieldOperand(edx, JSArray::kLengthOffset)); // Compare smis.
743 __ j(above_equal, &extra, not_taken); 727 __ j(above_equal, &extra, not_taken);
744 728
745 // Fast case: Do the store. 729 // Fast case: Do the store.
746 __ bind(&fast); 730 __ bind(&fast);
747 // eax: value 731 // eax: value
748 // ecx: FixedArray 732 // ecx: key (a smi)
749 // ebx: index (as a smi) 733 // edx: receiver
750 __ mov(Operand(ecx, ebx, times_2, FixedArray::kHeaderSize - kHeapObjectTag), 734 // edi: FixedArray receiver->elements
751 eax); 735 __ mov(FieldOperand(edi, ecx, times_2, FixedArray::kHeaderSize), eax);
752 // Update write barrier for the elements array address. 736 // Update write barrier for the elements array address.
753 __ mov(edx, Operand(eax)); 737 __ mov(edx, Operand(eax));
754 __ RecordWrite(ecx, 0, edx, ebx); 738 __ RecordWrite(edi, 0, edx, ecx);
755 __ ret(0); 739 __ ret(0);
756 } 740 }
757 741
758 742
759 void KeyedStoreIC::GenerateExternalArray(MacroAssembler* masm, 743 void KeyedStoreIC::GenerateExternalArray(MacroAssembler* masm,
760 ExternalArrayType array_type) { 744 ExternalArrayType array_type) {
761 // ----------- S t a t e ------------- 745 // ----------- S t a t e -------------
762 // -- eax : value 746 // -- eax : value
747 // -- ecx : key
748 // -- edx : receiver
763 // -- esp[0] : return address 749 // -- esp[0] : return address
764 // -- esp[4] : key
765 // -- esp[8] : receiver
766 // ----------------------------------- 750 // -----------------------------------
767 Label slow, check_heap_number; 751 Label slow, check_heap_number;
768 752
769 // Get the receiver from the stack.
770 __ mov(edx, Operand(esp, 2 * kPointerSize));
771 // Check that the object isn't a smi. 753 // Check that the object isn't a smi.
772 __ test(edx, Immediate(kSmiTagMask)); 754 __ test(edx, Immediate(kSmiTagMask));
773 __ j(zero, &slow); 755 __ j(zero, &slow);
774 // Get the map from the receiver. 756 // Get the map from the receiver.
775 __ mov(ecx, FieldOperand(edx, HeapObject::kMapOffset)); 757 __ mov(edi, FieldOperand(edx, HeapObject::kMapOffset));
776 // Check that the receiver does not require access checks. We need 758 // Check that the receiver does not require access checks. We need
777 // to do this because this generic stub does not perform map checks. 759 // to do this because this generic stub does not perform map checks.
778 __ movzx_b(ebx, FieldOperand(ecx, Map::kBitFieldOffset)); 760 __ movzx_b(ebx, FieldOperand(edi, Map::kBitFieldOffset));
779 __ test(ebx, Immediate(1 << Map::kIsAccessCheckNeeded)); 761 __ test(ebx, Immediate(1 << Map::kIsAccessCheckNeeded));
780 __ j(not_zero, &slow); 762 __ j(not_zero, &slow);
781 // Get the key from the stack.
782 __ mov(ebx, Operand(esp, 1 * kPointerSize)); // 1 ~ return address
783 // Check that the key is a smi. 763 // Check that the key is a smi.
784 __ test(ebx, Immediate(kSmiTagMask)); 764 __ test(ecx, Immediate(kSmiTagMask));
785 __ j(not_zero, &slow); 765 __ j(not_zero, &slow);
786 // Get the instance type from the map of the receiver. 766 // Get the instance type from the map of the receiver.
787 __ movzx_b(ecx, FieldOperand(ecx, Map::kInstanceTypeOffset)); 767 __ CmpInstanceType(edi, JS_OBJECT_TYPE);
788 // Check that the object is a JS object.
789 __ cmp(ecx, JS_OBJECT_TYPE);
790 __ j(not_equal, &slow); 768 __ j(not_equal, &slow);
791 769
792 // Check that the elements array is the appropriate type of 770 // Check that the elements array is the appropriate type of
793 // ExternalArray. 771 // ExternalArray.
794 // eax: value 772 // eax: value
795 // edx: JSObject 773 // edx: receiver, a JSObject
796 // ebx: index (as a smi) 774 // ecx: key, a smi
797 __ mov(ecx, FieldOperand(edx, JSObject::kElementsOffset)); 775 __ mov(edi, FieldOperand(edx, JSObject::kElementsOffset));
798 Handle<Map> map(Heap::MapForExternalArrayType(array_type)); 776 __ CheckMap(edi, Handle<Map>(Heap::MapForExternalArrayType(array_type)),
799 __ cmp(FieldOperand(ecx, HeapObject::kMapOffset), 777 &slow, true);
800 Immediate(map));
801 __ j(not_equal, &slow);
802 778
803 // Check that the index is in range. 779 // Check that the index is in range.
804 __ sar(ebx, kSmiTagSize); // Untag the index. 780 __ mov(ebx, ecx);
805 __ cmp(ebx, FieldOperand(ecx, ExternalArray::kLengthOffset)); 781 __ SmiUntag(ebx);
782 __ cmp(ebx, FieldOperand(edi, ExternalArray::kLengthOffset));
806 // Unsigned comparison catches both negative and too-large values. 783 // Unsigned comparison catches both negative and too-large values.
807 __ j(above_equal, &slow); 784 __ j(above_equal, &slow);
808 785
809 // Handle both smis and HeapNumbers in the fast path. Go to the 786 // Handle both smis and HeapNumbers in the fast path. Go to the
810 // runtime for all other kinds of values. 787 // runtime for all other kinds of values.
811 // eax: value 788 // eax: value
812 // ecx: elements array 789 // edx: receiver
790 // ecx: key
791 // edi: elements array
813 // ebx: untagged index 792 // ebx: untagged index
814 __ test(eax, Immediate(kSmiTagMask)); 793 __ test(eax, Immediate(kSmiTagMask));
815 __ j(not_equal, &check_heap_number); 794 __ j(not_equal, &check_heap_number);
816 // smi case 795 // smi case
817 __ mov(edx, eax); // Save the value. 796 __ mov(ecx, eax); // Preserve the value in eax. Key is no longer needed.
818 __ sar(eax, kSmiTagSize); // Untag the value. 797 __ SmiUntag(ecx);
819 __ mov(ecx, FieldOperand(ecx, ExternalArray::kExternalPointerOffset)); 798 __ mov(edi, FieldOperand(edi, ExternalArray::kExternalPointerOffset));
820 // ecx: base pointer of external storage 799 // ecx: base pointer of external storage
821 switch (array_type) { 800 switch (array_type) {
822 case kExternalByteArray: 801 case kExternalByteArray:
823 case kExternalUnsignedByteArray: 802 case kExternalUnsignedByteArray:
824 __ mov_b(Operand(ecx, ebx, times_1, 0), eax); 803 __ mov_b(Operand(edi, ebx, times_1, 0), ecx);
825 break; 804 break;
826 case kExternalShortArray: 805 case kExternalShortArray:
827 case kExternalUnsignedShortArray: 806 case kExternalUnsignedShortArray:
828 __ mov_w(Operand(ecx, ebx, times_2, 0), eax); 807 __ mov_w(Operand(edi, ebx, times_2, 0), ecx);
829 break; 808 break;
830 case kExternalIntArray: 809 case kExternalIntArray:
831 case kExternalUnsignedIntArray: 810 case kExternalUnsignedIntArray:
832 __ mov(Operand(ecx, ebx, times_4, 0), eax); 811 __ mov(Operand(edi, ebx, times_4, 0), ecx);
833 break; 812 break;
834 case kExternalFloatArray: 813 case kExternalFloatArray:
835 // Need to perform int-to-float conversion. 814 // Need to perform int-to-float conversion.
836 __ push(eax); 815 __ push(ecx);
837 __ fild_s(Operand(esp, 0)); 816 __ fild_s(Operand(esp, 0));
838 __ pop(eax); 817 __ pop(ecx);
839 __ fstp_s(Operand(ecx, ebx, times_4, 0)); 818 __ fstp_s(Operand(edi, ebx, times_4, 0));
840 break; 819 break;
841 default: 820 default:
842 UNREACHABLE(); 821 UNREACHABLE();
843 break; 822 break;
844 } 823 }
845 __ mov(eax, edx); // Return the original value. 824 __ ret(0); // Return the original value.
846 __ ret(0);
847 825
848 __ bind(&check_heap_number); 826 __ bind(&check_heap_number);
827 // eax: value
828 // edx: receiver
829 // ecx: key
830 // edi: elements array
831 // ebx: untagged index
849 __ cmp(FieldOperand(eax, HeapObject::kMapOffset), 832 __ cmp(FieldOperand(eax, HeapObject::kMapOffset),
850 Immediate(Factory::heap_number_map())); 833 Immediate(Factory::heap_number_map()));
851 __ j(not_equal, &slow); 834 __ j(not_equal, &slow);
852 835
853 // The WebGL specification leaves the behavior of storing NaN and 836 // The WebGL specification leaves the behavior of storing NaN and
854 // +/-Infinity into integer arrays basically undefined. For more 837 // +/-Infinity into integer arrays basically undefined. For more
855 // reproducible behavior, convert these to zero. 838 // reproducible behavior, convert these to zero.
856 __ fld_d(FieldOperand(eax, HeapNumber::kValueOffset)); 839 __ fld_d(FieldOperand(eax, HeapNumber::kValueOffset));
857 __ mov(edx, eax); // Save the value. 840 __ mov(edi, FieldOperand(edi, ExternalArray::kExternalPointerOffset));
858 __ mov(ecx, FieldOperand(ecx, ExternalArray::kExternalPointerOffset));
859 // ebx: untagged index 841 // ebx: untagged index
860 // ecx: base pointer of external storage 842 // edi: base pointer of external storage
861 // top of FPU stack: value 843 // top of FPU stack: value
862 if (array_type == kExternalFloatArray) { 844 if (array_type == kExternalFloatArray) {
863 __ fstp_s(Operand(ecx, ebx, times_4, 0)); 845 __ fstp_s(Operand(edi, ebx, times_4, 0));
864 __ mov(eax, edx); // Return the original value.
865 __ ret(0); 846 __ ret(0);
866 } else { 847 } else {
867 // Need to perform float-to-int conversion. 848 // Need to perform float-to-int conversion.
868 // Test the top of the FP stack for NaN. 849 // Test the top of the FP stack for NaN.
869 Label is_nan; 850 Label is_nan;
870 __ fucomi(0); 851 __ fucomi(0);
871 __ j(parity_even, &is_nan); 852 __ j(parity_even, &is_nan);
872 853
873 if (array_type != kExternalUnsignedIntArray) { 854 if (array_type != kExternalUnsignedIntArray) {
874 __ push(eax); // Make room on stack 855 __ push(ecx); // Make room on stack
875 __ fistp_s(Operand(esp, 0)); 856 __ fistp_s(Operand(esp, 0));
876 __ pop(eax); 857 __ pop(ecx);
877 } else { 858 } else {
878 // fistp stores values as signed integers. 859 // fistp stores values as signed integers.
879 // To represent the entire range, we need to store as a 64-bit 860 // To represent the entire range, we need to store as a 64-bit
880 // int and discard the high 32 bits. 861 // int and discard the high 32 bits.
881 __ push(eax); // Make room on stack 862 __ sub(Operand(esp), Immediate(2 * kPointerSize));
882 __ push(eax); // Make room on stack
883 __ fistp_d(Operand(esp, 0)); 863 __ fistp_d(Operand(esp, 0));
884 __ pop(eax); 864 __ pop(ecx);
885 __ mov(Operand(esp, 0), eax); 865 __ add(Operand(esp), Immediate(kPointerSize));
886 __ pop(eax);
887 } 866 }
888 // eax: untagged integer value 867 // ecx: untagged integer value
889 switch (array_type) { 868 switch (array_type) {
890 case kExternalByteArray: 869 case kExternalByteArray:
891 case kExternalUnsignedByteArray: 870 case kExternalUnsignedByteArray:
892 __ mov_b(Operand(ecx, ebx, times_1, 0), eax); 871 __ mov_b(Operand(edi, ebx, times_1, 0), ecx);
893 break; 872 break;
894 case kExternalShortArray: 873 case kExternalShortArray:
895 case kExternalUnsignedShortArray: 874 case kExternalUnsignedShortArray:
896 __ mov_w(Operand(ecx, ebx, times_2, 0), eax); 875 __ mov_w(Operand(edi, ebx, times_2, 0), ecx);
897 break; 876 break;
898 case kExternalIntArray: 877 case kExternalIntArray:
899 case kExternalUnsignedIntArray: { 878 case kExternalUnsignedIntArray: {
900 // We also need to explicitly check for +/-Infinity. These are 879 // We also need to explicitly check for +/-Infinity. These are
901 // converted to MIN_INT, but we need to be careful not to 880 // converted to MIN_INT, but we need to be careful not to
902 // confuse with legal uses of MIN_INT. 881 // confuse with legal uses of MIN_INT.
903 Label not_infinity; 882 Label not_infinity;
904 // This test would apparently detect both NaN and Infinity, 883 // This test would apparently detect both NaN and Infinity,
905 // but we've already checked for NaN using the FPU hardware 884 // but we've already checked for NaN using the FPU hardware
906 // above. 885 // above.
907 __ mov_w(edi, FieldOperand(edx, HeapNumber::kValueOffset + 6)); 886 __ mov_w(edx, FieldOperand(eax, HeapNumber::kValueOffset + 6));
908 __ and_(edi, 0x7FF0); 887 __ and_(edx, 0x7FF0);
909 __ cmp(edi, 0x7FF0); 888 __ cmp(edx, 0x7FF0);
910 __ j(not_equal, &not_infinity); 889 __ j(not_equal, &not_infinity);
911 __ mov(eax, 0); 890 __ mov(ecx, 0);
912 __ bind(&not_infinity); 891 __ bind(&not_infinity);
913 __ mov(Operand(ecx, ebx, times_4, 0), eax); 892 __ mov(Operand(edi, ebx, times_4, 0), ecx);
914 break; 893 break;
915 } 894 }
916 default: 895 default:
917 UNREACHABLE(); 896 UNREACHABLE();
918 break; 897 break;
919 } 898 }
920 __ mov(eax, edx); // Return the original value. 899 __ ret(0); // Return original value.
921 __ ret(0);
922 900
923 __ bind(&is_nan); 901 __ bind(&is_nan);
924 __ ffree(); 902 __ ffree();
925 __ fincstp(); 903 __ fincstp();
926 switch (array_type) { 904 switch (array_type) {
927 case kExternalByteArray: 905 case kExternalByteArray:
928 case kExternalUnsignedByteArray: 906 case kExternalUnsignedByteArray:
929 __ mov_b(Operand(ecx, ebx, times_1, 0), 0); 907 __ mov_b(Operand(edi, ebx, times_1, 0), 0);
930 break; 908 break;
931 case kExternalShortArray: 909 case kExternalShortArray:
932 case kExternalUnsignedShortArray: 910 case kExternalUnsignedShortArray:
933 __ mov(eax, 0); 911 __ xor_(ecx, Operand(ecx));
934 __ mov_w(Operand(ecx, ebx, times_2, 0), eax); 912 __ mov_w(Operand(edi, ebx, times_2, 0), ecx);
935 break; 913 break;
936 case kExternalIntArray: 914 case kExternalIntArray:
937 case kExternalUnsignedIntArray: 915 case kExternalUnsignedIntArray:
938 __ mov(Operand(ecx, ebx, times_4, 0), Immediate(0)); 916 __ mov(Operand(edi, ebx, times_4, 0), Immediate(0));
939 break; 917 break;
940 default: 918 default:
941 UNREACHABLE(); 919 UNREACHABLE();
942 break; 920 break;
943 } 921 }
944 __ mov(eax, edx); // Return the original value. 922 __ ret(0); // Return the original value.
945 __ ret(0);
946 } 923 }
947 924
948 // Slow case: call runtime. 925 // Slow case: call runtime.
949 __ bind(&slow); 926 __ bind(&slow);
950 GenerateRuntimeSetProperty(masm); 927 GenerateRuntimeSetProperty(masm);
951 } 928 }
952 929
953 930
954 // Defined in ic.cc. 931 // Defined in ic.cc.
955 Object* CallIC_Miss(Arguments args); 932 Object* CallIC_Miss(Arguments args);
(...skipping 534 matching lines...) Expand 10 before | Expand all | Expand 10 after
1490 GenerateMiss(masm); 1467 GenerateMiss(masm);
1491 } 1468 }
1492 1469
1493 1470
1494 // Defined in ic.cc. 1471 // Defined in ic.cc.
1495 Object* KeyedStoreIC_Miss(Arguments args); 1472 Object* KeyedStoreIC_Miss(Arguments args);
1496 1473
1497 void KeyedStoreIC::GenerateRuntimeSetProperty(MacroAssembler* masm) { 1474 void KeyedStoreIC::GenerateRuntimeSetProperty(MacroAssembler* masm) {
1498 // ----------- S t a t e ------------- 1475 // ----------- S t a t e -------------
1499 // -- eax : value 1476 // -- eax : value
1477 // -- ecx : key
1478 // -- edx : receiver
1500 // -- esp[0] : return address 1479 // -- esp[0] : return address
1501 // -- esp[4] : key
1502 // -- esp[8] : receiver
1503 // ----------------------------------- 1480 // -----------------------------------
1504 1481
1505 __ pop(ecx); 1482 __ pop(ebx);
1506 __ push(Operand(esp, 1 * kPointerSize)); 1483 __ push(edx);
1507 __ push(Operand(esp, 1 * kPointerSize)); 1484 __ push(ecx);
1508 __ push(eax); 1485 __ push(eax);
1509 __ push(ecx); 1486 __ push(ebx);
1510 1487
1511 // Do tail-call to runtime routine. 1488 // Do tail-call to runtime routine.
1512 __ TailCallRuntime(Runtime::kSetProperty, 3, 1); 1489 __ TailCallRuntime(Runtime::kSetProperty, 3, 1);
1513 } 1490 }
1514 1491
1515 1492
1516 void KeyedStoreIC::GenerateMiss(MacroAssembler* masm) { 1493 void KeyedStoreIC::GenerateMiss(MacroAssembler* masm) {
1517 // ----------- S t a t e ------------- 1494 // ----------- S t a t e -------------
1518 // -- eax : value 1495 // -- eax : value
1496 // -- ecx : key
1497 // -- edx : receiver
1519 // -- esp[0] : return address 1498 // -- esp[0] : return address
1520 // -- esp[4] : key
1521 // -- esp[8] : receiver
1522 // ----------------------------------- 1499 // -----------------------------------
1523 1500
1524 __ pop(ecx); 1501 __ pop(ebx);
1525 __ push(Operand(esp, 1 * kPointerSize)); 1502 __ push(edx);
1526 __ push(Operand(esp, 1 * kPointerSize)); 1503 __ push(ecx);
1527 __ push(eax); 1504 __ push(eax);
1528 __ push(ecx); 1505 __ push(ebx);
1529 1506
1530 // Do tail-call to runtime routine. 1507 // Do tail-call to runtime routine.
1531 ExternalReference ref = ExternalReference(IC_Utility(kKeyedStoreIC_Miss)); 1508 ExternalReference ref = ExternalReference(IC_Utility(kKeyedStoreIC_Miss));
1532 __ TailCallExternalReference(ref, 3, 1); 1509 __ TailCallExternalReference(ref, 3, 1);
1533 } 1510 }
1534 1511
1535 #undef __ 1512 #undef __
1536 1513
1537 1514
1538 } } // namespace v8::internal 1515 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/ia32/full-codegen-ia32.cc ('k') | src/ia32/stub-cache-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698