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 10382033: x86/x64 port of Math.floor(x/y) to use integer division for specific divisor (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 8 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
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 864 matching lines...) Expand 10 before | Expand all | Expand 10 after
875 __ jmp(&done, Label::kNear); 875 __ jmp(&done, Label::kNear);
876 876
877 __ bind(&remainder_eq_dividend); 877 __ bind(&remainder_eq_dividend);
878 __ movl(result_reg, left_reg); 878 __ movl(result_reg, left_reg);
879 879
880 __ bind(&done); 880 __ bind(&done);
881 } 881 }
882 } 882 }
883 883
884 884
885 void LCodeGen::DoMathFloorOfDiv(LMathFloorOfDiv* instr) {
886 ASSERT(instr->InputAt(1)->IsConstantOperand());
887
888 const Register dividend = ToRegister(instr->InputAt(0));
889 int32_t divisor = ToInteger32(LConstantOperand::cast(instr->InputAt(1)));
890 const Register result = ToRegister(instr->result());
891
892 switch (divisor) {
893 case 0:
894 DeoptimizeIf(no_condition, instr->environment());
895 return;
896
897 case 1:
898 if (!result.is(dividend)) {
899 __ movl(result, dividend);
900 }
901 return;
902
903 case -1:
904 if (!result.is(dividend)) {
905 __ movl(result, dividend);
906 }
907 __ negl(result);
908 // FIXME: set & check HValue::kBailoutOnMinusZero
Yang 2012/06/19 15:41:38 Any changes here?
909 DeoptimizeIf(zero, instr->environment());
910 if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) {
911 DeoptimizeIf(overflow, instr->environment());
912 }
913 return;
914 }
915
916 uint32_t divisor_abs = abs(divisor);
917 if (IsPowerOf2(divisor_abs)) {
918 int32_t power = WhichPowerOf2(divisor_abs);
919 if (divisor < 0) {
920 __ movsxlq(result, dividend);
921 __ neg(result);
922 // FIXME: set & check HValue::kBailoutOnMinusZero
Yang 2012/06/19 15:41:38 Ditto.
923 DeoptimizeIf(zero, instr->environment());
924 __ sar(result, Immediate(power));
925 } else {
926 if (!result.is(dividend)) {
927 __ movl(result, dividend);
928 }
929 __ sarl(result, Immediate(power));
930 }
931 } else {
932 Register reg1 = ToRegister(instr->TempAt(0));
933 Register reg2 = ToRegister(instr->result());
934
935 // b: 2^b < divisor_abs < 2^(b+1)
936 unsigned b = 31 - CompilerIntrinsics::CountLeadingZeros(divisor_abs);
937 unsigned shift = 32 + b; // precision +1bit (effectively)
938 double multiplier_f = static_cast<double>((uint64_t)1 << shift)
Yang 2012/06/19 15:41:38 Use static_cast please.
939 / divisor_abs;
940 int64_t multiplier;
941 if (multiplier_f - floor(multiplier_f) < 0.5) {
942 multiplier = floor(multiplier_f);
943 } else {
944 multiplier = floor(multiplier_f) + 1;
945 }
946 // multiplier is a uint32
947 ASSERT(multiplier > 0 && multiplier < ((int64_t)1<<32));
Yang 2012/06/19 15:41:38 Use static_cast please.
948 // the multiply is int64, so sign-extend to r64
949 __ movsxlq(reg1, dividend);
950 if (divisor < 0) {
951 __ neg(reg1);
952 // FIXME: set & check HValue::kBailoutOnMinusZero
Yang 2012/06/19 15:41:38 Ditto.
953 DeoptimizeIf(zero, instr->environment());
954 }
955 __ movq(reg2, multiplier, RelocInfo::NONE);
956 // result just fit in r64: because it's int32 * uint32
957 __ imul(reg2, reg1);
958
959 __ addq(reg2, Immediate(1<<30)); // effectively +1/2d
960 __ sar(reg2, Immediate(shift));
961 }
962 }
963
964
885 void LCodeGen::DoDivI(LDivI* instr) { 965 void LCodeGen::DoDivI(LDivI* instr) {
886 LOperand* right = instr->InputAt(1); 966 LOperand* right = instr->InputAt(1);
887 ASSERT(ToRegister(instr->result()).is(rax)); 967 ASSERT(ToRegister(instr->result()).is(rax));
888 ASSERT(ToRegister(instr->InputAt(0)).is(rax)); 968 ASSERT(ToRegister(instr->InputAt(0)).is(rax));
889 ASSERT(!ToRegister(instr->InputAt(1)).is(rax)); 969 ASSERT(!ToRegister(instr->InputAt(1)).is(rax));
890 ASSERT(!ToRegister(instr->InputAt(1)).is(rdx)); 970 ASSERT(!ToRegister(instr->InputAt(1)).is(rdx));
891 971
892 Register left_reg = rax; 972 Register left_reg = rax;
893 973
894 // Check for x / 0. 974 // Check for x / 0.
(...skipping 3916 matching lines...) Expand 10 before | Expand all | Expand 10 after
4811 FixedArray::kHeaderSize - kPointerSize)); 4891 FixedArray::kHeaderSize - kPointerSize));
4812 __ bind(&done); 4892 __ bind(&done);
4813 } 4893 }
4814 4894
4815 4895
4816 #undef __ 4896 #undef __
4817 4897
4818 } } // namespace v8::internal 4898 } } // namespace v8::internal
4819 4899
4820 #endif // V8_TARGET_ARCH_X64 4900 #endif // V8_TARGET_ARCH_X64
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698