<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[193933] trunk/Source/JavaScriptCore</title>
</head>
<body>
<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; }
#msg dl a { font-weight: bold}
#msg dl a:link { color:#fc3; }
#msg dl a:active { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/193933">193933</a></dd>
<dt>Author</dt> <dd>commit-queue@webkit.org</dd>
<dt>Date</dt> <dd>2015-12-10 16:31:51 -0800 (Thu, 10 Dec 2015)</dd>
</dl>
<h3>Log Message</h3>
<pre>[JSC] Add a Modulo operator to B3, and a chill variant
https://bugs.webkit.org/show_bug.cgi?id=152110
Patch by Benjamin Poulain <bpoulain@apple.com> on 2015-12-10
Reviewed by Geoffrey Garen.
It is basically refactoring the Div and ChillDiv
code to be used by both opcodes.
* b3/B3Common.h:
(JSC::B3::chillDiv):
(JSC::B3::chillMod):
* b3/B3Const32Value.cpp:
(JSC::B3::Const32Value::modConstant):
* b3/B3Const32Value.h:
* b3/B3Const64Value.cpp:
(JSC::B3::Const64Value::modConstant):
* b3/B3Const64Value.h:
* b3/B3ConstDoubleValue.cpp:
(JSC::B3::ConstDoubleValue::modConstant):
* b3/B3ConstDoubleValue.h:
* b3/B3LowerMacros.cpp:
* b3/B3LowerToAir.cpp:
(JSC::B3::Air::LowerToAir::lower):
(JSC::B3::Air::LowerToAir::lowerX86Div):
* b3/B3Opcode.cpp:
(WTF::printInternal):
* b3/B3Opcode.h:
* b3/B3ReduceStrength.cpp:
* b3/B3Validate.cpp:
* b3/B3Value.cpp:
(JSC::B3::Value::modConstant):
(JSC::B3::Value::effects):
(JSC::B3::Value::key):
(JSC::B3::Value::typeFor):
* b3/B3Value.h:
* b3/testb3.cpp:
(JSC::B3::testModArgDouble):
(JSC::B3::testModArgsDouble):
(JSC::B3::testModArgImmDouble):
(JSC::B3::testModImmArgDouble):
(JSC::B3::testModImmsDouble):
(JSC::B3::testModArgFloat):
(JSC::B3::testModArgsFloat):
(JSC::B3::testModArgImmFloat):
(JSC::B3::testModImmArgFloat):
(JSC::B3::testModImmsFloat):
(JSC::B3::testModArg):
(JSC::B3::testModArgs):
(JSC::B3::testModImms):
(JSC::B3::testModArg32):
(JSC::B3::testModArgs32):
(JSC::B3::testModImms32):
(JSC::B3::testChillModArg):
(JSC::B3::testChillModArgs):
(JSC::B3::testChillModImms):
(JSC::B3::testChillModArg32):
(JSC::B3::testChillModArgs32):
(JSC::B3::testChillModImms32):
(JSC::B3::run):
* ftl/FTLB3Output.h:
(JSC::FTL::Output::mod):
(JSC::FTL::Output::chillMod):
(JSC::FTL::Output::doubleMod):
(JSC::FTL::Output::rem): Deleted.
(JSC::FTL::Output::doubleRem): Deleted.
* ftl/FTLLowerDFGToLLVM.cpp:
(JSC::FTL::DFG::LowerDFGToLLVM::compileArithMod):
* ftl/FTLOutput.cpp:
(JSC::FTL::Output::chillMod):
* ftl/FTLOutput.h:
(JSC::FTL::Output::mod):
(JSC::FTL::Output::doubleMod):
(JSC::FTL::Output::rem): Deleted.
(JSC::FTL::Output::doubleRem): Deleted.</pre>
<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceJavaScriptCoreChangeLog">trunk/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3Commonh">trunk/Source/JavaScriptCore/b3/B3Common.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3Const32Valuecpp">trunk/Source/JavaScriptCore/b3/B3Const32Value.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3Const32Valueh">trunk/Source/JavaScriptCore/b3/B3Const32Value.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3Const64Valuecpp">trunk/Source/JavaScriptCore/b3/B3Const64Value.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3Const64Valueh">trunk/Source/JavaScriptCore/b3/B3Const64Value.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3ConstDoubleValuecpp">trunk/Source/JavaScriptCore/b3/B3ConstDoubleValue.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3ConstDoubleValueh">trunk/Source/JavaScriptCore/b3/B3ConstDoubleValue.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3LowerMacroscpp">trunk/Source/JavaScriptCore/b3/B3LowerMacros.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3LowerToAircpp">trunk/Source/JavaScriptCore/b3/B3LowerToAir.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3Opcodecpp">trunk/Source/JavaScriptCore/b3/B3Opcode.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3Opcodeh">trunk/Source/JavaScriptCore/b3/B3Opcode.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3ReduceStrengthcpp">trunk/Source/JavaScriptCore/b3/B3ReduceStrength.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3Validatecpp">trunk/Source/JavaScriptCore/b3/B3Validate.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3Valuecpp">trunk/Source/JavaScriptCore/b3/B3Value.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3Valueh">trunk/Source/JavaScriptCore/b3/B3Value.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3testb3cpp">trunk/Source/JavaScriptCore/b3/testb3.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLB3Outputh">trunk/Source/JavaScriptCore/ftl/FTLB3Output.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLLowerDFGToLLVMcpp">trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLOutputcpp">trunk/Source/JavaScriptCore/ftl/FTLOutput.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLOutputh">trunk/Source/JavaScriptCore/ftl/FTLOutput.h</a></li>
</ul>
</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (193932 => 193933)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2015-12-11 00:05:00 UTC (rev 193932)
+++ trunk/Source/JavaScriptCore/ChangeLog        2015-12-11 00:31:51 UTC (rev 193933)
</span><span class="lines">@@ -1,3 +1,80 @@
</span><ins>+2015-12-10 Benjamin Poulain <bpoulain@apple.com>
+
+ [JSC] Add a Modulo operator to B3, and a chill variant
+ https://bugs.webkit.org/show_bug.cgi?id=152110
+
+ Reviewed by Geoffrey Garen.
+
+ It is basically refactoring the Div and ChillDiv
+ code to be used by both opcodes.
+
+ * b3/B3Common.h:
+ (JSC::B3::chillDiv):
+ (JSC::B3::chillMod):
+ * b3/B3Const32Value.cpp:
+ (JSC::B3::Const32Value::modConstant):
+ * b3/B3Const32Value.h:
+ * b3/B3Const64Value.cpp:
+ (JSC::B3::Const64Value::modConstant):
+ * b3/B3Const64Value.h:
+ * b3/B3ConstDoubleValue.cpp:
+ (JSC::B3::ConstDoubleValue::modConstant):
+ * b3/B3ConstDoubleValue.h:
+ * b3/B3LowerMacros.cpp:
+ * b3/B3LowerToAir.cpp:
+ (JSC::B3::Air::LowerToAir::lower):
+ (JSC::B3::Air::LowerToAir::lowerX86Div):
+ * b3/B3Opcode.cpp:
+ (WTF::printInternal):
+ * b3/B3Opcode.h:
+ * b3/B3ReduceStrength.cpp:
+ * b3/B3Validate.cpp:
+ * b3/B3Value.cpp:
+ (JSC::B3::Value::modConstant):
+ (JSC::B3::Value::effects):
+ (JSC::B3::Value::key):
+ (JSC::B3::Value::typeFor):
+ * b3/B3Value.h:
+ * b3/testb3.cpp:
+ (JSC::B3::testModArgDouble):
+ (JSC::B3::testModArgsDouble):
+ (JSC::B3::testModArgImmDouble):
+ (JSC::B3::testModImmArgDouble):
+ (JSC::B3::testModImmsDouble):
+ (JSC::B3::testModArgFloat):
+ (JSC::B3::testModArgsFloat):
+ (JSC::B3::testModArgImmFloat):
+ (JSC::B3::testModImmArgFloat):
+ (JSC::B3::testModImmsFloat):
+ (JSC::B3::testModArg):
+ (JSC::B3::testModArgs):
+ (JSC::B3::testModImms):
+ (JSC::B3::testModArg32):
+ (JSC::B3::testModArgs32):
+ (JSC::B3::testModImms32):
+ (JSC::B3::testChillModArg):
+ (JSC::B3::testChillModArgs):
+ (JSC::B3::testChillModImms):
+ (JSC::B3::testChillModArg32):
+ (JSC::B3::testChillModArgs32):
+ (JSC::B3::testChillModImms32):
+ (JSC::B3::run):
+ * ftl/FTLB3Output.h:
+ (JSC::FTL::Output::mod):
+ (JSC::FTL::Output::chillMod):
+ (JSC::FTL::Output::doubleMod):
+ (JSC::FTL::Output::rem): Deleted.
+ (JSC::FTL::Output::doubleRem): Deleted.
+ * ftl/FTLLowerDFGToLLVM.cpp:
+ (JSC::FTL::DFG::LowerDFGToLLVM::compileArithMod):
+ * ftl/FTLOutput.cpp:
+ (JSC::FTL::Output::chillMod):
+ * ftl/FTLOutput.h:
+ (JSC::FTL::Output::mod):
+ (JSC::FTL::Output::doubleMod):
+ (JSC::FTL::Output::rem): Deleted.
+ (JSC::FTL::Output::doubleRem): Deleted.
+
</ins><span class="cx"> 2015-12-10 Csaba Osztrogonác <ossy@webkit.org>
</span><span class="cx">
</span><span class="cx"> [B3] Add new files to the cmake build system
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3Commonh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3Common.h (193932 => 193933)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3Common.h        2015-12-11 00:05:00 UTC (rev 193932)
+++ trunk/Source/JavaScriptCore/b3/B3Common.h        2015-12-11 00:31:51 UTC (rev 193933)
</span><span class="lines">@@ -94,22 +94,24 @@
</span><span class="cx"> return isRepresentableAsImpl<ResultType, double, int64_t>(value);
</span><span class="cx"> }
</span><span class="cx">
</span><del>-inline int32_t chillDiv(int32_t num, int32_t den)
</del><ins>+template<typename IntType>
+static IntType chillDiv(IntType numerator, IntType denominator)
</ins><span class="cx"> {
</span><del>- if (!den)
</del><ins>+ if (!denominator)
</ins><span class="cx"> return 0;
</span><del>- if (den == -1 && num == std::numeric_limits<int32_t>::min())
- return num;
- return num / den;
</del><ins>+ if (denominator == -1 && numerator == std::numeric_limits<IntType>::min())
+ return std::numeric_limits<IntType>::min();
+ return numerator / denominator;
</ins><span class="cx"> }
</span><span class="cx">
</span><del>-inline int64_t chillDiv(int64_t num, int64_t den)
</del><ins>+template<typename IntType>
+static IntType chillMod(IntType numerator, IntType denominator)
</ins><span class="cx"> {
</span><del>- if (!den)
</del><ins>+ if (!denominator)
</ins><span class="cx"> return 0;
</span><del>- if (den == -1 && num == std::numeric_limits<int64_t>::min())
- return num;
- return num / den;
</del><ins>+ if (denominator == -1 && numerator == std::numeric_limits<IntType>::min())
+ return 0;
+ return numerator % denominator;
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> } } // namespace JSC::B3
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3Const32Valuecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3Const32Value.cpp (193932 => 193933)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3Const32Value.cpp        2015-12-11 00:05:00 UTC (rev 193932)
+++ trunk/Source/JavaScriptCore/b3/B3Const32Value.cpp        2015-12-11 00:31:51 UTC (rev 193933)
</span><span class="lines">@@ -112,6 +112,13 @@
</span><span class="cx"> return proc.add<Const32Value>(origin(), chillDiv(m_value, other->asInt32()));
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+Value* Const32Value::modConstant(Procedure& proc, const Value* other) const
+{
+ if (!other->hasInt32())
+ return nullptr;
+ return proc.add<Const32Value>(origin(), chillMod(m_value, other->asInt32()));
+}
+
</ins><span class="cx"> Value* Const32Value::bitAndConstant(Procedure& proc, const Value* other) const
</span><span class="cx"> {
</span><span class="cx"> if (!other->hasInt32())
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3Const32Valueh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3Const32Value.h (193932 => 193933)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3Const32Value.h        2015-12-11 00:05:00 UTC (rev 193932)
+++ trunk/Source/JavaScriptCore/b3/B3Const32Value.h        2015-12-11 00:31:51 UTC (rev 193933)
</span><span class="lines">@@ -50,6 +50,7 @@
</span><span class="cx"> Value* checkMulConstant(Procedure&, const Value* other) const override;
</span><span class="cx"> Value* checkNegConstant(Procedure&) const override;
</span><span class="cx"> Value* divConstant(Procedure&, const Value* other) const override;
</span><ins>+ Value* modConstant(Procedure&, const Value* other) const override;
</ins><span class="cx"> Value* bitAndConstant(Procedure&, const Value* other) const override;
</span><span class="cx"> Value* bitOrConstant(Procedure&, const Value* other) const override;
</span><span class="cx"> Value* bitXorConstant(Procedure&, const Value* other) const override;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3Const64Valuecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3Const64Value.cpp (193932 => 193933)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3Const64Value.cpp        2015-12-11 00:05:00 UTC (rev 193932)
+++ trunk/Source/JavaScriptCore/b3/B3Const64Value.cpp        2015-12-11 00:31:51 UTC (rev 193933)
</span><span class="lines">@@ -112,6 +112,13 @@
</span><span class="cx"> return proc.add<Const64Value>(origin(), chillDiv(m_value, other->asInt64()));
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+Value* Const64Value::modConstant(Procedure& proc, const Value* other) const
+{
+ if (!other->hasInt64())
+ return nullptr;
+ return proc.add<Const64Value>(origin(), chillMod(m_value, other->asInt64()));
+}
+
</ins><span class="cx"> Value* Const64Value::bitAndConstant(Procedure& proc, const Value* other) const
</span><span class="cx"> {
</span><span class="cx"> if (!other->hasInt64())
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3Const64Valueh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3Const64Value.h (193932 => 193933)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3Const64Value.h        2015-12-11 00:05:00 UTC (rev 193932)
+++ trunk/Source/JavaScriptCore/b3/B3Const64Value.h        2015-12-11 00:31:51 UTC (rev 193933)
</span><span class="lines">@@ -50,6 +50,7 @@
</span><span class="cx"> Value* checkMulConstant(Procedure&, const Value* other) const override;
</span><span class="cx"> Value* checkNegConstant(Procedure&) const override;
</span><span class="cx"> Value* divConstant(Procedure&, const Value* other) const override;
</span><ins>+ Value* modConstant(Procedure&, const Value* other) const override;
</ins><span class="cx"> Value* bitAndConstant(Procedure&, const Value* other) const override;
</span><span class="cx"> Value* bitOrConstant(Procedure&, const Value* other) const override;
</span><span class="cx"> Value* bitXorConstant(Procedure&, const Value* other) const override;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3ConstDoubleValuecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3ConstDoubleValue.cpp (193932 => 193933)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3ConstDoubleValue.cpp        2015-12-11 00:05:00 UTC (rev 193932)
+++ trunk/Source/JavaScriptCore/b3/B3ConstDoubleValue.cpp        2015-12-11 00:31:51 UTC (rev 193933)
</span><span class="lines">@@ -91,6 +91,13 @@
</span><span class="cx"> return proc.add<ConstDoubleValue>(origin(), m_value / other->asDouble());
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+Value* ConstDoubleValue::modConstant(Procedure& proc, const Value* other) const
+{
+ if (!other->hasDouble())
+ return nullptr;
+ return proc.add<ConstDoubleValue>(origin(), fmod(m_value, other->asDouble()));
+}
+
</ins><span class="cx"> TriState ConstDoubleValue::equalConstant(const Value* other) const
</span><span class="cx"> {
</span><span class="cx"> if (!other->hasDouble())
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3ConstDoubleValueh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3ConstDoubleValue.h (193932 => 193933)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3ConstDoubleValue.h        2015-12-11 00:05:00 UTC (rev 193932)
+++ trunk/Source/JavaScriptCore/b3/B3ConstDoubleValue.h        2015-12-11 00:31:51 UTC (rev 193933)
</span><span class="lines">@@ -45,6 +45,7 @@
</span><span class="cx"> Value* addConstant(Procedure&, const Value* other) const override;
</span><span class="cx"> Value* subConstant(Procedure&, const Value* other) const override;
</span><span class="cx"> Value* divConstant(Procedure&, const Value* other) const override;
</span><ins>+ Value* modConstant(Procedure&, const Value* other) const override;
</ins><span class="cx"> Value* mulConstant(Procedure&, const Value* other) const override;
</span><span class="cx"> Value* bitwiseCastConstant(Procedure&) const override;
</span><span class="cx"> Value* doubleToFloatConstant(Procedure&) const override;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3LowerMacroscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3LowerMacros.cpp (193932 => 193933)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3LowerMacros.cpp        2015-12-11 00:05:00 UTC (rev 193932)
+++ trunk/Source/JavaScriptCore/b3/B3LowerMacros.cpp        2015-12-11 00:31:51 UTC (rev 193933)
</span><span class="lines">@@ -30,6 +30,8 @@
</span><span class="cx">
</span><span class="cx"> #include "B3BasicBlockInlines.h"
</span><span class="cx"> #include "B3BlockInsertionSet.h"
</span><ins>+#include "B3CCallValue.h"
+#include "B3ConstPtrValue.h"
</ins><span class="cx"> #include "B3ControlValue.h"
</span><span class="cx"> #include "B3InsertionSetInlines.h"
</span><span class="cx"> #include "B3PhaseScope.h"
</span><span class="lines">@@ -37,6 +39,7 @@
</span><span class="cx"> #include "B3SwitchValue.h"
</span><span class="cx"> #include "B3UpsilonValue.h"
</span><span class="cx"> #include "B3ValueInlines.h"
</span><ins>+#include <cmath>
</ins><span class="cx">
</span><span class="cx"> namespace JSC { namespace B3 {
</span><span class="cx">
</span><span class="lines">@@ -72,105 +75,36 @@
</span><span class="cx"> m_value = m_block->at(m_index);
</span><span class="cx"> m_origin = m_value->origin();
</span><span class="cx"> switch (m_value->opcode()) {
</span><ins>+ case Mod: {
+ if (m_value->type() == Double) {
+ Value* functionAddress = m_insertionSet.insert<ConstPtrValue>(m_index, m_origin, fmod);
+ Value* result = m_insertionSet.insert<CCallValue>(m_index, Double, m_origin,
+ Effects::none(),
+ functionAddress,
+ m_value->child(0),
+ m_value->child(1));
+ m_value->replaceWithIdentity(result);
+ } else if (m_value->type() == Float) {
+ Value* numeratorAsDouble = m_insertionSet.insert<Value>(m_index, FloatToDouble, m_origin, m_value->child(0));
+ Value* denominatorAsDouble = m_insertionSet.insert<Value>(m_index, FloatToDouble, m_origin, m_value->child(1));
+ Value* functionAddress = m_insertionSet.insert<ConstPtrValue>(m_index, m_origin, fmod);
+ Value* doubleMod = m_insertionSet.insert<CCallValue>(m_index, Double, m_origin,
+ Effects::none(),
+ functionAddress,
+ numeratorAsDouble,
+ denominatorAsDouble);
+ Value* result = m_insertionSet.insert<Value>(m_index, DoubleToFloat, m_origin, doubleMod);
+ m_value->replaceWithIdentity(result);
+ }
+ break;
+ }
</ins><span class="cx"> case ChillDiv: {
</span><del>- // ARM supports this instruction natively.
- if (isARM64())
- break;
</del><ins>+ makeDivisionChill(Div);
+ break;
+ }
</ins><span class="cx">
</span><del>- m_changed = true;
-
- // We implement "res = ChillDiv(num, den)" as follows:
- //
- // if (den + 1 <=_unsigned 1) {
- // if (!den) {
- // res = 0;
- // goto done;
- // }
- // if (num == -2147483648) {
- // res = num;
- // goto done;
- // }
- // }
- // res = num / dev;
- // done:
-
- Value* num = m_value->child(0);
- Value* den = m_value->child(1);
-
- Value* one =
- m_insertionSet.insertIntConstant(m_index, m_value, 1);
- Value* isDenOK = m_insertionSet.insert<Value>(
- m_index, Above, m_origin,
- m_insertionSet.insert<Value>(m_index, Add, m_origin, den, one),
- one);
-
- BasicBlock* before =
- m_blockInsertionSet.splitForward(m_block, m_index, &m_insertionSet);
-
- BasicBlock* normalDivCase = m_blockInsertionSet.insertBefore(m_block);
- BasicBlock* shadyDenCase = m_blockInsertionSet.insertBefore(m_block);
- BasicBlock* zeroDenCase = m_blockInsertionSet.insertBefore(m_block);
- BasicBlock* neg1DenCase = m_blockInsertionSet.insertBefore(m_block);
- BasicBlock* intMinCase = m_blockInsertionSet.insertBefore(m_block);
-
- before->replaceLastWithNew<ControlValue>(
- m_proc, Branch, m_origin, isDenOK,
- FrequentedBlock(normalDivCase, FrequencyClass::Normal),
- FrequentedBlock(shadyDenCase, FrequencyClass::Rare));
-
- UpsilonValue* normalResult = normalDivCase->appendNew<UpsilonValue>(
- m_proc, m_origin,
- normalDivCase->appendNew<Value>(m_proc, Div, m_origin, num, den));
- normalDivCase->appendNew<ControlValue>(
- m_proc, Jump, m_origin, FrequentedBlock(m_block));
-
- shadyDenCase->appendNew<ControlValue>(
- m_proc, Branch, m_origin, den,
- FrequentedBlock(neg1DenCase, FrequencyClass::Normal),
- FrequentedBlock(zeroDenCase, FrequencyClass::Rare));
-
- UpsilonValue* zeroResult = zeroDenCase->appendNew<UpsilonValue>(
- m_proc, m_origin,
- zeroDenCase->appendIntConstant(m_proc, m_value, 0));
- zeroDenCase->appendNew<ControlValue>(
- m_proc, Jump, m_origin, FrequentedBlock(m_block));
-
- int64_t badNumeratorConst;
- switch (m_value->type()) {
- case Int32:
- badNumeratorConst = std::numeric_limits<int32_t>::min();
- break;
- case Int64:
- badNumeratorConst = std::numeric_limits<int64_t>::min();
- break;
- default:
- ASSERT_NOT_REACHED();
- badNumeratorConst = 0;
- }
-
- Value* badNumerator =
- neg1DenCase->appendIntConstant(m_proc, m_value, badNumeratorConst);
-
- neg1DenCase->appendNew<ControlValue>(
- m_proc, Branch, m_origin,
- neg1DenCase->appendNew<Value>(
- m_proc, Equal, m_origin, num, badNumerator),
- FrequentedBlock(intMinCase, FrequencyClass::Rare),
- FrequentedBlock(normalDivCase, FrequencyClass::Normal));
-
- UpsilonValue* intMinResult = intMinCase->appendNew<UpsilonValue>(
- m_proc, m_origin, badNumerator);
- intMinCase->appendNew<ControlValue>(
- m_proc, Jump, m_origin, FrequentedBlock(m_block));
-
- Value* phi = m_insertionSet.insert<Value>(
- m_index, Phi, m_value->type(), m_origin);
- normalResult->setPhi(phi);
- zeroResult->setPhi(phi);
- intMinResult->setPhi(phi);
-
- m_value->replaceWithIdentity(phi);
- before->updatePredecessorsAfter();
</del><ins>+ case ChillMod: {
+ makeDivisionChill(Mod);
</ins><span class="cx"> break;
</span><span class="cx"> }
</span><span class="cx">
</span><span class="lines">@@ -199,6 +133,108 @@
</span><span class="cx"> m_insertionSet.execute(m_block);
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+ void makeDivisionChill(Opcode nonChillOpcode)
+ {
+ ASSERT(nonChillOpcode == Div || nonChillOpcode == Mod);
+
+ // ARM supports this instruction natively.
+ if (isARM64())
+ return;
+
+ // We implement "res = ChillDiv/ChillMod(num, den)" as follows:
+ //
+ // if (den + 1 <=_unsigned 1) {
+ // if (!den) {
+ // res = 0;
+ // goto done;
+ // }
+ // if (num == -2147483648) {
+ // res = isDiv ? num : 0;
+ // goto done;
+ // }
+ // }
+ // res = num (/ or %) dev;
+ // done:
+ m_changed = true;
+
+ Value* num = m_value->child(0);
+ Value* den = m_value->child(1);
+
+ Value* one = m_insertionSet.insertIntConstant(m_index, m_value, 1);
+ Value* isDenOK = m_insertionSet.insert<Value>(
+ m_index, Above, m_origin,
+ m_insertionSet.insert<Value>(m_index, Add, m_origin, den, one),
+ one);
+
+ BasicBlock* before = m_blockInsertionSet.splitForward(m_block, m_index, &m_insertionSet);
+
+ BasicBlock* normalDivCase = m_blockInsertionSet.insertBefore(m_block);
+ BasicBlock* shadyDenCase = m_blockInsertionSet.insertBefore(m_block);
+ BasicBlock* zeroDenCase = m_blockInsertionSet.insertBefore(m_block);
+ BasicBlock* neg1DenCase = m_blockInsertionSet.insertBefore(m_block);
+ BasicBlock* intMinCase = m_blockInsertionSet.insertBefore(m_block);
+
+ before->replaceLastWithNew<ControlValue>(
+ m_proc, Branch, m_origin, isDenOK,
+ FrequentedBlock(normalDivCase, FrequencyClass::Normal),
+ FrequentedBlock(shadyDenCase, FrequencyClass::Rare));
+
+ UpsilonValue* normalResult = normalDivCase->appendNew<UpsilonValue>(
+ m_proc, m_origin,
+ normalDivCase->appendNew<Value>(m_proc, nonChillOpcode, m_origin, num, den));
+ normalDivCase->appendNew<ControlValue>(
+ m_proc, Jump, m_origin, FrequentedBlock(m_block));
+
+ shadyDenCase->appendNew<ControlValue>(
+ m_proc, Branch, m_origin, den,
+ FrequentedBlock(neg1DenCase, FrequencyClass::Normal),
+ FrequentedBlock(zeroDenCase, FrequencyClass::Rare));
+
+ UpsilonValue* zeroResult = zeroDenCase->appendNew<UpsilonValue>(
+ m_proc, m_origin,
+ zeroDenCase->appendIntConstant(m_proc, m_value, 0));
+ zeroDenCase->appendNew<ControlValue>(
+ m_proc, Jump, m_origin, FrequentedBlock(m_block));
+
+ int64_t badNumeratorConst = 0;
+ switch (m_value->type()) {
+ case Int32:
+ badNumeratorConst = std::numeric_limits<int32_t>::min();
+ break;
+ case Int64:
+ badNumeratorConst = std::numeric_limits<int64_t>::min();
+ break;
+ default:
+ ASSERT_NOT_REACHED();
+ badNumeratorConst = 0;
+ }
+
+ Value* badNumerator =
+ neg1DenCase->appendIntConstant(m_proc, m_value, badNumeratorConst);
+
+ neg1DenCase->appendNew<ControlValue>(
+ m_proc, Branch, m_origin,
+ neg1DenCase->appendNew<Value>(
+ m_proc, Equal, m_origin, num, badNumerator),
+ FrequentedBlock(intMinCase, FrequencyClass::Rare),
+ FrequentedBlock(normalDivCase, FrequencyClass::Normal));
+
+ Value* intMinResult = nonChillOpcode == Div ? badNumerator : intMinCase->appendIntConstant(m_proc, m_value, 0);
+ UpsilonValue* intMinResultUpsilon = intMinCase->appendNew<UpsilonValue>(
+ m_proc, m_origin, intMinResult);
+ intMinCase->appendNew<ControlValue>(
+ m_proc, Jump, m_origin, FrequentedBlock(m_block));
+
+ Value* phi = m_insertionSet.insert<Value>(
+ m_index, Phi, m_value->type(), m_origin);
+ normalResult->setPhi(phi);
+ zeroResult->setPhi(phi);
+ intMinResultUpsilon->setPhi(phi);
+
+ m_value->replaceWithIdentity(phi);
+ before->updatePredecessorsAfter();
+ }
+
</ins><span class="cx"> void recursivelyBuildSwitch(
</span><span class="cx"> const Vector<SwitchCase>& cases, unsigned start, bool hardStart, unsigned end,
</span><span class="cx"> BasicBlock* before)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3LowerToAircpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3LowerToAir.cpp (193932 => 193933)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3LowerToAir.cpp        2015-12-11 00:05:00 UTC (rev 193932)
+++ trunk/Source/JavaScriptCore/b3/B3LowerToAir.cpp        2015-12-11 00:31:51 UTC (rev 193933)
</span><span class="lines">@@ -1441,29 +1441,8 @@
</span><span class="cx">
</span><span class="cx"> case Div: {
</span><span class="cx"> if (isInt(m_value->type())) {
</span><del>- Tmp eax = Tmp(X86Registers::eax);
- Tmp edx = Tmp(X86Registers::edx);
-
- Air::Opcode convertToDoubleWord;
- Air::Opcode div;
- switch (m_value->type()) {
- case Int32:
- convertToDoubleWord = X86ConvertToDoubleWord32;
- div = X86Div32;
- break;
- case Int64:
- convertToDoubleWord = X86ConvertToQuadWord64;
- div = X86Div64;
- break;
- default:
- RELEASE_ASSERT_NOT_REACHED();
- return;
- }
-
- append(Move, tmp(m_value->child(0)), eax);
- append(convertToDoubleWord, eax, edx);
- append(div, eax, edx, tmp(m_value->child(1)));
- append(Move, eax, tmp(m_value));
</del><ins>+ lowerX86Div();
+ append(Move, Tmp(X86Registers::eax), tmp(m_value));
</ins><span class="cx"> return;
</span><span class="cx"> }
</span><span class="cx"> ASSERT(isFloat(m_value->type()));
</span><span class="lines">@@ -1472,6 +1451,12 @@
</span><span class="cx"> return;
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+ case Mod: {
+ lowerX86Div();
+ append(Move, Tmp(X86Registers::edx), tmp(m_value));
+ return;
+ }
+
</ins><span class="cx"> case BitAnd: {
</span><span class="cx"> appendBinOp<And32, And64, Commutative>(
</span><span class="cx"> m_value->child(0), m_value->child(1));
</span><span class="lines">@@ -1977,6 +1962,32 @@
</span><span class="cx"> dataLog("FATAL: could not lower ", deepDump(m_value), "\n");
</span><span class="cx"> RELEASE_ASSERT_NOT_REACHED();
</span><span class="cx"> }
</span><ins>+
+ void lowerX86Div()
+ {
+ Tmp eax = Tmp(X86Registers::eax);
+ Tmp edx = Tmp(X86Registers::edx);
+
+ Air::Opcode convertToDoubleWord;
+ Air::Opcode div;
+ switch (m_value->type()) {
+ case Int32:
+ convertToDoubleWord = X86ConvertToDoubleWord32;
+ div = X86Div32;
+ break;
+ case Int64:
+ convertToDoubleWord = X86ConvertToQuadWord64;
+ div = X86Div64;
+ break;
+ default:
+ RELEASE_ASSERT_NOT_REACHED();
+ return;
+ }
+
+ append(Move, tmp(m_value->child(0)), eax);
+ append(convertToDoubleWord, eax, edx);
+ append(div, eax, edx, tmp(m_value->child(1)));
+ }
</ins><span class="cx">
</span><span class="cx"> IndexSet<Value> m_locked; // These are values that will have no Tmp in Air.
</span><span class="cx"> IndexMap<Value, Tmp> m_valueToTmp; // These are values that must have a Tmp in Air. We say that a Value* with a non-null Tmp is "pinned".
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3Opcodecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3Opcode.cpp (193932 => 193933)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3Opcode.cpp        2015-12-11 00:05:00 UTC (rev 193932)
+++ trunk/Source/JavaScriptCore/b3/B3Opcode.cpp        2015-12-11 00:31:51 UTC (rev 193933)
</span><span class="lines">@@ -116,11 +116,14 @@
</span><span class="cx"> case Div:
</span><span class="cx"> out.print("Div");
</span><span class="cx"> return;
</span><ins>+ case Mod:
+ out.print("Mod");
+ return;
</ins><span class="cx"> case ChillDiv:
</span><span class="cx"> out.print("ChillDiv");
</span><span class="cx"> return;
</span><del>- case Mod:
- out.print("Mod");
</del><ins>+ case ChillMod:
+ out.print("ChillMod");
</ins><span class="cx"> return;
</span><span class="cx"> case BitAnd:
</span><span class="cx"> out.print("BitAnd");
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3Opcodeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3Opcode.h (193932 => 193933)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3Opcode.h        2015-12-11 00:05:00 UTC (rev 193932)
+++ trunk/Source/JavaScriptCore/b3/B3Opcode.h        2015-12-11 00:31:51 UTC (rev 193933)
</span><span class="lines">@@ -71,10 +71,11 @@
</span><span class="cx"> Sub,
</span><span class="cx"> Mul,
</span><span class="cx"> Div, // All bets are off as to what will happen when you execute this for -2^31/-1 and x/0.
</span><ins>+ Mod, // All bets are off as to what will happen when you execute this for -2^31%-1 and x%0.
</ins><span class="cx">
</span><span class="cx"> // Integer math.
</span><span class="cx"> ChillDiv, // doesn't trap ever, behaves like JS (x/y)|0.
</span><del>- Mod,
</del><ins>+ ChillMod, // doesn't trap ever, behaves like JS (x%y)|0.
</ins><span class="cx"> BitAnd,
</span><span class="cx"> BitOr,
</span><span class="cx"> BitXor,
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3ReduceStrengthcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3ReduceStrength.cpp (193932 => 193933)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3ReduceStrength.cpp        2015-12-11 00:05:00 UTC (rev 193932)
+++ trunk/Source/JavaScriptCore/b3/B3ReduceStrength.cpp        2015-12-11 00:31:51 UTC (rev 193933)
</span><span class="lines">@@ -291,6 +291,11 @@
</span><span class="cx"> replaceWithNewValue(m_value->child(0)->divConstant(m_proc, m_value->child(1)));
</span><span class="cx"> break;
</span><span class="cx">
</span><ins>+ case Mod:
+ case ChillMod:
+ replaceWithNewValue(m_value->child(0)->modConstant(m_proc, m_value->child(1)));
+ break;
+
</ins><span class="cx"> case BitAnd:
</span><span class="cx"> handleCommutativity();
</span><span class="cx">
</span><span class="lines">@@ -658,7 +663,7 @@
</span><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> // Turn this: Load(constant1, offset = constant2)
</span><del>- // Into this: Laod(constant1 + constant2)
</del><ins>+ // Into this: Load(constant1 + constant2)
</ins><span class="cx"> //
</span><span class="cx"> // This is a fun canonicalization. It purely regresses naively generated code. We rely
</span><span class="cx"> // on constant materialization to be smart enough to materialize this constant the smart
</span><span class="lines">@@ -677,6 +682,18 @@
</span><span class="cx"> break;
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+ case CCall:
+ // Turn this: Call(fmod, constant1, constant2)
+ // Into this: fcall-constant(constant1, constant2)
+ if (m_value->type() == Double
+ && m_value->numChildren() == 3
+ && m_value->child(0)->isIntPtr(reinterpret_cast<intptr_t>(fmod))
+ && m_value->child(1)->type() == Double
+ && m_value->child(2)->type() == Double) {
+ replaceWithNewValue(m_value->child(1)->modConstant(m_proc, m_value->child(2)));
+ }
+ break;
+
</ins><span class="cx"> case Equal:
</span><span class="cx"> handleCommutativity();
</span><span class="cx">
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3Validatecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3Validate.cpp (193932 => 193933)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3Validate.cpp        2015-12-11 00:05:00 UTC (rev 193932)
+++ trunk/Source/JavaScriptCore/b3/B3Validate.cpp        2015-12-11 00:31:51 UTC (rev 193933)
</span><span class="lines">@@ -153,13 +153,14 @@
</span><span class="cx"> case Sub:
</span><span class="cx"> case Mul:
</span><span class="cx"> case Div:
</span><ins>+ case Mod:
</ins><span class="cx"> VALIDATE(value->numChildren() == 2, ("At ", *value));
</span><span class="cx"> VALIDATE(value->type() == value->child(0)->type(), ("At ", *value));
</span><span class="cx"> VALIDATE(value->type() == value->child(1)->type(), ("At ", *value));
</span><span class="cx"> VALIDATE(value->type() != Void, ("At ", *value));
</span><span class="cx"> break;
</span><span class="cx"> case ChillDiv:
</span><del>- case Mod:
</del><ins>+ case ChillMod:
</ins><span class="cx"> case BitAnd:
</span><span class="cx"> case BitOr:
</span><span class="cx"> case BitXor:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3Valuecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3Value.cpp (193932 => 193933)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3Value.cpp        2015-12-11 00:05:00 UTC (rev 193932)
+++ trunk/Source/JavaScriptCore/b3/B3Value.cpp        2015-12-11 00:31:51 UTC (rev 193933)
</span><span class="lines">@@ -164,6 +164,11 @@
</span><span class="cx"> return nullptr;
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+Value* Value::modConstant(Procedure&, const Value*) const
+{
+ return nullptr;
+}
+
</ins><span class="cx"> Value* Value::bitAndConstant(Procedure&, const Value*) const
</span><span class="cx"> {
</span><span class="cx"> return nullptr;
</span><span class="lines">@@ -337,7 +342,7 @@
</span><span class="cx"> case Sub:
</span><span class="cx"> case Mul:
</span><span class="cx"> case ChillDiv:
</span><del>- case Mod:
</del><ins>+ case ChillMod:
</ins><span class="cx"> case BitAnd:
</span><span class="cx"> case BitOr:
</span><span class="cx"> case BitXor:
</span><span class="lines">@@ -369,6 +374,7 @@
</span><span class="cx"> case Select:
</span><span class="cx"> break;
</span><span class="cx"> case Div:
</span><ins>+ case Mod:
</ins><span class="cx"> result.controlDependent = true;
</span><span class="cx"> break;
</span><span class="cx"> case Load8Z:
</span><span class="lines">@@ -436,8 +442,10 @@
</span><span class="cx"> case Add:
</span><span class="cx"> case Sub:
</span><span class="cx"> case Mul:
</span><ins>+ case Div:
+ case Mod:
</ins><span class="cx"> case ChillDiv:
</span><del>- case Mod:
</del><ins>+ case ChillMod:
</ins><span class="cx"> case BitAnd:
</span><span class="cx"> case BitOr:
</span><span class="cx"> case BitXor:
</span><span class="lines">@@ -452,7 +460,6 @@
</span><span class="cx"> case Below:
</span><span class="cx"> case AboveEqual:
</span><span class="cx"> case BelowEqual:
</span><del>- case Div:
</del><span class="cx"> case CheckAdd:
</span><span class="cx"> case CheckSub:
</span><span class="cx"> case CheckMul:
</span><span class="lines">@@ -514,8 +521,9 @@
</span><span class="cx"> case Sub:
</span><span class="cx"> case Mul:
</span><span class="cx"> case Div:
</span><ins>+ case Mod:
</ins><span class="cx"> case ChillDiv:
</span><del>- case Mod:
</del><ins>+ case ChillMod:
</ins><span class="cx"> case BitAnd:
</span><span class="cx"> case BitOr:
</span><span class="cx"> case BitXor:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3Valueh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3Value.h (193932 => 193933)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3Value.h        2015-12-11 00:05:00 UTC (rev 193932)
+++ trunk/Source/JavaScriptCore/b3/B3Value.h        2015-12-11 00:31:51 UTC (rev 193933)
</span><span class="lines">@@ -121,6 +121,7 @@
</span><span class="cx"> virtual Value* checkMulConstant(Procedure&, const Value* other) const;
</span><span class="cx"> virtual Value* checkNegConstant(Procedure&) const;
</span><span class="cx"> virtual Value* divConstant(Procedure&, const Value* other) const; // This chooses ChillDiv semantics for integers.
</span><ins>+ virtual Value* modConstant(Procedure&, const Value* other) const; // This chooses ChillMod semantics for integers.
</ins><span class="cx"> virtual Value* bitAndConstant(Procedure&, const Value* other) const;
</span><span class="cx"> virtual Value* bitOrConstant(Procedure&, const Value* other) const;
</span><span class="cx"> virtual Value* bitXorConstant(Procedure&, const Value* other) const;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3testb3cpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/testb3.cpp (193932 => 193933)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/testb3.cpp        2015-12-11 00:05:00 UTC (rev 193932)
+++ trunk/Source/JavaScriptCore/b3/testb3.cpp        2015-12-11 00:31:51 UTC (rev 193933)
</span><span class="lines">@@ -1027,6 +1027,145 @@
</span><span class="cx"> CHECK(isIdentical(compileAndRun<int32_t>(proc), bitwise_cast<int32_t>(a / b)));
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+void testModArgDouble(double a)
+{
+ Procedure proc;
+ BasicBlock* root = proc.addBlock();
+ Value* value = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
+ root->appendNew<ControlValue>(
+ proc, Return, Origin(),
+ root->appendNew<Value>(proc, Mod, Origin(), value, value));
+
+ CHECK(isIdentical(compileAndRun<double>(proc, a), fmod(a, a)));
+}
+
+void testModArgsDouble(double a, double b)
+{
+ Procedure proc;
+ BasicBlock* root = proc.addBlock();
+ Value* valueA = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
+ Value* valueB = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR1);
+ root->appendNew<ControlValue>(
+ proc, Return, Origin(),
+ root->appendNew<Value>(proc, Mod, Origin(), valueA, valueB));
+
+ CHECK(isIdentical(compileAndRun<double>(proc, a, b), fmod(a, b)));
+}
+
+void testModArgImmDouble(double a, double b)
+{
+ Procedure proc;
+ BasicBlock* root = proc.addBlock();
+ Value* valueA = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
+ Value* valueB = root->appendNew<ConstDoubleValue>(proc, Origin(), b);
+ root->appendNew<ControlValue>(
+ proc, Return, Origin(),
+ root->appendNew<Value>(proc, Mod, Origin(), valueA, valueB));
+
+ CHECK(isIdentical(compileAndRun<double>(proc, a), fmod(a, b)));
+}
+
+void testModImmArgDouble(double a, double b)
+{
+ Procedure proc;
+ BasicBlock* root = proc.addBlock();
+ Value* valueA = root->appendNew<ConstDoubleValue>(proc, Origin(), a);
+ Value* valueB = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
+ root->appendNew<ControlValue>(
+ proc, Return, Origin(),
+ root->appendNew<Value>(proc, Mod, Origin(), valueA, valueB));
+
+ CHECK(isIdentical(compileAndRun<double>(proc, b), fmod(a, b)));
+}
+
+void testModImmsDouble(double a, double b)
+{
+ Procedure proc;
+ BasicBlock* root = proc.addBlock();
+ Value* valueA = root->appendNew<ConstDoubleValue>(proc, Origin(), a);
+ Value* valueB = root->appendNew<ConstDoubleValue>(proc, Origin(), b);
+ root->appendNew<ControlValue>(
+ proc, Return, Origin(),
+ root->appendNew<Value>(proc, Mod, Origin(), valueA, valueB));
+
+ CHECK(isIdentical(compileAndRun<double>(proc), fmod(a, b)));
+}
+
+void testModArgFloat(float a)
+{
+ Procedure proc;
+ BasicBlock* root = proc.addBlock();
+ Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
+ root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
+ Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
+ Value* result = root->appendNew<Value>(proc, Mod, Origin(), floatValue, floatValue);
+ Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
+ root->appendNew<ControlValue>(proc, Return, Origin(), result32);
+
+
+ CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), bitwise_cast<int32_t>(static_cast<float>(fmod(a, a)))));
+}
+
+void testModArgsFloat(float a, float b)
+{
+ Procedure proc;
+ BasicBlock* root = proc.addBlock();
+ Value* argument1int32 = root->appendNew<Value>(proc, Trunc, Origin(),
+ root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
+ Value* argument2int32 = root->appendNew<Value>(proc, Trunc, Origin(),
+ root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
+ Value* floatValue1 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument1int32);
+ Value* floatValue2 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument2int32);
+ Value* result = root->appendNew<Value>(proc, Mod, Origin(), floatValue1, floatValue2);
+ Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
+ root->appendNew<ControlValue>(proc, Return, Origin(), result32);
+
+ CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a), bitwise_cast<int32_t>(b)), bitwise_cast<int32_t>(static_cast<float>(fmod(a, b)))));
+}
+
+void testModArgImmFloat(float a, float b)
+{
+ Procedure proc;
+ BasicBlock* root = proc.addBlock();
+ Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
+ root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
+ Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
+ Value* constValue = root->appendNew<ConstFloatValue>(proc, Origin(), b);
+ Value* result = root->appendNew<Value>(proc, Mod, Origin(), floatValue, constValue);
+ Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
+ root->appendNew<ControlValue>(proc, Return, Origin(), result32);
+
+ CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), bitwise_cast<int32_t>(static_cast<float>(fmod(a, b)))));
+}
+
+void testModImmArgFloat(float a, float b)
+{
+ Procedure proc;
+ BasicBlock* root = proc.addBlock();
+ Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
+ root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
+ Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
+ Value* constValue = root->appendNew<ConstFloatValue>(proc, Origin(), a);
+ Value* result = root->appendNew<Value>(proc, Mod, Origin(), constValue, floatValue);
+ Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
+ root->appendNew<ControlValue>(proc, Return, Origin(), result32);
+
+ CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(b)), bitwise_cast<int32_t>(static_cast<float>(fmod(a, b)))));
+}
+
+void testModImmsFloat(float a, float b)
+{
+ Procedure proc;
+ BasicBlock* root = proc.addBlock();
+ Value* constValue1 = root->appendNew<ConstFloatValue>(proc, Origin(), a);
+ Value* constValue2 = root->appendNew<ConstFloatValue>(proc, Origin(), b);
+ Value* result = root->appendNew<Value>(proc, Mod, Origin(), constValue1, constValue2);
+ Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
+ root->appendNew<ControlValue>(proc, Return, Origin(), result32);
+
+ CHECK(isIdentical(compileAndRun<int32_t>(proc), bitwise_cast<int32_t>(static_cast<float>(fmod(a, b)))));
+}
+
</ins><span class="cx"> void testDivArgFloatWithUselessDoubleConversion(float a)
</span><span class="cx"> {
</span><span class="cx"> Procedure proc;
</span><span class="lines">@@ -6300,6 +6439,190 @@
</span><span class="cx"> }
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+void testModArg(int64_t value)
+{
+ if (!value)
+ return;
+
+ Procedure proc;
+ BasicBlock* root = proc.addBlock();
+
+ Value* argument = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
+ Value* result = root->appendNew<Value>(proc, Mod, Origin(), argument, argument);
+ root->appendNew<ControlValue>(proc, Return, Origin(), result);
+
+ CHECK(!compileAndRun<int64_t>(proc, value));
+}
+
+void testModArgs(int64_t numerator, int64_t denominator)
+{
+ if (!denominator)
+ return;
+ if (numerator == std::numeric_limits<int64_t>::min() && denominator == -1)
+ return;
+
+ Procedure proc;
+ BasicBlock* root = proc.addBlock();
+
+ Value* argument1 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
+ Value* argument2 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
+ Value* result = root->appendNew<Value>(proc, Mod, Origin(), argument1, argument2);
+ root->appendNew<ControlValue>(proc, Return, Origin(), result);
+
+ CHECK(compileAndRun<int64_t>(proc, numerator, denominator) == numerator % denominator);
+}
+
+void testModImms(int64_t numerator, int64_t denominator)
+{
+ if (!denominator)
+ return;
+ if (numerator == std::numeric_limits<int64_t>::min() && denominator == -1)
+ return;
+
+ Procedure proc;
+ BasicBlock* root = proc.addBlock();
+
+ Value* argument1 = root->appendNew<Const64Value>(proc, Origin(), numerator);
+ Value* argument2 = root->appendNew<Const64Value>(proc, Origin(), denominator);
+ Value* result = root->appendNew<Value>(proc, Mod, Origin(), argument1, argument2);
+ root->appendNew<ControlValue>(proc, Return, Origin(), result);
+
+ CHECK(compileAndRun<int64_t>(proc, numerator, denominator) == numerator % denominator);
+}
+
+void testModArg32(int32_t value)
+{
+ if (!value)
+ return;
+
+ Procedure proc;
+ BasicBlock* root = proc.addBlock();
+
+ Value* argument = root->appendNew<Value>(proc, Trunc, Origin(),
+ root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
+ Value* result = root->appendNew<Value>(proc, Mod, Origin(), argument, argument);
+ root->appendNew<ControlValue>(proc, Return, Origin(), result);
+
+ CHECK(!compileAndRun<int32_t>(proc, value));
+}
+
+void testModArgs32(int32_t numerator, int32_t denominator)
+{
+ if (!denominator)
+ return;
+ if (numerator == std::numeric_limits<int32_t>::min() && denominator == -1)
+ return;
+
+ Procedure proc;
+ BasicBlock* root = proc.addBlock();
+
+ Value* argument1 = root->appendNew<Value>(proc, Trunc, Origin(),
+ root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
+ Value* argument2 = root->appendNew<Value>(proc, Trunc, Origin(),
+ root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
+ Value* result = root->appendNew<Value>(proc, Mod, Origin(), argument1, argument2);
+ root->appendNew<ControlValue>(proc, Return, Origin(), result);
+
+ CHECK(compileAndRun<int32_t>(proc, numerator, denominator) == numerator % denominator);
+}
+
+void testModImms32(int32_t numerator, int32_t denominator)
+{
+ if (!denominator)
+ return;
+ if (numerator == std::numeric_limits<int32_t>::min() && denominator == -1)
+ return;
+
+ Procedure proc;
+ BasicBlock* root = proc.addBlock();
+
+ Value* argument1 = root->appendNew<Const32Value>(proc, Origin(), numerator);
+ Value* argument2 = root->appendNew<Const32Value>(proc, Origin(), denominator);
+ Value* result = root->appendNew<Value>(proc, Mod, Origin(), argument1, argument2);
+ root->appendNew<ControlValue>(proc, Return, Origin(), result);
+
+ CHECK(compileAndRun<int32_t>(proc, numerator, denominator) == numerator % denominator);
+}
+
+void testChillModArg(int64_t value)
+{
+ Procedure proc;
+ BasicBlock* root = proc.addBlock();
+
+ Value* argument = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
+ Value* result = root->appendNew<Value>(proc, ChillMod, Origin(), argument, argument);
+ root->appendNew<ControlValue>(proc, Return, Origin(), result);
+
+ CHECK(!compileAndRun<int64_t>(proc, value));
+}
+
+void testChillModArgs(int64_t numerator, int64_t denominator)
+{
+ Procedure proc;
+ BasicBlock* root = proc.addBlock();
+
+ Value* argument1 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
+ Value* argument2 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
+ Value* result = root->appendNew<Value>(proc, ChillMod, Origin(), argument1, argument2);
+ root->appendNew<ControlValue>(proc, Return, Origin(), result);
+
+ CHECK(compileAndRun<int64_t>(proc, numerator, denominator) == chillMod(numerator, denominator));
+}
+
+void testChillModImms(int64_t numerator, int64_t denominator)
+{
+ Procedure proc;
+ BasicBlock* root = proc.addBlock();
+
+ Value* argument1 = root->appendNew<Const64Value>(proc, Origin(), numerator);
+ Value* argument2 = root->appendNew<Const64Value>(proc, Origin(), denominator);
+ Value* result = root->appendNew<Value>(proc, ChillMod, Origin(), argument1, argument2);
+ root->appendNew<ControlValue>(proc, Return, Origin(), result);
+
+ CHECK(compileAndRun<int64_t>(proc, numerator, denominator) == chillMod(numerator, denominator));
+}
+
+void testChillModArg32(int32_t value)
+{
+ Procedure proc;
+ BasicBlock* root = proc.addBlock();
+
+ Value* argument = root->appendNew<Value>(proc, Trunc, Origin(),
+ root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
+ Value* result = root->appendNew<Value>(proc, ChillMod, Origin(), argument, argument);
+ root->appendNew<ControlValue>(proc, Return, Origin(), result);
+
+ CHECK(!compileAndRun<int32_t>(proc, value));
+}
+
+void testChillModArgs32(int32_t numerator, int32_t denominator)
+{
+ Procedure proc;
+ BasicBlock* root = proc.addBlock();
+
+ Value* argument1 = root->appendNew<Value>(proc, Trunc, Origin(),
+ root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
+ Value* argument2 = root->appendNew<Value>(proc, Trunc, Origin(),
+ root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
+ Value* result = root->appendNew<Value>(proc, ChillMod, Origin(), argument1, argument2);
+ root->appendNew<ControlValue>(proc, Return, Origin(), result);
+
+ CHECK(compileAndRun<int32_t>(proc, numerator, denominator) == chillMod(numerator, denominator));
+}
+
+void testChillModImms32(int32_t numerator, int32_t denominator)
+{
+ Procedure proc;
+ BasicBlock* root = proc.addBlock();
+
+ Value* argument1 = root->appendNew<Const32Value>(proc, Origin(), numerator);
+ Value* argument2 = root->appendNew<Const32Value>(proc, Origin(), denominator);
+ Value* result = root->appendNew<Value>(proc, ChillMod, Origin(), argument1, argument2);
+ root->appendNew<ControlValue>(proc, Return, Origin(), result);
+
+ CHECK(compileAndRun<int32_t>(proc, numerator, denominator) == chillMod(numerator, denominator));
+}
+
</ins><span class="cx"> void testSwitch(unsigned degree, unsigned gap = 1)
</span><span class="cx"> {
</span><span class="cx"> Procedure proc;
</span><span class="lines">@@ -7059,6 +7382,17 @@
</span><span class="cx"> RUN_BINARY(testDivArgsFloatWithUselessDoubleConversion, floatingPointOperands<float>(), floatingPointOperands<float>());
</span><span class="cx"> RUN_BINARY(testDivArgsFloatWithEffectfulDoubleConversion, floatingPointOperands<float>(), floatingPointOperands<float>());
</span><span class="cx">
</span><ins>+ RUN_UNARY(testModArgDouble, floatingPointOperands<double>());
+ RUN_BINARY(testModArgsDouble, floatingPointOperands<double>(), floatingPointOperands<double>());
+ RUN_BINARY(testModArgImmDouble, floatingPointOperands<double>(), floatingPointOperands<double>());
+ RUN_BINARY(testModImmArgDouble, floatingPointOperands<double>(), floatingPointOperands<double>());
+ RUN_BINARY(testModImmsDouble, floatingPointOperands<double>(), floatingPointOperands<double>());
+ RUN_UNARY(testModArgFloat, floatingPointOperands<float>());
+ RUN_BINARY(testModArgsFloat, floatingPointOperands<float>(), floatingPointOperands<float>());
+ RUN_BINARY(testModArgImmFloat, floatingPointOperands<float>(), floatingPointOperands<float>());
+ RUN_BINARY(testModImmArgFloat, floatingPointOperands<float>(), floatingPointOperands<float>());
+ RUN_BINARY(testModImmsFloat, floatingPointOperands<float>(), floatingPointOperands<float>());
+
</ins><span class="cx"> RUN(testSubArg(24));
</span><span class="cx"> RUN(testSubArgs(1, 1));
</span><span class="cx"> RUN(testSubArgs(1, 2));
</span><span class="lines">@@ -7633,6 +7967,19 @@
</span><span class="cx"> RUN(testChillDivTwice(4, 0, 6, 2, 3));
</span><span class="cx"> RUN(testChillDivTwice(4, 2, 6, 0, 2));
</span><span class="cx">
</span><ins>+ RUN_UNARY(testModArg, int64Operands());
+ RUN_BINARY(testModArgs, int64Operands(), int64Operands());
+ RUN_BINARY(testModImms, int64Operands(), int64Operands());
+ RUN_UNARY(testModArg32, int32Operands());
+ RUN_BINARY(testModArgs32, int32Operands(), int32Operands());
+ RUN_BINARY(testModImms32, int32Operands(), int32Operands());
+ RUN_UNARY(testChillModArg, int64Operands());
+ RUN_BINARY(testChillModArgs, int64Operands(), int64Operands());
+ RUN_BINARY(testChillModImms, int64Operands(), int64Operands());
+ RUN_UNARY(testChillModArg32, int32Operands());
+ RUN_BINARY(testChillModArgs32, int32Operands(), int32Operands());
+ RUN_BINARY(testChillModImms32, int32Operands(), int32Operands());
+
</ins><span class="cx"> RUN(testSwitch(0, 1));
</span><span class="cx"> RUN(testSwitch(1, 1));
</span><span class="cx"> RUN(testSwitch(2, 1));
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLB3Outputh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLB3Output.h (193932 => 193933)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLB3Output.h        2015-12-11 00:05:00 UTC (rev 193932)
+++ trunk/Source/JavaScriptCore/ftl/FTLB3Output.h        2015-12-11 00:31:51 UTC (rev 193933)
</span><span class="lines">@@ -128,7 +128,8 @@
</span><span class="cx"> LValue mul(LValue left, LValue right) { return m_block->appendNew<B3::Value>(m_proc, B3::Mul, origin(), left, right); }
</span><span class="cx"> LValue div(LValue left, LValue right) { return m_block->appendNew<B3::Value>(m_proc, B3::Div, origin(), left, right); }
</span><span class="cx"> LValue chillDiv(LValue left, LValue right) { return m_block->appendNew<B3::Value>(m_proc, B3::ChillDiv, origin(), left, right); }
</span><del>- LValue rem(LValue left, LValue right) { CRASH(); }
</del><ins>+ LValue mod(LValue left, LValue right) { m_block->appendNew<B3::Value>(m_proc, B3::Mod, origin(), left, right); }
+ LValue chillMod(LValue left, LValue right) { m_block->appendNew<B3::Value>(m_proc, B3::ChillMod, origin(), left, right); }
</ins><span class="cx"> LValue neg(LValue value)
</span><span class="cx"> {
</span><span class="cx"> LValue zero = m_block->appendIntConstant(m_proc, origin(), value->type(), 0);
</span><span class="lines">@@ -139,7 +140,7 @@
</span><span class="cx"> LValue doubleSub(LValue left, LValue right) { return m_block->appendNew<B3::Value>(m_proc, B3::Sub, origin(), left, right); }
</span><span class="cx"> LValue doubleMul(LValue left, LValue right) { return m_block->appendNew<B3::Value>(m_proc, B3::Mul, origin(), left, right); }
</span><span class="cx"> LValue doubleDiv(LValue left, LValue right) { return m_block->appendNew<B3::Value>(m_proc, B3::Div, origin(), left, right); }
</span><del>- LValue doubleRem(LValue left, LValue right) { return callWithoutSideEffects(B3::Double, fmod, left, right); }
</del><ins>+ LValue doubleMod(LValue left, LValue right) { return m_block->appendNew<B3::Value>(m_proc, B3::Mod, origin(), left, right); }
</ins><span class="cx"> LValue doubleNeg(LValue value)
</span><span class="cx"> {
</span><span class="cx"> return sub(doubleZero, value);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLLowerDFGToLLVMcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp (193932 => 193933)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp        2015-12-11 00:05:00 UTC (rev 193932)
+++ trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp        2015-12-11 00:31:51 UTC (rev 193933)
</span><span class="lines">@@ -2025,89 +2025,53 @@
</span><span class="cx"> case Int32Use: {
</span><span class="cx"> LValue numerator = lowInt32(m_node->child1());
</span><span class="cx"> LValue denominator = lowInt32(m_node->child2());
</span><del>-
- LBasicBlock unsafeDenominator = FTL_NEW_BLOCK(m_out, ("ArithMod unsafe denominator"));
- LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("ArithMod continuation"));
- LBasicBlock done = FTL_NEW_BLOCK(m_out, ("ArithMod done"));
-
- Vector<ValueFromBlock, 3> results;
-
- LValue adjustedDenominator = m_out.add(denominator, m_out.int32One);
-
- m_out.branch(
- m_out.above(adjustedDenominator, m_out.int32One),
- usually(continuation), rarely(unsafeDenominator));
-
- LBasicBlock lastNext = m_out.appendTo(unsafeDenominator, continuation);
-
- LValue neg2ToThe31 = m_out.constInt32(-2147483647-1);
-
- // FIXME: -2^31 / -1 will actually yield negative zero, so we could have a
- // separate case for that. But it probably doesn't matter so much.
</del><ins>+
+ LValue remainder;
</ins><span class="cx"> if (shouldCheckOverflow(m_node->arithMode())) {
</span><ins>+ LBasicBlock unsafeDenominator = FTL_NEW_BLOCK(m_out, ("ArithMod unsafe denominator"));
+ LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("ArithMod continuation"));
+
+ LValue adjustedDenominator = m_out.add(denominator, m_out.int32One);
+ m_out.branch(
+ m_out.above(adjustedDenominator, m_out.int32One),
+ usually(continuation), rarely(unsafeDenominator));
+
+ LBasicBlock lastNext = m_out.appendTo(unsafeDenominator, continuation);
+ LValue neg2ToThe31 = m_out.constInt32(-2147483647-1);
</ins><span class="cx"> LValue cond = m_out.bitOr(m_out.isZero32(denominator), m_out.equal(numerator, neg2ToThe31));
</span><span class="cx"> speculate(Overflow, noValue(), 0, cond);
</span><span class="cx"> m_out.jump(continuation);
</span><del>- } else {
- // This is the case where we convert the result to an int after we're done. So,
- // if the denominator is zero, then the result should be result should be zero.
- // If the denominator is not zero (i.e. it's -1 because we're guarded by the
- // check above) and the numerator is -2^31 then the result should be -2^31.
-
- LBasicBlock modByZero = FTL_NEW_BLOCK(m_out, ("ArithMod modulo by zero"));
- LBasicBlock notModByZero = FTL_NEW_BLOCK(m_out, ("ArithMod not modulo by zero"));
- LBasicBlock neg2ToThe31ByNeg1 = FTL_NEW_BLOCK(m_out, ("ArithMod -2^31/-1"));
-
- m_out.branch(
- m_out.isZero32(denominator), rarely(modByZero), usually(notModByZero));
-
- m_out.appendTo(modByZero, notModByZero);
- results.append(m_out.anchor(m_out.int32Zero));
- m_out.jump(done);
-
- m_out.appendTo(notModByZero, neg2ToThe31ByNeg1);
- m_out.branch(
- m_out.equal(numerator, neg2ToThe31),
- rarely(neg2ToThe31ByNeg1), usually(continuation));
-
- m_out.appendTo(neg2ToThe31ByNeg1, continuation);
- results.append(m_out.anchor(m_out.int32Zero));
- m_out.jump(done);
- }
-
- m_out.appendTo(continuation, done);
-
- LValue remainder = m_out.rem(numerator, denominator);
-
</del><ins>+
+ m_out.appendTo(continuation, lastNext);
+ LValue result = m_out.mod(numerator, denominator);
+ remainder = result;
+ } else
+ remainder = m_out.chillMod(numerator, denominator);
+
</ins><span class="cx"> if (shouldCheckNegativeZero(m_node->arithMode())) {
</span><span class="cx"> LBasicBlock negativeNumerator = FTL_NEW_BLOCK(m_out, ("ArithMod negative numerator"));
</span><span class="cx"> LBasicBlock numeratorContinuation = FTL_NEW_BLOCK(m_out, ("ArithMod numerator continuation"));
</span><del>-
</del><ins>+
</ins><span class="cx"> m_out.branch(
</span><span class="cx"> m_out.lessThan(numerator, m_out.int32Zero),
</span><span class="cx"> unsure(negativeNumerator), unsure(numeratorContinuation));
</span><del>-
</del><ins>+
</ins><span class="cx"> LBasicBlock innerLastNext = m_out.appendTo(negativeNumerator, numeratorContinuation);
</span><del>-
</del><ins>+
</ins><span class="cx"> speculate(NegativeZero, noValue(), 0, m_out.isZero32(remainder));
</span><del>-
</del><ins>+
</ins><span class="cx"> m_out.jump(numeratorContinuation);
</span><del>-
</del><ins>+
</ins><span class="cx"> m_out.appendTo(numeratorContinuation, innerLastNext);
</span><span class="cx"> }
</span><del>-
- results.append(m_out.anchor(remainder));
- m_out.jump(done);
-
- m_out.appendTo(done, lastNext);
-
- setInt32(m_out.phi(m_out.int32, results));
</del><ins>+
+ setInt32(remainder);
</ins><span class="cx"> break;
</span><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> case DoubleRepUse: {
</span><span class="cx"> setDouble(
</span><del>- m_out.doubleRem(lowDouble(m_node->child1()), lowDouble(m_node->child2())));
</del><ins>+ m_out.doubleMod(lowDouble(m_node->child1()), lowDouble(m_node->child2())));
</ins><span class="cx"> break;
</span><span class="cx"> }
</span><span class="cx">
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLOutputcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLOutput.cpp (193932 => 193933)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLOutput.cpp        2015-12-11 00:05:00 UTC (rev 193932)
+++ trunk/Source/JavaScriptCore/ftl/FTLOutput.cpp        2015-12-11 00:31:51 UTC (rev 193933)
</span><span class="lines">@@ -116,6 +116,47 @@
</span><span class="cx"> return phi(int32, results);
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+LValue Output::chillMod(LValue numerator, LValue denominator)
+{
+ LBasicBlock unsafeDenominator = FTL_NEW_BLOCK(*this, ("ChillMod unsafe denominator"));
+ LBasicBlock continuation = FTL_NEW_BLOCK(*this, ("ChillMod continuation"));
+ LBasicBlock done = FTL_NEW_BLOCK(*this, ("ChillMod done"));
+ LBasicBlock divByZero = FTL_NEW_BLOCK(*this, ("ChillMod divide by zero"));
+ LBasicBlock notDivByZero = FTL_NEW_BLOCK(*this, ("ChillMod not divide by zero"));
+ LBasicBlock neg2ToThe31ByNeg1 = FTL_NEW_BLOCK(*this, ("ChillMod -2^31/-1"));
+
+ LValue adjustedDenominator = add(denominator, int32One);
+ branch(
+ above(adjustedDenominator, int32One),
+ usually(continuation), rarely(unsafeDenominator));
+
+ Vector<ValueFromBlock, 3> results;
+ LBasicBlock lastNext = appendTo(unsafeDenominator, continuation);
+
+ LValue neg2ToThe31 = constInt32(-2147483647-1);
+ branch(isZero32(denominator), rarely(divByZero), usually(notDivByZero));
+
+ appendTo(divByZero, notDivByZero);
+ results.append(anchor(int32Zero));
+ jump(done);
+
+ appendTo(notDivByZero, neg2ToThe31ByNeg1);
+ branch(equal(numerator, neg2ToThe31),
+ rarely(neg2ToThe31ByNeg1), usually(continuation));
+
+ appendTo(neg2ToThe31ByNeg1, continuation);
+ results.append(anchor(int32Zero));
+ jump(done);
+
+ appendTo(continuation, done);
+ LValue result = mod(numerator, denominator);
+ results.append(anchor(result));
+ jump(done);
+
+ appendTo(done, lastNext);
+ return phi(int32, results);
+}
+
</ins><span class="cx"> LValue Output::sensibleDoubleToInt(LValue value)
</span><span class="cx"> {
</span><span class="cx"> RELEASE_ASSERT(isX86());
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLOutputh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLOutput.h (193932 => 193933)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLOutput.h        2015-12-11 00:05:00 UTC (rev 193932)
+++ trunk/Source/JavaScriptCore/ftl/FTLOutput.h        2015-12-11 00:31:51 UTC (rev 193933)
</span><span class="lines">@@ -126,14 +126,15 @@
</span><span class="cx"> LValue mul(LValue left, LValue right) { return buildMul(m_builder, left, right); }
</span><span class="cx"> LValue div(LValue left, LValue right) { return buildDiv(m_builder, left, right); }
</span><span class="cx"> LValue chillDiv(LValue left, LValue right);
</span><del>- LValue rem(LValue left, LValue right) { return buildRem(m_builder, left, right); }
</del><ins>+ LValue mod(LValue left, LValue right) { return buildRem(m_builder, left, right); }
+ LValue chillMod(LValue left, LValue right);
</ins><span class="cx"> LValue neg(LValue value) { return buildNeg(m_builder, value); }
</span><span class="cx">
</span><span class="cx"> LValue doubleAdd(LValue left, LValue right) { return buildFAdd(m_builder, left, right); }
</span><span class="cx"> LValue doubleSub(LValue left, LValue right) { return buildFSub(m_builder, left, right); }
</span><span class="cx"> LValue doubleMul(LValue left, LValue right) { return buildFMul(m_builder, left, right); }
</span><span class="cx"> LValue doubleDiv(LValue left, LValue right) { return buildFDiv(m_builder, left, right); }
</span><del>- LValue doubleRem(LValue left, LValue right) { return buildFRem(m_builder, left, right); }
</del><ins>+ LValue doubleMod(LValue left, LValue right) { return buildFRem(m_builder, left, right); }
</ins><span class="cx"> LValue doubleNeg(LValue value) { return buildFNeg(m_builder, value); }
</span><span class="cx">
</span><span class="cx"> LValue bitAnd(LValue left, LValue right) { return buildAnd(m_builder, left, right); }
</span></span></pre>
</div>
</div>
</body>
</html>