<!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>[153133] 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/153133">153133</a></dd>
<dt>Author</dt> <dd>oliver@apple.com</dd>
<dt>Date</dt> <dd>2013-07-24 20:59:06 -0700 (Wed, 24 Jul 2013)</dd>
</dl>

<h3>Log Message</h3>
<pre>fourthTier: FTL should support double variables
https://bugs.webkit.org/show_bug.cgi?id=113624

Reviewed by Geoffrey Garen.

Made all of the operations that the FTL already supports, also support doubles.
OSR exit already basically had everything it needed, so no changes there. This
mostly just glues together bits of DFG IR to LLVM IR, in a straight-forward way.

* ftl/FTLAbbreviations.h:
(FTL):
(JSC::FTL::doubleType):
(JSC::FTL::constReal):
(JSC::FTL::buildPhi):
(JSC::FTL::addIncoming):
(JSC::FTL::buildFAdd):
(JSC::FTL::buildFSub):
(JSC::FTL::buildFMul):
(JSC::FTL::buildFNeg):
(JSC::FTL::buildSIToFP):
(JSC::FTL::buildUIToFP):
(JSC::FTL::buildBitCast):
(JSC::FTL::buildFCmp):
* ftl/FTLCapabilities.cpp:
(JSC::FTL::canCompile):
* ftl/FTLCommonValues.cpp:
(JSC::FTL::CommonValues::CommonValues):
* ftl/FTLCommonValues.h:
(CommonValues):
* ftl/FTLLowerDFGToLLVM.cpp:
(JSC::FTL::LowerDFGToLLVM::LowerDFGToLLVM):
(JSC::FTL::LowerDFGToLLVM::lower):
(JSC::FTL::LowerDFGToLLVM::compileGetLocal):
(JSC::FTL::LowerDFGToLLVM::compileSetLocal):
(JSC::FTL::LowerDFGToLLVM::compileAdd):
(JSC::FTL::LowerDFGToLLVM::compileArithSub):
(JSC::FTL::LowerDFGToLLVM::compileArithMul):
(JSC::FTL::LowerDFGToLLVM::compileArithNegate):
(JSC::FTL::LowerDFGToLLVM::compileUInt32ToNumber):
(JSC::FTL::LowerDFGToLLVM::compileGetByVal):
(JSC::FTL::LowerDFGToLLVM::compileCompareEq):
(JSC::FTL::LowerDFGToLLVM::compileCompareLess):
(JSC::FTL::LowerDFGToLLVM::lowDouble):
(LowerDFGToLLVM):
(JSC::FTL::LowerDFGToLLVM::lowJSValue):
(JSC::FTL::LowerDFGToLLVM::isCellOrMisc):
(JSC::FTL::LowerDFGToLLVM::unboxDouble):
(JSC::FTL::LowerDFGToLLVM::boxDouble):
(JSC::FTL::LowerDFGToLLVM::speculate):
(JSC::FTL::LowerDFGToLLVM::speculateNumber):
(JSC::FTL::LowerDFGToLLVM::speculateRealNumber):
(JSC::FTL::LowerDFGToLLVM::appendOSRExit):
(JSC::FTL::LowerDFGToLLVM::addExitArgumentForNode):
* ftl/FTLOutput.h:
(JSC::FTL::Output::constDouble):
(Output):
(JSC::FTL::Output::phi):
(JSC::FTL::Output::doubleAdd):
(JSC::FTL::Output::doubleSub):
(JSC::FTL::Output::doubleMul):
(JSC::FTL::Output::doubleNeg):
(JSC::FTL::Output::intToFP):
(JSC::FTL::Output::intToDouble):
(JSC::FTL::Output::unsignedToFP):
(JSC::FTL::Output::unsignedToDouble):
(JSC::FTL::Output::bitCast):
(JSC::FTL::Output::loadDouble):
(JSC::FTL::Output::storeDouble):
(JSC::FTL::Output::doubleEqual):
(JSC::FTL::Output::doubleNotEqualOrUnordered):
(JSC::FTL::Output::doubleLessThan):
(JSC::FTL::Output::doubleLessThanOrEqual):
(JSC::FTL::Output::doubleGreaterThan):
(JSC::FTL::Output::doubleGreaterThanOrEqual):
(JSC::FTL::Output::doubleEqualOrUnordered):
(JSC::FTL::Output::doubleNotEqual):
(JSC::FTL::Output::doubleLessThanOrUnordered):
(JSC::FTL::Output::doubleLessThanOrEqualOrUnordered):
(JSC::FTL::Output::doubleGreaterThanOrUnordered):
(JSC::FTL::Output::doubleGreaterThanOrEqualOrUnordered):
(JSC::FTL::Output::testIsZero64):</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceJavaScriptCoreChangeLog">trunk/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLAbbreviationsh">trunk/Source/JavaScriptCore/ftl/FTLAbbreviations.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLCapabilitiescpp">trunk/Source/JavaScriptCore/ftl/FTLCapabilities.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLCommonValuescpp">trunk/Source/JavaScriptCore/ftl/FTLCommonValues.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLCommonValuesh">trunk/Source/JavaScriptCore/ftl/FTLCommonValues.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLCompilecpp">trunk/Source/JavaScriptCore/ftl/FTLCompile.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLLowerDFGToLLVMcpp">trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.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 (153132 => 153133)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2013-07-25 03:59:04 UTC (rev 153132)
+++ trunk/Source/JavaScriptCore/ChangeLog        2013-07-25 03:59:06 UTC (rev 153133)
</span><span class="lines">@@ -1,5 +1,89 @@
</span><span class="cx"> 2013-04-27  Filip Pizlo  &lt;fpizlo@apple.com&gt;
</span><span class="cx"> 
</span><ins>+        FTL should support double variables
+        https://bugs.webkit.org/show_bug.cgi?id=113624
+
+        Reviewed by Geoffrey Garen.
+        
+        Made all of the operations that the FTL already supports, also support doubles.
+        OSR exit already basically had everything it needed, so no changes there. This
+        mostly just glues together bits of DFG IR to LLVM IR, in a straight-forward way.
+
+        * ftl/FTLAbbreviations.h:
+        (FTL):
+        (JSC::FTL::doubleType):
+        (JSC::FTL::constReal):
+        (JSC::FTL::buildPhi):
+        (JSC::FTL::addIncoming):
+        (JSC::FTL::buildFAdd):
+        (JSC::FTL::buildFSub):
+        (JSC::FTL::buildFMul):
+        (JSC::FTL::buildFNeg):
+        (JSC::FTL::buildSIToFP):
+        (JSC::FTL::buildUIToFP):
+        (JSC::FTL::buildBitCast):
+        (JSC::FTL::buildFCmp):
+        * ftl/FTLCapabilities.cpp:
+        (JSC::FTL::canCompile):
+        * ftl/FTLCommonValues.cpp:
+        (JSC::FTL::CommonValues::CommonValues):
+        * ftl/FTLCommonValues.h:
+        (CommonValues):
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::LowerDFGToLLVM::LowerDFGToLLVM):
+        (JSC::FTL::LowerDFGToLLVM::lower):
+        (JSC::FTL::LowerDFGToLLVM::compileGetLocal):
+        (JSC::FTL::LowerDFGToLLVM::compileSetLocal):
+        (JSC::FTL::LowerDFGToLLVM::compileAdd):
+        (JSC::FTL::LowerDFGToLLVM::compileArithSub):
+        (JSC::FTL::LowerDFGToLLVM::compileArithMul):
+        (JSC::FTL::LowerDFGToLLVM::compileArithNegate):
+        (JSC::FTL::LowerDFGToLLVM::compileUInt32ToNumber):
+        (JSC::FTL::LowerDFGToLLVM::compileGetByVal):
+        (JSC::FTL::LowerDFGToLLVM::compileCompareEq):
+        (JSC::FTL::LowerDFGToLLVM::compileCompareLess):
+        (JSC::FTL::LowerDFGToLLVM::lowDouble):
+        (LowerDFGToLLVM):
+        (JSC::FTL::LowerDFGToLLVM::lowJSValue):
+        (JSC::FTL::LowerDFGToLLVM::isCellOrMisc):
+        (JSC::FTL::LowerDFGToLLVM::unboxDouble):
+        (JSC::FTL::LowerDFGToLLVM::boxDouble):
+        (JSC::FTL::LowerDFGToLLVM::speculate):
+        (JSC::FTL::LowerDFGToLLVM::speculateNumber):
+        (JSC::FTL::LowerDFGToLLVM::speculateRealNumber):
+        (JSC::FTL::LowerDFGToLLVM::appendOSRExit):
+        (JSC::FTL::LowerDFGToLLVM::addExitArgumentForNode):
+        * ftl/FTLOutput.h:
+        (JSC::FTL::Output::constDouble):
+        (Output):
+        (JSC::FTL::Output::phi):
+        (JSC::FTL::Output::doubleAdd):
+        (JSC::FTL::Output::doubleSub):
+        (JSC::FTL::Output::doubleMul):
+        (JSC::FTL::Output::doubleNeg):
+        (JSC::FTL::Output::intToFP):
+        (JSC::FTL::Output::intToDouble):
+        (JSC::FTL::Output::unsignedToFP):
+        (JSC::FTL::Output::unsignedToDouble):
+        (JSC::FTL::Output::bitCast):
+        (JSC::FTL::Output::loadDouble):
+        (JSC::FTL::Output::storeDouble):
+        (JSC::FTL::Output::doubleEqual):
+        (JSC::FTL::Output::doubleNotEqualOrUnordered):
+        (JSC::FTL::Output::doubleLessThan):
+        (JSC::FTL::Output::doubleLessThanOrEqual):
+        (JSC::FTL::Output::doubleGreaterThan):
+        (JSC::FTL::Output::doubleGreaterThanOrEqual):
+        (JSC::FTL::Output::doubleEqualOrUnordered):
+        (JSC::FTL::Output::doubleNotEqual):
+        (JSC::FTL::Output::doubleLessThanOrUnordered):
+        (JSC::FTL::Output::doubleLessThanOrEqualOrUnordered):
+        (JSC::FTL::Output::doubleGreaterThanOrUnordered):
+        (JSC::FTL::Output::doubleGreaterThanOrEqualOrUnordered):
+        (JSC::FTL::Output::testIsZero64):
+
+2013-04-27  Filip Pizlo  &lt;fpizlo@apple.com&gt;
+
</ins><span class="cx">         fourthTier: SymbolTable should be thread-safe
</span><span class="cx">         https://bugs.webkit.org/show_bug.cgi?id=115301
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLAbbreviationsh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLAbbreviations.h (153132 => 153133)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLAbbreviations.h        2013-07-25 03:59:04 UTC (rev 153132)
+++ trunk/Source/JavaScriptCore/ftl/FTLAbbreviations.h        2013-07-25 03:59:06 UTC (rev 153133)
</span><span class="lines">@@ -47,6 +47,7 @@
</span><span class="cx"> typedef LLVMBuilderRef LBuilder;
</span><span class="cx"> typedef LLVMCallConv LCallConv;
</span><span class="cx"> typedef LLVMIntPredicate LIntPredicate;
</span><ins>+typedef LLVMRealPredicate LRealPredicate;
</ins><span class="cx"> typedef LLVMLinkage LLinkage;
</span><span class="cx"> typedef LLVMModuleRef LModule;
</span><span class="cx"> typedef LLVMTypeRef LType;
</span><span class="lines">@@ -57,6 +58,7 @@
</span><span class="cx"> static inline LType int32Type() { return LLVMInt32Type(); }
</span><span class="cx"> static inline LType int64Type() { return LLVMInt64Type(); }
</span><span class="cx"> static inline LType intPtrType() { return LLVMInt64Type(); }
</span><ins>+static inline LType doubleType() { return LLVMDoubleType(); }
</ins><span class="cx"> 
</span><span class="cx"> static inline LType pointerType(LType type) { return LLVMPointerType(type, 0); }
</span><span class="cx"> 
</span><span class="lines">@@ -134,17 +136,58 @@
</span><span class="cx"> 
</span><span class="cx"> enum BitExtension { ZeroExtend, SignExtend };
</span><span class="cx"> static inline LValue constInt(LType type, unsigned long long value, BitExtension extension) { return LLVMConstInt(type, value, extension == SignExtend); }
</span><ins>+static inline LValue constReal(LType type, double value) { return LLVMConstReal(type, value); }
</ins><span class="cx"> static inline LValue constIntToPtr(LValue value, LType type) { return LLVMConstIntToPtr(value, type); }
</span><span class="cx"> static inline LValue constBitCast(LValue value, LType type) { return LLVMConstBitCast(value, type); }
</span><span class="cx"> 
</span><span class="cx"> static inline LBasicBlock appendBasicBlock(LValue function, const char* name = &quot;&quot;) { return LLVMAppendBasicBlock(function, name); }
</span><span class="cx"> static inline LBasicBlock insertBasicBlock(LBasicBlock beforeBasicBlock, const char* name = &quot;&quot;) { return LLVMInsertBasicBlock(beforeBasicBlock, name); }
</span><span class="cx"> 
</span><ins>+static inline LValue buildPhi(LBuilder builder, LType type) { return LLVMBuildPhi(builder, type, &quot;&quot;); }
+static inline void addIncoming(LValue phi, const LValue* values, const LBasicBlock* blocks, unsigned numPredecessors)
+{
+    LLVMAddIncoming(phi, const_cast&lt;LValue*&gt;(values), const_cast&lt;LBasicBlock*&gt;(blocks), numPredecessors);
+}
+template&lt;typename ValueVectorType, typename BlockVectorType&gt;
+static inline void addIncoming(LValue phi, const ValueVectorType&amp; values, const BlockVectorType&amp; blocks)
+{
+    ASSERT(values.size() == blocks.size());
+    addIncoming(phi, values.begin(), blocks.begin(), values.size());
+}
+static inline void addIncoming(LValue phi, LValue value1, LBasicBlock block1)
+{
+    addIncoming(phi, &amp;value1, &amp;block1, 1);
+}
+static inline void addIncoming(LValue phi, LValue value1, LBasicBlock block1, LValue value2, LBasicBlock block2)
+{
+    LValue values[] = { value1, value2 };
+    LBasicBlock blocks[] = { block1, block2 };
+    addIncoming(phi, values, blocks, 2);
+}
+static inline LValue buildPhi(LBuilder builder, LType type, LValue value1, LBasicBlock block1)
+{
+    LValue result = buildPhi(builder, type);
+    addIncoming(result, value1, block1);
+    return result;
+}
+static inline LValue buildPhi(
+    LBuilder builder, LType type, LValue value1, LBasicBlock block1, LValue value2,
+    LBasicBlock block2)
+{
+    LValue result = buildPhi(builder, type);
+    addIncoming(result, value1, block1, value2, block2);
+    return result;
+}
+
</ins><span class="cx"> static inline LValue buildAlloca(LBuilder builder, LType type) { return LLVMBuildAlloca(builder, type, &quot;&quot;); }
</span><span class="cx"> static inline LValue buildAdd(LBuilder builder, LValue left, LValue right) { return LLVMBuildAdd(builder, left, right, &quot;&quot;); }
</span><span class="cx"> static inline LValue buildSub(LBuilder builder, LValue left, LValue right) { return LLVMBuildSub(builder, left, right, &quot;&quot;); }
</span><span class="cx"> static inline LValue buildMul(LBuilder builder, LValue left, LValue right) { return LLVMBuildMul(builder, left, right, &quot;&quot;); }
</span><span class="cx"> static inline LValue buildNeg(LBuilder builder, LValue value) { return LLVMBuildNeg(builder, value, &quot;&quot;); }
</span><ins>+static inline LValue buildFAdd(LBuilder builder, LValue left, LValue right) { return LLVMBuildFAdd(builder, left, right, &quot;&quot;); }
+static inline LValue buildFSub(LBuilder builder, LValue left, LValue right) { return LLVMBuildFSub(builder, left, right, &quot;&quot;); }
+static inline LValue buildFMul(LBuilder builder, LValue left, LValue right) { return LLVMBuildFMul(builder, left, right, &quot;&quot;); }
+static inline LValue buildFNeg(LBuilder builder, LValue value) { return LLVMBuildFNeg(builder, value, &quot;&quot;); }
</ins><span class="cx"> static inline LValue buildAnd(LBuilder builder, LValue left, LValue right) { return LLVMBuildAnd(builder, left, right, &quot;&quot;); }
</span><span class="cx"> static inline LValue buildOr(LBuilder builder, LValue left, LValue right) { return LLVMBuildOr(builder, left, right, &quot;&quot;); }
</span><span class="cx"> static inline LValue buildXor(LBuilder builder, LValue left, LValue right) { return LLVMBuildXor(builder, left, right, &quot;&quot;); }
</span><span class="lines">@@ -154,10 +197,14 @@
</span><span class="cx"> static inline LValue buildLoad(LBuilder builder, LValue pointer) { return LLVMBuildLoad(builder, pointer, &quot;&quot;); }
</span><span class="cx"> static inline LValue buildStore(LBuilder builder, LValue value, LValue pointer) { return LLVMBuildStore(builder, value, pointer); }
</span><span class="cx"> static inline LValue buildZExt(LBuilder builder, LValue value, LType type) { return LLVMBuildZExt(builder, value, type, &quot;&quot;); }
</span><ins>+static inline LValue buildSIToFP(LBuilder builder, LValue value, LType type) { return LLVMBuildSIToFP(builder, value, type, &quot;&quot;); }
+static inline LValue buildUIToFP(LBuilder builder, LValue value, LType type) { return LLVMBuildUIToFP(builder, value, type, &quot;&quot;); }
</ins><span class="cx"> static inline LValue buildIntCast(LBuilder builder, LValue value, LType type) { return LLVMBuildIntCast(builder, value, type, &quot;&quot;); }
</span><span class="cx"> static inline LValue buildIntToPtr(LBuilder builder, LValue value, LType type) { return LLVMBuildIntToPtr(builder, value, type, &quot;&quot;); }
</span><span class="cx"> static inline LValue buildPtrToInt(LBuilder builder, LValue value, LType type) { return LLVMBuildPtrToInt(builder, value, type, &quot;&quot;); }
</span><ins>+static inline LValue buildBitCast(LBuilder builder, LValue value, LType type) { return LLVMBuildBitCast(builder, value, type, &quot;&quot;); }
</ins><span class="cx"> static inline LValue buildICmp(LBuilder builder, LIntPredicate cond, LValue left, LValue right) { return LLVMBuildICmp(builder, cond, left, right, &quot;&quot;); }
</span><ins>+static inline LValue buildFCmp(LBuilder builder, LRealPredicate cond, LValue left, LValue right) { return LLVMBuildFCmp(builder, cond, left, right, &quot;&quot;); }
</ins><span class="cx"> static inline LValue buildCall(LBuilder builder, LValue function, const LValue* args, unsigned numArgs)
</span><span class="cx"> {
</span><span class="cx">     return LLVMBuildCall(builder, function, const_cast&lt;LValue*&gt;(args), numArgs, &quot;&quot;);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLCapabilitiescpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLCapabilities.cpp (153132 => 153133)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLCapabilities.cpp        2013-07-25 03:59:04 UTC (rev 153132)
+++ trunk/Source/JavaScriptCore/ftl/FTLCapabilities.cpp        2013-07-25 03:59:06 UTC (rev 153133)
</span><span class="lines">@@ -50,6 +50,9 @@
</span><span class="cx">                 case UntypedUse:
</span><span class="cx">                 case Int32Use:
</span><span class="cx">                 case KnownInt32Use:
</span><ins>+                case NumberUse:
+                case KnownNumberUse:
+                case RealNumberUse:
</ins><span class="cx">                 case BooleanUse:
</span><span class="cx">                 case CellUse:
</span><span class="cx">                 case KnownCellUse:
</span><span class="lines">@@ -90,22 +93,13 @@
</span><span class="cx">             case PutByOffset:
</span><span class="cx">             case GetGlobalVar:
</span><span class="cx">             case PutGlobalVar:
</span><del>-                // These are OK.
-                break;
</del><span class="cx">             case ValueAdd:
</span><span class="cx">             case ArithAdd:
</span><span class="cx">             case ArithSub:
</span><span class="cx">             case ArithMul:
</span><del>-                if (node-&gt;binaryUseKind() == Int32Use)
-                    break;
-                return false;
</del><span class="cx">             case ArithNegate:
</span><del>-                if (node-&gt;child1().useKind() == Int32Use)
-                    break;
-                return false;
</del><span class="cx">             case UInt32ToNumber:
</span><del>-                if (!nodeCanSpeculateInteger(node-&gt;arithNodeFlags()))
-                    return false;
</del><ins>+                // These are OK.
</ins><span class="cx">                 break;
</span><span class="cx">             case GetArrayLength:
</span><span class="cx">                 switch (node-&gt;arrayMode().type()) {
</span><span class="lines">@@ -120,6 +114,7 @@
</span><span class="cx">             case GetByVal:
</span><span class="cx">                 switch (node-&gt;arrayMode().type()) {
</span><span class="cx">                 case Array::Int32:
</span><ins>+                case Array::Double:
</ins><span class="cx">                 case Array::Contiguous:
</span><span class="cx">                     break;
</span><span class="cx">                 default:
</span><span class="lines">@@ -136,12 +131,16 @@
</span><span class="cx">             case CompareEq:
</span><span class="cx">                 if (node-&gt;isBinaryUseKind(Int32Use))
</span><span class="cx">                     break;
</span><ins>+                if (node-&gt;isBinaryUseKind(NumberUse))
+                    break;
</ins><span class="cx">                 if (node-&gt;isBinaryUseKind(ObjectUse))
</span><span class="cx">                     break;
</span><span class="cx">                 return false;
</span><span class="cx">             case CompareLess:
</span><span class="cx">                 if (node-&gt;isBinaryUseKind(Int32Use))
</span><span class="cx">                     break;
</span><ins>+                if (node-&gt;isBinaryUseKind(NumberUse))
+                    break;
</ins><span class="cx">                 return false;
</span><span class="cx">             case Branch:
</span><span class="cx">                 if (node-&gt;child1().useKind() == BooleanUse)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLCommonValuescpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLCommonValues.cpp (153132 => 153133)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLCommonValues.cpp        2013-07-25 03:59:04 UTC (rev 153132)
+++ trunk/Source/JavaScriptCore/ftl/FTLCommonValues.cpp        2013-07-25 03:59:06 UTC (rev 153133)
</span><span class="lines">@@ -36,9 +36,11 @@
</span><span class="cx">     , int32(int32Type())
</span><span class="cx">     , int64(int64Type())
</span><span class="cx">     , intPtr(intPtrType())
</span><ins>+    , doubleType(FTL::doubleType())
</ins><span class="cx">     , ref32(pointerType(int32))
</span><span class="cx">     , ref64(pointerType(int64))
</span><span class="cx">     , refPtr(pointerType(intPtr))
</span><ins>+    , refDouble(pointerType(doubleType))
</ins><span class="cx">     , booleanTrue(constInt(boolean, true, ZeroExtend))
</span><span class="cx">     , booleanFalse(constInt(boolean, false, ZeroExtend))
</span><span class="cx">     , int32Zero(constInt(int32, 0, SignExtend))
</span><span class="lines">@@ -50,6 +52,7 @@
</span><span class="cx">     , intPtrFour(constInt(intPtr, 4, SignExtend))
</span><span class="cx">     , intPtrEight(constInt(intPtr, 8, SignExtend))
</span><span class="cx">     , intPtrPtr(constInt(intPtr, sizeof(void*), SignExtend))
</span><ins>+    , doubleZero(constReal(doubleType, 0))
</ins><span class="cx">     , m_module(0)
</span><span class="cx"> {
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLCommonValuesh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLCommonValues.h (153132 => 153133)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLCommonValues.h        2013-07-25 03:59:04 UTC (rev 153132)
+++ trunk/Source/JavaScriptCore/ftl/FTLCommonValues.h        2013-07-25 03:59:06 UTC (rev 153133)
</span><span class="lines">@@ -48,9 +48,11 @@
</span><span class="cx">     const LType int32;
</span><span class="cx">     const LType int64;
</span><span class="cx">     const LType intPtr;
</span><ins>+    const LType doubleType;
</ins><span class="cx">     const LType ref32;
</span><span class="cx">     const LType ref64;
</span><span class="cx">     const LType refPtr;
</span><ins>+    const LType refDouble;
</ins><span class="cx">     const LValue booleanTrue;
</span><span class="cx">     const LValue booleanFalse;
</span><span class="cx">     const LValue int32Zero;
</span><span class="lines">@@ -62,6 +64,7 @@
</span><span class="cx">     const LValue intPtrFour;
</span><span class="cx">     const LValue intPtrEight;
</span><span class="cx">     const LValue intPtrPtr;
</span><ins>+    const LValue doubleZero;
</ins><span class="cx">     
</span><span class="cx">     LModule m_module;
</span><span class="cx"> };
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLCompilecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLCompile.cpp (153132 => 153133)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLCompile.cpp        2013-07-25 03:59:04 UTC (rev 153132)
+++ trunk/Source/JavaScriptCore/ftl/FTLCompile.cpp        2013-07-25 03:59:06 UTC (rev 153133)
</span><span class="lines">@@ -55,9 +55,10 @@
</span><span class="cx">     char* error = 0;
</span><span class="cx">     
</span><span class="cx">     LLVMMCJITCompilerOptions options;
</span><del>-    memset(&amp;options, 0, sizeof(options));
</del><ins>+    LLVMInitializeMCJITCompilerOptions(&amp;options, sizeof(options));
</ins><span class="cx">     options.OptLevel = Options::llvmOptimizationLevel();
</span><span class="cx">     options.NoFramePointerElim = true;
</span><ins>+    options.CodeModel = LLVMCodeModelSmall;
</ins><span class="cx">     
</span><span class="cx">     if (LLVMCreateMCJITCompilerForModule(&amp;engine, state.module, &amp;options, sizeof(options), &amp;error)) {
</span><span class="cx">         dataLog(&quot;FATAL: Could not create LLVM execution engine: &quot;, error, &quot;\n&quot;);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLLowerDFGToLLVMcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp (153132 => 153133)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp        2013-07-25 03:59:04 UTC (rev 153132)
+++ trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp        2013-07-25 03:59:06 UTC (rev 153133)
</span><span class="lines">@@ -62,6 +62,7 @@
</span><span class="cx">         , m_localsBoolean(OperandsLike, state.graph.m_blocks[0]-&gt;variablesAtHead)
</span><span class="cx">         , m_locals32(OperandsLike, state.graph.m_blocks[0]-&gt;variablesAtHead)
</span><span class="cx">         , m_locals64(OperandsLike, state.graph.m_blocks[0]-&gt;variablesAtHead)
</span><ins>+        , m_localsDouble(OperandsLike, state.graph.m_blocks[0]-&gt;variablesAtHead)
</ins><span class="cx">         , m_valueSources(OperandsLike, state.graph.m_blocks[0]-&gt;variablesAtHead)
</span><span class="cx">         , m_lastSetOperand(std::numeric_limits&lt;int&gt;::max())
</span><span class="cx">         , m_exitThunkGenerator(state)
</span><span class="lines">@@ -86,6 +87,7 @@
</span><span class="cx">             m_localsBoolean[index] = buildAlloca(m_out.m_builder, m_out.boolean);
</span><span class="cx">             m_locals32[index] = buildAlloca(m_out.m_builder, m_out.int32);
</span><span class="cx">             m_locals64[index] = buildAlloca(m_out.m_builder, m_out.int64);
</span><ins>+            m_localsDouble[index] = buildAlloca(m_out.m_builder, m_out.doubleType);
</ins><span class="cx">         }
</span><span class="cx">         
</span><span class="cx">         m_initialization = appendBasicBlock(m_ftlState.function);
</span><span class="lines">@@ -422,9 +424,8 @@
</span><span class="cx">         
</span><span class="cx">         if (variable-&gt;shouldUnboxIfPossible()) {
</span><span class="cx">             if (variable-&gt;shouldUseDoubleFormat()) {
</span><del>-                // FIXME: implement doubles in FTL.
-                // https://bugs.webkit.org/show_bug.cgi?id=113624
-                RELEASE_ASSERT_NOT_REACHED();
</del><ins>+                m_doubleValues.add(m_node, m_out.get(m_localsDouble.operand(variable-&gt;local())));
+                return;
</ins><span class="cx">             }
</span><span class="cx">             
</span><span class="cx">             // Locals that are marked shouldUnboxIfPossible() that aren't also forced to
</span><span class="lines">@@ -456,9 +457,12 @@
</span><span class="cx">         
</span><span class="cx">         if (variable-&gt;shouldUnboxIfPossible()) {
</span><span class="cx">             if (variable-&gt;shouldUseDoubleFormat()) {
</span><del>-                // FIXME: implement doubles in FTL.
-                // https://bugs.webkit.org/show_bug.cgi?id=113624
-                RELEASE_ASSERT_NOT_REACHED();
</del><ins>+                LValue value = lowDouble(m_node-&gt;child1());
+                m_out.set(value, m_localsDouble.operand(variable-&gt;local()));
+                if (needsFlushing) {
+                    m_out.storeDouble(value, addressFor(variable-&gt;local()));
+                    m_valueSources.operand(variable-&gt;local()) = ValueSource(DoubleInJSStack);
+                }
</ins><span class="cx">                 return;
</span><span class="cx">             }
</span><span class="cx">             
</span><span class="lines">@@ -552,6 +556,13 @@
</span><span class="cx">             break;
</span><span class="cx">         }
</span><span class="cx">             
</span><ins>+        case NumberUse: {
+            m_doubleValues.add(
+                m_node,
+                m_out.doubleAdd(lowDouble(m_node-&gt;child1()), lowDouble(m_node-&gt;child2())));
+            break;
+        }
+            
</ins><span class="cx">         default:
</span><span class="cx">             RELEASE_ASSERT_NOT_REACHED();
</span><span class="cx">             break;
</span><span class="lines">@@ -576,6 +587,13 @@
</span><span class="cx">             break;
</span><span class="cx">         }
</span><span class="cx">             
</span><ins>+        case NumberUse: {
+            m_doubleValues.add(
+                m_node,
+                m_out.doubleSub(lowDouble(m_node-&gt;child1()), lowDouble(m_node-&gt;child2())));
+            break;
+        }
+            
</ins><span class="cx">         default:
</span><span class="cx">             RELEASE_ASSERT_NOT_REACHED();
</span><span class="cx">             break;
</span><span class="lines">@@ -613,6 +631,13 @@
</span><span class="cx">             break;
</span><span class="cx">         }
</span><span class="cx">             
</span><ins>+        case NumberUse: {
+            m_doubleValues.add(
+                m_node,
+                m_out.doubleMul(lowDouble(m_node-&gt;child1()), lowDouble(m_node-&gt;child2())));
+            break;
+        }
+            
</ins><span class="cx">         default:
</span><span class="cx">             RELEASE_ASSERT_NOT_REACHED();
</span><span class="cx">             break;
</span><span class="lines">@@ -640,6 +665,11 @@
</span><span class="cx">             break;
</span><span class="cx">         }
</span><span class="cx">             
</span><ins>+        case NumberUse: {
+            m_doubleValues.add(m_node, m_out.doubleNeg(lowDouble(m_node-&gt;child1())));
+            break;
+        }
+            
</ins><span class="cx">         default:
</span><span class="cx">             RELEASE_ASSERT_NOT_REACHED();
</span><span class="cx">             break;
</span><span class="lines">@@ -693,15 +723,13 @@
</span><span class="cx">     
</span><span class="cx">     void compileUInt32ToNumber()
</span><span class="cx">     {
</span><ins>+        LValue value = lowInt32(m_node-&gt;child1());
+
</ins><span class="cx">         if (!nodeCanSpeculateInteger(m_node-&gt;arithNodeFlags())) {
</span><del>-            // FIXME: implement doubles in FTL.
-            // https://bugs.webkit.org/show_bug.cgi?id=113624
-            
-            RELEASE_ASSERT_NOT_REACHED();
</del><ins>+            m_doubleValues.add(m_node, m_out.unsignedToDouble(value));
</ins><span class="cx">             return;
</span><span class="cx">         }
</span><span class="cx">         
</span><del>-        LValue value = lowInt32(m_node-&gt;child1());
</del><span class="cx">         speculateForward(
</span><span class="cx">             Overflow, noValue(), 0, m_out.lessThan(value, m_out.int32Zero),
</span><span class="cx">             FormattedValue(ValueFormatUInt32, value));
</span><span class="lines">@@ -821,6 +849,36 @@
</span><span class="cx">             break;
</span><span class="cx">         }
</span><span class="cx">             
</span><ins>+        case Array::Double: {
+            if (m_node-&gt;arrayMode().isInBounds()) {
+                if (m_node-&gt;arrayMode().isSaneChain()) {
+                    // FIXME: Implement structure transition watchpoints.
+                    // https://bugs.webkit.org/show_bug.cgi?id=113647
+                }
+            
+                speculate(
+                    OutOfBounds, noValue(), 0,
+                    m_out.aboveOrEqual(
+                        index, m_out.load32(storage, m_heaps.Butterfly_publicLength)));
+                
+                LValue result = m_out.loadDouble(m_out.baseIndex(
+                    m_heaps.indexedDoubleProperties,
+                    storage, m_out.zeroExt(index, m_out.intPtr),
+                    m_state.forNode(m_node-&gt;child2()).m_value));
+                
+                if (!m_node-&gt;arrayMode().isSaneChain()) {
+                    speculate(
+                        LoadFromHole, noValue(), 0,
+                        m_out.doubleNotEqualOrUnordered(result, result));
+                }
+                m_doubleValues.add(m_node, result);
+                break;
+            }
+            
+            RELEASE_ASSERT_NOT_REACHED();
+            break;
+        }
+            
</ins><span class="cx">         default:
</span><span class="cx">             RELEASE_ASSERT_NOT_REACHED();
</span><span class="cx">             break;
</span><span class="lines">@@ -874,6 +932,12 @@
</span><span class="cx">             return;
</span><span class="cx">         }
</span><span class="cx">         
</span><ins>+        if (m_node-&gt;isBinaryUseKind(NumberUse)) {
+            m_booleanValues.add(
+                m_node,
+                m_out.doubleEqual(lowDouble(m_node-&gt;child1()), lowDouble(m_node-&gt;child2())));
+        }
+        
</ins><span class="cx">         if (m_node-&gt;isBinaryUseKind(ObjectUse)) {
</span><span class="cx">             m_booleanValues.add(
</span><span class="cx">                 m_node,
</span><span class="lines">@@ -893,6 +957,12 @@
</span><span class="cx">             return;
</span><span class="cx">         }
</span><span class="cx">         
</span><ins>+        if (m_node-&gt;isBinaryUseKind(NumberUse)) {
+            m_booleanValues.add(
+                m_node,
+                m_out.doubleLessThan(lowDouble(m_node-&gt;child1()), lowDouble(m_node-&gt;child2())));
+        }
+        
</ins><span class="cx">         RELEASE_ASSERT_NOT_REACHED();
</span><span class="cx">     }
</span><span class="cx">     
</span><span class="lines">@@ -1042,6 +1112,57 @@
</span><span class="cx">         return m_out.booleanFalse;
</span><span class="cx">     }
</span><span class="cx">     
</span><ins>+    LValue lowDouble(Edge edge, OperandSpeculationMode mode = AutomaticOperandSpeculation)
+    {
+        ASSERT_UNUSED(mode, mode == ManualOperandSpeculation || isDouble(edge.useKind()));
+        
+        if (LValue result = m_doubleValues.get(edge.node()))
+            return result;
+        
+        if (LValue intResult = m_int32Values.get(edge.node())) {
+            LValue result = m_out.intToDouble(intResult);
+            m_doubleValues.add(edge.node(), result);
+            return result;
+        }
+        
+        if (LValue boxedResult = m_jsValueValues.get(edge.node())) {
+            LBasicBlock intCase = FTL_NEW_BLOCK(m_out, (&quot;Double unboxing int case&quot;));
+            LBasicBlock doubleCase = FTL_NEW_BLOCK(m_out, (&quot;Double unboxing double case&quot;));
+            LBasicBlock continuation = FTL_NEW_BLOCK(m_out, (&quot;Double unboxing continuation&quot;));
+            
+            m_out.branch(isNotInt32(boxedResult), doubleCase, intCase);
+            
+            LBasicBlock lastNext = m_out.appendTo(intCase, doubleCase);
+            
+            LValue intToDouble = m_out.intToDouble(unboxInt32(boxedResult));
+            LBasicBlock intToDoubleBlock = m_out.m_block;
+            m_out.jump(continuation);
+            
+            m_out.appendTo(doubleCase, continuation);
+            
+            FTL_TYPE_CHECK(
+                jsValueValue(boxedResult), edge, SpecNumber, isCellOrMisc(boxedResult));
+            
+            LValue unboxedDouble = unboxDouble(boxedResult);
+            LBasicBlock unboxedDoubleBlock = m_out.m_block;
+            m_out.jump(continuation);
+            
+            m_out.appendTo(continuation, lastNext);
+            
+            LValue result = m_out.phi(
+                m_out.doubleType,
+                intToDouble, intToDoubleBlock,
+                unboxedDouble, unboxedDoubleBlock);
+            
+            m_doubleValues.add(edge.node(), result);
+            return result;
+        }
+        
+        RELEASE_ASSERT(!(m_state.forNode(edge).m_type &amp; SpecNumber));
+        terminate(Uncountable);
+        return m_out.doubleZero;
+    }
+    
</ins><span class="cx">     LValue lowJSValue(Edge edge, OperandSpeculationMode mode = AutomaticOperandSpeculation)
</span><span class="cx">     {
</span><span class="cx">         ASSERT_UNUSED(mode, mode == ManualOperandSpeculation || edge.useKind() == UntypedUse);
</span><span class="lines">@@ -1061,6 +1182,12 @@
</span><span class="cx">             return result;
</span><span class="cx">         }
</span><span class="cx">         
</span><ins>+        if (LValue unboxedResult = m_doubleValues.get(edge.node())) {
+            LValue result = boxDouble(unboxedResult);
+            m_jsValueValues.add(edge.node(), result);
+            return result;
+        }
+        
</ins><span class="cx">         RELEASE_ASSERT_NOT_REACHED();
</span><span class="cx">         return 0;
</span><span class="cx">     }
</span><span class="lines">@@ -1088,6 +1215,19 @@
</span><span class="cx">         return m_out.add(m_out.zeroExt(value, m_out.int64), m_tagTypeNumber);
</span><span class="cx">     }
</span><span class="cx">     
</span><ins>+    LValue isCellOrMisc(LValue jsValue)
+    {
+        return m_out.testIsZero64(jsValue, m_tagTypeNumber);
+    }
+    LValue unboxDouble(LValue jsValue)
+    {
+        return m_out.bitCast(m_out.add(jsValue, m_tagTypeNumber), m_out.doubleType);
+    }
+    LValue boxDouble(LValue doubleValue)
+    {
+        return m_out.sub(m_out.bitCast(doubleValue, m_out.int64), m_tagTypeNumber);
+    }
+    
</ins><span class="cx">     LValue isNotCell(LValue jsValue)
</span><span class="cx">     {
</span><span class="cx">         return m_out.testNonZero64(jsValue, m_tagMask);
</span><span class="lines">@@ -1117,6 +1257,7 @@
</span><span class="cx">         case UntypedUse:
</span><span class="cx">             break;
</span><span class="cx">         case KnownInt32Use:
</span><ins>+        case KnownNumberUse:
</ins><span class="cx">             ASSERT(!m_state.needsTypeCheck(edge));
</span><span class="cx">             break;
</span><span class="cx">         case Int32Use:
</span><span class="lines">@@ -1131,6 +1272,12 @@
</span><span class="cx">         case ObjectUse:
</span><span class="cx">             speculateObject(edge);
</span><span class="cx">             break;
</span><ins>+        case RealNumberUse:
+            speculateRealNumber(edge);
+            break;
+        case NumberUse:
+            speculateNumber(edge);
+            break;
</ins><span class="cx">         default:
</span><span class="cx">             RELEASE_ASSERT_NOT_REACHED();
</span><span class="cx">         }
</span><span class="lines">@@ -1165,6 +1312,27 @@
</span><span class="cx">         speculateObject(edge, lowCell(edge));
</span><span class="cx">     }
</span><span class="cx">     
</span><ins>+    void speculateNumber(Edge edge)
+    {
+        // Do an early return here because lowDouble() can create a lot of control flow.
+        if (!m_state.needsTypeCheck(edge))
+            return;
+        
+        lowDouble(edge);
+    }
+    
+    void speculateRealNumber(Edge edge)
+    {
+        // Do an early return here because lowDouble() can create a lot of control flow.
+        if (!m_state.needsTypeCheck(edge))
+            return;
+        
+        LValue value = lowDouble(edge);
+        FTL_TYPE_CHECK(
+            doubleValue(value), edge, SpecRealNumber,
+            m_out.doubleNotEqualOrUnordered(value, value));
+    }
+    
</ins><span class="cx">     bool isLive(Node* node)
</span><span class="cx">     {
</span><span class="cx">         HashMap&lt;Node*, unsigned&gt;::iterator iter = m_timeToLive.find(node);
</span><span class="lines">@@ -1315,9 +1483,8 @@
</span><span class="cx">                     exit, arguments, i, ValueFormatBoolean, m_out.get(m_localsBoolean[i]));
</span><span class="cx">                 break;
</span><span class="cx">             case DoubleInLocals:
</span><del>-                // FIXME: implement doubles in FTL.
-                // https://bugs.webkit.org/show_bug.cgi?id=113624
-                RELEASE_ASSERT_NOT_REACHED();
</del><ins>+                addExitArgument(
+                    exit, arguments, i, ValueFormatDouble, m_out.get(m_localsDouble[i]));
</ins><span class="cx">                 break;
</span><span class="cx">             case ArgumentsSource:
</span><span class="cx">                 // FIXME: implement PhantomArguments.
</span><span class="lines">@@ -1454,8 +1621,11 @@
</span><span class="cx">             return;
</span><span class="cx">         }
</span><span class="cx">         
</span><del>-        // FIXME: Implement doubles in the FTL.
-        // https://bugs.webkit.org/show_bug.cgi?id=113624
</del><ins>+        if (LValue result = m_doubleValues.get(node)) {
+            addExitArgument(exit, arguments, index, ValueFormatDouble, result);
+            return;
+        }
+
</ins><span class="cx">         RELEASE_ASSERT_NOT_REACHED();
</span><span class="cx">     }
</span><span class="cx">     
</span><span class="lines">@@ -1600,11 +1770,13 @@
</span><span class="cx">     HashMap&lt;Node*, LValue&gt; m_jsValueValues;
</span><span class="cx">     HashMap&lt;Node*, LValue&gt; m_booleanValues;
</span><span class="cx">     HashMap&lt;Node*, LValue&gt; m_storageValues;
</span><ins>+    HashMap&lt;Node*, LValue&gt; m_doubleValues;
</ins><span class="cx">     HashMap&lt;Node*, unsigned&gt; m_timeToLive;
</span><span class="cx">     
</span><span class="cx">     Operands&lt;LValue&gt; m_localsBoolean;
</span><span class="cx">     Operands&lt;LValue&gt; m_locals32;
</span><span class="cx">     Operands&lt;LValue&gt; m_locals64;
</span><ins>+    Operands&lt;LValue&gt; m_localsDouble;
</ins><span class="cx">     
</span><span class="cx">     Operands&lt;ValueSource&gt; m_valueSources;
</span><span class="cx">     int m_lastSetOperand;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLOutputh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLOutput.h (153132 => 153133)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLOutput.h        2013-07-25 03:59:04 UTC (rev 153132)
+++ trunk/Source/JavaScriptCore/ftl/FTLOutput.h        2013-07-25 03:59:06 UTC (rev 153133)
</span><span class="lines">@@ -109,11 +109,28 @@
</span><span class="cx">     template&lt;typename T&gt;
</span><span class="cx">     LValue constIntPtr(T value) { return constInt(intPtr, bitwise_cast&lt;intptr_t&gt;(value), SignExtend); }
</span><span class="cx">     LValue constInt64(int64_t value) { return constInt(int64, value, SignExtend); }
</span><ins>+    LValue constDouble(double value) { return constReal(doubleType, value); }
</ins><span class="cx">     
</span><ins>+    LValue phi(LType type) { return buildPhi(m_builder, type); }
+    LValue phi(LType type, LValue value1, LBasicBlock block1)
+    {
+        return buildPhi(m_builder, type, value1, block1);
+    }
+    LValue phi(LType type, LValue value1, LBasicBlock block1, LValue value2, LBasicBlock block2)
+    {
+        return buildPhi(m_builder, type, value1, block1, value2, block2);
+    }
+    
</ins><span class="cx">     LValue add(LValue left, LValue right) { return buildAdd(m_builder, left, right); }
</span><span class="cx">     LValue sub(LValue left, LValue right) { return buildSub(m_builder, left, right); }
</span><span class="cx">     LValue mul(LValue left, LValue right) { return buildMul(m_builder, left, right); }
</span><span class="cx">     LValue neg(LValue value) { return buildNeg(m_builder, value); }
</span><ins>+
+    LValue doubleAdd(LValue left, LValue right) { return buildFAdd(m_builder, left, right); }
+    LValue doubleSub(LValue left, LValue right) { return buildFSub(m_builder, left, right); }
+    LValue doubleMul(LValue left, LValue right) { return buildFMul(m_builder, left, right); }
+    LValue doubleNeg(LValue value) { return buildFNeg(m_builder, value); }
+
</ins><span class="cx">     LValue bitAnd(LValue left, LValue right) { return buildAnd(m_builder, left, right); }
</span><span class="cx">     LValue bitOr(LValue left, LValue right) { return buildOr(m_builder, left, right); }
</span><span class="cx">     LValue bitXor(LValue left, LValue right) { return buildXor(m_builder, left, right); }
</span><span class="lines">@@ -135,9 +152,14 @@
</span><span class="cx">     }
</span><span class="cx">     
</span><span class="cx">     LValue zeroExt(LValue value, LType type) { return buildZExt(m_builder, value, type); }
</span><ins>+    LValue intToFP(LValue value, LType type) { return buildSIToFP(m_builder, value, type); }
+    LValue intToDouble(LValue value) { return intToFP(value, doubleType); }
+    LValue unsignedToFP(LValue value, LType type) { return buildUIToFP(m_builder, value, type); }
+    LValue unsignedToDouble(LValue value) { return unsignedToFP(value, doubleType); }
</ins><span class="cx">     LValue intCast(LValue value, LType type) { return buildIntCast(m_builder, value, type); }
</span><span class="cx">     LValue castToInt32(LValue value) { return intCast(value, int32); }
</span><span class="cx">     LValue intToPtr(LValue value, LType type) { return buildIntToPtr(m_builder, value, type); }
</span><ins>+    LValue bitCast(LValue value, LType type) { return buildBitCast(m_builder, value, type); }
</ins><span class="cx">     
</span><span class="cx">     LValue get(LValue reference) { return buildLoad(m_builder, reference); }
</span><span class="cx">     LValue set(LValue value, LValue reference) { return buildStore(m_builder, value, reference); }
</span><span class="lines">@@ -157,9 +179,11 @@
</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><ins>+    LValue loadDouble(TypedPointer pointer) { return load(pointer, refDouble); }
</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 storeDouble(LValue value, TypedPointer pointer) { store(value, pointer, refDouble); }
</ins><span class="cx"> 
</span><span class="cx">     LValue addPtr(LValue value, ptrdiff_t immediate = 0)
</span><span class="cx">     {
</span><span class="lines">@@ -239,9 +263,23 @@
</span><span class="cx">     LValue lessThan(LValue left, LValue right) { return buildICmp(m_builder, LLVMIntSLT, left, right); }
</span><span class="cx">     LValue lessThanOrEqual(LValue left, LValue right) { return buildICmp(m_builder, LLVMIntSLE, left, right); }
</span><span class="cx">     
</span><ins>+    LValue doubleEqual(LValue left, LValue right) { return buildFCmp(m_builder, LLVMRealOEQ, left, right); }
+    LValue doubleNotEqualOrUnordered(LValue left, LValue right) { return buildFCmp(m_builder, LLVMRealUNE, left, right); }
+    LValue doubleLessThan(LValue left, LValue right) { return buildFCmp(m_builder, LLVMRealOLT, left, right); }
+    LValue doubleLessThanOrEqual(LValue left, LValue right) { return buildFCmp(m_builder, LLVMRealOLE, left, right); }
+    LValue doubleGreaterThan(LValue left, LValue right) { return buildFCmp(m_builder, LLVMRealOGT, left, right); }
+    LValue doubleGreaterThanOrEqual(LValue left, LValue right) { return buildFCmp(m_builder, LLVMRealOGE, left, right); }
+    LValue doubleEqualOrUnordered(LValue left, LValue right) { return buildFCmp(m_builder, LLVMRealUEQ, left, right); }
+    LValue doubleNotEqual(LValue left, LValue right) { return buildFCmp(m_builder, LLVMRealONE, left, right); }
+    LValue doubleLessThanOrUnordered(LValue left, LValue right) { return buildFCmp(m_builder, LLVMRealULT, left, right); }
+    LValue doubleLessThanOrEqualOrUnordered(LValue left, LValue right) { return buildFCmp(m_builder, LLVMRealULE, left, right); }
+    LValue doubleGreaterThanOrUnordered(LValue left, LValue right) { return buildFCmp(m_builder, LLVMRealUGT, left, right); }
+    LValue doubleGreaterThanOrEqualOrUnordered(LValue left, LValue right) { return buildFCmp(m_builder, LLVMRealUGE, left, right); }
+    
</ins><span class="cx">     LValue isZero64(LValue value) { return equal(value, int64Zero); }
</span><span class="cx">     LValue notZero64(LValue value) { return notEqual(value, int64Zero); }
</span><span class="cx">     
</span><ins>+    LValue testIsZero64(LValue value, LValue mask) { return isZero64(bitAnd(value, mask)); }
</ins><span class="cx">     LValue testNonZero64(LValue value, LValue mask) { return notZero64(bitAnd(value, mask)); }
</span><span class="cx">     
</span><span class="cx">     LValue select(LValue value, LValue taken, LValue notTaken) { return buildSelect(m_builder, value, taken, notTaken); }
</span></span></pre>
</div>
</div>

</body>
</html>