<!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>[189918] 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/189918">189918</a></dd>
<dt>Author</dt> <dd>commit-queue@webkit.org</dd>
<dt>Date</dt> <dd>2015-09-17 10:40:07 -0700 (Thu, 17 Sep 2015)</dd>
</dl>

<h3>Log Message</h3>
<pre>Calling a float function on x86 in WebAssembly incorrectly returns a double
https://bugs.webkit.org/show_bug.cgi?id=149254

Patch by Sukolsak Sakshuwong &lt;sukolsak@gmail.com&gt; on 2015-09-17
Reviewed by Michael Saboff.

In WebAssembly on x86 (32-bit), when we call a function that returns a
float or a double, we use the FSTP instruction to read the return value
from the FPU register stack. The FSTP instruction converts the value to
single-precision or double-precision floating-point format, depending on
the destination operand. Currently, we always use double as the
destination, which is wrong. This patch uses the correct return type.
This should fix the test errors in tests/stress/wasm-arithmetic-float32.js

* assembler/X86Assembler.h:
(JSC::X86Assembler::fstps):
* wasm/WASMFunctionCompiler.h:
(JSC::WASMFunctionCompiler::appendCallSetResult):
(JSC::WASMFunctionCompiler::callOperation):</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceJavaScriptCoreChangeLog">trunk/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCoreassemblerX86Assemblerh">trunk/Source/JavaScriptCore/assembler/X86Assembler.h</a></li>
<li><a href="#trunkSourceJavaScriptCorewasmWASMFunctionCompilerh">trunk/Source/JavaScriptCore/wasm/WASMFunctionCompiler.h</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (189917 => 189918)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2015-09-17 17:38:08 UTC (rev 189917)
+++ trunk/Source/JavaScriptCore/ChangeLog        2015-09-17 17:40:07 UTC (rev 189918)
</span><span class="lines">@@ -1,5 +1,26 @@
</span><span class="cx"> 2015-09-17  Sukolsak Sakshuwong  &lt;sukolsak@gmail.com&gt;
</span><span class="cx"> 
</span><ins>+        Calling a float function on x86 in WebAssembly incorrectly returns a double
+        https://bugs.webkit.org/show_bug.cgi?id=149254
+
+        Reviewed by Michael Saboff.
+
+        In WebAssembly on x86 (32-bit), when we call a function that returns a
+        float or a double, we use the FSTP instruction to read the return value
+        from the FPU register stack. The FSTP instruction converts the value to
+        single-precision or double-precision floating-point format, depending on
+        the destination operand. Currently, we always use double as the
+        destination, which is wrong. This patch uses the correct return type.
+        This should fix the test errors in tests/stress/wasm-arithmetic-float32.js
+
+        * assembler/X86Assembler.h:
+        (JSC::X86Assembler::fstps):
+        * wasm/WASMFunctionCompiler.h:
+        (JSC::WASMFunctionCompiler::appendCallSetResult):
+        (JSC::WASMFunctionCompiler::callOperation):
+
+2015-09-17  Sukolsak Sakshuwong  &lt;sukolsak@gmail.com&gt;
+
</ins><span class="cx">         Save and restore callee save registers in WebAssembly
</span><span class="cx">         https://bugs.webkit.org/show_bug.cgi?id=149247
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreassemblerX86Assemblerh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/assembler/X86Assembler.h (189917 => 189918)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/assembler/X86Assembler.h        2015-09-17 17:38:08 UTC (rev 189917)
+++ trunk/Source/JavaScriptCore/assembler/X86Assembler.h        2015-09-17 17:40:07 UTC (rev 189918)
</span><span class="lines">@@ -227,6 +227,7 @@
</span><span class="cx">         OP_INT3                         = 0xCC,
</span><span class="cx">         OP_GROUP2_Ev1                   = 0xD1,
</span><span class="cx">         OP_GROUP2_EvCL                  = 0xD3,
</span><ins>+        OP_ESCAPE_D9                    = 0xD9,
</ins><span class="cx">         OP_ESCAPE_DD                    = 0xDD,
</span><span class="cx">         OP_CALL_rel32                   = 0xE8,
</span><span class="cx">         OP_JMP_rel32                    = 0xE9,
</span><span class="lines">@@ -323,6 +324,7 @@
</span><span class="cx">         GROUP14_OP_PSLLQ = 6,
</span><span class="cx">         GROUP14_OP_PSRLQ = 2,
</span><span class="cx"> 
</span><ins>+        ESCAPE_D9_FSTP_singleReal = 3,
</ins><span class="cx">         ESCAPE_DD_FSTP_doubleReal = 3,
</span><span class="cx">     } GroupOpcodeID;
</span><span class="cx">     
</span><span class="lines">@@ -1265,6 +1267,11 @@
</span><span class="cx">         m_formatter.oneByteOp(OP_CDQ);
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    void fstps(int offset, RegisterID base)
+    {
+        m_formatter.oneByteOp(OP_ESCAPE_D9, ESCAPE_D9_FSTP_singleReal, base, offset);
+    }
+
</ins><span class="cx">     void fstpl(int offset, RegisterID base)
</span><span class="cx">     {
</span><span class="cx">         m_formatter.oneByteOp(OP_ESCAPE_DD, ESCAPE_DD_FSTP_doubleReal, base, offset);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorewasmWASMFunctionCompilerh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/wasm/WASMFunctionCompiler.h (189917 => 189918)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/wasm/WASMFunctionCompiler.h        2015-09-17 17:38:08 UTC (rev 189917)
+++ trunk/Source/JavaScriptCore/wasm/WASMFunctionCompiler.h        2015-09-17 17:40:07 UTC (rev 189918)
</span><span class="lines">@@ -811,6 +811,8 @@
</span><span class="cx">         double doubleValue;
</span><span class="cx">     };
</span><span class="cx"> 
</span><ins>+    enum class FloatingPointPrecision { Single, Double };
+
</ins><span class="cx">     Address localAddress(unsigned localIndex) const
</span><span class="cx">     {
</span><span class="cx">         ASSERT(localIndex &lt; m_numberOfLocals);
</span><span class="lines">@@ -848,20 +850,27 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx"> #if CPU(X86)
</span><del>-    void appendCallSetResult(const FunctionPtr&amp; function, FPRReg result)
</del><ins>+    void appendCallSetResult(const FunctionPtr&amp; function, FPRReg result, FloatingPointPrecision precision)
</ins><span class="cx">     {
</span><span class="cx">         appendCall(function);
</span><del>-        m_assembler.fstpl(0, stackPointerRegister);
</del><ins>+        switch (precision) {
+        case FloatingPointPrecision::Single:
+            m_assembler.fstps(0, stackPointerRegister);
+            break;
+        case FloatingPointPrecision::Double:
+            m_assembler.fstpl(0, stackPointerRegister);
+            break;
+        }
</ins><span class="cx">         loadDouble(stackPointerRegister, result);
</span><span class="cx">     }
</span><span class="cx"> #elif CPU(ARM) &amp;&amp; !CPU(ARM_HARDFP)
</span><del>-    void appendCallSetResult(const FunctionPtr&amp; function, FPRReg result)
</del><ins>+    void appendCallSetResult(const FunctionPtr&amp; function, FPRReg result, FloatingPointPrecision)
</ins><span class="cx">     {
</span><span class="cx">         appendCall(function);
</span><span class="cx">         m_assembler.vmov(result, GPRInfo::returnValueGPR, GPRInfo::returnValueGPR2);
</span><span class="cx">     }
</span><span class="cx"> #else // CPU(X86_64) || (CPU(ARM) &amp;&amp; CPU(ARM_HARDFP)) || CPU(ARM64) || CPU(MIPS) || CPU(SH4)
</span><del>-    void appendCallSetResult(const FunctionPtr&amp; function, FPRReg result)
</del><ins>+    void appendCallSetResult(const FunctionPtr&amp; function, FPRReg result, FloatingPointPrecision)
</ins><span class="cx">     {
</span><span class="cx">         appendCall(function);
</span><span class="cx">         moveDouble(FPRInfo::returnValueFPR, result);
</span><span class="lines">@@ -878,7 +887,7 @@
</span><span class="cx">     void callOperation(D_JITOperation_EJ operation, GPRReg src, FPRReg dst)
</span><span class="cx">     {
</span><span class="cx">         setupArgumentsWithExecState(src);
</span><del>-        appendCallSetResult(operation, dst);
</del><ins>+        appendCallSetResult(operation, dst, FloatingPointPrecision::Double);
</ins><span class="cx">     }
</span><span class="cx"> #else
</span><span class="cx">     // EncodedJSValue in JSVALUE32_64 is a 64-bit integer. When being compiled in ARM EABI, it must be aligned even-numbered register (r0, r2 or [sp]).
</span><span class="lines">@@ -898,14 +907,14 @@
</span><span class="cx">     void callOperation(D_JITOperation_EJ operation, GPRReg srcTag, GPRReg srcPayload, FPRReg dst)
</span><span class="cx">     {
</span><span class="cx">         setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG srcPayload, srcTag);
</span><del>-        appendCallSetResult(operation, dst);
</del><ins>+        appendCallSetResult(operation, dst, FloatingPointPrecision::Double);
</ins><span class="cx">     }
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="cx">     void callOperation(float JIT_OPERATION (*operation)(float), FPRegisterID src, FPRegisterID dst)
</span><span class="cx">     {
</span><span class="cx">         setupArguments(src);
</span><del>-        appendCallSetResult(operation, dst);
</del><ins>+        appendCallSetResult(operation, dst, FloatingPointPrecision::Single);
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     void callOperation(int32_t JIT_OPERATION (*operation)(int32_t, int32_t), GPRReg src1, GPRReg src2, GPRReg dst)
</span></span></pre>
</div>
</div>

</body>
</html>