OLD | NEW |
---|---|
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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_X64. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_X64. |
6 #if defined(TARGET_ARCH_X64) | 6 #if defined(TARGET_ARCH_X64) |
7 | 7 |
8 #include "vm/intermediate_language.h" | 8 #include "vm/intermediate_language.h" |
9 | 9 |
10 #include "vm/compiler.h" | 10 #include "vm/compiler.h" |
(...skipping 2861 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2872 } | 2872 } |
2873 | 2873 |
2874 private: | 2874 private: |
2875 CheckedSmiOpInstr* instruction_; | 2875 CheckedSmiOpInstr* instruction_; |
2876 intptr_t try_index_; | 2876 intptr_t try_index_; |
2877 }; | 2877 }; |
2878 | 2878 |
2879 | 2879 |
2880 LocationSummary* CheckedSmiOpInstr::MakeLocationSummary(Zone* zone, | 2880 LocationSummary* CheckedSmiOpInstr::MakeLocationSummary(Zone* zone, |
2881 bool opt) const { | 2881 bool opt) const { |
2882 bool is_shift = (op_kind() == Token::kSHL) || (op_kind() == Token::kSHR); | |
2882 const intptr_t kNumInputs = 2; | 2883 const intptr_t kNumInputs = 2; |
2883 const intptr_t kNumTemps = 0; | 2884 const intptr_t kNumTemps = is_shift ? 1 : 0; |
2884 LocationSummary* summary = new(zone) LocationSummary( | 2885 LocationSummary* summary = new(zone) LocationSummary( |
2885 zone, kNumInputs, kNumTemps, LocationSummary::kCallOnSlowPath); | 2886 zone, kNumInputs, kNumTemps, LocationSummary::kCallOnSlowPath); |
2886 summary->set_in(0, Location::RequiresRegister()); | 2887 summary->set_in(0, Location::RequiresRegister()); |
2887 summary->set_in(1, Location::RequiresRegister()); | 2888 summary->set_in(1, Location::RequiresRegister()); |
2888 switch (op_kind()) { | 2889 switch (op_kind()) { |
2889 case Token::kADD: | 2890 case Token::kADD: |
2890 case Token::kSUB: | 2891 case Token::kSUB: |
2891 case Token::kMUL: | 2892 case Token::kMUL: |
2893 case Token::kSHL: | |
2894 case Token::kSHR: | |
2892 summary->set_out(0, Location::RequiresRegister()); | 2895 summary->set_out(0, Location::RequiresRegister()); |
2893 break; | 2896 break; |
2894 case Token::kBIT_OR: | 2897 case Token::kBIT_OR: |
2895 case Token::kBIT_AND: | 2898 case Token::kBIT_AND: |
2896 case Token::kBIT_XOR: | 2899 case Token::kBIT_XOR: |
2897 summary->set_out(0, Location::SameAsFirstInput()); | 2900 summary->set_out(0, Location::SameAsFirstInput()); |
2898 break; | 2901 break; |
2899 default: | 2902 default: |
2900 UNIMPLEMENTED(); | 2903 UNIMPLEMENTED(); |
2901 } | 2904 } |
2905 if (is_shift) { | |
2906 summary->set_temp(0, Location::RegisterLocation(RCX)); | |
2907 } | |
2902 return summary; | 2908 return summary; |
2903 } | 2909 } |
2904 | 2910 |
2905 | 2911 |
2906 void CheckedSmiOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 2912 void CheckedSmiOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
2907 CheckedSmiSlowPath* slow_path = | 2913 CheckedSmiSlowPath* slow_path = |
2908 new CheckedSmiSlowPath(this, compiler->CurrentTryIndex()); | 2914 new CheckedSmiSlowPath(this, compiler->CurrentTryIndex()); |
2909 compiler->AddSlowPathCode(slow_path); | 2915 compiler->AddSlowPathCode(slow_path); |
2910 // Test operands if necessary. | 2916 // Test operands if necessary. |
2911 | 2917 |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2948 __ orq(result, right); | 2954 __ orq(result, right); |
2949 break; | 2955 break; |
2950 case Token::kBIT_AND: | 2956 case Token::kBIT_AND: |
2951 ASSERT(left == result); | 2957 ASSERT(left == result); |
2952 __ andq(result, right); | 2958 __ andq(result, right); |
2953 break; | 2959 break; |
2954 case Token::kBIT_XOR: | 2960 case Token::kBIT_XOR: |
2955 ASSERT(left == result); | 2961 ASSERT(left == result); |
2956 __ xorq(result, right); | 2962 __ xorq(result, right); |
2957 break; | 2963 break; |
2964 case Token::kSHL: | |
2965 ASSERT(result != right); | |
2966 ASSERT(locs()->temp(0).reg() == RCX); | |
2967 __ cmpq(right, Immediate(Smi::RawValue(Smi::kBits))); | |
2968 __ j(ABOVE_EQUAL, slow_path->entry_label()); | |
2969 | |
2970 __ movq(RCX, right); | |
2971 __ SmiUntag(RCX); | |
2972 __ movq(result, left); | |
2973 __ shlq(result, RCX); | |
2974 __ movq(TMP, result); | |
2975 __ sarq(TMP, RCX); | |
2976 __ cmpq(TMP, result); | |
2977 __ j(NOT_EQUAL, slow_path->entry_label()); | |
2978 break; | |
2979 case Token::kSHR: { | |
2980 Label shift_count_ok; | |
2981 ASSERT(result != right); | |
2982 ASSERT(locs()->temp(0).reg() == RCX); | |
2983 __ cmpq(right, Immediate(0)); | |
2984 __ j(LESS, slow_path->entry_label()); | |
Florian Schneider
2016/11/11 18:12:20
Can you use unsigned compare "right < (unsigned)Sm
rmacnak
2016/11/11 21:29:02
Yes. As discussed offline this means something lik
| |
2985 | |
2986 __ movq(RCX, right); | |
2987 __ SmiUntag(RCX); | |
2988 __ cmpq(RCX, Immediate(0x3F)); | |
2989 __ j(LESS_EQUAL, &shift_count_ok, Assembler::kNearJump); | |
2990 __ movq(RCX, Immediate(0x3F)); | |
2991 __ Bind(&shift_count_ok); | |
2992 __ movq(result, left); | |
2993 __ SmiUntag(result); | |
2994 __ sarq(result, RCX); | |
2995 __ SmiTag(result); | |
2996 break; | |
2997 } | |
2958 default: | 2998 default: |
2959 UNIMPLEMENTED(); | 2999 UNIMPLEMENTED(); |
2960 } | 3000 } |
2961 __ Bind(slow_path->exit_label()); | 3001 __ Bind(slow_path->exit_label()); |
2962 } | 3002 } |
2963 | 3003 |
2964 | 3004 |
2965 class CheckedSmiComparisonSlowPath : public SlowPathCode { | 3005 class CheckedSmiComparisonSlowPath : public SlowPathCode { |
2966 public: | 3006 public: |
2967 CheckedSmiComparisonSlowPath(CheckedSmiComparisonInstr* instruction, | 3007 CheckedSmiComparisonSlowPath(CheckedSmiComparisonInstr* instruction, |
(...skipping 3845 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6813 __ Drop(1); | 6853 __ Drop(1); |
6814 __ popq(result); | 6854 __ popq(result); |
6815 } | 6855 } |
6816 | 6856 |
6817 | 6857 |
6818 } // namespace dart | 6858 } // namespace dart |
6819 | 6859 |
6820 #undef __ | 6860 #undef __ |
6821 | 6861 |
6822 #endif // defined TARGET_ARCH_X64 | 6862 #endif // defined TARGET_ARCH_X64 |
OLD | NEW |