From: lrn@chromium.org Date: Fri, 12 Feb 2010 13:37:10 +0000 (+0000) Subject: Added optimization for div/mod by constant power of 2. X-Git-Tag: upstream/4.7.83~22496 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=2e6ab729efd29865b09b5b1da350a2bc0aa2b1fe;p=platform%2Fupstream%2Fv8.git Added optimization for div/mod by constant power of 2. Review URL: http://codereview.chromium.org/597059 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@3844 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- diff --git a/src/ia32/codegen-ia32.cc b/src/ia32/codegen-ia32.cc index 9d7319c..9fbdbf6 100644 --- a/src/ia32/codegen-ia32.cc +++ b/src/ia32/codegen-ia32.cc @@ -1848,6 +1848,39 @@ Result CodeGenerator::ConstantSmiBinaryOperation(Token::Value op, break; } + case Token::DIV: + if (!reversed && int_value == 2) { + operand->ToRegister(); + frame_->Spill(operand->reg()); + + DeferredInlineSmiOperation* deferred = + new DeferredInlineSmiOperation(op, + operand->reg(), + operand->reg(), + smi_value, + overwrite_mode); + // Check that lowest log2(value) bits of operand are zero, and test + // smi tag at the same time. + ASSERT_EQ(0, kSmiTag); + ASSERT_EQ(1, kSmiTagSize); + __ test(operand->reg(), Immediate(3)); + deferred->Branch(not_zero); // Branch if non-smi or odd smi. + __ sar(operand->reg(), 1); + deferred->BindExit(); + answer = *operand; + } else { + // Cannot fall through MOD to default case, so we duplicate the + // default case here. + Result constant_operand(value); + if (reversed) { + answer = LikelySmiBinaryOperation(op, &constant_operand, operand, + overwrite_mode); + } else { + answer = LikelySmiBinaryOperation(op, operand, &constant_operand, + overwrite_mode); + } + } + break; // Generate inline code for mod of powers of 2 and negative powers of 2. case Token::MOD: if (!reversed && diff --git a/test/mjsunit/div-mod.js b/test/mjsunit/div-mod.js index b3c77e1..1d352b5 100644 --- a/test/mjsunit/div-mod.js +++ b/test/mjsunit/div-mod.js @@ -154,4 +154,18 @@ function compute_mod(dividend, divisor) { doTest(-a,-b); } } -})() +})(); + + +(function () { + // Edge cases + var zero = 0; + var minsmi32 = -0x40000000; + var minsmi64 = -0x80000000; + var somenum = 3532; + assertEquals(-0, zero / -1, "0 / -1"); + assertEquals(1, minsmi32 / -0x40000000, "minsmi/minsmi-32"); + assertEquals(1, minsmi64 / -0x80000000, "minsmi/minsmi-64"); + assertEquals(somenum, somenum % -0x40000000, "%minsmi-32"); + assertEquals(somenum, somenum % -0x80000000, "%minsmi-64"); +})();