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

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

Issue 6840051: ARM: Implement correct rounding in the lithium codegenerator. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Minor edits. Created 9 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 | « src/arm/lithium-arm.cc ('k') | test/mjsunit/mjsunit.status » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 2843 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
OLDNEW
« no previous file with comments | « src/arm/lithium-arm.cc ('k') | test/mjsunit/mjsunit.status » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698