<!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>[193943] 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/193943">193943</a></dd>
<dt>Author</dt> <dd>fpizlo@apple.com</dd>
<dt>Date</dt> <dd>2015-12-10 20:03:28 -0800 (Thu, 10 Dec 2015)</dd>
</dl>

<h3>Log Message</h3>
<pre>FTL B3 should be able to run quicksort asm.js test
https://bugs.webkit.org/show_bug.cgi?id=152105

Reviewed by Geoffrey Garen.

This covers making all of the changes needed to run quicksort.js from AsmBench.

- Reintroduced float types to FTLLower since we now have B3::Float.

- Gave FTL::Output the ability to speak of load types and store types separately from LValue
  types. This dodges the problem that B3 doesn't have types for Int8 and Int16 but supports loads
  and stores of that type.

- Implemented Mod in B3 and wrote tests.

I also fixed a pre-existing bug in a test that appeared to only manifest in release builds.

Currently, B3's performance on asm.js tests is not good. It should be easy to fix:

- B3 should strength-reduce the shifting madness that happens in asm.js memory accesses
  https://bugs.webkit.org/show_bug.cgi?id=152106

- B3 constant hoisting should have a story for the asm.js heap constant
  https://bugs.webkit.org/show_bug.cgi?id=152107

* b3/B3CCallValue.h:
* b3/B3Const32Value.cpp:
(JSC::B3::Const32Value::divConstant):
(JSC::B3::Const32Value::modConstant):
(JSC::B3::Const32Value::bitAndConstant):
* b3/B3Const32Value.h:
* b3/B3Const64Value.cpp:
(JSC::B3::Const64Value::divConstant):
(JSC::B3::Const64Value::modConstant):
(JSC::B3::Const64Value::bitAndConstant):
* b3/B3Const64Value.h:
* b3/B3ReduceStrength.cpp:
* b3/B3Validate.cpp:
* b3/B3Value.cpp:
(JSC::B3::Value::divConstant):
(JSC::B3::Value::modConstant):
(JSC::B3::Value::bitAndConstant):
* b3/B3Value.h:
* b3/testb3.cpp:
(JSC::B3::testChillDiv64):
(JSC::B3::testMod):
(JSC::B3::testSwitch):
(JSC::B3::run):
* ftl/FTLB3Output.cpp:
(JSC::FTL::Output::load16ZeroExt32):
(JSC::FTL::Output::store):
(JSC::FTL::Output::store32As8):
(JSC::FTL::Output::store32As16):
(JSC::FTL::Output::loadFloatToDouble): Deleted.
* ftl/FTLB3Output.h:
(JSC::FTL::Output::mul):
(JSC::FTL::Output::div):
(JSC::FTL::Output::chillDiv):
(JSC::FTL::Output::rem):
(JSC::FTL::Output::neg):
(JSC::FTL::Output::load32):
(JSC::FTL::Output::load64):
(JSC::FTL::Output::loadPtr):
(JSC::FTL::Output::loadFloat):
(JSC::FTL::Output::loadDouble):
(JSC::FTL::Output::store32):
(JSC::FTL::Output::store64):
(JSC::FTL::Output::storePtr):
(JSC::FTL::Output::storeFloat):
(JSC::FTL::Output::storeDouble):
(JSC::FTL::Output::addPtr):
(JSC::FTL::Output::extractValue):
(JSC::FTL::Output::call):
(JSC::FTL::Output::operation):
* ftl/FTLLowerDFGToLLVM.cpp:
(JSC::FTL::DFG::LowerDFGToLLVM::compileGetByVal):
(JSC::FTL::DFG::LowerDFGToLLVM::compilePutByVal):
(JSC::FTL::DFG::LowerDFGToLLVM::compileArrayPush):
(JSC::FTL::DFG::LowerDFGToLLVM::compileArrayPop):
* ftl/FTLOutput.cpp:
(JSC::FTL::Output::Output):
(JSC::FTL::Output::store):
(JSC::FTL::Output::check):
(JSC::FTL::Output::load):
* ftl/FTLOutput.h:
(JSC::FTL::Output::load32):
(JSC::FTL::Output::load64):
(JSC::FTL::Output::loadPtr):
(JSC::FTL::Output::loadFloat):
(JSC::FTL::Output::loadDouble):
(JSC::FTL::Output::store32As8):
(JSC::FTL::Output::store32As16):
(JSC::FTL::Output::store32):
(JSC::FTL::Output::store64):
(JSC::FTL::Output::storePtr):
(JSC::FTL::Output::storeFloat):
(JSC::FTL::Output::storeDouble):
(JSC::FTL::Output::addPtr):
(JSC::FTL::Output::loadFloatToDouble): Deleted.
(JSC::FTL::Output::store16): Deleted.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceJavaScriptCoreChangeLog">trunk/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3CCallValueh">trunk/Source/JavaScriptCore/b3/B3CCallValue.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="#trunkSourceJavaScriptCoreb3B3Valueh">trunk/Source/JavaScriptCore/b3/B3Value.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3testb3cpp">trunk/Source/JavaScriptCore/b3/testb3.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLB3Outputcpp">trunk/Source/JavaScriptCore/ftl/FTLB3Output.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 (193942 => 193943)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2015-12-11 03:51:29 UTC (rev 193942)
+++ trunk/Source/JavaScriptCore/ChangeLog        2015-12-11 04:03:28 UTC (rev 193943)
</span><span class="lines">@@ -1,3 +1,106 @@
</span><ins>+2015-12-09  Filip Pizlo  &lt;fpizlo@apple.com&gt;
+
+        FTL B3 should be able to run quicksort asm.js test
+        https://bugs.webkit.org/show_bug.cgi?id=152105
+
+        Reviewed by Geoffrey Garen.
+
+        This covers making all of the changes needed to run quicksort.js from AsmBench.
+
+        - Reintroduced float types to FTLLower since we now have B3::Float.
+
+        - Gave FTL::Output the ability to speak of load types and store types separately from LValue
+          types. This dodges the problem that B3 doesn't have types for Int8 and Int16 but supports loads
+          and stores of that type.
+
+        - Implemented Mod in B3 and wrote tests.
+
+        I also fixed a pre-existing bug in a test that appeared to only manifest in release builds.
+
+        Currently, B3's performance on asm.js tests is not good. It should be easy to fix:
+
+        - B3 should strength-reduce the shifting madness that happens in asm.js memory accesses
+          https://bugs.webkit.org/show_bug.cgi?id=152106
+
+        - B3 constant hoisting should have a story for the asm.js heap constant
+          https://bugs.webkit.org/show_bug.cgi?id=152107
+
+        * b3/B3CCallValue.h:
+        * b3/B3Const32Value.cpp:
+        (JSC::B3::Const32Value::divConstant):
+        (JSC::B3::Const32Value::modConstant):
+        (JSC::B3::Const32Value::bitAndConstant):
+        * b3/B3Const32Value.h:
+        * b3/B3Const64Value.cpp:
+        (JSC::B3::Const64Value::divConstant):
+        (JSC::B3::Const64Value::modConstant):
+        (JSC::B3::Const64Value::bitAndConstant):
+        * b3/B3Const64Value.h:
+        * b3/B3ReduceStrength.cpp:
+        * b3/B3Validate.cpp:
+        * b3/B3Value.cpp:
+        (JSC::B3::Value::divConstant):
+        (JSC::B3::Value::modConstant):
+        (JSC::B3::Value::bitAndConstant):
+        * b3/B3Value.h:
+        * b3/testb3.cpp:
+        (JSC::B3::testChillDiv64):
+        (JSC::B3::testMod):
+        (JSC::B3::testSwitch):
+        (JSC::B3::run):
+        * ftl/FTLB3Output.cpp:
+        (JSC::FTL::Output::load16ZeroExt32):
+        (JSC::FTL::Output::store):
+        (JSC::FTL::Output::store32As8):
+        (JSC::FTL::Output::store32As16):
+        (JSC::FTL::Output::loadFloatToDouble): Deleted.
+        * ftl/FTLB3Output.h:
+        (JSC::FTL::Output::mul):
+        (JSC::FTL::Output::div):
+        (JSC::FTL::Output::chillDiv):
+        (JSC::FTL::Output::rem):
+        (JSC::FTL::Output::neg):
+        (JSC::FTL::Output::load32):
+        (JSC::FTL::Output::load64):
+        (JSC::FTL::Output::loadPtr):
+        (JSC::FTL::Output::loadFloat):
+        (JSC::FTL::Output::loadDouble):
+        (JSC::FTL::Output::store32):
+        (JSC::FTL::Output::store64):
+        (JSC::FTL::Output::storePtr):
+        (JSC::FTL::Output::storeFloat):
+        (JSC::FTL::Output::storeDouble):
+        (JSC::FTL::Output::addPtr):
+        (JSC::FTL::Output::extractValue):
+        (JSC::FTL::Output::call):
+        (JSC::FTL::Output::operation):
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::DFG::LowerDFGToLLVM::compileGetByVal):
+        (JSC::FTL::DFG::LowerDFGToLLVM::compilePutByVal):
+        (JSC::FTL::DFG::LowerDFGToLLVM::compileArrayPush):
+        (JSC::FTL::DFG::LowerDFGToLLVM::compileArrayPop):
+        * ftl/FTLOutput.cpp:
+        (JSC::FTL::Output::Output):
+        (JSC::FTL::Output::store):
+        (JSC::FTL::Output::check):
+        (JSC::FTL::Output::load):
+        * ftl/FTLOutput.h:
+        (JSC::FTL::Output::load32):
+        (JSC::FTL::Output::load64):
+        (JSC::FTL::Output::loadPtr):
+        (JSC::FTL::Output::loadFloat):
+        (JSC::FTL::Output::loadDouble):
+        (JSC::FTL::Output::store32As8):
+        (JSC::FTL::Output::store32As16):
+        (JSC::FTL::Output::store32):
+        (JSC::FTL::Output::store64):
+        (JSC::FTL::Output::storePtr):
+        (JSC::FTL::Output::storeFloat):
+        (JSC::FTL::Output::storeDouble):
+        (JSC::FTL::Output::addPtr):
+        (JSC::FTL::Output::loadFloatToDouble): Deleted.
+        (JSC::FTL::Output::store16): Deleted.
+
</ins><span class="cx"> 2015-12-10  Filip Pizlo  &lt;fpizlo@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Consider still matching an address expression even if B3 has already assigned a Tmp to it
</span><span class="lines">@@ -227,6 +330,7 @@
</span><span class="cx">         (JSC::ArrayPrototype::finishCreation):
</span><span class="cx">         * runtime/CommonIdentifiers.h:
</span><span class="cx"> 
</span><ins>+&gt;&gt;&gt;&gt;&gt;&gt;&gt; .r193940
</ins><span class="cx"> 2015-12-08  Filip Pizlo  &lt;fpizlo@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         FTL B3 should have basic GetById support
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3CCallValueh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3CCallValue.h (193942 => 193943)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3CCallValue.h        2015-12-11 03:51:29 UTC (rev 193942)
+++ trunk/Source/JavaScriptCore/b3/B3CCallValue.h        2015-12-11 04:03:28 UTC (rev 193943)
</span><span class="lines">@@ -49,6 +49,7 @@
</span><span class="cx">         : Value(index, CheckedOpcode, CCall, type, origin, arguments...)
</span><span class="cx">         , effects(Effects::forCall())
</span><span class="cx">     {
</span><ins>+        RELEASE_ASSERT(numChildren() &gt;= 1);
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     template&lt;typename... Arguments&gt;
</span><span class="lines">@@ -56,6 +57,7 @@
</span><span class="cx">         : Value(index, CheckedOpcode, CCall, type, origin, arguments...)
</span><span class="cx">         , effects(effects)
</span><span class="cx">     {
</span><ins>+        RELEASE_ASSERT(numChildren() &gt;= 1);
</ins><span class="cx">     }
</span><span class="cx"> };
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3ReduceStrengthcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3ReduceStrength.cpp (193942 => 193943)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3ReduceStrength.cpp        2015-12-11 03:51:29 UTC (rev 193942)
+++ trunk/Source/JavaScriptCore/b3/B3ReduceStrength.cpp        2015-12-11 04:03:28 UTC (rev 193943)
</span><span class="lines">@@ -293,6 +293,9 @@
</span><span class="cx"> 
</span><span class="cx">         case Mod:
</span><span class="cx">         case ChillMod:
</span><ins>+            // Turn this: Mod(constant1, constant2)
+            // Into this: constant1 / constant2
+            // Note that this uses ChillMod semantics.
</ins><span class="cx">             replaceWithNewValue(m_value-&gt;child(0)-&gt;modConstant(m_proc, m_value-&gt;child(1)));
</span><span class="cx">             break;
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3Validatecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3Validate.cpp (193942 => 193943)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3Validate.cpp        2015-12-11 03:51:29 UTC (rev 193942)
+++ trunk/Source/JavaScriptCore/b3/B3Validate.cpp        2015-12-11 04:03:28 UTC (rev 193943)
</span><span class="lines">@@ -289,8 +289,8 @@
</span><span class="cx">                 validateStackAccess(value);
</span><span class="cx">                 break;
</span><span class="cx">             case CCall:
</span><del>-                // This is a wildcard. You can pass any non-void arguments and you can select any
-                // return type.
</del><ins>+                VALIDATE(value-&gt;numChildren() &gt;= 1, (&quot;At &quot;, *value));
+                VALIDATE(value-&gt;child(0)-&gt;type() == pointerType(), (&quot;At &quot;, *value));
</ins><span class="cx">                 break;
</span><span class="cx">             case Patchpoint:
</span><span class="cx">                 if (value-&gt;type() == Void)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3Valueh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3Value.h (193942 => 193943)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3Value.h        2015-12-11 03:51:29 UTC (rev 193942)
+++ trunk/Source/JavaScriptCore/b3/B3Value.h        2015-12-11 04:03:28 UTC (rev 193943)
</span><span class="lines">@@ -121,7 +121,7 @@
</span><span class="cx">     virtual Value* checkMulConstant(Procedure&amp;, const Value* other) const;
</span><span class="cx">     virtual Value* checkNegConstant(Procedure&amp;) const;
</span><span class="cx">     virtual Value* divConstant(Procedure&amp;, const Value* other) const; // This chooses ChillDiv semantics for integers.
</span><del>-    virtual Value* modConstant(Procedure&amp;, const Value* other) const; // This chooses ChillMod semantics for integers.
</del><ins>+    virtual Value* modConstant(Procedure&amp;, const Value* other) const; // This chooses ChillMod semantics.
</ins><span class="cx">     virtual Value* bitAndConstant(Procedure&amp;, const Value* other) const;
</span><span class="cx">     virtual Value* bitOrConstant(Procedure&amp;, const Value* other) const;
</span><span class="cx">     virtual Value* bitXorConstant(Procedure&amp;, const Value* other) const;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3testb3cpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/testb3.cpp (193942 => 193943)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/testb3.cpp        2015-12-11 03:51:29 UTC (rev 193942)
+++ trunk/Source/JavaScriptCore/b3/testb3.cpp        2015-12-11 04:03:28 UTC (rev 193943)
</span><span class="lines">@@ -3000,12 +3000,13 @@
</span><span class="cx">     Value* result = root-&gt;appendNew&lt;Value&gt;(proc, Sqrt, Origin(), asDouble);
</span><span class="cx">     Value* floatResult = root-&gt;appendNew&lt;Value&gt;(proc, DoubleToFloat, Origin(), result);
</span><span class="cx">     Value* result32 = root-&gt;appendNew&lt;Value&gt;(proc, BitwiseCast, Origin(), floatResult);
</span><del>-    Value* doubleAddress = root-&gt;appendNew&lt;ArgumentRegValue&gt;(proc, Origin(), GPRInfo::argumentGPR2);
</del><ins>+    Value* doubleAddress = root-&gt;appendNew&lt;ArgumentRegValue&gt;(proc, Origin(), GPRInfo::argumentGPR1);
</ins><span class="cx">     root-&gt;appendNew&lt;MemoryValue&gt;(proc, Store, Origin(), result, doubleAddress);
</span><span class="cx">     root-&gt;appendNew&lt;ControlValue&gt;(proc, Return, Origin(), result32);
</span><span class="cx"> 
</span><span class="cx">     double effect = 0;
</span><del>-    CHECK(isIdentical(compileAndRun&lt;int32_t&gt;(proc, bitwise_cast&lt;int32_t&gt;(a), &amp;effect), bitwise_cast&lt;int32_t&gt;(static_cast&lt;float&gt;(sqrt(a)))));
</del><ins>+    int32_t resultValue = compileAndRun&lt;int32_t&gt;(proc, bitwise_cast&lt;int32_t&gt;(a), &amp;effect);
+    CHECK(isIdentical(resultValue, bitwise_cast&lt;int32_t&gt;(static_cast&lt;float&gt;(sqrt(a)))));
</ins><span class="cx">     CHECK(isIdentical(effect, sqrt(a)));
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -7206,9 +7207,9 @@
</span><span class="cx">             continue;                                   \
</span><span class="cx">         tasks.append(createSharedTask&lt;void()&gt;(          \
</span><span class="cx">             [=] () {                                    \
</span><del>-                dataLog(testStr, &quot;...\n&quot;);              \
</del><ins>+                dataLog(toCString(testStr, &quot;...\n&quot;));   \
</ins><span class="cx">                 test(a.value);                          \
</span><del>-                dataLog(testStr, &quot;: OK!\n&quot;);            \
</del><ins>+                dataLog(toCString(testStr, &quot;: OK!\n&quot;)); \
</ins><span class="cx">             }));                                        \
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="lines">@@ -7220,9 +7221,9 @@
</span><span class="cx">                 continue;                                   \
</span><span class="cx">             tasks.append(createSharedTask&lt;void()&gt;(          \
</span><span class="cx">                 [=] () {                                    \
</span><del>-                    dataLog(testStr, &quot;...\n&quot;);              \
</del><ins>+                    dataLog(toCString(testStr, &quot;...\n&quot;));   \
</ins><span class="cx">                     test(a.value, b.value);                 \
</span><del>-                    dataLog(testStr, &quot;: OK!\n&quot;);            \
</del><ins>+                    dataLog(toCString(testStr, &quot;: OK!\n&quot;)); \
</ins><span class="cx">                 }));                                        \
</span><span class="cx">         }                                                   \
</span><span class="cx">     }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLB3Outputcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLB3Output.cpp (193942 => 193943)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLB3Output.cpp        2015-12-11 03:51:29 UTC (rev 193942)
+++ trunk/Source/JavaScriptCore/ftl/FTLB3Output.cpp        2015-12-11 04:03:28 UTC (rev 193943)
</span><span class="lines">@@ -97,18 +97,24 @@
</span><span class="cx">     return load;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-LValue Output::loadFloatToDouble(TypedPointer pointer)
</del><ins>+void Output::store(LValue value, TypedPointer pointer)
</ins><span class="cx"> {
</span><del>-    LValue loadedFloat = load(pointer, floatType);
-    return m_block-&gt;appendNew&lt;B3::Value&gt;(m_proc, B3::FloatToDouble, origin(), loadedFloat);
</del><ins>+    LValue store = m_block-&gt;appendNew&lt;B3::MemoryValue&gt;(m_proc, B3::Store, origin(), value, pointer.value());
+    pointer.heap().decorateInstruction(store, *m_heaps);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-void Output::store(LValue value, TypedPointer pointer)
</del><ins>+void Output::store32As8(LValue value, TypedPointer pointer)
</ins><span class="cx"> {
</span><del>-    LValue store = m_block-&gt;appendNew&lt;B3::MemoryValue&gt;(m_proc, B3::Store, origin(), value, pointer.value());
</del><ins>+    LValue store = m_block-&gt;appendNew&lt;B3::MemoryValue&gt;(m_proc, B3::Store8, origin(), value, pointer.value());
</ins><span class="cx">     pointer.heap().decorateInstruction(store, *m_heaps);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void Output::store32As16(LValue value, TypedPointer pointer)
+{
+    LValue store = m_block-&gt;appendNew&lt;B3::MemoryValue&gt;(m_proc, B3::Store16, origin(), value, pointer.value());
+    pointer.heap().decorateInstruction(store, *m_heaps);
+}
+
</ins><span class="cx"> LValue Output::baseIndex(LValue base, LValue index, Scale scale, ptrdiff_t offset)
</span><span class="cx"> {
</span><span class="cx">     LValue accumulatedOffset;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLB3Outputh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLB3Output.h (193942 => 193943)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLB3Output.h        2015-12-11 03:51:29 UTC (rev 193942)
+++ trunk/Source/JavaScriptCore/ftl/FTLB3Output.h        2015-12-11 04:03:28 UTC (rev 193943)
</span><span class="lines">@@ -128,8 +128,8 @@
</span><span class="cx">     LValue mul(LValue left, LValue right) { return m_block-&gt;appendNew&lt;B3::Value&gt;(m_proc, B3::Mul, origin(), left, right); }
</span><span class="cx">     LValue div(LValue left, LValue right) { return m_block-&gt;appendNew&lt;B3::Value&gt;(m_proc, B3::Div, origin(), left, right); }
</span><span class="cx">     LValue chillDiv(LValue left, LValue right) { return m_block-&gt;appendNew&lt;B3::Value&gt;(m_proc, B3::ChillDiv, origin(), left, right); }
</span><del>-    LValue mod(LValue left, LValue right) { m_block-&gt;appendNew&lt;B3::Value&gt;(m_proc, B3::Mod, origin(), left, right); }
-    LValue chillMod(LValue left, LValue right) { m_block-&gt;appendNew&lt;B3::Value&gt;(m_proc, B3::ChillMod, origin(), left, right); }
</del><ins>+    LValue mod(LValue left, LValue right) { return m_block-&gt;appendNew&lt;B3::Value&gt;(m_proc, B3::Mod, origin(), left, right); }
+    LValue chillMod(LValue left, LValue right) { return m_block-&gt;appendNew&lt;B3::Value&gt;(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-&gt;appendIntConstant(m_proc, origin(), value-&gt;type(), 0);
</span><span class="lines">@@ -211,13 +211,62 @@
</span><span class="cx">     LValue load32(TypedPointer pointer) { return load(pointer, B3::Int32); }
</span><span class="cx">     LValue load64(TypedPointer pointer) { return load(pointer, B3::Int64); }
</span><span class="cx">     LValue loadPtr(TypedPointer pointer) { return load(pointer, B3::pointerType()); }
</span><del>-    LValue loadFloatToDouble(TypedPointer);
</del><ins>+    LValue loadFloat(TypedPointer pointer) { return load(pointer, B3::Float); }
</ins><span class="cx">     LValue loadDouble(TypedPointer pointer) { return load(pointer, B3::Double); }
</span><del>-    void store32(LValue value, TypedPointer pointer) { store(value, pointer); }
-    void store64(LValue value, TypedPointer pointer) { store(value, pointer); }
-    void storePtr(LValue value, TypedPointer pointer) { store(value, pointer); }
-    void storeDouble(LValue value, TypedPointer pointer) { store(value, pointer); }
</del><ins>+    void store32As8(LValue value, TypedPointer pointer);
+    void store32As16(LValue value, TypedPointer pointer);
+    void store32(LValue value, TypedPointer pointer)
+    {
+        ASSERT(value-&gt;type() == B3::Int32);
+        store(value, pointer);
+    }
+    void store64(LValue value, TypedPointer pointer)
+    {
+        ASSERT(value-&gt;type() == B3::Int64);
+        store(value, pointer);
+    }
+    void storePtr(LValue value, TypedPointer pointer)
+    {
+        ASSERT(value-&gt;type() == B3::pointerType());
+        store(value, pointer);
+    }
+    void storeFloat(LValue value, TypedPointer pointer)
+    {
+        ASSERT(value-&gt;type() == B3::Float);
+        store(value, pointer);
+    }
+    void storeDouble(LValue value, TypedPointer pointer)
+    {
+        ASSERT(value-&gt;type() == B3::Double);
+        store(value, pointer);
+    }
</ins><span class="cx"> 
</span><ins>+    enum LoadType {
+        Load8SignExt32,
+        Load8ZeroExt32,
+        Load16SignExt32,
+        Load16ZeroExt32,
+        Load32,
+        Load64,
+        LoadPtr,
+        LoadFloat,
+        LoadDouble
+    };
+
+    LValue load(TypedPointer, LoadType);
+    
+    enum StoreType {
+        Store32As8,
+        Store32As16,
+        Store32,
+        Store64,
+        StorePtr,
+        StoreFloat,
+        StoreDouble
+    };
+
+    void store(LValue, TypedPointer, StoreType);
+
</ins><span class="cx">     LValue addPtr(LValue value, ptrdiff_t immediate = 0)
</span><span class="cx">     {
</span><span class="cx">         if (!immediate)
</span><span class="lines">@@ -342,11 +391,16 @@
</span><span class="cx">     LValue extractValue(LValue aggVal, unsigned index) { CRASH(); }
</span><span class="cx"> 
</span><span class="cx">     template&lt;typename VectorType&gt;
</span><del>-    LValue call(LType type, LValue function, const VectorType&amp; vector) { return m_block-&gt;appendNew&lt;B3::CCallValue&gt;(m_proc, type, origin(), B3::Value::AdjacencyList(vector)); }
-    LValue call(LType type, LValue function) { return m_block-&gt;appendNew&lt;B3::CCallValue&gt;(m_proc, type, origin()); }
-    LValue call(LType type, LValue function, LValue arg1) { return m_block-&gt;appendNew&lt;B3::CCallValue&gt;(m_proc, type, origin(), arg1); }
</del><ins>+    LValue call(LType type, LValue function, const VectorType&amp; vector)
+    {
+        B3::CCallValue* result = m_block-&gt;appendNew&lt;B3::CCallValue&gt;(m_proc, type, origin(), function);
+        result-&gt;children().appendVector(vector);
+        return result;
+    }
+    LValue call(LType type, LValue function) { return m_block-&gt;appendNew&lt;B3::CCallValue&gt;(m_proc, type, origin(), function); }
+    LValue call(LType type, LValue function, LValue arg1) { return m_block-&gt;appendNew&lt;B3::CCallValue&gt;(m_proc, type, origin(), function, arg1); }
</ins><span class="cx">     template&lt;typename... Args&gt;
</span><del>-    LValue call(LType type, LValue function, LValue arg1, Args... args) { return m_block-&gt;appendNew&lt;B3::CCallValue&gt;(m_proc, type, origin(), arg1, args...); }
</del><ins>+    LValue call(LType type, LValue function, LValue arg1, Args... args) { return m_block-&gt;appendNew&lt;B3::CCallValue&gt;(m_proc, type, origin(), function, arg1, args...); }
</ins><span class="cx"> 
</span><span class="cx">     template&lt;typename FunctionType&gt;
</span><span class="cx">     LValue operation(FunctionType function) { return constIntPtr(bitwise_cast&lt;void*&gt;(function)); }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLLowerDFGToLLVMcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp (193942 => 193943)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp        2015-12-11 03:51:29 UTC (rev 193942)
+++ trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp        2015-12-11 04:03:28 UTC (rev 193943)
</span><span class="lines">@@ -3020,7 +3020,7 @@
</span><span class="cx">                 LValue result;
</span><span class="cx">                 switch (type) {
</span><span class="cx">                 case TypeFloat32:
</span><del>-                    result = m_out.loadFloatToDouble(pointer);
</del><ins>+                    result = m_out.fpCast(m_out.loadFloat(pointer), m_out.doubleType);
</ins><span class="cx">                     break;
</span><span class="cx">                 case TypeFloat64:
</span><span class="cx">                     result = m_out.loadDouble(pointer);
</span><span class="lines">@@ -3186,10 +3186,6 @@
</span><span class="cx">         }
</span><span class="cx">             
</span><span class="cx">         default:
</span><del>-#if FTL_USES_B3
-            UNUSED_PARAM(child5);
-            CRASH();
-#else
</del><span class="cx">             TypedArrayType type = m_node-&gt;arrayMode().typedArrayType();
</span><span class="cx">             
</span><span class="cx">             if (isTypedView(type)) {
</span><span class="lines">@@ -3201,7 +3197,7 @@
</span><span class="cx">                             m_out.zeroExt(index, m_out.intPtr),
</span><span class="cx">                             m_out.constIntPtr(logElementSize(type)))));
</span><span class="cx">                 
</span><del>-                LType refType;
</del><ins>+                Output::StoreType storeType;
</ins><span class="cx">                 LValue valueToStore;
</span><span class="cx">                 
</span><span class="cx">                 if (isInt(type)) {
</span><span class="lines">@@ -3276,19 +3272,17 @@
</span><span class="cx">                     default:
</span><span class="cx">                         DFG_CRASH(m_graph, m_node, &quot;Bad use kind&quot;);
</span><span class="cx">                     }
</span><del>-                    
</del><ins>+
+                    valueToStore = intValue;
</ins><span class="cx">                     switch (elementSize(type)) {
</span><span class="cx">                     case 1:
</span><del>-                        valueToStore = m_out.intCast(intValue, m_out.int8);
-                        refType = m_out.ref8;
</del><ins>+                        storeType = Output::Store32As8;
</ins><span class="cx">                         break;
</span><span class="cx">                     case 2:
</span><del>-                        valueToStore = m_out.intCast(intValue, m_out.int16);
-                        refType = m_out.ref16;
</del><ins>+                        storeType = Output::Store32As16;
</ins><span class="cx">                         break;
</span><span class="cx">                     case 4:
</span><del>-                        valueToStore = intValue;
-                        refType = m_out.ref32;
</del><ins>+                        storeType = Output::Store32;
</ins><span class="cx">                         break;
</span><span class="cx">                     default:
</span><span class="cx">                         DFG_CRASH(m_graph, m_node, &quot;Bad element size&quot;);
</span><span class="lines">@@ -3297,12 +3291,12 @@
</span><span class="cx">                     LValue value = lowDouble(child3);
</span><span class="cx">                     switch (type) {
</span><span class="cx">                     case TypeFloat32:
</span><del>-                        valueToStore = value;
-                        refType = m_out.refFloat;
</del><ins>+                        valueToStore = m_out.fpCast(value, m_out.floatType);
+                        storeType = Output::StoreFloat;
</ins><span class="cx">                         break;
</span><span class="cx">                     case TypeFloat64:
</span><span class="cx">                         valueToStore = value;
</span><del>-                        refType = m_out.refDouble;
</del><ins>+                        storeType = Output::StoreDouble;
</ins><span class="cx">                         break;
</span><span class="cx">                     default:
</span><span class="cx">                         DFG_CRASH(m_graph, m_node, &quot;Bad typed array type&quot;);
</span><span class="lines">@@ -3310,7 +3304,7 @@
</span><span class="cx">                 }
</span><span class="cx">                 
</span><span class="cx">                 if (m_node-&gt;arrayMode().isInBounds() || m_node-&gt;op() == PutByValAlias)
</span><del>-                    m_out.store(valueToStore, pointer, refType);
</del><ins>+                    m_out.store(valueToStore, pointer, storeType);
</ins><span class="cx">                 else {
</span><span class="cx">                     LBasicBlock isInBounds = FTL_NEW_BLOCK(m_out, (&quot;PutByVal typed array in bounds case&quot;));
</span><span class="cx">                     LBasicBlock continuation = FTL_NEW_BLOCK(m_out, (&quot;PutByVal typed array continuation&quot;));
</span><span class="lines">@@ -3320,7 +3314,7 @@
</span><span class="cx">                         unsure(continuation), unsure(isInBounds));
</span><span class="cx">                     
</span><span class="cx">                     LBasicBlock lastNext = m_out.appendTo(isInBounds, continuation);
</span><del>-                    m_out.store(valueToStore, pointer, refType);
</del><ins>+                    m_out.store(valueToStore, pointer, storeType);
</ins><span class="cx">                     m_out.jump(continuation);
</span><span class="cx">                     
</span><span class="cx">                     m_out.appendTo(continuation, lastNext);
</span><span class="lines">@@ -3330,7 +3324,6 @@
</span><span class="cx">             }
</span><span class="cx">             
</span><span class="cx">             DFG_CRASH(m_graph, m_node, &quot;Bad array type&quot;);
</span><del>-#endif // FTL_USES_B3
</del><span class="cx">             break;
</span><span class="cx">         }
</span><span class="cx">     }
</span><span class="lines">@@ -3371,10 +3364,6 @@
</span><span class="cx">     
</span><span class="cx">     void compileArrayPush()
</span><span class="cx">     {
</span><del>-#if FTL_USES_B3
-        if (verboseCompilationEnabled() || !verboseCompilationEnabled())
-            CRASH();
-#else
</del><span class="cx">         LValue base = lowCell(m_node-&gt;child1());
</span><span class="cx">         LValue storage = lowStorage(m_node-&gt;child3());
</span><span class="cx">         
</span><span class="lines">@@ -3383,7 +3372,7 @@
</span><span class="cx">         case Array::Contiguous:
</span><span class="cx">         case Array::Double: {
</span><span class="cx">             LValue value;
</span><del>-            LType refType;
</del><ins>+            Output::StoreType storeType;
</ins><span class="cx">             
</span><span class="cx">             if (m_node-&gt;arrayMode().type() != Array::Double) {
</span><span class="cx">                 value = lowJSValue(m_node-&gt;child2(), ManualOperandSpeculation);
</span><span class="lines">@@ -3391,13 +3380,13 @@
</span><span class="cx">                     FTL_TYPE_CHECK(
</span><span class="cx">                         jsValueValue(value), m_node-&gt;child2(), SpecInt32, isNotInt32(value));
</span><span class="cx">                 }
</span><del>-                refType = m_out.ref64;
</del><ins>+                storeType = Output::Store64;
</ins><span class="cx">             } else {
</span><span class="cx">                 value = lowDouble(m_node-&gt;child2());
</span><span class="cx">                 FTL_TYPE_CHECK(
</span><span class="cx">                     doubleValue(value), m_node-&gt;child2(), SpecDoubleReal,
</span><span class="cx">                     m_out.doubleNotEqualOrUnordered(value, value));
</span><del>-                refType = m_out.refDouble;
</del><ins>+                storeType = Output::StoreDouble;
</ins><span class="cx">             }
</span><span class="cx">             
</span><span class="cx">             IndexedAbstractHeap&amp; heap = m_heaps.forArrayType(m_node-&gt;arrayMode().type());
</span><span class="lines">@@ -3415,7 +3404,7 @@
</span><span class="cx">             
</span><span class="cx">             LBasicBlock lastNext = m_out.appendTo(fastPath, slowPath);
</span><span class="cx">             m_out.store(
</span><del>-                value, m_out.baseIndex(heap, storage, m_out.zeroExtPtr(prevLength)), refType);
</del><ins>+                value, m_out.baseIndex(heap, storage, m_out.zeroExtPtr(prevLength)), storeType);
</ins><span class="cx">             LValue newLength = m_out.add(prevLength, m_out.int32One);
</span><span class="cx">             m_out.store32(newLength, storage, m_heaps.Butterfly_publicLength);
</span><span class="cx">             
</span><span class="lines">@@ -3441,7 +3430,6 @@
</span><span class="cx">             DFG_CRASH(m_graph, m_node, &quot;Bad array type&quot;);
</span><span class="cx">             return;
</span><span class="cx">         }
</span><del>-#endif
</del><span class="cx">     }
</span><span class="cx">     
</span><span class="cx">     void compileArrayPop()
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLOutputcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLOutput.cpp (193942 => 193943)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLOutput.cpp        2015-12-11 03:51:29 UTC (rev 193942)
+++ trunk/Source/JavaScriptCore/ftl/FTLOutput.cpp        2015-12-11 04:03:28 UTC (rev 193943)
</span><span class="lines">@@ -26,13 +26,15 @@
</span><span class="cx"> #include &quot;config.h&quot;
</span><span class="cx"> 
</span><span class="cx"> #include &quot;DFGCommon.h&quot;
</span><ins>+#include &quot;FTLB3Output.h&quot;
</ins><span class="cx"> #include &quot;FTLOutput.h&quot;
</span><span class="cx"> 
</span><span class="cx"> #if ENABLE(FTL_JIT)
</span><del>-#if !FTL_USES_B3
</del><span class="cx"> 
</span><span class="cx"> namespace JSC { namespace FTL {
</span><span class="cx"> 
</span><ins>+#if !FTL_USES_B3
+
</ins><span class="cx"> Output::Output(State&amp; state)
</span><span class="cx">     : IntrinsicRepository(state.context)
</span><span class="cx">     , m_function(0)
</span><span class="lines">@@ -177,8 +179,6 @@
</span><span class="cx"> 
</span><span class="cx"> void Output::store(LValue value, TypedPointer pointer, LType refType)
</span><span class="cx"> {
</span><del>-    if (refType == refFloat)
-        value = buildFPCast(m_builder, value, floatType);
</del><span class="cx">     LValue result = set(value, intToPtr(pointer.value(), refType));
</span><span class="cx">     pointer.heap().decorateInstruction(result, *m_heaps);
</span><span class="cx"> }
</span><span class="lines">@@ -238,8 +238,63 @@
</span><span class="cx">     check(condition, taken, taken.weight().inverse());
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+#endif // !FTL_USES_B3
+
+LValue Output::load(TypedPointer pointer, LoadType type)
+{
+    switch (type) {
+    case Load8SignExt32:
+        return load8SignExt32(pointer);
+    case Load8ZeroExt32:
+        return load8ZeroExt32(pointer);
+    case Load16SignExt32:
+        return load8SignExt32(pointer);
+    case Load16ZeroExt32:
+        return load8ZeroExt32(pointer);
+    case Load32:
+        return load32(pointer);
+    case Load64:
+        return load64(pointer);
+    case LoadPtr:
+        return loadPtr(pointer);
+    case LoadFloat:
+        return loadFloat(pointer);
+    case LoadDouble:
+        return loadDouble(pointer);
+    }
+    RELEASE_ASSERT_NOT_REACHED();
+    return nullptr;
+}
+
+void Output::store(LValue value, TypedPointer pointer, StoreType type)
+{
+    switch (type) {
+    case Store32As8:
+        store32As8(value, pointer);
+        return;
+    case Store32As16:
+        store32As16(value, pointer);
+        return;
+    case Store32:
+        store32(value, pointer);
+        return;
+    case Store64:
+        store64(value, pointer);
+        return;
+    case StorePtr:
+        storePtr(value, pointer);
+        return;
+    case StoreFloat:
+        storeFloat(value, pointer);
+        return;
+    case StoreDouble:
+        storeDouble(value, pointer);
+        return;
+    }
+    RELEASE_ASSERT_NOT_REACHED();
+}
+
</ins><span class="cx"> } } // namespace JSC::FTL
</span><span class="cx"> 
</span><del>-#endif // !FTL_USES_B3
</del><span class="cx"> #endif // ENABLE(FTL_JIT)
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLOutputh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLOutput.h (193942 => 193943)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLOutput.h        2015-12-11 03:51:29 UTC (rev 193942)
+++ trunk/Source/JavaScriptCore/ftl/FTLOutput.h        2015-12-11 04:03:28 UTC (rev 193943)
</span><span class="lines">@@ -260,14 +260,43 @@
</span><span class="cx">     LValue load32(TypedPointer pointer) { return load(pointer, ref32); }
</span><span class="cx">     LValue load64(TypedPointer pointer) { return load(pointer, ref64); }
</span><span class="cx">     LValue loadPtr(TypedPointer pointer) { return load(pointer, refPtr); }
</span><del>-    LValue loadFloatToDouble(TypedPointer pointer) { return buildFPCast(m_builder, load(pointer, refFloat), doubleType); }
</del><ins>+    LValue loadFloat(TypedPointer pointer) { return load(pointer, refFloat); }
</ins><span class="cx">     LValue loadDouble(TypedPointer pointer) { return load(pointer, refDouble); }
</span><del>-    void store16(LValue value, TypedPointer pointer) { store(value, pointer, ref16); }
</del><ins>+
+    enum LoadType {
+        Load8SignExt32,
+        Load8ZeroExt32,
+        Load16SignExt32,
+        Load16ZeroExt32,
+        Load32,
+        Load64,
+        LoadPtr,
+        LoadFloat,
+        LoadDouble
+    };
+
+    LValue load(TypedPointer, LoadType);
+    
+    void store32As8(LValue value, TypedPointer pointer) { store(intCast(value, int8), pointer, ref8); }
+    void store32As16(LValue value, TypedPointer pointer) { store(intCast(value, int16), pointer, ref16); }
</ins><span class="cx">     void store32(LValue value, TypedPointer pointer) { store(value, pointer, ref32); }
</span><span class="cx">     void store64(LValue value, TypedPointer pointer) { store(value, pointer, ref64); }
</span><span class="cx">     void storePtr(LValue value, TypedPointer pointer) { store(value, pointer, refPtr); }
</span><ins>+    void storeFloat(LValue value, TypedPointer pointer) { store(value, pointer, refFloat); }
</ins><span class="cx">     void storeDouble(LValue value, TypedPointer pointer) { store(value, pointer, refDouble); }
</span><span class="cx"> 
</span><ins>+    enum StoreType {
+        Store32As8,
+        Store32As16,
+        Store32,
+        Store64,
+        StorePtr,
+        StoreFloat,
+        StoreDouble
+    };
+
+    void store(LValue, TypedPointer, StoreType);
+
</ins><span class="cx">     LValue addPtr(LValue value, ptrdiff_t immediate = 0)
</span><span class="cx">     {
</span><span class="cx">         if (!immediate)
</span></span></pre>
</div>
</div>

</body>
</html>