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

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

Issue 275433004: Require SSE2 support for the ia32 port. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 7 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
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "v8.h" 5 #include "v8.h"
6 6
7 #if V8_TARGET_ARCH_IA32 7 #if V8_TARGET_ARCH_IA32
8 8
9 #include "bootstrapper.h" 9 #include "bootstrapper.h"
10 #include "code-stubs.h" 10 #include "code-stubs.h"
(...skipping 438 matching lines...) Expand 10 before | Expand all | Expand 10 after
449 __ ret(0); 449 __ ret(0);
450 } 450 }
451 451
452 452
453 void StoreBufferOverflowStub::Generate(MacroAssembler* masm) { 453 void StoreBufferOverflowStub::Generate(MacroAssembler* masm) {
454 // We don't allow a GC during a store buffer overflow so there is no need to 454 // We don't allow a GC during a store buffer overflow so there is no need to
455 // store the registers in any particular way, but we do have to store and 455 // store the registers in any particular way, but we do have to store and
456 // restore them. 456 // restore them.
457 __ pushad(); 457 __ pushad();
458 if (save_doubles_ == kSaveFPRegs) { 458 if (save_doubles_ == kSaveFPRegs) {
459 CpuFeatureScope scope(masm, SSE2);
460 __ sub(esp, Immediate(kDoubleSize * XMMRegister::kNumRegisters)); 459 __ sub(esp, Immediate(kDoubleSize * XMMRegister::kNumRegisters));
461 for (int i = 0; i < XMMRegister::kNumRegisters; i++) { 460 for (int i = 0; i < XMMRegister::kNumRegisters; i++) {
462 XMMRegister reg = XMMRegister::from_code(i); 461 XMMRegister reg = XMMRegister::from_code(i);
463 __ movsd(Operand(esp, i * kDoubleSize), reg); 462 __ movsd(Operand(esp, i * kDoubleSize), reg);
464 } 463 }
465 } 464 }
466 const int argument_count = 1; 465 const int argument_count = 1;
467 466
468 AllowExternalCallThatCantCauseGC scope(masm); 467 AllowExternalCallThatCantCauseGC scope(masm);
469 __ PrepareCallCFunction(argument_count, ecx); 468 __ PrepareCallCFunction(argument_count, ecx);
470 __ mov(Operand(esp, 0 * kPointerSize), 469 __ mov(Operand(esp, 0 * kPointerSize),
471 Immediate(ExternalReference::isolate_address(isolate()))); 470 Immediate(ExternalReference::isolate_address(isolate())));
472 __ CallCFunction( 471 __ CallCFunction(
473 ExternalReference::store_buffer_overflow_function(isolate()), 472 ExternalReference::store_buffer_overflow_function(isolate()),
474 argument_count); 473 argument_count);
475 if (save_doubles_ == kSaveFPRegs) { 474 if (save_doubles_ == kSaveFPRegs) {
476 CpuFeatureScope scope(masm, SSE2);
477 for (int i = 0; i < XMMRegister::kNumRegisters; i++) { 475 for (int i = 0; i < XMMRegister::kNumRegisters; i++) {
478 XMMRegister reg = XMMRegister::from_code(i); 476 XMMRegister reg = XMMRegister::from_code(i);
479 __ movsd(reg, Operand(esp, i * kDoubleSize)); 477 __ movsd(reg, Operand(esp, i * kDoubleSize));
480 } 478 }
481 __ add(esp, Immediate(kDoubleSize * XMMRegister::kNumRegisters)); 479 __ add(esp, Immediate(kDoubleSize * XMMRegister::kNumRegisters));
482 } 480 }
483 __ popad(); 481 __ popad();
484 __ ret(0); 482 __ ret(0);
485 } 483 }
486 484
(...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after
719 __ mov(scratch, FieldOperand(eax, HeapObject::kMapOffset)); 717 __ mov(scratch, FieldOperand(eax, HeapObject::kMapOffset));
720 __ cmp(scratch, factory->heap_number_map()); 718 __ cmp(scratch, factory->heap_number_map());
721 __ j(not_equal, non_float); // argument in eax is not a number -> NaN 719 __ j(not_equal, non_float); // argument in eax is not a number -> NaN
722 720
723 // Fall-through: Both operands are numbers. 721 // Fall-through: Both operands are numbers.
724 __ bind(&done); 722 __ bind(&done);
725 } 723 }
726 724
727 725
728 void MathPowStub::Generate(MacroAssembler* masm) { 726 void MathPowStub::Generate(MacroAssembler* masm) {
729 CpuFeatureScope use_sse2(masm, SSE2);
730 Factory* factory = isolate()->factory(); 727 Factory* factory = isolate()->factory();
731 const Register exponent = eax; 728 const Register exponent = eax;
732 const Register base = edx; 729 const Register base = edx;
733 const Register scratch = ecx; 730 const Register scratch = ecx;
734 const XMMRegister double_result = xmm3; 731 const XMMRegister double_result = xmm3;
735 const XMMRegister double_base = xmm2; 732 const XMMRegister double_base = xmm2;
736 const XMMRegister double_exponent = xmm1; 733 const XMMRegister double_exponent = xmm1;
737 const XMMRegister double_scratch = xmm4; 734 const XMMRegister double_scratch = xmm4;
738 735
739 Label call_runtime, done, exponent_not_smi, int_exponent; 736 Label call_runtime, done, exponent_not_smi, int_exponent;
(...skipping 1294 matching lines...) Expand 10 before | Expand all | Expand 10 after
2034 __ j(equal, &return_not_equal); 2031 __ j(equal, &return_not_equal);
2035 2032
2036 // Fall through to the general case. 2033 // Fall through to the general case.
2037 __ bind(&slow); 2034 __ bind(&slow);
2038 } 2035 }
2039 2036
2040 // Generate the number comparison code. 2037 // Generate the number comparison code.
2041 Label non_number_comparison; 2038 Label non_number_comparison;
2042 Label unordered; 2039 Label unordered;
2043 __ bind(&generic_heap_number_comparison); 2040 __ bind(&generic_heap_number_comparison);
2044 if (CpuFeatures::IsSupported(SSE2)) { 2041
2045 CpuFeatureScope use_sse2(masm, SSE2); 2042 FloatingPointHelper::LoadSSE2Operands(masm, &non_number_comparison);
2043 __ ucomisd(xmm0, xmm1);
2044 // Don't base result on EFLAGS when a NaN is involved.
2045 __ j(parity_even, &unordered, Label::kNear);
2046
2047 if (CpuFeatures::IsSupported(CMOV)) {
2046 CpuFeatureScope use_cmov(masm, CMOV); 2048 CpuFeatureScope use_cmov(masm, CMOV);
2047
2048 FloatingPointHelper::LoadSSE2Operands(masm, &non_number_comparison);
2049 __ ucomisd(xmm0, xmm1);
2050
2051 // Don't base result on EFLAGS when a NaN is involved.
2052 __ j(parity_even, &unordered, Label::kNear);
2053 // Return a result of -1, 0, or 1, based on EFLAGS. 2049 // Return a result of -1, 0, or 1, based on EFLAGS.
2054 __ mov(eax, 0); // equal 2050 __ mov(eax, 0); // equal
2055 __ mov(ecx, Immediate(Smi::FromInt(1))); 2051 __ mov(ecx, Immediate(Smi::FromInt(1)));
2056 __ cmov(above, eax, ecx); 2052 __ cmov(above, eax, ecx);
2057 __ mov(ecx, Immediate(Smi::FromInt(-1))); 2053 __ mov(ecx, Immediate(Smi::FromInt(-1)));
2058 __ cmov(below, eax, ecx); 2054 __ cmov(below, eax, ecx);
2059 __ ret(0); 2055 __ ret(0);
2060 } else { 2056 } else {
2061 FloatingPointHelper::CheckFloatOperands(
2062 masm, &non_number_comparison, ebx);
2063 FloatingPointHelper::LoadFloatOperand(masm, eax);
2064 FloatingPointHelper::LoadFloatOperand(masm, edx);
2065 __ FCmp();
2066
2067 // Don't base result on EFLAGS when a NaN is involved.
2068 __ j(parity_even, &unordered, Label::kNear);
2069
2070 Label below_label, above_label; 2057 Label below_label, above_label;
2071 // Return a result of -1, 0, or 1, based on EFLAGS. 2058 // Return a result of -1, 0, or 1, based on EFLAGS.
2072 __ j(below, &below_label, Label::kNear); 2059 __ j(below, &below_label, Label::kNear);
2073 __ j(above, &above_label, Label::kNear); 2060 __ j(above, &above_label, Label::kNear);
2074 2061
2075 __ Move(eax, Immediate(0)); 2062 __ Move(eax, Immediate(0));
2076 __ ret(0); 2063 __ ret(0);
2077 2064
2078 __ bind(&below_label); 2065 __ bind(&below_label);
2079 __ mov(eax, Immediate(Smi::FromInt(-1))); 2066 __ mov(eax, Immediate(Smi::FromInt(-1)));
(...skipping 517 matching lines...) Expand 10 before | Expand all | Expand 10 after
2597 } 2584 }
2598 2585
2599 2586
2600 void CodeStub::GenerateStubsAheadOfTime(Isolate* isolate) { 2587 void CodeStub::GenerateStubsAheadOfTime(Isolate* isolate) {
2601 CEntryStub::GenerateAheadOfTime(isolate); 2588 CEntryStub::GenerateAheadOfTime(isolate);
2602 StoreBufferOverflowStub::GenerateFixedRegStubsAheadOfTime(isolate); 2589 StoreBufferOverflowStub::GenerateFixedRegStubsAheadOfTime(isolate);
2603 StubFailureTrampolineStub::GenerateAheadOfTime(isolate); 2590 StubFailureTrampolineStub::GenerateAheadOfTime(isolate);
2604 // It is important that the store buffer overflow stubs are generated first. 2591 // It is important that the store buffer overflow stubs are generated first.
2605 ArrayConstructorStubBase::GenerateStubsAheadOfTime(isolate); 2592 ArrayConstructorStubBase::GenerateStubsAheadOfTime(isolate);
2606 CreateAllocationSiteStub::GenerateAheadOfTime(isolate); 2593 CreateAllocationSiteStub::GenerateAheadOfTime(isolate);
2607 if (Serializer::enabled(isolate)) { 2594 BinaryOpICStub::GenerateAheadOfTime(isolate);
2608 PlatformFeatureScope sse2(isolate, SSE2); 2595 BinaryOpICWithAllocationSiteStub::GenerateAheadOfTime(isolate);
2609 BinaryOpICStub::GenerateAheadOfTime(isolate);
2610 BinaryOpICWithAllocationSiteStub::GenerateAheadOfTime(isolate);
2611 } else {
2612 BinaryOpICStub::GenerateAheadOfTime(isolate);
2613 BinaryOpICWithAllocationSiteStub::GenerateAheadOfTime(isolate);
2614 }
2615 } 2596 }
2616 2597
2617 2598
2618 void CodeStub::GenerateFPStubs(Isolate* isolate) { 2599 void CodeStub::GenerateFPStubs(Isolate* isolate) {
2619 if (CpuFeatures::IsSupported(SSE2)) { 2600 CEntryStub save_doubles(isolate, 1, kSaveFPRegs);
2620 CEntryStub save_doubles(isolate, 1, kSaveFPRegs); 2601 // Stubs might already be in the snapshot, detect that and don't regenerate,
2621 // Stubs might already be in the snapshot, detect that and don't regenerate, 2602 // which would lead to code stub initialization state being messed up.
2622 // which would lead to code stub initialization state being messed up. 2603 Code* save_doubles_code;
2623 Code* save_doubles_code; 2604 if (!save_doubles.FindCodeInCache(&save_doubles_code)) {
2624 if (!save_doubles.FindCodeInCache(&save_doubles_code)) { 2605 save_doubles_code = *(save_doubles.GetCode());
2625 save_doubles_code = *(save_doubles.GetCode());
2626 }
2627 isolate->set_fp_stubs_generated(true);
2628 } 2606 }
2607 isolate->set_fp_stubs_generated(true);
2629 } 2608 }
2630 2609
2631 2610
2632 void CEntryStub::GenerateAheadOfTime(Isolate* isolate) { 2611 void CEntryStub::GenerateAheadOfTime(Isolate* isolate) {
2633 CEntryStub stub(isolate, 1, kDontSaveFPRegs); 2612 CEntryStub stub(isolate, 1, kDontSaveFPRegs);
2634 stub.GetCode(); 2613 stub.GetCode();
2635 } 2614 }
2636 2615
2637 2616
2638 void CEntryStub::Generate(MacroAssembler* masm) { 2617 void CEntryStub::Generate(MacroAssembler* masm) {
(...skipping 1129 matching lines...) Expand 10 before | Expand all | Expand 10 after
3768 3747
3769 if (left_ == CompareIC::SMI) { 3748 if (left_ == CompareIC::SMI) {
3770 __ JumpIfNotSmi(edx, &miss); 3749 __ JumpIfNotSmi(edx, &miss);
3771 } 3750 }
3772 if (right_ == CompareIC::SMI) { 3751 if (right_ == CompareIC::SMI) {
3773 __ JumpIfNotSmi(eax, &miss); 3752 __ JumpIfNotSmi(eax, &miss);
3774 } 3753 }
3775 3754
3776 // Inlining the double comparison and falling back to the general compare 3755 // Inlining the double comparison and falling back to the general compare
3777 // stub if NaN is involved or SSE2 or CMOV is unsupported. 3756 // stub if NaN is involved or SSE2 or CMOV is unsupported.
3778 if (CpuFeatures::IsSupported(SSE2) && CpuFeatures::IsSupported(CMOV)) { 3757 if (CpuFeatures::IsSupported(CMOV)) {
3779 CpuFeatureScope scope1(masm, SSE2);
3780 CpuFeatureScope scope2(masm, CMOV); 3758 CpuFeatureScope scope2(masm, CMOV);
3781 3759
3782 // Load left and right operand. 3760 // Load left and right operand.
3783 Label done, left, left_smi, right_smi; 3761 Label done, left, left_smi, right_smi;
3784 __ JumpIfSmi(eax, &right_smi, Label::kNear); 3762 __ JumpIfSmi(eax, &right_smi, Label::kNear);
3785 __ cmp(FieldOperand(eax, HeapObject::kMapOffset), 3763 __ cmp(FieldOperand(eax, HeapObject::kMapOffset),
3786 isolate()->factory()->heap_number_map()); 3764 isolate()->factory()->heap_number_map());
3787 __ j(not_equal, &maybe_undefined1, Label::kNear); 3765 __ j(not_equal, &maybe_undefined1, Label::kNear);
3788 __ movsd(xmm1, FieldOperand(eax, HeapNumber::kValueOffset)); 3766 __ movsd(xmm1, FieldOperand(eax, HeapNumber::kValueOffset));
3789 __ jmp(&left, Label::kNear); 3767 __ jmp(&left, Label::kNear);
(...skipping 525 matching lines...) Expand 10 before | Expand all | Expand 10 after
4315 __ mov(result_, Immediate(0)); 4293 __ mov(result_, Immediate(0));
4316 __ Drop(1); 4294 __ Drop(1);
4317 __ ret(2 * kPointerSize); 4295 __ ret(2 * kPointerSize);
4318 } 4296 }
4319 4297
4320 4298
4321 void StoreBufferOverflowStub::GenerateFixedRegStubsAheadOfTime( 4299 void StoreBufferOverflowStub::GenerateFixedRegStubsAheadOfTime(
4322 Isolate* isolate) { 4300 Isolate* isolate) {
4323 StoreBufferOverflowStub stub(isolate, kDontSaveFPRegs); 4301 StoreBufferOverflowStub stub(isolate, kDontSaveFPRegs);
4324 stub.GetCode(); 4302 stub.GetCode();
4325 if (CpuFeatures::IsSafeForSnapshot(isolate, SSE2)) { 4303 StoreBufferOverflowStub stub2(isolate, kSaveFPRegs);
4326 StoreBufferOverflowStub stub2(isolate, kSaveFPRegs); 4304 stub2.GetCode();
4327 stub2.GetCode();
4328 }
4329 } 4305 }
4330 4306
4331 4307
4332 bool CodeStub::CanUseFPRegisters() { 4308 bool CodeStub::CanUseFPRegisters() {
Sven Panne 2014/05/07 13:46:03 We can nuke CanUseFPRegisters, it is always true o
4333 return CpuFeatures::IsSupported(SSE2); 4309 return true; // SSE2 support is mandatory.
4334 } 4310 }
4335 4311
4336 4312
4337 // Takes the input in 3 registers: address_ value_ and object_. A pointer to 4313 // Takes the input in 3 registers: address_ value_ and object_. A pointer to
4338 // the value has just been written into the object, now this stub makes sure 4314 // the value has just been written into the object, now this stub makes sure
4339 // we keep the GC informed. The word in the object where the value has been 4315 // we keep the GC informed. The word in the object where the value has been
4340 // written is in the address register. 4316 // written is in the address register.
4341 void RecordWriteStub::Generate(MacroAssembler* masm) { 4317 void RecordWriteStub::Generate(MacroAssembler* masm) {
4342 Label skip_to_incremental_noncompacting; 4318 Label skip_to_incremental_noncompacting;
4343 Label skip_to_incremental_compacting; 4319 Label skip_to_incremental_compacting;
(...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after
4599 // Array literal has ElementsKind of FAST_*_DOUBLE_ELEMENTS. 4575 // Array literal has ElementsKind of FAST_*_DOUBLE_ELEMENTS.
4600 __ bind(&double_elements); 4576 __ bind(&double_elements);
4601 4577
4602 __ push(edx); 4578 __ push(edx);
4603 __ mov(edx, FieldOperand(ebx, JSObject::kElementsOffset)); 4579 __ mov(edx, FieldOperand(ebx, JSObject::kElementsOffset));
4604 __ StoreNumberToDoubleElements(eax, 4580 __ StoreNumberToDoubleElements(eax,
4605 edx, 4581 edx,
4606 ecx, 4582 ecx,
4607 edi, 4583 edi,
4608 xmm0, 4584 xmm0,
4609 &slow_elements_from_double, 4585 &slow_elements_from_double);
4610 false);
4611 __ pop(edx); 4586 __ pop(edx);
4612 __ ret(0); 4587 __ ret(0);
4613 } 4588 }
4614 4589
4615 4590
4616 void StubFailureTrampolineStub::Generate(MacroAssembler* masm) { 4591 void StubFailureTrampolineStub::Generate(MacroAssembler* masm) {
4617 CEntryStub ces(isolate(), 1, fp_registers_ ? kSaveFPRegs : kDontSaveFPRegs); 4592 CEntryStub ces(isolate(), 1, fp_registers_ ? kSaveFPRegs : kDontSaveFPRegs);
4618 __ call(ces.GetCode(), RelocInfo::CODE_TARGET); 4593 __ call(ces.GetCode(), RelocInfo::CODE_TARGET);
4619 int parameter_count_offset = 4594 int parameter_count_offset =
4620 StubFailureTrampolineFrame::kCallerStackParameterCountFrameOffset; 4595 StubFailureTrampolineFrame::kCallerStackParameterCountFrameOffset;
(...skipping 513 matching lines...) Expand 10 before | Expand all | Expand 10 after
5134 Operand(ebp, 7 * kPointerSize), 5109 Operand(ebp, 7 * kPointerSize),
5135 NULL); 5110 NULL);
5136 } 5111 }
5137 5112
5138 5113
5139 #undef __ 5114 #undef __
5140 5115
5141 } } // namespace v8::internal 5116 } } // namespace v8::internal
5142 5117
5143 #endif // V8_TARGET_ARCH_IA32 5118 #endif // V8_TARGET_ARCH_IA32
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698