OLD | NEW |
---|---|
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 2843 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2854 __ tst(scratch1, Operand(HeapNumber::kSignMask)); | 2854 __ tst(scratch1, Operand(HeapNumber::kSignMask)); |
2855 DeoptimizeIf(ne, instr->environment()); | 2855 DeoptimizeIf(ne, instr->environment()); |
2856 __ bind(&done); | 2856 __ bind(&done); |
2857 } | 2857 } |
2858 } | 2858 } |
2859 | 2859 |
2860 | 2860 |
2861 void LCodeGen::DoMathRound(LUnaryMathOperation* instr) { | 2861 void LCodeGen::DoMathRound(LUnaryMathOperation* instr) { |
2862 DoubleRegister input = ToDoubleRegister(instr->InputAt(0)); | 2862 DoubleRegister input = ToDoubleRegister(instr->InputAt(0)); |
2863 Register result = ToRegister(instr->result()); | 2863 Register result = ToRegister(instr->result()); |
2864 Register scratch1 = scratch0(); | 2864 Register scratch1 = ToRegister(instr->TempAt(0)); |
2865 Register scratch2 = result; | 2865 Register scratch2 = scratch0(); |
2866 Register scratch3 = result; | |
2867 | |
2868 // Test for numbers with a decimal fraction of 0.5 first. | |
2869 // These cannot be rounded with kRoundToNearest, because it rounds | |
2870 // ties to even numbers instead of to the higher one, as required | |
2871 // by the ECMA standard. | |
2872 | |
2873 // Extract exponent bits. scratch1 holds the upper word | |
2874 // of the double and scratch2 the lower word. | |
2875 __ vmov(scratch2, scratch1, input); | |
2876 __ ubfx(scratch3, | |
2877 scratch1, | |
2878 HeapNumber::kExponentShift, | |
2879 HeapNumber::kExponentBits); | |
2880 | |
2881 // Unbias exponent. | |
2882 __ sub(scratch3, scratch3, Operand(HeapNumber::kExponentBias)); | |
2883 | |
2884 // Deoptimize if value is special. | |
2885 __ cmp(scratch3, Operand(1024)); | |
Lasse Reichstein
2011/04/14 19:09:04
You can deoptimize for all exponents above or equa
| |
2886 DeoptimizeIf(eq, instr->environment()); | |
2887 | |
2888 Label lower_word, one_half, test, normal_case, adjust_sign_on_zero, done; | |
2889 | |
2890 // If the exponent is -1 jump to special check for 0.5. | |
2891 __ cmp(scratch3, Operand(-1)); | |
2892 __ b(eq, &one_half); | |
2893 | |
2894 // If the exponent is smaller than -1, the result is +0 | |
2895 // or -0. | |
2896 __ mov(result, Operand(0), LeaveCC, lt); | |
2897 __ b(lt, &adjust_sign_on_zero); | |
Lasse Reichstein
2011/04/14 19:09:04
You can jump to after the zero-test at adjust_sign
| |
2898 | |
2899 // If the exponent is greater or equal to HeapNumber::kMantissaBits then | |
2900 // there is no fractional part. | |
2901 __ cmp(scratch3, Operand(HeapNumber::kMantissaBits)); | |
Lasse Reichstein
2011/04/14 19:09:04
If you bailed out for exponent >= 31, this isn't n
| |
2902 __ b(ge, &normal_case); | |
2903 | |
2904 // Exponent is greater or equal zero and below HeapNumber::kMantissaBits. | |
Søren Thygesen Gjesse
2011/04/15 07:55:35
equal zero -> equal to zero
| |
2905 // Check if the bit we want to test is in the upper or lower word. | |
Lasse Reichstein
2011/04/14 19:09:04
The bit we need to test is the one with value 0.5,
| |
2906 __ cmp(scratch3, Operand(HeapNumber::kMantissaBitsInTopWord - 1)); | |
Lasse Reichstein
2011/04/14 19:09:04
You might be able to save a few instructions here
| |
2907 __ b(gt, &lower_word); | |
2908 | |
2909 // If the first fractional bit is in the upper word and the fractional part | |
2910 // is 0.5 then the lower word of the double must be all zeroes. | |
2911 __ cmp(scratch2, Operand(0)); | |
2912 __ b(ne, &normal_case); | |
2913 | |
2914 // Calculate the bit position of the 1-bit we are looking for. All lower | |
2915 // bits must be zero. | |
2916 __ rsb(scratch3, scratch3, Operand(HeapNumber::kMantissaBitsInTopWord - 1)); | |
2917 __ jmp(&test); | |
2918 | |
2919 __ bind(&lower_word); | |
2920 // Calculate the bit position of the 1-bit we are looking for. All lower | |
2921 // bits must be zero. Copy lower word into higher word register for the | |
2922 // test code below. | |
2923 __ rsb(scratch3, scratch3, Operand(HeapNumber::kMantissaBits - 1)); | |
2924 __ mov(scratch1, scratch2); | |
2925 | |
2926 __ bind(&test); | |
2927 // Test the bit. | |
2928 __ mov(scratch2, Operand(1)); | |
2929 __ mov(scratch3, Operand(scratch2, LSL, scratch3)); | |
2930 __ tst(scratch1, scratch3); | |
2931 __ b(eq, &normal_case); | |
2932 | |
2933 // Test the rest of the mantissa in the high word. | |
2934 __ sub(scratch3, scratch3, Operand(1)); | |
2935 __ tst(scratch1, scratch3); | |
2936 __ b(ne, &normal_case); | |
2937 | |
2938 // We have to round to the higher number, so we add 0.5 and jump to | |
2939 // the normal case. | |
Lasse Reichstein
2011/04/14 19:09:04
If you are going to add 0.5 and round in half the
| |
2940 ExternalReference one_half_adr = ExternalReference::address_of_one_half(); | |
2941 __ mov(scratch1, Operand(one_half_adr)); | |
2942 __ vldr(double_scratch0(), MemOperand(scratch1)); | |
2943 __ vadd(input, input, double_scratch0()); | |
2944 __ jmp(&normal_case); | |
2945 | |
2946 __ bind(&one_half); | |
2947 // Check for the special case of +0.5 and -0.5: The mantissa | |
2948 // bits must be all zero. | |
2949 __ tst(scratch1, Operand(HeapNumber::kMantissaMask)); | |
2950 __ b(ne, &normal_case); | |
2951 __ cmp(scratch2, Operand(0)); | |
2952 __ b(ne, &normal_case); | |
2953 __ tst(scratch1, Operand(HeapNumber::kSignMask)); | |
2954 __ mov(result, Operand(1), LeaveCC, eq); | |
2955 __ b(&done, eq); | |
2956 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { | |
2957 DeoptimizeIf(ne, instr->environment()); | |
2958 } else { | |
2959 __ mov(result, Operand(0)); | |
2960 __ jmp(&done); | |
2961 } | |
2962 | |
2963 __ bind(&normal_case); | |
2866 __ EmitVFPTruncate(kRoundToNearest, | 2964 __ EmitVFPTruncate(kRoundToNearest, |
2867 double_scratch0().low(), | 2965 double_scratch0().low(), |
2868 input, | 2966 input, |
2869 scratch1, | 2967 scratch1, |
2870 scratch2); | 2968 scratch2); |
2871 DeoptimizeIf(ne, instr->environment()); | 2969 DeoptimizeIf(ne, instr->environment()); |
2872 __ vmov(result, double_scratch0().low()); | 2970 __ vmov(result, double_scratch0().low()); |
2873 | 2971 |
2972 __ bind(&adjust_sign_on_zero); | |
2874 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { | 2973 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { |
2875 // Test for -0. | 2974 // Test for -0. |
2876 Label done; | |
2877 __ cmp(result, Operand(0)); | 2975 __ cmp(result, Operand(0)); |
2878 __ b(ne, &done); | 2976 __ b(ne, &done); |
2879 __ vmov(scratch1, input.high()); | 2977 __ vmov(scratch1, input.high()); |
2880 __ tst(scratch1, Operand(HeapNumber::kSignMask)); | 2978 __ tst(scratch1, Operand(HeapNumber::kSignMask)); |
2881 DeoptimizeIf(ne, instr->environment()); | 2979 DeoptimizeIf(ne, instr->environment()); |
2882 __ bind(&done); | |
2883 } | 2980 } |
2981 __ bind(&done); | |
2884 } | 2982 } |
2885 | 2983 |
2886 | 2984 |
2887 void LCodeGen::DoMathSqrt(LUnaryMathOperation* instr) { | 2985 void LCodeGen::DoMathSqrt(LUnaryMathOperation* instr) { |
2888 DoubleRegister input = ToDoubleRegister(instr->InputAt(0)); | 2986 DoubleRegister input = ToDoubleRegister(instr->InputAt(0)); |
2889 ASSERT(ToDoubleRegister(instr->result()).is(input)); | 2987 ASSERT(ToDoubleRegister(instr->result()).is(input)); |
2890 __ vsqrt(input, input); | 2988 __ vsqrt(input, input); |
2891 } | 2989 } |
2892 | 2990 |
2893 | 2991 |
(...skipping 1304 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4198 ASSERT(!environment->HasBeenRegistered()); | 4296 ASSERT(!environment->HasBeenRegistered()); |
4199 RegisterEnvironmentForDeoptimization(environment); | 4297 RegisterEnvironmentForDeoptimization(environment); |
4200 ASSERT(osr_pc_offset_ == -1); | 4298 ASSERT(osr_pc_offset_ == -1); |
4201 osr_pc_offset_ = masm()->pc_offset(); | 4299 osr_pc_offset_ = masm()->pc_offset(); |
4202 } | 4300 } |
4203 | 4301 |
4204 | 4302 |
4205 #undef __ | 4303 #undef __ |
4206 | 4304 |
4207 } } // namespace v8::internal | 4305 } } // namespace v8::internal |
OLD | NEW |