<!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>[197851] releases/WebKitGTK/webkit-2.12/Source</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/197851">197851</a></dd>
<dt>Author</dt> <dd>carlosgc@webkit.org</dd>
<dt>Date</dt> <dd>2016-03-09 02:28:11 -0800 (Wed, 09 Mar 2016)</dd>
</dl>
<h3>Log Message</h3>
<pre>Merge <a href="http://trac.webkit.org/projects/webkit/changeset/197652">r197652</a> - [JSC] Improve codegen of Compare and Test
https://bugs.webkit.org/show_bug.cgi?id=155055
Patch by Benjamin Poulain <bpoulain@apple.com> on 2016-03-06
Reviewed by Filip Pizlo.
Source/JavaScriptCore:
This patch introduces a few improvements on how we lower
Compare and Test with immediates:
-Add certain Immediate forms of ARM64.
-Use CBZ/CBNZ when possible on ARM64.
-When possible, convert a CMP into a TST
On some hardware, we can issue more TST simultaneously.
On x86, any TST+Jump is candidate for macro-fusion.
They are also smaller.
(sections 3.4.2.2 and 3.5.1.9)
-Do not load the mask immediate of a TST
if it only contains ones (mostly useful for ARM64
since that would not have been a valid immediate).
* assembler/MacroAssembler.h:
(JSC::MacroAssembler::compare32):
* assembler/MacroAssemblerARM64.h:
(JSC::MacroAssemblerARM64::moveConditionallyAfterFloatingPointCompare):
(JSC::MacroAssemblerARM64::moveDoubleConditionallyAfterFloatingPointCompare):
This is somewhat unrelated but I found that out while working
on moveDoubleConditionallyTest32:
If "thenCase" and "dest" are assigned the same register
by the allocator, then the first (f)fcsel would override
the "thenCase" and the second fcsel would always be "elseCase".
This is covered by testb3 but was only uncovered
after recent "Move" removals in lowering.
(JSC::MacroAssemblerARM64::moveConditionally32):
(JSC::MacroAssemblerARM64::moveConditionally64):
(JSC::MacroAssemblerARM64::moveConditionallyTest32):
(JSC::MacroAssemblerARM64::moveDoubleConditionally32):
(JSC::MacroAssemblerARM64::moveDoubleConditionally64):
(JSC::MacroAssemblerARM64::moveDoubleConditionallyTest32):
(JSC::MacroAssemblerARM64::branch32):
(JSC::MacroAssemblerARM64::branch64):
(JSC::MacroAssemblerARM64::branchTest32):
(JSC::MacroAssemblerARM64::test32):
The version taking an immediate was guarded by
(cond == Zero) || (cond == NonZero). That is overzealous,
and only needed for CBZ/CBNZ.
(JSC::MacroAssemblerARM64::branchTest64):
(JSC::MacroAssemblerARM64::compare32):
(JSC::MacroAssemblerARM64::compare64):
(JSC::MacroAssemblerARM64::commuteCompareToZeroIntoTest):
* assembler/MacroAssemblerX86Common.h:
(JSC::MacroAssemblerX86Common::moveConditionally32):
(JSC::MacroAssemblerX86Common::moveConditionallyTest32):
(JSC::MacroAssemblerX86Common::branch32):
(JSC::MacroAssemblerX86Common::test32):
(JSC::MacroAssemblerX86Common::branchTest32):
(JSC::MacroAssemblerX86Common::compare32):
(JSC::MacroAssemblerX86Common::commuteCompareToZeroIntoTest):
* assembler/MacroAssemblerX86_64.h:
(JSC::MacroAssemblerX86_64::compare64):
(JSC::MacroAssemblerX86_64::branch64):
(JSC::MacroAssemblerX86_64::moveConditionally64):
* b3/B3LowerToAir.cpp:
(JSC::B3::Air::LowerToAir::createGenericCompare):
Unfortunately this cannot be abstracted by the MacroAssembler.
Those immediates are not valid, we have to pick the better
for right away.
* b3/air/AirOpcode.opcodes:
* b3/testb3.cpp:
(JSC::B3::int64Operands):
(JSC::B3::modelCompare):
(JSC::B3::testCompareImpl):
(JSC::B3::testCompare):
(JSC::B3::b3Pow):
(JSC::B3::testPowDoubleByIntegerLoop):
Some versions of pow(double, int) do not return
the exact same bits as our integer loop.
Added a new version to have the same behavior
as the B3 loop.
(JSC::B3::run):
* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::compilePeepHoleBooleanBranch):
* dfg/DFGSpeculativeJIT64.cpp:
(JSC::DFG::SpeculativeJIT::compileInt32Compare):
Comparing to an immediate is super common. Do not waste
a register for that!
Source/WebCore:
* cssjit/FunctionCall.h:
(WebCore::FunctionCall::callAndBranchOnCondition):</pre>
<h3>Modified Paths</h3>
<ul>
<li><a href="#releasesWebKitGTKwebkit212SourceJavaScriptCoreChangeLog">releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#releasesWebKitGTKwebkit212SourceJavaScriptCoreassemblerMacroAssemblerh">releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/assembler/MacroAssembler.h</a></li>
<li><a href="#releasesWebKitGTKwebkit212SourceJavaScriptCoreassemblerMacroAssemblerARM64h">releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/assembler/MacroAssemblerARM64.h</a></li>
<li><a href="#releasesWebKitGTKwebkit212SourceJavaScriptCoreassemblerMacroAssemblerARMv7h">releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/assembler/MacroAssemblerARMv7.h</a></li>
<li><a href="#releasesWebKitGTKwebkit212SourceJavaScriptCoreassemblerMacroAssemblerX86Commonh">releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/assembler/MacroAssemblerX86Common.h</a></li>
<li><a href="#releasesWebKitGTKwebkit212SourceJavaScriptCoreassemblerMacroAssemblerX86_64h">releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/assembler/MacroAssemblerX86_64.h</a></li>
<li><a href="#releasesWebKitGTKwebkit212SourceJavaScriptCoreb3B3LowerToAircpp">releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/b3/B3LowerToAir.cpp</a></li>
<li><a href="#releasesWebKitGTKwebkit212SourceJavaScriptCoreb3airAirOpcodeopcodes">releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/b3/air/AirOpcode.opcodes</a></li>
<li><a href="#releasesWebKitGTKwebkit212SourceJavaScriptCoreb3testb3cpp">releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/b3/testb3.cpp</a></li>
<li><a href="#releasesWebKitGTKwebkit212SourceJavaScriptCoredfgDFGSpeculativeJITcpp">releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp</a></li>
<li><a href="#releasesWebKitGTKwebkit212SourceJavaScriptCoredfgDFGSpeculativeJIT64cpp">releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp</a></li>
<li><a href="#releasesWebKitGTKwebkit212SourceWebCoreChangeLog">releases/WebKitGTK/webkit-2.12/Source/WebCore/ChangeLog</a></li>
<li><a href="#releasesWebKitGTKwebkit212SourceWebCorecssjitFunctionCallh">releases/WebKitGTK/webkit-2.12/Source/WebCore/cssjit/FunctionCall.h</a></li>
<li><a href="#releasesWebKitGTKwebkit212SourceWebCorecssjitSelectorCompilercpp">releases/WebKitGTK/webkit-2.12/Source/WebCore/cssjit/SelectorCompiler.cpp</a></li>
</ul>
</div>
<div id="patch">
<h3>Diff</h3>
<a id="releasesWebKitGTKwebkit212SourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/ChangeLog (197850 => 197851)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/ChangeLog        2016-03-09 10:15:23 UTC (rev 197850)
+++ releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/ChangeLog        2016-03-09 10:28:11 UTC (rev 197851)
</span><span class="lines">@@ -1,3 +1,95 @@
</span><ins>+2016-03-06 Benjamin Poulain <bpoulain@apple.com>
+
+ [JSC] Improve codegen of Compare and Test
+ https://bugs.webkit.org/show_bug.cgi?id=155055
+
+ Reviewed by Filip Pizlo.
+
+ This patch introduces a few improvements on how we lower
+ Compare and Test with immediates:
+ -Add certain Immediate forms of ARM64.
+ -Use CBZ/CBNZ when possible on ARM64.
+ -When possible, convert a CMP into a TST
+ On some hardware, we can issue more TST simultaneously.
+
+ On x86, any TST+Jump is candidate for macro-fusion.
+ They are also smaller.
+ (sections 3.4.2.2 and 3.5.1.9)
+ -Do not load the mask immediate of a TST
+ if it only contains ones (mostly useful for ARM64
+ since that would not have been a valid immediate).
+
+ * assembler/MacroAssembler.h:
+ (JSC::MacroAssembler::compare32):
+ * assembler/MacroAssemblerARM64.h:
+ (JSC::MacroAssemblerARM64::moveConditionallyAfterFloatingPointCompare):
+ (JSC::MacroAssemblerARM64::moveDoubleConditionallyAfterFloatingPointCompare):
+ This is somewhat unrelated but I found that out while working
+ on moveDoubleConditionallyTest32:
+ If "thenCase" and "dest" are assigned the same register
+ by the allocator, then the first (f)fcsel would override
+ the "thenCase" and the second fcsel would always be "elseCase".
+
+ This is covered by testb3 but was only uncovered
+ after recent "Move" removals in lowering.
+
+ (JSC::MacroAssemblerARM64::moveConditionally32):
+ (JSC::MacroAssemblerARM64::moveConditionally64):
+ (JSC::MacroAssemblerARM64::moveConditionallyTest32):
+ (JSC::MacroAssemblerARM64::moveDoubleConditionally32):
+ (JSC::MacroAssemblerARM64::moveDoubleConditionally64):
+ (JSC::MacroAssemblerARM64::moveDoubleConditionallyTest32):
+ (JSC::MacroAssemblerARM64::branch32):
+ (JSC::MacroAssemblerARM64::branch64):
+ (JSC::MacroAssemblerARM64::branchTest32):
+ (JSC::MacroAssemblerARM64::test32):
+ The version taking an immediate was guarded by
+ (cond == Zero) || (cond == NonZero). That is overzealous,
+ and only needed for CBZ/CBNZ.
+
+ (JSC::MacroAssemblerARM64::branchTest64):
+ (JSC::MacroAssemblerARM64::compare32):
+ (JSC::MacroAssemblerARM64::compare64):
+ (JSC::MacroAssemblerARM64::commuteCompareToZeroIntoTest):
+ * assembler/MacroAssemblerX86Common.h:
+ (JSC::MacroAssemblerX86Common::moveConditionally32):
+ (JSC::MacroAssemblerX86Common::moveConditionallyTest32):
+ (JSC::MacroAssemblerX86Common::branch32):
+ (JSC::MacroAssemblerX86Common::test32):
+ (JSC::MacroAssemblerX86Common::branchTest32):
+ (JSC::MacroAssemblerX86Common::compare32):
+ (JSC::MacroAssemblerX86Common::commuteCompareToZeroIntoTest):
+ * assembler/MacroAssemblerX86_64.h:
+ (JSC::MacroAssemblerX86_64::compare64):
+ (JSC::MacroAssemblerX86_64::branch64):
+ (JSC::MacroAssemblerX86_64::moveConditionally64):
+ * b3/B3LowerToAir.cpp:
+ (JSC::B3::Air::LowerToAir::createGenericCompare):
+ Unfortunately this cannot be abstracted by the MacroAssembler.
+ Those immediates are not valid, we have to pick the better
+ for right away.
+
+ * b3/air/AirOpcode.opcodes:
+ * b3/testb3.cpp:
+ (JSC::B3::int64Operands):
+ (JSC::B3::modelCompare):
+ (JSC::B3::testCompareImpl):
+ (JSC::B3::testCompare):
+ (JSC::B3::b3Pow):
+ (JSC::B3::testPowDoubleByIntegerLoop):
+ Some versions of pow(double, int) do not return
+ the exact same bits as our integer loop.
+ Added a new version to have the same behavior
+ as the B3 loop.
+
+ (JSC::B3::run):
+ * dfg/DFGSpeculativeJIT.cpp:
+ (JSC::DFG::SpeculativeJIT::compilePeepHoleBooleanBranch):
+ * dfg/DFGSpeculativeJIT64.cpp:
+ (JSC::DFG::SpeculativeJIT::compileInt32Compare):
+ Comparing to an immediate is super common. Do not waste
+ a register for that!
+
</ins><span class="cx"> 2016-03-06 Filip Pizlo <fpizlo@apple.com>
</span><span class="cx">
</span><span class="cx"> DFG should know how to speculate StringOrOther
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit212SourceJavaScriptCoreassemblerMacroAssemblerh"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/assembler/MacroAssembler.h (197850 => 197851)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/assembler/MacroAssembler.h        2016-03-09 10:15:23 UTC (rev 197850)
+++ releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/assembler/MacroAssembler.h        2016-03-09 10:28:11 UTC (rev 197851)
</span><span class="lines">@@ -112,6 +112,7 @@
</span><span class="cx"> using MacroAssemblerBase::pop;
</span><span class="cx"> using MacroAssemblerBase::jump;
</span><span class="cx"> using MacroAssemblerBase::branch32;
</span><ins>+ using MacroAssemblerBase::compare32;
</ins><span class="cx"> using MacroAssemblerBase::move;
</span><span class="cx"> using MacroAssemblerBase::add32;
</span><span class="cx"> using MacroAssemblerBase::and32;
</span><span class="lines">@@ -400,6 +401,11 @@
</span><span class="cx"> return branch32(commute(cond), right, left);
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+ void compare32(RelationalCondition cond, Imm32 left, RegisterID right, RegisterID dest)
+ {
+ compare32(commute(cond), right, left, dest);
+ }
+
</ins><span class="cx"> void branchTestPtr(ResultCondition cond, RegisterID reg, Label target)
</span><span class="cx"> {
</span><span class="cx"> branchTestPtr(cond, reg).linkTo(target, this);
</span><span class="lines">@@ -1621,6 +1627,29 @@
</span><span class="cx"> return branch32(cond, left, right.asTrustedImm32());
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+ void compare32(RelationalCondition cond, RegisterID left, Imm32 right, RegisterID dest)
+ {
+ if (shouldBlind(right)) {
+ if (left != dest || haveScratchRegisterForBlinding()) {
+ RegisterID blindedConstantReg = dest;
+ if (left == dest)
+ blindedConstantReg = scratchRegisterForBlinding();
+ loadXorBlindedConstant(xorBlindConstant(right), blindedConstantReg);
+ compare32(cond, left, blindedConstantReg, dest);
+ return;
+ }
+ // If we don't have a scratch register available for use, we'll just
+ // place a random number of nops.
+ uint32_t nopCount = random() & 3;
+ while (nopCount--)
+ nop();
+ compare32(cond, left, right.asTrustedImm32(), dest);
+ return;
+ }
+
+ compare32(cond, left, right.asTrustedImm32(), dest);
+ }
+
</ins><span class="cx"> Jump branchAdd32(ResultCondition cond, RegisterID src, Imm32 imm, RegisterID dest)
</span><span class="cx"> {
</span><span class="cx"> if (src == dest)
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit212SourceJavaScriptCoreassemblerMacroAssemblerARM64h"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/assembler/MacroAssemblerARM64.h (197850 => 197851)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/assembler/MacroAssemblerARM64.h        2016-03-09 10:15:23 UTC (rev 197850)
+++ releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/assembler/MacroAssemblerARM64.h        2016-03-09 10:28:11 UTC (rev 197851)
</span><span class="lines">@@ -31,6 +31,7 @@
</span><span class="cx"> #include "ARM64Assembler.h"
</span><span class="cx"> #include "AbstractMacroAssembler.h"
</span><span class="cx"> #include <wtf/MathExtras.h>
</span><ins>+#include <wtf/Optional.h>
</ins><span class="cx">
</span><span class="cx"> namespace JSC {
</span><span class="cx">
</span><span class="lines">@@ -1685,12 +1686,12 @@
</span><span class="cx"> return;
</span><span class="cx"> }
</span><span class="cx"> if (cond == DoubleEqualOrUnordered) {
</span><del>- // If the compare is unordered, thenCase is copied to dest and the
</del><ins>+ // If the compare is unordered, thenCase is copied to elseCase and the
</ins><span class="cx"> // next csel has all arguments equal to thenCase.
</span><span class="cx"> // If the compare is ordered, dest is unchanged and EQ decides
</span><span class="cx"> // what value to set.
</span><del>- m_assembler.csel<datasize>(dest, thenCase, elseCase, ARM64Assembler::ConditionVS);
- m_assembler.csel<datasize>(dest, thenCase, dest, ARM64Assembler::ConditionEQ);
</del><ins>+ m_assembler.csel<datasize>(elseCase, thenCase, elseCase, ARM64Assembler::ConditionVS);
+ m_assembler.csel<datasize>(dest, thenCase, elseCase, ARM64Assembler::ConditionEQ);
</ins><span class="cx"> return;
</span><span class="cx"> }
</span><span class="cx"> m_assembler.csel<datasize>(dest, thenCase, elseCase, ARM64Condition(cond));
</span><span class="lines">@@ -1706,12 +1707,12 @@
</span><span class="cx"> return;
</span><span class="cx"> }
</span><span class="cx"> if (cond == DoubleEqualOrUnordered) {
</span><del>- // If the compare is unordered, thenCase is copied to dest and the
</del><ins>+ // If the compare is unordered, thenCase is copied to elseCase and the
</ins><span class="cx"> // next csel has all arguments equal to thenCase.
</span><span class="cx"> // If the compare is ordered, dest is unchanged and EQ decides
</span><span class="cx"> // what value to set.
</span><del>- m_assembler.fcsel<datasize>(dest, thenCase, elseCase, ARM64Assembler::ConditionVS);
- m_assembler.fcsel<datasize>(dest, thenCase, dest, ARM64Assembler::ConditionEQ);
</del><ins>+ m_assembler.fcsel<datasize>(elseCase, thenCase, elseCase, ARM64Assembler::ConditionVS);
+ m_assembler.fcsel<datasize>(dest, thenCase, elseCase, ARM64Assembler::ConditionEQ);
</ins><span class="cx"> return;
</span><span class="cx"> }
</span><span class="cx"> m_assembler.fcsel<datasize>(dest, thenCase, elseCase, ARM64Condition(cond));
</span><span class="lines">@@ -2003,6 +2004,13 @@
</span><span class="cx">
</span><span class="cx"> void moveConditionally32(RelationalCondition cond, RegisterID left, TrustedImm32 right, RegisterID thenCase, RegisterID elseCase, RegisterID dest)
</span><span class="cx"> {
</span><ins>+ if (!right.m_value) {
+ if (auto resultCondition = commuteCompareToZeroIntoTest(cond)) {
+ moveConditionallyTest32(*resultCondition, left, left, thenCase, elseCase, dest);
+ return;
+ }
+ }
+
</ins><span class="cx"> if (isUInt12(right.m_value))
</span><span class="cx"> m_assembler.cmp<32>(left, UInt12(right.m_value));
</span><span class="cx"> else if (isUInt12(-right.m_value))
</span><span class="lines">@@ -2026,6 +2034,26 @@
</span><span class="cx"> m_assembler.csel<64>(dest, thenCase, elseCase, ARM64Condition(cond));
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+ void moveConditionally64(RelationalCondition cond, RegisterID left, TrustedImm32 right, RegisterID thenCase, RegisterID elseCase, RegisterID dest)
+ {
+ if (!right.m_value) {
+ if (auto resultCondition = commuteCompareToZeroIntoTest(cond)) {
+ moveConditionallyTest64(*resultCondition, left, left, thenCase, elseCase, dest);
+ return;
+ }
+ }
+
+ if (isUInt12(right.m_value))
+ m_assembler.cmp<64>(left, UInt12(right.m_value));
+ else if (isUInt12(-right.m_value))
+ m_assembler.cmn<64>(left, UInt12(-right.m_value));
+ else {
+ moveToCachedReg(right, dataMemoryTempRegister());
+ m_assembler.cmp<64>(left, dataTempRegister);
+ }
+ m_assembler.csel<64>(dest, thenCase, elseCase, ARM64Condition(cond));
+ }
+
</ins><span class="cx"> void moveConditionallyTest32(ResultCondition cond, RegisterID testReg, RegisterID mask, RegisterID src, RegisterID dest)
</span><span class="cx"> {
</span><span class="cx"> m_assembler.tst<32>(testReg, mask);
</span><span class="lines">@@ -2038,6 +2066,12 @@
</span><span class="cx"> m_assembler.csel<32>(dest, thenCase, elseCase, ARM64Condition(cond));
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+ void moveConditionallyTest32(ResultCondition cond, RegisterID left, TrustedImm32 right, RegisterID thenCase, RegisterID elseCase, RegisterID dest)
+ {
+ test32(left, right);
+ m_assembler.csel<32>(dest, thenCase, elseCase, ARM64Condition(cond));
+ }
+
</ins><span class="cx"> void moveConditionallyTest64(ResultCondition cond, RegisterID testReg, RegisterID mask, RegisterID src, RegisterID dest)
</span><span class="cx"> {
</span><span class="cx"> m_assembler.tst<64>(testReg, mask);
</span><span class="lines">@@ -2058,6 +2092,13 @@
</span><span class="cx">
</span><span class="cx"> void moveDoubleConditionally32(RelationalCondition cond, RegisterID left, TrustedImm32 right, FPRegisterID thenCase, FPRegisterID elseCase, FPRegisterID dest)
</span><span class="cx"> {
</span><ins>+ if (!right.m_value) {
+ if (auto resultCondition = commuteCompareToZeroIntoTest(cond)) {
+ moveDoubleConditionallyTest32(*resultCondition, left, left, thenCase, elseCase, dest);
+ return;
+ }
+ }
+
</ins><span class="cx"> if (isUInt12(right.m_value))
</span><span class="cx"> m_assembler.cmp<32>(left, UInt12(right.m_value));
</span><span class="cx"> else if (isUInt12(-right.m_value))
</span><span class="lines">@@ -2077,6 +2118,13 @@
</span><span class="cx">
</span><span class="cx"> void moveDoubleConditionally64(RelationalCondition cond, RegisterID left, TrustedImm32 right, FPRegisterID thenCase, FPRegisterID elseCase, FPRegisterID dest)
</span><span class="cx"> {
</span><ins>+ if (!right.m_value) {
+ if (auto resultCondition = commuteCompareToZeroIntoTest(cond)) {
+ moveDoubleConditionallyTest64(*resultCondition, left, left, thenCase, elseCase, dest);
+ return;
+ }
+ }
+
</ins><span class="cx"> if (isUInt12(right.m_value))
</span><span class="cx"> m_assembler.cmp<64>(left, UInt12(right.m_value));
</span><span class="cx"> else if (isUInt12(-right.m_value))
</span><span class="lines">@@ -2094,6 +2142,12 @@
</span><span class="cx"> m_assembler.fcsel<64>(dest, thenCase, elseCase, ARM64Condition(cond));
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+ void moveDoubleConditionallyTest32(ResultCondition cond, RegisterID left, TrustedImm32 right, FPRegisterID thenCase, FPRegisterID elseCase, FPRegisterID dest)
+ {
+ test32(left, right);
+ m_assembler.fcsel<64>(dest, thenCase, elseCase, ARM64Condition(cond));
+ }
+
</ins><span class="cx"> void moveDoubleConditionallyTest64(ResultCondition cond, RegisterID left, RegisterID right, FPRegisterID thenCase, FPRegisterID elseCase, FPRegisterID dest)
</span><span class="cx"> {
</span><span class="cx"> m_assembler.tst<64>(left, right);
</span><span class="lines">@@ -2126,6 +2180,11 @@
</span><span class="cx">
</span><span class="cx"> Jump branch32(RelationalCondition cond, RegisterID left, TrustedImm32 right)
</span><span class="cx"> {
</span><ins>+ if (!right.m_value) {
+ if (auto resultCondition = commuteCompareToZeroIntoTest(cond))
+ return branchTest32(*resultCondition, left, left);
+ }
+
</ins><span class="cx"> if (isUInt12(right.m_value))
</span><span class="cx"> m_assembler.cmp<32>(left, UInt12(right.m_value));
</span><span class="cx"> else if (isUInt12(-right.m_value))
</span><span class="lines">@@ -2191,6 +2250,11 @@
</span><span class="cx">
</span><span class="cx"> Jump branch64(RelationalCondition cond, RegisterID left, TrustedImm32 right)
</span><span class="cx"> {
</span><ins>+ if (!right.m_value) {
+ if (auto resultCondition = commuteCompareToZeroIntoTest(cond))
+ return branchTest64(*resultCondition, left, left);
+ }
+
</ins><span class="cx"> if (isUInt12(right.m_value))
</span><span class="cx"> m_assembler.cmp<64>(left, UInt12(right.m_value));
</span><span class="cx"> else if (isUInt12(-right.m_value))
</span><span class="lines">@@ -2205,6 +2269,11 @@
</span><span class="cx"> Jump branch64(RelationalCondition cond, RegisterID left, TrustedImm64 right)
</span><span class="cx"> {
</span><span class="cx"> intptr_t immediate = right.m_value;
</span><ins>+ if (!immediate) {
+ if (auto resultCondition = commuteCompareToZeroIntoTest(cond))
+ return branchTest64(*resultCondition, left, left);
+ }
+
</ins><span class="cx"> if (isUInt12(immediate))
</span><span class="cx"> m_assembler.cmp<64>(left, UInt12(static_cast<int32_t>(immediate)));
</span><span class="cx"> else if (isUInt12(-immediate))
</span><span class="lines">@@ -2269,25 +2338,22 @@
</span><span class="cx">
</span><span class="cx"> Jump branchTest32(ResultCondition cond, RegisterID reg, RegisterID mask)
</span><span class="cx"> {
</span><ins>+ if (reg == mask && (cond == Zero || cond == NonZero))
+ return Jump(makeCompareAndBranch<32>(static_cast<ZeroCondition>(cond), reg));
</ins><span class="cx"> m_assembler.tst<32>(reg, mask);
</span><span class="cx"> return Jump(makeBranch(cond));
</span><span class="cx"> }
</span><span class="cx">
</span><del>- void test32(ResultCondition cond, RegisterID reg, TrustedImm32 mask = TrustedImm32(-1))
</del><ins>+ void test32(RegisterID reg, TrustedImm32 mask = TrustedImm32(-1))
</ins><span class="cx"> {
</span><span class="cx"> if (mask.m_value == -1)
</span><span class="cx"> m_assembler.tst<32>(reg, reg);
</span><span class="cx"> else {
</span><del>- bool testedWithImmediate = false;
- if ((cond == Zero) || (cond == NonZero)) {
- LogicalImmediate logicalImm = LogicalImmediate::create32(mask.m_value);
</del><ins>+ LogicalImmediate logicalImm = LogicalImmediate::create32(mask.m_value);
</ins><span class="cx">
</span><del>- if (logicalImm.isValid()) {
- m_assembler.tst<32>(reg, logicalImm);
- testedWithImmediate = true;
- }
- }
- if (!testedWithImmediate) {
</del><ins>+ if (logicalImm.isValid())
+ m_assembler.tst<32>(reg, logicalImm);
+ else {
</ins><span class="cx"> move(mask, getCachedDataTempRegisterIDAndInvalidate());
</span><span class="cx"> m_assembler.tst<32>(reg, dataTempRegister);
</span><span class="cx"> }
</span><span class="lines">@@ -2308,13 +2374,10 @@
</span><span class="cx"> } else if (hasOneBitSet(mask.m_value) && ((cond == Zero) || (cond == NonZero)))
</span><span class="cx"> return Jump(makeTestBitAndBranch(reg, getLSBSet(mask.m_value), static_cast<ZeroCondition>(cond)));
</span><span class="cx"> else {
</span><del>- if ((cond == Zero) || (cond == NonZero)) {
- LogicalImmediate logicalImm = LogicalImmediate::create32(mask.m_value);
-
- if (logicalImm.isValid()) {
- m_assembler.tst<32>(reg, logicalImm);
- return Jump(makeBranch(cond));
- }
</del><ins>+ LogicalImmediate logicalImm = LogicalImmediate::create32(mask.m_value);
+ if (logicalImm.isValid()) {
+ m_assembler.tst<32>(reg, logicalImm);
+ return Jump(makeBranch(cond));
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> move(mask, getCachedDataTempRegisterIDAndInvalidate());
</span><span class="lines">@@ -2337,6 +2400,8 @@
</span><span class="cx">
</span><span class="cx"> Jump branchTest64(ResultCondition cond, RegisterID reg, RegisterID mask)
</span><span class="cx"> {
</span><ins>+ if (reg == mask && (cond == Zero || cond == NonZero))
+ return Jump(makeCompareAndBranch<64>(static_cast<ZeroCondition>(cond), reg));
</ins><span class="cx"> m_assembler.tst<64>(reg, mask);
</span><span class="cx"> return Jump(makeBranch(cond));
</span><span class="cx"> }
</span><span class="lines">@@ -2350,13 +2415,11 @@
</span><span class="cx"> } else if (hasOneBitSet(mask.m_value) && ((cond == Zero) || (cond == NonZero)))
</span><span class="cx"> return Jump(makeTestBitAndBranch(reg, getLSBSet(mask.m_value), static_cast<ZeroCondition>(cond)));
</span><span class="cx"> else {
</span><del>- if ((cond == Zero) || (cond == NonZero)) {
- LogicalImmediate logicalImm = LogicalImmediate::create64(mask.m_value);
</del><ins>+ LogicalImmediate logicalImm = LogicalImmediate::create64(mask.m_value);
</ins><span class="cx">
</span><del>- if (logicalImm.isValid()) {
- m_assembler.tst<64>(reg, logicalImm);
- return Jump(makeBranch(cond));
- }
</del><ins>+ if (logicalImm.isValid()) {
+ m_assembler.tst<64>(reg, logicalImm);
+ return Jump(makeBranch(cond));
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> signExtend32ToPtr(mask, getCachedDataTempRegisterIDAndInvalidate());
</span><span class="lines">@@ -2773,8 +2836,21 @@
</span><span class="cx">
</span><span class="cx"> void compare32(RelationalCondition cond, RegisterID left, TrustedImm32 right, RegisterID dest)
</span><span class="cx"> {
</span><del>- move(right, getCachedDataTempRegisterIDAndInvalidate());
- m_assembler.cmp<32>(left, dataTempRegister);
</del><ins>+ if (!right.m_value) {
+ if (auto resultCondition = commuteCompareToZeroIntoTest(cond)) {
+ test32(*resultCondition, left, left, dest);
+ return;
+ }
+ }
+
+ if (isUInt12(right.m_value))
+ m_assembler.cmp<32>(left, UInt12(right.m_value));
+ else if (isUInt12(-right.m_value))
+ m_assembler.cmn<32>(left, UInt12(-right.m_value));
+ else {
+ move(right, getCachedDataTempRegisterIDAndInvalidate());
+ m_assembler.cmp<32>(left, dataTempRegister);
+ }
</ins><span class="cx"> m_assembler.cset<32>(dest, ARM64Condition(cond));
</span><span class="cx"> }
</span><span class="cx">
</span><span class="lines">@@ -2786,6 +2862,13 @@
</span><span class="cx">
</span><span class="cx"> void compare64(RelationalCondition cond, RegisterID left, TrustedImm32 right, RegisterID dest)
</span><span class="cx"> {
</span><ins>+ if (!right.m_value) {
+ if (auto resultCondition = commuteCompareToZeroIntoTest(cond)) {
+ test64(*resultCondition, left, left, dest);
+ return;
+ }
+ }
+
</ins><span class="cx"> signExtend32ToPtr(right, getCachedDataTempRegisterIDAndInvalidate());
</span><span class="cx"> m_assembler.cmp<64>(left, dataTempRegister);
</span><span class="cx"> m_assembler.cset<32>(dest, ARM64Condition(cond));
</span><span class="lines">@@ -2806,12 +2889,7 @@
</span><span class="cx">
</span><span class="cx"> void test32(ResultCondition cond, RegisterID src, TrustedImm32 mask, RegisterID dest)
</span><span class="cx"> {
</span><del>- if (mask.m_value == -1)
- m_assembler.tst<32>(src, src);
- else {
- signExtend32ToPtr(mask, getCachedDataTempRegisterIDAndInvalidate());
- m_assembler.tst<32>(src, dataTempRegister);
- }
</del><ins>+ test32(src, mask);
</ins><span class="cx"> m_assembler.cset<32>(dest, ARM64Condition(cond));
</span><span class="cx"> }
</span><span class="cx">
</span><span class="lines">@@ -2994,6 +3072,23 @@
</span><span class="cx"> return static_cast<RelationalCondition>(ARM64Assembler::invert(static_cast<ARM64Assembler::Condition>(cond)));
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+ static Optional<ResultCondition> commuteCompareToZeroIntoTest(RelationalCondition cond)
+ {
+ switch (cond) {
+ case Equal:
+ return Zero;
+ case NotEqual:
+ return NonZero;
+ case LessThan:
+ return Signed;
+ case GreaterThanOrEqual:
+ return PositiveOrZero;
+ break;
+ default:
+ return Nullopt;
+ }
+ }
+
</ins><span class="cx"> static FunctionPtr readCallTarget(CodeLocationCall call)
</span><span class="cx"> {
</span><span class="cx"> return FunctionPtr(reinterpret_cast<void(*)()>(ARM64Assembler::readCallTarget(call.dataLocation())));
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit212SourceJavaScriptCoreassemblerMacroAssemblerARMv7h"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/assembler/MacroAssemblerARMv7.h (197850 => 197851)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/assembler/MacroAssemblerARMv7.h        2016-03-09 10:15:23 UTC (rev 197850)
+++ releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/assembler/MacroAssemblerARMv7.h        2016-03-09 10:28:11 UTC (rev 197851)
</span><span class="lines">@@ -1343,7 +1343,7 @@
</span><span class="cx"> private:
</span><span class="cx">
</span><span class="cx"> // Should we be using TEQ for equal/not-equal?
</span><del>- void compare32(RegisterID left, TrustedImm32 right)
</del><ins>+ void compare32AndSetFlags(RegisterID left, TrustedImm32 right)
</ins><span class="cx"> {
</span><span class="cx"> int32_t imm = right.m_value;
</span><span class="cx"> ARMThumbImmediate armImm = ARMThumbImmediate::makeEncodedImm(imm);
</span><span class="lines">@@ -1357,7 +1357,8 @@
</span><span class="cx"> }
</span><span class="cx"> }
</span><span class="cx">
</span><del>- void test32(RegisterID reg, TrustedImm32 mask)
</del><ins>+public:
+ void test32(RegisterID reg, TrustedImm32 mask = TrustedImm32(-1))
</ins><span class="cx"> {
</span><span class="cx"> int32_t imm = mask.m_value;
</span><span class="cx">
</span><span class="lines">@@ -1381,12 +1382,6 @@
</span><span class="cx"> }
</span><span class="cx"> }
</span><span class="cx"> }
</span><del>-
-public:
- void test32(ResultCondition, RegisterID reg, TrustedImm32 mask)
- {
- test32(reg, mask);
- }
</del><span class="cx">
</span><span class="cx"> Jump branch(ResultCondition cond)
</span><span class="cx"> {
</span><span class="lines">@@ -1401,7 +1396,7 @@
</span><span class="cx">
</span><span class="cx"> Jump branch32(RelationalCondition cond, RegisterID left, TrustedImm32 right)
</span><span class="cx"> {
</span><del>- compare32(left, right);
</del><ins>+ compare32AndSetFlags(left, right);
</ins><span class="cx"> return Jump(makeBranch(cond));
</span><span class="cx"> }
</span><span class="cx">
</span><span class="lines">@@ -1459,7 +1454,7 @@
</span><span class="cx">
</span><span class="cx"> Jump branch8(RelationalCondition cond, RegisterID left, TrustedImm32 right)
</span><span class="cx"> {
</span><del>- compare32(left, right);
</del><ins>+ compare32AndSetFlags(left, right);
</ins><span class="cx"> return Jump(makeBranch(cond));
</span><span class="cx"> }
</span><span class="cx">
</span><span class="lines">@@ -1765,7 +1760,7 @@
</span><span class="cx">
</span><span class="cx"> void compare32(RelationalCondition cond, RegisterID left, TrustedImm32 right, RegisterID dest)
</span><span class="cx"> {
</span><del>- compare32(left, right);
</del><ins>+ compare32AndSetFlags(left, right);
</ins><span class="cx"> m_assembler.it(armV7Condition(cond), false);
</span><span class="cx"> m_assembler.mov(dest, ARMThumbImmediate::makeUInt16(1));
</span><span class="cx"> m_assembler.mov(dest, ARMThumbImmediate::makeUInt16(0));
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit212SourceJavaScriptCoreassemblerMacroAssemblerX86Commonh"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/assembler/MacroAssemblerX86Common.h (197850 => 197851)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/assembler/MacroAssemblerX86Common.h        2016-03-09 10:15:23 UTC (rev 197850)
+++ releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/assembler/MacroAssemblerX86Common.h        2016-03-09 10:28:11 UTC (rev 197851)
</span><span class="lines">@@ -30,6 +30,7 @@
</span><span class="cx">
</span><span class="cx"> #include "X86Assembler.h"
</span><span class="cx"> #include "AbstractMacroAssembler.h"
</span><ins>+#include <wtf/Optional.h>
</ins><span class="cx">
</span><span class="cx"> namespace JSC {
</span><span class="cx">
</span><span class="lines">@@ -1779,11 +1780,15 @@
</span><span class="cx">
</span><span class="cx"> void moveConditionally32(RelationalCondition cond, RegisterID left, TrustedImm32 right, RegisterID thenCase, RegisterID elseCase, RegisterID dest)
</span><span class="cx"> {
</span><del>- if (((cond == Equal) || (cond == NotEqual)) && !right.m_value)
- m_assembler.testl_rr(left, left);
- else
- m_assembler.cmpl_ir(right.m_value, left);
</del><ins>+ if (!right.m_value) {
+ if (auto resultCondition = commuteCompareToZeroIntoTest(cond)) {
+ moveConditionallyTest32(*resultCondition, left, left, thenCase, elseCase, dest);
+ return;
+ }
+ }
</ins><span class="cx">
</span><ins>+ m_assembler.cmpl_ir(right.m_value, left);
+
</ins><span class="cx"> if (thenCase != dest && elseCase != dest) {
</span><span class="cx"> move(elseCase, dest);
</span><span class="cx"> elseCase = dest;
</span><span class="lines">@@ -1821,7 +1826,7 @@
</span><span class="cx">
</span><span class="cx"> void moveConditionallyTest32(ResultCondition cond, RegisterID testReg, TrustedImm32 mask, RegisterID src, RegisterID dest)
</span><span class="cx"> {
</span><del>- test32(cond, testReg, mask);
</del><ins>+ test32(testReg, mask);
</ins><span class="cx"> cmov(x86Condition(cond), src, dest);
</span><span class="cx"> }
</span><span class="cx">
</span><span class="lines">@@ -1830,7 +1835,7 @@
</span><span class="cx"> ASSERT(isInvertible(cond));
</span><span class="cx"> ASSERT_WITH_MESSAGE(cond != Overflow, "TEST does not set the Overflow Flag.");
</span><span class="cx">
</span><del>- test32(cond, testReg, mask);
</del><ins>+ test32(testReg, mask);
</ins><span class="cx">
</span><span class="cx"> if (thenCase != dest && elseCase != dest) {
</span><span class="cx"> move(elseCase, dest);
</span><span class="lines">@@ -1960,10 +1965,12 @@
</span><span class="cx">
</span><span class="cx"> Jump branch32(RelationalCondition cond, RegisterID left, TrustedImm32 right)
</span><span class="cx"> {
</span><del>- if (((cond == Equal) || (cond == NotEqual)) && !right.m_value)
- m_assembler.testl_rr(left, left);
- else
- m_assembler.cmpl_ir(right.m_value, left);
</del><ins>+ if (!right.m_value) {
+ if (auto resultCondition = commuteCompareToZeroIntoTest(cond))
+ return branchTest32(*resultCondition, left, left);
+ }
+
+ m_assembler.cmpl_ir(right.m_value, left);
</ins><span class="cx"> return Jump(m_assembler.jCC(x86Condition(cond)));
</span><span class="cx"> }
</span><span class="cx">
</span><span class="lines">@@ -2002,7 +2009,7 @@
</span><span class="cx"> return Jump(m_assembler.jCC(x86Condition(cond)));
</span><span class="cx"> }
</span><span class="cx">
</span><del>- void test32(ResultCondition, RegisterID reg, TrustedImm32 mask = TrustedImm32(-1))
</del><ins>+ void test32(RegisterID reg, TrustedImm32 mask = TrustedImm32(-1))
</ins><span class="cx"> {
</span><span class="cx"> if (mask.m_value == -1)
</span><span class="cx"> m_assembler.testl_rr(reg, reg);
</span><span class="lines">@@ -2022,7 +2029,7 @@
</span><span class="cx">
</span><span class="cx"> Jump branchTest32(ResultCondition cond, RegisterID reg, TrustedImm32 mask = TrustedImm32(-1))
</span><span class="cx"> {
</span><del>- test32(cond, reg, mask);
</del><ins>+ test32(reg, mask);
</ins><span class="cx"> return branch(cond);
</span><span class="cx"> }
</span><span class="cx">
</span><span class="lines">@@ -2290,10 +2297,14 @@
</span><span class="cx">
</span><span class="cx"> void compare32(RelationalCondition cond, RegisterID left, TrustedImm32 right, RegisterID dest)
</span><span class="cx"> {
</span><del>- if (((cond == Equal) || (cond == NotEqual)) && !right.m_value)
- m_assembler.testl_rr(left, left);
- else
- m_assembler.cmpl_ir(right.m_value, left);
</del><ins>+ if (!right.m_value) {
+ if (auto resultCondition = commuteCompareToZeroIntoTest(cond)) {
+ test32(*resultCondition, left, left, dest);
+ return;
+ }
+ }
+
+ m_assembler.cmpl_ir(right.m_value, left);
</ins><span class="cx"> set32(x86Condition(cond), dest);
</span><span class="cx"> }
</span><span class="cx">
</span><span class="lines">@@ -2323,6 +2334,12 @@
</span><span class="cx"> set32(x86Condition(cond), dest);
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+ void test32(ResultCondition cond, RegisterID reg, TrustedImm32 mask, RegisterID dest)
+ {
+ test32(reg, mask);
+ set32(x86Condition(cond), dest);
+ }
+
</ins><span class="cx"> void setCarry(RegisterID dest)
</span><span class="cx"> {
</span><span class="cx"> set32(X86Assembler::ConditionC, dest);
</span><span class="lines">@@ -2396,6 +2413,23 @@
</span><span class="cx"> }
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+ static Optional<ResultCondition> commuteCompareToZeroIntoTest(RelationalCondition cond)
+ {
+ switch (cond) {
+ case Equal:
+ return Zero;
+ case NotEqual:
+ return NonZero;
+ case LessThan:
+ return Signed;
+ case GreaterThanOrEqual:
+ return PositiveOrZero;
+ break;
+ default:
+ return Nullopt;
+ }
+ }
+
</ins><span class="cx"> void nop()
</span><span class="cx"> {
</span><span class="cx"> m_assembler.nop();
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit212SourceJavaScriptCoreassemblerMacroAssemblerX86_64h"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/assembler/MacroAssemblerX86_64.h (197850 => 197851)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/assembler/MacroAssemblerX86_64.h        2016-03-09 10:15:23 UTC (rev 197850)
+++ releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/assembler/MacroAssemblerX86_64.h        2016-03-09 10:28:11 UTC (rev 197851)
</span><span class="lines">@@ -701,19 +701,21 @@
</span><span class="cx">
</span><span class="cx"> void compare64(RelationalCondition cond, RegisterID left, TrustedImm32 right, RegisterID dest)
</span><span class="cx"> {
</span><del>- if (((cond == Equal) || (cond == NotEqual)) && !right.m_value)
- m_assembler.testq_rr(left, left);
- else
- m_assembler.cmpq_ir(right.m_value, left);
- m_assembler.setCC_r(x86Condition(cond), dest);
- m_assembler.movzbl_rr(dest, dest);
</del><ins>+ if (!right.m_value) {
+ if (auto resultCondition = commuteCompareToZeroIntoTest(cond)) {
+ test64(*resultCondition, left, left, dest);
+ return;
+ }
+ }
+
+ m_assembler.cmpq_ir(right.m_value, left);
+ set32(x86Condition(cond), dest);
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> void compare64(RelationalCondition cond, RegisterID left, RegisterID right, RegisterID dest)
</span><span class="cx"> {
</span><span class="cx"> m_assembler.cmpq_rr(right, left);
</span><del>- m_assembler.setCC_r(x86Condition(cond), dest);
- m_assembler.movzbl_rr(dest, dest);
</del><ins>+ set32(x86Condition(cond), dest);
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> void compareDouble(DoubleCondition cond, FPRegisterID left, FPRegisterID right, RegisterID dest)
</span><span class="lines">@@ -758,9 +760,9 @@
</span><span class="cx">
</span><span class="cx"> Jump branch64(RelationalCondition cond, RegisterID left, TrustedImm32 right)
</span><span class="cx"> {
</span><del>- if (((cond == Equal) || (cond == NotEqual)) && !right.m_value) {
- m_assembler.testq_rr(left, left);
- return Jump(m_assembler.jCC(x86Condition(cond)));
</del><ins>+ if (!right.m_value) {
+ if (auto resultCondition = commuteCompareToZeroIntoTest(cond))
+ return branchTest64(*resultCondition, left, left);
</ins><span class="cx"> }
</span><span class="cx"> m_assembler.cmpq_ir(right.m_value, left);
</span><span class="cx"> return Jump(m_assembler.jCC(x86Condition(cond)));
</span><span class="lines">@@ -994,6 +996,28 @@
</span><span class="cx"> cmov(x86Condition(invert(cond)), elseCase, dest);
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+ void moveConditionally64(RelationalCondition cond, RegisterID left, TrustedImm32 right, RegisterID thenCase, RegisterID elseCase, RegisterID dest)
+ {
+ if (!right.m_value) {
+ if (auto resultCondition = commuteCompareToZeroIntoTest(cond)) {
+ moveConditionallyTest64(*resultCondition, left, left, thenCase, elseCase, dest);
+ return;
+ }
+ }
+
+ m_assembler.cmpq_ir(right.m_value, left);
+
+ if (thenCase != dest && elseCase != dest) {
+ move(elseCase, dest);
+ elseCase = dest;
+ }
+
+ if (elseCase == dest)
+ cmov(x86Condition(cond), thenCase, dest);
+ else
+ cmov(x86Condition(invert(cond)), elseCase, dest);
+ }
+
</ins><span class="cx"> void moveConditionallyTest64(ResultCondition cond, RegisterID testReg, RegisterID mask, RegisterID src, RegisterID dest)
</span><span class="cx"> {
</span><span class="cx"> m_assembler.testq_rr(testReg, mask);
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit212SourceJavaScriptCoreb3B3LowerToAircpp"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/b3/B3LowerToAir.cpp (197850 => 197851)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/b3/B3LowerToAir.cpp        2016-03-09 10:15:23 UTC (rev 197850)
+++ releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/b3/B3LowerToAir.cpp        2016-03-09 10:28:11 UTC (rev 197851)
</span><span class="lines">@@ -1374,14 +1374,30 @@
</span><span class="cx">
</span><span class="cx"> // Now handle test's that involve an immediate and a tmp.
</span><span class="cx">
</span><del>- if (leftImm && leftImm.isRepresentableAs<uint32_t>()) {
- if (Inst result = tryTest(Arg::Width32, leftImm, tmpPromise(right)))
- return result;
</del><ins>+ if (leftImm) {
+ if ((width == Arg::Width32 && leftImm.value() == 0xffffffff)
+ || (width == Arg::Width64 && leftImm.value() == -1)) {
+ ArgPromise argPromise = tmpPromise(right);
+ if (Inst result = tryTest(width, argPromise, argPromise))
+ return result;
+ }
+ if (leftImm.isRepresentableAs<uint32_t>()) {
+ if (Inst result = tryTest(Arg::Width32, leftImm, tmpPromise(right)))
+ return result;
+ }
</ins><span class="cx"> }
</span><span class="cx">
</span><del>- if (rightImm && rightImm.isRepresentableAs<uint32_t>()) {
- if (Inst result = tryTest(Arg::Width32, tmpPromise(left), rightImm))
- return result;
</del><ins>+ if (rightImm) {
+ if ((width == Arg::Width32 && rightImm.value() == 0xffffffff)
+ || (width == Arg::Width64 && rightImm.value() == -1)) {
+ ArgPromise argPromise = tmpPromise(left);
+ if (Inst result = tryTest(width, argPromise, argPromise))
+ return result;
+ }
+ if (rightImm.isRepresentableAs<uint32_t>()) {
+ if (Inst result = tryTest(Arg::Width32, tmpPromise(left), rightImm))
+ return result;
+ }
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> // Finally, just do tmp's.
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit212SourceJavaScriptCoreb3airAirOpcodeopcodes"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/b3/air/AirOpcode.opcodes (197850 => 197851)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/b3/air/AirOpcode.opcodes        2016-03-09 10:15:23 UTC (rev 197850)
+++ releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/b3/air/AirOpcode.opcodes        2016-03-09 10:28:11 UTC (rev 197851)
</span><span class="lines">@@ -613,7 +613,7 @@
</span><span class="cx">
</span><span class="cx"> Compare32 U:G:32, U:G:32, U:G:32, ZD:G:32
</span><span class="cx"> RelCond, Tmp, Tmp, Tmp
</span><del>- x86: RelCond, Tmp, Imm, Tmp
</del><ins>+ RelCond, Tmp, Imm, Tmp
</ins><span class="cx">
</span><span class="cx"> 64: Compare64 U:G:32, U:G:64, U:G:64, ZD:G:32
</span><span class="cx"> RelCond, Tmp, Tmp, Tmp
</span><span class="lines">@@ -622,6 +622,7 @@
</span><span class="cx"> Test32 U:G:32, U:G:32, U:G:32, ZD:G:32
</span><span class="cx"> x86: ResCond, Addr, Imm, Tmp
</span><span class="cx"> ResCond, Tmp, Tmp, Tmp
</span><ins>+ ResCond, Tmp, BitImm, Tmp
</ins><span class="cx">
</span><span class="cx"> 64: Test64 U:G:32, U:G:64, U:G:64, ZD:G:32
</span><span class="cx"> x86: ResCond, Tmp, Imm, Tmp
</span><span class="lines">@@ -662,7 +663,7 @@
</span><span class="cx">
</span><span class="cx"> BranchTest32 U:G:32, U:G:32, U:G:32 /branch
</span><span class="cx"> ResCond, Tmp, Tmp
</span><del>- x86: ResCond, Tmp, Imm
</del><ins>+ ResCond, Tmp, BitImm
</ins><span class="cx"> x86: ResCond, Addr, Imm
</span><span class="cx"> x86: ResCond, Index, Imm
</span><span class="cx">
</span><span class="lines">@@ -670,7 +671,7 @@
</span><span class="cx"> # BranchTest32 in most cases where you use an immediate.
</span><span class="cx"> 64: BranchTest64 U:G:32, U:G:64, U:G:64 /branch
</span><span class="cx"> ResCond, Tmp, Tmp
</span><del>- x86: ResCond, Tmp, Imm
</del><ins>+ ResCond, Tmp, BitImm64
</ins><span class="cx"> x86: ResCond, Addr, Imm
</span><span class="cx"> x86: ResCond, Addr, Tmp
</span><span class="cx"> x86: ResCond, Index, Imm
</span><span class="lines">@@ -748,6 +749,7 @@
</span><span class="cx">
</span><span class="cx"> 64: MoveConditionally64 U:G:32, U:G:64, U:G:64, U:G:Ptr, U:G:Ptr, D:G:Ptr
</span><span class="cx"> RelCond, Tmp, Tmp, Tmp, Tmp, Tmp
</span><ins>+ RelCond, Tmp, Imm, Tmp, Tmp, Tmp
</ins><span class="cx">
</span><span class="cx"> MoveConditionallyTest32 U:G:32, U:G:32, U:G:32, U:G:Ptr, UD:G:Ptr
</span><span class="cx"> ResCond, Tmp, Tmp, Tmp, Tmp
</span><span class="lines">@@ -755,7 +757,7 @@
</span><span class="cx">
</span><span class="cx"> MoveConditionallyTest32 U:G:32, U:G:32, U:G:32, U:G:Ptr, U:G:Ptr, D:G:Ptr
</span><span class="cx"> ResCond, Tmp, Tmp, Tmp, Tmp, Tmp
</span><del>- x86: ResCond, Tmp, Imm, Tmp, Tmp, Tmp
</del><ins>+ ResCond, Tmp, BitImm, Tmp, Tmp, Tmp
</ins><span class="cx">
</span><span class="cx"> 64: MoveConditionallyTest64 U:G:32, U:G:64, U:G:64, U:G:Ptr, UD:G:Ptr
</span><span class="cx"> ResCond, Tmp, Tmp, Tmp, Tmp
</span><span class="lines">@@ -795,7 +797,7 @@
</span><span class="cx">
</span><span class="cx"> MoveDoubleConditionallyTest32 U:G:32, U:G:32, U:G:32, U:F:64, U:F:64, D:F:64
</span><span class="cx"> ResCond, Tmp, Tmp, Tmp, Tmp, Tmp
</span><del>- x86: ResCond, Tmp, Imm, Tmp, Tmp, Tmp
</del><ins>+ ResCond, Tmp, BitImm, Tmp, Tmp, Tmp
</ins><span class="cx"> x86: ResCond, Addr, Imm, Tmp, Tmp, Tmp
</span><span class="cx"> x86: ResCond, Index, Imm, Tmp, Tmp, Tmp
</span><span class="cx">
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit212SourceJavaScriptCoreb3testb3cpp"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/b3/testb3.cpp (197850 => 197851)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/b3/testb3.cpp        2016-03-09 10:15:23 UTC (rev 197850)
+++ releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/b3/testb3.cpp        2016-03-09 10:28:11 UTC (rev 197851)
</span><span class="lines">@@ -150,10 +150,10 @@
</span><span class="cx"> static Vector<Int64Operand> int64Operands()
</span><span class="cx"> {
</span><span class="cx"> Vector<Int64Operand> operands;
</span><del>- for (const auto& doubleOperand : floatingPointOperands<double>())
- operands.append({ doubleOperand.name, bitwise_cast<int64_t>(doubleOperand.value) });
</del><span class="cx"> operands.append({ "1", 1 });
</span><span class="cx"> operands.append({ "-1", -1 });
</span><ins>+ operands.append({ "42", 42 });
+ operands.append({ "-42", -42 });
</ins><span class="cx"> operands.append({ "int64-max", std::numeric_limits<int64_t>::max() });
</span><span class="cx"> operands.append({ "int64-min", std::numeric_limits<int64_t>::min() });
</span><span class="cx"> operands.append({ "int32-max", std::numeric_limits<int32_t>::max() });
</span><span class="lines">@@ -8822,7 +8822,8 @@
</span><span class="cx"> }
</span><span class="cx"> }
</span><span class="cx">
</span><del>-int modelCompare(B3::Opcode opcode, int left, int right)
</del><ins>+template<typename InputType>
+InputType modelCompare(B3::Opcode opcode, InputType left, InputType right)
</ins><span class="cx"> {
</span><span class="cx"> switch (opcode) {
</span><span class="cx"> case Equal:
</span><span class="lines">@@ -8838,13 +8839,17 @@
</span><span class="cx"> case GreaterEqual:
</span><span class="cx"> return left >= right;
</span><span class="cx"> case Above:
</span><del>- return static_cast<unsigned>(left) > static_cast<unsigned>(right);
</del><ins>+ return static_cast<typename std::make_unsigned<InputType>::type>(left) >
+ static_cast<typename std::make_unsigned<InputType>::type>(right);
</ins><span class="cx"> case Below:
</span><del>- return static_cast<unsigned>(left) < static_cast<unsigned>(right);
</del><ins>+ return static_cast<typename std::make_unsigned<InputType>::type>(left) <
+ static_cast<typename std::make_unsigned<InputType>::type>(right);
</ins><span class="cx"> case AboveEqual:
</span><del>- return static_cast<unsigned>(left) >= static_cast<unsigned>(right);
</del><ins>+ return static_cast<typename std::make_unsigned<InputType>::type>(left) >=
+ static_cast<typename std::make_unsigned<InputType>::type>(right);
</ins><span class="cx"> case BelowEqual:
</span><del>- return static_cast<unsigned>(left) <= static_cast<unsigned>(right);
</del><ins>+ return static_cast<typename std::make_unsigned<InputType>::type>(left) <=
+ static_cast<typename std::make_unsigned<InputType>::type>(right);
</ins><span class="cx"> case BitAnd:
</span><span class="cx"> return !!(left & right);
</span><span class="cx"> default:
</span><span class="lines">@@ -8939,7 +8944,8 @@
</span><span class="cx">
</span><span class="cx"> void testCompareImpl(B3::Opcode opcode, int64_t left, int64_t right)
</span><span class="cx"> {
</span><del>- int result = modelCompare(opcode, left, right);
</del><ins>+ int64_t result = modelCompare(opcode, left, right);
+ int32_t int32Result = modelCompare(opcode, static_cast<int32_t>(left), static_cast<int32_t>(right));
</ins><span class="cx">
</span><span class="cx"> // Test tmp-to-tmp.
</span><span class="cx"> genericTestCompare(
</span><span class="lines">@@ -8963,7 +8969,7 @@
</span><span class="cx"> proc, Trunc, Origin(),
</span><span class="cx"> block->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
</span><span class="cx"> },
</span><del>- left, right, result);
</del><ins>+ left, right, int32Result);
</ins><span class="cx">
</span><span class="cx"> // Test imm-to-tmp.
</span><span class="cx"> genericTestCompare(
</span><span class="lines">@@ -8985,7 +8991,7 @@
</span><span class="cx"> proc, Trunc, Origin(),
</span><span class="cx"> block->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
</span><span class="cx"> },
</span><del>- left, right, result);
</del><ins>+ left, right, int32Result);
</ins><span class="cx">
</span><span class="cx"> // Test tmp-to-imm.
</span><span class="cx"> genericTestCompare(
</span><span class="lines">@@ -9007,7 +9013,7 @@
</span><span class="cx"> [&] (BasicBlock* block, Procedure& proc) {
</span><span class="cx"> return block->appendNew<Const32Value>(proc, Origin(), right);
</span><span class="cx"> },
</span><del>- left, right, result);
</del><ins>+ left, right, int32Result);
</ins><span class="cx">
</span><span class="cx"> // Test imm-to-imm.
</span><span class="cx"> genericTestCompare(
</span><span class="lines">@@ -9027,7 +9033,7 @@
</span><span class="cx"> [&] (BasicBlock* block, Procedure& proc) {
</span><span class="cx"> return block->appendNew<Const32Value>(proc, Origin(), right);
</span><span class="cx"> },
</span><del>- left, right, result);
</del><ins>+ left, right, int32Result);
</ins><span class="cx">
</span><span class="cx"> testCompareLoad<int32_t>(opcode, Load, left, right);
</span><span class="cx"> testCompareLoad<int8_t>(opcode, Load8S, left, right);
</span><span class="lines">@@ -9036,37 +9042,11 @@
</span><span class="cx"> testCompareLoad<uint16_t>(opcode, Load16Z, left, right);
</span><span class="cx"> }
</span><span class="cx">
</span><del>-void testCompare(B3::Opcode opcode, int left, int right)
</del><ins>+void testCompare(B3::Opcode opcode, int64_t left, int64_t right)
</ins><span class="cx"> {
</span><del>- auto variants = [&] (int left, int right) {
- testCompareImpl(opcode, left, right);
- testCompareImpl(opcode, left, right + 1);
- testCompareImpl(opcode, left, right - 1);
-
- auto multipliedTests = [&] (int factor) {
- testCompareImpl(opcode, left * factor, right);
- testCompareImpl(opcode, left * factor, right + 1);
- testCompareImpl(opcode, left * factor, right - 1);
-
- testCompareImpl(opcode, left, right * factor);
- testCompareImpl(opcode, left, (right + 1) * factor);
- testCompareImpl(opcode, left, (right - 1) * factor);
-
- testCompareImpl(opcode, left * factor, right * factor);
- testCompareImpl(opcode, left * factor, (right + 1) * factor);
- testCompareImpl(opcode, left * factor, (right - 1) * factor);
- };
-
- multipliedTests(10);
- multipliedTests(100);
- multipliedTests(1000);
- multipliedTests(100000);
- };
-
- variants(left, right);
- variants(-left, right);
- variants(left, -right);
- variants(-left, -right);
</del><ins>+ testCompareImpl(opcode, left, right);
+ testCompareImpl(opcode, left, right + 1);
+ testCompareImpl(opcode, left, right - 1);
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> void testEqualDouble(double left, double right, bool result)
</span><span class="lines">@@ -10899,6 +10879,20 @@
</span><span class="cx"> CHECK(invoke<int>(*code, true, false) == 667);
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+double b3Pow(double x, int y)
+{
+ if (y < 0 || y > 1000)
+ return pow(x, y);
+ double result = 1;
+ while (y) {
+ if (y & 1)
+ result *= x;
+ x *= x;
+ y >>= 1;
+ }
+ return result;
+}
+
</ins><span class="cx"> void testPowDoubleByIntegerLoop(double xOperand, int32_t yOperand)
</span><span class="cx"> {
</span><span class="cx"> Procedure proc;
</span><span class="lines">@@ -10911,7 +10905,7 @@
</span><span class="cx"> BasicBlock* continuation = result.first;
</span><span class="cx"> continuation->appendNew<ControlValue>(proc, Return, Origin(), result.second);
</span><span class="cx">
</span><del>- CHECK(isIdentical(compileAndRun<double>(proc, xOperand, yOperand), pow(xOperand, yOperand)));
</del><ins>+ CHECK(isIdentical(compileAndRun<double>(proc, xOperand, yOperand), b3Pow(xOperand, yOperand)));
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> void testTruncOrHigh()
</span><span class="lines">@@ -12248,20 +12242,18 @@
</span><span class="cx"> RUN(testCheckMulArgumentAliasing64());
</span><span class="cx"> RUN(testCheckMulArgumentAliasing32());
</span><span class="cx">
</span><del>- RUN(testCompare(Equal, 42, 42));
- RUN(testCompare(NotEqual, 42, 42));
- RUN(testCompare(LessThan, 42, 42));
- RUN(testCompare(GreaterThan, 42, 42));
- RUN(testCompare(LessEqual, 42, 42));
- RUN(testCompare(GreaterEqual, 42, 42));
- RUN(testCompare(Below, 42, 42));
- RUN(testCompare(Above, 42, 42));
- RUN(testCompare(BelowEqual, 42, 42));
- RUN(testCompare(AboveEqual, 42, 42));
</del><ins>+ RUN_BINARY([](int32_t a, int32_t b) { testCompare(Equal, a, b); }, int64Operands(), int64Operands());
+ RUN_BINARY([](int32_t a, int32_t b) { testCompare(NotEqual, a, b); }, int64Operands(), int64Operands());
+ RUN_BINARY([](int32_t a, int32_t b) { testCompare(LessThan, a, b); }, int64Operands(), int64Operands());
+ RUN_BINARY([](int32_t a, int32_t b) { testCompare(GreaterThan, a, b); }, int64Operands(), int64Operands());
+ RUN_BINARY([](int32_t a, int32_t b) { testCompare(LessEqual, a, b); }, int64Operands(), int64Operands());
+ RUN_BINARY([](int32_t a, int32_t b) { testCompare(GreaterEqual, a, b); }, int64Operands(), int64Operands());
+ RUN_BINARY([](int32_t a, int32_t b) { testCompare(Below, a, b); }, int64Operands(), int64Operands());
+ RUN_BINARY([](int32_t a, int32_t b) { testCompare(Above, a, b); }, int64Operands(), int64Operands());
+ RUN_BINARY([](int32_t a, int32_t b) { testCompare(BelowEqual, a, b); }, int64Operands(), int64Operands());
+ RUN_BINARY([](int32_t a, int32_t b) { testCompare(AboveEqual, a, b); }, int64Operands(), int64Operands());
+ RUN_BINARY([](int32_t a, int32_t b) { testCompare(BitAnd, a, b); }, int64Operands(), int64Operands());
</ins><span class="cx">
</span><del>- RUN(testCompare(BitAnd, 42, 42));
- RUN(testCompare(BitAnd, 42, 0));
-
</del><span class="cx"> RUN(testEqualDouble(42, 42, true));
</span><span class="cx"> RUN(testEqualDouble(0, -0, true));
</span><span class="cx"> RUN(testEqualDouble(42, 43, false));
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit212SourceJavaScriptCoredfgDFGSpeculativeJITcpp"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp (197850 => 197851)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp        2016-03-09 10:15:23 UTC (rev 197850)
+++ releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp        2016-03-09 10:28:11 UTC (rev 197851)
</span><span class="lines">@@ -1293,14 +1293,14 @@
</span><span class="cx"> notTaken = tmp;
</span><span class="cx"> }
</span><span class="cx">
</span><del>- if (node->child1()->isBooleanConstant()) {
- bool imm = node->child1()->asBoolean();
</del><ins>+ if (node->child1()->isInt32Constant()) {
+ int32_t imm = node->child1()->asInt32();
</ins><span class="cx"> SpeculateBooleanOperand op2(this, node->child2());
</span><del>- branch32(condition, JITCompiler::Imm32(static_cast<int32_t>(JSValue::encode(jsBoolean(imm)))), op2.gpr(), taken);
- } else if (node->child2()->isBooleanConstant()) {
</del><ins>+ branch32(condition, JITCompiler::Imm32(imm), op2.gpr(), taken);
+ } else if (node->child2()->isInt32Constant()) {
</ins><span class="cx"> SpeculateBooleanOperand op1(this, node->child1());
</span><del>- bool imm = node->child2()->asBoolean();
- branch32(condition, op1.gpr(), JITCompiler::Imm32(static_cast<int32_t>(JSValue::encode(jsBoolean(imm)))), taken);
</del><ins>+ int32_t imm = node->child2()->asInt32();
+ branch32(condition, op1.gpr(), JITCompiler::Imm32(imm), taken);
</ins><span class="cx"> } else {
</span><span class="cx"> SpeculateBooleanOperand op1(this, node->child1());
</span><span class="cx"> SpeculateBooleanOperand op2(this, node->child2());
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit212SourceJavaScriptCoredfgDFGSpeculativeJIT64cpp"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp (197850 => 197851)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp        2016-03-09 10:15:23 UTC (rev 197850)
+++ releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp        2016-03-09 10:28:11 UTC (rev 197851)
</span><span class="lines">@@ -1566,15 +1566,34 @@
</span><span class="cx">
</span><span class="cx"> void SpeculativeJIT::compileInt32Compare(Node* node, MacroAssembler::RelationalCondition condition)
</span><span class="cx"> {
</span><del>- SpeculateInt32Operand op1(this, node->child1());
- SpeculateInt32Operand op2(this, node->child2());
- GPRTemporary result(this, Reuse, op1, op2);
-
- m_jit.compare32(condition, op1.gpr(), op2.gpr(), result.gpr());
-
- // If we add a DataFormatBool, we should use it here.
- m_jit.or32(TrustedImm32(ValueFalse), result.gpr());
- jsValueResult(result.gpr(), m_currentNode, DataFormatJSBoolean);
</del><ins>+ if (node->child1()->isInt32Constant()) {
+ SpeculateInt32Operand op2(this, node->child2());
+ GPRTemporary result(this, Reuse, op2);
+ int32_t imm = node->child1()->asInt32();
+ m_jit.compare32(condition, JITCompiler::Imm32(imm), op2.gpr(), result.gpr());
+
+ // If we add a DataFormatBool, we should use it here.
+ m_jit.or32(TrustedImm32(ValueFalse), result.gpr());
+ jsValueResult(result.gpr(), m_currentNode, DataFormatJSBoolean);
+ } else if (node->child2()->isInt32Constant()) {
+ SpeculateInt32Operand op1(this, node->child1());
+ GPRTemporary result(this, Reuse, op1);
+ int32_t imm = node->child2()->asInt32();
+ m_jit.compare32(condition, op1.gpr(), JITCompiler::Imm32(imm), result.gpr());
+
+ // If we add a DataFormatBool, we should use it here.
+ m_jit.or32(TrustedImm32(ValueFalse), result.gpr());
+ jsValueResult(result.gpr(), m_currentNode, DataFormatJSBoolean);
+ } else {
+ SpeculateInt32Operand op1(this, node->child1());
+ SpeculateInt32Operand op2(this, node->child2());
+ GPRTemporary result(this, Reuse, op1, op2);
+ m_jit.compare32(condition, op1.gpr(), op2.gpr(), result.gpr());
+
+ // If we add a DataFormatBool, we should use it here.
+ m_jit.or32(TrustedImm32(ValueFalse), result.gpr());
+ jsValueResult(result.gpr(), m_currentNode, DataFormatJSBoolean);
+ }
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> void SpeculativeJIT::compileInt52Compare(Node* node, MacroAssembler::RelationalCondition condition)
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit212SourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.12/Source/WebCore/ChangeLog (197850 => 197851)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.12/Source/WebCore/ChangeLog        2016-03-09 10:15:23 UTC (rev 197850)
+++ releases/WebKitGTK/webkit-2.12/Source/WebCore/ChangeLog        2016-03-09 10:28:11 UTC (rev 197851)
</span><span class="lines">@@ -1,3 +1,13 @@
</span><ins>+2016-03-06 Benjamin Poulain <bpoulain@apple.com>
+
+ [JSC] Improve codegen of Compare and Test
+ https://bugs.webkit.org/show_bug.cgi?id=155055
+
+ Reviewed by Filip Pizlo.
+
+ * cssjit/FunctionCall.h:
+ (WebCore::FunctionCall::callAndBranchOnCondition):
+
</ins><span class="cx"> 2016-03-04 Carlos Garcia Campos <cgarcia@igalia.com>
</span><span class="cx">
</span><span class="cx"> [GTK] Scrollbars are broken again with GTK+ >= 3.19.11
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit212SourceWebCorecssjitFunctionCallh"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.12/Source/WebCore/cssjit/FunctionCall.h (197850 => 197851)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.12/Source/WebCore/cssjit/FunctionCall.h        2016-03-09 10:15:23 UTC (rev 197850)
+++ releases/WebKitGTK/webkit-2.12/Source/WebCore/cssjit/FunctionCall.h        2016-03-09 10:28:11 UTC (rev 197851)
</span><span class="lines">@@ -87,7 +87,7 @@
</span><span class="cx"> JSC::MacroAssembler::Jump callAndBranchOnCondition(JSC::MacroAssembler::ResultCondition condition, JSC::MacroAssembler::TrustedImm32 mask)
</span><span class="cx"> {
</span><span class="cx"> prepareAndCall();
</span><del>- m_assembler.test32(condition, JSC::GPRInfo::returnValueGPR, mask);
</del><ins>+ m_assembler.test32(JSC::GPRInfo::returnValueGPR, mask);
</ins><span class="cx"> cleanupPostCall();
</span><span class="cx"> return m_assembler.branch(condition);
</span><span class="cx"> }
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit212SourceWebCorecssjitSelectorCompilercpp"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.12/Source/WebCore/cssjit/SelectorCompiler.cpp (197850 => 197851)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.12/Source/WebCore/cssjit/SelectorCompiler.cpp        2016-03-09 10:15:23 UTC (rev 197850)
+++ releases/WebKitGTK/webkit-2.12/Source/WebCore/cssjit/SelectorCompiler.cpp        2016-03-09 10:28:11 UTC (rev 197851)
</span><span class="lines">@@ -2389,7 +2389,7 @@
</span><span class="cx"> LocalRegister divisorRegister(m_registerAllocator);
</span><span class="cx"> m_assembler.move(Assembler::TrustedImm64(divisor), divisorRegister);
</span><span class="cx"> m_assembler.m_assembler.idivl_r(divisorRegister);
</span><del>- m_assembler.test32(condition, remainder);
</del><ins>+ m_assembler.test32(remainder);
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> // 3) Return RAX and RDX.
</span></span></pre>
</div>
</div>
</body>
</html>