OLD | NEW |
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_X87 |
8 | 8 |
9 #include "ic-inl.h" | 9 #include "ic-inl.h" |
10 #include "codegen.h" | 10 #include "codegen.h" |
11 #include "stub-cache.h" | 11 #include "stub-cache.h" |
12 | 12 |
13 namespace v8 { | 13 namespace v8 { |
14 namespace internal { | 14 namespace internal { |
15 | 15 |
16 #define __ ACCESS_MASM(masm) | 16 #define __ ACCESS_MASM(masm) |
17 | 17 |
(...skipping 502 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
520 __ j(equal, &do_store, Label::kNear); | 520 __ j(equal, &do_store, Label::kNear); |
521 } | 521 } |
522 __ bind(&do_store); | 522 __ bind(&do_store); |
523 } | 523 } |
524 } else if (representation.IsDouble()) { | 524 } else if (representation.IsDouble()) { |
525 Label do_store, heap_number; | 525 Label do_store, heap_number; |
526 __ AllocateHeapNumber(storage_reg, scratch1, scratch2, slow); | 526 __ AllocateHeapNumber(storage_reg, scratch1, scratch2, slow); |
527 | 527 |
528 __ JumpIfNotSmi(value_reg, &heap_number); | 528 __ JumpIfNotSmi(value_reg, &heap_number); |
529 __ SmiUntag(value_reg); | 529 __ SmiUntag(value_reg); |
530 __ Cvtsi2sd(xmm0, value_reg); | 530 __ push(value_reg); |
| 531 __ fild_s(Operand(esp, 0)); |
| 532 __ pop(value_reg); |
531 __ SmiTag(value_reg); | 533 __ SmiTag(value_reg); |
532 __ jmp(&do_store); | 534 __ jmp(&do_store); |
533 | 535 |
534 __ bind(&heap_number); | 536 __ bind(&heap_number); |
535 __ CheckMap(value_reg, masm->isolate()->factory()->heap_number_map(), | 537 __ CheckMap(value_reg, masm->isolate()->factory()->heap_number_map(), |
536 miss_label, DONT_DO_SMI_CHECK); | 538 miss_label, DONT_DO_SMI_CHECK); |
537 __ movsd(xmm0, FieldOperand(value_reg, HeapNumber::kValueOffset)); | 539 __ fld_d(FieldOperand(value_reg, HeapNumber::kValueOffset)); |
538 | 540 |
539 __ bind(&do_store); | 541 __ bind(&do_store); |
540 __ movsd(FieldOperand(storage_reg, HeapNumber::kValueOffset), xmm0); | 542 __ fstp_d(FieldOperand(storage_reg, HeapNumber::kValueOffset)); |
541 } | 543 } |
542 | 544 |
543 // Stub never generated for non-global objects that require access | 545 // Stub never generated for non-global objects that require access |
544 // checks. | 546 // checks. |
545 ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded()); | 547 ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded()); |
546 | 548 |
547 // Perform map transition for the receiver if necessary. | 549 // Perform map transition for the receiver if necessary. |
548 if (details.type() == FIELD && | 550 if (details.type() == FIELD && |
549 object->map()->unused_property_fields() == 0) { | 551 object->map()->unused_property_fields() == 0) { |
550 // The properties must be extended before we can store the value. | 552 // The properties must be extended before we can store the value. |
(...skipping 13 matching lines...) Expand all Loading... |
564 | 566 |
565 // Update the map of the object. | 567 // Update the map of the object. |
566 __ mov(scratch1, Immediate(transition)); | 568 __ mov(scratch1, Immediate(transition)); |
567 __ mov(FieldOperand(receiver_reg, HeapObject::kMapOffset), scratch1); | 569 __ mov(FieldOperand(receiver_reg, HeapObject::kMapOffset), scratch1); |
568 | 570 |
569 // Update the write barrier for the map field. | 571 // Update the write barrier for the map field. |
570 __ RecordWriteField(receiver_reg, | 572 __ RecordWriteField(receiver_reg, |
571 HeapObject::kMapOffset, | 573 HeapObject::kMapOffset, |
572 scratch1, | 574 scratch1, |
573 scratch2, | 575 scratch2, |
574 kDontSaveFPRegs, | |
575 OMIT_REMEMBERED_SET, | 576 OMIT_REMEMBERED_SET, |
576 OMIT_SMI_CHECK); | 577 OMIT_SMI_CHECK); |
577 | 578 |
578 if (details.type() == CONSTANT) { | 579 if (details.type() == CONSTANT) { |
579 ASSERT(value_reg.is(eax)); | 580 ASSERT(value_reg.is(eax)); |
580 __ ret(0); | 581 __ ret(0); |
581 return; | 582 return; |
582 } | 583 } |
583 | 584 |
584 int index = transition->instance_descriptors()->GetFieldIndex( | 585 int index = transition->instance_descriptors()->GetFieldIndex( |
(...skipping 18 matching lines...) Expand all Loading... |
603 | 604 |
604 if (!representation.IsSmi()) { | 605 if (!representation.IsSmi()) { |
605 // Update the write barrier for the array address. | 606 // Update the write barrier for the array address. |
606 if (!representation.IsDouble()) { | 607 if (!representation.IsDouble()) { |
607 __ mov(storage_reg, value_reg); | 608 __ mov(storage_reg, value_reg); |
608 } | 609 } |
609 __ RecordWriteField(receiver_reg, | 610 __ RecordWriteField(receiver_reg, |
610 offset, | 611 offset, |
611 storage_reg, | 612 storage_reg, |
612 scratch1, | 613 scratch1, |
613 kDontSaveFPRegs, | |
614 EMIT_REMEMBERED_SET, | 614 EMIT_REMEMBERED_SET, |
615 smi_check); | 615 smi_check); |
616 } | 616 } |
617 } else { | 617 } else { |
618 // Write to the properties array. | 618 // Write to the properties array. |
619 int offset = index * kPointerSize + FixedArray::kHeaderSize; | 619 int offset = index * kPointerSize + FixedArray::kHeaderSize; |
620 // Get the properties array (optimistically). | 620 // Get the properties array (optimistically). |
621 __ mov(scratch1, FieldOperand(receiver_reg, JSObject::kPropertiesOffset)); | 621 __ mov(scratch1, FieldOperand(receiver_reg, JSObject::kPropertiesOffset)); |
622 if (representation.IsDouble()) { | 622 if (representation.IsDouble()) { |
623 __ mov(FieldOperand(scratch1, offset), storage_reg); | 623 __ mov(FieldOperand(scratch1, offset), storage_reg); |
624 } else { | 624 } else { |
625 __ mov(FieldOperand(scratch1, offset), value_reg); | 625 __ mov(FieldOperand(scratch1, offset), value_reg); |
626 } | 626 } |
627 | 627 |
628 if (!representation.IsSmi()) { | 628 if (!representation.IsSmi()) { |
629 // Update the write barrier for the array address. | 629 // Update the write barrier for the array address. |
630 if (!representation.IsDouble()) { | 630 if (!representation.IsDouble()) { |
631 __ mov(storage_reg, value_reg); | 631 __ mov(storage_reg, value_reg); |
632 } | 632 } |
633 __ RecordWriteField(scratch1, | 633 __ RecordWriteField(scratch1, |
634 offset, | 634 offset, |
635 storage_reg, | 635 storage_reg, |
636 receiver_reg, | 636 receiver_reg, |
637 kDontSaveFPRegs, | |
638 EMIT_REMEMBERED_SET, | 637 EMIT_REMEMBERED_SET, |
639 smi_check); | 638 smi_check); |
640 } | 639 } |
641 } | 640 } |
642 | 641 |
643 // Return the value (register eax). | 642 // Return the value (register eax). |
644 ASSERT(value_reg.is(eax)); | 643 ASSERT(value_reg.is(eax)); |
645 __ ret(0); | 644 __ ret(0); |
646 } | 645 } |
647 | 646 |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
697 } else { | 696 } else { |
698 __ mov(scratch1, FieldOperand(receiver_reg, JSObject::kPropertiesOffset)); | 697 __ mov(scratch1, FieldOperand(receiver_reg, JSObject::kPropertiesOffset)); |
699 int offset = index * kPointerSize + FixedArray::kHeaderSize; | 698 int offset = index * kPointerSize + FixedArray::kHeaderSize; |
700 __ mov(scratch1, FieldOperand(scratch1, offset)); | 699 __ mov(scratch1, FieldOperand(scratch1, offset)); |
701 } | 700 } |
702 | 701 |
703 // Store the value into the storage. | 702 // Store the value into the storage. |
704 Label do_store, heap_number; | 703 Label do_store, heap_number; |
705 __ JumpIfNotSmi(value_reg, &heap_number); | 704 __ JumpIfNotSmi(value_reg, &heap_number); |
706 __ SmiUntag(value_reg); | 705 __ SmiUntag(value_reg); |
707 __ Cvtsi2sd(xmm0, value_reg); | 706 __ push(value_reg); |
| 707 __ fild_s(Operand(esp, 0)); |
| 708 __ pop(value_reg); |
708 __ SmiTag(value_reg); | 709 __ SmiTag(value_reg); |
709 __ jmp(&do_store); | 710 __ jmp(&do_store); |
710 __ bind(&heap_number); | 711 __ bind(&heap_number); |
711 __ CheckMap(value_reg, masm->isolate()->factory()->heap_number_map(), | 712 __ CheckMap(value_reg, masm->isolate()->factory()->heap_number_map(), |
712 miss_label, DONT_DO_SMI_CHECK); | 713 miss_label, DONT_DO_SMI_CHECK); |
713 __ movsd(xmm0, FieldOperand(value_reg, HeapNumber::kValueOffset)); | 714 __ fld_d(FieldOperand(value_reg, HeapNumber::kValueOffset)); |
714 __ bind(&do_store); | 715 __ bind(&do_store); |
715 __ movsd(FieldOperand(scratch1, HeapNumber::kValueOffset), xmm0); | 716 __ fstp_d(FieldOperand(scratch1, HeapNumber::kValueOffset)); |
716 // Return the value (register eax). | 717 // Return the value (register eax). |
717 ASSERT(value_reg.is(eax)); | 718 ASSERT(value_reg.is(eax)); |
718 __ ret(0); | 719 __ ret(0); |
719 return; | 720 return; |
720 } | 721 } |
721 | 722 |
722 ASSERT(!representation.IsDouble()); | 723 ASSERT(!representation.IsDouble()); |
723 // TODO(verwaest): Share this code as a code stub. | 724 // TODO(verwaest): Share this code as a code stub. |
724 SmiCheck smi_check = representation.IsTagged() | 725 SmiCheck smi_check = representation.IsTagged() |
725 ? INLINE_SMI_CHECK : OMIT_SMI_CHECK; | 726 ? INLINE_SMI_CHECK : OMIT_SMI_CHECK; |
726 if (index < 0) { | 727 if (index < 0) { |
727 // Set the property straight into the object. | 728 // Set the property straight into the object. |
728 int offset = object->map()->instance_size() + (index * kPointerSize); | 729 int offset = object->map()->instance_size() + (index * kPointerSize); |
729 __ mov(FieldOperand(receiver_reg, offset), value_reg); | 730 __ mov(FieldOperand(receiver_reg, offset), value_reg); |
730 | 731 |
731 if (!representation.IsSmi()) { | 732 if (!representation.IsSmi()) { |
732 // Update the write barrier for the array address. | 733 // Update the write barrier for the array address. |
733 // Pass the value being stored in the now unused name_reg. | 734 // Pass the value being stored in the now unused name_reg. |
734 __ mov(name_reg, value_reg); | 735 __ mov(name_reg, value_reg); |
735 __ RecordWriteField(receiver_reg, | 736 __ RecordWriteField(receiver_reg, |
736 offset, | 737 offset, |
737 name_reg, | 738 name_reg, |
738 scratch1, | 739 scratch1, |
739 kDontSaveFPRegs, | |
740 EMIT_REMEMBERED_SET, | 740 EMIT_REMEMBERED_SET, |
741 smi_check); | 741 smi_check); |
742 } | 742 } |
743 } else { | 743 } else { |
744 // Write to the properties array. | 744 // Write to the properties array. |
745 int offset = index * kPointerSize + FixedArray::kHeaderSize; | 745 int offset = index * kPointerSize + FixedArray::kHeaderSize; |
746 // Get the properties array (optimistically). | 746 // Get the properties array (optimistically). |
747 __ mov(scratch1, FieldOperand(receiver_reg, JSObject::kPropertiesOffset)); | 747 __ mov(scratch1, FieldOperand(receiver_reg, JSObject::kPropertiesOffset)); |
748 __ mov(FieldOperand(scratch1, offset), value_reg); | 748 __ mov(FieldOperand(scratch1, offset), value_reg); |
749 | 749 |
750 if (!representation.IsSmi()) { | 750 if (!representation.IsSmi()) { |
751 // Update the write barrier for the array address. | 751 // Update the write barrier for the array address. |
752 // Pass the value being stored in the now unused name_reg. | 752 // Pass the value being stored in the now unused name_reg. |
753 __ mov(name_reg, value_reg); | 753 __ mov(name_reg, value_reg); |
754 __ RecordWriteField(scratch1, | 754 __ RecordWriteField(scratch1, |
755 offset, | 755 offset, |
756 name_reg, | 756 name_reg, |
757 receiver_reg, | 757 receiver_reg, |
758 kDontSaveFPRegs, | |
759 EMIT_REMEMBERED_SET, | 758 EMIT_REMEMBERED_SET, |
760 smi_check); | 759 smi_check); |
761 } | 760 } |
762 } | 761 } |
763 | 762 |
764 // Return the value (register eax). | 763 // Return the value (register eax). |
765 ASSERT(value_reg.is(eax)); | 764 ASSERT(value_reg.is(eax)); |
766 __ ret(0); | 765 __ ret(0); |
767 } | 766 } |
768 | 767 |
(...skipping 730 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1499 // -- esp[0] : return address | 1498 // -- esp[0] : return address |
1500 // ----------------------------------- | 1499 // ----------------------------------- |
1501 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss); | 1500 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss); |
1502 } | 1501 } |
1503 | 1502 |
1504 | 1503 |
1505 #undef __ | 1504 #undef __ |
1506 | 1505 |
1507 } } // namespace v8::internal | 1506 } } // namespace v8::internal |
1508 | 1507 |
1509 #endif // V8_TARGET_ARCH_IA32 | 1508 #endif // V8_TARGET_ARCH_X87 |
OLD | NEW |