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

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

Issue 12342037: Handle negative input in inlined Math.round on Intel CPUs. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 7 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
« no previous file with comments | « src/assembler.cc ('k') | src/ia32/lithium-ia32.cc » ('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 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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 3716 matching lines...) Expand 10 before | Expand all | Expand 10 after
3727 __ j(equal, &done, Label::kNear); 3727 __ j(equal, &done, Label::kNear);
3728 __ sub(output_reg, Immediate(1)); 3728 __ sub(output_reg, Immediate(1));
3729 DeoptimizeIf(overflow, instr->environment()); 3729 DeoptimizeIf(overflow, instr->environment());
3730 3730
3731 __ bind(&done); 3731 __ bind(&done);
3732 } 3732 }
3733 } 3733 }
3734 3734
3735 void LCodeGen::DoMathRound(LUnaryMathOperation* instr) { 3735 void LCodeGen::DoMathRound(LUnaryMathOperation* instr) {
3736 CpuFeatures::Scope scope(SSE2); 3736 CpuFeatures::Scope scope(SSE2);
3737 XMMRegister xmm_scratch = xmm0;
3738 Register output_reg = ToRegister(instr->result()); 3737 Register output_reg = ToRegister(instr->result());
3739 XMMRegister input_reg = ToDoubleRegister(instr->value()); 3738 XMMRegister input_reg = ToDoubleRegister(instr->value());
3739 XMMRegister xmm_scratch = xmm0;
3740 ExternalReference one_half = ExternalReference::address_of_one_half();
3741 ExternalReference minus_one_half =
3742 ExternalReference::address_of_minus_one_half();
3743 bool minus_zero_check =
3744 instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero);
3740 3745
3741 Label below_half, done;
3742 // xmm_scratch = 0.5
3743 ExternalReference one_half = ExternalReference::address_of_one_half();
3744 __ movdbl(xmm_scratch, Operand::StaticVariable(one_half)); 3746 __ movdbl(xmm_scratch, Operand::StaticVariable(one_half));
3745 __ ucomisd(xmm_scratch, input_reg);
3746 __ j(above, &below_half);
3747 // xmm_scratch = input + 0.5
3748 __ addsd(xmm_scratch, input_reg);
3749 3747
3750 // Compute Math.floor(value + 0.5). 3748 if (CpuFeatures::IsSupported(SSE4_1) && !minus_zero_check) {
3751 // Use truncating instruction (OK because input is positive). 3749 CpuFeatures::Scope scope(SSE4_1);
3752 __ cvttsd2si(output_reg, Operand(xmm_scratch));
3753 3750
3754 // Overflow is signalled with minint. 3751 __ addsd(xmm_scratch, input_reg);
3755 __ cmp(output_reg, 0x80000000u); 3752 __ roundsd(xmm_scratch, input_reg, Assembler::kRoundDown);
3756 DeoptimizeIf(equal, instr->environment()); 3753 __ cvttsd2si(output_reg, Operand(xmm_scratch));
3757 __ jmp(&done); 3754 // Overflow is signalled with minint.
3755 __ cmp(output_reg, 0x80000000u);
3756 __ RecordComment("D2I conversion overflow");
3757 DeoptimizeIf(equal, instr->environment());
3758 } else {
3759 Label done, round_to_zero, below_one_half, do_not_compensate;
3760 __ ucomisd(xmm_scratch, input_reg);
3761 __ j(above, &below_one_half);
3758 3762
3759 __ bind(&below_half); 3763 // CVTTSD2SI rounds towards zero, since 0.5 <= x, we use floor(0.5 + x).
3764 __ addsd(xmm_scratch, input_reg);
3765 __ cvttsd2si(output_reg, Operand(xmm_scratch));
3766 // Overflow is signalled with minint.
3767 __ cmp(output_reg, 0x80000000u);
3768 __ RecordComment("D2I conversion overflow");
3769 DeoptimizeIf(equal, instr->environment());
3770 __ jmp(&done);
3760 3771
3761 // We return 0 for the input range [+0, 0.5[, or [-0.5, 0.5[ if 3772 __ bind(&below_one_half);
3762 // we can ignore the difference between a result of -0 and +0. 3773 __ movdbl(xmm_scratch, Operand::StaticVariable(minus_one_half));
3763 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 3774 __ ucomisd(xmm_scratch, input_reg);
3764 // If the sign is positive, we return +0. 3775 __ j(below_equal, &round_to_zero);
3765 __ movmskpd(output_reg, input_reg); 3776
3766 __ test(output_reg, Immediate(1)); 3777 // CVTTSD2SI rounds towards zero, we use ceil(x - (-0.5)) and then
3767 DeoptimizeIf(not_zero, instr->environment()); 3778 // compare and compensate.
3768 } else { 3779 __ subsd(input_reg, xmm_scratch);
3769 // If the input is >= -0.5, we return +0. 3780 __ cvttsd2si(output_reg, Operand(input_reg));
3770 __ mov(output_reg, Immediate(0xBF000000)); 3781 // Catch minint due to overflow, and to prevent overflow when compensating.
3771 __ movd(xmm_scratch, Operand(output_reg)); 3782 __ cmp(output_reg, 0x80000000u);
3772 __ cvtss2sd(xmm_scratch, xmm_scratch); 3783 __ RecordComment("D2I conversion overflow");
3773 __ ucomisd(input_reg, xmm_scratch); 3784 DeoptimizeIf(equal, instr->environment());
3774 DeoptimizeIf(below, instr->environment()); 3785
3786 __ cvtsi2sd(xmm_scratch, output_reg);
3787 __ ucomisd(xmm_scratch, input_reg);
3788 __ j(equal, &done);
3789 __ sub(output_reg, Immediate(1));
3790 // No overflow because we already ruled out minint.
3791 __ jmp(&done);
3792
3793 __ bind(&round_to_zero);
3794 // We return 0 for the input range [+0, 0.5[, or [-0.5, 0.5[ if
3795 // we can ignore the difference between a result of -0 and +0.
3796 if (minus_zero_check) {
3797 // If the sign is positive, we return +0.
3798 __ movmskpd(output_reg, input_reg);
3799 __ test(output_reg, Immediate(1));
3800 __ RecordComment("Minus zero");
3801 DeoptimizeIf(not_zero, instr->environment());
3802 }
3803 __ Set(output_reg, Immediate(0));
3804 __ bind(&done);
3775 } 3805 }
3776 __ Set(output_reg, Immediate(0));
3777 __ bind(&done);
3778 } 3806 }
3779 3807
3780 3808
3781 void LCodeGen::DoMathSqrt(LUnaryMathOperation* instr) { 3809 void LCodeGen::DoMathSqrt(LUnaryMathOperation* instr) {
3782 CpuFeatures::Scope scope(SSE2); 3810 CpuFeatures::Scope scope(SSE2);
3783 XMMRegister input_reg = ToDoubleRegister(instr->value()); 3811 XMMRegister input_reg = ToDoubleRegister(instr->value());
3784 ASSERT(ToDoubleRegister(instr->result()).is(input_reg)); 3812 ASSERT(ToDoubleRegister(instr->result()).is(input_reg));
3785 __ sqrtsd(input_reg, input_reg); 3813 __ sqrtsd(input_reg, input_reg);
3786 } 3814 }
3787 3815
(...skipping 2426 matching lines...) Expand 10 before | Expand all | Expand 10 after
6214 FixedArray::kHeaderSize - kPointerSize)); 6242 FixedArray::kHeaderSize - kPointerSize));
6215 __ bind(&done); 6243 __ bind(&done);
6216 } 6244 }
6217 6245
6218 6246
6219 #undef __ 6247 #undef __
6220 6248
6221 } } // namespace v8::internal 6249 } } // namespace v8::internal
6222 6250
6223 #endif // V8_TARGET_ARCH_IA32 6251 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/assembler.cc ('k') | src/ia32/lithium-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698