Revision: 3844
Author: [email protected]
Date: Fri Feb 12 05:37:10 2010
Log: Added optimization for div/mod by constant power of 2.
Review URL: http://codereview.chromium.org/597059
http://code.google.com/p/v8/source/detail?r=3844
Modified:
/branches/bleeding_edge/src/ia32/codegen-ia32.cc
/branches/bleeding_edge/test/mjsunit/div-mod.js
=======================================
--- /branches/bleeding_edge/src/ia32/codegen-ia32.cc Fri Feb 12 03:55:04
2010
+++ /branches/bleeding_edge/src/ia32/codegen-ia32.cc Fri Feb 12 05:37:10
2010
@@ -1848,6 +1848,39 @@
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 &&
=======================================
--- /branches/bleeding_edge/test/mjsunit/div-mod.js Fri Oct 23 02:18:19 2009
+++ /branches/bleeding_edge/test/mjsunit/div-mod.js Fri Feb 12 05:37:10 2010
@@ -154,4 +154,18 @@
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");
+})();
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev