| 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 "lib/error.h" | 10 #include "lib/error.h" |
| (...skipping 3075 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3086 | 3086 |
| 3087 | 3087 |
| 3088 LocationSummary* MathMinMaxInstr::MakeLocationSummary() const { | 3088 LocationSummary* MathMinMaxInstr::MakeLocationSummary() const { |
| 3089 if (result_cid() == kDoubleCid) { | 3089 if (result_cid() == kDoubleCid) { |
| 3090 const intptr_t kNumInputs = 2; | 3090 const intptr_t kNumInputs = 2; |
| 3091 const intptr_t kNumTemps = 1; | 3091 const intptr_t kNumTemps = 1; |
| 3092 LocationSummary* summary = | 3092 LocationSummary* summary = |
| 3093 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3093 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 3094 summary->set_in(0, Location::RequiresFpuRegister()); | 3094 summary->set_in(0, Location::RequiresFpuRegister()); |
| 3095 summary->set_in(1, Location::RequiresFpuRegister()); | 3095 summary->set_in(1, Location::RequiresFpuRegister()); |
| 3096 summary->set_out(Location::RequiresFpuRegister()); | 3096 // Reuse the left register so that code can be made shorter. |
| 3097 summary->set_out(Location::SameAsFirstInput()); |
| 3097 summary->set_temp(0, Location::RequiresRegister()); | 3098 summary->set_temp(0, Location::RequiresRegister()); |
| 3098 return summary; | 3099 return summary; |
| 3099 } | 3100 } |
| 3100 ASSERT(result_cid() == kSmiCid); | 3101 ASSERT(result_cid() == kSmiCid); |
| 3101 UNIMPLEMENTED(); | 3102 const intptr_t kNumInputs = 2; |
| 3102 return NULL; | 3103 const intptr_t kNumTemps = 0; |
| 3104 LocationSummary* summary = |
| 3105 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 3106 summary->set_in(0, Location::RequiresRegister()); |
| 3107 summary->set_in(1, Location::RequiresRegister()); |
| 3108 // Reuse the left register so that code can be made shorter. |
| 3109 summary->set_out(Location::SameAsFirstInput()); |
| 3110 return summary; |
| 3103 } | 3111 } |
| 3104 | 3112 |
| 3105 | 3113 |
| 3106 void MathMinMaxInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3114 void MathMinMaxInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3107 ASSERT((op_kind() == MethodRecognizer::kMathMin) || | 3115 ASSERT((op_kind() == MethodRecognizer::kMathMin) || |
| 3108 (op_kind() == MethodRecognizer::kMathMax)); | 3116 (op_kind() == MethodRecognizer::kMathMax)); |
| 3117 const intptr_t is_min = (op_kind() == MethodRecognizer::kMathMin); |
| 3109 if (result_cid() == kDoubleCid) { | 3118 if (result_cid() == kDoubleCid) { |
| 3110 Label done, returns_nan, returns_left, are_equal; | 3119 Label done, returns_nan, are_equal; |
| 3111 DRegister left = locs()->in(0).fpu_reg(); | 3120 DRegister left = locs()->in(0).fpu_reg(); |
| 3112 DRegister right = locs()->in(1).fpu_reg(); | 3121 DRegister right = locs()->in(1).fpu_reg(); |
| 3113 DRegister result = locs()->out().fpu_reg(); | 3122 DRegister result = locs()->out().fpu_reg(); |
| 3114 Register temp = locs()->temp(0).reg(); | 3123 Register temp = locs()->temp(0).reg(); |
| 3115 __ cund(left, right); | 3124 __ cund(left, right); |
| 3116 __ bc1t(&returns_nan); | 3125 __ bc1t(&returns_nan); |
| 3117 __ ceqd(left, right); | 3126 __ ceqd(left, right); |
| 3118 __ bc1t(&are_equal); | 3127 __ bc1t(&are_equal); |
| 3119 const intptr_t is_min = (op_kind() == MethodRecognizer::kMathMin); | |
| 3120 if (is_min) { | 3128 if (is_min) { |
| 3121 __ coltd(left, right); | 3129 __ coltd(left, right); |
| 3122 } else { | 3130 } else { |
| 3123 __ coltd(right, left); | 3131 __ coltd(right, left); |
| 3124 } | 3132 } |
| 3125 // TODO(zra): Add conditional moves. | 3133 // TODO(zra): Add conditional moves. |
| 3126 __ bc1t(&returns_left); | 3134 ASSERT(left == result); |
| 3135 __ bc1t(&done); |
| 3127 __ movd(result, right); | 3136 __ movd(result, right); |
| 3128 __ b(&done); | 3137 __ b(&done); |
| 3129 | 3138 |
| 3130 __ Bind(&returns_left); | |
| 3131 __ movd(result, left); | |
| 3132 __ b(&done); | |
| 3133 | |
| 3134 __ Bind(&returns_nan); | 3139 __ Bind(&returns_nan); |
| 3135 __ LoadImmediate(result, NAN); | 3140 __ LoadImmediate(result, NAN); |
| 3136 __ b(&done); | 3141 __ b(&done); |
| 3137 | 3142 |
| 3138 __ Bind(&are_equal); | 3143 __ Bind(&are_equal); |
| 3139 Label left_is_negative; | 3144 Label left_is_negative; |
| 3140 // Check for negative zero: -0.0 is equal 0.0 but min or max must return | 3145 // Check for negative zero: -0.0 is equal 0.0 but min or max must return |
| 3141 // -0.0 or 0.0 respectively. | 3146 // -0.0 or 0.0 respectively. |
| 3142 // Check for negative left value (get the sign bit): | 3147 // Check for negative left value (get the sign bit): |
| 3143 // - min -> left is negative ? left : right. | 3148 // - min -> left is negative ? left : right. |
| 3144 // - max -> left is negative ? right : left | 3149 // - max -> left is negative ? right : left |
| 3145 // Check the sign bit. | 3150 // Check the sign bit. |
| 3146 __ mfc1(temp, OddFRegisterOf(left)); // Moves bits 32...63 of left to temp. | 3151 __ mfc1(temp, OddFRegisterOf(left)); // Moves bits 32...63 of left to temp. |
| 3147 __ bltz(temp, &left_is_negative); | 3152 if (is_min) { |
| 3148 // Left is positive. | 3153 ASSERT(left == result); |
| 3149 __ movd(result, (is_min ? right : left)); | 3154 __ bltz(temp, &done); // Left is negative. |
| 3150 __ b(&done); | 3155 } else { |
| 3151 | 3156 __ bgez(temp, &done); // Left is positive. |
| 3152 __ Bind(&left_is_negative); | 3157 } |
| 3153 __ movd(result, (is_min ? left : right)); | 3158 __ movd(result, right); |
| 3154 __ Bind(&done); | 3159 __ Bind(&done); |
| 3155 return; | 3160 return; |
| 3156 } | 3161 } |
| 3162 |
| 3163 Label done; |
| 3157 ASSERT(result_cid() == kSmiCid); | 3164 ASSERT(result_cid() == kSmiCid); |
| 3158 UNIMPLEMENTED(); | 3165 Register left = locs()->in(0).reg(); |
| 3166 Register right = locs()->in(1).reg(); |
| 3167 Register result = locs()->out().reg(); |
| 3168 ASSERT(result == left); |
| 3169 if (is_min) { |
| 3170 __ BranchSignedLessEqual(left, right, &done); |
| 3171 } else { |
| 3172 __ BranchSignedGreaterEqual(left, right, &done); |
| 3173 } |
| 3174 __ mov(result, right); |
| 3175 __ Bind(&done); |
| 3159 } | 3176 } |
| 3160 | 3177 |
| 3161 | 3178 |
| 3162 LocationSummary* UnarySmiOpInstr::MakeLocationSummary() const { | 3179 LocationSummary* UnarySmiOpInstr::MakeLocationSummary() const { |
| 3163 const intptr_t kNumInputs = 1; | 3180 const intptr_t kNumInputs = 1; |
| 3164 const intptr_t kNumTemps = 0; | 3181 const intptr_t kNumTemps = 0; |
| 3165 LocationSummary* summary = | 3182 LocationSummary* summary = |
| 3166 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3183 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 3167 summary->set_in(0, Location::RequiresRegister()); | 3184 summary->set_in(0, Location::RequiresRegister()); |
| 3168 // We make use of 3-operand instructions by not requiring result register | 3185 // We make use of 3-operand instructions by not requiring result register |
| (...skipping 678 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3847 compiler->GenerateCall(token_pos(), | 3864 compiler->GenerateCall(token_pos(), |
| 3848 &label, | 3865 &label, |
| 3849 PcDescriptors::kOther, | 3866 PcDescriptors::kOther, |
| 3850 locs()); | 3867 locs()); |
| 3851 __ Drop(2); // Discard type arguments and receiver. | 3868 __ Drop(2); // Discard type arguments and receiver. |
| 3852 } | 3869 } |
| 3853 | 3870 |
| 3854 } // namespace dart | 3871 } // namespace dart |
| 3855 | 3872 |
| 3856 #endif // defined TARGET_ARCH_MIPS | 3873 #endif // defined TARGET_ARCH_MIPS |
| OLD | NEW |