Diff
Modified: trunk/LayoutTests/ChangeLog (149158 => 149159)
--- trunk/LayoutTests/ChangeLog 2013-04-26 00:40:27 UTC (rev 149158)
+++ trunk/LayoutTests/ChangeLog 2013-04-26 00:41:38 UTC (rev 149159)
@@ -1,3 +1,31 @@
+2013-04-24 Oliver Hunt <[email protected]>
+
+ Add support for Math.imul
+ https://bugs.webkit.org/show_bug.cgi?id=115143
+
+ Reviewed by Filip Pizlo.
+
+ Add a bunch of tests for Math.imul
+
+ * fast/js/Object-getOwnPropertyNames-expected.txt:
+ * fast/js/imul-expected.txt: Added.
+ * fast/js/imul.html: Added.
+ * fast/js/regress/imul-double-only-expected.txt: Added.
+ * fast/js/regress/imul-double-only.html: Added.
+ * fast/js/regress/imul-int-only-expected.txt: Added.
+ * fast/js/regress/imul-int-only.html: Added.
+ * fast/js/regress/imul-mixed-expected.txt: Added.
+ * fast/js/regress/imul-mixed.html: Added.
+ * fast/js/regress/script-tests/imul-double-only.js: Added.
+ (f):
+ * fast/js/regress/script-tests/imul-int-only.js: Added.
+ (f):
+ * fast/js/regress/script-tests/imul-mixed.js: Added.
+ (f):
+ * fast/js/script-tests/Object-getOwnPropertyNames.js:
+ * fast/js/script-tests/imul.js: Added.
+ (testIMul):
+
2013-04-25 Chris Fleizach <[email protected]>
<meter> element not exposed to accessibility
Modified: trunk/LayoutTests/fast/js/Object-getOwnPropertyNames-expected.txt (149158 => 149159)
--- trunk/LayoutTests/fast/js/Object-getOwnPropertyNames-expected.txt 2013-04-26 00:40:27 UTC (rev 149158)
+++ trunk/LayoutTests/fast/js/Object-getOwnPropertyNames-expected.txt 2013-04-26 00:41:38 UTC (rev 149159)
@@ -58,7 +58,7 @@
PASS getSortedOwnPropertyNames(RegExp.prototype) is ['compile', 'constructor', 'exec', 'global', 'ignoreCase', 'lastIndex', 'multiline', 'source', 'test', 'toString']
PASS getSortedOwnPropertyNames(Error) is ['length', 'name', 'prototype']
PASS getSortedOwnPropertyNames(Error.prototype) is ['constructor', 'message', 'name', 'toString']
-PASS getSortedOwnPropertyNames(Math) is ['E', 'LN10', 'LN2', 'LOG10E', 'LOG2E', 'PI', 'SQRT1_2', 'SQRT2', 'abs', 'acos', 'asin', 'atan', 'atan2', 'ceil', 'cos', 'exp', 'floor', 'log', 'max', 'min', 'pow', 'random', 'round', 'sin', 'sqrt', 'tan']
+PASS getSortedOwnPropertyNames(Math) is ['E', 'LN10', 'LN2', 'LOG10E', 'LOG2E', 'PI', 'SQRT1_2', 'SQRT2', 'abs', 'acos', 'asin', 'atan', 'atan2', 'ceil', 'cos', 'exp', 'floor', 'imul', 'log', 'max', 'min', 'pow', 'random', 'round', 'sin', 'sqrt', 'tan']
PASS getSortedOwnPropertyNames(JSON) is ['parse', 'stringify']
PASS globalPropertyNames.indexOf('NaN') != -1 is true
PASS globalPropertyNames.indexOf('Infinity') != -1 is true
Added: trunk/LayoutTests/fast/js/imul-expected.txt (0 => 149159)
--- trunk/LayoutTests/fast/js/imul-expected.txt (rev 0)
+++ trunk/LayoutTests/fast/js/imul-expected.txt 2013-04-26 00:41:38 UTC (rev 149159)
@@ -0,0 +1,53 @@
+Test Math.imul behaviour
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS Math.imul(1, 0.5) is 0
+PASS Math.imul(1, -0.5) is 0
+PASS Math.imul(2, 1<<30) is -2147483648
+PASS Math.imul(4, 1<<30) is 0
+PASS Math.imul(1, NaN) is 0
+PASS Math.imul(1, Infinity) is 0
+PASS Math.imul({valueOf:function(){throw 'left'}},{valueOf:function(){throw 'right'}}) threw exception left.
+PASS Math.imul(0.5, 1) is 0
+PASS Math.imul(-0.5, 1) is 0
+PASS Math.imul(1<<30, 2) is -2147483648
+PASS Math.imul(1<<30, 4) is 0
+PASS Math.imul(NaN, 1) is 0
+PASS Math.imul(Infinity, 1) is 0
+PASS Math.imul(NaN, NaN) is 0
+PASS Math.imul(Infinity, Infinity) is 0
+PASS Math.imul(Infinity, -Infinity) is 0
+PASS Math.imul(-Infinity, Infinity) is 0
+PASS Math.imul(-Infinity, -Infinity) is 0
+PASS testIMul(2,2,10000) is 40000
+PASS testIMul(2.5,2,10000) is 40000
+PASS testIMul(2,2.5,10000) is 40000
+PASS testIMul(2.5,2.5,10000) is 40000
+PASS testIMul(2.5,2.5,10000) is 40000
+PASS testIMul(-2,-2,10000) is 40000
+PASS testIMul(-2.5,-2,10000) is 40000
+PASS testIMul(-2,-2.5,10000) is 40000
+PASS testIMul(-2.5,-2.5,10000) is 40000
+PASS testIMul(-2.5,-2.5,10000) is 40000
+PASS testIMul(-2,2,10000) is -40000
+PASS testIMul(-2.5,2,10000) is -40000
+PASS testIMul(-2,2.5,10000) is -40000
+PASS testIMul(-2.5,2.5,10000) is -40000
+PASS testIMul(-2.5,2.5,10000) is -40000
+PASS testIMul(2,-2,10000) is -40000
+PASS testIMul(2.5,-2,10000) is -40000
+PASS testIMul(2,-2.5,10000) is -40000
+PASS testIMul(2.5,-2.5,10000) is -40000
+PASS testIMul(2.5,-2.5,10000) is -40000
+PASS testIMul(NaN, 1, 10000) is 0
+PASS testIMul(Infinity, 1, 10000) is 0
+PASS testIMul(1e40, 1, 10000) is 0
+PASS testIMul(1, NaN, 10000) is 0
+PASS testIMul(1, Infinity, 10000) is 0
+PASS testIMul(1, 1e40, 10000) is 0
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
Added: trunk/LayoutTests/fast/js/imul.html (0 => 149159)
--- trunk/LayoutTests/fast/js/imul.html (rev 0)
+++ trunk/LayoutTests/fast/js/imul.html 2013-04-26 00:41:38 UTC (rev 149159)
@@ -0,0 +1,10 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<script src=""
+</head>
+<body>
+<script src=""
+<script src=""
+</body>
+</html>
Added: trunk/LayoutTests/fast/js/regress/imul-double-only-expected.txt (0 => 149159)
--- trunk/LayoutTests/fast/js/regress/imul-double-only-expected.txt (rev 0)
+++ trunk/LayoutTests/fast/js/regress/imul-double-only-expected.txt 2013-04-26 00:41:38 UTC (rev 149159)
@@ -0,0 +1,10 @@
+JSRegress/imul-double-only
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS no exception thrown
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
Added: trunk/LayoutTests/fast/js/regress/imul-double-only.html (0 => 149159)
--- trunk/LayoutTests/fast/js/regress/imul-double-only.html (rev 0)
+++ trunk/LayoutTests/fast/js/regress/imul-double-only.html 2013-04-26 00:41:38 UTC (rev 149159)
@@ -0,0 +1,12 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<script src=""
+</head>
+<body>
+<script src=""
+<script src=""
+<script src=""
+<script src=""
+</body>
+</html>
Added: trunk/LayoutTests/fast/js/regress/imul-int-only-expected.txt (0 => 149159)
--- trunk/LayoutTests/fast/js/regress/imul-int-only-expected.txt (rev 0)
+++ trunk/LayoutTests/fast/js/regress/imul-int-only-expected.txt 2013-04-26 00:41:38 UTC (rev 149159)
@@ -0,0 +1,10 @@
+JSRegress/imul-int-only
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS no exception thrown
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
Added: trunk/LayoutTests/fast/js/regress/imul-int-only.html (0 => 149159)
--- trunk/LayoutTests/fast/js/regress/imul-int-only.html (rev 0)
+++ trunk/LayoutTests/fast/js/regress/imul-int-only.html 2013-04-26 00:41:38 UTC (rev 149159)
@@ -0,0 +1,12 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<script src=""
+</head>
+<body>
+<script src=""
+<script src=""
+<script src=""
+<script src=""
+</body>
+</html>
Added: trunk/LayoutTests/fast/js/regress/imul-mixed-expected.txt (0 => 149159)
--- trunk/LayoutTests/fast/js/regress/imul-mixed-expected.txt (rev 0)
+++ trunk/LayoutTests/fast/js/regress/imul-mixed-expected.txt 2013-04-26 00:41:38 UTC (rev 149159)
@@ -0,0 +1,10 @@
+JSRegress/imul-mixed
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS no exception thrown
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
Added: trunk/LayoutTests/fast/js/regress/imul-mixed.html (0 => 149159)
--- trunk/LayoutTests/fast/js/regress/imul-mixed.html (rev 0)
+++ trunk/LayoutTests/fast/js/regress/imul-mixed.html 2013-04-26 00:41:38 UTC (rev 149159)
@@ -0,0 +1,12 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<script src=""
+</head>
+<body>
+<script src=""
+<script src=""
+<script src=""
+<script src=""
+</body>
+</html>
Added: trunk/LayoutTests/fast/js/regress/script-tests/imul-double-only.js (0 => 149159)
--- trunk/LayoutTests/fast/js/regress/script-tests/imul-double-only.js (rev 0)
+++ trunk/LayoutTests/fast/js/regress/script-tests/imul-double-only.js 2013-04-26 00:41:38 UTC (rev 149159)
@@ -0,0 +1,12 @@
+function f(a,b) {
+ var result = 0;
+ for (var i = 0; i < 10000; i++)
+ result = (result + Math.imul(a,b)) | 0
+ return result;
+}
+var result = 0;
+for (var i = 0.5; i < 10000; i++)
+ result = result ^ f(i, i);
+
+if (result != -375267328)
+ throw "Bad result: " + result;
Added: trunk/LayoutTests/fast/js/regress/script-tests/imul-int-only.js (0 => 149159)
--- trunk/LayoutTests/fast/js/regress/script-tests/imul-int-only.js (rev 0)
+++ trunk/LayoutTests/fast/js/regress/script-tests/imul-int-only.js 2013-04-26 00:41:38 UTC (rev 149159)
@@ -0,0 +1,12 @@
+function f(a,b) {
+ var result = 0;
+ for (var i = 0; i < 10000; i++)
+ result = (result + Math.imul(a,b)) | 0
+ return result;
+}
+var result = 0;
+for (var i = 0; i < 10000; i++)
+ result = result ^ f(i + 1, i)
+
+if (result != 1656994304)
+ throw "Bad result: " + result;
Added: trunk/LayoutTests/fast/js/regress/script-tests/imul-mixed.js (0 => 149159)
--- trunk/LayoutTests/fast/js/regress/script-tests/imul-mixed.js (rev 0)
+++ trunk/LayoutTests/fast/js/regress/script-tests/imul-mixed.js 2013-04-26 00:41:38 UTC (rev 149159)
@@ -0,0 +1,12 @@
+function f(a,b) {
+ var result = 0;
+ for (var i = 0; i < 10000; i++)
+ result = (result + Math.imul(a,b)) | 0
+ return result;
+}
+var result = 0;
+for (var i = 0; i < 10000; i++)
+ result = result + f(result | 1, i+0.5) ^ f(i+1.3, result | 1);
+
+if (result != -420098048)
+ throw "Bad result: " + result;
\ No newline at end of file
Modified: trunk/LayoutTests/fast/js/script-tests/Object-getOwnPropertyNames.js (149158 => 149159)
--- trunk/LayoutTests/fast/js/script-tests/Object-getOwnPropertyNames.js 2013-04-26 00:40:27 UTC (rev 149158)
+++ trunk/LayoutTests/fast/js/script-tests/Object-getOwnPropertyNames.js 2013-04-26 00:41:38 UTC (rev 149159)
@@ -66,7 +66,7 @@
"RegExp.prototype": "['compile', 'constructor', 'exec', 'global', 'ignoreCase', 'lastIndex', 'multiline', 'source', 'test', 'toString']",
"Error": "['length', 'name', 'prototype']",
"Error.prototype": "['constructor', 'message', 'name', 'toString']",
- "Math": "['E', 'LN10', 'LN2', 'LOG10E', 'LOG2E', 'PI', 'SQRT1_2', 'SQRT2', 'abs', 'acos', 'asin', 'atan', 'atan2', 'ceil', 'cos', 'exp', 'floor', 'log', 'max', 'min', 'pow', 'random', 'round', 'sin', 'sqrt', 'tan']",
+ "Math": "['E', 'LN10', 'LN2', 'LOG10E', 'LOG2E', 'PI', 'SQRT1_2', 'SQRT2', 'abs', 'acos', 'asin', 'atan', 'atan2', 'ceil', 'cos', 'exp', 'floor', 'imul', 'log', 'max', 'min', 'pow', 'random', 'round', 'sin', 'sqrt', 'tan']",
"JSON": "['parse', 'stringify']"
};
Added: trunk/LayoutTests/fast/js/script-tests/imul.js (0 => 149159)
--- trunk/LayoutTests/fast/js/script-tests/imul.js (rev 0)
+++ trunk/LayoutTests/fast/js/script-tests/imul.js 2013-04-26 00:41:38 UTC (rev 149159)
@@ -0,0 +1,64 @@
+description("Test Math.imul behaviour");
+
+shouldBe("Math.imul(1, 0.5)", "0");
+shouldBe("Math.imul(1, -0.5)", "0");
+shouldBe("Math.imul(2, 1<<30)", "-2147483648");
+shouldBe("Math.imul(4, 1<<30)", "0");
+shouldBe("Math.imul(1, NaN)", "0");
+shouldBe("Math.imul(1, Infinity)", "0");
+
+shouldThrow("Math.imul({valueOf:function(){throw 'left'}},{valueOf:function(){throw 'right'}})", "'left'");
+
+shouldBe("Math.imul(0.5, 1)", "0");
+shouldBe("Math.imul(-0.5, 1)", "0");
+shouldBe("Math.imul(1<<30, 2)", "-2147483648");
+shouldBe("Math.imul(1<<30, 4)", "0");
+shouldBe("Math.imul(NaN, 1)", "0");
+shouldBe("Math.imul(Infinity, 1)", "0");
+shouldBe("Math.imul(NaN, NaN)", "0");
+shouldBe("Math.imul(Infinity, Infinity)", "0");
+shouldBe("Math.imul(Infinity, -Infinity)", "0");
+shouldBe("Math.imul(-Infinity, Infinity)", "0");
+shouldBe("Math.imul(-Infinity, -Infinity)", "0");
+
+function testIMul(left, right, count)
+{
+ var result = 0;
+ for (var i = 0; i < count; i++)
+ result += Math.imul(left, right);
+ return result;
+}
+
+shouldBe("testIMul(2,2,10000)", "40000")
+shouldBe("testIMul(2.5,2,10000)", "40000")
+shouldBe("testIMul(2,2.5,10000)", "40000")
+shouldBe("testIMul(2.5,2.5,10000)", "40000")
+shouldBe("testIMul(2.5,2.5,10000)", "40000")
+shouldBe("testIMul(-2,-2,10000)", "40000")
+shouldBe("testIMul(-2.5,-2,10000)", "40000")
+shouldBe("testIMul(-2,-2.5,10000)", "40000")
+shouldBe("testIMul(-2.5,-2.5,10000)", "40000")
+shouldBe("testIMul(-2.5,-2.5,10000)", "40000")
+
+shouldBe("testIMul(-2,2,10000)", "-40000")
+shouldBe("testIMul(-2.5,2,10000)", "-40000")
+shouldBe("testIMul(-2,2.5,10000)", "-40000")
+shouldBe("testIMul(-2.5,2.5,10000)", "-40000")
+shouldBe("testIMul(-2.5,2.5,10000)", "-40000")
+
+
+shouldBe("testIMul(2,-2,10000)", "-40000")
+shouldBe("testIMul(2.5,-2,10000)", "-40000")
+shouldBe("testIMul(2,-2.5,10000)", "-40000")
+shouldBe("testIMul(2.5,-2.5,10000)", "-40000")
+shouldBe("testIMul(2.5,-2.5,10000)", "-40000")
+
+
+shouldBe("testIMul(NaN, 1, 10000)", "0")
+shouldBe("testIMul(Infinity, 1, 10000)", "0")
+shouldBe("testIMul(1e40, 1, 10000)", "0")
+shouldBe("testIMul(1, NaN, 10000)", "0")
+shouldBe("testIMul(1, Infinity, 10000)", "0")
+shouldBe("testIMul(1, 1e40, 10000)", "0")
+
+successfullyParsed = true;
Modified: trunk/Source/_javascript_Core/ChangeLog (149158 => 149159)
--- trunk/Source/_javascript_Core/ChangeLog 2013-04-26 00:40:27 UTC (rev 149158)
+++ trunk/Source/_javascript_Core/ChangeLog 2013-04-26 00:41:38 UTC (rev 149159)
@@ -1,3 +1,51 @@
+2013-04-24 Oliver Hunt <[email protected]>
+
+ Add support for Math.imul
+ https://bugs.webkit.org/show_bug.cgi?id=115143
+
+ Reviewed by Filip Pizlo.
+
+ Add support for Math.imul, a thunk generator for Math.imul,
+ and an intrinsic.
+
+ Fairly self explanatory set of changes, DFG intrinsics simply
+ leverages the existing ValueToInt32 nodes.
+
+ * create_hash_table:
+ * dfg/DFGAbstractState.cpp:
+ (JSC::DFG::AbstractState::executeEffects):
+ * dfg/DFGBackwardsPropagationPhase.cpp:
+ (JSC::DFG::BackwardsPropagationPhase::propagate):
+ * dfg/DFGByteCodeParser.cpp:
+ (JSC::DFG::ByteCodeParser::handleIntrinsic):
+ * dfg/DFGCSEPhase.cpp:
+ (JSC::DFG::CSEPhase::performNodeCSE):
+ * dfg/DFGFixupPhase.cpp:
+ (JSC::DFG::FixupPhase::fixupNode):
+ * dfg/DFGNodeType.h:
+ (DFG):
+ * dfg/DFGPredictionPropagationPhase.cpp:
+ (JSC::DFG::PredictionPropagationPhase::propagate):
+ * dfg/DFGSpeculativeJIT.cpp:
+ (JSC::DFG::SpeculativeJIT::compileArithIMul):
+ * dfg/DFGSpeculativeJIT.h:
+ (SpeculativeJIT):
+ * dfg/DFGSpeculativeJIT32_64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+ * dfg/DFGSpeculativeJIT64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+ * jit/ThunkGenerators.cpp:
+ (JSC::imulThunkGenerator):
+ (JSC):
+ * jit/ThunkGenerators.h:
+ (JSC):
+ * runtime/Intrinsic.h:
+ * runtime/MathObject.cpp:
+ (JSC):
+ (JSC::mathProtoFuncIMul):
+ * runtime/VM.cpp:
+ (JSC::thunkGeneratorForIntrinsic):
+
2013-04-25 Filip Pizlo <[email protected]>
Unreviewed, roll out http://trac.webkit.org/changeset/148999
Modified: trunk/Source/_javascript_Core/create_hash_table (149158 => 149159)
--- trunk/Source/_javascript_Core/create_hash_table 2013-04-26 00:40:27 UTC (rev 149158)
+++ trunk/Source/_javascript_Core/create_hash_table 2013-04-26 00:41:38 UTC (rev 149159)
@@ -283,6 +283,7 @@
$intrinsic = "RoundIntrinsic" if ($key eq "round");
$intrinsic = "ExpIntrinsic" if ($key eq "exp");
$intrinsic = "LogIntrinsic" if ($key eq "log");
+ $intrinsic = "IMulIntrinsic" if ($key eq "imul");
}
if ($name eq "arrayPrototypeTable") {
$intrinsic = "ArrayPushIntrinsic" if ($key eq "push");
Modified: trunk/Source/_javascript_Core/dfg/DFGAbstractState.cpp (149158 => 149159)
--- trunk/Source/_javascript_Core/dfg/DFGAbstractState.cpp 2013-04-26 00:40:27 UTC (rev 149158)
+++ trunk/Source/_javascript_Core/dfg/DFGAbstractState.cpp 2013-04-26 00:41:38 UTC (rev 149159)
@@ -428,7 +428,7 @@
forNode(node).set(SpecInt32);
break;
}
-
+
case Int32ToDouble:
case ForwardInt32ToDouble: {
JSValue child = forNode(node->child1()).value();
@@ -555,6 +555,11 @@
}
break;
}
+
+ case ArithIMul: {
+ forNode(node).set(SpecInt32);
+ break;
+ }
case ArithDiv:
case ArithMin:
Modified: trunk/Source/_javascript_Core/dfg/DFGBackwardsPropagationPhase.cpp (149158 => 149159)
--- trunk/Source/_javascript_Core/dfg/DFGBackwardsPropagationPhase.cpp 2013-04-26 00:40:27 UTC (rev 149158)
+++ trunk/Source/_javascript_Core/dfg/DFGBackwardsPropagationPhase.cpp 2013-04-26 00:41:38 UTC (rev 149159)
@@ -192,7 +192,8 @@
case BitXor:
case BitRShift:
case BitLShift:
- case BitURShift: {
+ case BitURShift:
+ case ArithIMul: {
flags |= NodeUsedAsInt;
flags &= ~(NodeUsedAsNumber | NodeNeedsNegZero | NodeUsedAsOther);
node->child1()->mergeFlags(flags);
Modified: trunk/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp (149158 => 149159)
--- trunk/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp 2013-04-26 00:40:27 UTC (rev 149158)
+++ trunk/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp 2013-04-26 00:41:38 UTC (rev 149159)
@@ -1600,6 +1600,17 @@
return true;
}
+
+ case IMulIntrinsic: {
+ if (argumentCountIncludingThis != 3)
+ return false;
+ int leftOperand = registerOffset + argumentToOperand(1);
+ int rightOperand = registerOffset + argumentToOperand(2);
+ Node* left = getToInt32(leftOperand);
+ Node* right = getToInt32(rightOperand);
+ setIntrinsicResult(usesResult, resultOperand, addToGraph(ArithIMul, left, right));
+ return true;
+ }
default:
return false;
Modified: trunk/Source/_javascript_Core/dfg/DFGCSEPhase.cpp (149158 => 149159)
--- trunk/Source/_javascript_Core/dfg/DFGCSEPhase.cpp 2013-04-26 00:40:27 UTC (rev 149158)
+++ trunk/Source/_javascript_Core/dfg/DFGCSEPhase.cpp 2013-04-26 00:41:38 UTC (rev 149159)
@@ -1059,6 +1059,7 @@
case ArithSub:
case ArithNegate:
case ArithMul:
+ case ArithIMul:
case ArithMod:
case ArithDiv:
case ArithAbs:
Modified: trunk/Source/_javascript_Core/dfg/DFGFixupPhase.cpp (149158 => 149159)
--- trunk/Source/_javascript_Core/dfg/DFGFixupPhase.cpp 2013-04-26 00:40:27 UTC (rev 149158)
+++ trunk/Source/_javascript_Core/dfg/DFGFixupPhase.cpp 2013-04-26 00:41:38 UTC (rev 149159)
@@ -100,7 +100,8 @@
case BitXor:
case BitRShift:
case BitLShift:
- case BitURShift: {
+ case BitURShift:
+ case ArithIMul: {
fixIntEdge(node->child1());
fixIntEdge(node->child2());
break;
Modified: trunk/Source/_javascript_Core/dfg/DFGNodeType.h (149158 => 149159)
--- trunk/Source/_javascript_Core/dfg/DFGNodeType.h 2013-04-26 00:40:27 UTC (rev 149158)
+++ trunk/Source/_javascript_Core/dfg/DFGNodeType.h 2013-04-26 00:41:38 UTC (rev 149159)
@@ -105,6 +105,7 @@
macro(ArithSub, NodeResultNumber | NodeMustGenerate) \
macro(ArithNegate, NodeResultNumber | NodeMustGenerate) \
macro(ArithMul, NodeResultNumber | NodeMustGenerate) \
+ macro(ArithIMul, NodeResultInt32 | NodeMustGenerate) \
macro(ArithDiv, NodeResultNumber | NodeMustGenerate) \
macro(ArithMod, NodeResultNumber | NodeMustGenerate) \
macro(ArithAbs, NodeResultNumber | NodeMustGenerate) \
Modified: trunk/Source/_javascript_Core/dfg/DFGPredictionPropagationPhase.cpp (149158 => 149159)
--- trunk/Source/_javascript_Core/dfg/DFGPredictionPropagationPhase.cpp 2013-04-26 00:40:27 UTC (rev 149158)
+++ trunk/Source/_javascript_Core/dfg/DFGPredictionPropagationPhase.cpp 2013-04-26 00:41:38 UTC (rev 149159)
@@ -164,7 +164,8 @@
case BitXor:
case BitRShift:
case BitLShift:
- case BitURShift: {
+ case BitURShift:
+ case ArithIMul: {
changed |= setPrediction(SpecInt32);
break;
}
Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp (149158 => 149159)
--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp 2013-04-26 00:40:27 UTC (rev 149158)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp 2013-04-26 00:41:38 UTC (rev 149159)
@@ -3332,7 +3332,21 @@
return;
}
}
+void SpeculativeJIT::compileArithIMul(Node* node)
+{
+ SpeculateIntegerOperand op1(this, node->child1());
+ SpeculateIntegerOperand op2(this, node->child2());
+ GPRTemporary result(this);
+ GPRReg reg1 = op1.gpr();
+ GPRReg reg2 = op2.gpr();
+
+ m_jit.move(reg1, result.gpr());
+ m_jit.mul32(reg2, result.gpr());
+ integerResult(result.gpr(), node);
+ return;
+}
+
void SpeculativeJIT::compileArithMul(Node* node)
{
switch (node->binaryUseKind()) {
Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.h (149158 => 149159)
--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.h 2013-04-26 00:40:27 UTC (rev 149158)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.h 2013-04-26 00:41:38 UTC (rev 149159)
@@ -1968,6 +1968,7 @@
void compileArithSub(Node*);
void compileArithNegate(Node*);
void compileArithMul(Node*);
+ void compileArithIMul(Node*);
#if CPU(X86) || CPU(X86_64)
void compileIntegerArithDivForX86(Node*);
#elif CPU(APPLE_ARMV7S)
Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT32_64.cpp (149158 => 149159)
--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT32_64.cpp 2013-04-26 00:40:27 UTC (rev 149158)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT32_64.cpp 2013-04-26 00:41:38 UTC (rev 149159)
@@ -2244,6 +2244,10 @@
compileArithMul(node);
break;
+ case ArithIMul:
+ compileArithIMul(node);
+ break;
+
case ArithDiv: {
switch (node->binaryUseKind()) {
case Int32Use: {
Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp (149158 => 149159)
--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp 2013-04-26 00:40:27 UTC (rev 149158)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp 2013-04-26 00:41:38 UTC (rev 149159)
@@ -2182,6 +2182,10 @@
compileArithMul(node);
break;
+ case ArithIMul:
+ compileArithIMul(node);
+ break;
+
case ArithDiv: {
switch (node->binaryUseKind()) {
case Int32Use: {
Modified: trunk/Source/_javascript_Core/jit/ThunkGenerators.cpp (149158 => 149159)
--- trunk/Source/_javascript_Core/jit/ThunkGenerators.cpp 2013-04-26 00:40:27 UTC (rev 149158)
+++ trunk/Source/_javascript_Core/jit/ThunkGenerators.cpp 2013-04-26 00:41:38 UTC (rev 149159)
@@ -768,6 +768,39 @@
return jit.finalize(*vm, vm->jitStubs->ctiNativeCall(vm), "pow");
}
+MacroAssemblerCodeRef imulThunkGenerator(VM* vm)
+{
+ SpecializedThunkJIT jit(2);
+ MacroAssembler::Jump nonIntArg0Jump;
+ jit.loadInt32Argument(0, SpecializedThunkJIT::regT0, nonIntArg0Jump);
+ SpecializedThunkJIT::Label doneLoadingArg0(&jit);
+ MacroAssembler::Jump nonIntArg1Jump;
+ jit.loadInt32Argument(1, SpecializedThunkJIT::regT1, nonIntArg1Jump);
+ SpecializedThunkJIT::Label doneLoadingArg1(&jit);
+ jit.mul32(SpecializedThunkJIT::regT1, SpecializedThunkJIT::regT0);
+ jit.returnInt32(SpecializedThunkJIT::regT0);
+
+ if (jit.supportsFloatingPointTruncate()) {
+ nonIntArg0Jump.link(&jit);
+ jit.loadDoubleArgument(0, SpecializedThunkJIT::fpRegT0, SpecializedThunkJIT::regT0);
+ jit.branchTruncateDoubleToInt32(SpecializedThunkJIT::fpRegT0, SpecializedThunkJIT::regT0, SpecializedThunkJIT::BranchIfTruncateSuccessful).linkTo(doneLoadingArg0, &jit);
+ jit.xor32(SpecializedThunkJIT::regT0, SpecializedThunkJIT::regT0);
+ jit.jump(doneLoadingArg0);
+ } else
+ jit.appendFailure(nonIntArg0Jump);
+
+ if (jit.supportsFloatingPointTruncate()) {
+ nonIntArg1Jump.link(&jit);
+ jit.loadDoubleArgument(1, SpecializedThunkJIT::fpRegT0, SpecializedThunkJIT::regT1);
+ jit.branchTruncateDoubleToInt32(SpecializedThunkJIT::fpRegT0, SpecializedThunkJIT::regT1, SpecializedThunkJIT::BranchIfTruncateSuccessful).linkTo(doneLoadingArg1, &jit);
+ jit.xor32(SpecializedThunkJIT::regT1, SpecializedThunkJIT::regT1);
+ jit.jump(doneLoadingArg1);
+ } else
+ jit.appendFailure(nonIntArg1Jump);
+
+ return jit.finalize(*vm, vm->jitStubs->ctiNativeCall(vm), "imul");
}
+}
+
#endif // ENABLE(JIT)
Modified: trunk/Source/_javascript_Core/jit/ThunkGenerators.h (149158 => 149159)
--- trunk/Source/_javascript_Core/jit/ThunkGenerators.h 2013-04-26 00:40:27 UTC (rev 149158)
+++ trunk/Source/_javascript_Core/jit/ThunkGenerators.h 2013-04-26 00:41:38 UTC (rev 149159)
@@ -51,6 +51,7 @@
MacroAssemblerCodeRef roundThunkGenerator(VM*);
MacroAssemblerCodeRef sqrtThunkGenerator(VM*);
MacroAssemblerCodeRef powThunkGenerator(VM*);
+MacroAssemblerCodeRef imulThunkGenerator(VM*);
}
#endif // ENABLE(JIT)
Modified: trunk/Source/_javascript_Core/runtime/Intrinsic.h (149158 => 149159)
--- trunk/Source/_javascript_Core/runtime/Intrinsic.h 2013-04-26 00:40:27 UTC (rev 149158)
+++ trunk/Source/_javascript_Core/runtime/Intrinsic.h 2013-04-26 00:41:38 UTC (rev 149159)
@@ -47,7 +47,8 @@
LogIntrinsic,
RegExpExecIntrinsic,
RegExpTestIntrinsic,
- StringPrototypeValueOfIntrinsic
+ StringPrototypeValueOfIntrinsic,
+ IMulIntrinsic
};
} // namespace JSC
Modified: trunk/Source/_javascript_Core/runtime/MathObject.cpp (149158 => 149159)
--- trunk/Source/_javascript_Core/runtime/MathObject.cpp 2013-04-26 00:40:27 UTC (rev 149158)
+++ trunk/Source/_javascript_Core/runtime/MathObject.cpp 2013-04-26 00:41:38 UTC (rev 149159)
@@ -52,6 +52,7 @@
static EncodedJSValue JSC_HOST_CALL mathProtoFuncSin(ExecState*);
static EncodedJSValue JSC_HOST_CALL mathProtoFuncSqrt(ExecState*);
static EncodedJSValue JSC_HOST_CALL mathProtoFuncTan(ExecState*);
+static EncodedJSValue JSC_HOST_CALL mathProtoFuncIMul(ExecState*);
}
@@ -81,6 +82,7 @@
sin mathProtoFuncSin DontEnum|Function 1
sqrt mathProtoFuncSqrt DontEnum|Function 1
tan mathProtoFuncTan DontEnum|Function 1
+ imul mathProtoFuncIMul DontEnum|Function 2
@end
*/
@@ -278,6 +280,15 @@
return JSValue::encode(jsDoubleNumber(tan(exec->argument(0).toNumber(exec))));
}
+EncodedJSValue JSC_HOST_CALL mathProtoFuncIMul(ExecState* exec)
+{
+ int32_t left = exec->argument(0).toInt32(exec);
+ if (exec->hadException())
+ return JSValue::encode(jsNull());
+ int32_t right = exec->argument(1).toInt32(exec);
+ return JSValue::encode(jsNumber(left * right));
+}
+
#if PLATFORM(IOS) && CPU(ARM_THUMB2)
// The following code is taken from netlib.org:
Modified: trunk/Source/_javascript_Core/runtime/VM.cpp (149158 => 149159)
--- trunk/Source/_javascript_Core/runtime/VM.cpp 2013-04-26 00:40:27 UTC (rev 149158)
+++ trunk/Source/_javascript_Core/runtime/VM.cpp 2013-04-26 00:41:38 UTC (rev 149159)
@@ -395,6 +395,8 @@
return expThunkGenerator;
case LogIntrinsic:
return logThunkGenerator;
+ case IMulIntrinsic:
+ return imulThunkGenerator;
default:
return 0;
}