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

Side by Side Diff: src/assembler.cc

Issue 5640004: Allow the optimizing code generator to call Math.pow with untagged doubles. (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 10 years 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 | « src/assembler.h ('k') | src/hydrogen.cc » ('j') | src/hydrogen.cc » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 1994-2006 Sun Microsystems Inc. 1 // Copyright (c) 1994-2006 Sun Microsystems Inc.
2 // All Rights Reserved. 2 // All Rights Reserved.
3 // 3 //
4 // Redistribution and use in source and binary forms, with or without 4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are 5 // modification, are permitted provided that the following conditions are
6 // met: 6 // met:
7 // 7 //
8 // - Redistributions of source code must retain the above copyright notice, 8 // - Redistributions of source code must retain the above copyright notice,
9 // this list of conditions and the following disclaimer. 9 // this list of conditions and the following disclaimer.
10 // 10 //
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
59 #error "Unknown architecture." 59 #error "Unknown architecture."
60 #endif // Target architecture. 60 #endif // Target architecture.
61 #endif // V8_INTERPRETED_REGEXP 61 #endif // V8_INTERPRETED_REGEXP
62 62
63 namespace v8 { 63 namespace v8 {
64 namespace internal { 64 namespace internal {
65 65
66 66
67 const double DoubleConstant::min_int = kMinInt; 67 const double DoubleConstant::min_int = kMinInt;
68 const double DoubleConstant::one_half = 0.5; 68 const double DoubleConstant::one_half = 0.5;
69 const double DoubleConstant::negative_infinity = -V8_INFINITY;
69 70
70 71
71 // ----------------------------------------------------------------------------- 72 // -----------------------------------------------------------------------------
72 // Implementation of Label 73 // Implementation of Label
73 74
74 int Label::pos() const { 75 int Label::pos() const {
75 if (pos_ < 0) return -pos_ - 1; 76 if (pos_ < 0) return -pos_ - 1;
76 if (pos_ > 0) return pos_ - 1; 77 if (pos_ > 0) return pos_ - 1;
77 UNREACHABLE(); 78 UNREACHABLE();
78 return 0; 79 return 0;
(...skipping 636 matching lines...) Expand 10 before | Expand all | Expand 10 after
715 const_cast<double*>(&DoubleConstant::min_int))); 716 const_cast<double*>(&DoubleConstant::min_int)));
716 } 717 }
717 718
718 719
719 ExternalReference ExternalReference::address_of_one_half() { 720 ExternalReference ExternalReference::address_of_one_half() {
720 return ExternalReference(reinterpret_cast<void*>( 721 return ExternalReference(reinterpret_cast<void*>(
721 const_cast<double*>(&DoubleConstant::one_half))); 722 const_cast<double*>(&DoubleConstant::one_half)));
722 } 723 }
723 724
724 725
726 ExternalReference ExternalReference::address_of_negative_infinity() {
727 return ExternalReference(reinterpret_cast<void*>(
728 const_cast<double*>(&DoubleConstant::negative_infinity)));
729 }
730
731
725 #ifndef V8_INTERPRETED_REGEXP 732 #ifndef V8_INTERPRETED_REGEXP
726 733
727 ExternalReference ExternalReference::re_check_stack_guard_state() { 734 ExternalReference ExternalReference::re_check_stack_guard_state() {
728 Address function; 735 Address function;
729 #ifdef V8_TARGET_ARCH_X64 736 #ifdef V8_TARGET_ARCH_X64
730 function = FUNCTION_ADDR(RegExpMacroAssemblerX64::CheckStackGuardState); 737 function = FUNCTION_ADDR(RegExpMacroAssemblerX64::CheckStackGuardState);
731 #elif V8_TARGET_ARCH_IA32 738 #elif V8_TARGET_ARCH_IA32
732 function = FUNCTION_ADDR(RegExpMacroAssemblerIA32::CheckStackGuardState); 739 function = FUNCTION_ADDR(RegExpMacroAssemblerIA32::CheckStackGuardState);
733 #elif V8_TARGET_ARCH_ARM 740 #elif V8_TARGET_ARCH_ARM
734 function = FUNCTION_ADDR(RegExpMacroAssemblerARM::CheckStackGuardState); 741 function = FUNCTION_ADDR(RegExpMacroAssemblerARM::CheckStackGuardState);
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
784 791
785 792
786 static double div_two_doubles(double x, double y) { 793 static double div_two_doubles(double x, double y) {
787 return x / y; 794 return x / y;
788 } 795 }
789 796
790 797
791 static double mod_two_doubles(double x, double y) { 798 static double mod_two_doubles(double x, double y) {
792 return modulo(x, y); 799 return modulo(x, y);
793 } 800 }
794 801
fschneider 2010/12/08 11:27:07 It would be good to not duplicate code between her
William Hesse 2010/12/08 13:37:00 Done.
795 802
803 // Helper function to compute x^y, where y is known to be an
804 // integer. Uses binary decomposition to limit the number of
805 // multiplications; see the discussion in "Hacker's Delight" by Henry
806 // S. Warren, Jr., figure 11-6, page 213.
807 static double powi(double x, int y) {
808 unsigned n = (y < 0) ? -y : y;
809 double m = x;
810 double p = 1;
811 while (n != 0) {
812 if ((n & 1) != 0) p *= m;
813 m *= m;
814 if ((n & 2) != 0) p *= m;
815 m *= m;
816 n >>= 2;
817 }
818 if (y < 0) {
819 // Unfortunately, we have to be careful when p has reached
820 // infinity in the computation, because sometimes the higher
821 // internal precision in the pow() implementation would have
822 // given us a finite p. This happens very rarely.
823 double result = 1.0 / p;
824 return (result == 0 && isinf(p))
825 ? pow(x, static_cast<double>(y)) // Avoid pow(double, int).
826 : result;
827 } else {
828 return p;
829 }
830 }
831
832
833 static double power_two_doubles(double x, double y) {
834 int y_int = static_cast<int>(y);
835 if (y == y_int) {
836 return powi(x, y_int);
837 }
838 if (!isinf(x)) {
839 if (y == 0.5) return sqrt(x);
840 if (y == -0.5) return 1.0 / sqrt(x);
841 }
842 if (y == 0) return 1.0;
843 if (isnan(y) || ((x == 1 || x == -1) && isinf(y))) {
844 return OS::nan_value();
845 }
846 return pow(x, y);
847 }
848
849
850 static double power_double_int(double x, int y) {
851 return powi(x, y);
852 }
853
854
796 static int native_compare_doubles(double y, double x) { 855 static int native_compare_doubles(double y, double x) {
797 if (x == y) return EQUAL; 856 if (x == y) return EQUAL;
798 return x < y ? LESS : GREATER; 857 return x < y ? LESS : GREATER;
799 } 858 }
800 859
801 860
802 ExternalReference ExternalReference::double_fp_operation( 861 ExternalReference ExternalReference::double_fp_operation(
803 Token::Value operation) { 862 Token::Value operation) {
804 typedef double BinaryFPOperation(double x, double y); 863 typedef double BinaryFPOperation(double x, double y);
805 BinaryFPOperation* function = NULL; 864 BinaryFPOperation* function = NULL;
806 switch (operation) { 865 switch (operation) {
807 case Token::ADD: 866 case Token::ADD:
808 function = &add_two_doubles; 867 function = &add_two_doubles;
809 break; 868 break;
810 case Token::SUB: 869 case Token::SUB:
811 function = &sub_two_doubles; 870 function = &sub_two_doubles;
812 break; 871 break;
813 case Token::MUL: 872 case Token::MUL:
814 function = &mul_two_doubles; 873 function = &mul_two_doubles;
815 break; 874 break;
816 case Token::DIV: 875 case Token::DIV:
817 function = &div_two_doubles; 876 function = &div_two_doubles;
818 break; 877 break;
819 case Token::MOD: 878 case Token::MOD:
820 function = &mod_two_doubles; 879 function = &mod_two_doubles;
821 break; 880 break;
881 case Token::BIT_XOR:
Kevin Millikin (Chromium) 2010/12/08 10:01:46 Don't repurpose these tokens this way, it's a bug
William Hesse 2010/12/08 13:37:00 I removed the power case. Did not change the exis
882 function = &power_two_doubles;
883 break;
884 case Token::BIT_OR:
885 function = reinterpret_cast<BinaryFPOperation*>(&power_double_int);
886 break;
822 default: 887 default:
823 UNREACHABLE(); 888 UNREACHABLE();
824 } 889 }
825 // Passing true as 2nd parameter indicates that they return an fp value. 890 // Passing true as 2nd parameter indicates that they return an fp value.
826 return ExternalReference(Redirect(FUNCTION_ADDR(function), true)); 891 return ExternalReference(Redirect(FUNCTION_ADDR(function), true));
827 } 892 }
828 893
829 894
830 ExternalReference ExternalReference::compare_doubles() { 895 ExternalReference ExternalReference::compare_doubles() {
831 return ExternalReference(Redirect(FUNCTION_ADDR(native_compare_doubles), 896 return ExternalReference(Redirect(FUNCTION_ADDR(native_compare_doubles),
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
883 assembler_->RecordRelocInfo(RelocInfo::POSITION, state_.current_position); 948 assembler_->RecordRelocInfo(RelocInfo::POSITION, state_.current_position);
884 state_.written_position = state_.current_position; 949 state_.written_position = state_.current_position;
885 written = true; 950 written = true;
886 } 951 }
887 952
888 // Return whether something was written. 953 // Return whether something was written.
889 return written; 954 return written;
890 } 955 }
891 956
892 } } // namespace v8::internal 957 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/assembler.h ('k') | src/hydrogen.cc » ('j') | src/hydrogen.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698