| 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/compiler.h" | 10 #include "vm/compiler.h" |
| (...skipping 2936 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2947 if (!combined_smi_check) { | 2947 if (!combined_smi_check) { |
| 2948 __ orr(result, left, Operand(right)); | 2948 __ orr(result, left, Operand(right)); |
| 2949 } | 2949 } |
| 2950 break; | 2950 break; |
| 2951 case Token::kBIT_AND: | 2951 case Token::kBIT_AND: |
| 2952 __ and_(result, left, Operand(right)); | 2952 __ and_(result, left, Operand(right)); |
| 2953 break; | 2953 break; |
| 2954 case Token::kBIT_XOR: | 2954 case Token::kBIT_XOR: |
| 2955 __ eor(result, left, Operand(right)); | 2955 __ eor(result, left, Operand(right)); |
| 2956 break; | 2956 break; |
| 2957 case Token::kEQ: | |
| 2958 case Token::kLT: | |
| 2959 case Token::kLTE: | |
| 2960 case Token::kGT: | |
| 2961 case Token::kGTE: { | |
| 2962 Label true_label, false_label, done; | |
| 2963 BranchLabels labels = { &true_label, &false_label, &false_label }; | |
| 2964 Condition true_condition = | |
| 2965 EmitSmiComparisonOp(compiler, locs(), op_kind()); | |
| 2966 EmitBranchOnCondition(compiler, true_condition, labels); | |
| 2967 __ Bind(&false_label); | |
| 2968 __ LoadObject(result, Bool::False()); | |
| 2969 __ b(&done); | |
| 2970 __ Bind(&true_label); | |
| 2971 __ LoadObject(result, Bool::True()); | |
| 2972 __ Bind(&done); | |
| 2973 break; | |
| 2974 } | |
| 2975 default: | 2957 default: |
| 2976 UNIMPLEMENTED(); | 2958 UNIMPLEMENTED(); |
| 2977 } | 2959 } |
| 2978 __ Bind(slow_path->exit_label()); | 2960 __ Bind(slow_path->exit_label()); |
| 2979 } | 2961 } |
| 2980 | 2962 |
| 2981 | 2963 |
| 2964 class CheckedSmiComparisonSlowPath : public SlowPathCode { |
| 2965 public: |
| 2966 CheckedSmiComparisonSlowPath(CheckedSmiComparisonInstr* instruction, |
| 2967 intptr_t try_index, |
| 2968 BranchLabels labels, |
| 2969 bool merged) |
| 2970 : instruction_(instruction), |
| 2971 try_index_(try_index), |
| 2972 labels_(labels), |
| 2973 merged_(merged) { } |
| 2974 |
| 2975 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { |
| 2976 if (Assembler::EmittingComments()) { |
| 2977 __ Comment("slow path smi operation"); |
| 2978 } |
| 2979 __ Bind(entry_label()); |
| 2980 LocationSummary* locs = instruction_->locs(); |
| 2981 Register result = merged_ ? locs->temp(0).reg() : locs->out(0).reg(); |
| 2982 locs->live_registers()->Remove(Location::RegisterLocation(result)); |
| 2983 |
| 2984 compiler->SaveLiveRegisters(locs); |
| 2985 __ Push(locs->in(0).reg()); |
| 2986 __ Push(locs->in(1).reg()); |
| 2987 compiler->EmitMegamorphicInstanceCall( |
| 2988 *instruction_->call()->ic_data(), |
| 2989 instruction_->call()->ArgumentCount(), |
| 2990 instruction_->call()->deopt_id(), |
| 2991 instruction_->call()->token_pos(), |
| 2992 locs, |
| 2993 try_index_, |
| 2994 /* slow_path_argument_count = */ 2); |
| 2995 __ mov(result, R0); |
| 2996 compiler->RestoreLiveRegisters(locs); |
| 2997 if (merged_) { |
| 2998 __ CompareObject(result, Bool::True()); |
| 2999 __ b(instruction_->is_negated() |
| 3000 ? labels_.false_label : labels_.true_label, EQ); |
| 3001 __ b(instruction_->is_negated() |
| 3002 ? labels_.true_label : labels_.false_label); |
| 3003 } else { |
| 3004 __ b(exit_label()); |
| 3005 } |
| 3006 } |
| 3007 |
| 3008 private: |
| 3009 CheckedSmiComparisonInstr* instruction_; |
| 3010 intptr_t try_index_; |
| 3011 BranchLabels labels_; |
| 3012 bool merged_; |
| 3013 }; |
| 3014 |
| 3015 |
| 3016 LocationSummary* CheckedSmiComparisonInstr::MakeLocationSummary( |
| 3017 Zone* zone, bool opt) const { |
| 3018 const intptr_t kNumInputs = 2; |
| 3019 const intptr_t kNumTemps = 1; |
| 3020 LocationSummary* summary = new(zone) LocationSummary( |
| 3021 zone, kNumInputs, kNumTemps, LocationSummary::kCallOnSlowPath); |
| 3022 summary->set_in(0, Location::RequiresRegister()); |
| 3023 summary->set_in(1, Location::RequiresRegister()); |
| 3024 summary->set_temp(0, Location::RequiresRegister()); |
| 3025 summary->set_out(0, Location::RequiresRegister()); |
| 3026 return summary; |
| 3027 } |
| 3028 |
| 3029 |
| 3030 Condition CheckedSmiComparisonInstr::EmitComparisonCode( |
| 3031 FlowGraphCompiler* compiler, BranchLabels labels) { |
| 3032 return EmitSmiComparisonOp(compiler, locs(), kind()); |
| 3033 } |
| 3034 |
| 3035 |
| 3036 #define EMIT_SMI_CHECK \ |
| 3037 Register left = locs()->in(0).reg(); \ |
| 3038 Register right = locs()->in(1).reg(); \ |
| 3039 Register temp = locs()->temp(0).reg(); \ |
| 3040 intptr_t left_cid = this->left()->Type()->ToCid(); \ |
| 3041 intptr_t right_cid = this->right()->Type()->ToCid(); \ |
| 3042 if (this->left()->definition() == this->right()->definition()) { \ |
| 3043 __ tsti(left, Immediate(kSmiTagMask)); \ |
| 3044 } else if (left_cid == kSmiCid) { \ |
| 3045 __ tsti(right, Immediate(kSmiTagMask)); \ |
| 3046 } else if (right_cid == kSmiCid) { \ |
| 3047 __ tsti(left, Immediate(kSmiTagMask)); \ |
| 3048 } else { \ |
| 3049 __ orr(temp, left, Operand(right)); \ |
| 3050 __ tsti(temp, Immediate(kSmiTagMask)); \ |
| 3051 } \ |
| 3052 __ b(slow_path->entry_label(), NE) |
| 3053 |
| 3054 |
| 3055 void CheckedSmiComparisonInstr::EmitBranchCode(FlowGraphCompiler* compiler, |
| 3056 BranchInstr* branch) { |
| 3057 BranchLabels labels = compiler->CreateBranchLabels(branch); |
| 3058 CheckedSmiComparisonSlowPath* slow_path = |
| 3059 new CheckedSmiComparisonSlowPath(this, |
| 3060 compiler->CurrentTryIndex(), |
| 3061 labels, |
| 3062 /* merged = */ true); |
| 3063 compiler->AddSlowPathCode(slow_path); |
| 3064 EMIT_SMI_CHECK; |
| 3065 Condition true_condition = EmitComparisonCode(compiler, labels); |
| 3066 EmitBranchOnCondition(compiler, true_condition, labels); |
| 3067 __ Bind(slow_path->exit_label()); |
| 3068 } |
| 3069 |
| 3070 |
| 3071 void CheckedSmiComparisonInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3072 Label true_label, false_label, done; |
| 3073 BranchLabels labels = { &true_label, &false_label, &false_label }; |
| 3074 CheckedSmiComparisonSlowPath* slow_path = |
| 3075 new CheckedSmiComparisonSlowPath(this, |
| 3076 compiler->CurrentTryIndex(), |
| 3077 labels, |
| 3078 /* merged = */ false); |
| 3079 compiler->AddSlowPathCode(slow_path); |
| 3080 EMIT_SMI_CHECK; |
| 3081 Condition true_condition = |
| 3082 EmitComparisonCode(compiler, labels); |
| 3083 EmitBranchOnCondition(compiler, true_condition, labels); |
| 3084 Register result = locs()->out(0).reg(); |
| 3085 __ Bind(&false_label); |
| 3086 __ LoadObject(result, Bool::False()); |
| 3087 __ b(&done); |
| 3088 __ Bind(&true_label); |
| 3089 __ LoadObject(result, Bool::True()); |
| 3090 __ Bind(&done); |
| 3091 __ Bind(slow_path->exit_label()); |
| 3092 } |
| 3093 |
| 3094 |
| 2982 LocationSummary* BinarySmiOpInstr::MakeLocationSummary(Zone* zone, | 3095 LocationSummary* BinarySmiOpInstr::MakeLocationSummary(Zone* zone, |
| 2983 bool opt) const { | 3096 bool opt) const { |
| 2984 const intptr_t kNumInputs = 2; | 3097 const intptr_t kNumInputs = 2; |
| 2985 const intptr_t kNumTemps = | 3098 const intptr_t kNumTemps = |
| 2986 (((op_kind() == Token::kSHL) && can_overflow()) || | 3099 (((op_kind() == Token::kSHL) && can_overflow()) || |
| 2987 (op_kind() == Token::kSHR)) ? 1 : 0; | 3100 (op_kind() == Token::kSHR)) ? 1 : 0; |
| 2988 LocationSummary* summary = new(zone) LocationSummary( | 3101 LocationSummary* summary = new(zone) LocationSummary( |
| 2989 zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3102 zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 2990 if (op_kind() == Token::kTRUNCDIV) { | 3103 if (op_kind() == Token::kTRUNCDIV) { |
| 2991 summary->set_in(0, Location::RequiresRegister()); | 3104 summary->set_in(0, Location::RequiresRegister()); |
| (...skipping 2926 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5918 1, | 6031 1, |
| 5919 locs()); | 6032 locs()); |
| 5920 __ Drop(1); | 6033 __ Drop(1); |
| 5921 __ Pop(result); | 6034 __ Pop(result); |
| 5922 } | 6035 } |
| 5923 | 6036 |
| 5924 | 6037 |
| 5925 } // namespace dart | 6038 } // namespace dart |
| 5926 | 6039 |
| 5927 #endif // defined TARGET_ARCH_ARM64 | 6040 #endif // defined TARGET_ARCH_ARM64 |
| OLD | NEW |