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

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: Last batch of comment response, formatting issues. Created 8 years, 1 month 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/x64/lithium-codegen-x64.h ('k') | src/x64/lithium-x64.h » ('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 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::DoLoadKeyedExternalArray(LLoadKeyed* instr) {
2616 Register result = ToRegister(instr->result()); 2616 ElementsKind elements_kind = instr->elements_kind();
2617 LOperand* key = instr->key(); 2617 LOperand* key = instr->key();
2618 if (!key->IsConstantOperand()) { 2618 if (!key->IsConstantOperand()) {
2619 Register key_reg = ToRegister(key); 2619 Register key_reg = ToRegister(key);
2620 // Even though the HLoad/StoreKeyedFastElement instructions force the input 2620 // Even though the HLoad/StoreKeyed (in this case) instructions force
2621 // 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
2622 // during bound check elimination with the index argument to the bounds 2622 // gets replaced during bound check elimination with the index argument
2623 // 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.
2624 if (instr->hydrogen()->key()->representation().IsTagged()) { 2625 if (instr->hydrogen()->key()->representation().IsTagged()) {
2625 __ SmiToInteger64(key_reg, key_reg); 2626 __ SmiToInteger64(key_reg, key_reg);
2626 } else if (instr->hydrogen()->IsDehoisted()) { 2627 } else if (instr->hydrogen()->IsDehoisted()) {
2627 // 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
2628 // and the dehoisted address computation happens in 64 bits 2629 // and the dehoisted address computation happens in 64 bits
2629 __ movsxlq(key_reg, key_reg); 2630 __ movsxlq(key_reg, key_reg);
2630 } 2631 }
2631 } 2632 }
2633 Operand operand(BuildFastArrayOperand(
2634 instr->elements(),
2635 key,
2636 elements_kind,
2637 0,
2638 instr->additional_index()));
2632 2639
2633 // Load the result. 2640 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) {
2634 __ movq(result, 2641 XMMRegister result(ToDoubleRegister(instr->result()));
2635 BuildFastArrayOperand(instr->elements(), 2642 __ movss(result, operand);
2636 key, 2643 __ cvtss2sd(result, result);
2637 FAST_ELEMENTS, 2644 } else if (elements_kind == EXTERNAL_DOUBLE_ELEMENTS) {
2638 FixedArray::kHeaderSize - kHeapObjectTag, 2645 __ movsd(ToDoubleRegister(instr->result()), operand);
2639 instr->additional_index())); 2646 } else {
2640 2647 Register result(ToRegister(instr->result()));
2641 // Check for the hole value. 2648 switch (elements_kind) {
2642 if (instr->hydrogen()->RequiresHoleCheck()) { 2649 case EXTERNAL_BYTE_ELEMENTS:
2643 if (IsFastSmiElementsKind(instr->hydrogen()->elements_kind())) { 2650 __ movsxbq(result, operand);
2644 Condition smi = __ CheckSmi(result); 2651 break;
2645 DeoptimizeIf(NegateCondition(smi), instr->environment()); 2652 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
2646 } else { 2653 case EXTERNAL_PIXEL_ELEMENTS:
2647 __ CompareRoot(result, Heap::kTheHoleValueRootIndex); 2654 __ movzxbq(result, operand);
2648 DeoptimizeIf(equal, instr->environment()); 2655 break;
2656 case EXTERNAL_SHORT_ELEMENTS:
2657 __ movsxwq(result, operand);
2658 break;
2659 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
2660 __ movzxwq(result, operand);
2661 break;
2662 case EXTERNAL_INT_ELEMENTS:
2663 __ movsxlq(result, operand);
2664 break;
2665 case EXTERNAL_UNSIGNED_INT_ELEMENTS:
2666 __ movl(result, operand);
2667 if (!instr->hydrogen()->CheckFlag(HInstruction::kUint32)) {
2668 __ testl(result, result);
2669 DeoptimizeIf(negative, instr->environment());
2670 }
2671 break;
2672 case EXTERNAL_FLOAT_ELEMENTS:
2673 case EXTERNAL_DOUBLE_ELEMENTS:
2674 case FAST_ELEMENTS:
2675 case FAST_SMI_ELEMENTS:
2676 case FAST_DOUBLE_ELEMENTS:
2677 case FAST_HOLEY_ELEMENTS:
2678 case FAST_HOLEY_SMI_ELEMENTS:
2679 case FAST_HOLEY_DOUBLE_ELEMENTS:
2680 case DICTIONARY_ELEMENTS:
2681 case NON_STRICT_ARGUMENTS_ELEMENTS:
2682 UNREACHABLE();
2683 break;
2649 } 2684 }
2650 } 2685 }
2651 } 2686 }
2652 2687
2653 2688
2654 void LCodeGen::DoLoadKeyedFastDoubleElement( 2689 void LCodeGen::DoLoadKeyedFixedDoubleArray(LLoadKeyed* instr) {
2655 LLoadKeyedFastDoubleElement* instr) {
2656 XMMRegister result(ToDoubleRegister(instr->result())); 2690 XMMRegister result(ToDoubleRegister(instr->result()));
2657 LOperand* key = instr->key(); 2691 LOperand* key = instr->key();
2658 if (!key->IsConstantOperand()) { 2692 if (!key->IsConstantOperand()) {
2659 Register key_reg = ToRegister(key); 2693 Register key_reg = ToRegister(key);
2660 // Even though the HLoad/StoreKeyedFastElement instructions force the input 2694 // Even though the HLoad/StoreKeyed instructions force the input
2661 // representation for the key to be an integer, the input gets replaced 2695 // representation for the key to be an integer, the input gets replaced
2662 // during bound check elimination with the index argument to the bounds 2696 // 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. 2697 // check, which can be tagged, so that case must be handled here, too.
2664 if (instr->hydrogen()->key()->representation().IsTagged()) { 2698 if (instr->hydrogen()->key()->representation().IsTagged()) {
2665 __ SmiToInteger64(key_reg, key_reg); 2699 __ SmiToInteger64(key_reg, key_reg);
2666 } else if (instr->hydrogen()->IsDehoisted()) { 2700 } else if (instr->hydrogen()->IsDehoisted()) {
2667 // Sign extend key because it could be a 32 bit negative value 2701 // Sign extend key because it could be a 32 bit negative value
2668 // and the dehoisted address computation happens in 64 bits 2702 // and the dehoisted address computation happens in 64 bits
2669 __ movsxlq(key_reg, key_reg); 2703 __ movsxlq(key_reg, key_reg);
2670 } 2704 }
(...skipping 15 matching lines...) Expand all
2686 Operand double_load_operand = BuildFastArrayOperand( 2720 Operand double_load_operand = BuildFastArrayOperand(
2687 instr->elements(), 2721 instr->elements(),
2688 key, 2722 key,
2689 FAST_DOUBLE_ELEMENTS, 2723 FAST_DOUBLE_ELEMENTS,
2690 FixedDoubleArray::kHeaderSize - kHeapObjectTag, 2724 FixedDoubleArray::kHeaderSize - kHeapObjectTag,
2691 instr->additional_index()); 2725 instr->additional_index());
2692 __ movsd(result, double_load_operand); 2726 __ movsd(result, double_load_operand);
2693 } 2727 }
2694 2728
2695 2729
2730 void LCodeGen::DoLoadKeyedFixedArray(LLoadKeyed* instr) {
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 }
2768
2769
2770 void LCodeGen::DoLoadKeyed(LLoadKeyed* instr) {
2771 if (instr->is_external()) {
2772 DoLoadKeyedExternalArray(instr);
2773 } else if (instr->hydrogen()->representation().IsDouble()) {
2774 DoLoadKeyedFixedDoubleArray(instr);
2775 } else {
2776 DoLoadKeyedFixedArray(instr);
2777 }
2778 }
2779
2780
2696 Operand LCodeGen::BuildFastArrayOperand( 2781 Operand LCodeGen::BuildFastArrayOperand(
2697 LOperand* elements_pointer, 2782 LOperand* elements_pointer,
2698 LOperand* key, 2783 LOperand* key,
2699 ElementsKind elements_kind, 2784 ElementsKind elements_kind,
2700 uint32_t offset, 2785 uint32_t offset,
2701 uint32_t additional_index) { 2786 uint32_t additional_index) {
2702 Register elements_pointer_reg = ToRegister(elements_pointer); 2787 Register elements_pointer_reg = ToRegister(elements_pointer);
2703 int shift_size = ElementsKindToShiftSize(elements_kind); 2788 int shift_size = ElementsKindToShiftSize(elements_kind);
2704 if (key->IsConstantOperand()) { 2789 if (key->IsConstantOperand()) {
2705 int constant_value = ToInteger32(LConstantOperand::cast(key)); 2790 int constant_value = ToInteger32(LConstantOperand::cast(key));
2706 if (constant_value & 0xF0000000) { 2791 if (constant_value & 0xF0000000) {
2707 Abort("array index constant value too big"); 2792 Abort("array index constant value too big");
2708 } 2793 }
2709 return Operand(elements_pointer_reg, 2794 return Operand(elements_pointer_reg,
2710 ((constant_value + additional_index) << shift_size) 2795 ((constant_value + additional_index) << shift_size)
2711 + offset); 2796 + offset);
2712 } else { 2797 } else {
2713 ScaleFactor scale_factor = static_cast<ScaleFactor>(shift_size); 2798 ScaleFactor scale_factor = static_cast<ScaleFactor>(shift_size);
2714 return Operand(elements_pointer_reg, 2799 return Operand(elements_pointer_reg,
2715 ToRegister(key), 2800 ToRegister(key),
2716 scale_factor, 2801 scale_factor,
2717 offset + (additional_index << shift_size)); 2802 offset + (additional_index << shift_size));
2718 } 2803 }
2719 } 2804 }
2720 2805
2721 2806
2722 void LCodeGen::DoLoadKeyedSpecializedArrayElement(
2723 LLoadKeyedSpecializedArrayElement* instr) {
2724 ElementsKind elements_kind = instr->elements_kind();
2725 LOperand* key = instr->key();
2726 if (!key->IsConstantOperand()) {
2727 Register key_reg = ToRegister(key);
2728 // Even though the HLoad/StoreKeyedFastElement instructions force the input
2729 // representation for the key to be an integer, the input gets replaced
2730 // during bound check elimination with the index argument to the bounds
2731 // check, which can be tagged, so that case must be handled here, too.
2732 if (instr->hydrogen()->key()->representation().IsTagged()) {
2733 __ SmiToInteger64(key_reg, key_reg);
2734 } else if (instr->hydrogen()->IsDehoisted()) {
2735 // Sign extend key because it could be a 32 bit negative value
2736 // and the dehoisted address computation happens in 64 bits
2737 __ movsxlq(key_reg, key_reg);
2738 }
2739 }
2740 Operand operand(BuildFastArrayOperand(
2741 instr->external_pointer(),
2742 key,
2743 elements_kind,
2744 0,
2745 instr->additional_index()));
2746
2747 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) {
2748 XMMRegister result(ToDoubleRegister(instr->result()));
2749 __ movss(result, operand);
2750 __ cvtss2sd(result, result);
2751 } else if (elements_kind == EXTERNAL_DOUBLE_ELEMENTS) {
2752 __ movsd(ToDoubleRegister(instr->result()), operand);
2753 } else {
2754 Register result(ToRegister(instr->result()));
2755 switch (elements_kind) {
2756 case EXTERNAL_BYTE_ELEMENTS:
2757 __ movsxbq(result, operand);
2758 break;
2759 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
2760 case EXTERNAL_PIXEL_ELEMENTS:
2761 __ movzxbq(result, operand);
2762 break;
2763 case EXTERNAL_SHORT_ELEMENTS:
2764 __ movsxwq(result, operand);
2765 break;
2766 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
2767 __ movzxwq(result, operand);
2768 break;
2769 case EXTERNAL_INT_ELEMENTS:
2770 __ movsxlq(result, operand);
2771 break;
2772 case EXTERNAL_UNSIGNED_INT_ELEMENTS:
2773 __ movl(result, operand);
2774 if (!instr->hydrogen()->CheckFlag(HInstruction::kUint32)) {
2775 __ testl(result, result);
2776 DeoptimizeIf(negative, instr->environment());
2777 }
2778 break;
2779 case EXTERNAL_FLOAT_ELEMENTS:
2780 case EXTERNAL_DOUBLE_ELEMENTS:
2781 case FAST_ELEMENTS:
2782 case FAST_SMI_ELEMENTS:
2783 case FAST_DOUBLE_ELEMENTS:
2784 case FAST_HOLEY_ELEMENTS:
2785 case FAST_HOLEY_SMI_ELEMENTS:
2786 case FAST_HOLEY_DOUBLE_ELEMENTS:
2787 case DICTIONARY_ELEMENTS:
2788 case NON_STRICT_ARGUMENTS_ELEMENTS:
2789 UNREACHABLE();
2790 break;
2791 }
2792 }
2793 }
2794
2795
2796 void LCodeGen::DoLoadKeyedGeneric(LLoadKeyedGeneric* instr) { 2807 void LCodeGen::DoLoadKeyedGeneric(LLoadKeyedGeneric* instr) {
2797 ASSERT(ToRegister(instr->object()).is(rdx)); 2808 ASSERT(ToRegister(instr->object()).is(rdx));
2798 ASSERT(ToRegister(instr->key()).is(rax)); 2809 ASSERT(ToRegister(instr->key()).is(rax));
2799 2810
2800 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); 2811 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize();
2801 CallCode(ic, RelocInfo::CODE_TARGET, instr); 2812 CallCode(ic, RelocInfo::CODE_TARGET, instr);
2802 } 2813 }
2803 2814
2804 2815
2805 void LCodeGen::DoArgumentsElements(LArgumentsElements* instr) { 2816 void LCodeGen::DoArgumentsElements(LArgumentsElements* instr) {
(...skipping 852 matching lines...) Expand 10 before | Expand all | Expand 10 after
3658 ASSERT(ToRegister(instr->value()).is(rax)); 3669 ASSERT(ToRegister(instr->value()).is(rax));
3659 3670
3660 __ Move(rcx, instr->hydrogen()->name()); 3671 __ Move(rcx, instr->hydrogen()->name());
3661 Handle<Code> ic = (instr->strict_mode_flag() == kStrictMode) 3672 Handle<Code> ic = (instr->strict_mode_flag() == kStrictMode)
3662 ? isolate()->builtins()->StoreIC_Initialize_Strict() 3673 ? isolate()->builtins()->StoreIC_Initialize_Strict()
3663 : isolate()->builtins()->StoreIC_Initialize(); 3674 : isolate()->builtins()->StoreIC_Initialize();
3664 CallCode(ic, RelocInfo::CODE_TARGET, instr); 3675 CallCode(ic, RelocInfo::CODE_TARGET, instr);
3665 } 3676 }
3666 3677
3667 3678
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, 3679 void LCodeGen::DeoptIfTaggedButNotSmi(LEnvironment* environment,
3733 HValue* value, 3680 HValue* value,
3734 LOperand* operand) { 3681 LOperand* operand) {
3735 if (value->representation().IsTagged() && !value->type().IsSmi()) { 3682 if (value->representation().IsTagged() && !value->type().IsSmi()) {
3736 Condition cc; 3683 Condition cc;
3737 if (operand->IsRegister()) { 3684 if (operand->IsRegister()) {
3738 cc = masm()->CheckSmi(ToRegister(operand)); 3685 cc = masm()->CheckSmi(ToRegister(operand));
3739 } else { 3686 } else {
3740 cc = masm()->CheckSmi(ToOperand(operand)); 3687 cc = masm()->CheckSmi(ToOperand(operand));
3741 } 3688 }
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
3782 __ cmpq(length, Immediate(constant_index)); 3729 __ cmpq(length, Immediate(constant_index));
3783 } 3730 }
3784 } else { 3731 } else {
3785 __ cmpq(length, ToRegister(instr->index())); 3732 __ cmpq(length, ToRegister(instr->index()));
3786 } 3733 }
3787 } 3734 }
3788 DeoptimizeIf(below_equal, instr->environment()); 3735 DeoptimizeIf(below_equal, instr->environment());
3789 } 3736 }
3790 3737
3791 3738
3792 void LCodeGen::DoStoreKeyedFastElement(LStoreKeyedFastElement* instr) { 3739 void LCodeGen::DoStoreKeyedExternalArray(LStoreKeyed* instr) {
3793 Register value = ToRegister(instr->value()); 3740 ElementsKind elements_kind = instr->elements_kind();
3794 Register elements = ToRegister(instr->object());
3795 LOperand* key = instr->key(); 3741 LOperand* key = instr->key();
3796 if (!key->IsConstantOperand()) { 3742 if (!key->IsConstantOperand()) {
3797 Register key_reg = ToRegister(key); 3743 Register key_reg = ToRegister(key);
3798 // Even though the HLoad/StoreKeyedFastElement instructions force the input 3744 // Even though the HLoad/StoreKeyedFastElement instructions force
3799 // representation for the key to be an integer, the input gets replaced 3745 // the input representation for the key to be an integer, the input
3800 // during bound check elimination with the index argument to the bounds 3746 // gets replaced during bound check elimination with the index
3801 // check, which can be tagged, so that case must be handled here, too. 3747 // argument to the bounds check, which can be tagged, so that case
3748 // must be handled here, too.
3802 if (instr->hydrogen()->key()->representation().IsTagged()) { 3749 if (instr->hydrogen()->key()->representation().IsTagged()) {
3803 __ SmiToInteger64(key_reg, key_reg); 3750 __ SmiToInteger64(key_reg, key_reg);
3804 } else if (instr->hydrogen()->IsDehoisted()) { 3751 } else if (instr->hydrogen()->IsDehoisted()) {
3805 // Sign extend key because it could be a 32 bit negative value 3752 // Sign extend key because it could be a 32 bit negative value
3806 // and the dehoisted address computation happens in 64 bits 3753 // and the dehoisted address computation happens in 64 bits
3807 __ movsxlq(key_reg, key_reg); 3754 __ movsxlq(key_reg, key_reg);
3808 } 3755 }
3809 } 3756 }
3757 Operand operand(BuildFastArrayOperand(
3758 instr->elements(),
3759 key,
3760 elements_kind,
3761 0,
3762 instr->additional_index()));
3810 3763
3811 Operand operand = 3764 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) {
3812 BuildFastArrayOperand(instr->object(), 3765 XMMRegister value(ToDoubleRegister(instr->value()));
3813 key, 3766 __ cvtsd2ss(value, value);
3814 FAST_ELEMENTS, 3767 __ movss(operand, value);
3815 FixedArray::kHeaderSize - kHeapObjectTag, 3768 } else if (elements_kind == EXTERNAL_DOUBLE_ELEMENTS) {
3816 instr->additional_index()); 3769 __ 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 { 3770 } else {
3834 __ movq(operand, value); 3771 Register value(ToRegister(instr->value()));
3772 switch (elements_kind) {
3773 case EXTERNAL_PIXEL_ELEMENTS:
3774 case EXTERNAL_BYTE_ELEMENTS:
3775 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
3776 __ movb(operand, value);
3777 break;
3778 case EXTERNAL_SHORT_ELEMENTS:
3779 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
3780 __ movw(operand, value);
3781 break;
3782 case EXTERNAL_INT_ELEMENTS:
3783 case EXTERNAL_UNSIGNED_INT_ELEMENTS:
3784 __ movl(operand, value);
3785 break;
3786 case EXTERNAL_FLOAT_ELEMENTS:
3787 case EXTERNAL_DOUBLE_ELEMENTS:
3788 case FAST_ELEMENTS:
3789 case FAST_SMI_ELEMENTS:
3790 case FAST_DOUBLE_ELEMENTS:
3791 case FAST_HOLEY_ELEMENTS:
3792 case FAST_HOLEY_SMI_ELEMENTS:
3793 case FAST_HOLEY_DOUBLE_ELEMENTS:
3794 case DICTIONARY_ELEMENTS:
3795 case NON_STRICT_ARGUMENTS_ELEMENTS:
3796 UNREACHABLE();
3797 break;
3798 }
3835 } 3799 }
3836 } 3800 }
3837 3801
3838 3802
3839 void LCodeGen::DoStoreKeyedFastDoubleElement( 3803 void LCodeGen::DoStoreKeyedFixedDoubleArray(LStoreKeyed* instr) {
3840 LStoreKeyedFastDoubleElement* instr) {
3841 XMMRegister value = ToDoubleRegister(instr->value()); 3804 XMMRegister value = ToDoubleRegister(instr->value());
3842 LOperand* key = instr->key(); 3805 LOperand* key = instr->key();
3843 if (!key->IsConstantOperand()) { 3806 if (!key->IsConstantOperand()) {
3844 Register key_reg = ToRegister(key); 3807 Register key_reg = ToRegister(key);
3845 // Even though the HLoad/StoreKeyedFastElement instructions force the input 3808 // Even though the HLoad/StoreKeyedFastElement instructions force
3846 // representation for the key to be an integer, the input gets replaced 3809 // the input representation for the key to be an integer, the
3847 // during bound check elimination with the index argument to the bounds 3810 // input gets replaced during bound check elimination with the index
3848 // check, which can be tagged, so that case must be handled here, too. 3811 // argument to the bounds check, which can be tagged, so that case
3812 // must be handled here, too.
3849 if (instr->hydrogen()->key()->representation().IsTagged()) { 3813 if (instr->hydrogen()->key()->representation().IsTagged()) {
3850 __ SmiToInteger64(key_reg, key_reg); 3814 __ SmiToInteger64(key_reg, key_reg);
3851 } else if (instr->hydrogen()->IsDehoisted()) { 3815 } else if (instr->hydrogen()->IsDehoisted()) {
3852 // Sign extend key because it could be a 32 bit negative value 3816 // Sign extend key because it could be a 32 bit negative value
3853 // and the dehoisted address computation happens in 64 bits 3817 // and the dehoisted address computation happens in 64 bits
3854 __ movsxlq(key_reg, key_reg); 3818 __ movsxlq(key_reg, key_reg);
3855 } 3819 }
3856 } 3820 }
3857 3821
3858 if (instr->NeedsCanonicalization()) { 3822 if (instr->NeedsCanonicalization()) {
(...skipping 12 matching lines...) Expand all
3871 Operand double_store_operand = BuildFastArrayOperand( 3835 Operand double_store_operand = BuildFastArrayOperand(
3872 instr->elements(), 3836 instr->elements(),
3873 key, 3837 key,
3874 FAST_DOUBLE_ELEMENTS, 3838 FAST_DOUBLE_ELEMENTS,
3875 FixedDoubleArray::kHeaderSize - kHeapObjectTag, 3839 FixedDoubleArray::kHeaderSize - kHeapObjectTag,
3876 instr->additional_index()); 3840 instr->additional_index());
3877 3841
3878 __ movsd(double_store_operand, value); 3842 __ movsd(double_store_operand, value);
3879 } 3843 }
3880 3844
3845
3846 void LCodeGen::DoStoreKeyedFixedArray(LStoreKeyed* instr) {
3847 Register value = ToRegister(instr->value());
3848 Register elements = ToRegister(instr->elements());
3849 LOperand* key = instr->key();
3850 if (!key->IsConstantOperand()) {
3851 Register key_reg = ToRegister(key);
3852 // Even though the HLoad/StoreKeyedFastElement instructions force
3853 // the input representation for the key to be an integer, the
3854 // input gets replaced during bound check elimination with the index
3855 // argument to the bounds check, which can be tagged, so that case
3856 // must be handled here, too.
3857 if (instr->hydrogen()->key()->representation().IsTagged()) {
3858 __ SmiToInteger64(key_reg, key_reg);
3859 } else if (instr->hydrogen()->IsDehoisted()) {
3860 // Sign extend key because it could be a 32 bit negative value
3861 // and the dehoisted address computation happens in 64 bits
3862 __ movsxlq(key_reg, key_reg);
3863 }
3864 }
3865
3866 Operand operand =
3867 BuildFastArrayOperand(instr->elements(),
3868 key,
3869 FAST_ELEMENTS,
3870 FixedArray::kHeaderSize - kHeapObjectTag,
3871 instr->additional_index());
3872
3873 if (instr->hydrogen()->NeedsWriteBarrier()) {
3874 ASSERT(!instr->key()->IsConstantOperand());
3875 HType type = instr->hydrogen()->value()->type();
3876 SmiCheck check_needed =
3877 type.IsHeapObject() ? OMIT_SMI_CHECK : INLINE_SMI_CHECK;
3878 // Compute address of modified element and store it into key register.
3879 Register key_reg(ToRegister(key));
3880 __ lea(key_reg, operand);
3881 __ movq(Operand(key_reg, 0), value);
3882 __ RecordWrite(elements,
3883 key_reg,
3884 value,
3885 kSaveFPRegs,
3886 EMIT_REMEMBERED_SET,
3887 check_needed);
3888 } else {
3889 __ movq(operand, value);
3890 }
3891 }
3892
3893
3894 void LCodeGen::DoStoreKeyed(LStoreKeyed* instr) {
3895 if (instr->is_external()) {
3896 DoStoreKeyedExternalArray(instr);
3897 } else if (instr->hydrogen()->value()->representation().IsDouble()) {
3898 DoStoreKeyedFixedDoubleArray(instr);
3899 } else {
3900 DoStoreKeyedFixedArray(instr);
3901 }
3902 }
3903
3904
3881 void LCodeGen::DoStoreKeyedGeneric(LStoreKeyedGeneric* instr) { 3905 void LCodeGen::DoStoreKeyedGeneric(LStoreKeyedGeneric* instr) {
3882 ASSERT(ToRegister(instr->object()).is(rdx)); 3906 ASSERT(ToRegister(instr->object()).is(rdx));
3883 ASSERT(ToRegister(instr->key()).is(rcx)); 3907 ASSERT(ToRegister(instr->key()).is(rcx));
3884 ASSERT(ToRegister(instr->value()).is(rax)); 3908 ASSERT(ToRegister(instr->value()).is(rax));
3885 3909
3886 Handle<Code> ic = (instr->strict_mode_flag() == kStrictMode) 3910 Handle<Code> ic = (instr->strict_mode_flag() == kStrictMode)
3887 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict() 3911 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict()
3888 : isolate()->builtins()->KeyedStoreIC_Initialize(); 3912 : isolate()->builtins()->KeyedStoreIC_Initialize();
3889 CallCode(ic, RelocInfo::CODE_TARGET, instr); 3913 CallCode(ic, RelocInfo::CODE_TARGET, instr);
3890 } 3914 }
(...skipping 1420 matching lines...) Expand 10 before | Expand all | Expand 10 after
5311 FixedArray::kHeaderSize - kPointerSize)); 5335 FixedArray::kHeaderSize - kPointerSize));
5312 __ bind(&done); 5336 __ bind(&done);
5313 } 5337 }
5314 5338
5315 5339
5316 #undef __ 5340 #undef __
5317 5341
5318 } } // namespace v8::internal 5342 } } // namespace v8::internal
5319 5343
5320 #endif // V8_TARGET_ARCH_X64 5344 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « src/x64/lithium-codegen-x64.h ('k') | src/x64/lithium-x64.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698