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

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

Issue 6816049: Improve modulo operation in lithium on IA32. (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 __ and_(dividend, divisor - 1); 792 __ and_(dividend, divisor - 1);
793 __ neg(dividend); 793 __ neg(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 __ and_(dividend, divisor - 1); 799 __ and_(dividend, 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 ASSERT(ToRegister(instr->InputAt(0)).is(eax)); 803 Register left_reg = ToRegister(instr->InputAt(0));
804 ASSERT(ToRegister(instr->result()).is(edx)); 804 Register right_reg = ToRegister(instr->InputAt(1));
805 Register result_reg = ToRegister(instr->result());
805 806
806 Register right_reg = ToRegister(right); 807 ASSERT(left_reg.is(eax));
808 ASSERT(result_reg.is(edx));
807 ASSERT(!right_reg.is(eax)); 809 ASSERT(!right_reg.is(eax));
808 ASSERT(!right_reg.is(edx)); 810 ASSERT(!right_reg.is(edx));
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 __ test(right_reg, ToOperand(right)); 814 __ test(right_reg, Operand(right_reg));
813 DeoptimizeIf(zero, instr->environment()); 815 DeoptimizeIf(zero, instr->environment());
814 } 816 }
815 817
818 __ test(left_reg, Operand(left_reg));
819 __ j(zero, &remainder_eq_dividend);
820 __ j(sign, &slow);
821
822 __ test(right_reg, Operand(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 __ cmp(left_reg, Operand(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 __ mov(scratch, right_reg);
836 __ sub(Operand(scratch), Immediate(1));
837 __ test(scratch, Operand(right_reg));
838 __ j(not_zero, &do_subtraction);
839 __ and_(left_reg, Operand(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 __ mov(scratch, left_reg);
846 for (int i = 0; i < kUnfolds; i++) {
847 // Reduce the dividend by the divisor.
848 __ sub(left_reg, Operand(right_reg));
849 // Check if the dividend is less than the divisor.
850 __ cmp(left_reg, Operand(right_reg));
851 __ j(less, &remainder_eq_dividend);
852 }
853 __ mov(left_reg, scratch);
854
855 // Slow case, using idiv instruction.
856 __ bind(&slow);
816 // Sign extend to edx. 857 // Sign extend to edx.
817 __ cdq(); 858 __ cdq();
818 859
819 // Check for (0 % -x) that will produce negative zero. 860 // Check for (0 % -x) that will produce negative zero.
820 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 861 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
821 NearLabel positive_left; 862 NearLabel positive_left;
822 NearLabel done; 863 NearLabel done;
823 __ test(eax, Operand(eax)); 864 __ test(left_reg, Operand(left_reg));
824 __ j(not_sign, &positive_left); 865 __ j(not_sign, &positive_left);
825 __ idiv(right_reg); 866 __ idiv(right_reg);
826 867
827 // Test the remainder for 0, because then the result would be -0. 868 // Test the remainder for 0, because then the result would be -0.
828 __ test(edx, Operand(edx)); 869 __ test(result_reg, Operand(result_reg));
829 __ j(not_zero, &done); 870 __ j(not_zero, &done);
830 871
831 DeoptimizeIf(no_condition, instr->environment()); 872 DeoptimizeIf(no_condition, instr->environment());
832 __ bind(&positive_left); 873 __ bind(&positive_left);
833 __ idiv(right_reg); 874 __ idiv(right_reg);
834 __ bind(&done); 875 __ bind(&done);
835 } else { 876 } else {
836 __ idiv(right_reg); 877 __ idiv(right_reg);
837 } 878 }
879 __ jmp(&done);
880
881 __ bind(&remainder_eq_dividend);
882 __ mov(result_reg, left_reg);
883
884 __ bind(&done);
838 } 885 }
839 } 886 }
840 887
841 888
842 void LCodeGen::DoDivI(LDivI* instr) { 889 void LCodeGen::DoDivI(LDivI* instr) {
843 LOperand* right = instr->InputAt(1); 890 LOperand* right = instr->InputAt(1);
844 ASSERT(ToRegister(instr->result()).is(eax)); 891 ASSERT(ToRegister(instr->result()).is(eax));
845 ASSERT(ToRegister(instr->InputAt(0)).is(eax)); 892 ASSERT(ToRegister(instr->InputAt(0)).is(eax));
846 ASSERT(!ToRegister(instr->InputAt(1)).is(eax)); 893 ASSERT(!ToRegister(instr->InputAt(1)).is(eax));
847 ASSERT(!ToRegister(instr->InputAt(1)).is(edx)); 894 ASSERT(!ToRegister(instr->InputAt(1)).is(edx));
(...skipping 3402 matching lines...) Expand 10 before | Expand all | Expand 10 after
4250 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); 4297 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
4251 __ InvokeBuiltin(Builtins::IN, CALL_FUNCTION, &safepoint_generator); 4298 __ InvokeBuiltin(Builtins::IN, CALL_FUNCTION, &safepoint_generator);
4252 } 4299 }
4253 4300
4254 4301
4255 #undef __ 4302 #undef __
4256 4303
4257 } } // namespace v8::internal 4304 } } // namespace v8::internal
4258 4305
4259 #endif // V8_TARGET_ARCH_IA32 4306 #endif // V8_TARGET_ARCH_IA32
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