| 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_MIPS. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_MIPS. |
| 6 #if defined(TARGET_ARCH_MIPS) | 6 #if defined(TARGET_ARCH_MIPS) |
| 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 3045 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3056 if (!combined_smi_check) { | 3056 if (!combined_smi_check) { |
| 3057 __ or_(result, left, right); | 3057 __ or_(result, left, right); |
| 3058 } | 3058 } |
| 3059 break; | 3059 break; |
| 3060 case Token::kBIT_AND: | 3060 case Token::kBIT_AND: |
| 3061 __ and_(result, left, right); | 3061 __ and_(result, left, right); |
| 3062 break; | 3062 break; |
| 3063 case Token::kBIT_XOR: | 3063 case Token::kBIT_XOR: |
| 3064 __ xor_(result, left, right); | 3064 __ xor_(result, left, right); |
| 3065 break; | 3065 break; |
| 3066 case Token::kEQ: | |
| 3067 case Token::kLT: | |
| 3068 case Token::kLTE: | |
| 3069 case Token::kGT: | |
| 3070 case Token::kGTE: { | |
| 3071 Label true_label, false_label, done; | |
| 3072 BranchLabels labels = { &true_label, &false_label, &false_label }; | |
| 3073 Condition true_condition = | |
| 3074 EmitSmiComparisonOp(compiler, *locs(), op_kind()); | |
| 3075 EmitBranchOnCondition(compiler, true_condition, labels); | |
| 3076 __ Bind(&false_label); | |
| 3077 __ LoadObject(result, Bool::False()); | |
| 3078 __ b(&done); | |
| 3079 __ Bind(&true_label); | |
| 3080 __ LoadObject(result, Bool::True()); | |
| 3081 __ Bind(&done); | |
| 3082 break; | |
| 3083 } | |
| 3084 default: | 3066 default: |
| 3085 UNIMPLEMENTED(); | 3067 UNIMPLEMENTED(); |
| 3086 } | 3068 } |
| 3087 __ Bind(slow_path->exit_label()); | 3069 __ Bind(slow_path->exit_label()); |
| 3088 } | 3070 } |
| 3089 | 3071 |
| 3090 | 3072 |
| 3073 class CheckedSmiComparisonSlowPath : public SlowPathCode { |
| 3074 public: |
| 3075 CheckedSmiComparisonSlowPath(CheckedSmiComparisonInstr* instruction, |
| 3076 intptr_t try_index, |
| 3077 BranchLabels labels, |
| 3078 bool merged) |
| 3079 : instruction_(instruction), |
| 3080 try_index_(try_index), |
| 3081 labels_(labels), |
| 3082 merged_(merged) { } |
| 3083 |
| 3084 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3085 if (Assembler::EmittingComments()) { |
| 3086 __ Comment("slow path smi operation"); |
| 3087 } |
| 3088 __ Bind(entry_label()); |
| 3089 LocationSummary* locs = instruction_->locs(); |
| 3090 Register result = merged_ ? locs->temp(0).reg() : locs->out(0).reg(); |
| 3091 locs->live_registers()->Remove(Location::RegisterLocation(result)); |
| 3092 |
| 3093 compiler->SaveLiveRegisters(locs); |
| 3094 __ Push(locs->in(0).reg()); |
| 3095 __ Push(locs->in(1).reg()); |
| 3096 compiler->EmitMegamorphicInstanceCall( |
| 3097 *instruction_->call()->ic_data(), |
| 3098 instruction_->call()->ArgumentCount(), |
| 3099 instruction_->call()->deopt_id(), |
| 3100 instruction_->call()->token_pos(), |
| 3101 locs, |
| 3102 try_index_, |
| 3103 /* slow_path_argument_count = */ 2); |
| 3104 __ mov(result, V0); |
| 3105 compiler->RestoreLiveRegisters(locs); |
| 3106 if (merged_) { |
| 3107 __ BranchEqual(result, Bool::True(), |
| 3108 instruction_->is_negated() ? labels_.false_label : labels_.true_label); |
| 3109 __ b(instruction_->is_negated() |
| 3110 ? labels_.true_label : labels_.false_label); |
| 3111 } else { |
| 3112 __ b(exit_label()); |
| 3113 } |
| 3114 } |
| 3115 |
| 3116 private: |
| 3117 CheckedSmiComparisonInstr* instruction_; |
| 3118 intptr_t try_index_; |
| 3119 BranchLabels labels_; |
| 3120 bool merged_; |
| 3121 }; |
| 3122 |
| 3123 |
| 3124 LocationSummary* CheckedSmiComparisonInstr::MakeLocationSummary( |
| 3125 Zone* zone, bool opt) const { |
| 3126 const intptr_t kNumInputs = 2; |
| 3127 const intptr_t kNumTemps = 1; |
| 3128 LocationSummary* summary = new(zone) LocationSummary( |
| 3129 zone, kNumInputs, kNumTemps, LocationSummary::kCallOnSlowPath); |
| 3130 summary->set_in(0, Location::RequiresRegister()); |
| 3131 summary->set_in(1, Location::RequiresRegister()); |
| 3132 summary->set_temp(0, Location::RequiresRegister()); |
| 3133 summary->set_out(0, Location::RequiresRegister()); |
| 3134 return summary; |
| 3135 } |
| 3136 |
| 3137 |
| 3138 Condition CheckedSmiComparisonInstr::EmitComparisonCode( |
| 3139 FlowGraphCompiler* compiler, BranchLabels labels) { |
| 3140 return EmitSmiComparisonOp(compiler, *locs(), kind()); |
| 3141 } |
| 3142 |
| 3143 |
| 3144 #define EMIT_SMI_CHECK \ |
| 3145 Register left = locs()->in(0).reg(); \ |
| 3146 Register right = locs()->in(1).reg(); \ |
| 3147 Register temp = locs()->temp(0).reg(); \ |
| 3148 intptr_t left_cid = this->left()->Type()->ToCid(); \ |
| 3149 intptr_t right_cid = this->right()->Type()->ToCid(); \ |
| 3150 if (this->left()->definition() == this->right()->definition()) { \ |
| 3151 __ andi(CMPRES1, left, Immediate(kSmiTagMask)); \ |
| 3152 } else if (left_cid == kSmiCid) { \ |
| 3153 __ andi(CMPRES1, right, Immediate(kSmiTagMask)); \ |
| 3154 } else if (right_cid == kSmiCid) { \ |
| 3155 __ andi(CMPRES1, left, Immediate(kSmiTagMask)); \ |
| 3156 } else { \ |
| 3157 __ or_(temp, left, right); \ |
| 3158 __ andi(CMPRES1, temp, Immediate(kSmiTagMask)); \ |
| 3159 } \ |
| 3160 __ bne(CMPRES1, ZR, slow_path->entry_label()); \ |
| 3161 |
| 3162 |
| 3163 void CheckedSmiComparisonInstr::EmitBranchCode(FlowGraphCompiler* compiler, |
| 3164 BranchInstr* branch) { |
| 3165 BranchLabels labels = compiler->CreateBranchLabels(branch); |
| 3166 CheckedSmiComparisonSlowPath* slow_path = |
| 3167 new CheckedSmiComparisonSlowPath(this, |
| 3168 compiler->CurrentTryIndex(), |
| 3169 labels, |
| 3170 /* merged = */ true); |
| 3171 compiler->AddSlowPathCode(slow_path); |
| 3172 EMIT_SMI_CHECK; |
| 3173 Condition true_condition = EmitComparisonCode(compiler, labels); |
| 3174 EmitBranchOnCondition(compiler, true_condition, labels); |
| 3175 __ Bind(slow_path->exit_label()); |
| 3176 } |
| 3177 |
| 3178 |
| 3179 void CheckedSmiComparisonInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3180 Label true_label, false_label, done; |
| 3181 BranchLabels labels = { &true_label, &false_label, &false_label }; |
| 3182 CheckedSmiComparisonSlowPath* slow_path = |
| 3183 new CheckedSmiComparisonSlowPath(this, |
| 3184 compiler->CurrentTryIndex(), |
| 3185 labels, |
| 3186 /* merged = */ false); |
| 3187 compiler->AddSlowPathCode(slow_path); |
| 3188 EMIT_SMI_CHECK; |
| 3189 Condition true_condition = EmitComparisonCode(compiler, labels); |
| 3190 EmitBranchOnCondition(compiler, true_condition, labels); |
| 3191 Register result = locs()->out(0).reg(); |
| 3192 __ Bind(&false_label); |
| 3193 __ LoadObject(result, Bool::False()); |
| 3194 __ b(&done); |
| 3195 __ Bind(&true_label); |
| 3196 __ LoadObject(result, Bool::True()); |
| 3197 __ Bind(&done); |
| 3198 __ Bind(slow_path->exit_label()); |
| 3199 } |
| 3200 |
| 3201 |
| 3091 LocationSummary* BinarySmiOpInstr::MakeLocationSummary(Zone* zone, | 3202 LocationSummary* BinarySmiOpInstr::MakeLocationSummary(Zone* zone, |
| 3092 bool opt) const { | 3203 bool opt) const { |
| 3093 const intptr_t kNumInputs = 2; | 3204 const intptr_t kNumInputs = 2; |
| 3094 const intptr_t kNumTemps = | 3205 const intptr_t kNumTemps = |
| 3095 ((op_kind() == Token::kADD) || | 3206 ((op_kind() == Token::kADD) || |
| 3096 (op_kind() == Token::kMOD) || | 3207 (op_kind() == Token::kMOD) || |
| 3097 (op_kind() == Token::kTRUNCDIV) || | 3208 (op_kind() == Token::kTRUNCDIV) || |
| 3098 (((op_kind() == Token::kSHL) && can_overflow()) || | 3209 (((op_kind() == Token::kSHL) && can_overflow()) || |
| 3099 (op_kind() == Token::kSHR))) ? 1 : 0; | 3210 (op_kind() == Token::kSHR))) ? 1 : 0; |
| 3100 LocationSummary* summary = new(zone) LocationSummary( | 3211 LocationSummary* summary = new(zone) LocationSummary( |
| (...skipping 2841 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5942 1, | 6053 1, |
| 5943 locs()); | 6054 locs()); |
| 5944 __ lw(result, Address(SP, 1 * kWordSize)); | 6055 __ lw(result, Address(SP, 1 * kWordSize)); |
| 5945 __ addiu(SP, SP, Immediate(2 * kWordSize)); | 6056 __ addiu(SP, SP, Immediate(2 * kWordSize)); |
| 5946 } | 6057 } |
| 5947 | 6058 |
| 5948 | 6059 |
| 5949 } // namespace dart | 6060 } // namespace dart |
| 5950 | 6061 |
| 5951 #endif // defined TARGET_ARCH_MIPS | 6062 #endif // defined TARGET_ARCH_MIPS |
| OLD | NEW |