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

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

Issue 39973003: Merge bleeding_edge. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/parser
Patch Set: again Created 7 years, 2 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/code-stubs-ia32.cc ('k') | src/ia32/deoptimizer-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 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 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
110 if (buffer == NULL) return &exp; 110 if (buffer == NULL) return &exp;
111 ExternalReference::InitializeMathExpData(); 111 ExternalReference::InitializeMathExpData();
112 112
113 MacroAssembler masm(NULL, buffer, static_cast<int>(actual_size)); 113 MacroAssembler masm(NULL, buffer, static_cast<int>(actual_size));
114 // esp[1 * kPointerSize]: raw double input 114 // esp[1 * kPointerSize]: raw double input
115 // esp[0 * kPointerSize]: return address 115 // esp[0 * kPointerSize]: return address
116 { 116 {
117 CpuFeatureScope use_sse2(&masm, SSE2); 117 CpuFeatureScope use_sse2(&masm, SSE2);
118 XMMRegister input = xmm1; 118 XMMRegister input = xmm1;
119 XMMRegister result = xmm2; 119 XMMRegister result = xmm2;
120 __ movdbl(input, Operand(esp, 1 * kPointerSize)); 120 __ movsd(input, Operand(esp, 1 * kPointerSize));
121 __ push(eax); 121 __ push(eax);
122 __ push(ebx); 122 __ push(ebx);
123 123
124 MathExpGenerator::EmitMathExp(&masm, input, result, xmm0, eax, ebx); 124 MathExpGenerator::EmitMathExp(&masm, input, result, xmm0, eax, ebx);
125 125
126 __ pop(ebx); 126 __ pop(ebx);
127 __ pop(eax); 127 __ pop(eax);
128 __ movdbl(Operand(esp, 1 * kPointerSize), result); 128 __ movsd(Operand(esp, 1 * kPointerSize), result);
129 __ fld_d(Operand(esp, 1 * kPointerSize)); 129 __ fld_d(Operand(esp, 1 * kPointerSize));
130 __ Ret(); 130 __ Ret();
131 } 131 }
132 132
133 CodeDesc desc; 133 CodeDesc desc;
134 masm.GetCode(&desc); 134 masm.GetCode(&desc);
135 ASSERT(!RelocInfo::RequiresRelocation(desc)); 135 ASSERT(!RelocInfo::RequiresRelocation(desc));
136 136
137 CPU::FlushICache(buffer, actual_size); 137 CPU::FlushICache(buffer, actual_size);
138 OS::ProtectCode(buffer, actual_size); 138 OS::ProtectCode(buffer, actual_size);
139 return FUNCTION_CAST<UnaryMathFunction>(buffer); 139 return FUNCTION_CAST<UnaryMathFunction>(buffer);
140 } 140 }
141 141
142 142
143 UnaryMathFunction CreateSqrtFunction() { 143 UnaryMathFunction CreateSqrtFunction() {
144 size_t actual_size; 144 size_t actual_size;
145 // Allocate buffer in executable space. 145 // Allocate buffer in executable space.
146 byte* buffer = static_cast<byte*>(OS::Allocate(1 * KB, 146 byte* buffer = static_cast<byte*>(OS::Allocate(1 * KB,
147 &actual_size, 147 &actual_size,
148 true)); 148 true));
149 // If SSE2 is not available, we can use libc's implementation to ensure 149 // If SSE2 is not available, we can use libc's implementation to ensure
150 // consistency since code by fullcodegen's calls into runtime in that case. 150 // consistency since code by fullcodegen's calls into runtime in that case.
151 if (buffer == NULL || !CpuFeatures::IsSupported(SSE2)) return &sqrt; 151 if (buffer == NULL || !CpuFeatures::IsSupported(SSE2)) return &sqrt;
152 MacroAssembler masm(NULL, buffer, static_cast<int>(actual_size)); 152 MacroAssembler masm(NULL, buffer, static_cast<int>(actual_size));
153 // esp[1 * kPointerSize]: raw double input 153 // esp[1 * kPointerSize]: raw double input
154 // esp[0 * kPointerSize]: return address 154 // esp[0 * kPointerSize]: return address
155 // Move double input into registers. 155 // Move double input into registers.
156 { 156 {
157 CpuFeatureScope use_sse2(&masm, SSE2); 157 CpuFeatureScope use_sse2(&masm, SSE2);
158 __ movdbl(xmm0, Operand(esp, 1 * kPointerSize)); 158 __ movsd(xmm0, Operand(esp, 1 * kPointerSize));
159 __ sqrtsd(xmm0, xmm0); 159 __ sqrtsd(xmm0, xmm0);
160 __ movdbl(Operand(esp, 1 * kPointerSize), xmm0); 160 __ movsd(Operand(esp, 1 * kPointerSize), xmm0);
161 // Load result into floating point register as return value. 161 // Load result into floating point register as return value.
162 __ fld_d(Operand(esp, 1 * kPointerSize)); 162 __ fld_d(Operand(esp, 1 * kPointerSize));
163 __ Ret(); 163 __ Ret();
164 } 164 }
165 165
166 CodeDesc desc; 166 CodeDesc desc;
167 masm.GetCode(&desc); 167 masm.GetCode(&desc);
168 ASSERT(!RelocInfo::RequiresRelocation(desc)); 168 ASSERT(!RelocInfo::RequiresRelocation(desc));
169 169
170 CPU::FlushICache(buffer, actual_size); 170 CPU::FlushICache(buffer, actual_size);
(...skipping 284 matching lines...) Expand 10 before | Expand all | Expand 10 after
455 __ j(below_equal, &small_size); 455 __ j(below_equal, &small_size);
456 __ jmp(&medium_size); 456 __ jmp(&medium_size);
457 } 457 }
458 { 458 {
459 // Special handlers for 9 <= copy_size < 64. No assumptions about 459 // Special handlers for 9 <= copy_size < 64. No assumptions about
460 // alignment or move distance, so all reads must be unaligned and 460 // alignment or move distance, so all reads must be unaligned and
461 // must happen before any writes. 461 // must happen before any writes.
462 Label medium_handlers, f9_16, f17_32, f33_48, f49_63; 462 Label medium_handlers, f9_16, f17_32, f33_48, f49_63;
463 463
464 __ bind(&f9_16); 464 __ bind(&f9_16);
465 __ movdbl(xmm0, Operand(src, 0)); 465 __ movsd(xmm0, Operand(src, 0));
466 __ movdbl(xmm1, Operand(src, count, times_1, -8)); 466 __ movsd(xmm1, Operand(src, count, times_1, -8));
467 __ movdbl(Operand(dst, 0), xmm0); 467 __ movsd(Operand(dst, 0), xmm0);
468 __ movdbl(Operand(dst, count, times_1, -8), xmm1); 468 __ movsd(Operand(dst, count, times_1, -8), xmm1);
469 MemMoveEmitPopAndReturn(&masm); 469 MemMoveEmitPopAndReturn(&masm);
470 470
471 __ bind(&f17_32); 471 __ bind(&f17_32);
472 __ movdqu(xmm0, Operand(src, 0)); 472 __ movdqu(xmm0, Operand(src, 0));
473 __ movdqu(xmm1, Operand(src, count, times_1, -0x10)); 473 __ movdqu(xmm1, Operand(src, count, times_1, -0x10));
474 __ movdqu(Operand(dst, 0x00), xmm0); 474 __ movdqu(Operand(dst, 0x00), xmm0);
475 __ movdqu(Operand(dst, count, times_1, -0x10), xmm1); 475 __ movdqu(Operand(dst, count, times_1, -0x10), xmm1);
476 MemMoveEmitPopAndReturn(&masm); 476 MemMoveEmitPopAndReturn(&masm);
477 477
478 __ bind(&f33_48); 478 __ bind(&f33_48);
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after
659 Label* allocation_memento_found) { 659 Label* allocation_memento_found) {
660 // ----------- S t a t e ------------- 660 // ----------- S t a t e -------------
661 // -- eax : value 661 // -- eax : value
662 // -- ebx : target map 662 // -- ebx : target map
663 // -- ecx : key 663 // -- ecx : key
664 // -- edx : receiver 664 // -- edx : receiver
665 // -- esp[0] : return address 665 // -- esp[0] : return address
666 // ----------------------------------- 666 // -----------------------------------
667 if (mode == TRACK_ALLOCATION_SITE) { 667 if (mode == TRACK_ALLOCATION_SITE) {
668 ASSERT(allocation_memento_found != NULL); 668 ASSERT(allocation_memento_found != NULL);
669 __ TestJSArrayForAllocationMemento(edx, edi); 669 __ JumpIfJSArrayHasAllocationMemento(edx, edi, allocation_memento_found);
670 __ j(equal, allocation_memento_found);
671 } 670 }
672 671
673 // Set transitioned map. 672 // Set transitioned map.
674 __ mov(FieldOperand(edx, HeapObject::kMapOffset), ebx); 673 __ mov(FieldOperand(edx, HeapObject::kMapOffset), ebx);
675 __ RecordWriteField(edx, 674 __ RecordWriteField(edx,
676 HeapObject::kMapOffset, 675 HeapObject::kMapOffset,
677 ebx, 676 ebx,
678 edi, 677 edi,
679 kDontSaveFPRegs, 678 kDontSaveFPRegs,
680 EMIT_REMEMBERED_SET, 679 EMIT_REMEMBERED_SET,
681 OMIT_SMI_CHECK); 680 OMIT_SMI_CHECK);
682 } 681 }
683 682
684 683
685 void ElementsTransitionGenerator::GenerateSmiToDouble( 684 void ElementsTransitionGenerator::GenerateSmiToDouble(
686 MacroAssembler* masm, AllocationSiteMode mode, Label* fail) { 685 MacroAssembler* masm, AllocationSiteMode mode, Label* fail) {
687 // ----------- S t a t e ------------- 686 // ----------- S t a t e -------------
688 // -- eax : value 687 // -- eax : value
689 // -- ebx : target map 688 // -- ebx : target map
690 // -- ecx : key 689 // -- ecx : key
691 // -- edx : receiver 690 // -- edx : receiver
692 // -- esp[0] : return address 691 // -- esp[0] : return address
693 // ----------------------------------- 692 // -----------------------------------
694 Label loop, entry, convert_hole, gc_required, only_change_map; 693 Label loop, entry, convert_hole, gc_required, only_change_map;
695 694
696 if (mode == TRACK_ALLOCATION_SITE) { 695 if (mode == TRACK_ALLOCATION_SITE) {
697 __ TestJSArrayForAllocationMemento(edx, edi); 696 __ JumpIfJSArrayHasAllocationMemento(edx, edi, fail);
698 __ j(equal, fail);
699 } 697 }
700 698
701 // Check for empty arrays, which only require a map transition and no changes 699 // Check for empty arrays, which only require a map transition and no changes
702 // to the backing store. 700 // to the backing store.
703 __ mov(edi, FieldOperand(edx, JSObject::kElementsOffset)); 701 __ mov(edi, FieldOperand(edx, JSObject::kElementsOffset));
704 __ cmp(edi, Immediate(masm->isolate()->factory()->empty_fixed_array())); 702 __ cmp(edi, Immediate(masm->isolate()->factory()->empty_fixed_array()));
705 __ j(equal, &only_change_map); 703 __ j(equal, &only_change_map);
706 704
707 __ push(eax); 705 __ push(eax);
708 __ push(ebx); 706 __ push(ebx);
(...skipping 27 matching lines...) Expand all
736 OMIT_SMI_CHECK); 734 OMIT_SMI_CHECK);
737 735
738 __ mov(edi, FieldOperand(esi, FixedArray::kLengthOffset)); 736 __ mov(edi, FieldOperand(esi, FixedArray::kLengthOffset));
739 737
740 // Prepare for conversion loop. 738 // Prepare for conversion loop.
741 ExternalReference canonical_the_hole_nan_reference = 739 ExternalReference canonical_the_hole_nan_reference =
742 ExternalReference::address_of_the_hole_nan(); 740 ExternalReference::address_of_the_hole_nan();
743 XMMRegister the_hole_nan = xmm1; 741 XMMRegister the_hole_nan = xmm1;
744 if (CpuFeatures::IsSupported(SSE2)) { 742 if (CpuFeatures::IsSupported(SSE2)) {
745 CpuFeatureScope use_sse2(masm, SSE2); 743 CpuFeatureScope use_sse2(masm, SSE2);
746 __ movdbl(the_hole_nan, 744 __ movsd(the_hole_nan,
747 Operand::StaticVariable(canonical_the_hole_nan_reference)); 745 Operand::StaticVariable(canonical_the_hole_nan_reference));
748 } 746 }
749 __ jmp(&entry); 747 __ jmp(&entry);
750 748
751 // Call into runtime if GC is required. 749 // Call into runtime if GC is required.
752 __ bind(&gc_required); 750 __ bind(&gc_required);
753 // Restore registers before jumping into runtime. 751 // Restore registers before jumping into runtime.
754 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); 752 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
755 __ pop(ebx); 753 __ pop(ebx);
756 __ pop(eax); 754 __ pop(eax);
757 __ jmp(fail); 755 __ jmp(fail);
758 756
759 // Convert and copy elements 757 // Convert and copy elements
760 // esi: source FixedArray 758 // esi: source FixedArray
761 __ bind(&loop); 759 __ bind(&loop);
762 __ mov(ebx, FieldOperand(esi, edi, times_2, FixedArray::kHeaderSize)); 760 __ mov(ebx, FieldOperand(esi, edi, times_2, FixedArray::kHeaderSize));
763 // ebx: current element from source 761 // ebx: current element from source
764 // edi: index of current element 762 // edi: index of current element
765 __ JumpIfNotSmi(ebx, &convert_hole); 763 __ JumpIfNotSmi(ebx, &convert_hole);
766 764
767 // Normal smi, convert it to double and store. 765 // Normal smi, convert it to double and store.
768 __ SmiUntag(ebx); 766 __ SmiUntag(ebx);
769 if (CpuFeatures::IsSupported(SSE2)) { 767 if (CpuFeatures::IsSupported(SSE2)) {
770 CpuFeatureScope fscope(masm, SSE2); 768 CpuFeatureScope fscope(masm, SSE2);
771 __ Cvtsi2sd(xmm0, ebx); 769 __ Cvtsi2sd(xmm0, ebx);
772 __ movdbl(FieldOperand(eax, edi, times_4, FixedDoubleArray::kHeaderSize), 770 __ movsd(FieldOperand(eax, edi, times_4, FixedDoubleArray::kHeaderSize),
773 xmm0); 771 xmm0);
774 } else { 772 } else {
775 __ push(ebx); 773 __ push(ebx);
776 __ fild_s(Operand(esp, 0)); 774 __ fild_s(Operand(esp, 0));
777 __ pop(ebx); 775 __ pop(ebx);
778 __ fstp_d(FieldOperand(eax, edi, times_4, FixedDoubleArray::kHeaderSize)); 776 __ fstp_d(FieldOperand(eax, edi, times_4, FixedDoubleArray::kHeaderSize));
779 } 777 }
780 __ jmp(&entry); 778 __ jmp(&entry);
781 779
782 // Found hole, store hole_nan_as_double instead. 780 // Found hole, store hole_nan_as_double instead.
783 __ bind(&convert_hole); 781 __ bind(&convert_hole);
784 782
785 if (FLAG_debug_code) { 783 if (FLAG_debug_code) {
786 __ cmp(ebx, masm->isolate()->factory()->the_hole_value()); 784 __ cmp(ebx, masm->isolate()->factory()->the_hole_value());
787 __ Assert(equal, kObjectFoundInSmiOnlyArray); 785 __ Assert(equal, kObjectFoundInSmiOnlyArray);
788 } 786 }
789 787
790 if (CpuFeatures::IsSupported(SSE2)) { 788 if (CpuFeatures::IsSupported(SSE2)) {
791 CpuFeatureScope use_sse2(masm, SSE2); 789 CpuFeatureScope use_sse2(masm, SSE2);
792 __ movdbl(FieldOperand(eax, edi, times_4, FixedDoubleArray::kHeaderSize), 790 __ movsd(FieldOperand(eax, edi, times_4, FixedDoubleArray::kHeaderSize),
793 the_hole_nan); 791 the_hole_nan);
794 } else { 792 } else {
795 __ fld_d(Operand::StaticVariable(canonical_the_hole_nan_reference)); 793 __ fld_d(Operand::StaticVariable(canonical_the_hole_nan_reference));
796 __ fstp_d(FieldOperand(eax, edi, times_4, FixedDoubleArray::kHeaderSize)); 794 __ fstp_d(FieldOperand(eax, edi, times_4, FixedDoubleArray::kHeaderSize));
797 } 795 }
798 796
799 __ bind(&entry); 797 __ bind(&entry);
800 __ sub(edi, Immediate(Smi::FromInt(1))); 798 __ sub(edi, Immediate(Smi::FromInt(1)));
801 __ j(not_sign, &loop); 799 __ j(not_sign, &loop);
802 800
(...skipping 23 matching lines...) Expand all
826 // ----------- S t a t e ------------- 824 // ----------- S t a t e -------------
827 // -- eax : value 825 // -- eax : value
828 // -- ebx : target map 826 // -- ebx : target map
829 // -- ecx : key 827 // -- ecx : key
830 // -- edx : receiver 828 // -- edx : receiver
831 // -- esp[0] : return address 829 // -- esp[0] : return address
832 // ----------------------------------- 830 // -----------------------------------
833 Label loop, entry, convert_hole, gc_required, only_change_map, success; 831 Label loop, entry, convert_hole, gc_required, only_change_map, success;
834 832
835 if (mode == TRACK_ALLOCATION_SITE) { 833 if (mode == TRACK_ALLOCATION_SITE) {
836 __ TestJSArrayForAllocationMemento(edx, edi); 834 __ JumpIfJSArrayHasAllocationMemento(edx, edi, fail);
837 __ j(equal, fail);
838 } 835 }
839 836
840 // Check for empty arrays, which only require a map transition and no changes 837 // Check for empty arrays, which only require a map transition and no changes
841 // to the backing store. 838 // to the backing store.
842 __ mov(edi, FieldOperand(edx, JSObject::kElementsOffset)); 839 __ mov(edi, FieldOperand(edx, JSObject::kElementsOffset));
843 __ cmp(edi, Immediate(masm->isolate()->factory()->empty_fixed_array())); 840 __ cmp(edi, Immediate(masm->isolate()->factory()->empty_fixed_array()));
844 __ j(equal, &only_change_map); 841 __ j(equal, &only_change_map);
845 842
846 __ push(eax); 843 __ push(eax);
847 __ push(edx); 844 __ push(edx);
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
892 // ebx: index of current element (smi-tagged) 889 // ebx: index of current element (smi-tagged)
893 uint32_t offset = FixedDoubleArray::kHeaderSize + sizeof(kHoleNanLower32); 890 uint32_t offset = FixedDoubleArray::kHeaderSize + sizeof(kHoleNanLower32);
894 __ cmp(FieldOperand(edi, ebx, times_4, offset), Immediate(kHoleNanUpper32)); 891 __ cmp(FieldOperand(edi, ebx, times_4, offset), Immediate(kHoleNanUpper32));
895 __ j(equal, &convert_hole); 892 __ j(equal, &convert_hole);
896 893
897 // Non-hole double, copy value into a heap number. 894 // Non-hole double, copy value into a heap number.
898 __ AllocateHeapNumber(edx, esi, no_reg, &gc_required); 895 __ AllocateHeapNumber(edx, esi, no_reg, &gc_required);
899 // edx: new heap number 896 // edx: new heap number
900 if (CpuFeatures::IsSupported(SSE2)) { 897 if (CpuFeatures::IsSupported(SSE2)) {
901 CpuFeatureScope fscope(masm, SSE2); 898 CpuFeatureScope fscope(masm, SSE2);
902 __ movdbl(xmm0, 899 __ movsd(xmm0,
903 FieldOperand(edi, ebx, times_4, FixedDoubleArray::kHeaderSize)); 900 FieldOperand(edi, ebx, times_4, FixedDoubleArray::kHeaderSize));
904 __ movdbl(FieldOperand(edx, HeapNumber::kValueOffset), xmm0); 901 __ movsd(FieldOperand(edx, HeapNumber::kValueOffset), xmm0);
905 } else { 902 } else {
906 __ mov(esi, FieldOperand(edi, ebx, times_4, FixedDoubleArray::kHeaderSize)); 903 __ mov(esi, FieldOperand(edi, ebx, times_4, FixedDoubleArray::kHeaderSize));
907 __ mov(FieldOperand(edx, HeapNumber::kValueOffset), esi); 904 __ mov(FieldOperand(edx, HeapNumber::kValueOffset), esi);
908 __ mov(esi, FieldOperand(edi, ebx, times_4, offset)); 905 __ mov(esi, FieldOperand(edi, ebx, times_4, offset));
909 __ mov(FieldOperand(edx, HeapNumber::kValueOffset + kPointerSize), esi); 906 __ mov(FieldOperand(edx, HeapNumber::kValueOffset + kPointerSize), esi);
910 } 907 }
911 __ mov(FieldOperand(eax, ebx, times_2, FixedArray::kHeaderSize), edx); 908 __ mov(FieldOperand(eax, ebx, times_2, FixedArray::kHeaderSize), edx);
912 __ mov(esi, ebx); 909 __ mov(esi, ebx);
913 __ RecordWriteArray(eax, 910 __ RecordWriteArray(eax,
914 edx, 911 edx,
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after
1074 Register temp1, 1071 Register temp1,
1075 Register temp2) { 1072 Register temp2) {
1076 ASSERT(!input.is(double_scratch)); 1073 ASSERT(!input.is(double_scratch));
1077 ASSERT(!input.is(result)); 1074 ASSERT(!input.is(result));
1078 ASSERT(!result.is(double_scratch)); 1075 ASSERT(!result.is(double_scratch));
1079 ASSERT(!temp1.is(temp2)); 1076 ASSERT(!temp1.is(temp2));
1080 ASSERT(ExternalReference::math_exp_constants(0).address() != NULL); 1077 ASSERT(ExternalReference::math_exp_constants(0).address() != NULL);
1081 1078
1082 Label done; 1079 Label done;
1083 1080
1084 __ movdbl(double_scratch, ExpConstant(0)); 1081 __ movsd(double_scratch, ExpConstant(0));
1085 __ xorpd(result, result); 1082 __ xorpd(result, result);
1086 __ ucomisd(double_scratch, input); 1083 __ ucomisd(double_scratch, input);
1087 __ j(above_equal, &done); 1084 __ j(above_equal, &done);
1088 __ ucomisd(input, ExpConstant(1)); 1085 __ ucomisd(input, ExpConstant(1));
1089 __ movdbl(result, ExpConstant(2)); 1086 __ movsd(result, ExpConstant(2));
1090 __ j(above_equal, &done); 1087 __ j(above_equal, &done);
1091 __ movdbl(double_scratch, ExpConstant(3)); 1088 __ movsd(double_scratch, ExpConstant(3));
1092 __ movdbl(result, ExpConstant(4)); 1089 __ movsd(result, ExpConstant(4));
1093 __ mulsd(double_scratch, input); 1090 __ mulsd(double_scratch, input);
1094 __ addsd(double_scratch, result); 1091 __ addsd(double_scratch, result);
1095 __ movd(temp2, double_scratch); 1092 __ movd(temp2, double_scratch);
1096 __ subsd(double_scratch, result); 1093 __ subsd(double_scratch, result);
1097 __ movdbl(result, ExpConstant(6)); 1094 __ movsd(result, ExpConstant(6));
1098 __ mulsd(double_scratch, ExpConstant(5)); 1095 __ mulsd(double_scratch, ExpConstant(5));
1099 __ subsd(double_scratch, input); 1096 __ subsd(double_scratch, input);
1100 __ subsd(result, double_scratch); 1097 __ subsd(result, double_scratch);
1101 __ movsd(input, double_scratch); 1098 __ movsd(input, double_scratch);
1102 __ mulsd(input, double_scratch); 1099 __ mulsd(input, double_scratch);
1103 __ mulsd(result, input); 1100 __ mulsd(result, input);
1104 __ mov(temp1, temp2); 1101 __ mov(temp1, temp2);
1105 __ mulsd(result, ExpConstant(7)); 1102 __ mulsd(result, ExpConstant(7));
1106 __ subsd(result, double_scratch); 1103 __ subsd(result, double_scratch);
1107 __ add(temp1, Immediate(0x1ff800)); 1104 __ add(temp1, Immediate(0x1ff800));
1108 __ addsd(result, ExpConstant(8)); 1105 __ addsd(result, ExpConstant(8));
1109 __ and_(temp2, Immediate(0x7ff)); 1106 __ and_(temp2, Immediate(0x7ff));
1110 __ shr(temp1, 11); 1107 __ shr(temp1, 11);
1111 __ shl(temp1, 20); 1108 __ shl(temp1, 20);
1112 __ movd(input, temp1); 1109 __ movd(input, temp1);
1113 __ pshufd(input, input, static_cast<uint8_t>(0xe1)); // Order: 11 10 00 01 1110 __ pshufd(input, input, static_cast<uint8_t>(0xe1)); // Order: 11 10 00 01
1114 __ movdbl(double_scratch, Operand::StaticArray( 1111 __ movsd(double_scratch, Operand::StaticArray(
1115 temp2, times_8, ExternalReference::math_exp_log_table())); 1112 temp2, times_8, ExternalReference::math_exp_log_table()));
1116 __ por(input, double_scratch); 1113 __ por(input, double_scratch);
1117 __ mulsd(result, input); 1114 __ mulsd(result, input);
1118 __ bind(&done); 1115 __ bind(&done);
1119 } 1116 }
1120 1117
1121 #undef __ 1118 #undef __
1122 1119
1123 static const int kNoCodeAgeSequenceLength = 5;
1124 1120
1125 static byte* GetNoCodeAgeSequence(uint32_t* length) { 1121 static byte* GetNoCodeAgeSequence(uint32_t* length) {
1126 static bool initialized = false; 1122 static bool initialized = false;
1127 static byte sequence[kNoCodeAgeSequenceLength]; 1123 static byte sequence[kNoCodeAgeSequenceLength];
1128 *length = kNoCodeAgeSequenceLength; 1124 *length = kNoCodeAgeSequenceLength;
1129 if (!initialized) { 1125 if (!initialized) {
1130 // The sequence of instructions that is patched out for aging code is the 1126 // The sequence of instructions that is patched out for aging code is the
1131 // following boilerplate stack-building prologue that is found both in 1127 // following boilerplate stack-building prologue that is found both in
1132 // FUNCTION and OPTIMIZED_FUNCTION code: 1128 // FUNCTION and OPTIMIZED_FUNCTION code:
1133 CodePatcher patcher(sequence, kNoCodeAgeSequenceLength); 1129 CodePatcher patcher(sequence, kNoCodeAgeSequenceLength);
(...skipping 12 matching lines...) Expand all
1146 byte* young_sequence = GetNoCodeAgeSequence(&young_length); 1142 byte* young_sequence = GetNoCodeAgeSequence(&young_length);
1147 bool result = (!memcmp(sequence, young_sequence, young_length)); 1143 bool result = (!memcmp(sequence, young_sequence, young_length));
1148 ASSERT(result || *sequence == kCallOpcode); 1144 ASSERT(result || *sequence == kCallOpcode);
1149 return result; 1145 return result;
1150 } 1146 }
1151 1147
1152 1148
1153 void Code::GetCodeAgeAndParity(byte* sequence, Age* age, 1149 void Code::GetCodeAgeAndParity(byte* sequence, Age* age,
1154 MarkingParity* parity) { 1150 MarkingParity* parity) {
1155 if (IsYoungSequence(sequence)) { 1151 if (IsYoungSequence(sequence)) {
1156 *age = kNoAge; 1152 *age = kNoAgeCodeAge;
1157 *parity = NO_MARKING_PARITY; 1153 *parity = NO_MARKING_PARITY;
1158 } else { 1154 } else {
1159 sequence++; // Skip the kCallOpcode byte 1155 sequence++; // Skip the kCallOpcode byte
1160 Address target_address = sequence + *reinterpret_cast<int*>(sequence) + 1156 Address target_address = sequence + *reinterpret_cast<int*>(sequence) +
1161 Assembler::kCallTargetAddressOffset; 1157 Assembler::kCallTargetAddressOffset;
1162 Code* stub = GetCodeFromTargetAddress(target_address); 1158 Code* stub = GetCodeFromTargetAddress(target_address);
1163 GetCodeAgeAndParity(stub, age, parity); 1159 GetCodeAgeAndParity(stub, age, parity);
1164 } 1160 }
1165 } 1161 }
1166 1162
1167 1163
1168 void Code::PatchPlatformCodeAge(Isolate* isolate, 1164 void Code::PatchPlatformCodeAge(Isolate* isolate,
1169 byte* sequence, 1165 byte* sequence,
1170 Code::Age age, 1166 Code::Age age,
1171 MarkingParity parity) { 1167 MarkingParity parity) {
1172 uint32_t young_length; 1168 uint32_t young_length;
1173 byte* young_sequence = GetNoCodeAgeSequence(&young_length); 1169 byte* young_sequence = GetNoCodeAgeSequence(&young_length);
1174 if (age == kNoAge) { 1170 if (age == kNoAgeCodeAge) {
1175 CopyBytes(sequence, young_sequence, young_length); 1171 CopyBytes(sequence, young_sequence, young_length);
1176 CPU::FlushICache(sequence, young_length); 1172 CPU::FlushICache(sequence, young_length);
1177 } else { 1173 } else {
1178 Code* stub = GetCodeAgeStub(isolate, age, parity); 1174 Code* stub = GetCodeAgeStub(isolate, age, parity);
1179 CodePatcher patcher(sequence, young_length); 1175 CodePatcher patcher(sequence, young_length);
1180 patcher.masm()->call(stub->instruction_start(), RelocInfo::NONE32); 1176 patcher.masm()->call(stub->instruction_start(), RelocInfo::NONE32);
1181 } 1177 }
1182 } 1178 }
1183 1179
1184 1180
1185 } } // namespace v8::internal 1181 } } // namespace v8::internal
1186 1182
1187 #endif // V8_TARGET_ARCH_IA32 1183 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/ia32/code-stubs-ia32.cc ('k') | src/ia32/deoptimizer-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698