| 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_IA32. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_IA32. |
| 6 #if defined(TARGET_ARCH_IA32) | 6 #if defined(TARGET_ARCH_IA32) |
| 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 4760 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4771 // if (base != -Infinity && exponent == 0.5) { | 4771 // if (base != -Infinity && exponent == 0.5) { |
| 4772 // if (base == 0.0) return 0.0; | 4772 // if (base == 0.0) return 0.0; |
| 4773 // return sqrt(value); | 4773 // return sqrt(value); |
| 4774 // } | 4774 // } |
| 4775 XmmRegister base = locs()->in(0).fpu_reg(); | 4775 XmmRegister base = locs()->in(0).fpu_reg(); |
| 4776 XmmRegister exp = locs()->in(1).fpu_reg(); | 4776 XmmRegister exp = locs()->in(1).fpu_reg(); |
| 4777 XmmRegister result = locs()->out(0).fpu_reg(); | 4777 XmmRegister result = locs()->out(0).fpu_reg(); |
| 4778 Register temp = locs()->temp(kObjectTempIndex).reg(); | 4778 Register temp = locs()->temp(kObjectTempIndex).reg(); |
| 4779 XmmRegister zero_temp = locs()->temp(kDoubleTempIndex).fpu_reg(); | 4779 XmmRegister zero_temp = locs()->temp(kDoubleTempIndex).fpu_reg(); |
| 4780 | 4780 |
| 4781 Label do_call, check_base, return_nan; | 4781 Label try_sqrt, check_base, return_nan; |
| 4782 __ LoadObject(temp, Double::ZoneHandle(Double::NewCanonical(0))); | 4782 __ LoadObject(temp, Double::ZoneHandle(Double::NewCanonical(0))); |
| 4783 __ movsd(zero_temp, FieldAddress(temp, Double::value_offset())); | 4783 __ movsd(zero_temp, FieldAddress(temp, Double::value_offset())); |
| 4784 __ LoadObject(temp, Double::ZoneHandle(Double::NewCanonical(1))); | 4784 __ LoadObject(temp, Double::ZoneHandle(Double::NewCanonical(1))); |
| 4785 __ movsd(result, FieldAddress(temp, Double::value_offset())); | 4785 __ movsd(result, FieldAddress(temp, Double::value_offset())); |
| 4786 | 4786 |
| 4787 // exponent == 0.0 -> return 1.0; | 4787 // exponent == 0.0 -> return 1.0; |
| 4788 __ comisd(exp, zero_temp); | 4788 __ comisd(exp, zero_temp); |
| 4789 __ j(PARITY_EVEN, &check_base, Assembler::kNearJump); | 4789 __ j(PARITY_EVEN, &check_base, Assembler::kNearJump); |
| 4790 __ j(EQUAL, &skip_call, Assembler::kNearJump); // 'result' is 1.0. | 4790 __ j(EQUAL, &skip_call, Assembler::kNearJump); // 'result' is 1.0. |
| 4791 | 4791 |
| 4792 __ Bind(&check_base); | 4792 __ Bind(&check_base); |
| 4793 // Note: 'exp' could be NaN. | 4793 // Note: 'exp' could be NaN. |
| 4794 | 4794 |
| 4795 // base == 1.0 -> return 1.0; | 4795 // base == 1.0 -> return 1.0; |
| 4796 __ comisd(base, result); | 4796 __ comisd(base, result); |
| 4797 __ j(PARITY_EVEN, &return_nan, Assembler::kNearJump); | 4797 __ j(PARITY_EVEN, &return_nan, Assembler::kNearJump); |
| 4798 __ j(EQUAL, &skip_call, Assembler::kNearJump); | 4798 __ j(EQUAL, &skip_call, Assembler::kNearJump); |
| 4799 // Note: 'base' could be NaN. | 4799 // Note: 'base' could be NaN. |
| 4800 __ comisd(exp, base); | 4800 __ comisd(exp, base); |
| 4801 // Neither 'exp' nor 'base' is NaN. | 4801 // Neither 'exp' nor 'base' is NaN. |
| 4802 __ j(PARITY_ODD, &do_call, Assembler::kNearJump); | 4802 __ j(PARITY_ODD, &try_sqrt, Assembler::kNearJump); |
| 4803 // Return NaN. | 4803 // Return NaN. |
| 4804 __ Bind(&return_nan); | 4804 __ Bind(&return_nan); |
| 4805 __ LoadObject(temp, Double::ZoneHandle(Double::NewCanonical(NAN))); | 4805 __ LoadObject(temp, Double::ZoneHandle(Double::NewCanonical(NAN))); |
| 4806 __ movsd(result, FieldAddress(temp, Double::value_offset())); | 4806 __ movsd(result, FieldAddress(temp, Double::value_offset())); |
| 4807 __ jmp(&skip_call); | 4807 __ jmp(&skip_call); |
| 4808 | 4808 |
| 4809 Label do_pow, return_zero; | 4809 Label do_pow, return_zero; |
| 4810 __ Bind(&do_call); | 4810 __ Bind(&try_sqrt); |
| 4811 // Before calling check if we could use sqrt instead of pow. | 4811 // Before calling pow, check if we could use sqrt instead of pow. |
| 4812 __ LoadObject(temp, Double::ZoneHandle(Double::NewCanonical(-INFINITY))); | 4812 __ LoadObject(temp, Double::ZoneHandle(Double::NewCanonical(-INFINITY))); |
| 4813 __ movsd(result, FieldAddress(temp, Double::value_offset())); | 4813 __ movsd(result, FieldAddress(temp, Double::value_offset())); |
| 4814 // base == -Infinity -> call pow; | 4814 // base == -Infinity -> call pow; |
| 4815 __ comisd(base, result); | 4815 __ comisd(base, result); |
| 4816 __ j(EQUAL, &do_pow, Assembler::kNearJump); | 4816 __ j(EQUAL, &do_pow, Assembler::kNearJump); |
| 4817 | 4817 |
| 4818 // exponent == 0.5 ? | 4818 // exponent == 0.5 ? |
| 4819 __ LoadObject(temp, Double::ZoneHandle(Double::NewCanonical(0.5))); | 4819 __ LoadObject(temp, Double::ZoneHandle(Double::NewCanonical(0.5))); |
| 4820 __ movsd(result, FieldAddress(temp, Double::value_offset())); | 4820 __ movsd(result, FieldAddress(temp, Double::value_offset())); |
| 4821 __ comisd(exp, result); | 4821 __ comisd(exp, result); |
| (...skipping 1017 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5839 PcDescriptors::kOther, | 5839 PcDescriptors::kOther, |
| 5840 locs()); | 5840 locs()); |
| 5841 __ Drop(ArgumentCount()); // Discard arguments. | 5841 __ Drop(ArgumentCount()); // Discard arguments. |
| 5842 } | 5842 } |
| 5843 | 5843 |
| 5844 } // namespace dart | 5844 } // namespace dart |
| 5845 | 5845 |
| 5846 #undef __ | 5846 #undef __ |
| 5847 | 5847 |
| 5848 #endif // defined TARGET_ARCH_IA32 | 5848 #endif // defined TARGET_ARCH_IA32 |
| OLD | NEW |