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 2775 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2786 __ shlq(left, right); | 2786 __ shlq(left, right); |
2787 __ sarq(left, right); | 2787 __ sarq(left, right); |
2788 __ cmpq(left, temp); | 2788 __ cmpq(left, temp); |
2789 __ j(NOT_EQUAL, deopt); // Overflow. | 2789 __ j(NOT_EQUAL, deopt); // Overflow. |
2790 // Shift for result now we know there is no overflow. | 2790 // Shift for result now we know there is no overflow. |
2791 __ shlq(left, right); | 2791 __ shlq(left, right); |
2792 } | 2792 } |
2793 } | 2793 } |
2794 | 2794 |
2795 | 2795 |
2796 class CheckedSmiSlowPath : public SlowPathCode { | |
2797 public: | |
2798 CheckedSmiSlowPath(CheckedSmiOpInstr* instruction, intptr_t try_index) | |
2799 : instruction_(instruction), try_index_(try_index) { } | |
2800 | |
2801 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { | |
2802 if (Assembler::EmittingComments()) { | |
2803 __ Comment("slow path smi operation"); | |
2804 } | |
2805 __ Bind(entry_label()); | |
2806 LocationSummary* locs = instruction_->locs(); | |
2807 Register result = locs->out(0).reg(); | |
2808 locs->live_registers()->Remove(Location::RegisterLocation(result)); | |
2809 | |
2810 compiler->SaveLiveRegisters(locs); | |
2811 __ pushq(locs->in(0).reg()); | |
2812 __ pushq(locs->in(1).reg()); | |
2813 compiler->EmitMegamorphicInstanceCall( | |
2814 *instruction_->call()->ic_data(), | |
2815 instruction_->call()->ArgumentCount(), | |
2816 instruction_->call()->deopt_id(), | |
2817 instruction_->call()->token_pos(), | |
2818 locs, | |
2819 try_index_, | |
2820 /* slow_path_argument_count = */ 2); | |
2821 __ MoveRegister(result, RAX); | |
2822 compiler->RestoreLiveRegisters(locs); | |
2823 __ jmp(exit_label()); | |
2824 } | |
2825 | |
2826 private: | |
2827 CheckedSmiOpInstr* instruction_; | |
2828 intptr_t try_index_; | |
2829 }; | |
2830 | |
2831 | |
2832 LocationSummary* CheckedSmiOpInstr::MakeLocationSummary(Zone* zone, | |
2833 bool opt) const { | |
2834 const intptr_t kNumInputs = 2; | |
2835 const intptr_t kNumTemps = 0; | |
2836 LocationSummary* summary = new(zone) LocationSummary( | |
2837 zone, kNumInputs, kNumTemps, LocationSummary::kCallOnSlowPath); | |
2838 summary->set_in(0, Location::RequiresRegister()); | |
2839 summary->set_in(1, Location::RequiresRegister()); | |
2840 switch (op_kind()) { | |
2841 case Token::kADD: | |
2842 case Token::kSUB: | |
2843 summary->set_out(0, Location::RequiresRegister()); | |
2844 break; | |
2845 case Token::kBIT_OR: | |
2846 case Token::kBIT_AND: | |
2847 case Token::kBIT_XOR: | |
2848 summary->set_out(0, Location::SameAsFirstInput()); | |
2849 break; | |
2850 default: | |
2851 UNIMPLEMENTED(); | |
2852 } | |
2853 return summary; | |
2854 } | |
2855 | |
2856 | |
2857 void CheckedSmiOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | |
2858 CheckedSmiSlowPath* slow_path = | |
2859 new CheckedSmiSlowPath(this, compiler->CurrentTryIndex()); | |
2860 compiler->AddSlowPathCode(slow_path); | |
2861 // Test operands if necessary. | |
2862 Register left = locs()->in(0).reg(); | |
2863 Register right = locs()->in(1).reg(); | |
2864 Register result = locs()->out(0).reg(); | |
2865 __ testq(left, Immediate(kSmiTagMask)); | |
Vyacheslav Egorov (Google)
2016/03/04 13:30:36
__ movq(TMP, left);
__ orq(TMP, right);
__ testq(T
Florian Schneider
2016/03/04 16:55:10
Done.
| |
2866 __ j(NOT_ZERO, slow_path->entry_label()); | |
2867 __ testq(right, Immediate(kSmiTagMask)); | |
2868 __ j(NOT_ZERO, slow_path->entry_label()); | |
2869 switch (op_kind()) { | |
2870 case Token::kADD: | |
2871 __ movq(result, left); | |
2872 __ addq(result, right); | |
2873 __ j(OVERFLOW, slow_path->entry_label()); | |
2874 break; | |
2875 case Token::kSUB: | |
2876 __ movq(result, left); | |
2877 __ subq(result, right); | |
2878 __ j(OVERFLOW, slow_path->entry_label()); | |
2879 break; | |
2880 case Token::kBIT_OR: | |
2881 ASSERT(left == result); | |
2882 __ orq(result, right); | |
2883 break; | |
2884 case Token::kBIT_AND: | |
2885 ASSERT(left == result); | |
2886 __ andq(result, right); | |
2887 break; | |
2888 case Token::kBIT_XOR: | |
2889 ASSERT(left == result); | |
2890 __ xorq(result, right); | |
2891 break; | |
2892 default: | |
2893 UNIMPLEMENTED(); | |
2894 } | |
2895 __ Bind(slow_path->exit_label()); | |
2896 } | |
2897 | |
2898 | |
2796 static bool CanBeImmediate(const Object& constant) { | 2899 static bool CanBeImmediate(const Object& constant) { |
2797 return constant.IsSmi() && | 2900 return constant.IsSmi() && |
2798 Immediate(reinterpret_cast<int64_t>(constant.raw())).is_int32(); | 2901 Immediate(reinterpret_cast<int64_t>(constant.raw())).is_int32(); |
2799 } | 2902 } |
2800 | 2903 |
2801 | 2904 |
2802 LocationSummary* BinarySmiOpInstr::MakeLocationSummary(Zone* zone, | 2905 LocationSummary* BinarySmiOpInstr::MakeLocationSummary(Zone* zone, |
2803 bool opt) const { | 2906 bool opt) const { |
2804 const intptr_t kNumInputs = 2; | 2907 const intptr_t kNumInputs = 2; |
2805 | 2908 |
(...skipping 3591 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6397 __ Drop(1); | 6500 __ Drop(1); |
6398 __ popq(result); | 6501 __ popq(result); |
6399 } | 6502 } |
6400 | 6503 |
6401 | 6504 |
6402 } // namespace dart | 6505 } // namespace dart |
6403 | 6506 |
6404 #undef __ | 6507 #undef __ |
6405 | 6508 |
6406 #endif // defined TARGET_ARCH_X64 | 6509 #endif // defined TARGET_ARCH_X64 |
OLD | NEW |