<!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>[189280] branches/jsc-tailcall/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/189280">189280</a></dd>
<dt>Author</dt> <dd>msaboff@apple.com</dd>
<dt>Date</dt> <dd>2015-09-03 12:56:35 -0700 (Thu, 03 Sep 2015)</dd>
</dl>

<h3>Log Message</h3>
<pre>jsc-tailcall: Need to handle all architected callee saves for ARM64
https://bugs.webkit.org/show_bug.cgi?id=148652

Reviewed by Basile Clement.

Enumerate and handle all 10 ARM64 general purpose and 8 floating point callee save registers.
Moved the callee saved registers used by LLInt to be the last three callee saves.
Eliminated GPRInfo::numberOfLLIntBaselineCalleeSaveRegisters and use the number of registers
defined in RegisterSet::llintCalleeSaveRegisters() instead.
Eliminated GPRInfo::nonArgGPR1 for all architectures except ARM as it was a callee save for
other architectures.
Found and fixed an issue where we trash callee save 0 (csr0) in the nativeCallTrampoline() macro.

* bytecode/CodeBlock.cpp:
* bytecode/CodeBlock.h:
(JSC::CodeBlock::numberOfLLIntBaselineCalleeSaveRegisters):
* ftl/FTLOSRExitCompiler.cpp:
(JSC::FTL::compileStub):
* ftl/FTLThunks.cpp:
(JSC::FTL::osrExitGenerationThunkGenerator):
* jit/AssemblyHelpers.h:
* jit/FPRInfo.h:
* jit/GPRInfo.h:
* jit/RegisterAtOffsetList.cpp:
(JSC::RegisterAtOffsetList::RegisterAtOffsetList):
* jit/RegisterSet.cpp:
(JSC::RegisterSet::llintCalleeSaveRegisters):
(JSC::RegisterSet::baselineCalleeSaveRegisters):
(JSC::RegisterSet::dfgCalleeSaveRegisters):
(JSC::RegisterSet::ftlCalleeSaveRegisters):
* jit/TempRegisterSet.h:
(JSC::TempRegisterSet::getFPRByIndex):
(JSC::TempRegisterSet::getFreeFPR):
(JSC::TempRegisterSet::setByIndex):
* llint/LowLevelInterpreter.asm:
* llint/LowLevelInterpreter64.asm:
* offlineasm/arm64.rb:
* offlineasm/registers.rb:</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#branchesjsctailcallSourceJavaScriptCoreChangeLog">branches/jsc-tailcall/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#branchesjsctailcallSourceJavaScriptCorebytecodeCodeBlockcpp">branches/jsc-tailcall/Source/JavaScriptCore/bytecode/CodeBlock.cpp</a></li>
<li><a href="#branchesjsctailcallSourceJavaScriptCorebytecodeCodeBlockh">branches/jsc-tailcall/Source/JavaScriptCore/bytecode/CodeBlock.h</a></li>
<li><a href="#branchesjsctailcallSourceJavaScriptCoreftlFTLOSRExitCompilercpp">branches/jsc-tailcall/Source/JavaScriptCore/ftl/FTLOSRExitCompiler.cpp</a></li>
<li><a href="#branchesjsctailcallSourceJavaScriptCoreftlFTLThunkscpp">branches/jsc-tailcall/Source/JavaScriptCore/ftl/FTLThunks.cpp</a></li>
<li><a href="#branchesjsctailcallSourceJavaScriptCorejitAssemblyHelpersh">branches/jsc-tailcall/Source/JavaScriptCore/jit/AssemblyHelpers.h</a></li>
<li><a href="#branchesjsctailcallSourceJavaScriptCorejitFPRInfoh">branches/jsc-tailcall/Source/JavaScriptCore/jit/FPRInfo.h</a></li>
<li><a href="#branchesjsctailcallSourceJavaScriptCorejitGPRInfoh">branches/jsc-tailcall/Source/JavaScriptCore/jit/GPRInfo.h</a></li>
<li><a href="#branchesjsctailcallSourceJavaScriptCorejitRegisterAtOffsetListcpp">branches/jsc-tailcall/Source/JavaScriptCore/jit/RegisterAtOffsetList.cpp</a></li>
<li><a href="#branchesjsctailcallSourceJavaScriptCorejitRegisterSetcpp">branches/jsc-tailcall/Source/JavaScriptCore/jit/RegisterSet.cpp</a></li>
<li><a href="#branchesjsctailcallSourceJavaScriptCorejitTempRegisterSeth">branches/jsc-tailcall/Source/JavaScriptCore/jit/TempRegisterSet.h</a></li>
<li><a href="#branchesjsctailcallSourceJavaScriptCorellintLowLevelInterpreterasm">branches/jsc-tailcall/Source/JavaScriptCore/llint/LowLevelInterpreter.asm</a></li>
<li><a href="#branchesjsctailcallSourceJavaScriptCorellintLowLevelInterpreter64asm">branches/jsc-tailcall/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm</a></li>
<li><a href="#branchesjsctailcallSourceJavaScriptCoreofflineasmarm64rb">branches/jsc-tailcall/Source/JavaScriptCore/offlineasm/arm64.rb</a></li>
<li><a href="#branchesjsctailcallSourceJavaScriptCoreofflineasmregistersrb">branches/jsc-tailcall/Source/JavaScriptCore/offlineasm/registers.rb</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="branchesjsctailcallSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: branches/jsc-tailcall/Source/JavaScriptCore/ChangeLog (189279 => 189280)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsc-tailcall/Source/JavaScriptCore/ChangeLog        2015-09-03 19:45:44 UTC (rev 189279)
+++ branches/jsc-tailcall/Source/JavaScriptCore/ChangeLog        2015-09-03 19:56:35 UTC (rev 189280)
</span><span class="lines">@@ -1,3 +1,44 @@
</span><ins>+2015-09-02  Michael Saboff  &lt;msaboff@apple.com&gt;
+
+        jsc-tailcall: Need to handle all architected callee saves for ARM64
+        https://bugs.webkit.org/show_bug.cgi?id=148652
+
+        Reviewed by Basile Clement.
+
+        Enumerate and handle all 10 ARM64 general purpose and 8 floating point callee save registers.
+        Moved the callee saved registers used by LLInt to be the last three callee saves.
+        Eliminated GPRInfo::numberOfLLIntBaselineCalleeSaveRegisters and use the number of registers
+        defined in RegisterSet::llintCalleeSaveRegisters() instead.
+        Eliminated GPRInfo::nonArgGPR1 for all architectures except ARM as it was a callee save for
+        other architectures.
+        Found and fixed an issue where we trash callee save 0 (csr0) in the nativeCallTrampoline() macro.
+
+        * bytecode/CodeBlock.cpp:
+        * bytecode/CodeBlock.h:
+        (JSC::CodeBlock::numberOfLLIntBaselineCalleeSaveRegisters):
+        * ftl/FTLOSRExitCompiler.cpp:
+        (JSC::FTL::compileStub):
+        * ftl/FTLThunks.cpp:
+        (JSC::FTL::osrExitGenerationThunkGenerator):
+        * jit/AssemblyHelpers.h:
+        * jit/FPRInfo.h:
+        * jit/GPRInfo.h:
+        * jit/RegisterAtOffsetList.cpp:
+        (JSC::RegisterAtOffsetList::RegisterAtOffsetList):
+        * jit/RegisterSet.cpp:
+        (JSC::RegisterSet::llintCalleeSaveRegisters):
+        (JSC::RegisterSet::baselineCalleeSaveRegisters):
+        (JSC::RegisterSet::dfgCalleeSaveRegisters):
+        (JSC::RegisterSet::ftlCalleeSaveRegisters):
+        * jit/TempRegisterSet.h:
+        (JSC::TempRegisterSet::getFPRByIndex):
+        (JSC::TempRegisterSet::getFreeFPR):
+        (JSC::TempRegisterSet::setByIndex):
+        * llint/LowLevelInterpreter.asm:
+        * llint/LowLevelInterpreter64.asm:
+        * offlineasm/arm64.rb:
+        * offlineasm/registers.rb:
+
</ins><span class="cx"> 2015-08-27  Michael Saboff  &lt;msaboff@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         jsc-tailcall: ARM64 crashes running most any test
</span></span></pre></div>
<a id="branchesjsctailcallSourceJavaScriptCorebytecodeCodeBlockcpp"></a>
<div class="modfile"><h4>Modified: branches/jsc-tailcall/Source/JavaScriptCore/bytecode/CodeBlock.cpp (189279 => 189280)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsc-tailcall/Source/JavaScriptCore/bytecode/CodeBlock.cpp        2015-09-03 19:45:44 UTC (rev 189279)
+++ branches/jsc-tailcall/Source/JavaScriptCore/bytecode/CodeBlock.cpp        2015-09-03 19:56:35 UTC (rev 189280)
</span><span class="lines">@@ -55,6 +55,7 @@
</span><span class="cx"> #include &quot;PolymorphicPutByIdList.h&quot;
</span><span class="cx"> #include &quot;ProfilerDatabase.h&quot;
</span><span class="cx"> #include &quot;ReduceWhitespace.h&quot;
</span><ins>+#include &quot;RegisterSet.h&quot;
</ins><span class="cx"> #include &quot;Repatch.h&quot;
</span><span class="cx"> #include &quot;RepatchBuffer.h&quot;
</span><span class="cx"> #include &quot;SlotVisitorInlines.h&quot;
</span></span></pre></div>
<a id="branchesjsctailcallSourceJavaScriptCorebytecodeCodeBlockh"></a>
<div class="modfile"><h4>Modified: branches/jsc-tailcall/Source/JavaScriptCore/bytecode/CodeBlock.h (189279 => 189280)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsc-tailcall/Source/JavaScriptCore/bytecode/CodeBlock.h        2015-09-03 19:45:44 UTC (rev 189279)
+++ branches/jsc-tailcall/Source/JavaScriptCore/bytecode/CodeBlock.h        2015-09-03 19:56:35 UTC (rev 189280)
</span><span class="lines">@@ -733,7 +733,7 @@
</span><span class="cx">     JS_EXPORT_PRIVATE unsigned reoptimizationRetryCounter() const;
</span><span class="cx">     void countReoptimization();
</span><span class="cx"> #if ENABLE(JIT)
</span><del>-    static unsigned numberOfLLIntBaselineCalleeSaveRegisters() { return GPRInfo::numberOfLLIntBaselineCalleeSaveRegisters; }
</del><ins>+    static unsigned numberOfLLIntBaselineCalleeSaveRegisters() { return RegisterSet::llintCalleeSaveRegisters().numberOfSetRegisters(); }
</ins><span class="cx">     static size_t llintBaselineCalleeSaveSpaceAsVirtualRegisters();
</span><span class="cx">     size_t calleeSaveSpaceAsVirtualRegisters();
</span><span class="cx"> 
</span></span></pre></div>
<a id="branchesjsctailcallSourceJavaScriptCoreftlFTLOSRExitCompilercpp"></a>
<div class="modfile"><h4>Modified: branches/jsc-tailcall/Source/JavaScriptCore/ftl/FTLOSRExitCompiler.cpp (189279 => 189280)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsc-tailcall/Source/JavaScriptCore/ftl/FTLOSRExitCompiler.cpp        2015-09-03 19:45:44 UTC (rev 189279)
+++ branches/jsc-tailcall/Source/JavaScriptCore/ftl/FTLOSRExitCompiler.cpp        2015-09-03 19:56:35 UTC (rev 189280)
</span><span class="lines">@@ -440,25 +440,38 @@
</span><span class="cx">         unsigned unwindIndex = codeBlock-&gt;calleeSaveRegisters()-&gt;indexOf(reg);
</span><span class="cx">         RegisterAtOffset* baselineRegisterOffset = baselineCalleeSaves-&gt;find(reg);
</span><span class="cx"> 
</span><del>-        GPRReg regToLoad = baselineRegisterOffset ? GPRInfo::regT0 : reg.gpr();
</del><ins>+        if (reg.isGPR()) {
+            GPRReg regToLoad = baselineRegisterOffset ? GPRInfo::regT0 : reg.gpr();
</ins><span class="cx"> 
</span><del>-        if (unwindIndex == UINT_MAX) {
-            // The FTL compilation didn't preserve this register. This means that it also
-            // didn't use the register. So its value at the beginning of OSR exit should be
-            // preserved by the thunk. Luckily, we saved all registers into the register
-            // scratch buffer, so we can restore them from there.
-            jit.load64(registerScratch + offsetOfReg(reg), regToLoad);
</del><ins>+            if (unwindIndex == UINT_MAX) {
+                // The FTL compilation didn't preserve this register. This means that it also
+                // didn't use the register. So its value at the beginning of OSR exit should be
+                // preserved by the thunk. Luckily, we saved all registers into the register
+                // scratch buffer, so we can restore them from there.
+                jit.load64(registerScratch + offsetOfReg(reg), regToLoad);
+            } else {
+                // The FTL compilation preserved the register. Its new value is therefore
+                // irrelevant, but we can get the value that was preserved by using the unwind
+                // data. We've already copied all unwind-able preserved registers into the unwind
+                // scratch buffer, so we can get it from there.
+                jit.load64(unwindScratch + unwindIndex, regToLoad);
+            }
+
+            if (baselineRegisterOffset)
+                jit.store64(regToLoad, MacroAssembler::Address(MacroAssembler::framePointerRegister, baselineRegisterOffset-&gt;offset()));
</ins><span class="cx">         } else {
</span><del>-            // The FTL compilation preserved the register. Its new value is therefore
-            // irrelevant, but we can get the value that was preserved by using the unwind
-            // data. We've already copied all unwind-able preserved registers into the unwind
-            // scratch buffer, so we can get it from there.
-            jit.load64(unwindScratch + unwindIndex, regToLoad);
</del><ins>+            FPRReg fpRegToLoad = baselineRegisterOffset ? FPRInfo::fpRegT0 : reg.fpr();
+            
+            if (unwindIndex == UINT_MAX)
+                jit.loadDouble(MacroAssembler::TrustedImmPtr(registerScratch + offsetOfReg(reg)), fpRegToLoad);
+            else
+                jit.loadDouble(MacroAssembler::TrustedImmPtr(unwindScratch + unwindIndex), fpRegToLoad);
+            
+            if (baselineRegisterOffset)
+                jit.storeDouble(fpRegToLoad, MacroAssembler::Address(MacroAssembler::framePointerRegister, baselineRegisterOffset-&gt;offset()));
</ins><span class="cx">         }
</span><ins>+    }
</ins><span class="cx"> 
</span><del>-        if (baselineRegisterOffset)
-            jit.store64(regToLoad, MacroAssembler::Address(MacroAssembler::framePointerRegister, baselineRegisterOffset-&gt;offset()));
-    }
</del><span class="cx">     size_t baselineVirtualRegistersForCalleeSaves = baselineCodeBlock-&gt;calleeSaveSpaceAsVirtualRegisters();
</span><span class="cx"> 
</span><span class="cx">     // Now get state out of the scratch buffer and place it back into the stack. The values are
</span></span></pre></div>
<a id="branchesjsctailcallSourceJavaScriptCoreftlFTLThunkscpp"></a>
<div class="modfile"><h4>Modified: branches/jsc-tailcall/Source/JavaScriptCore/ftl/FTLThunks.cpp (189279 => 189280)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsc-tailcall/Source/JavaScriptCore/ftl/FTLThunks.cpp        2015-09-03 19:45:44 UTC (rev 189279)
+++ branches/jsc-tailcall/Source/JavaScriptCore/ftl/FTLThunks.cpp        2015-09-03 19:56:35 UTC (rev 189280)
</span><span class="lines">@@ -66,8 +66,8 @@
</span><span class="cx">     saveAllRegisters(jit, buffer);
</span><span class="cx">     
</span><span class="cx">     // Tell GC mark phase how much of the scratch buffer is active during call.
</span><del>-    jit.move(MacroAssembler::TrustedImmPtr(scratchBuffer-&gt;activeLengthPtr()), GPRInfo::nonArgGPR1);
-    jit.storePtr(MacroAssembler::TrustedImmPtr(requiredScratchMemorySizeInBytes()), GPRInfo::nonArgGPR1);
</del><ins>+    jit.move(MacroAssembler::TrustedImmPtr(scratchBuffer-&gt;activeLengthPtr()), GPRInfo::nonArgGPR0);
+    jit.storePtr(MacroAssembler::TrustedImmPtr(requiredScratchMemorySizeInBytes()), GPRInfo::nonArgGPR0);
</ins><span class="cx"> 
</span><span class="cx">     jit.loadPtr(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
</span><span class="cx">     jit.peek(
</span></span></pre></div>
<a id="branchesjsctailcallSourceJavaScriptCorejitAssemblyHelpersh"></a>
<div class="modfile"><h4>Modified: branches/jsc-tailcall/Source/JavaScriptCore/jit/AssemblyHelpers.h (189279 => 189280)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsc-tailcall/Source/JavaScriptCore/jit/AssemblyHelpers.h        2015-09-03 19:45:44 UTC (rev 189279)
+++ branches/jsc-tailcall/Source/JavaScriptCore/jit/AssemblyHelpers.h        2015-09-03 19:56:35 UTC (rev 189280)
</span><span class="lines">@@ -232,7 +232,10 @@
</span><span class="cx">             RegisterAtOffset entry = allCalleeSaves-&gt;at(i);
</span><span class="cx">             if (dontCopyRegisters.get(entry.reg()))
</span><span class="cx">                 continue;
</span><del>-            storePtr(entry.reg().gpr(), Address(temp1, entry.offset()));
</del><ins>+            if (entry.reg().isGPR())
+                storePtr(entry.reg().gpr(), Address(temp1, entry.offset()));
+            else
+                storeDouble(entry.reg().fpr(), Address(temp1, entry.offset()));
</ins><span class="cx">         }
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="lines">@@ -250,7 +253,10 @@
</span><span class="cx">             RegisterAtOffset entry = allCalleeSaves-&gt;at(i);
</span><span class="cx">             if (dontRestoreRegisters.get(entry.reg()))
</span><span class="cx">                 continue;
</span><del>-            loadPtr(Address(temp1, entry.offset()), entry.reg().gpr());
</del><ins>+            if (entry.reg().isGPR())
+                loadPtr(Address(temp1, entry.offset()), entry.reg().gpr());
+            else
+                loadDouble(Address(temp1, entry.offset()), entry.reg().fpr());
</ins><span class="cx">         }
</span><span class="cx">     }
</span><span class="cx">     
</span><span class="lines">@@ -258,6 +264,7 @@
</span><span class="cx">     {
</span><span class="cx">         GPRReg temp1 = usedRegisters.getFreeGPR(0);
</span><span class="cx">         GPRReg temp2 = usedRegisters.getFreeGPR(1);
</span><ins>+        FPRReg fpTemp = usedRegisters.getFreeFPR();
</ins><span class="cx">         ASSERT(temp2 != InvalidGPRReg);
</span><span class="cx"> 
</span><span class="cx">         ASSERT(codeBlock());
</span><span class="lines">@@ -269,24 +276,36 @@
</span><span class="cx">         RegisterAtOffsetList* currentCalleeSaves = codeBlock()-&gt;calleeSaveRegisters();
</span><span class="cx">         RegisterSet dontCopyRegisters = RegisterSet::stackRegisters();
</span><span class="cx">         unsigned registerCount = allCalleeSaves-&gt;size();
</span><del>-        
</del><ins>+
</ins><span class="cx">         for (unsigned i = 0; i &lt; registerCount; i++) {
</span><del>-            GPRReg regToStore;
-            
</del><span class="cx">             RegisterAtOffset vmEntry = allCalleeSaves-&gt;at(i);
</span><span class="cx">             if (dontCopyRegisters.get(vmEntry.reg()))
</span><span class="cx">                 continue;
</span><span class="cx">             RegisterAtOffset* currentFrameEntry = currentCalleeSaves-&gt;find(vmEntry.reg());
</span><del>-            
-            if (currentFrameEntry) {
-                // Load calleeSave from stack into temp register
-                regToStore = temp2;
-                loadPtr(Address(framePointerRegister, currentFrameEntry-&gt;offset()), regToStore);
-            } else
-                // Just store callee save directly
-                regToStore = vmEntry.reg().gpr();
-            
-            storePtr(regToStore, Address(temp1, vmEntry.offset()));
</del><ins>+
+            if (vmEntry.reg().isGPR()) {
+                GPRReg regToStore;
+                if (currentFrameEntry) {
+                    // Load calleeSave from stack into temp register
+                    regToStore = temp2;
+                    loadPtr(Address(framePointerRegister, currentFrameEntry-&gt;offset()), regToStore);
+                } else
+                    // Just store callee save directly
+                    regToStore = vmEntry.reg().gpr();
+
+                storePtr(regToStore, Address(temp1, vmEntry.offset()));
+            } else {
+                FPRReg fpRegToStore;
+                if (currentFrameEntry) {
+                    // Load calleeSave from stack into temp register
+                    fpRegToStore = fpTemp;
+                    loadDouble(Address(framePointerRegister, currentFrameEntry-&gt;offset()), fpRegToStore);
+                } else
+                    // Just store callee save directly
+                    fpRegToStore = vmEntry.reg().fpr();
+
+                storeDouble(fpRegToStore, Address(temp1, vmEntry.offset()));
+            }
</ins><span class="cx">         }
</span><span class="cx">     }
</span><span class="cx"> 
</span></span></pre></div>
<a id="branchesjsctailcallSourceJavaScriptCorejitFPRInfoh"></a>
<div class="modfile"><h4>Modified: branches/jsc-tailcall/Source/JavaScriptCore/jit/FPRInfo.h (189279 => 189280)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsc-tailcall/Source/JavaScriptCore/jit/FPRInfo.h        2015-09-03 19:45:44 UTC (rev 189279)
+++ branches/jsc-tailcall/Source/JavaScriptCore/jit/FPRInfo.h        2015-09-03 19:56:35 UTC (rev 189280)
</span><span class="lines">@@ -208,6 +208,14 @@
</span><span class="cx">     static const FPRReg fpRegT20 = ARM64Registers::q28;
</span><span class="cx">     static const FPRReg fpRegT21 = ARM64Registers::q29;
</span><span class="cx">     static const FPRReg fpRegT22 = ARM64Registers::q30;
</span><ins>+    static const FPRReg fpRegCS0 = ARM64Registers::q8;
+    static const FPRReg fpRegCS1 = ARM64Registers::q9;
+    static const FPRReg fpRegCS2 = ARM64Registers::q10;
+    static const FPRReg fpRegCS3 = ARM64Registers::q11;
+    static const FPRReg fpRegCS4 = ARM64Registers::q12;
+    static const FPRReg fpRegCS5 = ARM64Registers::q13;
+    static const FPRReg fpRegCS6 = ARM64Registers::q14;
+    static const FPRReg fpRegCS7 = ARM64Registers::q15;
</ins><span class="cx"> 
</span><span class="cx">     static const FPRReg argumentFPR0 = ARM64Registers::q0; // fpRegT0
</span><span class="cx">     static const FPRReg argumentFPR1 = ARM64Registers::q1; // fpRegT1
</span></span></pre></div>
<a id="branchesjsctailcallSourceJavaScriptCorejitGPRInfoh"></a>
<div class="modfile"><h4>Modified: branches/jsc-tailcall/Source/JavaScriptCore/jit/GPRInfo.h (189279 => 189280)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsc-tailcall/Source/JavaScriptCore/jit/GPRInfo.h        2015-09-03 19:45:44 UTC (rev 189279)
+++ branches/jsc-tailcall/Source/JavaScriptCore/jit/GPRInfo.h        2015-09-03 19:56:35 UTC (rev 189280)
</span><span class="lines">@@ -336,7 +336,6 @@
</span><span class="cx">     static const GPRReg argumentGPR2 = X86Registers::eax; // regT0
</span><span class="cx">     static const GPRReg argumentGPR3 = X86Registers::ebx; // regT3
</span><span class="cx">     static const GPRReg nonArgGPR0 = X86Registers::esi; // regT4
</span><del>-    static const GPRReg nonArgGPR1 = X86Registers::edi; // regT5
</del><span class="cx">     static const GPRReg returnValueGPR = X86Registers::eax; // regT0
</span><span class="cx">     static const GPRReg returnValueGPR2 = X86Registers::edx; // regT1
</span><span class="cx">     static const GPRReg nonPreservedNonReturnGPR = X86Registers::ecx;
</span><span class="lines">@@ -447,17 +446,15 @@
</span><span class="cx">     static const GPRReg argumentGPR3 = X86Registers::r9; // regT3
</span><span class="cx"> #endif
</span><span class="cx">     static const GPRReg nonArgGPR0 = X86Registers::r10; // regT5 (regT4 on Windows)
</span><del>-    static const GPRReg nonArgGPR1 = X86Registers::ebx; // Callee save
</del><span class="cx">     static const GPRReg returnValueGPR = X86Registers::eax; // regT0
</span><span class="cx">     static const GPRReg returnValueGPR2 = X86Registers::edx; // regT1 or regT2
</span><span class="cx">     static const GPRReg nonPreservedNonReturnGPR = X86Registers::r10; // regT5 (regT4 on Windows)
</span><span class="cx">     static const GPRReg nonPreservedNonArgumentGPR = X86Registers::r10; // regT5 (regT4 on Windows)
</span><span class="cx">     static const GPRReg patchpointScratchRegister = MacroAssembler::scratchRegister;
</span><ins>+    static const int numberOfLLIntBaselineCalleeSaveRegisters = 3; // r13 (LLInt only), r14 &amp; r15
</ins><span class="cx"> #if !OS(WINDOWS)
</span><del>-    static const int numberOfLLIntBaselineCalleeSaveRegisters = 3; // rbx, r14 &amp; r15
</del><span class="cx">     static const int numberCalleeSaveRegisters = 5;
</span><span class="cx"> #else
</span><del>-    static const int numberOfLLIntBaselineCalleeSaveRegisters = 3; // rbx, r14 &amp; r15
</del><span class="cx">     static const int numberCalleeSaveRegisters = 7;
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="lines">@@ -545,7 +542,6 @@
</span><span class="cx">     static const GPRReg argumentGPR3 = ARMRegisters::r3; // regT3
</span><span class="cx">     static const GPRReg nonArgGPR0 = ARMRegisters::r4; // regT8
</span><span class="cx">     static const GPRReg nonArgGPR1 = ARMRegisters::r8; // regT4
</span><del>-    static const GPRReg nonArgGPR2 = ARMRegisters::r9; // regT5
</del><span class="cx">     static const GPRReg returnValueGPR = ARMRegisters::r0; // regT0
</span><span class="cx">     static const GPRReg returnValueGPR2 = ARMRegisters::r1; // regT1
</span><span class="cx">     static const GPRReg nonPreservedNonReturnGPR = ARMRegisters::r5;
</span><span class="lines">@@ -628,9 +624,16 @@
</span><span class="cx">     static const GPRReg regT13 = ARM64Registers::x13;
</span><span class="cx">     static const GPRReg regT14 = ARM64Registers::x14;
</span><span class="cx">     static const GPRReg regT15 = ARM64Registers::x15;
</span><del>-    static const GPRReg regCS0 = ARM64Registers::x26; // Used by LLInt only
-    static const GPRReg regCS1 = ARM64Registers::x27; // tagTypeNumber
-    static const GPRReg regCS2 = ARM64Registers::x28; // tagMask
</del><ins>+    static const GPRReg regCS0 = ARM64Registers::x19; // Used by FTL only
+    static const GPRReg regCS1 = ARM64Registers::x20; // Used by FTL only
+    static const GPRReg regCS2 = ARM64Registers::x21; // Used by FTL only
+    static const GPRReg regCS3 = ARM64Registers::x22; // Used by FTL only
+    static const GPRReg regCS4 = ARM64Registers::x23; // Used by FTL only
+    static const GPRReg regCS5 = ARM64Registers::x24; // Used by FTL only
+    static const GPRReg regCS6 = ARM64Registers::x25; // Used by FTL only
+    static const GPRReg regCS7 = ARM64Registers::x26;
+    static const GPRReg regCS8 = ARM64Registers::x27; // tagTypeNumber
+    static const GPRReg regCS9 = ARM64Registers::x28; // tagMask
</ins><span class="cx">     // These constants provide the names for the general purpose argument &amp; return value registers.
</span><span class="cx">     static const GPRReg argumentGPR0 = ARM64Registers::x0; // regT0
</span><span class="cx">     static const GPRReg argumentGPR1 = ARM64Registers::x1; // regT1
</span><span class="lines">@@ -641,16 +644,15 @@
</span><span class="cx">     static const GPRReg argumentGPR6 = ARM64Registers::x6; // regT6
</span><span class="cx">     static const GPRReg argumentGPR7 = ARM64Registers::x7; // regT7
</span><span class="cx">     static const GPRReg nonArgGPR0 = ARM64Registers::x8; // regT8
</span><del>-    static const GPRReg nonArgGPR1 = ARM64Registers::x9; // regT9
</del><span class="cx">     static const GPRReg returnValueGPR = ARM64Registers::x0; // regT0
</span><span class="cx">     static const GPRReg returnValueGPR2 = ARM64Registers::x1; // regT1
</span><span class="cx">     static const GPRReg nonPreservedNonReturnGPR = ARM64Registers::x2;
</span><span class="cx">     static const GPRReg nonPreservedNonArgumentGPR = ARM64Registers::x8;
</span><span class="cx">     static const GPRReg patchpointScratchRegister = ARM64Registers::ip0;
</span><span class="cx">     static const int numberOfLLIntBaselineCalleeSaveRegisters = 3; // x26 (LLInt only), x27 &amp; x28
</span><del>-    static const int numberCalleeSaveRegisters = 10;
</del><ins>+    static const int numberCalleeSaveRegisters = 18; // x19..x28 and q8..q15
</ins><span class="cx"> 
</span><del>-    // GPRReg mapping is direct, the machine regsiter numbers can
</del><ins>+    // GPRReg mapping is direct, the machine register numbers can
</ins><span class="cx">     // be used directly as indices into the GPR RegisterBank.
</span><span class="cx">     COMPILE_ASSERT(ARM64Registers::q0 == 0, q0_is_0);
</span><span class="cx">     COMPILE_ASSERT(ARM64Registers::q1 == 1, q1_is_1);
</span><span class="lines">@@ -732,7 +734,6 @@
</span><span class="cx">     static const GPRReg argumentGPR2 = MIPSRegisters::a2;
</span><span class="cx">     static const GPRReg argumentGPR3 = MIPSRegisters::a3;
</span><span class="cx">     static const GPRReg nonArgGPR0 = regT0;
</span><del>-    static const GPRReg nonArgGPR1 = regT1;
</del><span class="cx">     static const GPRReg returnValueGPR = regT0;
</span><span class="cx">     static const GPRReg returnValueGPR2 = regT1;
</span><span class="cx">     static const GPRReg nonPreservedNonReturnGPR = regT2;
</span><span class="lines">@@ -808,7 +809,6 @@
</span><span class="cx">     static const GPRReg argumentGPR2 = SH4Registers::r6; // regT2
</span><span class="cx">     static const GPRReg argumentGPR3 = SH4Registers::r7; // regT3
</span><span class="cx">     static const GPRReg nonArgGPR0 = regT4;
</span><del>-    static const GPRReg nonArgGPR1 = regT5;
</del><span class="cx">     static const GPRReg returnValueGPR = regT0;
</span><span class="cx">     static const GPRReg returnValueGPR2 = regT1;
</span><span class="cx">     static const GPRReg nonPreservedNonReturnGPR = regT2;
</span></span></pre></div>
<a id="branchesjsctailcallSourceJavaScriptCorejitRegisterAtOffsetListcpp"></a>
<div class="modfile"><h4>Modified: branches/jsc-tailcall/Source/JavaScriptCore/jit/RegisterAtOffsetList.cpp (189279 => 189280)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsc-tailcall/Source/JavaScriptCore/jit/RegisterAtOffsetList.cpp        2015-09-03 19:45:44 UTC (rev 189279)
+++ branches/jsc-tailcall/Source/JavaScriptCore/jit/RegisterAtOffsetList.cpp        2015-09-03 19:56:35 UTC (rev 189280)
</span><span class="lines">@@ -36,14 +36,14 @@
</span><span class="cx"> 
</span><span class="cx"> RegisterAtOffsetList::RegisterAtOffsetList(RegisterSet registerSet, OffsetBaseType offsetBaseType)
</span><span class="cx"> {
</span><del>-    size_t numberOfRegisters = registerSet.numberOfSetGPRs();
</del><ins>+    size_t numberOfRegisters = registerSet.numberOfSetRegisters();
</ins><span class="cx">     ptrdiff_t offset = 0;
</span><span class="cx">     
</span><span class="cx">     if (offsetBaseType == FramePointerBased)
</span><span class="cx">         offset = -(static_cast&lt;ptrdiff_t&gt;(numberOfRegisters) * sizeof(void*));
</span><span class="cx"> 
</span><span class="cx">     for (Reg reg = Reg::first(); reg &lt;= Reg::last();reg = reg.next()) {
</span><del>-        if (registerSet.get(reg) &amp;&amp; reg.isGPR()) {
</del><ins>+        if (registerSet.get(reg)) {
</ins><span class="cx">             append(RegisterAtOffset(reg, offset));
</span><span class="cx">             offset += sizeof(void*);
</span><span class="cx">         }
</span></span></pre></div>
<a id="branchesjsctailcallSourceJavaScriptCorejitRegisterSetcpp"></a>
<div class="modfile"><h4>Modified: branches/jsc-tailcall/Source/JavaScriptCore/jit/RegisterSet.cpp (189279 => 189280)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsc-tailcall/Source/JavaScriptCore/jit/RegisterSet.cpp        2015-09-03 19:45:44 UTC (rev 189279)
+++ branches/jsc-tailcall/Source/JavaScriptCore/jit/RegisterSet.cpp        2015-09-03 19:56:35 UTC (rev 189280)
</span><span class="lines">@@ -132,13 +132,14 @@
</span><span class="cx">     RegisterSet result;
</span><span class="cx"> #if CPU(X86)
</span><span class="cx"> #elif CPU(X86_64)
</span><del>-    result.set(GPRInfo::regCS0);
</del><span class="cx"> #if !OS(WINDOWS)
</span><ins>+    result.set(GPRInfo::regCS2);
</ins><span class="cx">     ASSERT(GPRInfo::regCS3 == GPRInfo::tagTypeNumberRegister);
</span><span class="cx">     ASSERT(GPRInfo::regCS4 == GPRInfo::tagMaskRegister);
</span><span class="cx">     result.set(GPRInfo::regCS3);
</span><span class="cx">     result.set(GPRInfo::regCS4);
</span><span class="cx"> #else
</span><ins>+    result.set(GPRInfo::regCS4);
</ins><span class="cx">     ASSERT(GPRInfo::regCS5 == GPRInfo::tagTypeNumberRegister);
</span><span class="cx">     ASSERT(GPRInfo::regCS6 == GPRInfo::tagMaskRegister);
</span><span class="cx">     result.set(GPRInfo::regCS5);
</span><span class="lines">@@ -147,11 +148,11 @@
</span><span class="cx"> #elif CPU(ARM_THUMB2)
</span><span class="cx"> #elif CPU(ARM_TRADITIONAL)
</span><span class="cx"> #elif CPU(ARM64)
</span><del>-    result.set(GPRInfo::regCS0);
-    ASSERT(GPRInfo::regCS1 == GPRInfo::tagTypeNumberRegister);
-    ASSERT(GPRInfo::regCS2 == GPRInfo::tagMaskRegister);
-    result.set(GPRInfo::regCS1);
-    result.set(GPRInfo::regCS2);
</del><ins>+    result.set(GPRInfo::regCS7);
+    ASSERT(GPRInfo::regCS8 == GPRInfo::tagTypeNumberRegister);
+    ASSERT(GPRInfo::regCS9 == GPRInfo::tagMaskRegister);
+    result.set(GPRInfo::regCS8);
+    result.set(GPRInfo::regCS9);
</ins><span class="cx"> #elif CPU(MIPS)
</span><span class="cx"> #elif CPU(SH4)
</span><span class="cx"> #else
</span><span class="lines">@@ -165,7 +166,6 @@
</span><span class="cx">     RegisterSet result;
</span><span class="cx"> #if CPU(X86)
</span><span class="cx"> #elif CPU(X86_64)
</span><del>-    result.set(GPRInfo::regCS0);
</del><span class="cx"> #if !OS(WINDOWS)
</span><span class="cx">     ASSERT(GPRInfo::regCS3 == GPRInfo::tagTypeNumberRegister);
</span><span class="cx">     ASSERT(GPRInfo::regCS4 == GPRInfo::tagMaskRegister);
</span><span class="lines">@@ -180,10 +180,10 @@
</span><span class="cx"> #elif CPU(ARM_THUMB2)
</span><span class="cx"> #elif CPU(ARM_TRADITIONAL)
</span><span class="cx"> #elif CPU(ARM64)
</span><del>-    ASSERT(GPRInfo::regCS1 == GPRInfo::tagTypeNumberRegister);
-    ASSERT(GPRInfo::regCS2 == GPRInfo::tagMaskRegister);
-    result.set(GPRInfo::regCS1);
-    result.set(GPRInfo::regCS2);
</del><ins>+    ASSERT(GPRInfo::regCS8 == GPRInfo::tagTypeNumberRegister);
+    ASSERT(GPRInfo::regCS9 == GPRInfo::tagMaskRegister);
+    result.set(GPRInfo::regCS8);
+    result.set(GPRInfo::regCS9);
</ins><span class="cx"> #elif CPU(MIPS)
</span><span class="cx"> #elif CPU(SH4)
</span><span class="cx"> #else
</span><span class="lines">@@ -216,10 +216,10 @@
</span><span class="cx"> #elif CPU(ARM_THUMB2)
</span><span class="cx"> #elif CPU(ARM_TRADITIONAL)
</span><span class="cx"> #elif CPU(ARM64)
</span><del>-    ASSERT(GPRInfo::regCS1 == GPRInfo::tagTypeNumberRegister);
-    ASSERT(GPRInfo::regCS2 == GPRInfo::tagMaskRegister);
-    result.set(GPRInfo::regCS1);
-    result.set(GPRInfo::regCS2);
</del><ins>+    ASSERT(GPRInfo::regCS8 == GPRInfo::tagTypeNumberRegister);
+    ASSERT(GPRInfo::regCS9 == GPRInfo::tagMaskRegister);
+    result.set(GPRInfo::regCS8);
+    result.set(GPRInfo::regCS9);
</ins><span class="cx"> #elif CPU(MIPS)
</span><span class="cx"> #elif CPU(SH4)
</span><span class="cx"> #else
</span><span class="lines">@@ -242,18 +242,26 @@
</span><span class="cx">     result.set(GPRInfo::regCS4);
</span><span class="cx"> #elif CPU(ARM64)
</span><span class="cx">     // LLVM might save and use all ARM64 callee saves specified in the ABI.
</span><del>-    result.set(ARM64Registers::x19);
-    result.set(ARM64Registers::x20);
-    result.set(ARM64Registers::x21);
-    result.set(ARM64Registers::x22);
-    result.set(ARM64Registers::x23);
-    result.set(ARM64Registers::x24);
-    result.set(ARM64Registers::x25);
</del><span class="cx">     result.set(GPRInfo::regCS0);
</span><del>-    ASSERT(GPRInfo::regCS1 == GPRInfo::tagTypeNumberRegister);
-    ASSERT(GPRInfo::regCS2 == GPRInfo::tagMaskRegister);
</del><span class="cx">     result.set(GPRInfo::regCS1);
</span><span class="cx">     result.set(GPRInfo::regCS2);
</span><ins>+    result.set(GPRInfo::regCS3);
+    result.set(GPRInfo::regCS4);
+    result.set(GPRInfo::regCS5);
+    result.set(GPRInfo::regCS6);
+    result.set(GPRInfo::regCS7);
+    ASSERT(GPRInfo::regCS8 == GPRInfo::tagTypeNumberRegister);
+    ASSERT(GPRInfo::regCS9 == GPRInfo::tagMaskRegister);
+    result.set(GPRInfo::regCS8);
+    result.set(GPRInfo::regCS9);
+    result.set(FPRInfo::fpRegCS0);
+    result.set(FPRInfo::fpRegCS1);
+    result.set(FPRInfo::fpRegCS2);
+    result.set(FPRInfo::fpRegCS3);
+    result.set(FPRInfo::fpRegCS4);
+    result.set(FPRInfo::fpRegCS5);
+    result.set(FPRInfo::fpRegCS6);
+    result.set(FPRInfo::fpRegCS7);
</ins><span class="cx"> #else
</span><span class="cx">     UNREACHABLE_FOR_PLATFORM();
</span><span class="cx"> #endif
</span></span></pre></div>
<a id="branchesjsctailcallSourceJavaScriptCorejitTempRegisterSeth"></a>
<div class="modfile"><h4>Modified: branches/jsc-tailcall/Source/JavaScriptCore/jit/TempRegisterSet.h (189279 => 189280)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsc-tailcall/Source/JavaScriptCore/jit/TempRegisterSet.h        2015-09-03 19:45:44 UTC (rev 189279)
+++ branches/jsc-tailcall/Source/JavaScriptCore/jit/TempRegisterSet.h        2015-09-03 19:56:35 UTC (rev 189280)
</span><span class="lines">@@ -115,6 +115,16 @@
</span><span class="cx">         return getBit(GPRInfo::numberOfRegisters + index);
</span><span class="cx">     }
</span><span class="cx">     
</span><ins>+    // Return the index'th free FPR.
+    FPRReg getFreeFPR(unsigned index = 0) const
+    {
+        for (unsigned i = FPRInfo::numberOfRegisters; i--;) {
+            if (!getFPRByIndex(i) &amp;&amp; !index--)
+                return FPRInfo::toRegister(i);
+        }
+        return InvalidFPRReg;
+    }
+    
</ins><span class="cx">     template&lt;typename BankInfo&gt;
</span><span class="cx">     void setByIndex(unsigned index)
</span><span class="cx">     {
</span></span></pre></div>
<a id="branchesjsctailcallSourceJavaScriptCorellintLowLevelInterpreterasm"></a>
<div class="modfile"><h4>Modified: branches/jsc-tailcall/Source/JavaScriptCore/llint/LowLevelInterpreter.asm (189279 => 189280)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsc-tailcall/Source/JavaScriptCore/llint/LowLevelInterpreter.asm        2015-09-03 19:45:44 UTC (rev 189279)
+++ branches/jsc-tailcall/Source/JavaScriptCore/llint/LowLevelInterpreter.asm        2015-09-03 19:56:35 UTC (rev 189280)
</span><span class="lines">@@ -107,10 +107,9 @@
</span><span class="cx"> #  - t4 and t5 are never argument registers, t3 can only be a3, t1 can only be
</span><span class="cx"> #  a1; but t0 and t2 can be either a0 or a2.
</span><span class="cx"> #
</span><del>-#  - On 64 bits, csr0, csr1, csr2 and optionally csr3, csr4, csr5 and csr6
-#  are available as callee-save registers.
-#  csr0 is used to store the PC base, while the last two csr registers are used
-#  to store special tag values. Don't use them for anything else.
</del><ins>+#  - On 64 bits, there are callee-save registers named csr0, csr1, ... csrN.
+#  The last three csr registers are used used to store the PC base and
+#  two special tag values. Don't use them for anything else.
</ins><span class="cx"> #
</span><span class="cx"> # Additional platform-specific details (you shouldn't rely on this remaining
</span><span class="cx"> # true):
</span><span class="lines">@@ -243,14 +242,16 @@
</span><span class="cx">     # - C calls are still given the Instruction* rather than the PC index.
</span><span class="cx">     #   This requires an add before the call, and a sub after.
</span><span class="cx">     const PC = t4
</span><del>-    const PB = csr0
</del><span class="cx">     if ARM64
</span><del>-        const tagTypeNumber = csr1
-        const tagMask = csr2
</del><ins>+        const PB = csr7
+        const tagTypeNumber = csr8
+        const tagMask = csr9
</ins><span class="cx">     elsif X86_64
</span><ins>+        const PB = csr2
</ins><span class="cx">         const tagTypeNumber = csr3
</span><span class="cx">         const tagMask = csr4
</span><span class="cx">     elsif X86_64_WIN
</span><ins>+        const PB = csr4
</ins><span class="cx">         const tagTypeNumber = csr5
</span><span class="cx">         const tagMask = csr6
</span><span class="cx">     end
</span><span class="lines">@@ -518,11 +519,11 @@
</span><span class="cx">     elsif X86_64
</span><span class="cx">         storep csr4, -8[cfr]
</span><span class="cx">         storep csr3, -16[cfr]
</span><del>-        storep csr0, -24[cfr]
</del><ins>+        storep csr2, -24[cfr]
</ins><span class="cx">     elsif X86_64_WIN
</span><span class="cx">         storep csr6, -8[cfr]
</span><span class="cx">         storep csr5, -16[cfr]
</span><del>-        storep csr0, -24[cfr]
</del><ins>+        storep csr4, -24[cfr]
</ins><span class="cx">     end
</span><span class="cx"> end
</span><span class="cx"> 
</span><span class="lines">@@ -538,11 +539,11 @@
</span><span class="cx">     elsif X86
</span><span class="cx">     elsif X86_WIN
</span><span class="cx">     elsif X86_64
</span><del>-        loadp -24[cfr], csr0
</del><ins>+        loadp -24[cfr], csr2
</ins><span class="cx">         loadp -16[cfr], csr3
</span><span class="cx">         loadp -8[cfr], csr4
</span><span class="cx">     elsif X86_64_WIN
</span><del>-        loadp -24[cfr], csr0
</del><ins>+        loadp -24[cfr], csr4
</ins><span class="cx">         loadp -16[cfr], csr5
</span><span class="cx">         loadp -8[cfr], csr6
</span><span class="cx">     end
</span><span class="lines">@@ -555,6 +556,21 @@
</span><span class="cx">             storep csr0, [temp]
</span><span class="cx">             storep csr1, 8[temp]
</span><span class="cx">             storep csr2, 16[temp]
</span><ins>+            storep csr3, 24[temp]
+            storep csr4, 32[temp]
+            storep csr5, 40[temp]
+            storep csr6, 48[temp]
+            storep csr7, 56[temp]
+            storep csr8, 64[temp]
+            storep csr9, 72[temp]
+            stored csfr0, 80[temp]
+            stored csfr1, 88[temp]
+            stored csfr2, 96[temp]
+            stored csfr3, 104[temp]
+            stored csfr4, 112[temp]
+            stored csfr5, 120[temp]
+            stored csfr6, 128[temp]
+            stored csfr7, 136[temp]
</ins><span class="cx">         elsif X86_64
</span><span class="cx">             storep csr0, [temp]
</span><span class="cx">             storep csr1, 8[temp]
</span><span class="lines">@@ -580,6 +596,21 @@
</span><span class="cx">             loadp [temp], csr0
</span><span class="cx">             loadp 8[temp], csr1
</span><span class="cx">             loadp 16[temp], csr2
</span><ins>+            loadp 24[temp], csr3
+            loadp 32[temp], csr4
+            loadp 40[temp], csr5
+            loadp 48[temp], csr6
+            loadp 56[temp], csr7
+            loadp 64[temp], csr8
+            loadp 72[temp], csr9
+            loadd 80[temp], csfr0
+            loadd 88[temp], csfr1
+            loadd 96[temp], csfr2
+            loadd 104[temp], csfr3
+            loadd 112[temp], csfr4
+            loadd 120[temp], csfr5
+            loadd 128[temp], csfr6
+            loadd 136[temp], csfr7
</ins><span class="cx">         elsif X86_64
</span><span class="cx">             loadp [temp], csr0
</span><span class="cx">             loadp 8[temp], csr1
</span><span class="lines">@@ -609,17 +640,6 @@
</span><span class="cx">     end
</span><span class="cx"> end
</span><span class="cx"> 
</span><del>-macro restoreReturnAddressBeforeReturn(sourceRegister)
-    if C_LOOP or ARM or ARMv7 or ARMv7_TRADITIONAL or ARM64 or MIPS or SH4
-        # In C_LOOP case, we're only restoring the bytecode vPC.
-        move sourceRegister, lr
-    elsif X86 or X86_WIN or X86_64 or X86_64_WIN
-        push sourceRegister
-    else
-        error
-    end
-end
-
</del><span class="cx"> macro functionPrologue()
</span><span class="cx">     if X86 or X86_WIN or X86_64 or X86_64_WIN
</span><span class="cx">         push cfr
</span></span></pre></div>
<a id="branchesjsctailcallSourceJavaScriptCorellintLowLevelInterpreter64asm"></a>
<div class="modfile"><h4>Modified: branches/jsc-tailcall/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm (189279 => 189280)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsc-tailcall/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm        2015-09-03 19:45:44 UTC (rev 189279)
+++ branches/jsc-tailcall/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm        2015-09-03 19:56:35 UTC (rev 189280)
</span><span class="lines">@@ -1835,7 +1835,6 @@
</span><span class="cx">     loadp MarkedBlock::m_weakSet + WeakSet::m_vm[t1], t1
</span><span class="cx">     storep cfr, VM::topCallFrame[t1]
</span><span class="cx">     if ARM64 or C_LOOP
</span><del>-        move lr, csr0
</del><span class="cx">         storep lr, ReturnPC[cfr]
</span><span class="cx">     end
</span><span class="cx">     move cfr, a0
</span><span class="lines">@@ -1853,9 +1852,6 @@
</span><span class="cx">             addp 32, sp
</span><span class="cx">         end
</span><span class="cx">     end
</span><del>-    if ARM64 or C_LOOP
-        move csr0, lr
-    end
</del><span class="cx">     loadp Callee[cfr], t3
</span><span class="cx">     andp MarkedBlockMask, t3
</span><span class="cx">     loadp MarkedBlock::m_weakSet + WeakSet::m_vm[t3], t3
</span></span></pre></div>
<a id="branchesjsctailcallSourceJavaScriptCoreofflineasmarm64rb"></a>
<div class="modfile"><h4>Modified: branches/jsc-tailcall/Source/JavaScriptCore/offlineasm/arm64.rb (189279 => 189280)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsc-tailcall/Source/JavaScriptCore/offlineasm/arm64.rb        2015-09-03 19:45:44 UTC (rev 189279)
+++ branches/jsc-tailcall/Source/JavaScriptCore/offlineasm/arm64.rb        2015-09-03 19:56:35 UTC (rev 189280)
</span><span class="lines">@@ -61,6 +61,14 @@
</span><span class="cx"> #  q3  =&gt; ft3, fa3
</span><span class="cx"> #  q4  =&gt; ft4          (unused in baseline)
</span><span class="cx"> #  q5  =&gt; ft5          (unused in baseline)
</span><ins>+#  q8  =&gt; csfr0        (Only the lower 64 bits)
+#  q9  =&gt; csfr1        (Only the lower 64 bits)
+# q10  =&gt; csfr2        (Only the lower 64 bits)
+# q11  =&gt; csfr3        (Only the lower 64 bits)
+# q12  =&gt; csfr4        (Only the lower 64 bits)
+# q13  =&gt; csfr5        (Only the lower 64 bits)
+# q14  =&gt; csfr6        (Only the lower 64 bits)
+# q15  =&gt; csfr7        (Only the lower 64 bits)
</ins><span class="cx"> # q31  =&gt; scratch
</span><span class="cx"> 
</span><span class="cx"> def arm64GPRName(name, kind)
</span><span class="lines">@@ -116,10 +124,24 @@
</span><span class="cx">         when 'cfr'
</span><span class="cx">             arm64GPRName('x29', kind)
</span><span class="cx">         when 'csr0'
</span><ins>+            arm64GPRName('x19', kind)
+        when 'csr1'
+            arm64GPRName('x20', kind)
+        when 'csr2'
+            arm64GPRName('x21', kind)
+        when 'csr3'
+            arm64GPRName('x22', kind)
+        when 'csr4'
+            arm64GPRName('x23', kind)
+        when 'csr5'
+            arm64GPRName('x24', kind)
+        when 'csr6'
+            arm64GPRName('x25', kind)
+        when 'csr7'
</ins><span class="cx">             arm64GPRName('x26', kind)
</span><del>-        when 'csr1'
</del><ins>+        when 'csr8'
</ins><span class="cx">             arm64GPRName('x27', kind)
</span><del>-        when 'csr2'
</del><ins>+        when 'csr9'
</ins><span class="cx">             arm64GPRName('x28', kind)
</span><span class="cx">         when 'sp'
</span><span class="cx">             'sp'
</span><span class="lines">@@ -146,6 +168,22 @@
</span><span class="cx">             arm64FPRName('q4', kind)
</span><span class="cx">         when 'ft5'
</span><span class="cx">             arm64FPRName('q5', kind)
</span><ins>+        when 'csfr0'
+            arm64FPRName('q8', kind)
+        when 'csfr1'
+            arm64FPRName('q9', kind)
+        when 'csfr2'
+            arm64FPRName('q10', kind)
+        when 'csfr3'
+            arm64FPRName('q11', kind)
+        when 'csfr4'
+            arm64FPRName('q12', kind)
+        when 'csfr5'
+            arm64FPRName('q13', kind)
+        when 'csfr6'
+            arm64FPRName('q14', kind)
+        when 'csfr7'
+            arm64FPRName('q15', kind)
</ins><span class="cx">         else &quot;Bad register name #{@name} at #{codeOriginString}&quot;
</span><span class="cx">         end
</span><span class="cx">     end
</span></span></pre></div>
<a id="branchesjsctailcallSourceJavaScriptCoreofflineasmregistersrb"></a>
<div class="modfile"><h4>Modified: branches/jsc-tailcall/Source/JavaScriptCore/offlineasm/registers.rb (189279 => 189280)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsc-tailcall/Source/JavaScriptCore/offlineasm/registers.rb        2015-09-03 19:45:44 UTC (rev 189279)
+++ branches/jsc-tailcall/Source/JavaScriptCore/offlineasm/registers.rb        2015-09-03 19:56:35 UTC (rev 189280)
</span><span class="lines">@@ -48,7 +48,10 @@
</span><span class="cx">      &quot;csr3&quot;,
</span><span class="cx">      &quot;csr4&quot;,
</span><span class="cx">      &quot;csr5&quot;,
</span><del>-     &quot;csr6&quot;
</del><ins>+     &quot;csr6&quot;,
+     &quot;csr7&quot;,
+     &quot;csr8&quot;,
+     &quot;csr9&quot;
</ins><span class="cx">     ]
</span><span class="cx"> 
</span><span class="cx"> FPRS =
</span><span class="lines">@@ -63,6 +66,14 @@
</span><span class="cx">      &quot;fa1&quot;,
</span><span class="cx">      &quot;fa2&quot;,
</span><span class="cx">      &quot;fa3&quot;,
</span><ins>+     &quot;csfr0&quot;,
+     &quot;csfr1&quot;,
+     &quot;csfr2&quot;,
+     &quot;csfr3&quot;,
+     &quot;csfr4&quot;,
+     &quot;csfr5&quot;,
+     &quot;csfr6&quot;,
+     &quot;csfr7&quot;,
</ins><span class="cx">      &quot;fr&quot;
</span><span class="cx">     ]
</span><span class="cx"> 
</span></span></pre>
</div>
</div>

</body>
</html>