| 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_IA32. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_IA32. |
| 6 #if defined(TARGET_ARCH_IA32) | 6 #if defined(TARGET_ARCH_IA32) |
| 7 | 7 |
| 8 #include "vm/intermediate_language.h" | 8 #include "vm/intermediate_language.h" |
| 9 | 9 |
| 10 #include "vm/dart_entry.h" | 10 #include "vm/dart_entry.h" |
| (...skipping 2810 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2821 // TODO(turnidge): Implement stack overflow count in assembly to | 2821 // TODO(turnidge): Implement stack overflow count in assembly to |
| 2822 // make --stacktrace-every and --deoptimize-every faster. | 2822 // make --stacktrace-every and --deoptimize-every faster. |
| 2823 __ jmp(slow_path->entry_label()); | 2823 __ jmp(slow_path->entry_label()); |
| 2824 } | 2824 } |
| 2825 __ Bind(slow_path->exit_label()); | 2825 __ Bind(slow_path->exit_label()); |
| 2826 } | 2826 } |
| 2827 | 2827 |
| 2828 | 2828 |
| 2829 static void EmitSmiShiftLeft(FlowGraphCompiler* compiler, | 2829 static void EmitSmiShiftLeft(FlowGraphCompiler* compiler, |
| 2830 BinarySmiOpInstr* shift_left) { | 2830 BinarySmiOpInstr* shift_left) { |
| 2831 const bool is_truncating = shift_left->is_truncating(); | 2831 const bool is_truncating = shift_left->IsTruncating(); |
| 2832 const LocationSummary& locs = *shift_left->locs(); | 2832 const LocationSummary& locs = *shift_left->locs(); |
| 2833 Register left = locs.in(0).reg(); | 2833 Register left = locs.in(0).reg(); |
| 2834 Register result = locs.out(0).reg(); | 2834 Register result = locs.out(0).reg(); |
| 2835 ASSERT(left == result); | 2835 ASSERT(left == result); |
| 2836 Label* deopt = shift_left->CanDeoptimize() ? | 2836 Label* deopt = shift_left->CanDeoptimize() ? |
| 2837 compiler->AddDeoptStub(shift_left->deopt_id(), ICData::kDeoptBinarySmiOp) | 2837 compiler->AddDeoptStub(shift_left->deopt_id(), ICData::kDeoptBinarySmiOp) |
| 2838 : NULL; | 2838 : NULL; |
| 2839 if (locs.in(1).IsConstant()) { | 2839 if (locs.in(1).IsConstant()) { |
| 2840 const Object& constant = locs.in(1).constant(); | 2840 const Object& constant = locs.in(1).constant(); |
| 2841 ASSERT(constant.IsSmi()); | 2841 ASSERT(constant.IsSmi()); |
| 2842 // shll operation masks the count to 5 bits. | 2842 // shll operation masks the count to 5 bits. |
| 2843 const intptr_t kCountLimit = 0x1F; | 2843 const intptr_t kCountLimit = 0x1F; |
| 2844 const intptr_t value = Smi::Cast(constant).Value(); | 2844 const intptr_t value = Smi::Cast(constant).Value(); |
| 2845 if (value == 0) { | 2845 if (value == 0) { |
| 2846 // No code needed. | 2846 // No code needed. |
| 2847 } else if ((value < 0) || (value >= kCountLimit)) { | 2847 } else if ((value < 0) || (value >= kCountLimit)) { |
| 2848 // This condition may not be known earlier in some cases because | 2848 // This condition may not be known earlier in some cases because |
| 2849 // of constant propagation, inlining, etc. | 2849 // of constant propagation, inlining, etc. |
| 2850 if ((value >=kCountLimit) && is_truncating) { | 2850 if ((value >= kCountLimit) && is_truncating) { |
| 2851 __ xorl(result, result); | 2851 __ xorl(result, result); |
| 2852 } else { | 2852 } else { |
| 2853 // Result is Mint or exception. | 2853 // Result is Mint or exception. |
| 2854 __ jmp(deopt); | 2854 __ jmp(deopt); |
| 2855 } | 2855 } |
| 2856 } else { | 2856 } else { |
| 2857 if (!is_truncating) { | 2857 if (!is_truncating) { |
| 2858 // Check for overflow. | 2858 // Check for overflow. |
| 2859 Register temp = locs.temp(0).reg(); | 2859 Register temp = locs.temp(0).reg(); |
| 2860 __ movl(temp, left); | 2860 __ movl(temp, left); |
| (...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2983 return summary; | 2983 return summary; |
| 2984 } else if (op_kind() == Token::kSHR) { | 2984 } else if (op_kind() == Token::kSHR) { |
| 2985 const intptr_t kNumTemps = 0; | 2985 const intptr_t kNumTemps = 0; |
| 2986 LocationSummary* summary = new(isolate) LocationSummary( | 2986 LocationSummary* summary = new(isolate) LocationSummary( |
| 2987 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); | 2987 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 2988 summary->set_in(0, Location::RequiresRegister()); | 2988 summary->set_in(0, Location::RequiresRegister()); |
| 2989 summary->set_in(1, Location::FixedRegisterOrSmiConstant(right(), ECX)); | 2989 summary->set_in(1, Location::FixedRegisterOrSmiConstant(right(), ECX)); |
| 2990 summary->set_out(0, Location::SameAsFirstInput()); | 2990 summary->set_out(0, Location::SameAsFirstInput()); |
| 2991 return summary; | 2991 return summary; |
| 2992 } else if (op_kind() == Token::kSHL) { | 2992 } else if (op_kind() == Token::kSHL) { |
| 2993 const intptr_t kNumTemps = !is_truncating() ? 1 : 0; | 2993 const intptr_t kNumTemps = !IsTruncating() ? 1 : 0; |
| 2994 LocationSummary* summary = new(isolate) LocationSummary( | 2994 LocationSummary* summary = new(isolate) LocationSummary( |
| 2995 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); | 2995 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 2996 summary->set_in(0, Location::RequiresRegister()); | 2996 summary->set_in(0, Location::RequiresRegister()); |
| 2997 summary->set_in(1, Location::FixedRegisterOrSmiConstant(right(), ECX)); | 2997 summary->set_in(1, Location::FixedRegisterOrSmiConstant(right(), ECX)); |
| 2998 if (!is_truncating()) { | 2998 if (!IsTruncating()) { |
| 2999 summary->set_temp(0, Location::RequiresRegister()); | 2999 summary->set_temp(0, Location::RequiresRegister()); |
| 3000 } | 3000 } |
| 3001 summary->set_out(0, Location::SameAsFirstInput()); | 3001 summary->set_out(0, Location::SameAsFirstInput()); |
| 3002 return summary; | 3002 return summary; |
| 3003 } else { | 3003 } else { |
| 3004 const intptr_t kNumTemps = 0; | 3004 const intptr_t kNumTemps = 0; |
| 3005 LocationSummary* summary = new(isolate) LocationSummary( | 3005 LocationSummary* summary = new(isolate) LocationSummary( |
| 3006 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3006 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 3007 summary->set_in(0, Location::RequiresRegister()); | 3007 summary->set_in(0, Location::RequiresRegister()); |
| 3008 ConstantInstr* constant = right()->definition()->AsConstant(); | 3008 ConstantInstr* constant = right()->definition()->AsConstant(); |
| 3009 if (constant != NULL) { | 3009 if (constant != NULL) { |
| 3010 summary->set_in(1, Location::RegisterOrSmiConstant(right())); | 3010 summary->set_in(1, Location::RegisterOrSmiConstant(right())); |
| 3011 } else { | 3011 } else { |
| 3012 summary->set_in(1, Location::PrefersRegister()); | 3012 summary->set_in(1, Location::PrefersRegister()); |
| 3013 } | 3013 } |
| 3014 summary->set_out(0, Location::SameAsFirstInput()); | 3014 summary->set_out(0, Location::SameAsFirstInput()); |
| 3015 return summary; | 3015 return summary; |
| 3016 } | 3016 } |
| 3017 } | 3017 } |
| 3018 | 3018 |
| 3019 | 3019 |
| 3020 void BinarySmiOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3020 void BinarySmiOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3021 if (op_kind() == Token::kSHL) { | 3021 if (op_kind() == Token::kSHL) { |
| 3022 EmitSmiShiftLeft(compiler, this); | 3022 EmitSmiShiftLeft(compiler, this); |
| 3023 return; | 3023 return; |
| 3024 } | 3024 } |
| 3025 | 3025 |
| 3026 ASSERT(!is_truncating()); | |
| 3027 Register left = locs()->in(0).reg(); | 3026 Register left = locs()->in(0).reg(); |
| 3028 Register result = locs()->out(0).reg(); | 3027 Register result = locs()->out(0).reg(); |
| 3029 ASSERT(left == result); | 3028 ASSERT(left == result); |
| 3030 Label* deopt = NULL; | 3029 Label* deopt = NULL; |
| 3031 if (CanDeoptimize()) { | 3030 if (CanDeoptimize()) { |
| 3032 deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptBinarySmiOp); | 3031 deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptBinarySmiOp); |
| 3033 } | 3032 } |
| 3034 | 3033 |
| 3035 if (locs()->in(1).IsConstant()) { | 3034 if (locs()->in(1).IsConstant()) { |
| 3036 const Object& constant = locs()->in(1).constant(); | 3035 const Object& constant = locs()->in(1).constant(); |
| (...skipping 3271 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6308 __ movl(EDX, Immediate(kInvalidObjectPointer)); | 6307 __ movl(EDX, Immediate(kInvalidObjectPointer)); |
| 6309 __ movl(EDX, Immediate(kInvalidObjectPointer)); | 6308 __ movl(EDX, Immediate(kInvalidObjectPointer)); |
| 6310 #endif | 6309 #endif |
| 6311 } | 6310 } |
| 6312 | 6311 |
| 6313 } // namespace dart | 6312 } // namespace dart |
| 6314 | 6313 |
| 6315 #undef __ | 6314 #undef __ |
| 6316 | 6315 |
| 6317 #endif // defined TARGET_ARCH_IA32 | 6316 #endif // defined TARGET_ARCH_IA32 |
| OLD | NEW |