Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(713)

Side by Side Diff: runtime/vm/intermediate_language_ia32.cc

Issue 221433002: Optimize pow(x, 0.5) to use sqrt instead. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 4742 matching lines...) Expand 10 before | Expand all | Expand 10 after
4753 } 4753 }
4754 4754
4755 4755
4756 void InvokeMathCFunctionInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4756 void InvokeMathCFunctionInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4757 // Save ESP. 4757 // Save ESP.
4758 __ movl(locs()->temp(kSavedSpTempIndex).reg(), ESP); 4758 __ movl(locs()->temp(kSavedSpTempIndex).reg(), ESP);
4759 __ ReserveAlignedFrameSpace(kDoubleSize * InputCount()); 4759 __ ReserveAlignedFrameSpace(kDoubleSize * InputCount());
4760 for (intptr_t i = 0; i < InputCount(); i++) { 4760 for (intptr_t i = 0; i < InputCount(); i++) {
4761 __ movsd(Address(ESP, kDoubleSize * i), locs()->in(i).fpu_reg()); 4761 __ movsd(Address(ESP, kDoubleSize * i), locs()->in(i).fpu_reg());
4762 } 4762 }
4763 Label do_call, skip_call; 4763 Label skip_call;
4764 if (recognized_kind() == MethodRecognizer::kMathDoublePow) { 4764 if (recognized_kind() == MethodRecognizer::kMathDoublePow) {
4765 // Pseudo code: 4765 // Pseudo code:
4766 // if (exponent == 0.0) return 1.0; 4766 // if (exponent == 0.0) return 1.0;
4767 // if (base == 1.0) return 1.0; 4767 // if (base == 1.0) return 1.0;
4768 // if (base.isNaN || exponent.isNaN) { 4768 // if (base.isNaN || exponent.isNaN) {
4769 // return double.NAN; 4769 // return double.NAN;
4770 // } 4770 // }
4771 // if (base != -Infinity && exponent == 0.5) {
4772 // if (base == 0.0) return 0.0;
4773 // return sqrt(value);
4774 // }
4771 XmmRegister base = locs()->in(0).fpu_reg(); 4775 XmmRegister base = locs()->in(0).fpu_reg();
4772 XmmRegister exp = locs()->in(1).fpu_reg(); 4776 XmmRegister exp = locs()->in(1).fpu_reg();
4773 XmmRegister result = locs()->out(0).fpu_reg(); 4777 XmmRegister result = locs()->out(0).fpu_reg();
4774 Register temp = locs()->temp(kObjectTempIndex).reg(); 4778 Register temp = locs()->temp(kObjectTempIndex).reg();
4775 XmmRegister zero_temp = locs()->temp(kDoubleTempIndex).fpu_reg(); 4779 XmmRegister zero_temp = locs()->temp(kDoubleTempIndex).fpu_reg();
4776 4780
4777 Label check_base_is_one; 4781 Label do_call, check_base, return_nan;
4778 // Check if exponent is 0.0 -> return 1.0;
4779 __ LoadObject(temp, Double::ZoneHandle(Double::NewCanonical(0))); 4782 __ LoadObject(temp, Double::ZoneHandle(Double::NewCanonical(0)));
4780 __ movsd(zero_temp, FieldAddress(temp, Double::value_offset())); 4783 __ movsd(zero_temp, FieldAddress(temp, Double::value_offset()));
4781 __ LoadObject(temp, Double::ZoneHandle(Double::NewCanonical(1))); 4784 __ LoadObject(temp, Double::ZoneHandle(Double::NewCanonical(1)));
4782 __ movsd(result, FieldAddress(temp, Double::value_offset())); 4785 __ movsd(result, FieldAddress(temp, Double::value_offset()));
4783 // 'result' contains 1.0. 4786
4787 // Check if exponent is 0.0 -> return 1.0;
4784 __ comisd(exp, zero_temp); 4788 __ comisd(exp, zero_temp);
4785 __ j(PARITY_EVEN, &check_base_is_one, Assembler::kNearJump); // NaN. 4789 __ j(PARITY_EVEN, &check_base, Assembler::kNearJump);
4786 __ j(EQUAL, &skip_call, Assembler::kNearJump); // exp is 0, result is 1.0. 4790 __ j(EQUAL, &skip_call, Assembler::kNearJump); // 'result' is 1.0.
4787 4791
4788 Label base_is_nan; 4792 __ Bind(&check_base);
4789 __ Bind(&check_base_is_one); 4793 // Note: 'exp' could be NaN.
4790 __ comisd(base, result); 4794 __ comisd(base, result);
4791 __ j(PARITY_EVEN, &base_is_nan, Assembler::kNearJump); 4795 __ j(PARITY_EVEN, &return_nan, Assembler::kNearJump);
4792 __ j(EQUAL, &skip_call, Assembler::kNearJump); // base and result are 1.0 4796 __ j(EQUAL, &skip_call, Assembler::kNearJump);
4793 __ jmp(&do_call, Assembler::kNearJump); 4797 // Note: 'base' could be NaN.
4798 __ comisd(exp, base);
4799 // Neither 'exp' nor 'base' is NaN.
4800 __ j(PARITY_ODD, &do_call, Assembler::kNearJump);
4801 // Return NaN.
4802 __ Bind(&return_nan);
4803 __ LoadObject(temp, Double::ZoneHandle(Double::NewCanonical(NAN)));
4804 __ movsd(result, FieldAddress(temp, Double::value_offset()));
4805 __ jmp(&skip_call);
4794 4806
4795 __ Bind(&base_is_nan); 4807 Label do_pow, return_zero;
4796 // Returns NaN. 4808 __ Bind(&do_call);
4797 __ movsd(result, base); 4809
4810
4811 __ LoadObject(temp, Double::ZoneHandle(Double::NewCanonical(-1.0/0.0)));
4812 __ movsd(result, FieldAddress(temp, Double::value_offset()));
4813 // base == -Infinity -> pow;
4814 __ comisd(base, result);
4815 __ j(EQUAL, &do_pow, Assembler::kNearJump);
4816
4817 // Check if exponent is 0.5 -> sqrt(value).
4818 __ LoadObject(temp, Double::ZoneHandle(Double::NewCanonical(0.5)));
4819 __ movsd(result, FieldAddress(temp, Double::value_offset()));
4820 __ comisd(exp, result);
4821 __ j(NOT_EQUAL, &do_pow, Assembler::kNearJump);
4822
4823 // base == 0
4824 __ comisd(base, zero_temp);
4825 __ j(EQUAL, &return_zero, Assembler::kNearJump);
4826
4827 __ sqrtsd(result, base);
4798 __ jmp(&skip_call, Assembler::kNearJump); 4828 __ jmp(&skip_call, Assembler::kNearJump);
4799 // exp is Nan case is handled correctly in the C-library. 4829
4830 __ Bind(&return_zero);
4831 __ movsd(result, zero_temp);
4832 __ jmp(&skip_call);
4833
4834 __ Bind(&do_pow);
4800 } 4835 }
4801 __ Bind(&do_call); 4836
4802 __ CallRuntime(TargetFunction(), InputCount()); 4837 __ CallRuntime(TargetFunction(), InputCount());
4803 __ fstpl(Address(ESP, 0)); 4838 __ fstpl(Address(ESP, 0));
4804 __ movsd(locs()->out(0).fpu_reg(), Address(ESP, 0)); 4839 __ movsd(locs()->out(0).fpu_reg(), Address(ESP, 0));
4805 __ Bind(&skip_call); 4840 __ Bind(&skip_call);
4806 // Restore ESP. 4841 // Restore ESP.
4807 __ movl(ESP, locs()->temp(kSavedSpTempIndex).reg()); 4842 __ movl(ESP, locs()->temp(kSavedSpTempIndex).reg());
4808 } 4843 }
4809 4844
4810 4845
4811 LocationSummary* MergedMathInstr::MakeLocationSummary(bool opt) const { 4846 LocationSummary* MergedMathInstr::MakeLocationSummary(bool opt) const {
(...skipping 991 matching lines...) Expand 10 before | Expand all | Expand 10 after
5803 PcDescriptors::kOther, 5838 PcDescriptors::kOther,
5804 locs()); 5839 locs());
5805 __ Drop(ArgumentCount()); // Discard arguments. 5840 __ Drop(ArgumentCount()); // Discard arguments.
5806 } 5841 }
5807 5842
5808 } // namespace dart 5843 } // namespace dart
5809 5844
5810 #undef __ 5845 #undef __
5811 5846
5812 #endif // defined TARGET_ARCH_IA32 5847 #endif // defined TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698