| 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/dart_entry.h" | 10 #include "vm/dart_entry.h" |
| (...skipping 4210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4221 // if (base == 1.0) return 1.0; | 4221 // if (base == 1.0) return 1.0; |
| 4222 // if (base.isNaN || exponent.isNaN) { | 4222 // if (base.isNaN || exponent.isNaN) { |
| 4223 // return double.NAN; | 4223 // return double.NAN; |
| 4224 // } | 4224 // } |
| 4225 XmmRegister base = locs()->in(0).fpu_reg(); | 4225 XmmRegister base = locs()->in(0).fpu_reg(); |
| 4226 XmmRegister exp = locs()->in(1).fpu_reg(); | 4226 XmmRegister exp = locs()->in(1).fpu_reg(); |
| 4227 XmmRegister result = locs()->out().fpu_reg(); | 4227 XmmRegister result = locs()->out().fpu_reg(); |
| 4228 Register temp = locs()->temp(0).reg(); | 4228 Register temp = locs()->temp(0).reg(); |
| 4229 XmmRegister zero_temp = locs()->temp(1).fpu_reg(); | 4229 XmmRegister zero_temp = locs()->temp(1).fpu_reg(); |
| 4230 | 4230 |
| 4231 Label check_base_is_one; | |
| 4232 // Check if exponent is 0.0 -> return 1.0; | 4231 // Check if exponent is 0.0 -> return 1.0; |
| 4233 __ LoadObject(temp, Double::ZoneHandle(Double::NewCanonical(0)), PP); | 4232 __ LoadObject(temp, Double::ZoneHandle(Double::NewCanonical(0)), PP); |
| 4234 __ movsd(zero_temp, FieldAddress(temp, Double::value_offset())); | 4233 __ movsd(zero_temp, FieldAddress(temp, Double::value_offset())); |
| 4235 __ LoadObject(temp, Double::ZoneHandle(Double::NewCanonical(1)), PP); | 4234 __ LoadObject(temp, Double::ZoneHandle(Double::NewCanonical(1)), PP); |
| 4236 __ movsd(result, FieldAddress(temp, Double::value_offset())); | 4235 __ movsd(result, FieldAddress(temp, Double::value_offset())); |
| 4237 // 'result' contains 1.0. | 4236 // 'result' contains 1.0. |
| 4237 Label exp_is_nan; |
| 4238 __ comisd(exp, zero_temp); | 4238 __ comisd(exp, zero_temp); |
| 4239 __ j(PARITY_EVEN, &check_base_is_one, Assembler::kNearJump); // NaN. | 4239 __ j(PARITY_EVEN, &exp_is_nan, Assembler::kNearJump); // NaN. |
| 4240 __ j(EQUAL, &skip_call, Assembler::kNearJump); // exp is 0, result is 1.0. | 4240 __ j(EQUAL, &skip_call, Assembler::kNearJump); // exp is 0, result is 1.0. |
| 4241 | 4241 |
| 4242 Label base_is_nan; | 4242 Label base_is_nan; |
| 4243 __ Bind(&check_base_is_one); | |
| 4244 // Checks if base == 1.0. | 4243 // Checks if base == 1.0. |
| 4245 __ comisd(base, result); | 4244 __ comisd(base, result); |
| 4246 __ j(PARITY_EVEN, &base_is_nan, Assembler::kNearJump); | 4245 __ j(PARITY_EVEN, &base_is_nan, Assembler::kNearJump); |
| 4247 __ j(EQUAL, &skip_call, Assembler::kNearJump); // base and result are 1.0 | 4246 __ j(EQUAL, &skip_call, Assembler::kNearJump); // base and result are 1.0 |
| 4248 __ jmp(&do_call, Assembler::kNearJump); | 4247 __ jmp(&do_call, Assembler::kNearJump); |
| 4249 | 4248 |
| 4250 __ Bind(&base_is_nan); | 4249 __ Bind(&base_is_nan); |
| 4251 // Returns NaN. | 4250 // Returns NaN. |
| 4252 __ movsd(result, base); | 4251 __ movsd(result, base); |
| 4253 __ jmp(&skip_call, Assembler::kNearJump); | 4252 __ jmp(&skip_call, Assembler::kNearJump); |
| 4254 // exp is Nan case is handled correctly in the C-library. | 4253 |
| 4254 __ Bind(&exp_is_nan); |
| 4255 // Checks if base == 1.0. |
| 4256 __ comisd(base, result); |
| 4257 __ j(PARITY_EVEN, &base_is_nan, Assembler::kNearJump); |
| 4258 __ j(EQUAL, &skip_call, Assembler::kNearJump); // base and result are 1.0 |
| 4259 __ movsd(result, exp); // result is NaN |
| 4260 __ jmp(&skip_call, Assembler::kNearJump); |
| 4255 } | 4261 } |
| 4256 __ Bind(&do_call); | 4262 __ Bind(&do_call); |
| 4257 __ CallRuntime(TargetFunction(), InputCount()); | 4263 __ CallRuntime(TargetFunction(), InputCount()); |
| 4258 __ movaps(locs()->out().fpu_reg(), XMM0); | 4264 __ movaps(locs()->out().fpu_reg(), XMM0); |
| 4259 __ Bind(&skip_call); | 4265 __ Bind(&skip_call); |
| 4260 __ leave(); | 4266 __ leave(); |
| 4261 } | 4267 } |
| 4262 | 4268 |
| 4263 | 4269 |
| 4264 LocationSummary* PolymorphicInstanceCallInstr::MakeLocationSummary() const { | 4270 LocationSummary* PolymorphicInstanceCallInstr::MakeLocationSummary() const { |
| (...skipping 571 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4836 PcDescriptors::kOther, | 4842 PcDescriptors::kOther, |
| 4837 locs()); | 4843 locs()); |
| 4838 __ Drop(2); // Discard type arguments and receiver. | 4844 __ Drop(2); // Discard type arguments and receiver. |
| 4839 } | 4845 } |
| 4840 | 4846 |
| 4841 } // namespace dart | 4847 } // namespace dart |
| 4842 | 4848 |
| 4843 #undef __ | 4849 #undef __ |
| 4844 | 4850 |
| 4845 #endif // defined TARGET_ARCH_X64 | 4851 #endif // defined TARGET_ARCH_X64 |
| OLD | NEW |