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

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

Issue 7628017: Add roundsd instruction to ia32 and use it in optimized Math.floor. (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 9 years, 4 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 2695 matching lines...) Expand 10 before | Expand all | Expand 10 after
2706 EmitIntegerMathAbs(instr); 2706 EmitIntegerMathAbs(instr);
2707 __ bind(deferred->exit()); 2707 __ bind(deferred->exit());
2708 } 2708 }
2709 } 2709 }
2710 2710
2711 2711
2712 void LCodeGen::DoMathFloor(LUnaryMathOperation* instr) { 2712 void LCodeGen::DoMathFloor(LUnaryMathOperation* instr) {
2713 XMMRegister xmm_scratch = xmm0; 2713 XMMRegister xmm_scratch = xmm0;
2714 Register output_reg = ToRegister(instr->result()); 2714 Register output_reg = ToRegister(instr->result());
2715 XMMRegister input_reg = ToDoubleRegister(instr->value()); 2715 XMMRegister input_reg = ToDoubleRegister(instr->value());
2716 Label done;
2717 2716
2718 // Deoptimize on negative numbers. 2717 if (CpuFeatures::IsSupported(SSE4_1)) {
2719 __ xorps(xmm_scratch, xmm_scratch); // Zero the register. 2718 CpuFeatures::Scope scope(SSE4_1);
2720 __ ucomisd(input_reg, xmm_scratch); 2719 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
2721 DeoptimizeIf(below, instr->environment()); 2720 // Deoptimize on negative zero.
Sven Panne 2011/08/12 09:41:40 Why do we have to deoptimize on -0 when using roun
2721 Label non_zero;
2722 __ xorps(xmm_scratch, xmm_scratch); // Zero the register.
2723 __ ucomisd(input_reg, xmm_scratch);
2724 __ j(not_equal, &non_zero, Label::kNear);
2725 __ movmskpd(output_reg, input_reg);
2726 __ test(output_reg, Immediate(1));
2727 DeoptimizeIf(not_zero, instr->environment());
2728 __ bind(&non_zero);
2729 }
2730 __ roundsd(xmm_scratch, input_reg, Assembler::kRoundDown);
2731 __ cvttsd2si(output_reg, Operand(xmm_scratch));
2732 // Overflow is signalled with minint.
2733 __ cmp(output_reg, 0x80000000u);
2734 DeoptimizeIf(equal, instr->environment());
2735 } else {
2736 Label done;
2737 // Deoptimize on negative numbers.
2738 __ xorps(xmm_scratch, xmm_scratch); // Zero the register.
2739 __ ucomisd(input_reg, xmm_scratch);
2740 DeoptimizeIf(below, instr->environment());
2722 2741
2723 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 2742 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
2724 // Check for negative zero. 2743 // Check for negative zero.
2725 Label positive_sign; 2744 Label positive_sign;
2726 __ j(above, &positive_sign, Label::kNear); 2745 __ j(above, &positive_sign, Label::kNear);
2727 __ movmskpd(output_reg, input_reg); 2746 __ movmskpd(output_reg, input_reg);
2728 __ test(output_reg, Immediate(1)); 2747 __ test(output_reg, Immediate(1));
2729 DeoptimizeIf(not_zero, instr->environment()); 2748 DeoptimizeIf(not_zero, instr->environment());
2730 __ Set(output_reg, Immediate(0)); 2749 __ Set(output_reg, Immediate(0));
2731 __ jmp(&done, Label::kNear); 2750 __ jmp(&done, Label::kNear);
2732 __ bind(&positive_sign); 2751 __ bind(&positive_sign);
2752 }
2753
2754 // Use truncating instruction (OK because input is positive).
2755 __ cvttsd2si(output_reg, Operand(input_reg));
2756
2757 // Overflow is signalled with minint.
2758 __ cmp(output_reg, 0x80000000u);
2759 DeoptimizeIf(equal, instr->environment());
2760 __ bind(&done);
2733 } 2761 }
2734
2735 // Use truncating instruction (OK because input is positive).
2736 __ cvttsd2si(output_reg, Operand(input_reg));
2737
2738 // Overflow is signalled with minint.
2739 __ cmp(output_reg, 0x80000000u);
2740 DeoptimizeIf(equal, instr->environment());
2741 __ bind(&done);
2742 } 2762 }
2743 2763
2744
2745 void LCodeGen::DoMathRound(LUnaryMathOperation* instr) { 2764 void LCodeGen::DoMathRound(LUnaryMathOperation* instr) {
2746 XMMRegister xmm_scratch = xmm0; 2765 XMMRegister xmm_scratch = xmm0;
2747 Register output_reg = ToRegister(instr->result()); 2766 Register output_reg = ToRegister(instr->result());
2748 XMMRegister input_reg = ToDoubleRegister(instr->value()); 2767 XMMRegister input_reg = ToDoubleRegister(instr->value());
2749 2768
2750 Label below_half, done; 2769 Label below_half, done;
2751 // xmm_scratch = 0.5 2770 // xmm_scratch = 0.5
2752 ExternalReference one_half = ExternalReference::address_of_one_half(); 2771 ExternalReference one_half = ExternalReference::address_of_one_half();
2753 __ movdbl(xmm_scratch, Operand::StaticVariable(one_half)); 2772 __ movdbl(xmm_scratch, Operand::StaticVariable(one_half));
2754
2755 __ ucomisd(xmm_scratch, input_reg); 2773 __ ucomisd(xmm_scratch, input_reg);
2756 __ j(above, &below_half); 2774 __ j(above, &below_half);
2757 // input = input + 0.5 2775 // input = input + 0.5
2758 __ addsd(input_reg, xmm_scratch); 2776 __ addsd(input_reg, xmm_scratch);
2759 2777
2760
2761 // Compute Math.floor(value + 0.5). 2778 // Compute Math.floor(value + 0.5).
2762 // Use truncating instruction (OK because input is positive). 2779 // Use truncating instruction (OK because input is positive).
2763 __ cvttsd2si(output_reg, Operand(input_reg)); 2780 __ cvttsd2si(output_reg, Operand(input_reg));
2764 2781
2765 // Overflow is signalled with minint. 2782 // Overflow is signalled with minint.
2766 __ cmp(output_reg, 0x80000000u); 2783 __ cmp(output_reg, 0x80000000u);
2767 DeoptimizeIf(equal, instr->environment()); 2784 DeoptimizeIf(equal, instr->environment());
2768 __ jmp(&done); 2785 __ jmp(&done);
2769 2786
2770 __ bind(&below_half); 2787 __ bind(&below_half);
(...skipping 1602 matching lines...) Expand 10 before | Expand all | Expand 10 after
4373 env->deoptimization_index()); 4390 env->deoptimization_index());
4374 __ InvokeBuiltin(Builtins::IN, CALL_FUNCTION, safepoint_generator); 4391 __ InvokeBuiltin(Builtins::IN, CALL_FUNCTION, safepoint_generator);
4375 } 4392 }
4376 4393
4377 4394
4378 #undef __ 4395 #undef __
4379 4396
4380 } } // namespace v8::internal 4397 } } // namespace v8::internal
4381 4398
4382 #endif // V8_TARGET_ARCH_IA32 4399 #endif // V8_TARGET_ARCH_IA32
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698