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

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

Issue 844006: Merge changes up to V8 version 2.1.3 into the partial snapshots (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/partial_snapshots/
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/jump-target-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 574 matching lines...) Expand 10 before | Expand all | Expand 10 after
585 __ cmp(Operand(ecx), Immediate(1 << Map::kHasIndexedInterceptor)); 585 __ cmp(Operand(ecx), Immediate(1 << Map::kHasIndexedInterceptor));
586 __ j(not_zero, &slow, not_taken); 586 __ j(not_zero, &slow, not_taken);
587 587
588 // Everything is fine, call runtime. 588 // Everything is fine, call runtime.
589 __ pop(ecx); 589 __ pop(ecx);
590 __ push(edx); // receiver 590 __ push(edx); // receiver
591 __ push(eax); // key 591 __ push(eax); // key
592 __ push(ecx); // return address 592 __ push(ecx); // return address
593 593
594 // Perform tail call to the entry. 594 // Perform tail call to the entry.
595 __ TailCallRuntime(ExternalReference( 595 ExternalReference ref = ExternalReference(
596 IC_Utility(kKeyedLoadPropertyWithInterceptor)), 2, 1); 596 IC_Utility(kKeyedLoadPropertyWithInterceptor));
597 __ TailCallExternalReference(ref, 2, 1);
597 598
598 __ bind(&slow); 599 __ bind(&slow);
599 GenerateMiss(masm); 600 GenerateMiss(masm);
600 } 601 }
601 602
602 603
603 void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm) { 604 void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm) {
604 // ----------- S t a t e ------------- 605 // ----------- S t a t e -------------
605 // -- eax : value 606 // -- eax : value
607 // -- ecx : key
608 // -- edx : receiver
606 // -- esp[0] : return address 609 // -- esp[0] : return address
607 // -- esp[4] : key
608 // -- esp[8] : receiver
609 // ----------------------------------- 610 // -----------------------------------
610 Label slow, fast, array, extra, check_pixel_array; 611 Label slow, fast, array, extra, check_pixel_array;
611 612
612 // Get the receiver from the stack.
613 __ mov(edx, Operand(esp, 2 * kPointerSize)); // 2 ~ return address, key
614 // Check that the object isn't a smi. 613 // Check that the object isn't a smi.
615 __ test(edx, Immediate(kSmiTagMask)); 614 __ test(edx, Immediate(kSmiTagMask));
616 __ j(zero, &slow, not_taken); 615 __ j(zero, &slow, not_taken);
617 // Get the map from the receiver. 616 // Get the map from the receiver.
618 __ mov(ecx, FieldOperand(edx, HeapObject::kMapOffset)); 617 __ mov(edi, FieldOperand(edx, HeapObject::kMapOffset));
619 // Check that the receiver does not require access checks. We need 618 // Check that the receiver does not require access checks. We need
620 // to do this because this generic stub does not perform map checks. 619 // to do this because this generic stub does not perform map checks.
621 __ movzx_b(ebx, FieldOperand(ecx, Map::kBitFieldOffset)); 620 __ movzx_b(ebx, FieldOperand(edi, Map::kBitFieldOffset));
622 __ test(ebx, Immediate(1 << Map::kIsAccessCheckNeeded)); 621 __ test(ebx, Immediate(1 << Map::kIsAccessCheckNeeded));
623 __ j(not_zero, &slow, not_taken); 622 __ j(not_zero, &slow, not_taken);
624 // Get the key from the stack.
625 __ mov(ebx, Operand(esp, 1 * kPointerSize)); // 1 ~ return address
626 // Check that the key is a smi. 623 // Check that the key is a smi.
627 __ test(ebx, Immediate(kSmiTagMask)); 624 __ test(ecx, Immediate(kSmiTagMask));
628 __ j(not_zero, &slow, not_taken); 625 __ j(not_zero, &slow, not_taken);
629 // Get the instance type from the map of the receiver. 626 __ CmpInstanceType(edi, JS_ARRAY_TYPE);
630 __ movzx_b(ecx, FieldOperand(ecx, Map::kInstanceTypeOffset));
631 // Check if the object is a JS array or not.
632 __ cmp(ecx, JS_ARRAY_TYPE);
633 __ j(equal, &array); 627 __ j(equal, &array);
634 // Check that the object is some kind of JS object. 628 // Check that the object is some kind of JS object.
635 __ cmp(ecx, FIRST_JS_OBJECT_TYPE); 629 __ CmpInstanceType(edi, FIRST_JS_OBJECT_TYPE);
636 __ j(less, &slow, not_taken); 630 __ j(below, &slow, not_taken);
637 631
638 // Object case: Check key against length in the elements array. 632 // Object case: Check key against length in the elements array.
639 // eax: value 633 // eax: value
640 // edx: JSObject 634 // edx: JSObject
641 // ebx: index (as a smi) 635 // ecx: key (a smi)
642 __ mov(ecx, FieldOperand(edx, JSObject::kElementsOffset)); 636 __ mov(edi, FieldOperand(edx, JSObject::kElementsOffset));
643 // Check that the object is in fast mode (not dictionary). 637 // Check that the object is in fast mode (not dictionary).
644 __ cmp(FieldOperand(ecx, HeapObject::kMapOffset), 638 __ CheckMap(edi, Factory::fixed_array_map(), &check_pixel_array, true);
645 Immediate(Factory::fixed_array_map())); 639 __ mov(ebx, Operand(ecx));
646 __ j(not_equal, &check_pixel_array, not_taken); 640 __ SmiUntag(ebx);
647 // Untag the key (for checking against untagged length in the fixed array). 641 __ cmp(ebx, FieldOperand(edi, Array::kLengthOffset));
648 __ mov(edx, Operand(ebx));
649 __ sar(edx, kSmiTagSize); // untag the index and use it for the comparison
650 __ cmp(edx, FieldOperand(ecx, Array::kLengthOffset));
651 // eax: value
652 // ecx: FixedArray
653 // ebx: index (as a smi)
654 __ j(below, &fast, taken); 642 __ j(below, &fast, taken);
655 643
656 // Slow case: call runtime. 644 // Slow case: call runtime.
657 __ bind(&slow); 645 __ bind(&slow);
658 GenerateRuntimeSetProperty(masm); 646 GenerateRuntimeSetProperty(masm);
659 647
660 // Check whether the elements is a pixel array. 648 // Check whether the elements is a pixel array.
649 __ bind(&check_pixel_array);
661 // eax: value 650 // eax: value
662 // ecx: elements array 651 // ecx: key
663 // ebx: index (as a smi) 652 // edx: receiver
664 __ bind(&check_pixel_array); 653 // edi: elements array
665 __ cmp(FieldOperand(ecx, HeapObject::kMapOffset), 654 __ CheckMap(edi, Factory::pixel_array_map(), &slow, true);
666 Immediate(Factory::pixel_array_map()));
667 __ j(not_equal, &slow);
668 // Check that the value is a smi. If a conversion is needed call into the 655 // Check that the value is a smi. If a conversion is needed call into the
669 // runtime to convert and clamp. 656 // runtime to convert and clamp.
670 __ test(eax, Immediate(kSmiTagMask)); 657 __ test(eax, Immediate(kSmiTagMask));
671 __ j(not_zero, &slow); 658 __ j(not_zero, &slow);
672 __ sar(ebx, kSmiTagSize); // Untag the index. 659 __ mov(ebx, ecx);
673 __ cmp(ebx, FieldOperand(ecx, PixelArray::kLengthOffset)); 660 __ SmiUntag(ebx);
661 __ cmp(ebx, FieldOperand(edi, PixelArray::kLengthOffset));
674 __ j(above_equal, &slow); 662 __ j(above_equal, &slow);
675 __ mov(edx, eax); // Save the value. 663 __ mov(ecx, eax); // Save the value. Key is not longer needed.
676 __ sar(eax, kSmiTagSize); // Untag the value. 664 __ SmiUntag(ecx);
677 { // Clamp the value to [0..255]. 665 { // Clamp the value to [0..255].
678 Label done; 666 Label done;
679 __ test(eax, Immediate(0xFFFFFF00)); 667 __ test(ecx, Immediate(0xFFFFFF00));
680 __ j(zero, &done); 668 __ j(zero, &done);
681 __ setcc(negative, eax); // 1 if negative, 0 if positive. 669 __ setcc(negative, ecx); // 1 if negative, 0 if positive.
682 __ dec_b(eax); // 0 if negative, 255 if positive. 670 __ dec_b(ecx); // 0 if negative, 255 if positive.
683 __ bind(&done); 671 __ bind(&done);
684 } 672 }
685 __ mov(ecx, FieldOperand(ecx, PixelArray::kExternalPointerOffset)); 673 __ mov(edi, FieldOperand(edi, PixelArray::kExternalPointerOffset));
686 __ mov_b(Operand(ecx, ebx, times_1, 0), eax); 674 __ mov_b(Operand(edi, ebx, times_1, 0), ecx);
687 __ mov(eax, edx); // Return the original value. 675 __ ret(0); // Return value in eax.
688 __ ret(0);
689 676
690 // Extra capacity case: Check if there is extra capacity to 677 // Extra capacity case: Check if there is extra capacity to
691 // perform the store and update the length. Used for adding one 678 // perform the store and update the length. Used for adding one
692 // element to the array by writing to array[array.length]. 679 // element to the array by writing to array[array.length].
693 __ bind(&extra); 680 __ bind(&extra);
694 // eax: value 681 // eax: value
695 // edx: JSArray 682 // edx: receiver, a JSArray
696 // ecx: FixedArray 683 // ecx: key, a smi.
697 // ebx: index (as a smi) 684 // edi: receiver->elements, a FixedArray
698 // flags: compare (ebx, edx.length()) 685 // flags: compare (ecx, edx.length())
699 __ j(not_equal, &slow, not_taken); // do not leave holes in the array 686 __ j(not_equal, &slow, not_taken); // do not leave holes in the array
700 __ sar(ebx, kSmiTagSize); // untag 687 __ mov(ebx, ecx);
701 __ cmp(ebx, FieldOperand(ecx, Array::kLengthOffset)); 688 __ SmiUntag(ebx); // untag
689 __ cmp(ebx, FieldOperand(edi, Array::kLengthOffset));
702 __ j(above_equal, &slow, not_taken); 690 __ j(above_equal, &slow, not_taken);
703 // Restore tag and increment. 691 // Add 1 to receiver->length, and go to fast array write.
704 __ lea(ebx, Operand(ebx, times_2, 1 << kSmiTagSize)); 692 __ add(FieldOperand(edx, JSArray::kLengthOffset),
705 __ mov(FieldOperand(edx, JSArray::kLengthOffset), ebx); 693 Immediate(1 << kSmiTagSize));
706 __ sub(Operand(ebx), Immediate(1 << kSmiTagSize)); // decrement ebx again
707 __ jmp(&fast); 694 __ jmp(&fast);
708 695
709 // Array case: Get the length and the elements array from the JS 696 // Array case: Get the length and the elements array from the JS
710 // array. Check that the array is in fast mode; if it is the 697 // array. Check that the array is in fast mode; if it is the
711 // length is always a smi. 698 // length is always a smi.
712 __ bind(&array); 699 __ bind(&array);
713 // eax: value 700 // eax: value
714 // edx: JSArray 701 // edx: receiver, a JSArray
715 // ebx: index (as a smi) 702 // ecx: key, a smi.
716 __ mov(ecx, FieldOperand(edx, JSObject::kElementsOffset)); 703 __ mov(edi, FieldOperand(edx, JSObject::kElementsOffset));
717 __ cmp(FieldOperand(ecx, HeapObject::kMapOffset), 704 __ CheckMap(edi, Factory::fixed_array_map(), &check_pixel_array, true);
718 Immediate(Factory::fixed_array_map()));
719 __ j(not_equal, &check_pixel_array);
720 705
721 // Check the key against the length in the array, compute the 706 // Check the key against the length in the array, compute the
722 // address to store into and fall through to fast case. 707 // address to store into and fall through to fast case.
723 __ cmp(ebx, FieldOperand(edx, JSArray::kLengthOffset)); 708 __ cmp(ecx, FieldOperand(edx, JSArray::kLengthOffset)); // Compare smis.
724 __ j(above_equal, &extra, not_taken); 709 __ j(above_equal, &extra, not_taken);
725 710
726 // Fast case: Do the store. 711 // Fast case: Do the store.
727 __ bind(&fast); 712 __ bind(&fast);
728 // eax: value 713 // eax: value
729 // ecx: FixedArray 714 // ecx: key (a smi)
730 // ebx: index (as a smi) 715 // edx: receiver
731 __ mov(Operand(ecx, ebx, times_2, FixedArray::kHeaderSize - kHeapObjectTag), 716 // edi: FixedArray receiver->elements
732 eax); 717 __ mov(FieldOperand(edi, ecx, times_2, FixedArray::kHeaderSize), eax);
733 // Update write barrier for the elements array address. 718 // Update write barrier for the elements array address.
734 __ mov(edx, Operand(eax)); 719 __ mov(edx, Operand(eax));
735 __ RecordWrite(ecx, 0, edx, ebx); 720 __ RecordWrite(edi, 0, edx, ecx);
736 __ ret(0); 721 __ ret(0);
737 } 722 }
738 723
739 724
740 void KeyedStoreIC::GenerateExternalArray(MacroAssembler* masm, 725 void KeyedStoreIC::GenerateExternalArray(MacroAssembler* masm,
741 ExternalArrayType array_type) { 726 ExternalArrayType array_type) {
742 // ----------- S t a t e ------------- 727 // ----------- S t a t e -------------
743 // -- eax : value 728 // -- eax : value
729 // -- ecx : key
730 // -- edx : receiver
744 // -- esp[0] : return address 731 // -- esp[0] : return address
745 // -- esp[4] : key
746 // -- esp[8] : receiver
747 // ----------------------------------- 732 // -----------------------------------
748 Label slow, check_heap_number; 733 Label slow, check_heap_number;
749 734
750 // Get the receiver from the stack.
751 __ mov(edx, Operand(esp, 2 * kPointerSize));
752 // Check that the object isn't a smi. 735 // Check that the object isn't a smi.
753 __ test(edx, Immediate(kSmiTagMask)); 736 __ test(edx, Immediate(kSmiTagMask));
754 __ j(zero, &slow); 737 __ j(zero, &slow);
755 // Get the map from the receiver. 738 // Get the map from the receiver.
756 __ mov(ecx, FieldOperand(edx, HeapObject::kMapOffset)); 739 __ mov(edi, FieldOperand(edx, HeapObject::kMapOffset));
757 // Check that the receiver does not require access checks. We need 740 // Check that the receiver does not require access checks. We need
758 // to do this because this generic stub does not perform map checks. 741 // to do this because this generic stub does not perform map checks.
759 __ movzx_b(ebx, FieldOperand(ecx, Map::kBitFieldOffset)); 742 __ movzx_b(ebx, FieldOperand(edi, Map::kBitFieldOffset));
760 __ test(ebx, Immediate(1 << Map::kIsAccessCheckNeeded)); 743 __ test(ebx, Immediate(1 << Map::kIsAccessCheckNeeded));
761 __ j(not_zero, &slow); 744 __ j(not_zero, &slow);
762 // Get the key from the stack.
763 __ mov(ebx, Operand(esp, 1 * kPointerSize)); // 1 ~ return address
764 // Check that the key is a smi. 745 // Check that the key is a smi.
765 __ test(ebx, Immediate(kSmiTagMask)); 746 __ test(ecx, Immediate(kSmiTagMask));
766 __ j(not_zero, &slow); 747 __ j(not_zero, &slow);
767 // Get the instance type from the map of the receiver. 748 // Get the instance type from the map of the receiver.
768 __ movzx_b(ecx, FieldOperand(ecx, Map::kInstanceTypeOffset)); 749 __ CmpInstanceType(edi, JS_OBJECT_TYPE);
769 // Check that the object is a JS object.
770 __ cmp(ecx, JS_OBJECT_TYPE);
771 __ j(not_equal, &slow); 750 __ j(not_equal, &slow);
772 751
773 // Check that the elements array is the appropriate type of 752 // Check that the elements array is the appropriate type of
774 // ExternalArray. 753 // ExternalArray.
775 // eax: value 754 // eax: value
776 // edx: JSObject 755 // edx: receiver, a JSObject
777 // ebx: index (as a smi) 756 // ecx: key, a smi
778 __ mov(ecx, FieldOperand(edx, JSObject::kElementsOffset)); 757 __ mov(edi, FieldOperand(edx, JSObject::kElementsOffset));
779 Handle<Map> map(Heap::MapForExternalArrayType(array_type)); 758 __ CheckMap(edi, Handle<Map>(Heap::MapForExternalArrayType(array_type)),
780 __ cmp(FieldOperand(ecx, HeapObject::kMapOffset), 759 &slow, true);
781 Immediate(map));
782 __ j(not_equal, &slow);
783 760
784 // Check that the index is in range. 761 // Check that the index is in range.
785 __ sar(ebx, kSmiTagSize); // Untag the index. 762 __ mov(ebx, ecx);
786 __ cmp(ebx, FieldOperand(ecx, ExternalArray::kLengthOffset)); 763 __ SmiUntag(ebx);
764 __ cmp(ebx, FieldOperand(edi, ExternalArray::kLengthOffset));
787 // Unsigned comparison catches both negative and too-large values. 765 // Unsigned comparison catches both negative and too-large values.
788 __ j(above_equal, &slow); 766 __ j(above_equal, &slow);
789 767
790 // Handle both smis and HeapNumbers in the fast path. Go to the 768 // Handle both smis and HeapNumbers in the fast path. Go to the
791 // runtime for all other kinds of values. 769 // runtime for all other kinds of values.
792 // eax: value 770 // eax: value
793 // ecx: elements array 771 // edx: receiver
772 // ecx: key
773 // edi: elements array
794 // ebx: untagged index 774 // ebx: untagged index
795 __ test(eax, Immediate(kSmiTagMask)); 775 __ test(eax, Immediate(kSmiTagMask));
796 __ j(not_equal, &check_heap_number); 776 __ j(not_equal, &check_heap_number);
797 // smi case 777 // smi case
798 __ mov(edx, eax); // Save the value. 778 __ mov(ecx, eax); // Preserve the value in eax. Key is no longer needed.
799 __ sar(eax, kSmiTagSize); // Untag the value. 779 __ SmiUntag(ecx);
800 __ mov(ecx, FieldOperand(ecx, ExternalArray::kExternalPointerOffset)); 780 __ mov(edi, FieldOperand(edi, ExternalArray::kExternalPointerOffset));
801 // ecx: base pointer of external storage 781 // ecx: base pointer of external storage
802 switch (array_type) { 782 switch (array_type) {
803 case kExternalByteArray: 783 case kExternalByteArray:
804 case kExternalUnsignedByteArray: 784 case kExternalUnsignedByteArray:
805 __ mov_b(Operand(ecx, ebx, times_1, 0), eax); 785 __ mov_b(Operand(edi, ebx, times_1, 0), ecx);
806 break; 786 break;
807 case kExternalShortArray: 787 case kExternalShortArray:
808 case kExternalUnsignedShortArray: 788 case kExternalUnsignedShortArray:
809 __ mov_w(Operand(ecx, ebx, times_2, 0), eax); 789 __ mov_w(Operand(edi, ebx, times_2, 0), ecx);
810 break; 790 break;
811 case kExternalIntArray: 791 case kExternalIntArray:
812 case kExternalUnsignedIntArray: 792 case kExternalUnsignedIntArray:
813 __ mov(Operand(ecx, ebx, times_4, 0), eax); 793 __ mov(Operand(edi, ebx, times_4, 0), ecx);
814 break; 794 break;
815 case kExternalFloatArray: 795 case kExternalFloatArray:
816 // Need to perform int-to-float conversion. 796 // Need to perform int-to-float conversion.
817 __ push(eax); 797 __ push(ecx);
818 __ fild_s(Operand(esp, 0)); 798 __ fild_s(Operand(esp, 0));
819 __ pop(eax); 799 __ pop(ecx);
820 __ fstp_s(Operand(ecx, ebx, times_4, 0)); 800 __ fstp_s(Operand(edi, ebx, times_4, 0));
821 break; 801 break;
822 default: 802 default:
823 UNREACHABLE(); 803 UNREACHABLE();
824 break; 804 break;
825 } 805 }
826 __ mov(eax, edx); // Return the original value. 806 __ ret(0); // Return the original value.
827 __ ret(0);
828 807
829 __ bind(&check_heap_number); 808 __ bind(&check_heap_number);
809 // eax: value
810 // edx: receiver
811 // ecx: key
812 // edi: elements array
813 // ebx: untagged index
830 __ cmp(FieldOperand(eax, HeapObject::kMapOffset), 814 __ cmp(FieldOperand(eax, HeapObject::kMapOffset),
831 Immediate(Factory::heap_number_map())); 815 Immediate(Factory::heap_number_map()));
832 __ j(not_equal, &slow); 816 __ j(not_equal, &slow);
833 817
834 // The WebGL specification leaves the behavior of storing NaN and 818 // The WebGL specification leaves the behavior of storing NaN and
835 // +/-Infinity into integer arrays basically undefined. For more 819 // +/-Infinity into integer arrays basically undefined. For more
836 // reproducible behavior, convert these to zero. 820 // reproducible behavior, convert these to zero.
837 __ fld_d(FieldOperand(eax, HeapNumber::kValueOffset)); 821 __ fld_d(FieldOperand(eax, HeapNumber::kValueOffset));
838 __ mov(edx, eax); // Save the value. 822 __ mov(edi, FieldOperand(edi, ExternalArray::kExternalPointerOffset));
839 __ mov(ecx, FieldOperand(ecx, ExternalArray::kExternalPointerOffset));
840 // ebx: untagged index 823 // ebx: untagged index
841 // ecx: base pointer of external storage 824 // edi: base pointer of external storage
842 // top of FPU stack: value 825 // top of FPU stack: value
843 if (array_type == kExternalFloatArray) { 826 if (array_type == kExternalFloatArray) {
844 __ fstp_s(Operand(ecx, ebx, times_4, 0)); 827 __ fstp_s(Operand(edi, ebx, times_4, 0));
845 __ mov(eax, edx); // Return the original value.
846 __ ret(0); 828 __ ret(0);
847 } else { 829 } else {
848 // Need to perform float-to-int conversion. 830 // Need to perform float-to-int conversion.
849 // Test the top of the FP stack for NaN. 831 // Test the top of the FP stack for NaN.
850 Label is_nan; 832 Label is_nan;
851 __ fucomi(0); 833 __ fucomi(0);
852 __ j(parity_even, &is_nan); 834 __ j(parity_even, &is_nan);
853 835
854 if (array_type != kExternalUnsignedIntArray) { 836 if (array_type != kExternalUnsignedIntArray) {
855 __ push(eax); // Make room on stack 837 __ push(ecx); // Make room on stack
856 __ fistp_s(Operand(esp, 0)); 838 __ fistp_s(Operand(esp, 0));
857 __ pop(eax); 839 __ pop(ecx);
858 } else { 840 } else {
859 // fistp stores values as signed integers. 841 // fistp stores values as signed integers.
860 // To represent the entire range, we need to store as a 64-bit 842 // To represent the entire range, we need to store as a 64-bit
861 // int and discard the high 32 bits. 843 // int and discard the high 32 bits.
862 __ push(eax); // Make room on stack 844 __ sub(Operand(esp), Immediate(2 * kPointerSize));
863 __ push(eax); // Make room on stack
864 __ fistp_d(Operand(esp, 0)); 845 __ fistp_d(Operand(esp, 0));
865 __ pop(eax); 846 __ pop(ecx);
866 __ mov(Operand(esp, 0), eax); 847 __ add(Operand(esp), Immediate(kPointerSize));
867 __ pop(eax);
868 } 848 }
869 // eax: untagged integer value 849 // ecx: untagged integer value
870 switch (array_type) { 850 switch (array_type) {
871 case kExternalByteArray: 851 case kExternalByteArray:
872 case kExternalUnsignedByteArray: 852 case kExternalUnsignedByteArray:
873 __ mov_b(Operand(ecx, ebx, times_1, 0), eax); 853 __ mov_b(Operand(edi, ebx, times_1, 0), ecx);
874 break; 854 break;
875 case kExternalShortArray: 855 case kExternalShortArray:
876 case kExternalUnsignedShortArray: 856 case kExternalUnsignedShortArray:
877 __ mov_w(Operand(ecx, ebx, times_2, 0), eax); 857 __ mov_w(Operand(edi, ebx, times_2, 0), ecx);
878 break; 858 break;
879 case kExternalIntArray: 859 case kExternalIntArray:
880 case kExternalUnsignedIntArray: { 860 case kExternalUnsignedIntArray: {
881 // We also need to explicitly check for +/-Infinity. These are 861 // We also need to explicitly check for +/-Infinity. These are
882 // converted to MIN_INT, but we need to be careful not to 862 // converted to MIN_INT, but we need to be careful not to
883 // confuse with legal uses of MIN_INT. 863 // confuse with legal uses of MIN_INT.
884 Label not_infinity; 864 Label not_infinity;
885 // This test would apparently detect both NaN and Infinity, 865 // This test would apparently detect both NaN and Infinity,
886 // but we've already checked for NaN using the FPU hardware 866 // but we've already checked for NaN using the FPU hardware
887 // above. 867 // above.
888 __ mov_w(edi, FieldOperand(edx, HeapNumber::kValueOffset + 6)); 868 __ mov_w(edx, FieldOperand(eax, HeapNumber::kValueOffset + 6));
889 __ and_(edi, 0x7FF0); 869 __ and_(edx, 0x7FF0);
890 __ cmp(edi, 0x7FF0); 870 __ cmp(edx, 0x7FF0);
891 __ j(not_equal, &not_infinity); 871 __ j(not_equal, &not_infinity);
892 __ mov(eax, 0); 872 __ mov(ecx, 0);
893 __ bind(&not_infinity); 873 __ bind(&not_infinity);
894 __ mov(Operand(ecx, ebx, times_4, 0), eax); 874 __ mov(Operand(edi, ebx, times_4, 0), ecx);
895 break; 875 break;
896 } 876 }
897 default: 877 default:
898 UNREACHABLE(); 878 UNREACHABLE();
899 break; 879 break;
900 } 880 }
901 __ mov(eax, edx); // Return the original value. 881 __ ret(0); // Return original value.
902 __ ret(0);
903 882
904 __ bind(&is_nan); 883 __ bind(&is_nan);
905 __ ffree(); 884 __ ffree();
906 __ fincstp(); 885 __ fincstp();
907 switch (array_type) { 886 switch (array_type) {
908 case kExternalByteArray: 887 case kExternalByteArray:
909 case kExternalUnsignedByteArray: 888 case kExternalUnsignedByteArray:
910 __ mov_b(Operand(ecx, ebx, times_1, 0), 0); 889 __ mov_b(Operand(edi, ebx, times_1, 0), 0);
911 break; 890 break;
912 case kExternalShortArray: 891 case kExternalShortArray:
913 case kExternalUnsignedShortArray: 892 case kExternalUnsignedShortArray:
914 __ mov(eax, 0); 893 __ xor_(ecx, Operand(ecx));
915 __ mov_w(Operand(ecx, ebx, times_2, 0), eax); 894 __ mov_w(Operand(edi, ebx, times_2, 0), ecx);
916 break; 895 break;
917 case kExternalIntArray: 896 case kExternalIntArray:
918 case kExternalUnsignedIntArray: 897 case kExternalUnsignedIntArray:
919 __ mov(Operand(ecx, ebx, times_4, 0), Immediate(0)); 898 __ mov(Operand(edi, ebx, times_4, 0), Immediate(0));
920 break; 899 break;
921 default: 900 default:
922 UNREACHABLE(); 901 UNREACHABLE();
923 break; 902 break;
924 } 903 }
925 __ mov(eax, edx); // Return the original value. 904 __ ret(0); // Return the original value.
926 __ ret(0);
927 } 905 }
928 906
929 // Slow case: call runtime. 907 // Slow case: call runtime.
930 __ bind(&slow); 908 __ bind(&slow);
931 GenerateRuntimeSetProperty(masm); 909 GenerateRuntimeSetProperty(masm);
932 } 910 }
933 911
934 912
935 // Defined in ic.cc. 913 // Defined in ic.cc.
936 Object* CallIC_Miss(Arguments args); 914 Object* CallIC_Miss(Arguments args);
(...skipping 294 matching lines...) Expand 10 before | Expand all | Expand 10 after
1231 // -- ecx : name 1209 // -- ecx : name
1232 // -- esp[0] : return address 1210 // -- esp[0] : return address
1233 // ----------------------------------- 1211 // -----------------------------------
1234 1212
1235 __ pop(ebx); 1213 __ pop(ebx);
1236 __ push(eax); // receiver 1214 __ push(eax); // receiver
1237 __ push(ecx); // name 1215 __ push(ecx); // name
1238 __ push(ebx); // return address 1216 __ push(ebx); // return address
1239 1217
1240 // Perform tail call to the entry. 1218 // Perform tail call to the entry.
1241 __ TailCallRuntime(ExternalReference(IC_Utility(kLoadIC_Miss)), 2, 1); 1219 ExternalReference ref = ExternalReference(IC_Utility(kLoadIC_Miss));
1220 __ TailCallExternalReference(ref, 2, 1);
1242 } 1221 }
1243 1222
1244 1223
1245 // One byte opcode for test eax,0xXXXXXXXX. 1224 // One byte opcode for test eax,0xXXXXXXXX.
1246 static const byte kTestEaxByte = 0xA9; 1225 static const byte kTestEaxByte = 0xA9;
1247 1226
1248 1227
1249 void LoadIC::ClearInlinedVersion(Address address) { 1228 void LoadIC::ClearInlinedVersion(Address address) {
1250 // Reset the map check of the inlined inobject property load (if 1229 // Reset the map check of the inlined inobject property load (if
1251 // present) to guarantee failure by holding an invalid map (the null 1230 // present) to guarantee failure by holding an invalid map (the null
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
1346 // -- edx : receiver 1325 // -- edx : receiver
1347 // -- esp[0] : return address 1326 // -- esp[0] : return address
1348 // ----------------------------------- 1327 // -----------------------------------
1349 1328
1350 __ pop(ebx); 1329 __ pop(ebx);
1351 __ push(edx); // receiver 1330 __ push(edx); // receiver
1352 __ push(eax); // name 1331 __ push(eax); // name
1353 __ push(ebx); // return address 1332 __ push(ebx); // return address
1354 1333
1355 // Perform tail call to the entry. 1334 // Perform tail call to the entry.
1356 __ TailCallRuntime(ExternalReference(IC_Utility(kKeyedLoadIC_Miss)), 2, 1); 1335 ExternalReference ref = ExternalReference(IC_Utility(kKeyedLoadIC_Miss));
1336 __ TailCallExternalReference(ref, 2, 1);
1357 } 1337 }
1358 1338
1359 1339
1360 void KeyedLoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) { 1340 void KeyedLoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) {
1361 // ----------- S t a t e ------------- 1341 // ----------- S t a t e -------------
1362 // -- eax : key 1342 // -- eax : key
1363 // -- edx : receiver 1343 // -- edx : receiver
1364 // -- esp[0] : return address 1344 // -- esp[0] : return address
1365 // ----------------------------------- 1345 // -----------------------------------
1366 1346
1367 __ pop(ebx); 1347 __ pop(ebx);
1368 __ push(edx); // receiver 1348 __ push(edx); // receiver
1369 __ push(eax); // name 1349 __ push(eax); // name
1370 __ push(ebx); // return address 1350 __ push(ebx); // return address
1371 1351
1372 // Perform tail call to the entry. 1352 // Perform tail call to the entry.
1373 __ TailCallRuntime(ExternalReference(Runtime::kKeyedGetProperty), 2, 1); 1353 __ TailCallRuntime(Runtime::kKeyedGetProperty, 2, 1);
1374 } 1354 }
1375 1355
1376 1356
1377 void StoreIC::GenerateMegamorphic(MacroAssembler* masm) { 1357 void StoreIC::GenerateMegamorphic(MacroAssembler* masm) {
1378 // ----------- S t a t e ------------- 1358 // ----------- S t a t e -------------
1379 // -- eax : value 1359 // -- eax : value
1380 // -- ecx : name 1360 // -- ecx : name
1381 // -- edx : receiver 1361 // -- edx : receiver
1382 // -- esp[0] : return address 1362 // -- esp[0] : return address
1383 // ----------------------------------- 1363 // -----------------------------------
(...skipping 16 matching lines...) Expand all
1400 // -- esp[0] : return address 1380 // -- esp[0] : return address
1401 // ----------------------------------- 1381 // -----------------------------------
1402 1382
1403 __ pop(ebx); 1383 __ pop(ebx);
1404 __ push(edx); 1384 __ push(edx);
1405 __ push(ecx); 1385 __ push(ecx);
1406 __ push(eax); 1386 __ push(eax);
1407 __ push(ebx); 1387 __ push(ebx);
1408 1388
1409 // Perform tail call to the entry. 1389 // Perform tail call to the entry.
1410 __ TailCallRuntime(ExternalReference(IC_Utility(kStoreIC_Miss)), 3, 1); 1390 ExternalReference ref = ExternalReference(IC_Utility(kStoreIC_Miss));
1391 __ TailCallExternalReference(ref, 3, 1);
1411 } 1392 }
1412 1393
1413 1394
1414 void StoreIC::GenerateArrayLength(MacroAssembler* masm) { 1395 void StoreIC::GenerateArrayLength(MacroAssembler* masm) {
1415 // ----------- S t a t e ------------- 1396 // ----------- S t a t e -------------
1416 // -- eax : value 1397 // -- eax : value
1417 // -- ecx : name 1398 // -- ecx : name
1418 // -- edx : receiver 1399 // -- edx : receiver
1419 // -- esp[0] : return address 1400 // -- esp[0] : return address
1420 // ----------------------------------- 1401 // -----------------------------------
(...skipping 26 matching lines...) Expand all
1447 // Check that value is a smi. 1428 // Check that value is a smi.
1448 __ test(value, Immediate(kSmiTagMask)); 1429 __ test(value, Immediate(kSmiTagMask));
1449 __ j(not_zero, &miss, not_taken); 1430 __ j(not_zero, &miss, not_taken);
1450 1431
1451 // Prepare tail call to StoreIC_ArrayLength. 1432 // Prepare tail call to StoreIC_ArrayLength.
1452 __ pop(scratch); 1433 __ pop(scratch);
1453 __ push(receiver); 1434 __ push(receiver);
1454 __ push(value); 1435 __ push(value);
1455 __ push(scratch); // return address 1436 __ push(scratch); // return address
1456 1437
1457 __ TailCallRuntime(ExternalReference(IC_Utility(kStoreIC_ArrayLength)), 2, 1); 1438 ExternalReference ref = ExternalReference(IC_Utility(kStoreIC_ArrayLength));
1439 __ TailCallExternalReference(ref, 2, 1);
1458 1440
1459 __ bind(&miss); 1441 __ bind(&miss);
1460 1442
1461 GenerateMiss(masm); 1443 GenerateMiss(masm);
1462 } 1444 }
1463 1445
1464 1446
1465 // Defined in ic.cc. 1447 // Defined in ic.cc.
1466 Object* KeyedStoreIC_Miss(Arguments args); 1448 Object* KeyedStoreIC_Miss(Arguments args);
1467 1449
1468 void KeyedStoreIC::GenerateRuntimeSetProperty(MacroAssembler* masm) { 1450 void KeyedStoreIC::GenerateRuntimeSetProperty(MacroAssembler* masm) {
1469 // ----------- S t a t e ------------- 1451 // ----------- S t a t e -------------
1470 // -- eax : value 1452 // -- eax : value
1453 // -- ecx : key
1454 // -- edx : receiver
1471 // -- esp[0] : return address 1455 // -- esp[0] : return address
1472 // -- esp[4] : key
1473 // -- esp[8] : receiver
1474 // ----------------------------------- 1456 // -----------------------------------
1475 1457
1476 __ pop(ecx); 1458 __ pop(ebx);
1477 __ push(Operand(esp, 1 * kPointerSize)); 1459 __ push(edx);
1478 __ push(Operand(esp, 1 * kPointerSize)); 1460 __ push(ecx);
1479 __ push(eax); 1461 __ push(eax);
1480 __ push(ecx); 1462 __ push(ebx);
1481 1463
1482 // Do tail-call to runtime routine. 1464 // Do tail-call to runtime routine.
1483 __ TailCallRuntime(ExternalReference(Runtime::kSetProperty), 3, 1); 1465 __ TailCallRuntime(Runtime::kSetProperty, 3, 1);
1484 } 1466 }
1485 1467
1486 1468
1487 void KeyedStoreIC::GenerateMiss(MacroAssembler* masm) { 1469 void KeyedStoreIC::GenerateMiss(MacroAssembler* masm) {
1488 // ----------- S t a t e ------------- 1470 // ----------- S t a t e -------------
1489 // -- eax : value 1471 // -- eax : value
1472 // -- ecx : key
1473 // -- edx : receiver
1490 // -- esp[0] : return address 1474 // -- esp[0] : return address
1491 // -- esp[4] : key
1492 // -- esp[8] : receiver
1493 // ----------------------------------- 1475 // -----------------------------------
1494 1476
1495 __ pop(ecx); 1477 __ pop(ebx);
1496 __ push(Operand(esp, 1 * kPointerSize)); 1478 __ push(edx);
1497 __ push(Operand(esp, 1 * kPointerSize)); 1479 __ push(ecx);
1498 __ push(eax); 1480 __ push(eax);
1499 __ push(ecx); 1481 __ push(ebx);
1500 1482
1501 // Do tail-call to runtime routine. 1483 // Do tail-call to runtime routine.
1502 __ TailCallRuntime(ExternalReference(IC_Utility(kKeyedStoreIC_Miss)), 3, 1); 1484 ExternalReference ref = ExternalReference(IC_Utility(kKeyedStoreIC_Miss));
1485 __ TailCallExternalReference(ref, 3, 1);
1503 } 1486 }
1504 1487
1505 #undef __ 1488 #undef __
1506 1489
1507 1490
1508 } } // namespace v8::internal 1491 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/ia32/full-codegen-ia32.cc ('k') | src/ia32/jump-target-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698