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

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

Issue 6901091: Improve modulo operation in lithium on x64. (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 9 years, 7 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 | « no previous file | no next file » | 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 781 matching lines...) Expand 10 before | Expand all | Expand 10 after
792 __ andl(dividend, Immediate(divisor - 1)); 792 __ andl(dividend, Immediate(divisor - 1));
793 __ negl(dividend); 793 __ negl(dividend);
794 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 794 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
795 __ j(not_zero, &done); 795 __ j(not_zero, &done);
796 DeoptimizeIf(no_condition, instr->environment()); 796 DeoptimizeIf(no_condition, instr->environment());
797 } 797 }
798 __ bind(&positive_dividend); 798 __ bind(&positive_dividend);
799 __ andl(dividend, Immediate(divisor - 1)); 799 __ andl(dividend, Immediate(divisor - 1));
800 __ bind(&done); 800 __ bind(&done);
801 } else { 801 } else {
802 LOperand* right = instr->InputAt(1); 802 NearLabel done, remainder_eq_dividend, slow, do_subtraction, both_positive;
803 Register right_reg = ToRegister(right); 803 Register left_reg = ToRegister(instr->InputAt(0));
804 Register right_reg = ToRegister(instr->InputAt(1));
805 Register result_reg = ToRegister(instr->result());
804 806
805 ASSERT(ToRegister(instr->result()).is(rdx)); 807 ASSERT(left_reg.is(rax));
806 ASSERT(ToRegister(instr->InputAt(0)).is(rax)); 808 ASSERT(result_reg.is(rdx));
807 ASSERT(!right_reg.is(rax)); 809 ASSERT(!right_reg.is(rax));
808 ASSERT(!right_reg.is(rdx)); 810 ASSERT(!right_reg.is(rdx));
809 811
810 // Check for x % 0. 812 // Check for x % 0.
811 if (instr->hydrogen()->CheckFlag(HValue::kCanBeDivByZero)) { 813 if (instr->hydrogen()->CheckFlag(HValue::kCanBeDivByZero)) {
812 __ testl(right_reg, right_reg); 814 __ testl(right_reg, right_reg);
813 DeoptimizeIf(zero, instr->environment()); 815 DeoptimizeIf(zero, instr->environment());
814 } 816 }
815 817
818 __ testl(left_reg, left_reg);
819 __ j(zero, &remainder_eq_dividend);
820 __ j(sign, &slow);
821
822 __ testl(right_reg, right_reg);
823 __ j(not_sign, &both_positive);
824 // The sign of the divisor doesn't matter.
825 __ neg(right_reg);
826
827 __ bind(&both_positive);
828 // If the dividend is smaller than the nonnegative
829 // divisor, the dividend is the result.
830 __ cmpl(left_reg, right_reg);
831 __ j(less, &remainder_eq_dividend);
832
833 // Check if the divisor is a PowerOfTwo integer.
834 Register scratch = ToRegister(instr->TempAt(0));
835 __ movl(scratch, right_reg);
836 __ subl(scratch, Immediate(1));
837 __ testl(scratch, right_reg);
838 __ j(not_zero, &do_subtraction);
839 __ andl(left_reg, scratch);
840 __ jmp(&remainder_eq_dividend);
841
842 __ bind(&do_subtraction);
843 const int kUnfolds = 3;
844 // Try a few subtractions of the dividend.
845 __ movl(scratch, left_reg);
846 for (int i = 0; i < kUnfolds; i++) {
847 // Reduce the dividend by the divisor.
848 __ subl(left_reg, right_reg);
849 // Check if the dividend is less than the divisor.
850 __ cmpl(left_reg, right_reg);
851 __ j(less, &remainder_eq_dividend);
852 }
853 __ movl(left_reg, scratch);
854
855 // Slow case, using idiv instruction.
856 __ bind(&slow);
816 // Sign extend eax to edx. 857 // Sign extend eax to edx.
817 // (We are using only the low 32 bits of the values.) 858 // (We are using only the low 32 bits of the values.)
818 __ cdq(); 859 __ cdq();
819 860
820 // Check for (0 % -x) that will produce negative zero. 861 // Check for (0 % -x) that will produce negative zero.
821 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 862 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
822 NearLabel positive_left; 863 NearLabel positive_left;
823 NearLabel done; 864 NearLabel done;
824 __ testl(rax, rax); 865 __ testl(left_reg, left_reg);
825 __ j(not_sign, &positive_left); 866 __ j(not_sign, &positive_left);
826 __ idivl(right_reg); 867 __ idivl(right_reg);
827 868
828 // Test the remainder for 0, because then the result would be -0. 869 // Test the remainder for 0, because then the result would be -0.
829 __ testl(rdx, rdx); 870 __ testl(result_reg, result_reg);
830 __ j(not_zero, &done); 871 __ j(not_zero, &done);
831 872
832 DeoptimizeIf(no_condition, instr->environment()); 873 DeoptimizeIf(no_condition, instr->environment());
833 __ bind(&positive_left); 874 __ bind(&positive_left);
834 __ idivl(right_reg); 875 __ idivl(right_reg);
835 __ bind(&done); 876 __ bind(&done);
836 } else { 877 } else {
837 __ idivl(right_reg); 878 __ idivl(right_reg);
838 } 879 }
880 __ jmp(&done);
881
882 __ bind(&remainder_eq_dividend);
883 __ movl(result_reg, left_reg);
884
885 __ bind(&done);
839 } 886 }
840 } 887 }
841 888
842 889
843 void LCodeGen::DoDivI(LDivI* instr) { 890 void LCodeGen::DoDivI(LDivI* instr) {
844 LOperand* right = instr->InputAt(1); 891 LOperand* right = instr->InputAt(1);
845 ASSERT(ToRegister(instr->result()).is(rax)); 892 ASSERT(ToRegister(instr->result()).is(rax));
846 ASSERT(ToRegister(instr->InputAt(0)).is(rax)); 893 ASSERT(ToRegister(instr->InputAt(0)).is(rax));
847 ASSERT(!ToRegister(instr->InputAt(1)).is(rax)); 894 ASSERT(!ToRegister(instr->InputAt(1)).is(rax));
848 ASSERT(!ToRegister(instr->InputAt(1)).is(rdx)); 895 ASSERT(!ToRegister(instr->InputAt(1)).is(rdx));
(...skipping 3200 matching lines...) Expand 10 before | Expand all | Expand 10 after
4049 RegisterEnvironmentForDeoptimization(environment); 4096 RegisterEnvironmentForDeoptimization(environment);
4050 ASSERT(osr_pc_offset_ == -1); 4097 ASSERT(osr_pc_offset_ == -1);
4051 osr_pc_offset_ = masm()->pc_offset(); 4098 osr_pc_offset_ = masm()->pc_offset();
4052 } 4099 }
4053 4100
4054 #undef __ 4101 #undef __
4055 4102
4056 } } // namespace v8::internal 4103 } } // namespace v8::internal
4057 4104
4058 #endif // V8_TARGET_ARCH_X64 4105 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698