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

Side by Side Diff: src/ia32/code-stubs-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.h ('k') | src/ia32/codegen-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 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
63 descriptor->deoptimization_handler_ = NULL; 63 descriptor->deoptimization_handler_ = NULL;
64 } 64 }
65 65
66 66
67 void NumberToStringStub::InitializeInterfaceDescriptor( 67 void NumberToStringStub::InitializeInterfaceDescriptor(
68 Isolate* isolate, 68 Isolate* isolate,
69 CodeStubInterfaceDescriptor* descriptor) { 69 CodeStubInterfaceDescriptor* descriptor) {
70 static Register registers[] = { eax }; 70 static Register registers[] = { eax };
71 descriptor->register_param_count_ = 1; 71 descriptor->register_param_count_ = 1;
72 descriptor->register_params_ = registers; 72 descriptor->register_params_ = registers;
73 descriptor->deoptimization_handler_ = NULL; 73 descriptor->deoptimization_handler_ =
74 Runtime::FunctionForId(Runtime::kNumberToString)->entry;
74 } 75 }
75 76
76 77
77 void FastCloneShallowArrayStub::InitializeInterfaceDescriptor( 78 void FastCloneShallowArrayStub::InitializeInterfaceDescriptor(
78 Isolate* isolate, 79 Isolate* isolate,
79 CodeStubInterfaceDescriptor* descriptor) { 80 CodeStubInterfaceDescriptor* descriptor) {
80 static Register registers[] = { eax, ebx, ecx }; 81 static Register registers[] = { eax, ebx, ecx };
81 descriptor->register_param_count_ = 3; 82 descriptor->register_param_count_ = 3;
82 descriptor->register_params_ = registers; 83 descriptor->register_params_ = registers;
83 descriptor->deoptimization_handler_ = 84 descriptor->deoptimization_handler_ =
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
165 int constant_stack_parameter_count) { 166 int constant_stack_parameter_count) {
166 // register state 167 // register state
167 // eax -- number of arguments 168 // eax -- number of arguments
168 // edi -- function 169 // edi -- function
169 // ebx -- type info cell with elements kind 170 // ebx -- type info cell with elements kind
170 static Register registers[] = { edi, ebx }; 171 static Register registers[] = { edi, ebx };
171 descriptor->register_param_count_ = 2; 172 descriptor->register_param_count_ = 2;
172 173
173 if (constant_stack_parameter_count != 0) { 174 if (constant_stack_parameter_count != 0) {
174 // stack param count needs (constructor pointer, and single argument) 175 // stack param count needs (constructor pointer, and single argument)
175 descriptor->stack_parameter_count_ = &eax; 176 descriptor->stack_parameter_count_ = eax;
176 } 177 }
177 descriptor->hint_stack_parameter_count_ = constant_stack_parameter_count; 178 descriptor->hint_stack_parameter_count_ = constant_stack_parameter_count;
178 descriptor->register_params_ = registers; 179 descriptor->register_params_ = registers;
179 descriptor->function_mode_ = JS_FUNCTION_STUB_MODE; 180 descriptor->function_mode_ = JS_FUNCTION_STUB_MODE;
180 descriptor->deoptimization_handler_ = 181 descriptor->deoptimization_handler_ =
181 Runtime::FunctionForId(Runtime::kArrayConstructor)->entry; 182 Runtime::FunctionForId(Runtime::kArrayConstructor)->entry;
182 } 183 }
183 184
184 185
185 static void InitializeInternalArrayConstructorDescriptor( 186 static void InitializeInternalArrayConstructorDescriptor(
186 Isolate* isolate, 187 Isolate* isolate,
187 CodeStubInterfaceDescriptor* descriptor, 188 CodeStubInterfaceDescriptor* descriptor,
188 int constant_stack_parameter_count) { 189 int constant_stack_parameter_count) {
189 // register state 190 // register state
190 // eax -- number of arguments 191 // eax -- number of arguments
191 // edi -- constructor function 192 // edi -- constructor function
192 static Register registers[] = { edi }; 193 static Register registers[] = { edi };
193 descriptor->register_param_count_ = 1; 194 descriptor->register_param_count_ = 1;
194 195
195 if (constant_stack_parameter_count != 0) { 196 if (constant_stack_parameter_count != 0) {
196 // stack param count needs (constructor pointer, and single argument) 197 // stack param count needs (constructor pointer, and single argument)
197 descriptor->stack_parameter_count_ = &eax; 198 descriptor->stack_parameter_count_ = eax;
198 } 199 }
199 descriptor->hint_stack_parameter_count_ = constant_stack_parameter_count; 200 descriptor->hint_stack_parameter_count_ = constant_stack_parameter_count;
200 descriptor->register_params_ = registers; 201 descriptor->register_params_ = registers;
201 descriptor->function_mode_ = JS_FUNCTION_STUB_MODE; 202 descriptor->function_mode_ = JS_FUNCTION_STUB_MODE;
202 descriptor->deoptimization_handler_ = 203 descriptor->deoptimization_handler_ =
203 Runtime::FunctionForId(Runtime::kInternalArrayConstructor)->entry; 204 Runtime::FunctionForId(Runtime::kInternalArrayConstructor)->entry;
204 } 205 }
205 206
206 207
207 void ArrayNoArgumentConstructorStub::InitializeInterfaceDescriptor( 208 void ArrayNoArgumentConstructorStub::InitializeInterfaceDescriptor(
(...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after
447 void StoreBufferOverflowStub::Generate(MacroAssembler* masm) { 448 void StoreBufferOverflowStub::Generate(MacroAssembler* masm) {
448 // We don't allow a GC during a store buffer overflow so there is no need to 449 // We don't allow a GC during a store buffer overflow so there is no need to
449 // store the registers in any particular way, but we do have to store and 450 // store the registers in any particular way, but we do have to store and
450 // restore them. 451 // restore them.
451 __ pushad(); 452 __ pushad();
452 if (save_doubles_ == kSaveFPRegs) { 453 if (save_doubles_ == kSaveFPRegs) {
453 CpuFeatureScope scope(masm, SSE2); 454 CpuFeatureScope scope(masm, SSE2);
454 __ sub(esp, Immediate(kDoubleSize * XMMRegister::kNumRegisters)); 455 __ sub(esp, Immediate(kDoubleSize * XMMRegister::kNumRegisters));
455 for (int i = 0; i < XMMRegister::kNumRegisters; i++) { 456 for (int i = 0; i < XMMRegister::kNumRegisters; i++) {
456 XMMRegister reg = XMMRegister::from_code(i); 457 XMMRegister reg = XMMRegister::from_code(i);
457 __ movdbl(Operand(esp, i * kDoubleSize), reg); 458 __ movsd(Operand(esp, i * kDoubleSize), reg);
458 } 459 }
459 } 460 }
460 const int argument_count = 1; 461 const int argument_count = 1;
461 462
462 AllowExternalCallThatCantCauseGC scope(masm); 463 AllowExternalCallThatCantCauseGC scope(masm);
463 __ PrepareCallCFunction(argument_count, ecx); 464 __ PrepareCallCFunction(argument_count, ecx);
464 __ mov(Operand(esp, 0 * kPointerSize), 465 __ mov(Operand(esp, 0 * kPointerSize),
465 Immediate(ExternalReference::isolate_address(masm->isolate()))); 466 Immediate(ExternalReference::isolate_address(masm->isolate())));
466 __ CallCFunction( 467 __ CallCFunction(
467 ExternalReference::store_buffer_overflow_function(masm->isolate()), 468 ExternalReference::store_buffer_overflow_function(masm->isolate()),
468 argument_count); 469 argument_count);
469 if (save_doubles_ == kSaveFPRegs) { 470 if (save_doubles_ == kSaveFPRegs) {
470 CpuFeatureScope scope(masm, SSE2); 471 CpuFeatureScope scope(masm, SSE2);
471 for (int i = 0; i < XMMRegister::kNumRegisters; i++) { 472 for (int i = 0; i < XMMRegister::kNumRegisters; i++) {
472 XMMRegister reg = XMMRegister::from_code(i); 473 XMMRegister reg = XMMRegister::from_code(i);
473 __ movdbl(reg, Operand(esp, i * kDoubleSize)); 474 __ movsd(reg, Operand(esp, i * kDoubleSize));
474 } 475 }
475 __ add(esp, Immediate(kDoubleSize * XMMRegister::kNumRegisters)); 476 __ add(esp, Immediate(kDoubleSize * XMMRegister::kNumRegisters));
476 } 477 }
477 __ popad(); 478 __ popad();
478 __ ret(0); 479 __ ret(0);
479 } 480 }
480 481
481 482
482 class FloatingPointHelper : public AllStatic { 483 class FloatingPointHelper : public AllStatic {
483 public: 484 public:
(...skipping 279 matching lines...) Expand 10 before | Expand all | Expand 10 after
763 __ j(not_equal, &cache_miss, Label::kNear); 764 __ j(not_equal, &cache_miss, Label::kNear);
764 // Cache hit! 765 // Cache hit!
765 Counters* counters = masm->isolate()->counters(); 766 Counters* counters = masm->isolate()->counters();
766 __ IncrementCounter(counters->transcendental_cache_hit(), 1); 767 __ IncrementCounter(counters->transcendental_cache_hit(), 1);
767 __ mov(eax, Operand(ecx, 2 * kIntSize)); 768 __ mov(eax, Operand(ecx, 2 * kIntSize));
768 if (tagged) { 769 if (tagged) {
769 __ fstp(0); 770 __ fstp(0);
770 __ ret(kPointerSize); 771 __ ret(kPointerSize);
771 } else { // UNTAGGED. 772 } else { // UNTAGGED.
772 CpuFeatureScope scope(masm, SSE2); 773 CpuFeatureScope scope(masm, SSE2);
773 __ movdbl(xmm1, FieldOperand(eax, HeapNumber::kValueOffset)); 774 __ movsd(xmm1, FieldOperand(eax, HeapNumber::kValueOffset));
774 __ Ret(); 775 __ Ret();
775 } 776 }
776 777
777 __ bind(&cache_miss); 778 __ bind(&cache_miss);
778 __ IncrementCounter(counters->transcendental_cache_miss(), 1); 779 __ IncrementCounter(counters->transcendental_cache_miss(), 1);
779 // Update cache with new value. 780 // Update cache with new value.
780 // We are short on registers, so use no_reg as scratch. 781 // We are short on registers, so use no_reg as scratch.
781 // This gives slightly larger code. 782 // This gives slightly larger code.
782 if (tagged) { 783 if (tagged) {
783 __ AllocateHeapNumber(eax, edi, no_reg, &runtime_call_clear_stack); 784 __ AllocateHeapNumber(eax, edi, no_reg, &runtime_call_clear_stack);
784 } else { // UNTAGGED. 785 } else { // UNTAGGED.
785 CpuFeatureScope scope(masm, SSE2); 786 CpuFeatureScope scope(masm, SSE2);
786 __ AllocateHeapNumber(eax, edi, no_reg, &skip_cache); 787 __ AllocateHeapNumber(eax, edi, no_reg, &skip_cache);
787 __ sub(esp, Immediate(kDoubleSize)); 788 __ sub(esp, Immediate(kDoubleSize));
788 __ movdbl(Operand(esp, 0), xmm1); 789 __ movsd(Operand(esp, 0), xmm1);
789 __ fld_d(Operand(esp, 0)); 790 __ fld_d(Operand(esp, 0));
790 __ add(esp, Immediate(kDoubleSize)); 791 __ add(esp, Immediate(kDoubleSize));
791 } 792 }
792 GenerateOperation(masm, type_); 793 GenerateOperation(masm, type_);
793 __ mov(Operand(ecx, 0), ebx); 794 __ mov(Operand(ecx, 0), ebx);
794 __ mov(Operand(ecx, kIntSize), edx); 795 __ mov(Operand(ecx, kIntSize), edx);
795 __ mov(Operand(ecx, 2 * kIntSize), eax); 796 __ mov(Operand(ecx, 2 * kIntSize), eax);
796 __ fstp_d(FieldOperand(eax, HeapNumber::kValueOffset)); 797 __ fstp_d(FieldOperand(eax, HeapNumber::kValueOffset));
797 if (tagged) { 798 if (tagged) {
798 __ ret(kPointerSize); 799 __ ret(kPointerSize);
799 } else { // UNTAGGED. 800 } else { // UNTAGGED.
800 CpuFeatureScope scope(masm, SSE2); 801 CpuFeatureScope scope(masm, SSE2);
801 __ movdbl(xmm1, FieldOperand(eax, HeapNumber::kValueOffset)); 802 __ movsd(xmm1, FieldOperand(eax, HeapNumber::kValueOffset));
802 __ Ret(); 803 __ Ret();
803 804
804 // Skip cache and return answer directly, only in untagged case. 805 // Skip cache and return answer directly, only in untagged case.
805 __ bind(&skip_cache); 806 __ bind(&skip_cache);
806 __ sub(esp, Immediate(kDoubleSize)); 807 __ sub(esp, Immediate(kDoubleSize));
807 __ movdbl(Operand(esp, 0), xmm1); 808 __ movsd(Operand(esp, 0), xmm1);
808 __ fld_d(Operand(esp, 0)); 809 __ fld_d(Operand(esp, 0));
809 GenerateOperation(masm, type_); 810 GenerateOperation(masm, type_);
810 __ fstp_d(Operand(esp, 0)); 811 __ fstp_d(Operand(esp, 0));
811 __ movdbl(xmm1, Operand(esp, 0)); 812 __ movsd(xmm1, Operand(esp, 0));
812 __ add(esp, Immediate(kDoubleSize)); 813 __ add(esp, Immediate(kDoubleSize));
813 // We return the value in xmm1 without adding it to the cache, but 814 // We return the value in xmm1 without adding it to the cache, but
814 // we cause a scavenging GC so that future allocations will succeed. 815 // we cause a scavenging GC so that future allocations will succeed.
815 { 816 {
816 FrameScope scope(masm, StackFrame::INTERNAL); 817 FrameScope scope(masm, StackFrame::INTERNAL);
817 // Allocate an unused object bigger than a HeapNumber. 818 // Allocate an unused object bigger than a HeapNumber.
818 __ push(Immediate(Smi::FromInt(2 * kDoubleSize))); 819 __ push(Immediate(Smi::FromInt(2 * kDoubleSize)));
819 __ CallRuntimeSaveDoubles(Runtime::kAllocateInNewSpace); 820 __ CallRuntimeSaveDoubles(Runtime::kAllocateInNewSpace);
820 } 821 }
821 __ Ret(); 822 __ Ret();
822 } 823 }
823 824
824 // Call runtime, doing whatever allocation and cleanup is necessary. 825 // Call runtime, doing whatever allocation and cleanup is necessary.
825 if (tagged) { 826 if (tagged) {
826 __ bind(&runtime_call_clear_stack); 827 __ bind(&runtime_call_clear_stack);
827 __ fstp(0); 828 __ fstp(0);
828 __ bind(&runtime_call); 829 __ bind(&runtime_call);
829 ExternalReference runtime = 830 ExternalReference runtime =
830 ExternalReference(RuntimeFunction(), masm->isolate()); 831 ExternalReference(RuntimeFunction(), masm->isolate());
831 __ TailCallExternalReference(runtime, 1, 1); 832 __ TailCallExternalReference(runtime, 1, 1);
832 } else { // UNTAGGED. 833 } else { // UNTAGGED.
833 CpuFeatureScope scope(masm, SSE2); 834 CpuFeatureScope scope(masm, SSE2);
834 __ bind(&runtime_call_clear_stack); 835 __ bind(&runtime_call_clear_stack);
835 __ bind(&runtime_call); 836 __ bind(&runtime_call);
836 __ AllocateHeapNumber(eax, edi, no_reg, &skip_cache); 837 __ AllocateHeapNumber(eax, edi, no_reg, &skip_cache);
837 __ movdbl(FieldOperand(eax, HeapNumber::kValueOffset), xmm1); 838 __ movsd(FieldOperand(eax, HeapNumber::kValueOffset), xmm1);
838 { 839 {
839 FrameScope scope(masm, StackFrame::INTERNAL); 840 FrameScope scope(masm, StackFrame::INTERNAL);
840 __ push(eax); 841 __ push(eax);
841 __ CallRuntime(RuntimeFunction(), 1); 842 __ CallRuntime(RuntimeFunction(), 1);
842 } 843 }
843 __ movdbl(xmm1, FieldOperand(eax, HeapNumber::kValueOffset)); 844 __ movsd(xmm1, FieldOperand(eax, HeapNumber::kValueOffset));
844 __ Ret(); 845 __ Ret();
845 } 846 }
846 } 847 }
847 848
848 849
849 Runtime::FunctionId TranscendentalCacheStub::RuntimeFunction() { 850 Runtime::FunctionId TranscendentalCacheStub::RuntimeFunction() {
850 switch (type_) { 851 switch (type_) {
851 case TranscendentalCache::SIN: return Runtime::kMath_sin; 852 case TranscendentalCache::SIN: return Runtime::kMath_sin;
852 case TranscendentalCache::COS: return Runtime::kMath_cos; 853 case TranscendentalCache::COS: return Runtime::kMath_cos;
853 case TranscendentalCache::TAN: return Runtime::kMath_tan; 854 case TranscendentalCache::TAN: return Runtime::kMath_tan;
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
976 977
977 978
978 void FloatingPointHelper::LoadSSE2Operands(MacroAssembler* masm, 979 void FloatingPointHelper::LoadSSE2Operands(MacroAssembler* masm,
979 Label* not_numbers) { 980 Label* not_numbers) {
980 Label load_smi_edx, load_eax, load_smi_eax, load_float_eax, done; 981 Label load_smi_edx, load_eax, load_smi_eax, load_float_eax, done;
981 // Load operand in edx into xmm0, or branch to not_numbers. 982 // Load operand in edx into xmm0, or branch to not_numbers.
982 __ JumpIfSmi(edx, &load_smi_edx, Label::kNear); 983 __ JumpIfSmi(edx, &load_smi_edx, Label::kNear);
983 Factory* factory = masm->isolate()->factory(); 984 Factory* factory = masm->isolate()->factory();
984 __ cmp(FieldOperand(edx, HeapObject::kMapOffset), factory->heap_number_map()); 985 __ cmp(FieldOperand(edx, HeapObject::kMapOffset), factory->heap_number_map());
985 __ j(not_equal, not_numbers); // Argument in edx is not a number. 986 __ j(not_equal, not_numbers); // Argument in edx is not a number.
986 __ movdbl(xmm0, FieldOperand(edx, HeapNumber::kValueOffset)); 987 __ movsd(xmm0, FieldOperand(edx, HeapNumber::kValueOffset));
987 __ bind(&load_eax); 988 __ bind(&load_eax);
988 // Load operand in eax into xmm1, or branch to not_numbers. 989 // Load operand in eax into xmm1, or branch to not_numbers.
989 __ JumpIfSmi(eax, &load_smi_eax, Label::kNear); 990 __ JumpIfSmi(eax, &load_smi_eax, Label::kNear);
990 __ cmp(FieldOperand(eax, HeapObject::kMapOffset), factory->heap_number_map()); 991 __ cmp(FieldOperand(eax, HeapObject::kMapOffset), factory->heap_number_map());
991 __ j(equal, &load_float_eax, Label::kNear); 992 __ j(equal, &load_float_eax, Label::kNear);
992 __ jmp(not_numbers); // Argument in eax is not a number. 993 __ jmp(not_numbers); // Argument in eax is not a number.
993 __ bind(&load_smi_edx); 994 __ bind(&load_smi_edx);
994 __ SmiUntag(edx); // Untag smi before converting to float. 995 __ SmiUntag(edx); // Untag smi before converting to float.
995 __ Cvtsi2sd(xmm0, edx); 996 __ Cvtsi2sd(xmm0, edx);
996 __ SmiTag(edx); // Retag smi for heap number overwriting test. 997 __ SmiTag(edx); // Retag smi for heap number overwriting test.
997 __ jmp(&load_eax); 998 __ jmp(&load_eax);
998 __ bind(&load_smi_eax); 999 __ bind(&load_smi_eax);
999 __ SmiUntag(eax); // Untag smi before converting to float. 1000 __ SmiUntag(eax); // Untag smi before converting to float.
1000 __ Cvtsi2sd(xmm1, eax); 1001 __ Cvtsi2sd(xmm1, eax);
1001 __ SmiTag(eax); // Retag smi for heap number overwriting test. 1002 __ SmiTag(eax); // Retag smi for heap number overwriting test.
1002 __ jmp(&done, Label::kNear); 1003 __ jmp(&done, Label::kNear);
1003 __ bind(&load_float_eax); 1004 __ bind(&load_float_eax);
1004 __ movdbl(xmm1, FieldOperand(eax, HeapNumber::kValueOffset)); 1005 __ movsd(xmm1, FieldOperand(eax, HeapNumber::kValueOffset));
1005 __ bind(&done); 1006 __ bind(&done);
1006 } 1007 }
1007 1008
1008 1009
1009 void FloatingPointHelper::CheckFloatOperands(MacroAssembler* masm, 1010 void FloatingPointHelper::CheckFloatOperands(MacroAssembler* masm,
1010 Label* non_float, 1011 Label* non_float,
1011 Register scratch) { 1012 Register scratch) {
1012 Label test_other, done; 1013 Label test_other, done;
1013 // Test if both operands are floats or smi -> scratch=k_is_float; 1014 // Test if both operands are floats or smi -> scratch=k_is_float;
1014 // Otherwise scratch = k_not_float. 1015 // Otherwise scratch = k_not_float.
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
1052 // This can only happen if the stub is called from non-optimized code. 1053 // This can only happen if the stub is called from non-optimized code.
1053 // Load input parameters from stack. 1054 // Load input parameters from stack.
1054 __ mov(base, Operand(esp, 2 * kPointerSize)); 1055 __ mov(base, Operand(esp, 2 * kPointerSize));
1055 __ mov(exponent, Operand(esp, 1 * kPointerSize)); 1056 __ mov(exponent, Operand(esp, 1 * kPointerSize));
1056 1057
1057 __ JumpIfSmi(base, &base_is_smi, Label::kNear); 1058 __ JumpIfSmi(base, &base_is_smi, Label::kNear);
1058 __ cmp(FieldOperand(base, HeapObject::kMapOffset), 1059 __ cmp(FieldOperand(base, HeapObject::kMapOffset),
1059 factory->heap_number_map()); 1060 factory->heap_number_map());
1060 __ j(not_equal, &call_runtime); 1061 __ j(not_equal, &call_runtime);
1061 1062
1062 __ movdbl(double_base, FieldOperand(base, HeapNumber::kValueOffset)); 1063 __ movsd(double_base, FieldOperand(base, HeapNumber::kValueOffset));
1063 __ jmp(&unpack_exponent, Label::kNear); 1064 __ jmp(&unpack_exponent, Label::kNear);
1064 1065
1065 __ bind(&base_is_smi); 1066 __ bind(&base_is_smi);
1066 __ SmiUntag(base); 1067 __ SmiUntag(base);
1067 __ Cvtsi2sd(double_base, base); 1068 __ Cvtsi2sd(double_base, base);
1068 1069
1069 __ bind(&unpack_exponent); 1070 __ bind(&unpack_exponent);
1070 __ JumpIfNotSmi(exponent, &exponent_not_smi, Label::kNear); 1071 __ JumpIfNotSmi(exponent, &exponent_not_smi, Label::kNear);
1071 __ SmiUntag(exponent); 1072 __ SmiUntag(exponent);
1072 __ jmp(&int_exponent); 1073 __ jmp(&int_exponent);
1073 1074
1074 __ bind(&exponent_not_smi); 1075 __ bind(&exponent_not_smi);
1075 __ cmp(FieldOperand(exponent, HeapObject::kMapOffset), 1076 __ cmp(FieldOperand(exponent, HeapObject::kMapOffset),
1076 factory->heap_number_map()); 1077 factory->heap_number_map());
1077 __ j(not_equal, &call_runtime); 1078 __ j(not_equal, &call_runtime);
1078 __ movdbl(double_exponent, 1079 __ movsd(double_exponent,
1079 FieldOperand(exponent, HeapNumber::kValueOffset)); 1080 FieldOperand(exponent, HeapNumber::kValueOffset));
1080 } else if (exponent_type_ == TAGGED) { 1081 } else if (exponent_type_ == TAGGED) {
1081 __ JumpIfNotSmi(exponent, &exponent_not_smi, Label::kNear); 1082 __ JumpIfNotSmi(exponent, &exponent_not_smi, Label::kNear);
1082 __ SmiUntag(exponent); 1083 __ SmiUntag(exponent);
1083 __ jmp(&int_exponent); 1084 __ jmp(&int_exponent);
1084 1085
1085 __ bind(&exponent_not_smi); 1086 __ bind(&exponent_not_smi);
1086 __ movdbl(double_exponent, 1087 __ movsd(double_exponent,
1087 FieldOperand(exponent, HeapNumber::kValueOffset)); 1088 FieldOperand(exponent, HeapNumber::kValueOffset));
1088 } 1089 }
1089 1090
1090 if (exponent_type_ != INTEGER) { 1091 if (exponent_type_ != INTEGER) {
1091 Label fast_power, try_arithmetic_simplification; 1092 Label fast_power, try_arithmetic_simplification;
1092 __ DoubleToI(exponent, double_exponent, double_scratch, 1093 __ DoubleToI(exponent, double_exponent, double_scratch,
1093 TREAT_MINUS_ZERO_AS_ZERO, &try_arithmetic_simplification); 1094 TREAT_MINUS_ZERO_AS_ZERO, &try_arithmetic_simplification);
1094 __ jmp(&int_exponent); 1095 __ jmp(&int_exponent);
1095 1096
1096 __ bind(&try_arithmetic_simplification); 1097 __ bind(&try_arithmetic_simplification);
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
1171 __ divsd(double_result, double_exponent); 1172 __ divsd(double_result, double_exponent);
1172 __ jmp(&done); 1173 __ jmp(&done);
1173 } 1174 }
1174 1175
1175 // Using FPU instructions to calculate power. 1176 // Using FPU instructions to calculate power.
1176 Label fast_power_failed; 1177 Label fast_power_failed;
1177 __ bind(&fast_power); 1178 __ bind(&fast_power);
1178 __ fnclex(); // Clear flags to catch exceptions later. 1179 __ fnclex(); // Clear flags to catch exceptions later.
1179 // Transfer (B)ase and (E)xponent onto the FPU register stack. 1180 // Transfer (B)ase and (E)xponent onto the FPU register stack.
1180 __ sub(esp, Immediate(kDoubleSize)); 1181 __ sub(esp, Immediate(kDoubleSize));
1181 __ movdbl(Operand(esp, 0), double_exponent); 1182 __ movsd(Operand(esp, 0), double_exponent);
1182 __ fld_d(Operand(esp, 0)); // E 1183 __ fld_d(Operand(esp, 0)); // E
1183 __ movdbl(Operand(esp, 0), double_base); 1184 __ movsd(Operand(esp, 0), double_base);
1184 __ fld_d(Operand(esp, 0)); // B, E 1185 __ fld_d(Operand(esp, 0)); // B, E
1185 1186
1186 // Exponent is in st(1) and base is in st(0) 1187 // Exponent is in st(1) and base is in st(0)
1187 // B ^ E = (2^(E * log2(B)) - 1) + 1 = (2^X - 1) + 1 for X = E * log2(B) 1188 // B ^ E = (2^(E * log2(B)) - 1) + 1 = (2^X - 1) + 1 for X = E * log2(B)
1188 // FYL2X calculates st(1) * log2(st(0)) 1189 // FYL2X calculates st(1) * log2(st(0))
1189 __ fyl2x(); // X 1190 __ fyl2x(); // X
1190 __ fld(0); // X, X 1191 __ fld(0); // X, X
1191 __ frndint(); // rnd(X), X 1192 __ frndint(); // rnd(X), X
1192 __ fsub(1); // rnd(X), X-rnd(X) 1193 __ fsub(1); // rnd(X), X-rnd(X)
1193 __ fxch(1); // X - rnd(X), rnd(X) 1194 __ fxch(1); // X - rnd(X), rnd(X)
1194 // F2XM1 calculates 2^st(0) - 1 for -1 < st(0) < 1 1195 // F2XM1 calculates 2^st(0) - 1 for -1 < st(0) < 1
1195 __ f2xm1(); // 2^(X-rnd(X)) - 1, rnd(X) 1196 __ f2xm1(); // 2^(X-rnd(X)) - 1, rnd(X)
1196 __ fld1(); // 1, 2^(X-rnd(X)) - 1, rnd(X) 1197 __ fld1(); // 1, 2^(X-rnd(X)) - 1, rnd(X)
1197 __ faddp(1); // 2^(X-rnd(X)), rnd(X) 1198 __ faddp(1); // 2^(X-rnd(X)), rnd(X)
1198 // FSCALE calculates st(0) * 2^st(1) 1199 // FSCALE calculates st(0) * 2^st(1)
1199 __ fscale(); // 2^X, rnd(X) 1200 __ fscale(); // 2^X, rnd(X)
1200 __ fstp(1); // 2^X 1201 __ fstp(1); // 2^X
1201 // Bail out to runtime in case of exceptions in the status word. 1202 // Bail out to runtime in case of exceptions in the status word.
1202 __ fnstsw_ax(); 1203 __ fnstsw_ax();
1203 __ test_b(eax, 0x5F); // We check for all but precision exception. 1204 __ test_b(eax, 0x5F); // We check for all but precision exception.
1204 __ j(not_zero, &fast_power_failed, Label::kNear); 1205 __ j(not_zero, &fast_power_failed, Label::kNear);
1205 __ fstp_d(Operand(esp, 0)); 1206 __ fstp_d(Operand(esp, 0));
1206 __ movdbl(double_result, Operand(esp, 0)); 1207 __ movsd(double_result, Operand(esp, 0));
1207 __ add(esp, Immediate(kDoubleSize)); 1208 __ add(esp, Immediate(kDoubleSize));
1208 __ jmp(&done); 1209 __ jmp(&done);
1209 1210
1210 __ bind(&fast_power_failed); 1211 __ bind(&fast_power_failed);
1211 __ fninit(); 1212 __ fninit();
1212 __ add(esp, Immediate(kDoubleSize)); 1213 __ add(esp, Immediate(kDoubleSize));
1213 __ jmp(&call_runtime); 1214 __ jmp(&call_runtime);
1214 } 1215 }
1215 1216
1216 // Calculate power with integer exponent. 1217 // Calculate power with integer exponent.
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
1263 Counters* counters = masm->isolate()->counters(); 1264 Counters* counters = masm->isolate()->counters();
1264 if (exponent_type_ == ON_STACK) { 1265 if (exponent_type_ == ON_STACK) {
1265 // The arguments are still on the stack. 1266 // The arguments are still on the stack.
1266 __ bind(&call_runtime); 1267 __ bind(&call_runtime);
1267 __ TailCallRuntime(Runtime::kMath_pow_cfunction, 2, 1); 1268 __ TailCallRuntime(Runtime::kMath_pow_cfunction, 2, 1);
1268 1269
1269 // The stub is called from non-optimized code, which expects the result 1270 // The stub is called from non-optimized code, which expects the result
1270 // as heap number in exponent. 1271 // as heap number in exponent.
1271 __ bind(&done); 1272 __ bind(&done);
1272 __ AllocateHeapNumber(eax, scratch, base, &call_runtime); 1273 __ AllocateHeapNumber(eax, scratch, base, &call_runtime);
1273 __ movdbl(FieldOperand(eax, HeapNumber::kValueOffset), double_result); 1274 __ movsd(FieldOperand(eax, HeapNumber::kValueOffset), double_result);
1274 __ IncrementCounter(counters->math_pow(), 1); 1275 __ IncrementCounter(counters->math_pow(), 1);
1275 __ ret(2 * kPointerSize); 1276 __ ret(2 * kPointerSize);
1276 } else { 1277 } else {
1277 __ bind(&call_runtime); 1278 __ bind(&call_runtime);
1278 { 1279 {
1279 AllowExternalCallThatCantCauseGC scope(masm); 1280 AllowExternalCallThatCantCauseGC scope(masm);
1280 __ PrepareCallCFunction(4, scratch); 1281 __ PrepareCallCFunction(4, scratch);
1281 __ movdbl(Operand(esp, 0 * kDoubleSize), double_base); 1282 __ movsd(Operand(esp, 0 * kDoubleSize), double_base);
1282 __ movdbl(Operand(esp, 1 * kDoubleSize), double_exponent); 1283 __ movsd(Operand(esp, 1 * kDoubleSize), double_exponent);
1283 __ CallCFunction( 1284 __ CallCFunction(
1284 ExternalReference::power_double_double_function(masm->isolate()), 4); 1285 ExternalReference::power_double_double_function(masm->isolate()), 4);
1285 } 1286 }
1286 // Return value is in st(0) on ia32. 1287 // Return value is in st(0) on ia32.
1287 // Store it into the (fixed) result register. 1288 // Store it into the (fixed) result register.
1288 __ sub(esp, Immediate(kDoubleSize)); 1289 __ sub(esp, Immediate(kDoubleSize));
1289 __ fstp_d(Operand(esp, 0)); 1290 __ fstp_d(Operand(esp, 0));
1290 __ movdbl(double_result, Operand(esp, 0)); 1291 __ movsd(double_result, Operand(esp, 0));
1291 __ add(esp, Immediate(kDoubleSize)); 1292 __ add(esp, Immediate(kDoubleSize));
1292 1293
1293 __ bind(&done); 1294 __ bind(&done);
1294 __ IncrementCounter(counters->math_pow(), 1); 1295 __ IncrementCounter(counters->math_pow(), 1);
1295 __ ret(0); 1296 __ ret(0);
1296 } 1297 }
1297 } 1298 }
1298 1299
1299 1300
1300 void FunctionPrototypeStub::Generate(MacroAssembler* masm) { 1301 void FunctionPrototypeStub::Generate(MacroAssembler* masm) {
(...skipping 2629 matching lines...) Expand 10 before | Expand all | Expand 10 after
3930 // edi: length of second argument 3931 // edi: length of second argument
3931 StringHelper::GenerateCopyCharacters(masm, ecx, edx, edi, ebx, false); 3932 StringHelper::GenerateCopyCharacters(masm, ecx, edx, edi, ebx, false);
3932 __ IncrementCounter(counters->string_add_native(), 1); 3933 __ IncrementCounter(counters->string_add_native(), 1);
3933 __ ret(2 * kPointerSize); 3934 __ ret(2 * kPointerSize);
3934 3935
3935 // Recover stack pointer before jumping to runtime. 3936 // Recover stack pointer before jumping to runtime.
3936 __ bind(&call_runtime_drop_two); 3937 __ bind(&call_runtime_drop_two);
3937 __ Drop(2); 3938 __ Drop(2);
3938 // Just jump to runtime to add the two strings. 3939 // Just jump to runtime to add the two strings.
3939 __ bind(&call_runtime); 3940 __ bind(&call_runtime);
3940 if ((flags_ & STRING_ADD_ERECT_FRAME) != 0) { 3941 __ TailCallRuntime(Runtime::kStringAdd, 2, 1);
3941 GenerateRegisterArgsPop(masm, ecx);
3942 // Build a frame
3943 {
3944 FrameScope scope(masm, StackFrame::INTERNAL);
3945 GenerateRegisterArgsPush(masm);
3946 __ CallRuntime(Runtime::kStringAdd, 2);
3947 }
3948 __ ret(0);
3949 } else {
3950 __ TailCallRuntime(Runtime::kStringAdd, 2, 1);
3951 }
3952 3942
3953 if (call_builtin.is_linked()) { 3943 if (call_builtin.is_linked()) {
3954 __ bind(&call_builtin); 3944 __ bind(&call_builtin);
3955 if ((flags_ & STRING_ADD_ERECT_FRAME) != 0) { 3945 __ InvokeBuiltin(builtin_id, JUMP_FUNCTION);
3956 GenerateRegisterArgsPop(masm, ecx);
3957 // Build a frame
3958 {
3959 FrameScope scope(masm, StackFrame::INTERNAL);
3960 GenerateRegisterArgsPush(masm);
3961 __ InvokeBuiltin(builtin_id, CALL_FUNCTION);
3962 }
3963 __ ret(0);
3964 } else {
3965 __ InvokeBuiltin(builtin_id, JUMP_FUNCTION);
3966 }
3967 } 3946 }
3968 } 3947 }
3969 3948
3970 3949
3971 void StringAddStub::GenerateRegisterArgsPush(MacroAssembler* masm) { 3950 void StringAddStub::GenerateRegisterArgsPush(MacroAssembler* masm) {
3972 __ push(eax); 3951 __ push(eax);
3973 __ push(edx); 3952 __ push(edx);
3974 } 3953 }
3975 3954
3976 3955
(...skipping 746 matching lines...) Expand 10 before | Expand all | Expand 10 after
4723 if (CpuFeatures::IsSupported(SSE2) && CpuFeatures::IsSupported(CMOV)) { 4702 if (CpuFeatures::IsSupported(SSE2) && CpuFeatures::IsSupported(CMOV)) {
4724 CpuFeatureScope scope1(masm, SSE2); 4703 CpuFeatureScope scope1(masm, SSE2);
4725 CpuFeatureScope scope2(masm, CMOV); 4704 CpuFeatureScope scope2(masm, CMOV);
4726 4705
4727 // Load left and right operand. 4706 // Load left and right operand.
4728 Label done, left, left_smi, right_smi; 4707 Label done, left, left_smi, right_smi;
4729 __ JumpIfSmi(eax, &right_smi, Label::kNear); 4708 __ JumpIfSmi(eax, &right_smi, Label::kNear);
4730 __ cmp(FieldOperand(eax, HeapObject::kMapOffset), 4709 __ cmp(FieldOperand(eax, HeapObject::kMapOffset),
4731 masm->isolate()->factory()->heap_number_map()); 4710 masm->isolate()->factory()->heap_number_map());
4732 __ j(not_equal, &maybe_undefined1, Label::kNear); 4711 __ j(not_equal, &maybe_undefined1, Label::kNear);
4733 __ movdbl(xmm1, FieldOperand(eax, HeapNumber::kValueOffset)); 4712 __ movsd(xmm1, FieldOperand(eax, HeapNumber::kValueOffset));
4734 __ jmp(&left, Label::kNear); 4713 __ jmp(&left, Label::kNear);
4735 __ bind(&right_smi); 4714 __ bind(&right_smi);
4736 __ mov(ecx, eax); // Can't clobber eax because we can still jump away. 4715 __ mov(ecx, eax); // Can't clobber eax because we can still jump away.
4737 __ SmiUntag(ecx); 4716 __ SmiUntag(ecx);
4738 __ Cvtsi2sd(xmm1, ecx); 4717 __ Cvtsi2sd(xmm1, ecx);
4739 4718
4740 __ bind(&left); 4719 __ bind(&left);
4741 __ JumpIfSmi(edx, &left_smi, Label::kNear); 4720 __ JumpIfSmi(edx, &left_smi, Label::kNear);
4742 __ cmp(FieldOperand(edx, HeapObject::kMapOffset), 4721 __ cmp(FieldOperand(edx, HeapObject::kMapOffset),
4743 masm->isolate()->factory()->heap_number_map()); 4722 masm->isolate()->factory()->heap_number_map());
4744 __ j(not_equal, &maybe_undefined2, Label::kNear); 4723 __ j(not_equal, &maybe_undefined2, Label::kNear);
4745 __ movdbl(xmm0, FieldOperand(edx, HeapNumber::kValueOffset)); 4724 __ movsd(xmm0, FieldOperand(edx, HeapNumber::kValueOffset));
4746 __ jmp(&done); 4725 __ jmp(&done);
4747 __ bind(&left_smi); 4726 __ bind(&left_smi);
4748 __ mov(ecx, edx); // Can't clobber edx because we can still jump away. 4727 __ mov(ecx, edx); // Can't clobber edx because we can still jump away.
4749 __ SmiUntag(ecx); 4728 __ SmiUntag(ecx);
4750 __ Cvtsi2sd(xmm0, ecx); 4729 __ Cvtsi2sd(xmm0, ecx);
4751 4730
4752 __ bind(&done); 4731 __ bind(&done);
4753 // Compare operands. 4732 // Compare operands.
4754 __ ucomisd(xmm0, xmm1); 4733 __ ucomisd(xmm0, xmm1);
4755 4734
(...skipping 1266 matching lines...) Expand 10 before | Expand all | Expand 10 after
6022 __ bind(&fast_elements_case); 6001 __ bind(&fast_elements_case);
6023 GenerateCase(masm, FAST_ELEMENTS); 6002 GenerateCase(masm, FAST_ELEMENTS);
6024 } 6003 }
6025 6004
6026 6005
6027 #undef __ 6006 #undef __
6028 6007
6029 } } // namespace v8::internal 6008 } } // namespace v8::internal
6030 6009
6031 #endif // V8_TARGET_ARCH_IA32 6010 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/ia32/code-stubs-ia32.h ('k') | src/ia32/codegen-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698