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

Unified Diff: src/ia32/lithium-codegen-ia32.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 side-by-side diff with in-line comments
Download patch
Index: src/ia32/lithium-codegen-ia32.cc
===================================================================
--- src/ia32/lithium-codegen-ia32.cc (revision 11554)
+++ src/ia32/lithium-codegen-ia32.cc (working copy)
@@ -963,6 +963,106 @@
}
+void LCodeGen::DoMathFloorOfDiv(LMathFloorOfDiv* instr) {
+ ASSERT(instr->InputAt(1)->IsConstantOperand());
+
+ Register dividend = ToRegister(instr->InputAt(0));
+ int32_t divisor = ToInteger32(LConstantOperand::cast(instr->InputAt(1)));
+ Register result = ToRegister(instr->result());
+
+ switch (divisor) {
+ case 0:
+ DeoptimizeIf(no_condition, instr->environment());
+ return;
+
+ case 1:
+ __ Move(result, dividend);
+ return;
+
+ case -1:
+ __ Move(result, dividend);
+ __ neg(result);
+ // FIXME: set & check HValue::kBailoutOnMinusZero
Yang 2012/06/19 15:41:38 Is this going to be fixed?
+ DeoptimizeIf(zero, instr->environment());
+ if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) {
+ DeoptimizeIf(overflow, instr->environment());
+ }
+ return;
+ }
+
+ uint32_t divisor_abs = abs(divisor);
+ if (IsPowerOf2(divisor_abs)) {
+ int32_t power = WhichPowerOf2(divisor_abs);
+ if (divisor < 0) {
+ // input[dividend] is clobbered
+ // tedious because neg(dividend) might overflow
Yang 2012/06/19 15:41:38 Comments should start with capital letter and end
+ __ mov(result, dividend);
+ __ sar(dividend, 31);
+ __ neg(result);
+ // FIXME: set & check HValue::kBailoutOnMinusZero
+ DeoptimizeIf(zero, instr->environment());
+ __ shl(dividend, 32 - power);
+ __ sar(result, power);
+ __ not_(dividend);
+ // clear result.sign if dividend.sign
+ __ and_(result, dividend);
+ } else {
+ __ Move(result, dividend);
+ __ sar(result, power);
+ }
+ } else {
+ ASSERT(ToRegister(instr->InputAt(0)).is(eax));
+ ASSERT(ToRegister(instr->result()).is(edx));
+ Register scratch = ToRegister(instr->TempAt(0));
+
+ // b: 2^b < divisor_abs < 2^(b+1)
+ unsigned b = 31 - CompilerIntrinsics::CountLeadingZeros(divisor_abs);
+ unsigned shift = 32 + b; // precision +1bit (effectively)
+ double multiplier_f = static_cast<double>((uint64_t)1 << shift)
Yang 2012/06/19 15:41:38 Use static_cast please.
+ / divisor_abs;
+ int64_t multiplier;
+ if (multiplier_f - floor(multiplier_f) < 0.5) {
+ multiplier = floor(multiplier_f);
+ } else {
+ multiplier = floor(multiplier_f) + 1;
+ }
+ // multiplier is a uint32
+ ASSERT(multiplier > 0 && multiplier < ((int64_t)1<<32));
Yang 2012/06/19 15:41:38 Use static_cast please.
+ __ mov(scratch, dividend);
+ // FIXME: set & check HValue::kBailoutOnMinusZero
Yang 2012/06/19 15:41:38 Same here.
+ if (divisor < 0) {
+ __ test(dividend, dividend);
+ DeoptimizeIf(zero, instr->environment());
+ }
+ __ mov(edx, multiplier);
+ __ imul(edx);
+ if ((int32_t)multiplier < 0) {
Yang 2012/06/19 15:41:38 Use static_cast please.
+ __ add(edx, scratch);
+ }
+ Register reg_lo = eax;
+ Register reg_byte_scratch = scratch;
+ if (!reg_byte_scratch.is_byte_register()) {
+ __ xchg(reg_lo, reg_byte_scratch);
+ reg_lo = scratch;
+ reg_byte_scratch = eax;
+ }
+ if (divisor < 0) {
+ __ xor_(reg_byte_scratch, reg_byte_scratch);
+ __ cmp(reg_lo, 0x40000000);
+ __ setcc(above, reg_byte_scratch);
+ __ neg(edx);
+ __ sub(edx, reg_byte_scratch);
+ } else {
+ __ xor_(reg_byte_scratch, reg_byte_scratch);
+ __ cmp(reg_lo, 0xC0000000);
+ __ setcc(above_equal, reg_byte_scratch);
+ __ add(edx, reg_byte_scratch);
+ }
+ __ sar(edx, shift - 32);
+ }
+}
+
+
void LCodeGen::DoMulI(LMulI* instr) {
Register left = ToRegister(instr->InputAt(0));
LOperand* right = instr->InputAt(1);
« no previous file with comments | « src/ia32/disasm-ia32.cc ('k') | src/ia32/lithium-ia32.h » ('j') | src/x64/lithium-codegen-x64.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698