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

Side by Side Diff: src/arm/lithium-codegen-arm.cc

Issue 6676060: Improved modulo operation in lithium as well as bailout on -0.... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 9 years, 9 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
OLDNEW
1 // Copyright 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 782 matching lines...) Expand 10 before | Expand all | Expand 10 after
793 void LCodeGen::DoModI(LModI* instr) { 793 void LCodeGen::DoModI(LModI* instr) {
794 if (instr->hydrogen()->HasPowerOf2Divisor()) { 794 if (instr->hydrogen()->HasPowerOf2Divisor()) {
795 Register dividend = ToRegister(instr->InputAt(0)); 795 Register dividend = ToRegister(instr->InputAt(0));
796 796
797 int32_t divisor = 797 int32_t divisor =
798 HConstant::cast(instr->hydrogen()->right())->Integer32Value(); 798 HConstant::cast(instr->hydrogen()->right())->Integer32Value();
799 799
800 if (divisor < 0) divisor = -divisor; 800 if (divisor < 0) divisor = -divisor;
801 801
802 Label positive_dividend, done; 802 Label positive_dividend, done;
803 __ tst(dividend, Operand(dividend)); 803 __ cmp(dividend, Operand(0));
804 __ b(pl, &positive_dividend); 804 __ b(pl, &positive_dividend);
805 __ rsb(dividend, dividend, Operand(0)); 805 __ rsb(dividend, dividend, Operand(0));
806 __ and_(dividend, dividend, Operand(divisor - 1)); 806 __ and_(dividend, dividend, Operand(divisor - 1));
807 __ rsb(dividend, dividend, Operand(0), SetCC); 807 __ rsb(dividend, dividend, Operand(0), SetCC);
808 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 808 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
809 __ b(ne, &done); 809 __ b(ne, &done);
810 DeoptimizeIf(al, instr->environment()); 810 DeoptimizeIf(al, instr->environment());
811 } 811 }
812 __ bind(&positive_dividend); 812 __ bind(&positive_dividend);
813 __ and_(dividend, dividend, Operand(divisor - 1)); 813 __ and_(dividend, dividend, Operand(divisor - 1));
814 __ bind(&done); 814 __ bind(&done);
815 return; 815 return;
816 } 816 }
817 817
818 class DeferredModI: public LDeferredCode {
819 public:
820 DeferredModI(LCodeGen* codegen, LModI* instr)
821 : LDeferredCode(codegen), instr_(instr) { }
822 virtual void Generate() {
823 codegen()->DoDeferredBinaryOpStub(instr_, Token::MOD);
824 }
825 private:
826 LModI* instr_;
827 };
828 // These registers hold untagged 32 bit values. 818 // These registers hold untagged 32 bit values.
829 Register left = ToRegister(instr->InputAt(0)); 819 Register left = ToRegister(instr->InputAt(0));
830 Register right = ToRegister(instr->InputAt(1)); 820 Register right = ToRegister(instr->InputAt(1));
831 Register result = ToRegister(instr->result()); 821 Register result = ToRegister(instr->result());
822
832 Register scratch = scratch0(); 823 Register scratch = scratch0();
824 Register scratch2 = ToRegister(instr->TempAt(0));
825 DwVfpRegister dividend = ToDoubleRegister(instr->TempAt(1));
826 DwVfpRegister divisor = ToDoubleRegister(instr->TempAt(2));
827 DwVfpRegister quotient = double_scratch0();
833 828
834 Label deoptimize, done; 829 ASSERT(result.is(left));
830
831 ASSERT(!dividend.is(divisor));
832 ASSERT(!dividend.is(quotient));
833 ASSERT(!divisor.is(quotient));
834 ASSERT(!scratch.is(left));
835 ASSERT(!scratch.is(right));
836 ASSERT(!scratch.is(result));
837
838 Label done, vfp_modulo, both_positive, right_negative;
839
835 // Check for x % 0. 840 // Check for x % 0.
836 if (instr->hydrogen()->CheckFlag(HValue::kCanBeDivByZero)) { 841 if (instr->hydrogen()->CheckFlag(HValue::kCanBeDivByZero)) {
837 __ tst(right, Operand(right)); 842 __ cmp(right, Operand(0));
838 __ b(eq, &deoptimize); 843 DeoptimizeIf(eq, instr->environment());
839 } 844 }
840 845
841 // Check for (0 % -x) that will produce negative zero. 846 // (0 % x) must yield 0 (if x is finite, which is the case here).
842 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 847 __ cmp(left, Operand(0));
843 Label ok; 848 __ b(eq, &done);
844 __ tst(left, Operand(left)); 849 // Preload right in a vfp register.
845 __ b(ne, &ok); 850 __ vmov(divisor.low(), right);
846 __ tst(right, Operand(right)); 851 __ b(lt, &vfp_modulo);
847 __ b(pl, &ok);
848 __ b(al, &deoptimize);
849 __ bind(&ok);
850 }
851 852
852 // Try a few common cases before using the stub. 853 __ cmp(left, Operand(right));
853 Label call_stub; 854 __ b(lt, &done);
855
856 // Check for (positive) power of two on the right hand side.
857 __ JumpIfNotPowerOfTwoOrZeroAndNeg(right,
858 scratch,
859 &right_negative,
860 &both_positive);
861 // Perform modulo operation (scratch contains right - 1).
862 __ and_(result, scratch, Operand(left));
863 __ b(&done);
864
865 __ bind(&right_negative);
866 // Negate right. The sign of the divisor does not matter.
867 __ rsb(right, right, Operand(0));
868
869 __ bind(&both_positive);
854 const int kUnfolds = 3; 870 const int kUnfolds = 3;
855 // Skip if either side is negative.
856 __ cmp(left, Operand(0));
857 __ cmp(right, Operand(0), NegateCondition(mi));
858 __ b(mi, &call_stub);
859 // If the right hand side is smaller than the (nonnegative) 871 // If the right hand side is smaller than the (nonnegative)
860 // left hand side, it is the result. Else try a few subtractions 872 // left hand side, the left hand side is the result.
861 // of the left hand side. 873 // Else try a few subtractions of the left hand side.
862 __ mov(scratch, left); 874 __ mov(scratch, left);
863 for (int i = 0; i < kUnfolds; i++) { 875 for (int i = 0; i < kUnfolds; i++) {
864 // Check if the left hand side is less or equal than the 876 // Check if the left hand side is less or equal than the
865 // the right hand side. 877 // the right hand side.
866 __ cmp(scratch, right); 878 __ cmp(scratch, Operand(right));
867 __ mov(result, scratch, LeaveCC, lt); 879 __ mov(result, scratch, LeaveCC, lt);
868 __ b(lt, &done); 880 __ b(lt, &done);
869 // If not, reduce the left hand side by the right hand 881 // If not, reduce the left hand side by the right hand
870 // side and check again. 882 // side and check again.
871 if (i < kUnfolds - 1) __ sub(scratch, scratch, right); 883 if (i < kUnfolds - 1) __ sub(scratch, scratch, right);
872 } 884 }
873 885
874 // Check for power of two on the right hand side. 886 __ bind(&vfp_modulo);
875 __ JumpIfNotPowerOfTwoOrZero(right, scratch, &call_stub); 887 // Load the arguments in VFP registers.
876 // Perform modulo operation (scratch contains right - 1). 888 // The divisor value is preloaded before. Be careful that 'right' is only live
877 __ and_(result, scratch, Operand(left)); 889 // on entry.
878 __ b(&done); 890 __ vmov(dividend.low(), left);
891 // From here on don't use right as it may have been reallocated (for example
892 // to scratch2).
893 right = no_reg;
879 894
880 __ bind(&call_stub); 895 __ vcvt_f64_s32(dividend, dividend.low());
881 // Call the stub. The numbers in r0 and r1 have 896 __ vcvt_f64_s32(divisor, divisor.low());
882 // to be tagged to Smis. If that is not possible, deoptimize.
883 DeferredModI* deferred = new DeferredModI(this, instr);
884 __ TrySmiTag(left, &deoptimize, scratch);
885 __ TrySmiTag(right, &deoptimize, scratch);
886 897
887 __ b(al, deferred->entry()); 898 // We do not care about the sign of the divisor.
888 __ bind(deferred->exit()); 899 __ vabs(divisor, divisor);
900 // Compute the quotient.
Søren Thygesen Gjesse 2011/03/21 08:42:03 Please extend comment to say that the quotient is
Alexandre 2011/03/21 09:05:02 Done.
901 __ vdiv(quotient, dividend, divisor);
902 __ vcvt_s32_f64(quotient.low(), quotient);
903 __ vcvt_f64_s32(quotient, quotient.low());
889 904
890 // If the result in r0 is a Smi, untag it, else deoptimize. 905 // Compute the remainder in result.
891 __ JumpIfNotSmi(result, &deoptimize); 906 DwVfpRegister double_scratch = dividend;
892 __ SmiUntag(result); 907 __ vmul(double_scratch, divisor, quotient);
908 __ vcvt_s32_f64(double_scratch.low(), double_scratch);
909 __ vmov(scratch, double_scratch.low());
893 910
894 __ b(al, &done); 911 if (!instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
895 __ bind(&deoptimize); 912 __ sub(result, left, scratch);
896 DeoptimizeIf(al, instr->environment()); 913 } else {
914 Label ok;
915 // Check for -0.
916 __ sub(scratch2, left, scratch, SetCC);
917 __ b(ne, &ok);
918 __ cmp(left, Operand(0));
919 DeoptimizeIf(mi, instr->environment());
920 __ bind(&ok);
921 // Load the result and we are done.
922 __ mov(result, scratch2);
923 }
924
897 __ bind(&done); 925 __ bind(&done);
898 } 926 }
899 927
900 928
901 void LCodeGen::DoDivI(LDivI* instr) { 929 void LCodeGen::DoDivI(LDivI* instr) {
902 class DeferredDivI: public LDeferredCode { 930 class DeferredDivI: public LDeferredCode {
903 public: 931 public:
904 DeferredDivI(LCodeGen* codegen, LDivI* instr) 932 DeferredDivI(LCodeGen* codegen, LDivI* instr)
905 : LDeferredCode(codegen), instr_(instr) { } 933 : LDeferredCode(codegen), instr_(instr) { }
906 virtual void Generate() { 934 virtual void Generate() {
907 codegen()->DoDeferredBinaryOpStub(instr_, Token::DIV); 935 codegen()->DoDeferredBinaryOpStub(instr_, Token::DIV);
908 } 936 }
909 private: 937 private:
910 LDivI* instr_; 938 LDivI* instr_;
911 }; 939 };
912 940
913 const Register left = ToRegister(instr->InputAt(0)); 941 const Register left = ToRegister(instr->InputAt(0));
914 const Register right = ToRegister(instr->InputAt(1)); 942 const Register right = ToRegister(instr->InputAt(1));
915 const Register scratch = scratch0(); 943 const Register scratch = scratch0();
916 const Register result = ToRegister(instr->result()); 944 const Register result = ToRegister(instr->result());
917 945
918 // Check for x / 0. 946 // Check for x / 0.
919 if (instr->hydrogen()->CheckFlag(HValue::kCanBeDivByZero)) { 947 if (instr->hydrogen()->CheckFlag(HValue::kCanBeDivByZero)) {
920 __ tst(right, right); 948 __ cmp(right, Operand(0));
921 DeoptimizeIf(eq, instr->environment()); 949 DeoptimizeIf(eq, instr->environment());
922 } 950 }
923 951
924 // Check for (0 / -x) that will produce negative zero. 952 // Check for (0 / -x) that will produce negative zero.
925 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 953 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
926 Label left_not_zero; 954 Label left_not_zero;
927 __ tst(left, Operand(left)); 955 __ cmp(left, Operand(0));
928 __ b(ne, &left_not_zero); 956 __ b(ne, &left_not_zero);
929 __ tst(right, Operand(right)); 957 __ cmp(right, Operand(0));
930 DeoptimizeIf(mi, instr->environment()); 958 DeoptimizeIf(mi, instr->environment());
931 __ bind(&left_not_zero); 959 __ bind(&left_not_zero);
932 } 960 }
933 961
934 // Check for (-kMinInt / -1). 962 // Check for (-kMinInt / -1).
935 if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) { 963 if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) {
936 Label left_not_min_int; 964 Label left_not_min_int;
937 __ cmp(left, Operand(kMinInt)); 965 __ cmp(left, Operand(kMinInt));
938 __ b(ne, &left_not_min_int); 966 __ b(ne, &left_not_min_int);
939 __ cmp(right, Operand(-1)); 967 __ cmp(right, Operand(-1));
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
1026 __ mov(ip, Operand(left, ASR, 31)); 1054 __ mov(ip, Operand(left, ASR, 31));
1027 __ cmp(ip, Operand(scratch)); 1055 __ cmp(ip, Operand(scratch));
1028 DeoptimizeIf(ne, instr->environment()); 1056 DeoptimizeIf(ne, instr->environment());
1029 } else { 1057 } else {
1030 __ mul(left, left, right); 1058 __ mul(left, left, right);
1031 } 1059 }
1032 1060
1033 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 1061 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
1034 // Bail out if the result is supposed to be negative zero. 1062 // Bail out if the result is supposed to be negative zero.
1035 Label done; 1063 Label done;
1036 __ tst(left, Operand(left)); 1064 __ cmp(left, Operand(0));
1037 __ b(ne, &done); 1065 __ b(ne, &done);
1038 if (instr->InputAt(1)->IsConstantOperand()) { 1066 if (instr->InputAt(1)->IsConstantOperand()) {
1039 if (ToInteger32(LConstantOperand::cast(instr->InputAt(1))) <= 0) { 1067 if (ToInteger32(LConstantOperand::cast(instr->InputAt(1))) <= 0) {
1040 DeoptimizeIf(al, instr->environment()); 1068 DeoptimizeIf(al, instr->environment());
1041 } 1069 }
1042 } else { 1070 } else {
1043 // Test the non-zero operand for negative sign. 1071 // Test the non-zero operand for negative sign.
1044 __ cmp(ToRegister(instr->TempAt(0)), Operand(0)); 1072 __ cmp(ToRegister(instr->TempAt(0)), Operand(0));
1045 DeoptimizeIf(mi, instr->environment()); 1073 DeoptimizeIf(mi, instr->environment());
1046 } 1074 }
(...skipping 845 matching lines...) Expand 10 before | Expand all | Expand 10 after
1892 1920
1893 1921
1894 void LCodeGen::DoInstanceOf(LInstanceOf* instr) { 1922 void LCodeGen::DoInstanceOf(LInstanceOf* instr) {
1895 ASSERT(ToRegister(instr->InputAt(0)).is(r0)); // Object is in r0. 1923 ASSERT(ToRegister(instr->InputAt(0)).is(r0)); // Object is in r0.
1896 ASSERT(ToRegister(instr->InputAt(1)).is(r1)); // Function is in r1. 1924 ASSERT(ToRegister(instr->InputAt(1)).is(r1)); // Function is in r1.
1897 1925
1898 InstanceofStub stub(InstanceofStub::kArgsInRegisters); 1926 InstanceofStub stub(InstanceofStub::kArgsInRegisters);
1899 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); 1927 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
1900 1928
1901 Label true_value, done; 1929 Label true_value, done;
1902 __ tst(r0, r0); 1930 __ cmp(r0, Operand(0));
1903 __ mov(r0, Operand(Factory::false_value()), LeaveCC, ne); 1931 __ mov(r0, Operand(Factory::false_value()), LeaveCC, ne);
1904 __ mov(r0, Operand(Factory::true_value()), LeaveCC, eq); 1932 __ mov(r0, Operand(Factory::true_value()), LeaveCC, eq);
1905 } 1933 }
1906 1934
1907 1935
1908 void LCodeGen::DoInstanceOfAndBranch(LInstanceOfAndBranch* instr) { 1936 void LCodeGen::DoInstanceOfAndBranch(LInstanceOfAndBranch* instr) {
1909 ASSERT(ToRegister(instr->InputAt(0)).is(r0)); // Object is in r0. 1937 ASSERT(ToRegister(instr->InputAt(0)).is(r0)); // Object is in r0.
1910 ASSERT(ToRegister(instr->InputAt(1)).is(r1)); // Function is in r1. 1938 ASSERT(ToRegister(instr->InputAt(1)).is(r1)); // Function is in r1.
1911 1939
1912 int true_block = chunk_->LookupDestination(instr->true_block_id()); 1940 int true_block = chunk_->LookupDestination(instr->true_block_id());
1913 int false_block = chunk_->LookupDestination(instr->false_block_id()); 1941 int false_block = chunk_->LookupDestination(instr->false_block_id());
1914 1942
1915 InstanceofStub stub(InstanceofStub::kArgsInRegisters); 1943 InstanceofStub stub(InstanceofStub::kArgsInRegisters);
1916 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); 1944 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
1917 __ tst(r0, Operand(r0)); 1945 __ cmp(r0, Operand(0));
1918 EmitBranch(true_block, false_block, eq); 1946 EmitBranch(true_block, false_block, eq);
1919 } 1947 }
1920 1948
1921 1949
1922 void LCodeGen::DoInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr) { 1950 void LCodeGen::DoInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr) {
1923 class DeferredInstanceOfKnownGlobal: public LDeferredCode { 1951 class DeferredInstanceOfKnownGlobal: public LDeferredCode {
1924 public: 1952 public:
1925 DeferredInstanceOfKnownGlobal(LCodeGen* codegen, 1953 DeferredInstanceOfKnownGlobal(LCodeGen* codegen,
1926 LInstanceOfKnownGlobal* instr) 1954 LInstanceOfKnownGlobal* instr)
1927 : LDeferredCode(codegen), instr_(instr) { } 1955 : LDeferredCode(codegen), instr_(instr) { }
(...skipping 479 matching lines...) Expand 10 before | Expand all | Expand 10 after
2407 // number of arguments. 2435 // number of arguments.
2408 __ push(receiver); 2436 __ push(receiver);
2409 __ mov(receiver, length); 2437 __ mov(receiver, length);
2410 // The arguments are at a one pointer size offset from elements. 2438 // The arguments are at a one pointer size offset from elements.
2411 __ add(elements, elements, Operand(1 * kPointerSize)); 2439 __ add(elements, elements, Operand(1 * kPointerSize));
2412 2440
2413 // Loop through the arguments pushing them onto the execution 2441 // Loop through the arguments pushing them onto the execution
2414 // stack. 2442 // stack.
2415 Label invoke, loop; 2443 Label invoke, loop;
2416 // length is a small non-negative integer, due to the test above. 2444 // length is a small non-negative integer, due to the test above.
2417 __ tst(length, Operand(length)); 2445 __ cmp(length, Operand(0));
2418 __ b(eq, &invoke); 2446 __ b(eq, &invoke);
2419 __ bind(&loop); 2447 __ bind(&loop);
2420 __ ldr(scratch, MemOperand(elements, length, LSL, 2)); 2448 __ ldr(scratch, MemOperand(elements, length, LSL, 2));
2421 __ push(scratch); 2449 __ push(scratch);
2422 __ sub(length, length, Operand(1), SetCC); 2450 __ sub(length, length, Operand(1), SetCC);
2423 __ b(ne, &loop); 2451 __ b(ne, &loop);
2424 2452
2425 __ bind(&invoke); 2453 __ bind(&invoke);
2426 ASSERT(instr->HasPointerMap() && instr->HasDeoptimizationEnvironment()); 2454 ASSERT(instr->HasPointerMap() && instr->HasDeoptimizationEnvironment());
2427 LPointerMap* pointers = instr->pointer_map(); 2455 LPointerMap* pointers = instr->pointer_map();
(...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after
2643 __ EmitVFPTruncate(kRoundToMinusInf, 2671 __ EmitVFPTruncate(kRoundToMinusInf,
2644 single_scratch, 2672 single_scratch,
2645 input, 2673 input,
2646 scratch1, 2674 scratch1,
2647 scratch2); 2675 scratch2);
2648 DeoptimizeIf(ne, instr->environment()); 2676 DeoptimizeIf(ne, instr->environment());
2649 2677
2650 // Move the result back to general purpose register r0. 2678 // Move the result back to general purpose register r0.
2651 __ vmov(result, single_scratch); 2679 __ vmov(result, single_scratch);
2652 2680
2653 // Test for -0. 2681 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
2654 Label done; 2682 // Test for -0.
2655 __ cmp(result, Operand(0)); 2683 Label done;
2656 __ b(ne, &done); 2684 __ cmp(result, Operand(0));
2657 __ vmov(scratch1, input.high()); 2685 __ b(ne, &done);
2658 __ tst(scratch1, Operand(HeapNumber::kSignMask)); 2686 __ vmov(scratch1, input.high());
2659 DeoptimizeIf(ne, instr->environment()); 2687 __ tst(scratch1, Operand(HeapNumber::kSignMask));
2660 __ bind(&done); 2688 DeoptimizeIf(ne, instr->environment());
2689 __ bind(&done);
2690 }
2661 } 2691 }
2662 2692
2663 2693
2664 void LCodeGen::DoMathRound(LUnaryMathOperation* instr) { 2694 void LCodeGen::DoMathRound(LUnaryMathOperation* instr) {
2665 DoubleRegister input = ToDoubleRegister(instr->InputAt(0)); 2695 DoubleRegister input = ToDoubleRegister(instr->InputAt(0));
2666 Register result = ToRegister(instr->result()); 2696 Register result = ToRegister(instr->result());
2667 Register scratch1 = scratch0(); 2697 Register scratch1 = scratch0();
2668 Register scratch2 = result; 2698 Register scratch2 = result;
2669 __ EmitVFPTruncate(kRoundToNearest, 2699 __ EmitVFPTruncate(kRoundToNearest,
2670 double_scratch0().low(), 2700 double_scratch0().low(),
2671 input, 2701 input,
2672 scratch1, 2702 scratch1,
2673 scratch2); 2703 scratch2);
2674 DeoptimizeIf(ne, instr->environment()); 2704 DeoptimizeIf(ne, instr->environment());
2675 __ vmov(result, double_scratch0().low()); 2705 __ vmov(result, double_scratch0().low());
2676 2706
2677 // Test for -0. 2707 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
2678 Label done; 2708 // Test for -0.
2679 __ cmp(result, Operand(0)); 2709 Label done;
2680 __ b(ne, &done); 2710 __ cmp(result, Operand(0));
2681 __ vmov(scratch1, input.high()); 2711 __ b(ne, &done);
2682 __ tst(scratch1, Operand(HeapNumber::kSignMask)); 2712 __ vmov(scratch1, input.high());
2683 DeoptimizeIf(ne, instr->environment()); 2713 __ tst(scratch1, Operand(HeapNumber::kSignMask));
2684 __ bind(&done); 2714 DeoptimizeIf(ne, instr->environment());
2715 __ bind(&done);
2716 }
2685 } 2717 }
2686 2718
2687 2719
2688 void LCodeGen::DoMathSqrt(LUnaryMathOperation* instr) { 2720 void LCodeGen::DoMathSqrt(LUnaryMathOperation* instr) {
2689 DoubleRegister input = ToDoubleRegister(instr->InputAt(0)); 2721 DoubleRegister input = ToDoubleRegister(instr->InputAt(0));
2690 ASSERT(ToDoubleRegister(instr->result()).is(input)); 2722 ASSERT(ToDoubleRegister(instr->result()).is(input));
2691 __ vsqrt(input, input); 2723 __ vsqrt(input, input);
2692 } 2724 }
2693 2725
2694 2726
(...skipping 1273 matching lines...) Expand 10 before | Expand all | Expand 10 after
3968 ASSERT(!environment->HasBeenRegistered()); 4000 ASSERT(!environment->HasBeenRegistered());
3969 RegisterEnvironmentForDeoptimization(environment); 4001 RegisterEnvironmentForDeoptimization(environment);
3970 ASSERT(osr_pc_offset_ == -1); 4002 ASSERT(osr_pc_offset_ == -1);
3971 osr_pc_offset_ = masm()->pc_offset(); 4003 osr_pc_offset_ = masm()->pc_offset();
3972 } 4004 }
3973 4005
3974 4006
3975 #undef __ 4007 #undef __
3976 4008
3977 } } // namespace v8::internal 4009 } } // namespace v8::internal
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698