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

Side by Side Diff: src/x64/lithium-codegen-x64.cc

Issue 11238016: Consolidated all the key store/load classes in the Hydrogen and Lithium (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Fixed the 2 failing mjsunit tests Created 8 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
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 2594 matching lines...) Expand 10 before | Expand all | Expand 10 after
2605 // Subtracting from length accounts for one of them add one more. 2605 // Subtracting from length accounts for one of them add one more.
2606 if (instr->index()->IsRegister()) { 2606 if (instr->index()->IsRegister()) {
2607 __ subl(length, ToRegister(instr->index())); 2607 __ subl(length, ToRegister(instr->index()));
2608 } else { 2608 } else {
2609 __ subl(length, ToOperand(instr->index())); 2609 __ subl(length, ToOperand(instr->index()));
2610 } 2610 }
2611 __ movq(result, Operand(arguments, length, times_pointer_size, kPointerSize)); 2611 __ movq(result, Operand(arguments, length, times_pointer_size, kPointerSize));
2612 } 2612 }
2613 2613
2614 2614
2615 void LCodeGen::DoLoadKeyedFastElement(LLoadKeyedFastElement* instr) { 2615 void LCodeGen::DoLoadKeyedExternal(LLoadKeyed* instr) {
2616 Register result = ToRegister(instr->result());
2617 LOperand* key = instr->key();
2618 if (!key->IsConstantOperand()) {
2619 Register key_reg = ToRegister(key);
2620 // Even though the HLoad/StoreKeyedFastElement instructions force the input
2621 // representation for the key to be an integer, the input gets replaced
2622 // during bound check elimination with the index argument to the bounds
2623 // check, which can be tagged, so that case must be handled here, too.
2624 if (instr->hydrogen()->key()->representation().IsTagged()) {
2625 __ SmiToInteger64(key_reg, key_reg);
2626 } else if (instr->hydrogen()->IsDehoisted()) {
2627 // Sign extend key because it could be a 32 bit negative value
2628 // and the dehoisted address computation happens in 64 bits
2629 __ movsxlq(key_reg, key_reg);
2630 }
2631 }
2632
2633 // Load the result.
2634 __ movq(result,
2635 BuildFastArrayOperand(instr->elements(),
2636 key,
2637 FAST_ELEMENTS,
2638 FixedArray::kHeaderSize - kHeapObjectTag,
2639 instr->additional_index()));
2640
2641 // Check for the hole value.
2642 if (instr->hydrogen()->RequiresHoleCheck()) {
2643 if (IsFastSmiElementsKind(instr->hydrogen()->elements_kind())) {
2644 Condition smi = __ CheckSmi(result);
2645 DeoptimizeIf(NegateCondition(smi), instr->environment());
2646 } else {
2647 __ CompareRoot(result, Heap::kTheHoleValueRootIndex);
2648 DeoptimizeIf(equal, instr->environment());
2649 }
2650 }
2651 }
2652
2653
2654 void LCodeGen::DoLoadKeyedFastDoubleElement(
2655 LLoadKeyedFastDoubleElement* instr) {
2656 XMMRegister result(ToDoubleRegister(instr->result()));
2657 LOperand* key = instr->key();
2658 if (!key->IsConstantOperand()) {
2659 Register key_reg = ToRegister(key);
2660 // Even though the HLoad/StoreKeyedFastElement instructions force the input
2661 // representation for the key to be an integer, the input gets replaced
2662 // during bound check elimination with the index argument to the bounds
2663 // check, which can be tagged, so that case must be handled here, too.
2664 if (instr->hydrogen()->key()->representation().IsTagged()) {
2665 __ SmiToInteger64(key_reg, key_reg);
2666 } else if (instr->hydrogen()->IsDehoisted()) {
2667 // Sign extend key because it could be a 32 bit negative value
2668 // and the dehoisted address computation happens in 64 bits
2669 __ movsxlq(key_reg, key_reg);
2670 }
2671 }
2672
2673 if (instr->hydrogen()->RequiresHoleCheck()) {
2674 int offset = FixedDoubleArray::kHeaderSize - kHeapObjectTag +
2675 sizeof(kHoleNanLower32);
2676 Operand hole_check_operand = BuildFastArrayOperand(
2677 instr->elements(),
2678 key,
2679 FAST_DOUBLE_ELEMENTS,
2680 offset,
2681 instr->additional_index());
2682 __ cmpl(hole_check_operand, Immediate(kHoleNanUpper32));
2683 DeoptimizeIf(equal, instr->environment());
2684 }
2685
2686 Operand double_load_operand = BuildFastArrayOperand(
2687 instr->elements(),
2688 key,
2689 FAST_DOUBLE_ELEMENTS,
2690 FixedDoubleArray::kHeaderSize - kHeapObjectTag,
2691 instr->additional_index());
2692 __ movsd(result, double_load_operand);
2693 }
2694
2695
2696 Operand LCodeGen::BuildFastArrayOperand(
2697 LOperand* elements_pointer,
2698 LOperand* key,
2699 ElementsKind elements_kind,
2700 uint32_t offset,
2701 uint32_t additional_index) {
2702 Register elements_pointer_reg = ToRegister(elements_pointer);
2703 int shift_size = ElementsKindToShiftSize(elements_kind);
2704 if (key->IsConstantOperand()) {
2705 int constant_value = ToInteger32(LConstantOperand::cast(key));
2706 if (constant_value & 0xF0000000) {
2707 Abort("array index constant value too big");
2708 }
2709 return Operand(elements_pointer_reg,
2710 ((constant_value + additional_index) << shift_size)
2711 + offset);
2712 } else {
2713 ScaleFactor scale_factor = static_cast<ScaleFactor>(shift_size);
2714 return Operand(elements_pointer_reg,
2715 ToRegister(key),
2716 scale_factor,
2717 offset + (additional_index << shift_size));
2718 }
2719 }
2720
2721
2722 void LCodeGen::DoLoadKeyedSpecializedArrayElement(
2723 LLoadKeyedSpecializedArrayElement* instr) {
2724 ElementsKind elements_kind = instr->elements_kind(); 2616 ElementsKind elements_kind = instr->elements_kind();
2725 LOperand* key = instr->key(); 2617 LOperand* key = instr->key();
2726 if (!key->IsConstantOperand()) { 2618 if (!key->IsConstantOperand()) {
2727 Register key_reg = ToRegister(key); 2619 Register key_reg = ToRegister(key);
2728 // Even though the HLoad/StoreKeyedFastElement instructions force the input 2620 // Even though the HLoad/StoreKeyed (in this case) instructions force
2729 // representation for the key to be an integer, the input gets replaced 2621 // the input representation for the key to be an integer, the input
2730 // during bound check elimination with the index argument to the bounds 2622 // gets replaced during bound check elimination with the index argument
2731 // check, which can be tagged, so that case must be handled here, too. 2623 // to the bounds check, which can be tagged, so that case must be
2624 // handled here, too.
2732 if (instr->hydrogen()->key()->representation().IsTagged()) { 2625 if (instr->hydrogen()->key()->representation().IsTagged()) {
2733 __ SmiToInteger64(key_reg, key_reg); 2626 __ SmiToInteger64(key_reg, key_reg);
2734 } else if (instr->hydrogen()->IsDehoisted()) { 2627 } else if (instr->hydrogen()->IsDehoisted()) {
2735 // Sign extend key because it could be a 32 bit negative value 2628 // Sign extend key because it could be a 32 bit negative value
2736 // and the dehoisted address computation happens in 64 bits 2629 // and the dehoisted address computation happens in 64 bits
2737 __ movsxlq(key_reg, key_reg); 2630 __ movsxlq(key_reg, key_reg);
2738 } 2631 }
2739 } 2632 }
2740 Operand operand(BuildFastArrayOperand( 2633 Operand operand(BuildFastArrayOperand(
2741 instr->external_pointer(), 2634 instr->external_pointer(),
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
2783 case FAST_DOUBLE_ELEMENTS: 2676 case FAST_DOUBLE_ELEMENTS:
2784 case FAST_HOLEY_ELEMENTS: 2677 case FAST_HOLEY_ELEMENTS:
2785 case FAST_HOLEY_SMI_ELEMENTS: 2678 case FAST_HOLEY_SMI_ELEMENTS:
2786 case FAST_HOLEY_DOUBLE_ELEMENTS: 2679 case FAST_HOLEY_DOUBLE_ELEMENTS:
2787 case DICTIONARY_ELEMENTS: 2680 case DICTIONARY_ELEMENTS:
2788 case NON_STRICT_ARGUMENTS_ELEMENTS: 2681 case NON_STRICT_ARGUMENTS_ELEMENTS:
2789 UNREACHABLE(); 2682 UNREACHABLE();
2790 break; 2683 break;
2791 } 2684 }
2792 } 2685 }
2686
2687 }
2688
2689 void LCodeGen::DoLoadKeyed(LLoadKeyed* instr) {
2690 if (instr->is_external()) {
2691 DoLoadKeyedExternal(instr);
2692 } else if (instr->hydrogen()->representation().IsDouble()) {
2693 XMMRegister result(ToDoubleRegister(instr->result()));
2694 LOperand* key = instr->key();
2695 if (!key->IsConstantOperand()) {
2696 Register key_reg = ToRegister(key);
2697 // Even though the HLoad/StoreKeyed instructions force the input
2698 // representation for the key to be an integer, the input gets replaced
2699 // during bound check elimination with the index argument to the bounds
2700 // check, which can be tagged, so that case must be handled here, too.
2701 if (instr->hydrogen()->key()->representation().IsTagged()) {
2702 __ SmiToInteger64(key_reg, key_reg);
2703 } else if (instr->hydrogen()->IsDehoisted()) {
2704 // Sign extend key because it could be a 32 bit negative value
2705 // and the dehoisted address computation happens in 64 bits
2706 __ movsxlq(key_reg, key_reg);
2707 }
2708 }
2709
2710 if (instr->hydrogen()->RequiresHoleCheck()) {
2711 int offset = FixedDoubleArray::kHeaderSize - kHeapObjectTag +
2712 sizeof(kHoleNanLower32);
2713 Operand hole_check_operand = BuildFastArrayOperand(
2714 instr->elements(),
2715 key,
2716 FAST_DOUBLE_ELEMENTS,
2717 offset,
2718 instr->additional_index());
2719 __ cmpl(hole_check_operand, Immediate(kHoleNanUpper32));
2720 DeoptimizeIf(equal, instr->environment());
2721 }
2722
2723 Operand double_load_operand = BuildFastArrayOperand(
2724 instr->elements(),
2725 key,
2726 FAST_DOUBLE_ELEMENTS,
2727 FixedDoubleArray::kHeaderSize - kHeapObjectTag,
2728 instr->additional_index());
2729 __ movsd(result, double_load_operand);
2730 } else {
2731 Register result = ToRegister(instr->result());
2732 LOperand* key = instr->key();
2733 if (!key->IsConstantOperand()) {
2734 Register key_reg = ToRegister(key);
2735 // Even though the HLoad/StoreKeyedFastElement instructions force
2736 // the input representation for the key to be an integer, the input
2737 // gets replaced during bound check elimination with the index
2738 // argument to the bounds check, which can be tagged, so that
2739 // case must be handled here, too.
2740 if (instr->hydrogen()->key()->representation().IsTagged()) {
2741 __ SmiToInteger64(key_reg, key_reg);
2742 } else if (instr->hydrogen()->IsDehoisted()) {
2743 // Sign extend key because it could be a 32 bit negative value
2744 // and the dehoisted address computation happens in 64 bits
2745 __ movsxlq(key_reg, key_reg);
2746 }
2747 }
2748
2749 // Load the result.
2750 __ movq(result,
2751 BuildFastArrayOperand(instr->elements(),
2752 key,
2753 FAST_ELEMENTS,
2754 FixedArray::kHeaderSize - kHeapObjectTag,
2755 instr->additional_index()));
2756
2757 // Check for the hole value.
2758 if (instr->hydrogen()->RequiresHoleCheck()) {
2759 if (IsFastSmiElementsKind(instr->hydrogen()->elements_kind())) {
2760 Condition smi = __ CheckSmi(result);
2761 DeoptimizeIf(NegateCondition(smi), instr->environment());
2762 } else {
2763 __ CompareRoot(result, Heap::kTheHoleValueRootIndex);
2764 DeoptimizeIf(equal, instr->environment());
2765 }
2766 }
2767 }
2793 } 2768 }
2794 2769
2795 2770
2771 Operand LCodeGen::BuildFastArrayOperand(
2772 LOperand* elements_pointer,
2773 LOperand* key,
2774 ElementsKind elements_kind,
2775 uint32_t offset,
2776 uint32_t additional_index) {
2777 Register elements_pointer_reg = ToRegister(elements_pointer);
2778 int shift_size = ElementsKindToShiftSize(elements_kind);
2779 if (key->IsConstantOperand()) {
2780 int constant_value = ToInteger32(LConstantOperand::cast(key));
2781 if (constant_value & 0xF0000000) {
2782 Abort("array index constant value too big");
2783 }
2784 return Operand(elements_pointer_reg,
2785 ((constant_value + additional_index) << shift_size)
2786 + offset);
2787 } else {
2788 ScaleFactor scale_factor = static_cast<ScaleFactor>(shift_size);
2789 return Operand(elements_pointer_reg,
2790 ToRegister(key),
2791 scale_factor,
2792 offset + (additional_index << shift_size));
2793 }
2794 }
2795
2796
2796 void LCodeGen::DoLoadKeyedGeneric(LLoadKeyedGeneric* instr) { 2797 void LCodeGen::DoLoadKeyedGeneric(LLoadKeyedGeneric* instr) {
2797 ASSERT(ToRegister(instr->object()).is(rdx)); 2798 ASSERT(ToRegister(instr->object()).is(rdx));
2798 ASSERT(ToRegister(instr->key()).is(rax)); 2799 ASSERT(ToRegister(instr->key()).is(rax));
2799 2800
2800 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); 2801 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize();
2801 CallCode(ic, RelocInfo::CODE_TARGET, instr); 2802 CallCode(ic, RelocInfo::CODE_TARGET, instr);
2802 } 2803 }
2803 2804
2804 2805
2805 void LCodeGen::DoArgumentsElements(LArgumentsElements* instr) { 2806 void LCodeGen::DoArgumentsElements(LArgumentsElements* instr) {
(...skipping 852 matching lines...) Expand 10 before | Expand all | Expand 10 after
3658 ASSERT(ToRegister(instr->value()).is(rax)); 3659 ASSERT(ToRegister(instr->value()).is(rax));
3659 3660
3660 __ Move(rcx, instr->hydrogen()->name()); 3661 __ Move(rcx, instr->hydrogen()->name());
3661 Handle<Code> ic = (instr->strict_mode_flag() == kStrictMode) 3662 Handle<Code> ic = (instr->strict_mode_flag() == kStrictMode)
3662 ? isolate()->builtins()->StoreIC_Initialize_Strict() 3663 ? isolate()->builtins()->StoreIC_Initialize_Strict()
3663 : isolate()->builtins()->StoreIC_Initialize(); 3664 : isolate()->builtins()->StoreIC_Initialize();
3664 CallCode(ic, RelocInfo::CODE_TARGET, instr); 3665 CallCode(ic, RelocInfo::CODE_TARGET, instr);
3665 } 3666 }
3666 3667
3667 3668
3668 void LCodeGen::DoStoreKeyedSpecializedArrayElement(
3669 LStoreKeyedSpecializedArrayElement* instr) {
3670 ElementsKind elements_kind = instr->elements_kind();
3671 LOperand* key = instr->key();
3672 if (!key->IsConstantOperand()) {
3673 Register key_reg = ToRegister(key);
3674 // Even though the HLoad/StoreKeyedFastElement instructions force the input
3675 // representation for the key to be an integer, the input gets replaced
3676 // during bound check elimination with the index argument to the bounds
3677 // check, which can be tagged, so that case must be handled here, too.
3678 if (instr->hydrogen()->key()->representation().IsTagged()) {
3679 __ SmiToInteger64(key_reg, key_reg);
3680 } else if (instr->hydrogen()->IsDehoisted()) {
3681 // Sign extend key because it could be a 32 bit negative value
3682 // and the dehoisted address computation happens in 64 bits
3683 __ movsxlq(key_reg, key_reg);
3684 }
3685 }
3686 Operand operand(BuildFastArrayOperand(
3687 instr->external_pointer(),
3688 key,
3689 elements_kind,
3690 0,
3691 instr->additional_index()));
3692
3693 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) {
3694 XMMRegister value(ToDoubleRegister(instr->value()));
3695 __ cvtsd2ss(value, value);
3696 __ movss(operand, value);
3697 } else if (elements_kind == EXTERNAL_DOUBLE_ELEMENTS) {
3698 __ movsd(operand, ToDoubleRegister(instr->value()));
3699 } else {
3700 Register value(ToRegister(instr->value()));
3701 switch (elements_kind) {
3702 case EXTERNAL_PIXEL_ELEMENTS:
3703 case EXTERNAL_BYTE_ELEMENTS:
3704 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
3705 __ movb(operand, value);
3706 break;
3707 case EXTERNAL_SHORT_ELEMENTS:
3708 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
3709 __ movw(operand, value);
3710 break;
3711 case EXTERNAL_INT_ELEMENTS:
3712 case EXTERNAL_UNSIGNED_INT_ELEMENTS:
3713 __ movl(operand, value);
3714 break;
3715 case EXTERNAL_FLOAT_ELEMENTS:
3716 case EXTERNAL_DOUBLE_ELEMENTS:
3717 case FAST_ELEMENTS:
3718 case FAST_SMI_ELEMENTS:
3719 case FAST_DOUBLE_ELEMENTS:
3720 case FAST_HOLEY_ELEMENTS:
3721 case FAST_HOLEY_SMI_ELEMENTS:
3722 case FAST_HOLEY_DOUBLE_ELEMENTS:
3723 case DICTIONARY_ELEMENTS:
3724 case NON_STRICT_ARGUMENTS_ELEMENTS:
3725 UNREACHABLE();
3726 break;
3727 }
3728 }
3729 }
3730
3731
3732 void LCodeGen::DeoptIfTaggedButNotSmi(LEnvironment* environment, 3669 void LCodeGen::DeoptIfTaggedButNotSmi(LEnvironment* environment,
3733 HValue* value, 3670 HValue* value,
3734 LOperand* operand) { 3671 LOperand* operand) {
3735 if (value->representation().IsTagged() && !value->type().IsSmi()) { 3672 if (value->representation().IsTagged() && !value->type().IsSmi()) {
3736 Condition cc; 3673 Condition cc;
3737 if (operand->IsRegister()) { 3674 if (operand->IsRegister()) {
3738 cc = masm()->CheckSmi(ToRegister(operand)); 3675 cc = masm()->CheckSmi(ToRegister(operand));
3739 } else { 3676 } else {
3740 cc = masm()->CheckSmi(ToOperand(operand)); 3677 cc = masm()->CheckSmi(ToOperand(operand));
3741 } 3678 }
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
3782 __ cmpq(length, Immediate(constant_index)); 3719 __ cmpq(length, Immediate(constant_index));
3783 } 3720 }
3784 } else { 3721 } else {
3785 __ cmpq(length, ToRegister(instr->index())); 3722 __ cmpq(length, ToRegister(instr->index()));
3786 } 3723 }
3787 } 3724 }
3788 DeoptimizeIf(below_equal, instr->environment()); 3725 DeoptimizeIf(below_equal, instr->environment());
3789 } 3726 }
3790 3727
3791 3728
3792 void LCodeGen::DoStoreKeyedFastElement(LStoreKeyedFastElement* instr) { 3729 void LCodeGen::DoStoreKeyedExternal(LStoreKeyed* instr) {
3793 Register value = ToRegister(instr->value()); 3730 ElementsKind elements_kind = instr->elements_kind();
3794 Register elements = ToRegister(instr->object());
3795 LOperand* key = instr->key(); 3731 LOperand* key = instr->key();
3796 if (!key->IsConstantOperand()) { 3732 if (!key->IsConstantOperand()) {
3797 Register key_reg = ToRegister(key); 3733 Register key_reg = ToRegister(key);
3798 // Even though the HLoad/StoreKeyedFastElement instructions force the input 3734 // Even though the HLoad/StoreKeyedFastElement instructions force
3799 // representation for the key to be an integer, the input gets replaced 3735 // the input representation for the key to be an integer, the input
3800 // during bound check elimination with the index argument to the bounds 3736 // gets replaced during bound check elimination with the index
3801 // check, which can be tagged, so that case must be handled here, too. 3737 // argument to the bounds check, which can be tagged, so that case
3738 // must be handled here, too.
3802 if (instr->hydrogen()->key()->representation().IsTagged()) { 3739 if (instr->hydrogen()->key()->representation().IsTagged()) {
3803 __ SmiToInteger64(key_reg, key_reg); 3740 __ SmiToInteger64(key_reg, key_reg);
3804 } else if (instr->hydrogen()->IsDehoisted()) { 3741 } else if (instr->hydrogen()->IsDehoisted()) {
3805 // Sign extend key because it could be a 32 bit negative value 3742 // Sign extend key because it could be a 32 bit negative value
3806 // and the dehoisted address computation happens in 64 bits 3743 // and the dehoisted address computation happens in 64 bits
3807 __ movsxlq(key_reg, key_reg); 3744 __ movsxlq(key_reg, key_reg);
3808 } 3745 }
3809 } 3746 }
3747 Operand operand(BuildFastArrayOperand(
3748 instr->external_pointer(),
3749 key,
3750 elements_kind,
3751 0,
3752 instr->additional_index()));
3810 3753
3811 Operand operand = 3754 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) {
3812 BuildFastArrayOperand(instr->object(), 3755 XMMRegister value(ToDoubleRegister(instr->value()));
3813 key, 3756 __ cvtsd2ss(value, value);
3814 FAST_ELEMENTS, 3757 __ movss(operand, value);
3815 FixedArray::kHeaderSize - kHeapObjectTag, 3758 } else if (elements_kind == EXTERNAL_DOUBLE_ELEMENTS) {
3816 instr->additional_index()); 3759 __ movsd(operand, ToDoubleRegister(instr->value()));
3817
3818 if (instr->hydrogen()->NeedsWriteBarrier()) {
3819 ASSERT(!instr->key()->IsConstantOperand());
3820 HType type = instr->hydrogen()->value()->type();
3821 SmiCheck check_needed =
3822 type.IsHeapObject() ? OMIT_SMI_CHECK : INLINE_SMI_CHECK;
3823 // Compute address of modified element and store it into key register.
3824 Register key_reg(ToRegister(key));
3825 __ lea(key_reg, operand);
3826 __ movq(Operand(key_reg, 0), value);
3827 __ RecordWrite(elements,
3828 key_reg,
3829 value,
3830 kSaveFPRegs,
3831 EMIT_REMEMBERED_SET,
3832 check_needed);
3833 } else { 3760 } else {
3834 __ movq(operand, value); 3761 Register value(ToRegister(instr->value()));
3762 switch (elements_kind) {
3763 case EXTERNAL_PIXEL_ELEMENTS:
3764 case EXTERNAL_BYTE_ELEMENTS:
3765 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
3766 __ movb(operand, value);
3767 break;
3768 case EXTERNAL_SHORT_ELEMENTS:
3769 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
3770 __ movw(operand, value);
3771 break;
3772 case EXTERNAL_INT_ELEMENTS:
3773 case EXTERNAL_UNSIGNED_INT_ELEMENTS:
3774 __ movl(operand, value);
3775 break;
3776 case EXTERNAL_FLOAT_ELEMENTS:
3777 case EXTERNAL_DOUBLE_ELEMENTS:
3778 case FAST_ELEMENTS:
3779 case FAST_SMI_ELEMENTS:
3780 case FAST_DOUBLE_ELEMENTS:
3781 case FAST_HOLEY_ELEMENTS:
3782 case FAST_HOLEY_SMI_ELEMENTS:
3783 case FAST_HOLEY_DOUBLE_ELEMENTS:
3784 case DICTIONARY_ELEMENTS:
3785 case NON_STRICT_ARGUMENTS_ELEMENTS:
3786 UNREACHABLE();
3787 break;
3788 }
3835 } 3789 }
3836 } 3790 }
3837 3791
3838 3792
3839 void LCodeGen::DoStoreKeyedFastDoubleElement( 3793 void LCodeGen::DoStoreKeyed(LStoreKeyed* instr) {
3840 LStoreKeyedFastDoubleElement* instr) { 3794 if (instr->is_external()) {
3841 XMMRegister value = ToDoubleRegister(instr->value()); 3795 DoStoreKeyedExternal(instr);
3842 LOperand* key = instr->key(); 3796 } else if (instr->hydrogen()->value()->representation().IsDouble()) {
3843 if (!key->IsConstantOperand()) { 3797 XMMRegister value = ToDoubleRegister(instr->value());
3844 Register key_reg = ToRegister(key); 3798 LOperand* key = instr->key();
3845 // Even though the HLoad/StoreKeyedFastElement instructions force the input 3799 if (!key->IsConstantOperand()) {
3846 // representation for the key to be an integer, the input gets replaced 3800 Register key_reg = ToRegister(key);
3847 // during bound check elimination with the index argument to the bounds 3801 // Even though the HLoad/StoreKeyedFastElement instructions force
3848 // check, which can be tagged, so that case must be handled here, too. 3802 // the input representation for the key to be an integer, the
3849 if (instr->hydrogen()->key()->representation().IsTagged()) { 3803 // input gets replaced during bound check elimination with the index
3850 __ SmiToInteger64(key_reg, key_reg); 3804 // argument to the bounds check, which can be tagged, so that case
3851 } else if (instr->hydrogen()->IsDehoisted()) { 3805 // must be handled here, too.
3852 // Sign extend key because it could be a 32 bit negative value 3806 if (instr->hydrogen()->key()->representation().IsTagged()) {
3853 // and the dehoisted address computation happens in 64 bits 3807 __ SmiToInteger64(key_reg, key_reg);
3854 __ movsxlq(key_reg, key_reg); 3808 } else if (instr->hydrogen()->IsDehoisted()) {
3809 // Sign extend key because it could be a 32 bit negative value
3810 // and the dehoisted address computation happens in 64 bits
3811 __ movsxlq(key_reg, key_reg);
3812 }
3813 }
3814
3815 if (instr->NeedsCanonicalization()) {
3816 Label have_value;
3817
3818 __ ucomisd(value, value);
3819 __ j(parity_odd, &have_value); // NaN.
3820
3821 __ Set(kScratchRegister, BitCast<uint64_t>(
3822 FixedDoubleArray::canonical_not_the_hole_nan_as_double()));
3823 __ movq(value, kScratchRegister);
3824
3825 __ bind(&have_value);
3826 }
3827
3828 Operand double_store_operand = BuildFastArrayOperand(
3829 instr->object(),
3830 key,
3831 FAST_DOUBLE_ELEMENTS,
3832 FixedDoubleArray::kHeaderSize - kHeapObjectTag,
3833 instr->additional_index());
3834
3835 __ movsd(double_store_operand, value);
3836 } else {
3837 Register value = ToRegister(instr->value());
3838 Register elements = ToRegister(instr->object());
3839 LOperand* key = instr->key();
3840 if (!key->IsConstantOperand()) {
3841 Register key_reg = ToRegister(key);
3842 // Even though the HLoad/StoreKeyedFastElement instructions force
3843 // the input representation for the key to be an integer, the
3844 // input gets replaced during bound check elimination with the index
3845 // argument to the bounds check, which can be tagged, so that case
3846 // must be handled here, too.
3847 if (instr->hydrogen()->key()->representation().IsTagged()) {
3848 __ SmiToInteger64(key_reg, key_reg);
3849 } else if (instr->hydrogen()->IsDehoisted()) {
3850 // Sign extend key because it could be a 32 bit negative value
3851 // and the dehoisted address computation happens in 64 bits
3852 __ movsxlq(key_reg, key_reg);
3853 }
3854 }
3855
3856 Operand operand =
3857 BuildFastArrayOperand(instr->object(),
3858 key,
3859 FAST_ELEMENTS,
3860 FixedArray::kHeaderSize - kHeapObjectTag,
3861 instr->additional_index());
3862
3863 if (instr->hydrogen()->NeedsWriteBarrier()) {
3864 ASSERT(!instr->key()->IsConstantOperand());
3865 HType type = instr->hydrogen()->value()->type();
3866 SmiCheck check_needed =
3867 type.IsHeapObject() ? OMIT_SMI_CHECK : INLINE_SMI_CHECK;
3868 // Compute address of modified element and store it into key register.
3869 Register key_reg(ToRegister(key));
3870 __ lea(key_reg, operand);
3871 __ movq(Operand(key_reg, 0), value);
3872 __ RecordWrite(elements,
3873 key_reg,
3874 value,
3875 kSaveFPRegs,
3876 EMIT_REMEMBERED_SET,
3877 check_needed);
3878 } else {
3879 __ movq(operand, value);
3855 } 3880 }
3856 } 3881 }
3882 }
3857 3883
3858 if (instr->NeedsCanonicalization()) {
3859 Label have_value;
3860
3861 __ ucomisd(value, value);
3862 __ j(parity_odd, &have_value); // NaN.
3863
3864 __ Set(kScratchRegister, BitCast<uint64_t>(
3865 FixedDoubleArray::canonical_not_the_hole_nan_as_double()));
3866 __ movq(value, kScratchRegister);
3867
3868 __ bind(&have_value);
3869 }
3870
3871 Operand double_store_operand = BuildFastArrayOperand(
3872 instr->elements(),
3873 key,
3874 FAST_DOUBLE_ELEMENTS,
3875 FixedDoubleArray::kHeaderSize - kHeapObjectTag,
3876 instr->additional_index());
3877
3878 __ movsd(double_store_operand, value);
3879 }
3880 3884
3881 void LCodeGen::DoStoreKeyedGeneric(LStoreKeyedGeneric* instr) { 3885 void LCodeGen::DoStoreKeyedGeneric(LStoreKeyedGeneric* instr) {
3882 ASSERT(ToRegister(instr->object()).is(rdx)); 3886 ASSERT(ToRegister(instr->object()).is(rdx));
3883 ASSERT(ToRegister(instr->key()).is(rcx)); 3887 ASSERT(ToRegister(instr->key()).is(rcx));
3884 ASSERT(ToRegister(instr->value()).is(rax)); 3888 ASSERT(ToRegister(instr->value()).is(rax));
3885 3889
3886 Handle<Code> ic = (instr->strict_mode_flag() == kStrictMode) 3890 Handle<Code> ic = (instr->strict_mode_flag() == kStrictMode)
3887 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict() 3891 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict()
3888 : isolate()->builtins()->KeyedStoreIC_Initialize(); 3892 : isolate()->builtins()->KeyedStoreIC_Initialize();
3889 CallCode(ic, RelocInfo::CODE_TARGET, instr); 3893 CallCode(ic, RelocInfo::CODE_TARGET, instr);
(...skipping 1421 matching lines...) Expand 10 before | Expand all | Expand 10 after
5311 FixedArray::kHeaderSize - kPointerSize)); 5315 FixedArray::kHeaderSize - kPointerSize));
5312 __ bind(&done); 5316 __ bind(&done);
5313 } 5317 }
5314 5318
5315 5319
5316 #undef __ 5320 #undef __
5317 5321
5318 } } // namespace v8::internal 5322 } } // namespace v8::internal
5319 5323
5320 #endif // V8_TARGET_ARCH_X64 5324 #endif // V8_TARGET_ARCH_X64
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698