| OLD | NEW |
| 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, 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_ARM64. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_ARM64. |
| 6 #if defined(TARGET_ARCH_ARM64) | 6 #if defined(TARGET_ARCH_ARM64) |
| 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 2488 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2499 __ LoadImmediate(TMP, 0x20000000000000LL, PP); | 2499 __ LoadImmediate(TMP, 0x20000000000000LL, PP); |
| 2500 __ add(TMP2, result, Operand(TMP)); | 2500 __ add(TMP2, result, Operand(TMP)); |
| 2501 __ cmp(TMP2, Operand(TMP, LSL, 1)); | 2501 __ cmp(TMP2, Operand(TMP, LSL, 1)); |
| 2502 __ b(overflow, HI); | 2502 __ b(overflow, HI); |
| 2503 } | 2503 } |
| 2504 } | 2504 } |
| 2505 | 2505 |
| 2506 | 2506 |
| 2507 static void EmitSmiShiftLeft(FlowGraphCompiler* compiler, | 2507 static void EmitSmiShiftLeft(FlowGraphCompiler* compiler, |
| 2508 BinarySmiOpInstr* shift_left) { | 2508 BinarySmiOpInstr* shift_left) { |
| 2509 const bool is_truncating = shift_left->is_truncating(); | 2509 const bool is_truncating = shift_left->IsTruncating(); |
| 2510 const LocationSummary& locs = *shift_left->locs(); | 2510 const LocationSummary& locs = *shift_left->locs(); |
| 2511 const Register left = locs.in(0).reg(); | 2511 const Register left = locs.in(0).reg(); |
| 2512 const Register result = locs.out(0).reg(); | 2512 const Register result = locs.out(0).reg(); |
| 2513 Label* deopt = shift_left->CanDeoptimize() ? | 2513 Label* deopt = shift_left->CanDeoptimize() ? |
| 2514 compiler->AddDeoptStub(shift_left->deopt_id(), ICData::kDeoptBinarySmiOp) | 2514 compiler->AddDeoptStub(shift_left->deopt_id(), ICData::kDeoptBinarySmiOp) |
| 2515 : NULL; | 2515 : NULL; |
| 2516 if (locs.in(1).IsConstant()) { | 2516 if (locs.in(1).IsConstant()) { |
| 2517 const Object& constant = locs.in(1).constant(); | 2517 const Object& constant = locs.in(1).constant(); |
| 2518 ASSERT(constant.IsSmi()); | 2518 ASSERT(constant.IsSmi()); |
| 2519 // Immediate shift operation takes 6 bits for the count. | 2519 // Immediate shift operation takes 6 bits for the count. |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2623 if (FLAG_throw_on_javascript_int_overflow) { | 2623 if (FLAG_throw_on_javascript_int_overflow) { |
| 2624 EmitJavascriptOverflowCheck(compiler, shift_left->range(), deopt, result); | 2624 EmitJavascriptOverflowCheck(compiler, shift_left->range(), deopt, result); |
| 2625 } | 2625 } |
| 2626 } | 2626 } |
| 2627 | 2627 |
| 2628 | 2628 |
| 2629 LocationSummary* BinarySmiOpInstr::MakeLocationSummary(Isolate* isolate, | 2629 LocationSummary* BinarySmiOpInstr::MakeLocationSummary(Isolate* isolate, |
| 2630 bool opt) const { | 2630 bool opt) const { |
| 2631 const intptr_t kNumInputs = 2; | 2631 const intptr_t kNumInputs = 2; |
| 2632 const intptr_t kNumTemps = | 2632 const intptr_t kNumTemps = |
| 2633 (((op_kind() == Token::kSHL) && !is_truncating()) || | 2633 (((op_kind() == Token::kSHL) && !IsTruncating()) || |
| 2634 (op_kind() == Token::kSHR)) ? 1 : 0; | 2634 (op_kind() == Token::kSHR)) ? 1 : 0; |
| 2635 LocationSummary* summary = new(isolate) LocationSummary( | 2635 LocationSummary* summary = new(isolate) LocationSummary( |
| 2636 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); | 2636 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 2637 if (op_kind() == Token::kTRUNCDIV) { | 2637 if (op_kind() == Token::kTRUNCDIV) { |
| 2638 summary->set_in(0, Location::RequiresRegister()); | 2638 summary->set_in(0, Location::RequiresRegister()); |
| 2639 if (RightIsPowerOfTwoConstant()) { | 2639 if (RightIsPowerOfTwoConstant()) { |
| 2640 ConstantInstr* right_constant = right()->definition()->AsConstant(); | 2640 ConstantInstr* right_constant = right()->definition()->AsConstant(); |
| 2641 summary->set_in(1, Location::Constant(right_constant->value())); | 2641 summary->set_in(1, Location::Constant(right_constant->value())); |
| 2642 } else { | 2642 } else { |
| 2643 summary->set_in(1, Location::RequiresRegister()); | 2643 summary->set_in(1, Location::RequiresRegister()); |
| 2644 } | 2644 } |
| 2645 summary->set_out(0, Location::RequiresRegister()); | 2645 summary->set_out(0, Location::RequiresRegister()); |
| 2646 return summary; | 2646 return summary; |
| 2647 } | 2647 } |
| 2648 if (op_kind() == Token::kMOD) { | 2648 if (op_kind() == Token::kMOD) { |
| 2649 summary->set_in(0, Location::RequiresRegister()); | 2649 summary->set_in(0, Location::RequiresRegister()); |
| 2650 summary->set_in(1, Location::RequiresRegister()); | 2650 summary->set_in(1, Location::RequiresRegister()); |
| 2651 summary->set_out(0, Location::RequiresRegister()); | 2651 summary->set_out(0, Location::RequiresRegister()); |
| 2652 return summary; | 2652 return summary; |
| 2653 } | 2653 } |
| 2654 summary->set_in(0, Location::RequiresRegister()); | 2654 summary->set_in(0, Location::RequiresRegister()); |
| 2655 summary->set_in(1, Location::RegisterOrSmiConstant(right())); | 2655 summary->set_in(1, Location::RegisterOrSmiConstant(right())); |
| 2656 if (((op_kind() == Token::kSHL) && !is_truncating()) || | 2656 if (((op_kind() == Token::kSHL) && !IsTruncating()) || |
| 2657 (op_kind() == Token::kSHR)) { | 2657 (op_kind() == Token::kSHR)) { |
| 2658 summary->set_temp(0, Location::RequiresRegister()); | 2658 summary->set_temp(0, Location::RequiresRegister()); |
| 2659 } | 2659 } |
| 2660 // We make use of 3-operand instructions by not requiring result register | 2660 // We make use of 3-operand instructions by not requiring result register |
| 2661 // to be identical to first input register as on Intel. | 2661 // to be identical to first input register as on Intel. |
| 2662 summary->set_out(0, Location::RequiresRegister()); | 2662 summary->set_out(0, Location::RequiresRegister()); |
| 2663 return summary; | 2663 return summary; |
| 2664 } | 2664 } |
| 2665 | 2665 |
| 2666 | 2666 |
| 2667 void BinarySmiOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 2667 void BinarySmiOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 2668 if (op_kind() == Token::kSHL) { | 2668 if (op_kind() == Token::kSHL) { |
| 2669 EmitSmiShiftLeft(compiler, this); | 2669 EmitSmiShiftLeft(compiler, this); |
| 2670 return; | 2670 return; |
| 2671 } | 2671 } |
| 2672 | 2672 |
| 2673 ASSERT(!is_truncating()); | |
| 2674 const Register left = locs()->in(0).reg(); | 2673 const Register left = locs()->in(0).reg(); |
| 2675 const Register result = locs()->out(0).reg(); | 2674 const Register result = locs()->out(0).reg(); |
| 2676 Label* deopt = NULL; | 2675 Label* deopt = NULL; |
| 2677 if (CanDeoptimize()) { | 2676 if (CanDeoptimize()) { |
| 2678 deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptBinarySmiOp); | 2677 deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptBinarySmiOp); |
| 2679 } | 2678 } |
| 2680 | 2679 |
| 2681 if (locs()->in(1).IsConstant()) { | 2680 if (locs()->in(1).IsConstant()) { |
| 2682 const Object& constant = locs()->in(1).constant(); | 2681 const Object& constant = locs()->in(1).constant(); |
| 2683 ASSERT(constant.IsSmi()); | 2682 ASSERT(constant.IsSmi()); |
| (...skipping 2661 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5345 compiler->GenerateCall(token_pos(), &label, stub_kind_, locs()); | 5344 compiler->GenerateCall(token_pos(), &label, stub_kind_, locs()); |
| 5346 #if defined(DEBUG) | 5345 #if defined(DEBUG) |
| 5347 __ LoadImmediate(R4, kInvalidObjectPointer, kNoPP); | 5346 __ LoadImmediate(R4, kInvalidObjectPointer, kNoPP); |
| 5348 __ LoadImmediate(R5, kInvalidObjectPointer, kNoPP); | 5347 __ LoadImmediate(R5, kInvalidObjectPointer, kNoPP); |
| 5349 #endif | 5348 #endif |
| 5350 } | 5349 } |
| 5351 | 5350 |
| 5352 } // namespace dart | 5351 } // namespace dart |
| 5353 | 5352 |
| 5354 #endif // defined TARGET_ARCH_ARM64 | 5353 #endif // defined TARGET_ARCH_ARM64 |
| OLD | NEW |