| OLD | NEW |
| 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_DBC. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_DBC. |
| 6 #if defined(TARGET_ARCH_DBC) | 6 #if defined(TARGET_ARCH_DBC) |
| 7 | 7 |
| 8 #include "vm/intermediate_language.h" | 8 #include "vm/intermediate_language.h" |
| 9 | 9 |
| 10 #include "vm/cpu.h" | 10 #include "vm/cpu.h" |
| (...skipping 13 matching lines...) Expand all Loading... |
| 24 #define __ compiler->assembler()-> | 24 #define __ compiler->assembler()-> |
| 25 | 25 |
| 26 namespace dart { | 26 namespace dart { |
| 27 | 27 |
| 28 DECLARE_FLAG(bool, emit_edge_counters); | 28 DECLARE_FLAG(bool, emit_edge_counters); |
| 29 DECLARE_FLAG(int, optimization_counter_threshold); | 29 DECLARE_FLAG(int, optimization_counter_threshold); |
| 30 | 30 |
| 31 // List of instructions that are still unimplemented by DBC backend. | 31 // List of instructions that are still unimplemented by DBC backend. |
| 32 #define FOR_EACH_UNIMPLEMENTED_INSTRUCTION(M) \ | 32 #define FOR_EACH_UNIMPLEMENTED_INSTRUCTION(M) \ |
| 33 M(LoadCodeUnits) \ | 33 M(LoadCodeUnits) \ |
| 34 M(LoadUntagged) \ | |
| 35 M(AllocateUninitializedContext) \ | |
| 36 M(BinaryInt32Op) \ | 34 M(BinaryInt32Op) \ |
| 37 M(Int32ToDouble) \ | 35 M(Int32ToDouble) \ |
| 38 M(DoubleToInteger) \ | 36 M(DoubleToInteger) \ |
| 39 M(DoubleToDouble) \ | 37 M(DoubleToDouble) \ |
| 40 M(DoubleToFloat) \ | 38 M(DoubleToFloat) \ |
| 41 M(FloatToDouble) \ | 39 M(FloatToDouble) \ |
| 42 M(BoxInt64) \ | 40 M(BoxInt64) \ |
| 43 M(MergedMath) \ | 41 M(MergedMath) \ |
| 44 M(GuardFieldClass) \ | 42 M(GuardFieldClass) \ |
| 45 M(GuardFieldLength) \ | 43 M(GuardFieldLength) \ |
| (...skipping 647 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 693 __ CreateArrayTOS(); | 691 __ CreateArrayTOS(); |
| 694 compiler->RecordSafepoint(locs()); | 692 compiler->RecordSafepoint(locs()); |
| 695 if (compiler->is_optimizing()) { | 693 if (compiler->is_optimizing()) { |
| 696 __ PopLocal(locs()->out(0).reg()); | 694 __ PopLocal(locs()->out(0).reg()); |
| 697 } | 695 } |
| 698 } | 696 } |
| 699 | 697 |
| 700 | 698 |
| 701 EMIT_NATIVE_CODE(StoreIndexed, 3, Location::NoLocation(), | 699 EMIT_NATIVE_CODE(StoreIndexed, 3, Location::NoLocation(), |
| 702 LocationSummary::kNoCall, 1) { | 700 LocationSummary::kNoCall, 1) { |
| 703 if (compiler->is_optimizing()) { | 701 if (!compiler->is_optimizing()) { |
| 704 if (IsExternal()) { | 702 ASSERT(class_id() == kArrayCid); |
| 703 __ StoreIndexedTOS(); |
| 704 return; |
| 705 } |
| 706 |
| 707 const Register array = locs()->in(kArrayPos).reg(); |
| 708 const Register index = locs()->in(kIndexPos).reg(); |
| 709 const Register value = locs()->in(kValuePos).reg(); |
| 710 const Register temp = locs()->temp(0).reg(); |
| 711 switch (class_id()) { |
| 712 case kArrayCid: |
| 713 __ StoreIndexed(array, index, value); |
| 714 break; |
| 715 case kTypedDataUint8ArrayCid: |
| 716 case kTypedDataInt8ArrayCid: |
| 717 case kExternalOneByteStringCid: |
| 718 case kExternalTypedDataUint8ArrayCid: |
| 719 ASSERT(index_scale() == 1); |
| 720 if (IsExternal()) { |
| 721 __ StoreIndexedExternalUint8(array, index, value); |
| 722 } else { |
| 723 __ StoreIndexedUint8(array, index, value); |
| 724 } |
| 725 break; |
| 726 case kTypedDataFloat64ArrayCid: |
| 727 if (IsExternal() || ((index_scale() != 8) && (index_scale() != 1))) { |
| 728 Unsupported(compiler); |
| 729 UNREACHABLE(); |
| 730 } |
| 731 if (index_scale() == 1) { |
| 732 __ ShrImm(temp, index, 3); |
| 733 } else { |
| 734 __ Move(temp, index); |
| 735 } |
| 736 __ StoreIndexedFloat64(array, temp, value); |
| 737 break; |
| 738 default: |
| 705 Unsupported(compiler); | 739 Unsupported(compiler); |
| 706 UNREACHABLE(); | 740 UNREACHABLE(); |
| 707 } | 741 break; |
| 708 const Register array = locs()->in(kArrayPos).reg(); | |
| 709 const Register index = locs()->in(kIndexPos).reg(); | |
| 710 const Register value = locs()->in(kValuePos).reg(); | |
| 711 const Register temp = locs()->temp(0).reg(); | |
| 712 switch (class_id()) { | |
| 713 case kArrayCid: | |
| 714 __ StoreIndexed(array, index, value); | |
| 715 break; | |
| 716 case kTypedDataFloat64ArrayCid: | |
| 717 if ((index_scale() != 8) && (index_scale() != 1)) { | |
| 718 Unsupported(compiler); | |
| 719 UNREACHABLE(); | |
| 720 } | |
| 721 if (index_scale() == 1) { | |
| 722 __ ShrImm(temp, index, 3); | |
| 723 } else { | |
| 724 __ Move(temp, index); | |
| 725 } | |
| 726 __ StoreFloat64Indexed(array, temp, value); | |
| 727 break; | |
| 728 default: | |
| 729 Unsupported(compiler); | |
| 730 UNREACHABLE(); | |
| 731 break; | |
| 732 } | |
| 733 } else { | |
| 734 ASSERT(class_id() == kArrayCid); | |
| 735 __ StoreIndexedTOS(); | |
| 736 } | 742 } |
| 737 } | 743 } |
| 738 | 744 |
| 739 | 745 |
| 740 EMIT_NATIVE_CODE(LoadIndexed, 2, Location::RequiresRegister()) { | 746 EMIT_NATIVE_CODE(LoadIndexed, 2, Location::RequiresRegister()) { |
| 741 ASSERT(compiler->is_optimizing()); | 747 ASSERT(compiler->is_optimizing()); |
| 742 if (IsExternal()) { | |
| 743 Unsupported(compiler); | |
| 744 UNREACHABLE(); | |
| 745 } | |
| 746 const Register array = locs()->in(0).reg(); | 748 const Register array = locs()->in(0).reg(); |
| 747 const Register index = locs()->in(1).reg(); | 749 const Register index = locs()->in(1).reg(); |
| 748 const Register result = locs()->out(0).reg(); | 750 const Register result = locs()->out(0).reg(); |
| 749 switch (class_id()) { | 751 switch (class_id()) { |
| 750 case kArrayCid: | 752 case kArrayCid: |
| 751 __ LoadIndexed(result, array, index); | 753 __ LoadIndexed(result, array, index); |
| 752 break; | 754 break; |
| 753 case kTypedDataFloat64ArrayCid: | 755 case kTypedDataUint8ArrayCid: |
| 754 if ((index_scale() != 8) && (index_scale() != 1)) { | 756 case kTypedDataUint8ClampedArrayCid: |
| 755 Unsupported(compiler); | 757 case kExternalOneByteStringCid: |
| 756 UNREACHABLE(); | 758 case kExternalTypedDataUint8ArrayCid: |
| 759 case kExternalTypedDataUint8ClampedArrayCid: |
| 760 ASSERT(index_scale() == 1); |
| 761 if (IsExternal()) { |
| 762 __ LoadIndexedExternalUint8(result, array, index); |
| 763 } else { |
| 764 __ LoadIndexedUint8(result, array, index); |
| 757 } | 765 } |
| 758 if (index_scale() == 1) { | 766 break; |
| 759 __ ShrImm(index, index, 3); | 767 case kTypedDataInt8ArrayCid: |
| 768 ASSERT(index_scale() == 1); |
| 769 if (IsExternal()) { |
| 770 __ LoadIndexedExternalInt8(result, array, index); |
| 771 } else { |
| 772 __ LoadIndexedInt8(result, array, index); |
| 760 } | 773 } |
| 761 __ LoadFloat64Indexed(result, array, index); | |
| 762 break; | 774 break; |
| 763 case kOneByteStringCid: | 775 case kOneByteStringCid: |
| 764 ASSERT(index_scale() == 1); | 776 ASSERT(index_scale() == 1); |
| 765 __ LoadOneByteStringIndexed(result, array, index); | 777 __ LoadIndexedOneByteString(result, array, index); |
| 766 break; | 778 break; |
| 767 case kTwoByteStringCid: | 779 case kTwoByteStringCid: |
| 768 if (index_scale() != 2) { | 780 if (index_scale() != 2) { |
| 769 // TODO(zra): Fix-up index. | 781 // TODO(zra): Fix-up index. |
| 770 Unsupported(compiler); | 782 Unsupported(compiler); |
| 771 UNREACHABLE(); | 783 UNREACHABLE(); |
| 772 } | 784 } |
| 773 __ LoadTwoByteStringIndexed(result, array, index); | 785 __ LoadIndexedTwoByteString(result, array, index); |
| 786 break; |
| 787 case kTypedDataFloat64ArrayCid: |
| 788 if ((index_scale() != 8) && (index_scale() != 1)) { |
| 789 Unsupported(compiler); |
| 790 UNREACHABLE(); |
| 791 } |
| 792 if (index_scale() == 1) { |
| 793 __ ShrImm(index, index, 3); |
| 794 } |
| 795 __ LoadIndexedFloat64(result, array, index); |
| 774 break; | 796 break; |
| 775 default: | 797 default: |
| 776 Unsupported(compiler); | 798 Unsupported(compiler); |
| 777 UNREACHABLE(); | 799 UNREACHABLE(); |
| 778 break; | 800 break; |
| 779 } | 801 } |
| 780 } | 802 } |
| 781 | 803 |
| 782 | 804 |
| 783 EMIT_NATIVE_CODE(StringInterpolate, | 805 EMIT_NATIVE_CODE(StringInterpolate, |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 887 if (compiler->is_optimizing()) { | 909 if (compiler->is_optimizing()) { |
| 888 const Register result = locs()->out(0).reg(); | 910 const Register result = locs()->out(0).reg(); |
| 889 const Register instance = locs()->in(0).reg(); | 911 const Register instance = locs()->in(0).reg(); |
| 890 __ LoadField(result, instance, offset_in_bytes() / kWordSize); | 912 __ LoadField(result, instance, offset_in_bytes() / kWordSize); |
| 891 } else { | 913 } else { |
| 892 __ LoadFieldTOS(offset_in_bytes() / kWordSize); | 914 __ LoadFieldTOS(offset_in_bytes() / kWordSize); |
| 893 } | 915 } |
| 894 } | 916 } |
| 895 | 917 |
| 896 | 918 |
| 919 EMIT_NATIVE_CODE(LoadUntagged, 1, Location::RequiresRegister()) { |
| 920 const Register obj = locs()->in(0).reg(); |
| 921 const Register result = locs()->out(0).reg(); |
| 922 if (object()->definition()->representation() == kUntagged) { |
| 923 __ LoadUntagged(result, obj, offset() / kWordSize); |
| 924 } else { |
| 925 ASSERT(object()->definition()->representation() == kTagged); |
| 926 __ LoadField(result, obj, offset() / kWordSize); |
| 927 } |
| 928 } |
| 929 |
| 930 |
| 897 EMIT_NATIVE_CODE(BooleanNegate, 1, Location::RequiresRegister()) { | 931 EMIT_NATIVE_CODE(BooleanNegate, 1, Location::RequiresRegister()) { |
| 898 if (compiler->is_optimizing()) { | 932 if (compiler->is_optimizing()) { |
| 899 __ BooleanNegate(locs()->out(0).reg(), locs()->in(0).reg()); | 933 __ BooleanNegate(locs()->out(0).reg(), locs()->in(0).reg()); |
| 900 } else { | 934 } else { |
| 901 __ BooleanNegateTOS(); | 935 __ BooleanNegateTOS(); |
| 902 } | 936 } |
| 903 } | 937 } |
| 904 | 938 |
| 905 | 939 |
| 906 EMIT_NATIVE_CODE(AllocateContext, | 940 EMIT_NATIVE_CODE(AllocateContext, |
| 907 0, Location::RequiresRegister(), | 941 0, Location::RequiresRegister(), |
| 908 LocationSummary::kCall) { | 942 LocationSummary::kCall) { |
| 909 ASSERT(!compiler->is_optimizing()); | 943 ASSERT(!compiler->is_optimizing()); |
| 910 __ AllocateContext(num_context_variables()); | 944 __ AllocateContext(num_context_variables()); |
| 911 compiler->RecordSafepoint(locs()); | 945 compiler->RecordSafepoint(locs()); |
| 912 compiler->AddCurrentDescriptor(RawPcDescriptors::kOther, | 946 compiler->AddCurrentDescriptor(RawPcDescriptors::kOther, |
| 913 Thread::kNoDeoptId, | 947 Thread::kNoDeoptId, |
| 914 token_pos()); | 948 token_pos()); |
| 915 } | 949 } |
| 916 | 950 |
| 917 | 951 |
| 952 EMIT_NATIVE_CODE(AllocateUninitializedContext, |
| 953 0, Location::RequiresRegister(), |
| 954 LocationSummary::kCall) { |
| 955 ASSERT(compiler->is_optimizing()); |
| 956 __ AllocateContext(num_context_variables()); |
| 957 compiler->RecordSafepoint(locs()); |
| 958 compiler->AddCurrentDescriptor(RawPcDescriptors::kOther, |
| 959 Thread::kNoDeoptId, |
| 960 token_pos()); |
| 961 __ PopLocal(locs()->out(0).reg()); |
| 962 } |
| 963 |
| 964 |
| 918 EMIT_NATIVE_CODE(CloneContext, | 965 EMIT_NATIVE_CODE(CloneContext, |
| 919 1, Location::RequiresRegister(), | 966 1, Location::RequiresRegister(), |
| 920 LocationSummary::kCall) { | 967 LocationSummary::kCall) { |
| 921 ASSERT(!compiler->is_optimizing()); | 968 if (compiler->is_optimizing()) { |
| 969 __ Push(locs()->in(0).reg()); |
| 970 } |
| 922 __ CloneContext(); | 971 __ CloneContext(); |
| 923 compiler->RecordSafepoint(locs()); | 972 compiler->RecordSafepoint(locs()); |
| 924 compiler->AddCurrentDescriptor(RawPcDescriptors::kOther, | 973 compiler->AddCurrentDescriptor(RawPcDescriptors::kOther, |
| 925 Thread::kNoDeoptId, | 974 Thread::kNoDeoptId, |
| 926 token_pos()); | 975 token_pos()); |
| 976 if (compiler->is_optimizing()) { |
| 977 __ PopLocal(locs()->out(0).reg()); |
| 978 } |
| 927 } | 979 } |
| 928 | 980 |
| 929 | 981 |
| 930 EMIT_NATIVE_CODE(CatchBlockEntry, 0) { | 982 EMIT_NATIVE_CODE(CatchBlockEntry, 0) { |
| 931 __ Bind(compiler->GetJumpLabel(this)); | 983 __ Bind(compiler->GetJumpLabel(this)); |
| 932 compiler->AddExceptionHandler(catch_try_index(), | 984 compiler->AddExceptionHandler(catch_try_index(), |
| 933 try_index(), | 985 try_index(), |
| 934 compiler->assembler()->CodeSize(), | 986 compiler->assembler()->CodeSize(), |
| 935 catch_handler_types_, | 987 catch_handler_types_, |
| 936 needs_stacktrace()); | 988 needs_stacktrace()); |
| (...skipping 681 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1618 __ IfULe(length, index); | 1670 __ IfULe(length, index); |
| 1619 compiler->EmitDeopt(deopt_id(), | 1671 compiler->EmitDeopt(deopt_id(), |
| 1620 ICData::kDeoptCheckArrayBound, | 1672 ICData::kDeoptCheckArrayBound, |
| 1621 (generalized_ ? ICData::kGeneralized : 0) | | 1673 (generalized_ ? ICData::kGeneralized : 0) | |
| 1622 (licm_hoisted_ ? ICData::kHoisted : 0)); | 1674 (licm_hoisted_ ? ICData::kHoisted : 0)); |
| 1623 } | 1675 } |
| 1624 | 1676 |
| 1625 } // namespace dart | 1677 } // namespace dart |
| 1626 | 1678 |
| 1627 #endif // defined TARGET_ARCH_DBC | 1679 #endif // defined TARGET_ARCH_DBC |
| OLD | NEW |