<!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>[189293] 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/189293">189293</a></dd>
<dt>Author</dt> <dd>msaboff@apple.com</dd>
<dt>Date</dt> <dd>2015-09-03 15:16:23 -0700 (Thu, 03 Sep 2015)</dd>
</dl>

<h3>Log Message</h3>
<pre>Clean up register naming
https://bugs.webkit.org/show_bug.cgi?id=148658

Reviewed by Geoffrey Garen.

This changes register naming conventions in the llint and baseline JIT
in order to use as few (native) callee-save registers as possible on
64-bits platforms. It also introduces significant changes in the way
registers names are defined in the LLint and baseline JIT in order to
enable a simpler convention about which registers can be aliased. That
convention is valid across all architecture, and described in
llint/LowLevelInterpreter.asm.

Callee save registers are now called out regCS&lt;n&gt; (in the JIT) or
csr&lt;n&gt; (in the LLInt) with a common numbering across all tiers. Some
registers are unused in some tiers.

As a part of this change, rdi was removed from the list of temporary
registers for X86-64 Windows as it is a callee saves register. This
reduced the number of temporary registers for X86-64 Windows.

This is in preparation for properly handling callee save register
preservation and restoration.

* dfg/DFGJITCompiler.cpp:
(JSC::DFG::JITCompiler::compileFunction):
* ftl/FTLLink.cpp:
(JSC::FTL::link):
* jit/FPRInfo.h:
(JSC::FPRInfo::toRegister):
(JSC::FPRInfo::toIndex):
* jit/GPRInfo.h:
(JSC::GPRInfo::toIndex):
(JSC::GPRInfo::toRegister):
(JSC::GPRInfo::debugName): Deleted.
* jit/JIT.cpp:
(JSC::JIT::privateCompile):
* jit/JITArithmetic.cpp:
(JSC::JIT::emit_op_mod):
* jit/JITOpcodes.cpp:
(JSC::JIT::emitSlow_op_loop_hint):
* jit/JITOpcodes32_64.cpp:
(JSC::JIT::emit_op_end):
(JSC::JIT::emit_op_new_object):
* jit/RegisterPreservationWrapperGenerator.cpp:
(JSC::generateRegisterPreservationWrapper):
(JSC::generateRegisterRestoration):
* jit/ThunkGenerators.cpp:
(JSC::arityFixupGenerator):
(JSC::nativeForGenerator): Deleted.
* llint/LowLevelInterpreter.asm:
* llint/LowLevelInterpreter32_64.asm:
* llint/LowLevelInterpreter64.asm:
* offlineasm/arm.rb:
* offlineasm/arm64.rb:
* offlineasm/cloop.rb:
* offlineasm/mips.rb:
* offlineasm/registers.rb:
* offlineasm/sh4.rb:
* offlineasm/x86.rb:</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceJavaScriptCoreChangeLog">trunk/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGJITCompilercpp">trunk/Source/JavaScriptCore/dfg/DFGJITCompiler.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLLinkcpp">trunk/Source/JavaScriptCore/ftl/FTLLink.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorejitFPRInfoh">trunk/Source/JavaScriptCore/jit/FPRInfo.h</a></li>
<li><a href="#trunkSourceJavaScriptCorejitGPRInfoh">trunk/Source/JavaScriptCore/jit/GPRInfo.h</a></li>
<li><a href="#trunkSourceJavaScriptCorejitJITcpp">trunk/Source/JavaScriptCore/jit/JIT.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorejitJITArithmeticcpp">trunk/Source/JavaScriptCore/jit/JITArithmetic.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorejitJITOpcodescpp">trunk/Source/JavaScriptCore/jit/JITOpcodes.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorejitJITOpcodes32_64cpp">trunk/Source/JavaScriptCore/jit/JITOpcodes32_64.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorejitRegisterPreservationWrapperGeneratorcpp">trunk/Source/JavaScriptCore/jit/RegisterPreservationWrapperGenerator.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorejitThunkGeneratorscpp">trunk/Source/JavaScriptCore/jit/ThunkGenerators.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorellintLowLevelInterpreterasm">trunk/Source/JavaScriptCore/llint/LowLevelInterpreter.asm</a></li>
<li><a href="#trunkSourceJavaScriptCorellintLowLevelInterpreter32_64asm">trunk/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm</a></li>
<li><a href="#trunkSourceJavaScriptCorellintLowLevelInterpreter64asm">trunk/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm</a></li>
<li><a href="#trunkSourceJavaScriptCoreofflineasmarmrb">trunk/Source/JavaScriptCore/offlineasm/arm.rb</a></li>
<li><a href="#trunkSourceJavaScriptCoreofflineasmarm64rb">trunk/Source/JavaScriptCore/offlineasm/arm64.rb</a></li>
<li><a href="#trunkSourceJavaScriptCoreofflineasmclooprb">trunk/Source/JavaScriptCore/offlineasm/cloop.rb</a></li>
<li><a href="#trunkSourceJavaScriptCoreofflineasmmipsrb">trunk/Source/JavaScriptCore/offlineasm/mips.rb</a></li>
<li><a href="#trunkSourceJavaScriptCoreofflineasmregistersrb">trunk/Source/JavaScriptCore/offlineasm/registers.rb</a></li>
<li><a href="#trunkSourceJavaScriptCoreofflineasmsh4rb">trunk/Source/JavaScriptCore/offlineasm/sh4.rb</a></li>
<li><a href="#trunkSourceJavaScriptCoreofflineasmx86rb">trunk/Source/JavaScriptCore/offlineasm/x86.rb</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (189292 => 189293)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2015-09-03 21:55:40 UTC (rev 189292)
+++ trunk/Source/JavaScriptCore/ChangeLog        2015-09-03 22:16:23 UTC (rev 189293)
</span><span class="lines">@@ -1,3 +1,66 @@
</span><ins>+2015-09-03  Basile Clement  &lt;basile_clement@apple.com&gt; and Michael Saboff  &lt;msaboff@apple.com&gt;
+
+        Clean up register naming
+        https://bugs.webkit.org/show_bug.cgi?id=148658
+
+        Reviewed by Geoffrey Garen.
+
+        This changes register naming conventions in the llint and baseline JIT
+        in order to use as few (native) callee-save registers as possible on
+        64-bits platforms. It also introduces significant changes in the way
+        registers names are defined in the LLint and baseline JIT in order to
+        enable a simpler convention about which registers can be aliased. That
+        convention is valid across all architecture, and described in
+        llint/LowLevelInterpreter.asm.
+
+        Callee save registers are now called out regCS&lt;n&gt; (in the JIT) or
+        csr&lt;n&gt; (in the LLInt) with a common numbering across all tiers. Some
+        registers are unused in some tiers.
+
+        As a part of this change, rdi was removed from the list of temporary
+        registers for X86-64 Windows as it is a callee saves register. This
+        reduced the number of temporary registers for X86-64 Windows.
+
+        This is in preparation for properly handling callee save register
+        preservation and restoration.
+
+        * dfg/DFGJITCompiler.cpp:
+        (JSC::DFG::JITCompiler::compileFunction):
+        * ftl/FTLLink.cpp:
+        (JSC::FTL::link):
+        * jit/FPRInfo.h:
+        (JSC::FPRInfo::toRegister):
+        (JSC::FPRInfo::toIndex):
+        * jit/GPRInfo.h:
+        (JSC::GPRInfo::toIndex):
+        (JSC::GPRInfo::toRegister):
+        (JSC::GPRInfo::debugName): Deleted.
+        * jit/JIT.cpp:
+        (JSC::JIT::privateCompile):
+        * jit/JITArithmetic.cpp:
+        (JSC::JIT::emit_op_mod):
+        * jit/JITOpcodes.cpp:
+        (JSC::JIT::emitSlow_op_loop_hint):
+        * jit/JITOpcodes32_64.cpp:
+        (JSC::JIT::emit_op_end):
+        (JSC::JIT::emit_op_new_object):
+        * jit/RegisterPreservationWrapperGenerator.cpp:
+        (JSC::generateRegisterPreservationWrapper):
+        (JSC::generateRegisterRestoration):
+        * jit/ThunkGenerators.cpp:
+        (JSC::arityFixupGenerator):
+        (JSC::nativeForGenerator): Deleted.
+        * llint/LowLevelInterpreter.asm:
+        * llint/LowLevelInterpreter32_64.asm:
+        * llint/LowLevelInterpreter64.asm:
+        * offlineasm/arm.rb:
+        * offlineasm/arm64.rb:
+        * offlineasm/cloop.rb:
+        * offlineasm/mips.rb:
+        * offlineasm/registers.rb:
+        * offlineasm/sh4.rb:
+        * offlineasm/x86.rb:
+
</ins><span class="cx"> 2015-09-03  Filip Pizlo  &lt;fpizlo@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Get rid of RepatchBuffer and replace it with static functions
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGJITCompilercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGJITCompiler.cpp (189292 => 189293)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGJITCompiler.cpp        2015-09-03 21:55:40 UTC (rev 189292)
+++ trunk/Source/JavaScriptCore/dfg/DFGJITCompiler.cpp        2015-09-03 22:16:23 UTC (rev 189293)
</span><span class="lines">@@ -395,18 +395,14 @@
</span><span class="cx">     m_speculative-&gt;callOperationWithCallFrameRollbackOnException(m_codeBlock-&gt;m_isConstructor ? operationConstructArityCheck : operationCallArityCheck, GPRInfo::regT0);
</span><span class="cx">     if (maxFrameExtentForSlowPathCall)
</span><span class="cx">         addPtr(TrustedImm32(maxFrameExtentForSlowPathCall), stackPointerRegister);
</span><del>-    branchTest32(Zero, GPRInfo::regT0).linkTo(fromArityCheck, this);
</del><ins>+    branchTest32(Zero, GPRInfo::returnValueGPR).linkTo(fromArityCheck, this);
</ins><span class="cx">     emitStoreCodeOrigin(CodeOrigin(0));
</span><del>-    GPRReg thunkReg;
-#if USE(JSVALUE64)
-    thunkReg = GPRInfo::regT7;
-#else
-    thunkReg = GPRInfo::regT5;
-#endif
</del><ins>+    GPRReg thunkReg = GPRInfo::argumentGPR1;
</ins><span class="cx">     CodeLocationLabel* arityThunkLabels =
</span><span class="cx">         m_vm-&gt;arityCheckFailReturnThunks-&gt;returnPCsFor(*m_vm, m_codeBlock-&gt;numParameters());
</span><span class="cx">     move(TrustedImmPtr(arityThunkLabels), thunkReg);
</span><del>-    loadPtr(BaseIndex(thunkReg, GPRInfo::regT0, timesPtr()), thunkReg);
</del><ins>+    loadPtr(BaseIndex(thunkReg, GPRInfo::returnValueGPR, timesPtr()), thunkReg);
+    move(GPRInfo::returnValueGPR, GPRInfo::argumentGPR0);
</ins><span class="cx">     m_callArityFixup = call();
</span><span class="cx">     jump(fromArityCheck);
</span><span class="cx">     
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLLinkcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLLink.cpp (189292 => 189293)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLLink.cpp        2015-09-03 21:55:40 UTC (rev 189292)
+++ trunk/Source/JavaScriptCore/ftl/FTLLink.cpp        2015-09-03 22:16:23 UTC (rev 189293)
</span><span class="lines">@@ -165,14 +165,14 @@
</span><span class="cx">         jit.load64(vm.addressOfException(), GPRInfo::regT1);
</span><span class="cx">         jit.jitAssertIsNull(GPRInfo::regT1);
</span><span class="cx"> #endif
</span><del>-        jit.move(GPRInfo::returnValueGPR, GPRInfo::regT0);
</del><ins>+        jit.move(GPRInfo::returnValueGPR, GPRInfo::argumentGPR0);
</ins><span class="cx">         jit.emitFunctionEpilogue();
</span><del>-        mainPathJumps.append(jit.branchTest32(CCallHelpers::Zero, GPRInfo::regT0));
</del><ins>+        mainPathJumps.append(jit.branchTest32(CCallHelpers::Zero, GPRInfo::argumentGPR0));
</ins><span class="cx">         jit.emitFunctionPrologue();
</span><span class="cx">         CodeLocationLabel* arityThunkLabels =
</span><span class="cx">             vm.arityCheckFailReturnThunks-&gt;returnPCsFor(vm, codeBlock-&gt;numParameters());
</span><del>-        jit.move(CCallHelpers::TrustedImmPtr(arityThunkLabels), GPRInfo::regT7);
-        jit.loadPtr(CCallHelpers::BaseIndex(GPRInfo::regT7, GPRInfo::regT0, CCallHelpers::timesPtr()), GPRInfo::regT7);
</del><ins>+        jit.move(CCallHelpers::TrustedImmPtr(arityThunkLabels), GPRInfo::argumentGPR1);
+        jit.loadPtr(CCallHelpers::BaseIndex(GPRInfo::argumentGPR1, GPRInfo::argumentGPR0, CCallHelpers::timesPtr()), GPRInfo::argumentGPR1);
</ins><span class="cx">         CCallHelpers::Call callArityFixup = jit.call();
</span><span class="cx">         jit.emitFunctionEpilogue();
</span><span class="cx">         mainPathJumps.append(jit.jump());
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitFPRInfoh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/FPRInfo.h (189292 => 189293)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/FPRInfo.h        2015-09-03 21:55:40 UTC (rev 189292)
+++ trunk/Source/JavaScriptCore/jit/FPRInfo.h        2015-09-03 22:16:23 UTC (rev 189293)
</span><span class="lines">@@ -268,15 +268,16 @@
</span><span class="cx"> class FPRInfo {
</span><span class="cx"> public:
</span><span class="cx">     typedef FPRReg RegisterType;
</span><del>-    static const unsigned numberOfRegisters = 6;
</del><ins>+    static const unsigned numberOfRegisters = 7;
</ins><span class="cx"> 
</span><span class="cx">     // Temporary registers.
</span><span class="cx">     static const FPRReg fpRegT0 = MIPSRegisters::f0;
</span><del>-    static const FPRReg fpRegT1 = MIPSRegisters::f4;
-    static const FPRReg fpRegT2 = MIPSRegisters::f6;
-    static const FPRReg fpRegT3 = MIPSRegisters::f8;
-    static const FPRReg fpRegT4 = MIPSRegisters::f10;
-    static const FPRReg fpRegT5 = MIPSRegisters::f18;
</del><ins>+    static const FPRReg fpRegT1 = MIPSRegisters::f2;
+    static const FPRReg fpRegT2 = MIPSRegisters::f4;
+    static const FPRReg fpRegT3 = MIPSRegisters::f6;
+    static const FPRReg fpRegT4 = MIPSRegisters::f8;
+    static const FPRReg fpRegT5 = MIPSRegisters::f10;
+    static const FPRReg fpRegT6 = MIPSRegisters::f18;
</ins><span class="cx"> 
</span><span class="cx">     static const FPRReg returnValueFPR = MIPSRegisters::f0;
</span><span class="cx"> 
</span><span class="lines">@@ -286,7 +287,7 @@
</span><span class="cx">     static FPRReg toRegister(unsigned index)
</span><span class="cx">     {
</span><span class="cx">         static const FPRReg registerForIndex[numberOfRegisters] = {
</span><del>-            fpRegT0, fpRegT1, fpRegT2, fpRegT3, fpRegT4, fpRegT5 };
</del><ins>+            fpRegT0, fpRegT1, fpRegT2, fpRegT3, fpRegT4, fpRegT5, fpRegT6 };
</ins><span class="cx"> 
</span><span class="cx">         ASSERT(index &lt; numberOfRegisters);
</span><span class="cx">         return registerForIndex[index];
</span><span class="lines">@@ -297,11 +298,11 @@
</span><span class="cx">         ASSERT(reg != InvalidFPRReg);
</span><span class="cx">         ASSERT(reg &lt; 20);
</span><span class="cx">         static const unsigned indexForRegister[20] = {
</span><del>-            0, InvalidIndex, InvalidIndex, InvalidIndex,
-            1, InvalidIndex, 2, InvalidIndex,
-            3, InvalidIndex, 4, InvalidIndex,
</del><ins>+            0, InvalidIndex, 1, InvalidIndex,
+            2, InvalidIndex, 3, InvalidIndex,
+            4, InvalidIndex, 5, InvalidIndex,
</ins><span class="cx">             InvalidIndex, InvalidIndex, InvalidIndex, InvalidIndex,
</span><del>-            InvalidIndex, InvalidIndex, 5, InvalidIndex,
</del><ins>+            InvalidIndex, InvalidIndex, 6, InvalidIndex,
</ins><span class="cx">         };
</span><span class="cx">         unsigned result = indexForRegister[reg];
</span><span class="cx">         return result;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitGPRInfoh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/GPRInfo.h (189292 => 189293)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/GPRInfo.h        2015-09-03 21:55:40 UTC (rev 189292)
+++ trunk/Source/JavaScriptCore/jit/GPRInfo.h        2015-09-03 22:16:23 UTC (rev 189293)
</span><span class="lines">@@ -31,6 +31,11 @@
</span><span class="cx"> 
</span><span class="cx"> namespace JSC {
</span><span class="cx"> 
</span><ins>+// We use the same conventions in the basline JIT as in the LLint. If you
+// change mappings in the GPRInfo, you should change them in the offlineasm
+// compiler adequately. The register naming conventions are described at the
+// top of the LowLevelInterpreter.asm file.
+
</ins><span class="cx"> typedef MacroAssembler::RegisterID GPRReg;
</span><span class="cx"> #define InvalidGPRReg ((::JSC::GPRReg)-1)
</span><span class="cx"> 
</span><span class="lines">@@ -294,8 +299,6 @@
</span><span class="cx"> };
</span><span class="cx"> #endif // USE(JSVALUE32_64)
</span><span class="cx"> 
</span><del>-// The baseline JIT requires that regT3 be callee-preserved.
-
</del><span class="cx"> #if CPU(X86)
</span><span class="cx"> #define NUMBER_OF_ARGUMENT_REGISTERS 0u
</span><span class="cx"> 
</span><span class="lines">@@ -305,25 +308,21 @@
</span><span class="cx">     static const unsigned numberOfRegisters = 6;
</span><span class="cx">     static const unsigned numberOfArgumentRegisters = NUMBER_OF_ARGUMENT_REGISTERS;
</span><span class="cx"> 
</span><del>-    // Note: regT3 is required to be callee-preserved.
-
</del><span class="cx">     // Temporary registers.
</span><span class="cx">     static const GPRReg regT0 = X86Registers::eax;
</span><span class="cx">     static const GPRReg regT1 = X86Registers::edx;
</span><span class="cx">     static const GPRReg regT2 = X86Registers::ecx;
</span><del>-    static const GPRReg regT3 = X86Registers::ebx;
-    static const GPRReg regT4 = X86Registers::edi;
-    static const GPRReg regT5 = X86Registers::esi;
-    // These registers match the baseline JIT.
-    static const GPRReg cachedResultRegister = regT0;
-    static const GPRReg cachedResultRegister2 = regT1;
</del><ins>+    static const GPRReg regT3 = X86Registers::ebx; // Callee-save
+    static const GPRReg regT4 = X86Registers::esi; // Callee-save
+    static const GPRReg regT5 = X86Registers::edi; // Callee-save
</ins><span class="cx">     static const GPRReg callFrameRegister = X86Registers::ebp;
</span><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 = X86Registers::ecx; // regT2
</span><span class="cx">     static const GPRReg argumentGPR1 = X86Registers::edx; // regT1
</span><ins>+    static const GPRReg argumentGPR2 = X86Registers::eax; // regT0
+    static const GPRReg argumentGPR3 = X86Registers::ebx; // regT3
</ins><span class="cx">     static const GPRReg nonArgGPR0 = X86Registers::esi; // regT4
</span><del>-    static const GPRReg nonArgGPR1 = X86Registers::eax; // regT0
-    static const GPRReg nonArgGPR2 = X86Registers::ebx; // regT3
</del><ins>+    static const GPRReg nonArgGPR1 = X86Registers::edi; // regT5
</ins><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">@@ -345,7 +344,7 @@
</span><span class="cx">     {
</span><span class="cx">         ASSERT(reg != InvalidGPRReg);
</span><span class="cx">         ASSERT(static_cast&lt;int&gt;(reg) &lt; 8);
</span><del>-        static const unsigned indexForRegister[8] = { 0, 2, 1, 3, InvalidIndex, InvalidIndex, 5, 4 };
</del><ins>+        static const unsigned indexForRegister[8] = { 0, 2, 1, 3, InvalidIndex, InvalidIndex, 4, 5 };
</ins><span class="cx">         unsigned result = indexForRegister[reg];
</span><span class="cx">         return result;
</span><span class="cx">     }
</span><span class="lines">@@ -379,52 +378,74 @@
</span><span class="cx">     static const unsigned numberOfRegisters = 11;
</span><span class="cx">     static const unsigned numberOfArgumentRegisters = NUMBER_OF_ARGUMENT_REGISTERS;
</span><span class="cx"> 
</span><del>-    // Note: regT3 is required to be callee-preserved.
-
</del><span class="cx">     // These registers match the baseline JIT.
</span><del>-    static const GPRReg cachedResultRegister = X86Registers::eax;
</del><span class="cx">     static const GPRReg callFrameRegister = X86Registers::ebp;
</span><span class="cx">     static const GPRReg tagTypeNumberRegister = X86Registers::r14;
</span><span class="cx">     static const GPRReg tagMaskRegister = X86Registers::r15;
</span><span class="cx">     // Temporary registers.
</span><span class="cx">     static const GPRReg regT0 = X86Registers::eax;
</span><ins>+#if !OS(WINDOWS)
+    static const GPRReg regT1 = X86Registers::esi;
+    static const GPRReg regT2 = X86Registers::edx;
+    static const GPRReg regT3 = X86Registers::ecx;
+    static const GPRReg regT4 = X86Registers::r8;
+    static const GPRReg regT5 = X86Registers::r10;
+    static const GPRReg regT6 = X86Registers::edi;
+    static const GPRReg regT7 = X86Registers::r9;
+#else
</ins><span class="cx">     static const GPRReg regT1 = X86Registers::edx;
</span><del>-    static const GPRReg regT2 = X86Registers::ecx;
-    static const GPRReg regT3 = X86Registers::ebx;
-    static const GPRReg regT4 = X86Registers::edi;
-    static const GPRReg regT5 = X86Registers::esi;
-    static const GPRReg regT6 = X86Registers::r8;
-    static const GPRReg regT7 = X86Registers::r9;
-    static const GPRReg regT8 = X86Registers::r10;
-    static const GPRReg regT9 = X86Registers::r12;
-    static const GPRReg regT10 = X86Registers::r13;
</del><ins>+    static const GPRReg regT2 = X86Registers::r8;
+    static const GPRReg regT3 = X86Registers::r9;
+    static const GPRReg regT4 = X86Registers::r10;
+    static const GPRReg regT5 = X86Registers::ecx;
+#endif
+
+    static const GPRReg regCS0 = X86Registers::ebx;
+
+#if !OS(WINDOWS)
+    static const GPRReg regCS1 = X86Registers::r12;
+    static const GPRReg regCS2 = X86Registers::r13;
+    static const GPRReg regCS3 = X86Registers::r14;
+    static const GPRReg regCS4 = X86Registers::r15;
+#else
+    static const GPRReg regCS1 = X86Registers::esi;
+    static const GPRReg regCS2 = X86Registers::edi;
+    static const GPRReg regCS3 = X86Registers::r12;
+    static const GPRReg regCS4 = X86Registers::r13;
+    static const GPRReg regCS5 = X86Registers::r14;
+    static const GPRReg regCS6 = X86Registers::r15;
+#endif
+
</ins><span class="cx">     // These constants provide the names for the general purpose argument &amp; return value registers.
</span><span class="cx"> #if !OS(WINDOWS)
</span><del>-    static const GPRReg argumentGPR0 = X86Registers::edi; // regT4
-    static const GPRReg argumentGPR1 = X86Registers::esi; // regT5
-    static const GPRReg argumentGPR2 = X86Registers::edx; // regT1
-    static const GPRReg argumentGPR3 = X86Registers::ecx; // regT2
-    static const GPRReg argumentGPR4 = X86Registers::r8;  // regT6
-    static const GPRReg argumentGPR5 = X86Registers::r9;  // regT7
</del><ins>+    static const GPRReg argumentGPR0 = X86Registers::edi; // regT6
+    static const GPRReg argumentGPR1 = X86Registers::esi; // regT1
+    static const GPRReg argumentGPR2 = X86Registers::edx; // regT2
+    static const GPRReg argumentGPR3 = X86Registers::ecx; // regT3
+    static const GPRReg argumentGPR4 = X86Registers::r8; // regT4
+    static const GPRReg argumentGPR5 = X86Registers::r9; // regT7
</ins><span class="cx"> #else
</span><del>-    static const GPRReg argumentGPR0 = X86Registers::ecx;
-    static const GPRReg argumentGPR1 = X86Registers::edx;
-    static const GPRReg argumentGPR2 = X86Registers::r8; // regT6
-    static const GPRReg argumentGPR3 = X86Registers::r9; // regT7
</del><ins>+    static const GPRReg argumentGPR0 = X86Registers::ecx; // regT5
+    static const GPRReg argumentGPR1 = X86Registers::edx; // regT1
+    static const GPRReg argumentGPR2 = X86Registers::r8; // regT2
+    static const GPRReg argumentGPR3 = X86Registers::r9; // regT3
</ins><span class="cx"> #endif
</span><del>-    static const GPRReg nonArgGPR0 = X86Registers::r10; // regT8
-    static const GPRReg nonArgGPR1 = X86Registers::ebx; // regT3
-    static const GPRReg nonArgGPR2 = X86Registers::r12; // regT9
</del><ins>+    static const GPRReg nonArgGPR0 = X86Registers::r10; // regT5 (regT4 on Windows)
+    static const GPRReg nonArgGPR1 = X86Registers::ebx; // Callee save
</ins><span class="cx">     static const GPRReg returnValueGPR = X86Registers::eax; // regT0
</span><del>-    static const GPRReg returnValueGPR2 = X86Registers::edx; // regT1
-    static const GPRReg nonPreservedNonReturnGPR = X86Registers::esi;
-    static const GPRReg nonPreservedNonArgumentGPR = X86Registers::r10;
</del><ins>+    static const GPRReg returnValueGPR2 = X86Registers::edx; // regT1 or regT2
+    static const GPRReg nonPreservedNonReturnGPR = X86Registers::r10; // regT5 (regT4 on Windows)
+    static const GPRReg nonPreservedNonArgumentGPR = X86Registers::r10; // regT5 (regT4 on Windows)
</ins><span class="cx">     static const GPRReg patchpointScratchRegister = MacroAssembler::scratchRegister;
</span><span class="cx"> 
</span><span class="cx">     static GPRReg toRegister(unsigned index)
</span><span class="cx">     {
</span><span class="cx">         ASSERT(index &lt; numberOfRegisters);
</span><del>-        static const GPRReg registerForIndex[numberOfRegisters] = { regT0, regT1, regT2, regT3, regT4, regT5, regT6, regT7, regT8, regT9, regT10 };
</del><ins>+#if !OS(WINDOWS)
+        static const GPRReg registerForIndex[numberOfRegisters] = { regT0, regT1, regT2, regT3, regT4, regT5, regT6, regT7, regCS0, regCS1, regCS2 };
+#else
+        static const GPRReg registerForIndex[numberOfRegisters] = { regT0, regT1, regT2, regT3, regT4, regT5, regCS0, regCS1, regCS2, regCS3, regCS4 };
+#endif
</ins><span class="cx">         return registerForIndex[index];
</span><span class="cx">     }
</span><span class="cx">     
</span><span class="lines">@@ -443,7 +464,11 @@
</span><span class="cx">     {
</span><span class="cx">         ASSERT(reg != InvalidGPRReg);
</span><span class="cx">         ASSERT(static_cast&lt;int&gt;(reg) &lt; 16);
</span><del>-        static const unsigned indexForRegister[16] = { 0, 2, 1, 3, InvalidIndex, InvalidIndex, 5, 4, 6, 7, 8, InvalidIndex, 9, 10, InvalidIndex, InvalidIndex };
</del><ins>+#if !OS(WINDOWS)
+        static const unsigned indexForRegister[16] = { 0, 3, 2, 8, InvalidIndex, InvalidIndex, 1, 6, 4, 7, 5, InvalidIndex, 9, 10, InvalidIndex, InvalidIndex };
+#else
+        static const unsigned indexForRegister[16] = { 0, 5, 1, 6, InvalidIndex, InvalidIndex, 7, 8, 2, 3, 4, InvalidIndex, 9, 10, InvalidIndex, InvalidIndex };
+#endif
</ins><span class="cx">         return indexForRegister[reg];
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="lines">@@ -474,13 +499,11 @@
</span><span class="cx">     static const unsigned numberOfRegisters = 9;
</span><span class="cx">     static const unsigned numberOfArgumentRegisters = NUMBER_OF_ARGUMENT_REGISTERS;
</span><span class="cx"> 
</span><del>-    // Note: regT3 is required to be callee-preserved.
-
</del><span class="cx">     // Temporary registers.
</span><span class="cx">     static const GPRReg regT0 = ARMRegisters::r0;
</span><span class="cx">     static const GPRReg regT1 = ARMRegisters::r1;
</span><span class="cx">     static const GPRReg regT2 = ARMRegisters::r2;
</span><del>-    static const GPRReg regT3 = ARMRegisters::r4;
</del><ins>+    static const GPRReg regT3 = ARMRegisters::r3;
</ins><span class="cx">     static const GPRReg regT4 = ARMRegisters::r8;
</span><span class="cx">     static const GPRReg regT5 = ARMRegisters::r9;
</span><span class="cx">     static const GPRReg regT6 = ARMRegisters::r10;
</span><span class="lines">@@ -489,22 +512,20 @@
</span><span class="cx"> #else 
</span><span class="cx">     static const GPRReg regT7 = ARMRegisters::r7;
</span><span class="cx"> #endif
</span><del>-    static const GPRReg regT8 = ARMRegisters::r3;
</del><ins>+    static const GPRReg regT8 = ARMRegisters::r4;
</ins><span class="cx">     // These registers match the baseline JIT.
</span><del>-    static const GPRReg cachedResultRegister = regT0;
-    static const GPRReg cachedResultRegister2 = regT1;
</del><span class="cx">     static const GPRReg callFrameRegister = ARMRegisters::fp;
</span><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 = ARMRegisters::r0; // regT0
</span><span class="cx">     static const GPRReg argumentGPR1 = ARMRegisters::r1; // regT1
</span><span class="cx">     static const GPRReg argumentGPR2 = ARMRegisters::r2; // regT2
</span><del>-    static const GPRReg argumentGPR3 = ARMRegisters::r3; // regT8
-    static const GPRReg nonArgGPR0 = ARMRegisters::r4; // regT3
</del><ins>+    static const GPRReg argumentGPR3 = ARMRegisters::r3; // regT3
+    static const GPRReg nonArgGPR0 = ARMRegisters::r4; // regT8
</ins><span class="cx">     static const GPRReg nonArgGPR1 = ARMRegisters::r8; // regT4
</span><span class="cx">     static const GPRReg nonArgGPR2 = ARMRegisters::r9; // regT5
</span><span class="cx">     static const GPRReg returnValueGPR = ARMRegisters::r0; // regT0
</span><span class="cx">     static const GPRReg returnValueGPR2 = ARMRegisters::r1; // regT1
</span><del>-    static const GPRReg nonPreservedNonReturnGPR = ARMRegisters::r5; // regT7
</del><ins>+    static const GPRReg nonPreservedNonReturnGPR = ARMRegisters::r5;
</ins><span class="cx"> 
</span><span class="cx">     static GPRReg toRegister(unsigned index)
</span><span class="cx">     {
</span><span class="lines">@@ -526,9 +547,9 @@
</span><span class="cx">         ASSERT(static_cast&lt;int&gt;(reg) &lt; 16);
</span><span class="cx">         static const unsigned indexForRegister[16] =
</span><span class="cx"> #if CPU(ARM_THUMB2)
</span><del>-            { 0, 1, 2, 8, 3, 9, InvalidIndex, InvalidIndex, 4, 5, 6, 7, InvalidIndex, InvalidIndex, InvalidIndex, InvalidIndex };
</del><ins>+            { 0, 1, 2, 3, 8, InvalidIndex, InvalidIndex, InvalidIndex, 4, 5, 6, 7, InvalidIndex, InvalidIndex, InvalidIndex, InvalidIndex };
</ins><span class="cx"> #else
</span><del>-            { 0, 1, 2, 8, 3, 9, InvalidIndex, 7, 4, 5, 6, InvalidIndex, InvalidIndex, InvalidIndex, InvalidIndex, InvalidIndex };
</del><ins>+            { 0, 1, 2, 3, 8, InvalidIndex, InvalidIndex, 7, 4, 5, 6, InvalidIndex, InvalidIndex, InvalidIndex, InvalidIndex, InvalidIndex };
</ins><span class="cx"> #endif
</span><span class="cx">         unsigned result = indexForRegister[reg];
</span><span class="cx">         return result;
</span><span class="lines">@@ -561,11 +582,7 @@
</span><span class="cx">     static const unsigned numberOfRegisters = 16;
</span><span class="cx">     static const unsigned numberOfArgumentRegisters = 8;
</span><span class="cx"> 
</span><del>-    // Note: regT3 is required to be callee-preserved.
-
</del><span class="cx">     // These registers match the baseline JIT.
</span><del>-    static const GPRReg cachedResultRegister = ARM64Registers::x0;
-    static const GPRReg timeoutCheckRegister = ARM64Registers::x26;
</del><span class="cx">     static const GPRReg callFrameRegister = ARM64Registers::fp;
</span><span class="cx">     static const GPRReg tagTypeNumberRegister = ARM64Registers::x27;
</span><span class="cx">     static const GPRReg tagMaskRegister = ARM64Registers::x28;
</span><span class="lines">@@ -573,9 +590,9 @@
</span><span class="cx">     static const GPRReg regT0 = ARM64Registers::x0;
</span><span class="cx">     static const GPRReg regT1 = ARM64Registers::x1;
</span><span class="cx">     static const GPRReg regT2 = ARM64Registers::x2;
</span><del>-    static const GPRReg regT3 = ARM64Registers::x23;
-    static const GPRReg regT4 = ARM64Registers::x5;
-    static const GPRReg regT5 = ARM64Registers::x24;
</del><ins>+    static const GPRReg regT3 = ARM64Registers::x3;
+    static const GPRReg regT4 = ARM64Registers::x4;
+    static const GPRReg regT5 = ARM64Registers::x5;
</ins><span class="cx">     static const GPRReg regT6 = ARM64Registers::x6;
</span><span class="cx">     static const GPRReg regT7 = ARM64Registers::x7;
</span><span class="cx">     static const GPRReg regT8 = ARM64Registers::x8;
</span><span class="lines">@@ -586,18 +603,20 @@
</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><ins>+    static const GPRReg regCS0 = ARM64Registers::x26; // Used by LLInt only
+    static const GPRReg regCS1 = ARM64Registers::x27; // tagTypeNumber
+    static const GPRReg regCS2 = 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="cx">     static const GPRReg argumentGPR2 = ARM64Registers::x2; // regT2
</span><del>-    static const GPRReg argumentGPR3 = ARM64Registers::x3;
-    static const GPRReg argumentGPR4 = ARM64Registers::x4;
-    static const GPRReg argumentGPR5 = ARM64Registers::x5; // regT4
</del><ins>+    static const GPRReg argumentGPR3 = ARM64Registers::x3; // regT3
+    static const GPRReg argumentGPR4 = ARM64Registers::x4; // regT4
+    static const GPRReg argumentGPR5 = ARM64Registers::x5; // regT5
</ins><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><span class="cx">     static const GPRReg nonArgGPR1 = ARM64Registers::x9; // regT9
</span><del>-    static const GPRReg nonArgGPR2 = ARM64Registers::x10; // regT10
</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="lines">@@ -663,41 +682,38 @@
</span><span class="cx"> class GPRInfo {
</span><span class="cx"> public:
</span><span class="cx">     typedef GPRReg RegisterType;
</span><del>-    static const unsigned numberOfRegisters = 7;
</del><ins>+    static const unsigned numberOfRegisters = 8;
</ins><span class="cx">     static const unsigned numberOfArgumentRegisters = NUMBER_OF_ARGUMENT_REGISTERS;
</span><span class="cx"> 
</span><span class="cx">     // regT0 must be v0 for returning a 32-bit value.
</span><span class="cx">     // regT1 must be v1 for returning a pair of 32-bit value.
</span><del>-    // regT3 must be saved in the callee, so use an S register.
</del><span class="cx"> 
</span><span class="cx">     // Temporary registers.
</span><span class="cx">     static const GPRReg regT0 = MIPSRegisters::v0;
</span><span class="cx">     static const GPRReg regT1 = MIPSRegisters::v1;
</span><del>-    static const GPRReg regT2 = MIPSRegisters::t4;
-    static const GPRReg regT3 = MIPSRegisters::s2;
-    static const GPRReg regT4 = MIPSRegisters::t5;
-    static const GPRReg regT5 = MIPSRegisters::t6;
-    static const GPRReg regT6 = MIPSRegisters::s0;
</del><ins>+    static const GPRReg regT2 = MIPSRegisters::t2;
+    static const GPRReg regT3 = MIPSRegisters::t3;
+    static const GPRReg regT4 = MIPSRegisters::t4;
+    static const GPRReg regT5 = MIPSRegisters::t5;
+    static const GPRReg regT6 = MIPSRegisters::t0;
+    static const GPRReg regT7 = MIPSRegisters::t1;
</ins><span class="cx">     // These registers match the baseline JIT.
</span><del>-    static const GPRReg cachedResultRegister = regT0;
-    static const GPRReg cachedResultRegister2 = regT1;
</del><span class="cx">     static const GPRReg callFrameRegister = MIPSRegisters::fp;
</span><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 = MIPSRegisters::a0;
</span><span class="cx">     static const GPRReg argumentGPR1 = MIPSRegisters::a1;
</span><span class="cx">     static const GPRReg argumentGPR2 = MIPSRegisters::a2;
</span><span class="cx">     static const GPRReg argumentGPR3 = MIPSRegisters::a3;
</span><del>-    static const GPRReg nonArgGPR0 = regT2;
-    static const GPRReg nonArgGPR1 = regT3;
-    static const GPRReg nonArgGPR2 = regT4;
</del><ins>+    static const GPRReg nonArgGPR0 = regT0;
+    static const GPRReg nonArgGPR1 = regT1;
</ins><span class="cx">     static const GPRReg returnValueGPR = regT0;
</span><span class="cx">     static const GPRReg returnValueGPR2 = regT1;
</span><del>-    static const GPRReg nonPreservedNonReturnGPR = regT5;
</del><ins>+    static const GPRReg nonPreservedNonReturnGPR = regT2;
</ins><span class="cx"> 
</span><span class="cx">     static GPRReg toRegister(unsigned index)
</span><span class="cx">     {
</span><span class="cx">         ASSERT(index &lt; numberOfRegisters);
</span><del>-        static const GPRReg registerForIndex[numberOfRegisters] = { regT0, regT1, regT2, regT3, regT4, regT5, regT6 };
</del><ins>+        static const GPRReg registerForIndex[numberOfRegisters] = { regT0, regT1, regT2, regT3, regT4, regT5, regT6, regT7 };
</ins><span class="cx">         return registerForIndex[index];
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="lines">@@ -707,8 +723,8 @@
</span><span class="cx">         ASSERT(reg &lt; 24);
</span><span class="cx">         static const unsigned indexForRegister[24] = {
</span><span class="cx">             InvalidIndex, InvalidIndex, 0, 1, InvalidIndex, InvalidIndex, InvalidIndex, InvalidIndex,
</span><del>-            InvalidIndex, InvalidIndex, InvalidIndex, InvalidIndex, 2, 4, 5, InvalidIndex,
-            6, InvalidIndex, 3, InvalidIndex, InvalidIndex, InvalidIndex, InvalidIndex, InvalidIndex
</del><ins>+            6, 7, 2, 3, 4, 5, InvalidIndex, InvalidIndex,
+            InvalidIndex, InvalidIndex, InvalidIndex, InvalidIndex, InvalidIndex, InvalidIndex, InvalidIndex, InvalidIndex
</ins><span class="cx">         };
</span><span class="cx">         unsigned result = indexForRegister[reg];
</span><span class="cx">         return result;
</span><span class="lines">@@ -745,12 +761,12 @@
</span><span class="cx">     // Temporary registers.
</span><span class="cx">     static const GPRReg regT0 = SH4Registers::r0;
</span><span class="cx">     static const GPRReg regT1 = SH4Registers::r1;
</span><del>-    static const GPRReg regT2 = SH4Registers::r2;
-    static const GPRReg regT3 = SH4Registers::r10;
-    static const GPRReg regT4 = SH4Registers::r4;
-    static const GPRReg regT5 = SH4Registers::r5;
-    static const GPRReg regT6 = SH4Registers::r6;
-    static const GPRReg regT7 = SH4Registers::r7;
</del><ins>+    static const GPRReg regT2 = SH4Registers::r6;
+    static const GPRReg regT3 = SH4Registers::r7;
+    static const GPRReg regT4 = SH4Registers::r2;
+    static const GPRReg regT5 = SH4Registers::r3;
+    static const GPRReg regT6 = SH4Registers::r4;
+    static const GPRReg regT7 = SH4Registers::r5;
</ins><span class="cx">     static const GPRReg regT8 = SH4Registers::r8;
</span><span class="cx">     static const GPRReg regT9 = SH4Registers::r9;
</span><span class="cx">     // These registers match the baseline JIT.
</span><span class="lines">@@ -758,13 +774,12 @@
</span><span class="cx">     static const GPRReg cachedResultRegister2 = regT1;
</span><span class="cx">     static const GPRReg callFrameRegister = SH4Registers::fp;
</span><span class="cx">     // These constants provide the names for the general purpose argument &amp; return value registers.
</span><del>-    static const GPRReg argumentGPR0 = regT4;
-    static const GPRReg argumentGPR1 = regT5;
-    static const GPRReg argumentGPR2 = regT6;
-    static const GPRReg argumentGPR3 = regT7;
-    static const GPRReg nonArgGPR0 = regT3;
-    static const GPRReg nonArgGPR1 = regT8;
-    static const GPRReg nonArgGPR2 = regT9;
</del><ins>+    static const GPRReg argumentGPR0 = SH4Registers::r4; // regT6
+    static const GPRReg argumentGPR1 = SH4Registers::r5; // regT7
+    static const GPRReg argumentGPR2 = SH4Registers::r6; // regT2
+    static const GPRReg argumentGPR3 = SH4Registers::r7; // regT3
+    static const GPRReg nonArgGPR0 = regT4;
+    static const GPRReg nonArgGPR1 = regT5;
</ins><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">@@ -780,7 +795,7 @@
</span><span class="cx">     {
</span><span class="cx">         ASSERT(reg != InvalidGPRReg);
</span><span class="cx">         ASSERT(reg &lt; 14);
</span><del>-        static const unsigned indexForRegister[14] = { 0, 1, 2, InvalidIndex, 4, 5, 6, 7, 8, 9, 3, InvalidIndex, InvalidIndex, InvalidIndex };
</del><ins>+        static const unsigned indexForRegister[14] = { 0, 1, 4, 5, 6, 7, 2, 3, 8, 9, InvalidIndex, InvalidIndex, InvalidIndex, InvalidIndex };
</ins><span class="cx">         unsigned result = indexForRegister[reg];
</span><span class="cx">         return result;
</span><span class="cx">     }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitJITcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/JIT.cpp (189292 => 189293)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/JIT.cpp        2015-09-03 21:55:40 UTC (rev 189292)
+++ trunk/Source/JavaScriptCore/jit/JIT.cpp        2015-09-03 22:16:23 UTC (rev 189293)
</span><span class="lines">@@ -572,19 +572,13 @@
</span><span class="cx">         callOperationWithCallFrameRollbackOnException(m_codeBlock-&gt;m_isConstructor ? operationConstructArityCheck : operationCallArityCheck);
</span><span class="cx">         if (maxFrameExtentForSlowPathCall)
</span><span class="cx">             addPtr(TrustedImm32(maxFrameExtentForSlowPathCall), stackPointerRegister);
</span><del>-        if (returnValueGPR != regT0)
-            move(returnValueGPR, regT0);
-        branchTest32(Zero, regT0).linkTo(beginLabel, this);
-        GPRReg thunkReg;
-#if USE(JSVALUE64)
-        thunkReg = GPRInfo::regT7;
-#else
-        thunkReg = GPRInfo::regT5;
-#endif
</del><ins>+        branchTest32(Zero, returnValueGPR).linkTo(beginLabel, this);
+        GPRReg thunkReg = GPRInfo::argumentGPR1;
</ins><span class="cx">         CodeLocationLabel* failThunkLabels =
</span><span class="cx">             m_vm-&gt;arityCheckFailReturnThunks-&gt;returnPCsFor(*m_vm, m_codeBlock-&gt;numParameters());
</span><span class="cx">         move(TrustedImmPtr(failThunkLabels), thunkReg);
</span><del>-        loadPtr(BaseIndex(thunkReg, regT0, timesPtr()), thunkReg);
</del><ins>+        loadPtr(BaseIndex(thunkReg, returnValueGPR, timesPtr()), thunkReg);
+        move(returnValueGPR, GPRInfo::argumentGPR0);
</ins><span class="cx">         emitNakedCall(m_vm-&gt;getCTIStub(arityFixupGenerator).code());
</span><span class="cx"> 
</span><span class="cx"> #if !ASSERT_DISABLED
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitJITArithmeticcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/JITArithmetic.cpp (189292 => 189293)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/JITArithmetic.cpp        2015-09-03 21:55:40 UTC (rev 189292)
+++ trunk/Source/JavaScriptCore/jit/JITArithmetic.cpp        2015-09-03 22:16:23 UTC (rev 189293)
</span><span class="lines">@@ -611,25 +611,35 @@
</span><span class="cx">     int op2 = currentInstruction[3].u.operand;
</span><span class="cx"> 
</span><span class="cx">     // Make sure registers are correct for x86 IDIV instructions.
</span><ins>+#if CPU(X86)
+    auto edx = regT1;
+    auto ecx = regT2;
+#elif OS(WINDOWS)
+    auto edx = regT1;
+    auto ecx = regT5;
+#else
+    auto edx = regT2;
+    auto ecx = regT3;
+#endif
</ins><span class="cx">     ASSERT(regT0 == X86Registers::eax);
</span><del>-    ASSERT(regT1 == X86Registers::edx);
-    ASSERT(regT2 == X86Registers::ecx);
</del><ins>+    ASSERT(edx == X86Registers::edx);
+    ASSERT(ecx == X86Registers::ecx);
</ins><span class="cx"> 
</span><del>-    emitGetVirtualRegisters(op1, regT3, op2, regT2);
-    emitJumpSlowCaseIfNotImmediateInteger(regT3);
-    emitJumpSlowCaseIfNotImmediateInteger(regT2);
</del><ins>+    emitGetVirtualRegisters(op1, regT4, op2, ecx);
+    emitJumpSlowCaseIfNotImmediateInteger(regT4);
+    emitJumpSlowCaseIfNotImmediateInteger(ecx);
</ins><span class="cx"> 
</span><del>-    move(regT3, regT0);
-    addSlowCase(branchTest32(Zero, regT2));
-    Jump denominatorNotNeg1 = branch32(NotEqual, regT2, TrustedImm32(-1));
</del><ins>+    move(regT4, regT0);
+    addSlowCase(branchTest32(Zero, ecx));
+    Jump denominatorNotNeg1 = branch32(NotEqual, ecx, TrustedImm32(-1));
</ins><span class="cx">     addSlowCase(branch32(Equal, regT0, TrustedImm32(-2147483647-1)));
</span><span class="cx">     denominatorNotNeg1.link(this);
</span><span class="cx">     m_assembler.cdq();
</span><del>-    m_assembler.idivl_r(regT2);
-    Jump numeratorPositive = branch32(GreaterThanOrEqual, regT3, TrustedImm32(0));
-    addSlowCase(branchTest32(Zero, regT1));
</del><ins>+    m_assembler.idivl_r(ecx);
+    Jump numeratorPositive = branch32(GreaterThanOrEqual, regT4, TrustedImm32(0));
+    addSlowCase(branchTest32(Zero, edx));
</ins><span class="cx">     numeratorPositive.link(this);
</span><del>-    emitFastArithReTagImmediate(regT1, regT0);
</del><ins>+    emitFastArithReTagImmediate(edx, regT0);
</ins><span class="cx">     emitPutVirtualRegister(result);
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitJITOpcodescpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/JITOpcodes.cpp (189292 => 189293)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/JITOpcodes.cpp        2015-09-03 21:55:40 UTC (rev 189292)
+++ trunk/Source/JavaScriptCore/jit/JITOpcodes.cpp        2015-09-03 22:16:23 UTC (rev 189293)
</span><span class="lines">@@ -928,7 +928,7 @@
</span><span class="cx">         callOperation(operationOptimize, m_bytecodeOffset);
</span><span class="cx">         Jump noOptimizedEntry = branchTestPtr(Zero, returnValueGPR);
</span><span class="cx">         if (!ASSERT_DISABLED) {
</span><del>-            Jump ok = branchPtr(MacroAssembler::Above, regT0, TrustedImmPtr(bitwise_cast&lt;void*&gt;(static_cast&lt;intptr_t&gt;(1000))));
</del><ins>+            Jump ok = branchPtr(MacroAssembler::Above, returnValueGPR, TrustedImmPtr(bitwise_cast&lt;void*&gt;(static_cast&lt;intptr_t&gt;(1000))));
</ins><span class="cx">             abortWithReason(JITUnreasonableLoopHintJumpTarget);
</span><span class="cx">             ok.link(this);
</span><span class="cx">         }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitJITOpcodes32_64cpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/JITOpcodes32_64.cpp (189292 => 189293)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/JITOpcodes32_64.cpp        2015-09-03 21:55:40 UTC (rev 189292)
+++ trunk/Source/JavaScriptCore/jit/JITOpcodes32_64.cpp        2015-09-03 22:16:23 UTC (rev 189293)
</span><span class="lines">@@ -147,7 +147,7 @@
</span><span class="cx"> void JIT::emit_op_end(Instruction* currentInstruction)
</span><span class="cx"> {
</span><span class="cx">     ASSERT(returnValueGPR != callFrameRegister);
</span><del>-    emitLoad(currentInstruction[1].u.operand, regT1, regT0);
</del><ins>+    emitLoad(currentInstruction[1].u.operand, regT1, returnValueGPR);
</ins><span class="cx">     emitFunctionEpilogue();
</span><span class="cx">     ret();
</span><span class="cx"> }
</span><span class="lines">@@ -164,9 +164,9 @@
</span><span class="cx">     size_t allocationSize = JSFinalObject::allocationSize(structure-&gt;inlineCapacity());
</span><span class="cx">     MarkedAllocator* allocator = &amp;m_vm-&gt;heap.allocatorForObjectWithoutDestructor(allocationSize);
</span><span class="cx"> 
</span><del>-    RegisterID resultReg = regT0;
</del><ins>+    RegisterID resultReg = returnValueGPR;
</ins><span class="cx">     RegisterID allocatorReg = regT1;
</span><del>-    RegisterID scratchReg = regT2;
</del><ins>+    RegisterID scratchReg = regT3;
</ins><span class="cx"> 
</span><span class="cx">     move(TrustedImmPtr(allocator), allocatorReg);
</span><span class="cx">     emitAllocateJSObject(allocatorReg, TrustedImmPtr(structure), resultReg, scratchReg);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitRegisterPreservationWrapperGeneratorcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/RegisterPreservationWrapperGenerator.cpp (189292 => 189293)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/RegisterPreservationWrapperGenerator.cpp        2015-09-03 21:55:40 UTC (rev 189292)
+++ trunk/Source/JavaScriptCore/jit/RegisterPreservationWrapperGenerator.cpp        2015-09-03 22:16:23 UTC (rev 189293)
</span><span class="lines">@@ -65,6 +65,10 @@
</span><span class="cx">     // We shouldn't ever be generating wrappers for native functions.
</span><span class="cx">     RegisterSet toSave = registersToPreserve();
</span><span class="cx">     ptrdiff_t offset = registerPreservationOffset();
</span><ins>+
+    ASSERT(!toSave.get(GPRInfo::regT1));
+    ASSERT(!toSave.get(GPRInfo::regT2));
+    ASSERT(!toSave.get(GPRInfo::regT3));
</ins><span class="cx">     
</span><span class="cx">     AssemblyHelpers jit(&amp;vm, 0);
</span><span class="cx">     
</span><span class="lines">@@ -84,31 +88,30 @@
</span><span class="cx">             JSStack::CallFrameHeaderSize - JSStack::CallerFrameAndPCSize),
</span><span class="cx">         GPRInfo::regT2);
</span><span class="cx"> 
</span><del>-    ASSERT(!toSave.get(GPRInfo::regT4));
-    jit.move(AssemblyHelpers::stackPointerRegister, GPRInfo::regT4);
</del><ins>+    jit.move(AssemblyHelpers::stackPointerRegister, GPRInfo::regT3);
</ins><span class="cx">     
</span><span class="cx">     AssemblyHelpers::Label loop = jit.label();
</span><span class="cx">     jit.sub32(AssemblyHelpers::TrustedImm32(1), GPRInfo::regT2);
</span><del>-    jit.load64(AssemblyHelpers::Address(GPRInfo::regT4, offset), GPRInfo::regT0);
-    jit.store64(GPRInfo::regT0, GPRInfo::regT4);
-    jit.addPtr(AssemblyHelpers::TrustedImm32(sizeof(Register)), GPRInfo::regT4);
</del><ins>+    jit.load64(AssemblyHelpers::Address(GPRInfo::regT3, offset), GPRInfo::regT0);
+    jit.store64(GPRInfo::regT0, GPRInfo::regT3);
+    jit.addPtr(AssemblyHelpers::TrustedImm32(sizeof(Register)), GPRInfo::regT3);
</ins><span class="cx">     jit.branchTest32(AssemblyHelpers::NonZero, GPRInfo::regT2).linkTo(loop, &amp;jit);
</span><span class="cx"> 
</span><del>-    // At this point regT4 + offset points to where we save things.
</del><ins>+    // At this point regT3 + offset points to where we save things.
</ins><span class="cx">     ptrdiff_t currentOffset = 0;
</span><del>-    jit.storePtr(GPRInfo::regT1, AssemblyHelpers::Address(GPRInfo::regT4, currentOffset));
</del><ins>+    jit.storePtr(GPRInfo::regT1, AssemblyHelpers::Address(GPRInfo::regT3, currentOffset));
</ins><span class="cx">     
</span><span class="cx">     for (GPRReg gpr = AssemblyHelpers::firstRegister(); gpr &lt;= AssemblyHelpers::lastRegister(); gpr = static_cast&lt;GPRReg&gt;(gpr + 1)) {
</span><span class="cx">         if (!toSave.get(gpr))
</span><span class="cx">             continue;
</span><span class="cx">         currentOffset += sizeof(Register);
</span><del>-        jit.store64(gpr, AssemblyHelpers::Address(GPRInfo::regT4, currentOffset));
</del><ins>+        jit.store64(gpr, AssemblyHelpers::Address(GPRInfo::regT3, currentOffset));
</ins><span class="cx">     }
</span><span class="cx">     for (FPRReg fpr = AssemblyHelpers::firstFPRegister(); fpr &lt;= AssemblyHelpers::lastFPRegister(); fpr = static_cast&lt;FPRReg&gt;(fpr + 1)) {
</span><span class="cx">         if (!toSave.get(fpr))
</span><span class="cx">             continue;
</span><span class="cx">         currentOffset += sizeof(Register);
</span><del>-        jit.storeDouble(fpr, AssemblyHelpers::Address(GPRInfo::regT4, currentOffset));
</del><ins>+        jit.storeDouble(fpr, AssemblyHelpers::Address(GPRInfo::regT3, currentOffset));
</ins><span class="cx">     }
</span><span class="cx">     
</span><span class="cx">     // Assume that there aren't any saved FP registers.
</span><span class="lines">@@ -151,7 +154,9 @@
</span><span class="cx">     RegisterSet toSave = registersToPreserve();
</span><span class="cx">     ptrdiff_t offset = registerPreservationOffset();
</span><span class="cx">     
</span><del>-    ASSERT(!toSave.get(GPRInfo::regT4));
</del><ins>+    ASSERT(!toSave.get(GPRInfo::regT1));
+    ASSERT(!toSave.get(GPRInfo::regT2));
+    ASSERT(!toSave.get(GPRInfo::regT3));
</ins><span class="cx"> 
</span><span class="cx">     // We need to place the stack pointer back to where the caller thought they left it.
</span><span class="cx">     // But also, in order to recover the registers, we need to figure out how big the
</span><span class="lines">@@ -161,9 +166,9 @@
</span><span class="cx">         AssemblyHelpers::Address(
</span><span class="cx">             AssemblyHelpers::stackPointerRegister,
</span><span class="cx">             (JSStack::ArgumentCount - JSStack::CallerFrameAndPCSize) * sizeof(Register) + PayloadOffset),
</span><del>-        GPRInfo::regT4);
</del><ins>+        GPRInfo::regT3);
</ins><span class="cx">     
</span><del>-    jit.move(GPRInfo::regT4, GPRInfo::regT2);
</del><ins>+    jit.move(GPRInfo::regT3, GPRInfo::regT2);
</ins><span class="cx">     jit.lshift32(AssemblyHelpers::TrustedImm32(3), GPRInfo::regT2);
</span><span class="cx">     
</span><span class="cx">     jit.addPtr(AssemblyHelpers::TrustedImm32(offset), AssemblyHelpers::stackPointerRegister);
</span><span class="lines">@@ -203,7 +208,7 @@
</span><span class="cx">     
</span><span class="cx">     // Thunks like this rely on the ArgumentCount being intact. Pay it forward.
</span><span class="cx">     jit.store32(
</span><del>-        GPRInfo::regT4,
</del><ins>+        GPRInfo::regT3,
</ins><span class="cx">         AssemblyHelpers::Address(
</span><span class="cx">             AssemblyHelpers::stackPointerRegister,
</span><span class="cx">             (JSStack::ArgumentCount - JSStack::CallerFrameAndPCSize) * sizeof(Register) + PayloadOffset));
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitThunkGeneratorscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/ThunkGenerators.cpp (189292 => 189293)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/ThunkGenerators.cpp        2015-09-03 21:55:40 UTC (rev 189292)
+++ trunk/Source/JavaScriptCore/jit/ThunkGenerators.cpp        2015-09-03 22:16:23 UTC (rev 189293)
</span><span class="lines">@@ -255,8 +255,6 @@
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="cx"> #elif CPU(ARM64)
</span><del>-    COMPILE_ASSERT(ARM64Registers::x3 != JSInterfaceJIT::regT1, prev_callframe_not_trampled_by_T1);
-    COMPILE_ASSERT(ARM64Registers::x3 != JSInterfaceJIT::regT3, prev_callframe_not_trampled_by_T3);
</del><span class="cx">     COMPILE_ASSERT(ARM64Registers::x0 != JSInterfaceJIT::regT3, T3_not_trampled_by_arg_0);
</span><span class="cx">     COMPILE_ASSERT(ARM64Registers::x1 != JSInterfaceJIT::regT3, T3_not_trampled_by_arg_1);
</span><span class="cx">     COMPILE_ASSERT(ARM64Registers::x2 != JSInterfaceJIT::regT3, T3_not_trampled_by_arg_2);
</span><span class="lines">@@ -355,46 +353,51 @@
</span><span class="cx"> {
</span><span class="cx">     JSInterfaceJIT jit(vm);
</span><span class="cx"> 
</span><del>-    // We enter with fixup count, in aligned stack units, in regT0 and the return thunk in
-    // regT5 on 32-bit and regT7 on 64-bit.
</del><ins>+    // We enter with fixup count, in aligned stack units, in argumentGPR0 and the return thunk in argumentGPR1
+    // We have the guarantee that a0, a1, a2, t3, t4 and t5 (or t0 for Windows) are all distinct :-)
</ins><span class="cx"> #if USE(JSVALUE64)
</span><ins>+#if OS(WINDOWS)
+    const GPRReg extraTemp = JSInterfaceJIT::regT0;
+#else
+    const GPRReg extraTemp = JSInterfaceJIT::regT5;
+#endif
</ins><span class="cx"> #  if CPU(X86_64)
</span><span class="cx">     jit.pop(JSInterfaceJIT::regT4);
</span><span class="cx"> #  endif
</span><del>-    jit.lshift32(JSInterfaceJIT::TrustedImm32(logStackAlignmentRegisters()), JSInterfaceJIT::regT0);
-    jit.neg64(JSInterfaceJIT::regT0);
-    jit.move(JSInterfaceJIT::callFrameRegister, JSInterfaceJIT::regT6);
-    jit.load32(JSInterfaceJIT::Address(JSInterfaceJIT::callFrameRegister, JSStack::ArgumentCount * sizeof(Register)), JSInterfaceJIT::regT2);
-    jit.add32(JSInterfaceJIT::TrustedImm32(JSStack::CallFrameHeaderSize), JSInterfaceJIT::regT2);
</del><ins>+    jit.lshift32(JSInterfaceJIT::TrustedImm32(logStackAlignmentRegisters()), JSInterfaceJIT::argumentGPR0);
+    jit.neg64(JSInterfaceJIT::argumentGPR0);
+    jit.move(JSInterfaceJIT::callFrameRegister, JSInterfaceJIT::regT3);
+    jit.load32(JSInterfaceJIT::Address(JSInterfaceJIT::callFrameRegister, JSStack::ArgumentCount * sizeof(Register)), JSInterfaceJIT::argumentGPR2);
+    jit.add32(JSInterfaceJIT::TrustedImm32(JSStack::CallFrameHeaderSize), JSInterfaceJIT::argumentGPR2);
</ins><span class="cx"> 
</span><del>-    // Move current frame down regT0 number of slots
</del><ins>+    // Move current frame down argumentGPR0 number of slots
</ins><span class="cx">     JSInterfaceJIT::Label copyLoop(jit.label());
</span><del>-    jit.load64(JSInterfaceJIT::regT6, JSInterfaceJIT::regT1);
-    jit.store64(JSInterfaceJIT::regT1, MacroAssembler::BaseIndex(JSInterfaceJIT::regT6, JSInterfaceJIT::regT0, JSInterfaceJIT::TimesEight));
-    jit.addPtr(JSInterfaceJIT::TrustedImm32(8), JSInterfaceJIT::regT6);
-    jit.branchSub32(MacroAssembler::NonZero, JSInterfaceJIT::TrustedImm32(1), JSInterfaceJIT::regT2).linkTo(copyLoop, &amp;jit);
</del><ins>+    jit.load64(JSInterfaceJIT::regT3, extraTemp);
+    jit.store64(extraTemp, MacroAssembler::BaseIndex(JSInterfaceJIT::regT3, JSInterfaceJIT::argumentGPR0, JSInterfaceJIT::TimesEight));
+    jit.addPtr(JSInterfaceJIT::TrustedImm32(8), JSInterfaceJIT::regT3);
+    jit.branchSub32(MacroAssembler::NonZero, JSInterfaceJIT::TrustedImm32(1), JSInterfaceJIT::argumentGPR2).linkTo(copyLoop, &amp;jit);
</ins><span class="cx"> 
</span><del>-    // Fill in regT0 - 1 missing arg slots with undefined
-    jit.move(JSInterfaceJIT::regT0, JSInterfaceJIT::regT2);
-    jit.move(JSInterfaceJIT::TrustedImm64(ValueUndefined), JSInterfaceJIT::regT1);
-    jit.add32(JSInterfaceJIT::TrustedImm32(1), JSInterfaceJIT::regT2);
</del><ins>+    // Fill in argumentGPR0 - 1 missing arg slots with undefined
+    jit.move(JSInterfaceJIT::argumentGPR0, JSInterfaceJIT::argumentGPR2);
+    jit.move(JSInterfaceJIT::TrustedImm64(ValueUndefined), extraTemp);
+    jit.add32(JSInterfaceJIT::TrustedImm32(1), JSInterfaceJIT::argumentGPR2);
</ins><span class="cx">     JSInterfaceJIT::Label fillUndefinedLoop(jit.label());
</span><del>-    jit.store64(JSInterfaceJIT::regT1, MacroAssembler::BaseIndex(JSInterfaceJIT::regT6, JSInterfaceJIT::regT0, JSInterfaceJIT::TimesEight));
-    jit.addPtr(JSInterfaceJIT::TrustedImm32(8), JSInterfaceJIT::regT6);
-    jit.branchAdd32(MacroAssembler::NonZero, JSInterfaceJIT::TrustedImm32(1), JSInterfaceJIT::regT2).linkTo(fillUndefinedLoop, &amp;jit);
</del><ins>+    jit.store64(extraTemp, MacroAssembler::BaseIndex(JSInterfaceJIT::regT3, JSInterfaceJIT::argumentGPR0, JSInterfaceJIT::TimesEight));
+    jit.addPtr(JSInterfaceJIT::TrustedImm32(8), JSInterfaceJIT::regT3);
+    jit.branchAdd32(MacroAssembler::NonZero, JSInterfaceJIT::TrustedImm32(1), JSInterfaceJIT::argumentGPR2).linkTo(fillUndefinedLoop, &amp;jit);
</ins><span class="cx">     
</span><span class="cx">     // Adjust call frame register and stack pointer to account for missing args
</span><del>-    jit.move(JSInterfaceJIT::regT0, JSInterfaceJIT::regT1);
-    jit.lshift64(JSInterfaceJIT::TrustedImm32(3), JSInterfaceJIT::regT1);
-    jit.addPtr(JSInterfaceJIT::regT1, JSInterfaceJIT::callFrameRegister);
-    jit.addPtr(JSInterfaceJIT::regT1, JSInterfaceJIT::stackPointerRegister);
</del><ins>+    jit.move(JSInterfaceJIT::argumentGPR0, extraTemp);
+    jit.lshift64(JSInterfaceJIT::TrustedImm32(3), extraTemp);
+    jit.addPtr(extraTemp, JSInterfaceJIT::callFrameRegister);
+    jit.addPtr(extraTemp, JSInterfaceJIT::stackPointerRegister);
</ins><span class="cx"> 
</span><span class="cx">     // Save the original return PC.
</span><del>-    jit.loadPtr(JSInterfaceJIT::Address(JSInterfaceJIT::callFrameRegister, CallFrame::returnPCOffset()), GPRInfo::regT1);
-    jit.storePtr(GPRInfo::regT1, MacroAssembler::BaseIndex(JSInterfaceJIT::regT6, JSInterfaceJIT::regT0, JSInterfaceJIT::TimesEight));
-    
</del><ins>+    jit.loadPtr(JSInterfaceJIT::Address(JSInterfaceJIT::callFrameRegister, CallFrame::returnPCOffset()), extraTemp);
+    jit.storePtr(extraTemp, MacroAssembler::BaseIndex(JSInterfaceJIT::regT3, JSInterfaceJIT::argumentGPR0, JSInterfaceJIT::TimesEight));
+
</ins><span class="cx">     // Install the new return PC.
</span><del>-    jit.storePtr(GPRInfo::regT7, JSInterfaceJIT::Address(JSInterfaceJIT::callFrameRegister, CallFrame::returnPCOffset()));
</del><ins>+    jit.storePtr(GPRInfo::argumentGPR1, JSInterfaceJIT::Address(JSInterfaceJIT::callFrameRegister, CallFrame::returnPCOffset()));
</ins><span class="cx"> 
</span><span class="cx"> #  if CPU(X86_64)
</span><span class="cx">     jit.push(JSInterfaceJIT::regT4);
</span><span class="lines">@@ -404,45 +407,45 @@
</span><span class="cx"> #  if CPU(X86)
</span><span class="cx">     jit.pop(JSInterfaceJIT::regT4);
</span><span class="cx"> #  endif
</span><del>-    jit.lshift32(JSInterfaceJIT::TrustedImm32(logStackAlignmentRegisters()), JSInterfaceJIT::regT0);
-    jit.neg32(JSInterfaceJIT::regT0);
</del><ins>+    jit.lshift32(JSInterfaceJIT::TrustedImm32(logStackAlignmentRegisters()), JSInterfaceJIT::argumentGPR0);
+    jit.neg32(JSInterfaceJIT::argumentGPR0);
</ins><span class="cx">     jit.move(JSInterfaceJIT::callFrameRegister, JSInterfaceJIT::regT3);
</span><del>-    jit.load32(JSInterfaceJIT::Address(JSInterfaceJIT::callFrameRegister, JSStack::ArgumentCount * sizeof(Register)), JSInterfaceJIT::regT2);
-    jit.add32(JSInterfaceJIT::TrustedImm32(JSStack::CallFrameHeaderSize), JSInterfaceJIT::regT2);
</del><ins>+    jit.load32(JSInterfaceJIT::Address(JSInterfaceJIT::callFrameRegister, JSStack::ArgumentCount * sizeof(Register)), JSInterfaceJIT::argumentGPR2);
+    jit.add32(JSInterfaceJIT::TrustedImm32(JSStack::CallFrameHeaderSize), JSInterfaceJIT::argumentGPR2);
</ins><span class="cx"> 
</span><del>-    // Move current frame down regT0 number of slots
</del><ins>+    // Move current frame down argumentGPR0 number of slots
</ins><span class="cx">     JSInterfaceJIT::Label copyLoop(jit.label());
</span><del>-    jit.load32(JSInterfaceJIT::regT3, JSInterfaceJIT::regT1);
-    jit.store32(JSInterfaceJIT::regT1, MacroAssembler::BaseIndex(JSInterfaceJIT::regT3, JSInterfaceJIT::regT0, JSInterfaceJIT::TimesEight));
-    jit.load32(MacroAssembler::Address(JSInterfaceJIT::regT3, 4), JSInterfaceJIT::regT1);
-    jit.store32(JSInterfaceJIT::regT1, MacroAssembler::BaseIndex(JSInterfaceJIT::regT3, JSInterfaceJIT::regT0, JSInterfaceJIT::TimesEight, 4));
</del><ins>+    jit.load32(JSInterfaceJIT::regT3, JSInterfaceJIT::regT5);
+    jit.store32(JSInterfaceJIT::regT5, MacroAssembler::BaseIndex(JSInterfaceJIT::regT3, JSInterfaceJIT::argumentGPR0, JSInterfaceJIT::TimesEight));
+    jit.load32(MacroAssembler::Address(JSInterfaceJIT::regT3, 4), JSInterfaceJIT::regT5);
+    jit.store32(JSInterfaceJIT::regT5, MacroAssembler::BaseIndex(JSInterfaceJIT::regT3, JSInterfaceJIT::argumentGPR0, JSInterfaceJIT::TimesEight, 4));
</ins><span class="cx">     jit.addPtr(JSInterfaceJIT::TrustedImm32(8), JSInterfaceJIT::regT3);
</span><del>-    jit.branchSub32(MacroAssembler::NonZero, JSInterfaceJIT::TrustedImm32(1), JSInterfaceJIT::regT2).linkTo(copyLoop, &amp;jit);
</del><ins>+    jit.branchSub32(MacroAssembler::NonZero, JSInterfaceJIT::TrustedImm32(1), JSInterfaceJIT::argumentGPR2).linkTo(copyLoop, &amp;jit);
</ins><span class="cx"> 
</span><del>-    // Fill in regT0 - 1 missing arg slots with undefined
-    jit.move(JSInterfaceJIT::regT0, JSInterfaceJIT::regT2);
-    jit.add32(JSInterfaceJIT::TrustedImm32(1), JSInterfaceJIT::regT2);
</del><ins>+    // Fill in argumentGPR0 - 1 missing arg slots with undefined
+    jit.move(JSInterfaceJIT::argumentGPR0, JSInterfaceJIT::argumentGPR2);
+    jit.add32(JSInterfaceJIT::TrustedImm32(1), JSInterfaceJIT::argumentGPR2);
</ins><span class="cx">     JSInterfaceJIT::Label fillUndefinedLoop(jit.label());
</span><del>-    jit.move(JSInterfaceJIT::TrustedImm32(0), JSInterfaceJIT::regT1);
-    jit.store32(JSInterfaceJIT::regT1, MacroAssembler::BaseIndex(JSInterfaceJIT::regT3, JSInterfaceJIT::regT0, JSInterfaceJIT::TimesEight));
-    jit.move(JSInterfaceJIT::TrustedImm32(JSValue::UndefinedTag), JSInterfaceJIT::regT1);
-    jit.store32(JSInterfaceJIT::regT1, MacroAssembler::BaseIndex(JSInterfaceJIT::regT3, JSInterfaceJIT::regT0, JSInterfaceJIT::TimesEight, 4));
</del><ins>+    jit.move(JSInterfaceJIT::TrustedImm32(0), JSInterfaceJIT::regT5);
+    jit.store32(JSInterfaceJIT::regT5, MacroAssembler::BaseIndex(JSInterfaceJIT::regT3, JSInterfaceJIT::argumentGPR0, JSInterfaceJIT::TimesEight));
+    jit.move(JSInterfaceJIT::TrustedImm32(JSValue::UndefinedTag), JSInterfaceJIT::regT5);
+    jit.store32(JSInterfaceJIT::regT5, MacroAssembler::BaseIndex(JSInterfaceJIT::regT3, JSInterfaceJIT::argumentGPR0, JSInterfaceJIT::TimesEight, 4));
</ins><span class="cx"> 
</span><span class="cx">     jit.addPtr(JSInterfaceJIT::TrustedImm32(8), JSInterfaceJIT::regT3);
</span><del>-    jit.branchAdd32(MacroAssembler::NonZero, JSInterfaceJIT::TrustedImm32(1), JSInterfaceJIT::regT2).linkTo(fillUndefinedLoop, &amp;jit);
</del><ins>+    jit.branchAdd32(MacroAssembler::NonZero, JSInterfaceJIT::TrustedImm32(1), JSInterfaceJIT::argumentGPR2).linkTo(fillUndefinedLoop, &amp;jit);
</ins><span class="cx"> 
</span><span class="cx">     // Adjust call frame register and stack pointer to account for missing args
</span><del>-    jit.move(JSInterfaceJIT::regT0, JSInterfaceJIT::regT1);
-    jit.lshift32(JSInterfaceJIT::TrustedImm32(3), JSInterfaceJIT::regT1);
-    jit.addPtr(JSInterfaceJIT::regT1, JSInterfaceJIT::callFrameRegister);
-    jit.addPtr(JSInterfaceJIT::regT1, JSInterfaceJIT::stackPointerRegister);
</del><ins>+    jit.move(JSInterfaceJIT::argumentGPR0, JSInterfaceJIT::regT5);
+    jit.lshift32(JSInterfaceJIT::TrustedImm32(3), JSInterfaceJIT::regT5);
+    jit.addPtr(JSInterfaceJIT::regT5, JSInterfaceJIT::callFrameRegister);
+    jit.addPtr(JSInterfaceJIT::regT5, JSInterfaceJIT::stackPointerRegister);
</ins><span class="cx"> 
</span><span class="cx">     // Save the original return PC.
</span><del>-    jit.loadPtr(JSInterfaceJIT::Address(JSInterfaceJIT::callFrameRegister, CallFrame::returnPCOffset()), GPRInfo::regT1);
-    jit.storePtr(GPRInfo::regT1, MacroAssembler::BaseIndex(JSInterfaceJIT::regT3, JSInterfaceJIT::regT0, JSInterfaceJIT::TimesEight));
</del><ins>+    jit.loadPtr(JSInterfaceJIT::Address(JSInterfaceJIT::callFrameRegister, CallFrame::returnPCOffset()), GPRInfo::regT5);
+    jit.storePtr(GPRInfo::regT5, MacroAssembler::BaseIndex(JSInterfaceJIT::regT3, JSInterfaceJIT::argumentGPR0, JSInterfaceJIT::TimesEight));
</ins><span class="cx">     
</span><span class="cx">     // Install the new return PC.
</span><del>-    jit.storePtr(GPRInfo::regT5, JSInterfaceJIT::Address(JSInterfaceJIT::callFrameRegister, CallFrame::returnPCOffset()));
</del><ins>+    jit.storePtr(GPRInfo::argumentGPR1, JSInterfaceJIT::Address(JSInterfaceJIT::callFrameRegister, CallFrame::returnPCOffset()));
</ins><span class="cx">     
</span><span class="cx"> #  if CPU(X86)
</span><span class="cx">     jit.push(JSInterfaceJIT::regT4);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorellintLowLevelInterpreterasm"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/llint/LowLevelInterpreter.asm (189292 => 189293)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/llint/LowLevelInterpreter.asm        2015-09-03 21:55:40 UTC (rev 189292)
+++ trunk/Source/JavaScriptCore/llint/LowLevelInterpreter.asm        2015-09-03 22:16:23 UTC (rev 189293)
</span><span class="lines">@@ -21,6 +21,126 @@
</span><span class="cx"> # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
</span><span class="cx"> # THE POSSIBILITY OF SUCH DAMAGE.
</span><span class="cx"> 
</span><ins>+# Crash course on the language that this is written in (which I just call
+# &quot;assembly&quot; even though it's more than that):
+#
+# - Mostly gas-style operand ordering. The last operand tends to be the
+#   destination. So &quot;a := b&quot; is written as &quot;mov b, a&quot;. But unlike gas,
+#   comparisons are in-order, so &quot;if (a &lt; b)&quot; is written as
+#   &quot;bilt a, b, ...&quot;.
+#
+# - &quot;b&quot; = byte, &quot;h&quot; = 16-bit word, &quot;i&quot; = 32-bit word, &quot;p&quot; = pointer.
+#   For 32-bit, &quot;i&quot; and &quot;p&quot; are interchangeable except when an op supports one
+#   but not the other.
+#
+# - In general, valid operands for macro invocations and instructions are
+#   registers (eg &quot;t0&quot;), addresses (eg &quot;4[t0]&quot;), base-index addresses
+#   (eg &quot;7[t0, t1, 2]&quot;), absolute addresses (eg &quot;0xa0000000[]&quot;), or labels
+#   (eg &quot;_foo&quot; or &quot;.foo&quot;). Macro invocations can also take anonymous
+#   macros as operands. Instructions cannot take anonymous macros.
+#
+# - Labels must have names that begin with either &quot;_&quot; or &quot;.&quot;.  A &quot;.&quot; label
+#   is local and gets renamed before code gen to minimize namespace
+#   pollution. A &quot;_&quot; label is an extern symbol (i.e. &quot;.globl&quot;). The &quot;_&quot;
+#   may or may not be removed during code gen depending on whether the asm
+#   conventions for C name mangling on the target platform mandate a &quot;_&quot;
+#   prefix.
+#
+# - A &quot;macro&quot; is a lambda expression, which may be either anonymous or
+#   named. But this has caveats. &quot;macro&quot; can take zero or more arguments,
+#   which may be macros or any valid operands, but it can only return
+#   code. But you can do Turing-complete things via continuation passing
+#   style: &quot;macro foo (a, b) b(a, a) end foo(foo, foo)&quot;. Actually, don't do
+#   that, since you'll just crash the assembler.
+#
+# - An &quot;if&quot; is a conditional on settings. Any identifier supplied in the
+#   predicate of an &quot;if&quot; is assumed to be a #define that is available
+#   during code gen. So you can't use &quot;if&quot; for computation in a macro, but
+#   you can use it to select different pieces of code for different
+#   platforms.
+#
+# - Arguments to macros follow lexical scoping rather than dynamic scoping.
+#   Const's also follow lexical scoping and may override (hide) arguments
+#   or other consts. All variables (arguments and constants) can be bound
+#   to operands. Additionally, arguments (but not constants) can be bound
+#   to macros.
+
+# The following general-purpose registers are available:
+#
+#  - cfr and sp hold the call frame and (native) stack pointer respectively.
+#  They are callee-save registers, and guaranteed to be distinct from all other
+#  registers on all architectures.
+#
+#  - lr is defined on non-X86 architectures (ARM64, ARMv7, ARM,
+#  ARMv7_TRADITIONAL, MIPS, SH4 and CLOOP) and holds the return PC
+#
+#  - pc holds the (native) program counter on 32-bits ARM architectures (ARM,
+#  ARMv7, ARMv7_TRADITIONAL)
+#
+#  - t0, t1, t2, t3, t4 and optionally t5 are temporary registers that can get trashed on
+#  calls, and are pairwise distinct registers. t4 holds the JS program counter, so use
+#  with caution in opcodes (actually, don't use it in opcodes at all, except as PC).
+#
+#  - r0 and r1 are the platform's customary return registers, and thus are
+#  two distinct registers
+#
+#  - a0, a1, a2 and a3 are the platform's customary argument registers, and
+#  thus are pairwise distinct registers. Be mindful that:
+#    + On X86, there are no argument registers. a0 and a1 are edx and
+#    ecx following the fastcall convention, but you should still use the stack
+#    to pass your arguments. The cCall2 and cCall4 macros do this for you.
+#    + On X86_64_WIN, you should allocate space on the stack for the arguments,
+#    and the return convention is weird for &gt; 8 bytes types. The only place we
+#    use &gt; 8 bytes return values is on a cCall, and cCall2 and cCall4 handle
+#    this for you.
+#
+#  - The only registers guaranteed to be caller-saved are r0, r1, a0, a1 and a2, and
+#  you should be mindful of that in functions that are called directly from C.
+#  If you need more registers, you should push and pop them like a good
+#  assembly citizen, because any other register will be callee-saved on X86.
+#
+# You can additionally assume:
+#
+#  - a3, t2, t3, t4 and t5 are never return registers; t0, t1, a0, a1 and a2
+#  can be return registers.
+#
+#  - t4 and t5 are never argument registers, t3 can only be a3, t1 can only be
+#  a1; but t0 and t2 can be either a0 or a2.
+#
+#  - 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.
+#
+# Additional platform-specific details (you shouldn't rely on this remaining
+# true):
+#
+#  - For consistency with the baseline JIT, t0 is always r0 (and t1 is always
+#  r1 on 32 bits platforms). You should use the r version when you need return
+#  registers, and the t version otherwise: code using t0 (or t1) should still
+#  work if swapped with e.g. t3, while code using r0 (or r1) should not. There
+#  *may* be legacy code relying on this.
+#
+#  - On all platforms other than X86, t0 can only be a0 and t2 can only be a2.
+#
+#  - On all platforms other than X86 and X86_64, a2 is not a return register.
+#  a2 is r0 on X86 (because we have so few registers) and r1 on X86_64 (because
+#  the ABI enforces it).
+#
+# The following floating-point registers are available:
+#
+#  - ft0-ft5 are temporary floating-point registers that get trashed on calls,
+#  and are pairwise distinct.
+#
+#  - fa0 and fa1 are the platform's customary floating-point argument
+#  registers, and are both distinct. On 64-bits platforms, fa2 and fa3 are
+#  additional floating-point argument registers.
+#
+#  - fr is the platform's customary floating-point return register
+#
+# You can assume that ft1-ft5 or fa1-fa3 are never fr, and that ftX is never
+# faY if X != Y.
+
</ins><span class="cx"> # First come the common protocols that both interpreters use. Note that each
</span><span class="cx"> # of these must have an ASSERT() in LLIntData.cpp
</span><span class="cx"> 
</span><span class="lines">@@ -107,16 +227,25 @@
</span><span class="cx"> if JSVALUE64
</span><span class="cx">     # - Use a pair of registers to represent the PC: one register for the
</span><span class="cx">     #   base of the bytecodes, and one register for the index.
</span><del>-    # - The PC base (or PB for short) should be stored in the csr. It will
-    #   get clobbered on calls to other JS code, but will get saved on calls
-    #   to C functions.
</del><ins>+    # - The PC base (or PB for short) must be stored in a callee-save register.
</ins><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><del>-    const PC = t5
-    const PB = t6
-    const tagTypeNumber = csr1
-    const tagMask = csr2
-    
</del><ins>+    const PC = t4
+    const PB = csr0
+    if ARM64
+        const tagTypeNumber = csr1
+        const tagMask = csr2
+    elsif X86_64
+        const tagTypeNumber = csr3
+        const tagMask = csr4
+    elsif X86_64_WIN
+        const tagTypeNumber = csr5
+        const tagMask = csr6
+    elsif C_LOOP
+        const tagTypeNumber = csr1
+        const tagMask = csr2
+    end
+
</ins><span class="cx">     macro loadisFromInstruction(offset, dest)
</span><span class="cx">         loadis offset * 8[PB, PC, 8], dest
</span><span class="cx">     end
</span><span class="lines">@@ -130,7 +259,7 @@
</span><span class="cx">     end
</span><span class="cx"> 
</span><span class="cx"> else
</span><del>-    const PC = t5
</del><ins>+    const PC = t4
</ins><span class="cx">     macro loadisFromInstruction(offset, dest)
</span><span class="cx">         loadis offset * 4[PC], dest
</span><span class="cx">     end
</span><span class="lines">@@ -140,6 +269,12 @@
</span><span class="cx">     end
</span><span class="cx"> end
</span><span class="cx"> 
</span><ins>+if X86_64_WIN
+    const extraTempReg = t0
+else
+    const extraTempReg = t5
+end
+
</ins><span class="cx"> # Constants for reasoning about value representation.
</span><span class="cx"> if BIG_ENDIAN
</span><span class="cx">     const TagOffset = 0
</span><span class="lines">@@ -465,12 +600,12 @@
</span><span class="cx"> 
</span><span class="cx"> macro restoreStackPointerAfterCall()
</span><span class="cx">     loadp CodeBlock[cfr], t2
</span><del>-    getFrameRegisterSizeForCodeBlock(t2, t4)
</del><ins>+    getFrameRegisterSizeForCodeBlock(t2, t2)
</ins><span class="cx">     if ARMv7
</span><del>-        subp cfr, t4, t4
-        move t4, sp
</del><ins>+        subp cfr, t2, t2
+        move t2, sp
</ins><span class="cx">     else
</span><del>-        subp cfr, t4, sp
</del><ins>+        subp cfr, t2, sp
</ins><span class="cx">     end
</span><span class="cx"> end
</span><span class="cx"> 
</span><span class="lines">@@ -494,13 +629,13 @@
</span><span class="cx"> macro slowPathForCall(slowPath)
</span><span class="cx">     callCallSlowPath(
</span><span class="cx">         slowPath,
</span><del>-        macro (callee)
-            btpz t1, .dontUpdateSP
</del><ins>+        macro (callee, calleeFrame)
+            btpz calleeFrame, .dontUpdateSP
</ins><span class="cx">             if ARMv7
</span><del>-                addp CallerFrameAndPCSize, t1, t1
-                move t1, sp
</del><ins>+                addp CallerFrameAndPCSize, calleeFrame, calleeFrame
+                move calleeFrame, sp
</ins><span class="cx">             else
</span><del>-                addp CallerFrameAndPCSize, t1, sp
</del><ins>+                addp CallerFrameAndPCSize, calleeFrame, sp
</ins><span class="cx">             end
</span><span class="cx">         .dontUpdateSP:
</span><span class="cx">             if C_LOOP
</span><span class="lines">@@ -596,15 +731,19 @@
</span><span class="cx">     if not C_LOOP
</span><span class="cx">         baddis 5, CodeBlock::m_llintExecuteCounter + BaselineExecutionCounter::m_counter[t1], .continue
</span><span class="cx">         if JSVALUE64
</span><del>-            cCall2(osrSlowPath, cfr, PC)
</del><ins>+            move cfr, a0
+            move PC, a1
+            cCall2(osrSlowPath)
</ins><span class="cx">         else
</span><span class="cx">             # We are after the function prologue, but before we have set up sp from the CodeBlock.
</span><span class="cx">             # Temporarily align stack pointer for this call.
</span><span class="cx">             subp 8, sp
</span><del>-            cCall2(osrSlowPath, cfr, PC)
</del><ins>+            move cfr, a0
+            move PC, a1
+            cCall2(osrSlowPath)
</ins><span class="cx">             addp 8, sp
</span><span class="cx">         end
</span><del>-        btpz t0, .recover
</del><ins>+        btpz r0, .recover
</ins><span class="cx">         move cfr, sp # restore the previous sp
</span><span class="cx">         # pop the callerFrame since we will jump to a function that wants to save it
</span><span class="cx">         if ARM64
</span><span class="lines">@@ -615,7 +754,7 @@
</span><span class="cx">         else
</span><span class="cx">             pop cfr
</span><span class="cx">         end
</span><del>-        jmp t0
</del><ins>+        jmp r0
</ins><span class="cx">     .recover:
</span><span class="cx">         codeBlockGetter(t1)
</span><span class="cx">     .continue:
</span><span class="lines">@@ -640,8 +779,8 @@
</span><span class="cx">     # Stack height check failed - need to call a slow_path.
</span><span class="cx">     subp maxFrameExtentForSlowPathCall, sp # Set up temporary stack pointer for call
</span><span class="cx">     callSlowPath(_llint_stack_check)
</span><del>-    bpeq t1, 0, .stackHeightOKGetCodeBlock
-    move t1, cfr
</del><ins>+    bpeq r1, 0, .stackHeightOKGetCodeBlock
+    move r1, cfr
</ins><span class="cx">     dispatch(0) # Go to exception handler in PC
</span><span class="cx"> 
</span><span class="cx"> .stackHeightOKGetCodeBlock:
</span><span class="lines">@@ -738,27 +877,14 @@
</span><span class="cx">     # void sanitizeStackForVMImpl(VM* vm)
</span><span class="cx">     global _sanitizeStackForVMImpl
</span><span class="cx">     _sanitizeStackForVMImpl:
</span><del>-        if X86_64
-            const vm = t4
-            const address = t1
-            const zeroValue = t0
-        elsif X86_64_WIN
-            const vm = t2
-            const address = t1
-            const zeroValue = t0
-        elsif X86 or X86_WIN
-            const vm = t2
-            const address = t1
-            const zeroValue = t0
-        else
-            const vm = a0
-            const address = t1
-            const zeroValue = t2
-        end
-    
</del><ins>+        # We need three non-aliased caller-save registers. We are guaranteed
+        # this for a0, a1 and a2 on all architectures.
</ins><span class="cx">         if X86 or X86_WIN
</span><del>-            loadp 4[sp], vm
</del><ins>+            loadp 4[sp], a0
</ins><span class="cx">         end
</span><ins>+        const vm = a0
+        const address = a1
+        const zeroValue = a2
</ins><span class="cx">     
</span><span class="cx">         loadp VM::m_lastStackTop[vm], address
</span><span class="cx">         bpbeq sp, address, .zeroFillDone
</span><span class="lines">@@ -777,22 +903,11 @@
</span><span class="cx">     # VMEntryRecord* vmEntryRecord(const VMEntryFrame* entryFrame)
</span><span class="cx">     global _vmEntryRecord
</span><span class="cx">     _vmEntryRecord:
</span><del>-        if X86_64
-            const entryFrame = t4
-            const result = t0
-        elsif X86 or X86_WIN or X86_64_WIN
-            const entryFrame = t2
-            const result = t0
-        else
-            const entryFrame = a0
-            const result = t0
-        end
-    
</del><span class="cx">         if X86 or X86_WIN
</span><del>-            loadp 4[sp], entryFrame
</del><ins>+            loadp 4[sp], a0
</ins><span class="cx">         end
</span><del>-    
-        vmEntryRecord(entryFrame, result)
</del><ins>+
+        vmEntryRecord(a0, r0)
</ins><span class="cx">         ret
</span><span class="cx"> end
</span><span class="cx"> 
</span><span class="lines">@@ -800,17 +915,12 @@
</span><span class="cx">     # Dummy entry point the C Loop uses to initialize.
</span><span class="cx">     _llint_entry:
</span><span class="cx">         crash()
</span><del>-    else
</del><ins>+else
</ins><span class="cx">     macro initPCRelative(pcBase)
</span><del>-        if X86_64 or X86_64_WIN
</del><ins>+        if X86_64 or X86_64_WIN or X86 or X86_WIN
</ins><span class="cx">             call _relativePCBase
</span><span class="cx">         _relativePCBase:
</span><span class="cx">             pop pcBase
</span><del>-        elsif X86 or X86_WIN
-            call _relativePCBase
-        _relativePCBase:
-            pop pcBase
-            loadp 20[sp], t4
</del><span class="cx">         elsif ARM64
</span><span class="cx">         elsif ARMv7
</span><span class="cx">         _relativePCBase:
</span><span class="lines">@@ -831,41 +941,39 @@
</span><span class="cx">         end
</span><span class="cx"> end
</span><span class="cx"> 
</span><ins>+# The PC base is in t1, as this is what _llint_entry leaves behind through
+# initPCRelative(t1)
</ins><span class="cx"> macro setEntryAddress(index, label)
</span><del>-    if X86_64
-        leap (label - _relativePCBase)[t1], t0
-        move index, t2
-        storep t0, [t4, t2, 8]
-    elsif X86_64_WIN
-        leap (label - _relativePCBase)[t1], t0
</del><ins>+    if X86_64 or X86_64_WIN
+        leap (label - _relativePCBase)[t1], t3
</ins><span class="cx">         move index, t4
</span><del>-        storep t0, [t2, t4, 8]
</del><ins>+        storep t3, [a0, t4, 8]
</ins><span class="cx">     elsif X86 or X86_WIN
</span><del>-        leap (label - _relativePCBase)[t1], t0
-        move index, t2
-        storep t0, [t4, t2, 4]
</del><ins>+        leap (label - _relativePCBase)[t1], t3
+        move index, t4
+        storep t3, [a0, t4, 4]
</ins><span class="cx">     elsif ARM64
</span><span class="cx">         pcrtoaddr label, t1
</span><del>-        move index, t2
-        storep t1, [a0, t2, 8]
</del><ins>+        move index, t4
+        storep t1, [a0, t4, 8]
</ins><span class="cx">     elsif ARM or ARMv7 or ARMv7_TRADITIONAL
</span><del>-        mvlbl (label - _relativePCBase), t2
-        addp t2, t1, t2
</del><ins>+        mvlbl (label - _relativePCBase), t4
+        addp t4, t1, t4
</ins><span class="cx">         move index, t3
</span><del>-        storep t2, [a0, t3, 4]
</del><ins>+        storep t4, [a0, t3, 4]
</ins><span class="cx">     elsif SH4
</span><del>-        move (label - _relativePCBase), t2
-        addp t2, t1, t2
</del><ins>+        move (label - _relativePCBase), t4
+        addp t4, t1, t4
</ins><span class="cx">         move index, t3
</span><del>-        storep t2, [a0, t3, 4]
</del><ins>+        storep t4, [a0, t3, 4]
</ins><span class="cx">         flushcp # Force constant pool flush to avoid &quot;pcrel too far&quot; link error.
</span><span class="cx">     elsif MIPS
</span><del>-        la label, t2
</del><ins>+        la label, t4
</ins><span class="cx">         la _relativePCBase, t3
</span><del>-        subp t3, t2
-        addp t2, t1, t2
</del><ins>+        subp t3, t4
+        addp t4, t1, t4
</ins><span class="cx">         move index, t3
</span><del>-        storep t2, [a0, t3, 4]
</del><ins>+        storep t4, [a0, t3, 4]
</ins><span class="cx">     end
</span><span class="cx"> end
</span><span class="cx"> 
</span><span class="lines">@@ -874,6 +982,9 @@
</span><span class="cx"> _llint_entry:
</span><span class="cx">     functionPrologue()
</span><span class="cx">     pushCalleeSaves()
</span><ins>+    if X86 or X86_WIN
+        loadp 20[sp], a0
+    end
</ins><span class="cx">     initPCRelative(t1)
</span><span class="cx"> 
</span><span class="cx">     # Include generated bytecode initialization file.
</span><span class="lines">@@ -1213,16 +1324,16 @@
</span><span class="cx">     traceExecution()
</span><span class="cx">     callSlowPath(_llint_slow_path_size_frame_for_varargs)
</span><span class="cx">     branchIfException(_llint_throw_from_slow_path_trampoline)
</span><del>-    # calleeFrame in t1
</del><ins>+    # calleeFrame in r1
</ins><span class="cx">     if JSVALUE64
</span><del>-        move t1, sp
</del><ins>+        move r1, sp
</ins><span class="cx">     else
</span><span class="cx">         # The calleeFrame is not stack aligned, move down by CallerFrameAndPCSize to align
</span><span class="cx">         if ARMv7
</span><del>-            subp t1, CallerFrameAndPCSize, t2
</del><ins>+            subp r1, CallerFrameAndPCSize, t2
</ins><span class="cx">             move t2, sp
</span><span class="cx">         else
</span><del>-            subp t1, CallerFrameAndPCSize, sp
</del><ins>+            subp r1, CallerFrameAndPCSize, sp
</ins><span class="cx">         end
</span><span class="cx">     end
</span><span class="cx">     slowPathForCall(_llint_slow_path_call_varargs)
</span><span class="lines">@@ -1231,16 +1342,16 @@
</span><span class="cx">     traceExecution()
</span><span class="cx">     callSlowPath(_llint_slow_path_size_frame_for_varargs)
</span><span class="cx">     branchIfException(_llint_throw_from_slow_path_trampoline)
</span><del>-    # calleeFrame in t1
</del><ins>+    # calleeFrame in r1
</ins><span class="cx">     if JSVALUE64
</span><del>-        move t1, sp
</del><ins>+        move r1, sp
</ins><span class="cx">     else
</span><span class="cx">         # The calleeFrame is not stack aligned, move down by CallerFrameAndPCSize to align
</span><span class="cx">         if ARMv7
</span><del>-            subp t1, CallerFrameAndPCSize, t2
</del><ins>+            subp r1, CallerFrameAndPCSize, t2
</ins><span class="cx">             move t2, sp
</span><span class="cx">         else
</span><del>-            subp t1, CallerFrameAndPCSize, sp
</del><ins>+            subp r1, CallerFrameAndPCSize, sp
</ins><span class="cx">         end
</span><span class="cx">     end
</span><span class="cx">     slowPathForCall(_llint_slow_path_construct_varargs)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorellintLowLevelInterpreter32_64asm"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm (189292 => 189293)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm        2015-09-03 21:55:40 UTC (rev 189292)
+++ trunk/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm        2015-09-03 22:16:23 UTC (rev 189293)
</span><span class="lines">@@ -22,54 +22,6 @@
</span><span class="cx"> # THE POSSIBILITY OF SUCH DAMAGE.
</span><span class="cx"> 
</span><span class="cx"> 
</span><del>-# Crash course on the language that this is written in (which I just call
-# &quot;assembly&quot; even though it's more than that):
-#
-# - Mostly gas-style operand ordering. The last operand tends to be the
-#   destination. So &quot;a := b&quot; is written as &quot;mov b, a&quot;. But unlike gas,
-#   comparisons are in-order, so &quot;if (a &lt; b)&quot; is written as
-#   &quot;bilt a, b, ...&quot;.
-#
-# - &quot;b&quot; = byte, &quot;h&quot; = 16-bit word, &quot;i&quot; = 32-bit word, &quot;p&quot; = pointer.
-#   Currently this is just 32-bit so &quot;i&quot; and &quot;p&quot; are interchangeable
-#   except when an op supports one but not the other.
-#
-# - In general, valid operands for macro invocations and instructions are
-#   registers (eg &quot;t0&quot;), addresses (eg &quot;4[t0]&quot;), base-index addresses
-#   (eg &quot;7[t0, t1, 2]&quot;), absolute addresses (eg &quot;0xa0000000[]&quot;), or labels
-#   (eg &quot;_foo&quot; or &quot;.foo&quot;). Macro invocations can also take anonymous
-#   macros as operands. Instructions cannot take anonymous macros.
-#
-# - Labels must have names that begin with either &quot;_&quot; or &quot;.&quot;.  A &quot;.&quot; label
-#   is local and gets renamed before code gen to minimize namespace
-#   pollution. A &quot;_&quot; label is an extern symbol (i.e. &quot;.globl&quot;). The &quot;_&quot;
-#   may or may not be removed during code gen depending on whether the asm
-#   conventions for C name mangling on the target platform mandate a &quot;_&quot;
-#   prefix.
-#
-# - A &quot;macro&quot; is a lambda expression, which may be either anonymous or
-#   named. But this has caveats. &quot;macro&quot; can take zero or more arguments,
-#   which may be macros or any valid operands, but it can only return
-#   code. But you can do Turing-complete things via continuation passing
-#   style: &quot;macro foo (a, b) b(a) end foo(foo, foo)&quot;. Actually, don't do
-#   that, since you'll just crash the assembler.
-#
-# - An &quot;if&quot; is a conditional on settings. Any identifier supplied in the
-#   predicate of an &quot;if&quot; is assumed to be a #define that is available
-#   during code gen. So you can't use &quot;if&quot; for computation in a macro, but
-#   you can use it to select different pieces of code for different
-#   platforms.
-#
-# - Arguments to macros follow lexical scoping rather than dynamic scoping.
-#   Const's also follow lexical scoping and may override (hide) arguments
-#   or other consts. All variables (arguments and constants) can be bound
-#   to operands. Additionally, arguments (but not constants) can be bound
-#   to macros.
-
-
-# Below we have a bunch of constant declarations. Each constant must have
-# a corresponding ASSERT() in LLIntData.cpp.
-
</del><span class="cx"> # Utilities
</span><span class="cx"> macro dispatch(advance)
</span><span class="cx">     addp advance * 4, PC
</span><span class="lines">@@ -89,60 +41,47 @@
</span><span class="cx"> 
</span><span class="cx"> macro dispatchAfterCall()
</span><span class="cx">     loadi ArgumentCount + TagOffset[cfr], PC
</span><del>-    loadi 4[PC], t2
-    storei t1, TagOffset[cfr, t2, 8]
-    storei t0, PayloadOffset[cfr, t2, 8]
-    valueProfile(t1, t0, 4 * (CallOpCodeSize - 1), t3)
</del><ins>+    loadi 4[PC], t3
+    storei r1, TagOffset[cfr, t3, 8]
+    storei r0, PayloadOffset[cfr, t3, 8]
+    valueProfile(r1, r0, 4 * (CallOpCodeSize - 1), t3)
</ins><span class="cx">     dispatch(CallOpCodeSize)
</span><span class="cx"> end
</span><span class="cx"> 
</span><del>-macro cCall2(function, arg1, arg2)
-    if ARM or ARMv7 or ARMv7_TRADITIONAL or MIPS
-        move arg1, a0
-        move arg2, a1
</del><ins>+macro cCall2(function)
+    if ARM or ARMv7 or ARMv7_TRADITIONAL or MIPS or SH4
</ins><span class="cx">         call function
</span><span class="cx">     elsif X86 or X86_WIN
</span><span class="cx">         subp 8, sp
</span><del>-        push arg2
-        push arg1
</del><ins>+        push a1
+        push a0
</ins><span class="cx">         call function
</span><span class="cx">         addp 16, sp
</span><del>-    elsif SH4
-        setargs arg1, arg2
-        call function
</del><span class="cx">     elsif C_LOOP
</span><del>-        cloopCallSlowPath function, arg1, arg2
</del><ins>+        cloopCallSlowPath function, a0, a1
</ins><span class="cx">     else
</span><span class="cx">         error
</span><span class="cx">     end
</span><span class="cx"> end
</span><span class="cx"> 
</span><del>-macro cCall2Void(function, arg1, arg2)
</del><ins>+macro cCall2Void(function)
</ins><span class="cx">     if C_LOOP
</span><del>-        cloopCallSlowPathVoid function, arg1, arg2
</del><ins>+        cloopCallSlowPathVoid function, a0, a1
</ins><span class="cx">     else
</span><del>-        cCall2(function, arg1, arg2)
</del><ins>+        cCall2(function)
</ins><span class="cx">     end
</span><span class="cx"> end
</span><span class="cx"> 
</span><del>-# This barely works. arg3 and arg4 should probably be immediates.
-macro cCall4(function, arg1, arg2, arg3, arg4)
-    if ARM or ARMv7 or ARMv7_TRADITIONAL or MIPS
-        move arg1, a0
-        move arg2, a1
-        move arg3, a2
-        move arg4, a3
</del><ins>+macro cCall4(function)
+    if ARM or ARMv7 or ARMv7_TRADITIONAL or MIPS or SH4
</ins><span class="cx">         call function
</span><span class="cx">     elsif X86 or X86_WIN
</span><del>-        push arg4
-        push arg3
-        push arg2
-        push arg1
</del><ins>+        push a3
+        push a2
+        push a1
+        push a0
</ins><span class="cx">         call function
</span><span class="cx">         addp 16, sp
</span><del>-    elsif SH4
-        setargs arg1, arg2, arg3, arg4
-        call function
</del><span class="cx">     elsif C_LOOP
</span><span class="cx">         error
</span><span class="cx">     else
</span><span class="lines">@@ -151,133 +90,105 @@
</span><span class="cx"> end
</span><span class="cx"> 
</span><span class="cx"> macro callSlowPath(slowPath)
</span><del>-    cCall2(slowPath, cfr, PC)
-    move t0, PC
</del><ins>+    move cfr, a0
+    move PC, a1
+    cCall2(slowPath)
+    move r0, PC
</ins><span class="cx"> end
</span><span class="cx"> 
</span><span class="cx"> macro doVMEntry(makeCall)
</span><del>-    if X86 or X86_WIN
-        const entry = t4
-        const vm = t3
-        const protoCallFrame = t5
-
-        const temp1 = t0
-        const temp2 = t1
-        const temp3 = t2
-        const temp4 = t3 # same as vm
-    elsif ARM or ARMv7 or ARMv7_TRADITIONAL or C_LOOP
-        const entry = a0
-        const vm = a1
-        const protoCallFrame = a2
-
-        const temp1 = t3
-        const temp2 = t4
-        const temp3 = t5
-        const temp4 = t4 # Same as temp2
-    elsif MIPS
-        const entry = a0
-        const vm = a1
-        const protoCallFrame = a2
-
-        const temp1 = t3
-        const temp2 = t5
-        const temp3 = t4
-        const temp4 = t6
-    elsif SH4
-        const entry = a0
-        const vm = a1
-        const protoCallFrame = a2
-
-        const temp1 = t3
-        const temp2 = a3
-        const temp3 = t8
-        const temp4 = t9
-    end
-
</del><span class="cx">     functionPrologue()
</span><span class="cx">     pushCalleeSaves()
</span><span class="cx"> 
</span><ins>+    # x86 needs to load arguments from the stack
</ins><span class="cx">     if X86 or X86_WIN
</span><del>-        loadp 12[cfr], vm
-        loadp 8[cfr], entry
</del><ins>+        loadp 16[cfr], a2
+        loadp 12[cfr], a1
+        loadp 8[cfr], a0
</ins><span class="cx">     end
</span><span class="cx"> 
</span><ins>+    const entry = a0
+    const vm = a1
+    const protoCallFrame = a2
+
+    # We are using t3, t4 and t5 as temporaries through the function.
+    # Since we have the guarantee that tX != aY when X != Y, we are safe from
+    # aliasing problems with our arguments.
+
</ins><span class="cx">     if ARMv7
</span><del>-        vmEntryRecord(cfr, temp1)
-        move temp1, sp
</del><ins>+        vmEntryRecord(cfr, t3)
+        move t3, sp
</ins><span class="cx">     else
</span><span class="cx">         vmEntryRecord(cfr, sp)
</span><span class="cx">     end
</span><span class="cx"> 
</span><span class="cx">     storep vm, VMEntryRecord::m_vm[sp]
</span><del>-    loadp VM::topCallFrame[vm], temp2
-    storep temp2, VMEntryRecord::m_prevTopCallFrame[sp]
-    loadp VM::topVMEntryFrame[vm], temp2
-    storep temp2, VMEntryRecord::m_prevTopVMEntryFrame[sp]
</del><ins>+    loadp VM::topCallFrame[vm], t4
+    storep t4, VMEntryRecord::m_prevTopCallFrame[sp]
+    loadp VM::topVMEntryFrame[vm], t4
+    storep t4, VMEntryRecord::m_prevTopVMEntryFrame[sp]
</ins><span class="cx"> 
</span><span class="cx">     # Align stack pointer
</span><span class="cx">     if X86_WIN
</span><del>-        addp CallFrameAlignSlots * SlotSize, sp, temp1
-        andp ~StackAlignmentMask, temp1
-        subp temp1, CallFrameAlignSlots * SlotSize, sp
</del><ins>+        addp CallFrameAlignSlots * SlotSize, sp, t3
+        andp ~StackAlignmentMask, t3
+        subp t3, CallFrameAlignSlots * SlotSize, sp
</ins><span class="cx">     elsif ARM or ARMv7 or ARMv7_TRADITIONAL
</span><del>-        addp CallFrameAlignSlots * SlotSize, sp, temp1
-        clrbp temp1, StackAlignmentMask, temp1
</del><ins>+        addp CallFrameAlignSlots * SlotSize, sp, t3
+        clrbp t3, StackAlignmentMask, t3
</ins><span class="cx">         if ARMv7
</span><del>-            subp temp1, CallFrameAlignSlots * SlotSize, temp1
-            move temp1, sp
</del><ins>+            subp t3, CallFrameAlignSlots * SlotSize, t3
+            move t3, sp
</ins><span class="cx">         else
</span><del>-            subp temp1, CallFrameAlignSlots * SlotSize, sp
</del><ins>+            subp t3, CallFrameAlignSlots * SlotSize, sp
</ins><span class="cx">         end
</span><span class="cx">     end
</span><span class="cx"> 
</span><del>-    if X86 or X86_WIN
-        loadp 16[cfr], protoCallFrame
-    end
</del><ins>+    loadi ProtoCallFrame::paddedArgCount[protoCallFrame], t4
+    addp CallFrameHeaderSlots, t4, t4
+    lshiftp 3, t4
+    subp sp, t4, t3
</ins><span class="cx"> 
</span><del>-    loadi ProtoCallFrame::paddedArgCount[protoCallFrame], temp2
-    addp CallFrameHeaderSlots, temp2, temp2
-    lshiftp 3, temp2
-    subp sp, temp2, temp1
-
</del><span class="cx">     # Ensure that we have enough additional stack capacity for the incoming args,
</span><span class="cx">     # and the frame for the JS code we're executing. We need to do this check
</span><span class="cx">     # before we start copying the args from the protoCallFrame below.
</span><del>-    bpaeq temp1, VM::m_jsStackLimit[vm], .stackHeightOK
</del><ins>+    bpaeq t3, VM::m_jsStackLimit[vm], .stackHeightOK
</ins><span class="cx"> 
</span><span class="cx">     if C_LOOP
</span><del>-        move entry, temp2
-        move vm, temp3
-        cloopCallSlowPath _llint_stack_check_at_vm_entry, vm, temp1
</del><ins>+        move entry, t4
+        move vm, t5
+        cloopCallSlowPath _llint_stack_check_at_vm_entry, vm, t3
</ins><span class="cx">         bpeq t0, 0, .stackCheckFailed
</span><del>-        move temp2, entry
-        move temp3, vm
</del><ins>+        move t4, entry
+        move t5, vm
</ins><span class="cx">         jmp .stackHeightOK
</span><span class="cx"> 
</span><span class="cx"> .stackCheckFailed:
</span><del>-        move temp2, entry
-        move temp3, vm
</del><ins>+        move t4, entry
+        move t5, vm
</ins><span class="cx">     end
</span><span class="cx"> 
</span><span class="cx">     subp 8, sp # Align stack for cCall2() to make a call.
</span><del>-    cCall2(_llint_throw_stack_overflow_error, vm, protoCallFrame)
</del><ins>+    move vm, a0
+    move protoCallFrame, a1
+    cCall2(_llint_throw_stack_overflow_error)
</ins><span class="cx"> 
</span><span class="cx">     if ARMv7
</span><del>-        vmEntryRecord(cfr, temp1)
-        move temp1, sp
</del><ins>+        vmEntryRecord(cfr, t3)
+        move t3, sp
</ins><span class="cx">     else
</span><span class="cx">         vmEntryRecord(cfr, sp)
</span><span class="cx">     end
</span><span class="cx"> 
</span><del>-    loadp VMEntryRecord::m_vm[sp], temp3
-    loadp VMEntryRecord::m_prevTopCallFrame[sp], temp4
-    storep temp4, VM::topCallFrame[temp3]
-    loadp VMEntryRecord::m_prevTopVMEntryFrame[sp], temp4
-    storep temp4, VM::topVMEntryFrame[temp3]
</del><ins>+    loadp VMEntryRecord::m_vm[sp], t5
+    loadp VMEntryRecord::m_prevTopCallFrame[sp], t4
+    storep t4, VM::topCallFrame[t5]
+    loadp VMEntryRecord::m_prevTopVMEntryFrame[sp], t4
+    storep t4, VM::topVMEntryFrame[t5]
</ins><span class="cx"> 
</span><span class="cx">     if ARMv7
</span><del>-        subp cfr, CalleeRegisterSaveSize, temp3
-        move temp3, sp
</del><ins>+        subp cfr, CalleeRegisterSaveSize, t5
+        move t5, sp
</ins><span class="cx">     else
</span><span class="cx">         subp cfr, CalleeRegisterSaveSize, sp
</span><span class="cx">     end
</span><span class="lines">@@ -287,63 +198,63 @@
</span><span class="cx">     ret
</span><span class="cx"> 
</span><span class="cx"> .stackHeightOK:
</span><del>-    move temp1, sp
-    move 4, temp1
</del><ins>+    move t3, sp
+    move 4, t3
</ins><span class="cx"> 
</span><span class="cx"> .copyHeaderLoop:
</span><del>-    subi 1, temp1
-    loadi TagOffset[protoCallFrame, temp1, 8], temp3
-    storei temp3, TagOffset + CodeBlock[sp, temp1, 8]
-    loadi PayloadOffset[protoCallFrame, temp1, 8], temp3
-    storei temp3, PayloadOffset + CodeBlock[sp, temp1, 8]
-    btinz temp1, .copyHeaderLoop
</del><ins>+    subi 1, t3
+    loadi TagOffset[protoCallFrame, t3, 8], t5
+    storei t5, TagOffset + CodeBlock[sp, t3, 8]
+    loadi PayloadOffset[protoCallFrame, t3, 8], t5
+    storei t5, PayloadOffset + CodeBlock[sp, t3, 8]
+    btinz t3, .copyHeaderLoop
</ins><span class="cx"> 
</span><del>-    loadi PayloadOffset + ProtoCallFrame::argCountAndCodeOriginValue[protoCallFrame], temp2
-    subi 1, temp2
-    loadi ProtoCallFrame::paddedArgCount[protoCallFrame], temp3
-    subi 1, temp3
</del><ins>+    loadi PayloadOffset + ProtoCallFrame::argCountAndCodeOriginValue[protoCallFrame], t4
+    subi 1, t4
+    loadi ProtoCallFrame::paddedArgCount[protoCallFrame], t5
+    subi 1, t5
</ins><span class="cx"> 
</span><del>-    bieq temp2, temp3, .copyArgs
</del><ins>+    bieq t4, t5, .copyArgs
</ins><span class="cx"> .fillExtraArgsLoop:
</span><del>-    subi 1, temp3
-    storei UndefinedTag, ThisArgumentOffset + 8 + TagOffset[sp, temp3, 8]
-    storei 0, ThisArgumentOffset + 8 + PayloadOffset[sp, temp3, 8]
-    bineq temp2, temp3, .fillExtraArgsLoop
</del><ins>+    subi 1, t5
+    storei UndefinedTag, ThisArgumentOffset + 8 + TagOffset[sp, t5, 8]
+    storei 0, ThisArgumentOffset + 8 + PayloadOffset[sp, t5, 8]
+    bineq t4, t5, .fillExtraArgsLoop
</ins><span class="cx"> 
</span><span class="cx"> .copyArgs:
</span><del>-    loadp ProtoCallFrame::args[protoCallFrame], temp1
</del><ins>+    loadp ProtoCallFrame::args[protoCallFrame], t3
</ins><span class="cx"> 
</span><span class="cx"> .copyArgsLoop:
</span><del>-    btiz temp2, .copyArgsDone
-    subi 1, temp2
-    loadi TagOffset[temp1, temp2, 8], temp3
-    storei temp3, ThisArgumentOffset + 8 + TagOffset[sp, temp2, 8]
-    loadi PayloadOffset[temp1, temp2, 8], temp3
-    storei temp3, ThisArgumentOffset + 8 + PayloadOffset[sp, temp2, 8]
</del><ins>+    btiz t4, .copyArgsDone
+    subi 1, t4
+    loadi TagOffset[t3, t4, 8], t5
+    storei t5, ThisArgumentOffset + 8 + TagOffset[sp, t4, 8]
+    loadi PayloadOffset[t3, t4, 8], t5
+    storei t5, ThisArgumentOffset + 8 + PayloadOffset[sp, t4, 8]
</ins><span class="cx">     jmp .copyArgsLoop
</span><span class="cx"> 
</span><span class="cx"> .copyArgsDone:
</span><span class="cx">     storep sp, VM::topCallFrame[vm]
</span><span class="cx">     storep cfr, VM::topVMEntryFrame[vm]
</span><span class="cx"> 
</span><del>-    makeCall(entry, temp1, temp2)
</del><ins>+    makeCall(entry, t3, t4)
</ins><span class="cx"> 
</span><span class="cx">     if ARMv7
</span><del>-        vmEntryRecord(cfr, temp1)
-        move temp1, sp
</del><ins>+        vmEntryRecord(cfr, t3)
+        move t3, sp
</ins><span class="cx">     else
</span><span class="cx">         vmEntryRecord(cfr, sp)
</span><span class="cx">     end
</span><span class="cx"> 
</span><del>-    loadp VMEntryRecord::m_vm[sp], temp3
-    loadp VMEntryRecord::m_prevTopCallFrame[sp], temp4
-    storep temp4, VM::topCallFrame[temp3]
-    loadp VMEntryRecord::m_prevTopVMEntryFrame[sp], temp4
-    storep temp4, VM::topVMEntryFrame[temp3]
</del><ins>+    loadp VMEntryRecord::m_vm[sp], t5
+    loadp VMEntryRecord::m_prevTopCallFrame[sp], t4
+    storep t4, VM::topCallFrame[t5]
+    loadp VMEntryRecord::m_prevTopVMEntryFrame[sp], t4
+    storep t4, VM::topVMEntryFrame[t5]
</ins><span class="cx"> 
</span><span class="cx">     if ARMv7
</span><del>-        subp cfr, CalleeRegisterSaveSize, temp3
-        move temp3, sp
</del><ins>+        subp cfr, CalleeRegisterSaveSize, t5
+        move t5, sp
</ins><span class="cx">     else
</span><span class="cx">         subp cfr, CalleeRegisterSaveSize, sp
</span><span class="cx">     end
</span><span class="lines">@@ -355,13 +266,13 @@
</span><span class="cx"> 
</span><span class="cx"> macro makeJavaScriptCall(entry, temp, unused)
</span><span class="cx">     addp CallerFrameAndPCSize, sp
</span><del>-    checkStackPointerAlignment(t2, 0xbad0dc02)
</del><ins>+    checkStackPointerAlignment(temp, 0xbad0dc02)
</ins><span class="cx">     if C_LOOP
</span><span class="cx">         cloopCallJSFunction entry
</span><span class="cx">     else
</span><span class="cx">         call entry
</span><span class="cx">     end
</span><del>-    checkStackPointerAlignment(t2, 0xbad0dc03)
</del><ins>+    checkStackPointerAlignment(temp, 0xbad0dc03)
</ins><span class="cx">     subp CallerFrameAndPCSize, sp
</span><span class="cx"> end
</span><span class="cx"> 
</span><span class="lines">@@ -376,9 +287,9 @@
</span><span class="cx">         # Put callee frame pointer on stack as arg0, also put it in ecx for &quot;fastcall&quot; targets
</span><span class="cx">         move 0, temp2
</span><span class="cx">         move temp2, 4[sp] # put 0 in ReturnPC
</span><del>-        move sp, t2 # t2 is ecx
</del><ins>+        move sp, a0 # a0 is ecx
</ins><span class="cx">         push temp2 # Push dummy arg1
</span><del>-        push t2
</del><ins>+        push a0
</ins><span class="cx">         call temp1
</span><span class="cx">         addp 8, sp
</span><span class="cx">     else
</span><span class="lines">@@ -429,31 +340,43 @@
</span><span class="cx"> # debugging from. operand should likewise be an immediate, and should identify the operand
</span><span class="cx"> # in the instruction stream you'd like to print out.
</span><span class="cx"> macro traceOperand(fromWhere, operand)
</span><del>-    cCall4(_llint_trace_operand, cfr, PC, fromWhere, operand)
-    move t0, PC
-    move t1, cfr
</del><ins>+    move fromWhere, a2
+    move operand, a3
+    move cfr, a0
+    move PC, a1
+    cCall4(_llint_trace_operand)
+    move r0, PC
+    move r1, cfr
</ins><span class="cx"> end
</span><span class="cx"> 
</span><span class="cx"> # Debugging operation if you'd like to print the value of an operand in the instruction
</span><span class="cx"> # stream. Same as traceOperand(), but assumes that the operand is a register, and prints its
</span><span class="cx"> # value.
</span><span class="cx"> macro traceValue(fromWhere, operand)
</span><del>-    cCall4(_llint_trace_value, cfr, PC, fromWhere, operand)
-    move t0, PC
-    move t1, cfr
</del><ins>+    move fromWhere, a2
+    move operand, a3
+    move cfr, a0
+    move PC, a1
+    cCall4(_llint_trace_value)
+    move r0, PC
+    move r1, cfr
</ins><span class="cx"> end
</span><span class="cx"> 
</span><span class="cx"> # Call a slowPath for call opcodes.
</span><span class="cx"> macro callCallSlowPath(slowPath, action)
</span><span class="cx">     storep PC, ArgumentCount + TagOffset[cfr]
</span><del>-    cCall2(slowPath, cfr, PC)
-    action(t0)
</del><ins>+    move cfr, a0
+    move PC, a1
+    cCall2(slowPath)
+    action(r0, r1)
</ins><span class="cx"> end
</span><span class="cx"> 
</span><span class="cx"> macro callWatchdogTimerHandler(throwHandler)
</span><span class="cx">     storei PC, ArgumentCount + TagOffset[cfr]
</span><del>-    cCall2(_llint_slow_path_handle_watchdog_timer, cfr, PC)
-    btpnz t0, throwHandler
</del><ins>+    move cfr, a0
+    move PC, a1
+    cCall2(_llint_slow_path_handle_watchdog_timer)
+    btpnz r0, throwHandler
</ins><span class="cx">     loadi ArgumentCount + TagOffset[cfr], PC
</span><span class="cx"> end
</span><span class="cx"> 
</span><span class="lines">@@ -462,10 +385,12 @@
</span><span class="cx">         1,
</span><span class="cx">         macro ()
</span><span class="cx">             storei PC, ArgumentCount + TagOffset[cfr]
</span><del>-            cCall2(_llint_loop_osr, cfr, PC)
-            btpz t0, .recover
-            move t1, sp
-            jmp t0
</del><ins>+            move cfr, a0
+            move PC, a1
+            cCall2(_llint_loop_osr)
+            btpz r0, .recover
+            move r1, sp
+            jmp r0
</ins><span class="cx">         .recover:
</span><span class="cx">             loadi ArgumentCount + TagOffset[cfr], PC
</span><span class="cx">         end)
</span><span class="lines">@@ -576,7 +501,9 @@
</span><span class="cx">                 push cfr, PC
</span><span class="cx">                 # We make two extra slots because cCall2 will poke.
</span><span class="cx">                 subp 8, sp
</span><del>-                cCall2Void(_llint_write_barrier_slow, cfr, t2)
</del><ins>+                move t2, a1 # t2 can be a0 on x86
+                move cfr, a0
+                cCall2Void(_llint_write_barrier_slow)
</ins><span class="cx">                 addp 8, sp
</span><span class="cx">                 pop PC, cfr
</span><span class="cx">             end
</span><span class="lines">@@ -610,7 +537,9 @@
</span><span class="cx">                 push cfr, PC
</span><span class="cx">                 # We make two extra slots because cCall2 will poke.
</span><span class="cx">                 subp 8, sp
</span><del>-                cCall2Void(_llint_write_barrier_slow, cfr, t3)
</del><ins>+                move cfr, a0
+                move t3, a1
+                cCall2Void(_llint_write_barrier_slow)
</ins><span class="cx">                 addp 8, sp
</span><span class="cx">                 pop PC, cfr
</span><span class="cx">             end
</span><span class="lines">@@ -649,19 +578,21 @@
</span><span class="cx"> macro functionArityCheck(doneLabel, slowPath)
</span><span class="cx">     loadi PayloadOffset + ArgumentCount[cfr], t0
</span><span class="cx">     biaeq t0, CodeBlock::m_numParameters[t1], doneLabel
</span><del>-    cCall2(slowPath, cfr, PC)   # This slowPath has a simple protocol: t0 = 0 =&gt; no error, t0 != 0 =&gt; error
-    btiz t0, .noError
-    move t1, cfr   # t1 contains caller frame
</del><ins>+    move cfr, a0
+    move PC, a1
+    cCall2(slowPath)   # This slowPath has a simple protocol: t0 = 0 =&gt; no error, t0 != 0 =&gt; error
+    btiz r0, .noError
+    move r1, cfr   # r1 contains caller frame
</ins><span class="cx">     jmp _llint_throw_from_slow_path_trampoline
</span><span class="cx"> 
</span><span class="cx"> .noError:
</span><del>-    # t1 points to ArityCheckData.
-    loadp CommonSlowPaths::ArityCheckData::thunkToCall[t1], t2
-    btpz t2, .proceedInline
</del><ins>+    # r1 points to ArityCheckData.
+    loadp CommonSlowPaths::ArityCheckData::thunkToCall[r1], t3
+    btpz t3, .proceedInline
</ins><span class="cx">     
</span><del>-    loadp CommonSlowPaths::ArityCheckData::returnPC[t1], t5
-    loadp CommonSlowPaths::ArityCheckData::paddedStackSpace[t1], t0
-    call t2
</del><ins>+    loadp CommonSlowPaths::ArityCheckData::paddedStackSpace[r1], a0
+    loadp CommonSlowPaths::ArityCheckData::returnPC[r1], a1
+    call t3
</ins><span class="cx">     if ASSERT_ENABLED
</span><span class="cx">         loadp ReturnPC[cfr], t0
</span><span class="cx">         loadp [t0], t0
</span><span class="lines">@@ -669,7 +600,7 @@
</span><span class="cx">     jmp .continue
</span><span class="cx"> 
</span><span class="cx"> .proceedInline:
</span><del>-    loadi CommonSlowPaths::ArityCheckData::paddedStackSpace[t1], t1
</del><ins>+    loadi CommonSlowPaths::ArityCheckData::paddedStackSpace[r1], t1
</ins><span class="cx">     btiz t1, .continue
</span><span class="cx"> 
</span><span class="cx">     // Move frame up &quot;t1 * 2&quot; slots
</span><span class="lines">@@ -751,14 +682,14 @@
</span><span class="cx">     traceExecution()
</span><span class="cx">     loadi 8[PC], t0
</span><span class="cx">     loadp PayloadOffset[cfr, t0, 8], t0
</span><del>-    loadp JSFunction::m_rareData[t0], t4
-    btpz t4, .opCreateThisSlow
-    loadp FunctionRareData::m_allocationProfile + ObjectAllocationProfile::m_allocator[t4], t1
-    loadp FunctionRareData::m_allocationProfile + ObjectAllocationProfile::m_structure[t4], t2
</del><ins>+    loadp JSFunction::m_rareData[t0], t5
+    btpz t5, .opCreateThisSlow
+    loadp FunctionRareData::m_allocationProfile + ObjectAllocationProfile::m_allocator[t5], t1
+    loadp FunctionRareData::m_allocationProfile + ObjectAllocationProfile::m_structure[t5], t2
</ins><span class="cx">     btpz t1, .opCreateThisSlow
</span><del>-    loadpFromInstruction(4, t4)
-    bpeq t4, 1, .hasSeenMultipleCallee
-    bpneq t4, t0, .opCreateThisSlow
</del><ins>+    loadpFromInstruction(4, t5)
+    bpeq t5, 1, .hasSeenMultipleCallee
+    bpneq t5, t0, .opCreateThisSlow
</ins><span class="cx"> .hasSeenMultipleCallee:
</span><span class="cx">     allocateJSObject(t1, t2, t0, t3, .opCreateThisSlow)
</span><span class="cx">     loadi 4[PC], t1
</span><span class="lines">@@ -2006,8 +1937,8 @@
</span><span class="cx">         andp MarkedBlockMask, t1
</span><span class="cx">         loadp MarkedBlock::m_weakSet + WeakSet::m_vm[t1], t3
</span><span class="cx">         storep cfr, VM::topCallFrame[t3]
</span><del>-        move cfr, t2  # t2 = ecx
-        storep t2, [sp]
</del><ins>+        move cfr, a0  # a0 = ecx
+        storep a0, [sp]
</ins><span class="cx">         loadi Callee + PayloadOffset[cfr], t1
</span><span class="cx">         loadp JSFunction::m_executable[t1], t1
</span><span class="cx">         checkStackPointerAlignment(t3, 0xdead0001)
</span><span class="lines">@@ -2022,11 +1953,7 @@
</span><span class="cx">         andp MarkedBlockMask, t1
</span><span class="cx">         loadp MarkedBlock::m_weakSet + WeakSet::m_vm[t1], t1
</span><span class="cx">         storep cfr, VM::topCallFrame[t1]
</span><del>-        if MIPS or SH4
-            move cfr, a0
-        else
-            move cfr, t0
-        end
</del><ins>+        move cfr, a0
</ins><span class="cx">         loadi Callee + PayloadOffset[cfr], t1
</span><span class="cx">         loadp JSFunction::m_executable[t1], t1
</span><span class="cx">         checkStackPointerAlignment(t3, 0xdead0001)
</span><span class="lines">@@ -2269,9 +2196,9 @@
</span><span class="cx"> macro putLocalClosureVar()
</span><span class="cx">     loadisFromInstruction(3, t1)
</span><span class="cx">     loadConstantOrVariable(t1, t2, t3)
</span><del>-    loadpFromInstruction(5, t4)
-    btpz t4, .noVariableWatchpointSet
-    notifyWrite(t4, .pDynamic)
</del><ins>+    loadpFromInstruction(5, t5)
+    btpz t5, .noVariableWatchpointSet
+    notifyWrite(t5, .pDynamic)
</ins><span class="cx"> .noVariableWatchpointSet:
</span><span class="cx">     loadisFromInstruction(6, t1)
</span><span class="cx">     storei t2, JSEnvironmentRecord_variables + TagOffset[t0, t1, 8]
</span><span class="lines">@@ -2396,9 +2323,9 @@
</span><span class="cx">     # t1 is holding the pointer to the typeProfilerLog.
</span><span class="cx">     loadp VM::m_typeProfilerLog[t1], t1
</span><span class="cx"> 
</span><del>-    # t0 is holding the payload, t4 is holding the tag.
</del><ins>+    # t0 is holding the payload, t5 is holding the tag.
</ins><span class="cx">     loadisFromInstruction(1, t2)
</span><del>-    loadConstantOrVariable(t2, t4, t0)
</del><ins>+    loadConstantOrVariable(t2, t5, t0)
</ins><span class="cx"> 
</span><span class="cx">     bieq t4, EmptyValueTag, .opProfileTypeDone
</span><span class="cx"> 
</span><span class="lines">@@ -2406,14 +2333,14 @@
</span><span class="cx">     loadp TypeProfilerLog::m_currentLogEntryPtr[t1], t2
</span><span class="cx"> 
</span><span class="cx">     # Store the JSValue onto the log entry.
</span><del>-    storei t4, TypeProfilerLog::LogEntry::value + TagOffset[t2]
</del><ins>+    storei t5, TypeProfilerLog::LogEntry::value + TagOffset[t2]
</ins><span class="cx">     storei t0, TypeProfilerLog::LogEntry::value + PayloadOffset[t2]
</span><span class="cx"> 
</span><span class="cx">     # Store the TypeLocation onto the log entry.
</span><span class="cx">     loadpFromInstruction(2, t3)
</span><span class="cx">     storep t3, TypeProfilerLog::LogEntry::location[t2]
</span><span class="cx"> 
</span><del>-    bieq t4, CellTag, .opProfileTypeIsCell
</del><ins>+    bieq t5, CellTag, .opProfileTypeIsCell
</ins><span class="cx">     storei 0, TypeProfilerLog::LogEntry::structureID[t2]
</span><span class="cx">     jmp .opProfileTypeSkipIsCell
</span><span class="cx"> .opProfileTypeIsCell:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorellintLowLevelInterpreter64asm"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm (189292 => 189293)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm        2015-09-03 21:55:40 UTC (rev 189292)
+++ trunk/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm        2015-09-03 22:16:23 UTC (rev 189293)
</span><span class="lines">@@ -46,177 +46,127 @@
</span><span class="cx">     loadp CodeBlock[cfr], PB
</span><span class="cx">     loadp CodeBlock::m_instructions[PB], PB
</span><span class="cx">     loadisFromInstruction(1, t1)
</span><del>-    storeq t0, [cfr, t1, 8]
-    valueProfile(t0, (CallOpCodeSize - 1), t2)
</del><ins>+    storeq r0, [cfr, t1, 8]
+    valueProfile(r0, (CallOpCodeSize - 1), t3)
</ins><span class="cx">     dispatch(CallOpCodeSize)
</span><span class="cx"> end
</span><span class="cx"> 
</span><del>-macro cCall2(function, arg1, arg2)
</del><ins>+macro cCall2(function)
</ins><span class="cx">     checkStackPointerAlignment(t4, 0xbad0c002)
</span><del>-    if X86_64
-        move arg1, t4
-        move arg2, t5
</del><ins>+    if X86_64 or ARM64
</ins><span class="cx">         call function
</span><span class="cx">     elsif X86_64_WIN
</span><span class="cx">         # Note: this implementation is only correct if the return type size is &gt; 8 bytes.
</span><span class="cx">         # See macro cCall2Void for an implementation when the return type &lt;= 8 bytes.
</span><span class="cx">         # On Win64, when the return type is larger than 8 bytes, we need to allocate space on the stack for the return value.
</span><del>-        # On entry rcx (t2), should contain a pointer to this stack space. The other parameters are shifted to the right,
-        # rdx (t1) should contain the first argument, and r8 (t6) should contain the second argument.
-        # On return, rax contains a pointer to this stack value, and we then need to copy the 16 byte return value into rax (t0) and rdx (t1)
</del><ins>+        # On entry rcx (a0), should contain a pointer to this stack space. The other parameters are shifted to the right,
+        # rdx (a1) should contain the first argument, and r8 (a2) should contain the second argument.
+        # On return, rax contains a pointer to this stack value, and we then need to copy the 16 byte return value into rax (r0) and rdx (r1)
</ins><span class="cx">         # since the return value is expected to be split between the two.
</span><span class="cx">         # See http://msdn.microsoft.com/en-us/library/7572ztz4.aspx
</span><del>-        move arg1, t1
-        move arg2, t6
</del><ins>+        move a1, a2
+        move a0, a1
</ins><span class="cx">         subp 48, sp
</span><del>-        move sp, t2
-        addp 32, t2
</del><ins>+        move sp, a0
+        addp 32, a0
</ins><span class="cx">         call function
</span><span class="cx">         addp 48, sp
</span><del>-        move 8[t0], t1
-        move [t0], t0
-    elsif ARM64
-        move arg1, t0
-        move arg2, t1
-        call function
</del><ins>+        move 8[r0], r1
+        move [r0], r0
</ins><span class="cx">     elsif C_LOOP
</span><del>-        cloopCallSlowPath function, arg1, arg2
</del><ins>+        cloopCallSlowPath function, a0, a1
</ins><span class="cx">     else
</span><span class="cx">         error
</span><span class="cx">     end
</span><span class="cx"> end
</span><span class="cx"> 
</span><del>-macro cCall2Void(function, arg1, arg2)
</del><ins>+macro cCall2Void(function)
</ins><span class="cx">     if C_LOOP
</span><del>-        cloopCallSlowPathVoid function, arg1, arg2
</del><ins>+        cloopCallSlowPathVoid function, a0, a1
</ins><span class="cx">     elsif X86_64_WIN
</span><span class="cx">         # Note: we cannot use the cCall2 macro for Win64 in this case,
</span><span class="cx">         # as the Win64 cCall2 implemenation is only correct when the return type size is &gt; 8 bytes.
</span><span class="cx">         # On Win64, rcx and rdx are used for passing the first two parameters.
</span><span class="cx">         # We also need to make room on the stack for all four parameter registers.
</span><span class="cx">         # See http://msdn.microsoft.com/en-us/library/ms235286.aspx
</span><del>-        move arg2, t1
-        move arg1, t2
</del><span class="cx">         subp 32, sp 
</span><span class="cx">         call function
</span><span class="cx">         addp 32, sp 
</span><span class="cx">     else
</span><del>-        cCall2(function, arg1, arg2)
</del><ins>+        cCall2(function)
</ins><span class="cx">     end
</span><span class="cx"> end
</span><span class="cx"> 
</span><span class="cx"> # This barely works. arg3 and arg4 should probably be immediates.
</span><del>-macro cCall4(function, arg1, arg2, arg3, arg4)
</del><ins>+macro cCall4(function)
</ins><span class="cx">     checkStackPointerAlignment(t4, 0xbad0c004)
</span><del>-    if X86_64
-        move arg1, t4
-        move arg2, t5
-        move arg3, t1
-        move arg4, t2
</del><ins>+    if X86_64 or ARM64
</ins><span class="cx">         call function
</span><span class="cx">     elsif X86_64_WIN
</span><span class="cx">         # On Win64, rcx, rdx, r8, and r9 are used for passing the first four parameters.
</span><span class="cx">         # We also need to make room on the stack for all four parameter registers.
</span><span class="cx">         # See http://msdn.microsoft.com/en-us/library/ms235286.aspx
</span><del>-        move arg1, t2
-        move arg2, t1
-        move arg3, t6
-        move arg4, t7
-        subp 32, sp 
</del><ins>+        subp 64, sp
</ins><span class="cx">         call function
</span><del>-        addp 32, sp 
-    elsif ARM64
-        move arg1, t0
-        move arg2, t1
-        move arg3, t2
-        move arg4, t3
-        call function
-    elsif C_LOOP
-        error
</del><ins>+        addp 64, sp
</ins><span class="cx">     else
</span><span class="cx">         error
</span><span class="cx">     end
</span><span class="cx"> end
</span><span class="cx"> 
</span><span class="cx"> macro doVMEntry(makeCall)
</span><del>-    if X86_64
-        const entry = t4
-        const vm = t5
-        const protoCallFrame = t1
-
-        const previousCFR = t0
-        const previousPC = t6
-        const temp1 = t0
-        const temp2 = t3
-        const temp3 = t6
-    elsif X86_64_WIN
-        const entry = t2
-        const vm = t1
-        const protoCallFrame = t6
-
-        const previousCFR = t0
-        const previousPC = t4
-        const temp1 = t0
-        const temp2 = t3
-        const temp3 = t7
-    elsif ARM64 or C_LOOP
-        const entry = a0
-        const vm = a1
-        const protoCallFrame = a2
-
-        const previousCFR = t5
-        const previousPC = lr
-        const temp1 = t3
-        const temp2 = t4
-        const temp3 = t6
-    end
-
</del><span class="cx">     functionPrologue()
</span><span class="cx">     pushCalleeSaves()
</span><span class="cx"> 
</span><ins>+    const entry = a0
+    const vm = a1
+    const protoCallFrame = a2
+
</ins><span class="cx">     vmEntryRecord(cfr, sp)
</span><span class="cx"> 
</span><del>-    checkStackPointerAlignment(temp2, 0xbad0dc01)
</del><ins>+    checkStackPointerAlignment(t4, 0xbad0dc01)
</ins><span class="cx"> 
</span><span class="cx">     storep vm, VMEntryRecord::m_vm[sp]
</span><del>-    loadp VM::topCallFrame[vm], temp2
-    storep temp2, VMEntryRecord::m_prevTopCallFrame[sp]
-    loadp VM::topVMEntryFrame[vm], temp2
-    storep temp2, VMEntryRecord::m_prevTopVMEntryFrame[sp]
</del><ins>+    loadp VM::topCallFrame[vm], t4
+    storep t4, VMEntryRecord::m_prevTopCallFrame[sp]
+    loadp VM::topVMEntryFrame[vm], t4
+    storep t4, VMEntryRecord::m_prevTopVMEntryFrame[sp]
</ins><span class="cx"> 
</span><del>-    loadi ProtoCallFrame::paddedArgCount[protoCallFrame], temp2
-    addp CallFrameHeaderSlots, temp2, temp2
-    lshiftp 3, temp2
-    subp sp, temp2, temp1
</del><ins>+    loadi ProtoCallFrame::paddedArgCount[protoCallFrame], t4
+    addp CallFrameHeaderSlots, t4, t4
+    lshiftp 3, t4
+    subp sp, t4, t3
</ins><span class="cx"> 
</span><span class="cx">     # Ensure that we have enough additional stack capacity for the incoming args,
</span><span class="cx">     # and the frame for the JS code we're executing. We need to do this check
</span><span class="cx">     # before we start copying the args from the protoCallFrame below.
</span><del>-    bpaeq temp1, VM::m_jsStackLimit[vm], .stackHeightOK
</del><ins>+    bpaeq t3, VM::m_jsStackLimit[vm], .stackHeightOK
</ins><span class="cx"> 
</span><span class="cx">     if C_LOOP
</span><del>-        move entry, temp2
-        move vm, temp3
-        cloopCallSlowPath _llint_stack_check_at_vm_entry, vm, temp1
</del><ins>+        move entry, t4
+        move vm, t5
+        cloopCallSlowPath _llint_stack_check_at_vm_entry, vm, t3
</ins><span class="cx">         bpeq t0, 0, .stackCheckFailed
</span><del>-        move temp2, entry
-        move temp3, vm
</del><ins>+        move t4, entry
+        move t5, vm
</ins><span class="cx">         jmp .stackHeightOK
</span><span class="cx"> 
</span><span class="cx"> .stackCheckFailed:
</span><del>-        move temp2, entry
-        move temp3, vm
</del><ins>+        move t4, entry
+        move t5, vm
</ins><span class="cx">     end
</span><span class="cx"> 
</span><del>-    cCall2(_llint_throw_stack_overflow_error, vm, protoCallFrame)
</del><ins>+    move vm, a0
+    move protoCallFrame, a1
+    cCall2(_llint_throw_stack_overflow_error)
</ins><span class="cx"> 
</span><del>-    vmEntryRecord(cfr, temp2)
</del><ins>+    vmEntryRecord(cfr, t4)
</ins><span class="cx"> 
</span><del>-    loadp VMEntryRecord::m_vm[temp2], vm
-    loadp VMEntryRecord::m_prevTopCallFrame[temp2], temp3
-    storep temp3, VM::topCallFrame[vm]
-    loadp VMEntryRecord::m_prevTopVMEntryFrame[temp2], temp3
-    storep temp3, VM::topVMEntryFrame[vm]
</del><ins>+    loadp VMEntryRecord::m_vm[t4], vm
+    loadp VMEntryRecord::m_prevTopCallFrame[t4], extraTempReg
+    storep extraTempReg, VM::topCallFrame[vm]
+    loadp VMEntryRecord::m_prevTopVMEntryFrame[t4], extraTempReg
+    storep extraTempReg, VM::topVMEntryFrame[vm]
</ins><span class="cx"> 
</span><span class="cx">     subp cfr, CalleeRegisterSaveSize, sp
</span><span class="cx"> 
</span><span class="lines">@@ -225,62 +175,65 @@
</span><span class="cx">     ret
</span><span class="cx"> 
</span><span class="cx"> .stackHeightOK:
</span><del>-    move temp1, sp
-    move 4, temp1
</del><ins>+    move t3, sp
+    move 4, t3
</ins><span class="cx"> 
</span><span class="cx"> .copyHeaderLoop:
</span><del>-    subi 1, temp1
-    loadq [protoCallFrame, temp1, 8], temp3
-    storeq temp3, CodeBlock[sp, temp1, 8]
-    btinz temp1, .copyHeaderLoop
</del><ins>+    subi 1, t3
+    loadq [protoCallFrame, t3, 8], extraTempReg
+    storeq extraTempReg, CodeBlock[sp, t3, 8]
+    btinz t3, .copyHeaderLoop
</ins><span class="cx"> 
</span><del>-    loadi PayloadOffset + ProtoCallFrame::argCountAndCodeOriginValue[protoCallFrame], temp2
-    subi 1, temp2
-    loadi ProtoCallFrame::paddedArgCount[protoCallFrame], temp3
-    subi 1, temp3
</del><ins>+    loadi PayloadOffset + ProtoCallFrame::argCountAndCodeOriginValue[protoCallFrame], t4
+    subi 1, t4
+    loadi ProtoCallFrame::paddedArgCount[protoCallFrame], extraTempReg
+    subi 1, extraTempReg
</ins><span class="cx"> 
</span><del>-    bieq temp2, temp3, .copyArgs
-    move ValueUndefined, temp1
</del><ins>+    bieq t4, extraTempReg, .copyArgs
+    move ValueUndefined, t3
</ins><span class="cx"> .fillExtraArgsLoop:
</span><del>-    subi 1, temp3
-    storeq temp1, ThisArgumentOffset + 8[sp, temp3, 8]
-    bineq temp2, temp3, .fillExtraArgsLoop
</del><ins>+    subi 1, extraTempReg
+    storeq t3, ThisArgumentOffset + 8[sp, extraTempReg, 8]
+    bineq t4, extraTempReg, .fillExtraArgsLoop
</ins><span class="cx"> 
</span><span class="cx"> .copyArgs:
</span><del>-    loadp ProtoCallFrame::args[protoCallFrame], temp1
</del><ins>+    loadp ProtoCallFrame::args[protoCallFrame], t3
</ins><span class="cx"> 
</span><span class="cx"> .copyArgsLoop:
</span><del>-    btiz temp2, .copyArgsDone
-    subi 1, temp2
-    loadq [temp1, temp2, 8], temp3
-    storeq temp3, ThisArgumentOffset + 8[sp, temp2, 8]
</del><ins>+    btiz t4, .copyArgsDone
+    subi 1, t4
+    loadq [t3, t4, 8], extraTempReg
+    storeq extraTempReg, ThisArgumentOffset + 8[sp, t4, 8]
</ins><span class="cx">     jmp .copyArgsLoop
</span><span class="cx"> 
</span><span class="cx"> .copyArgsDone:
</span><span class="cx">     if ARM64
</span><del>-        move sp, temp2
-        storep temp2, VM::topCallFrame[vm]
</del><ins>+        move sp, t4
+        storep t4, VM::topCallFrame[vm]
</ins><span class="cx">     else
</span><span class="cx">         storep sp, VM::topCallFrame[vm]
</span><span class="cx">     end
</span><span class="cx">     storep cfr, VM::topVMEntryFrame[vm]
</span><span class="cx"> 
</span><del>-    move 0xffff000000000000, csr1
-    addp 2, csr1, csr2
</del><ins>+    move TagTypeNumber, tagTypeNumber
+    addp TagBitTypeOther, tagTypeNumber, tagMask
</ins><span class="cx"> 
</span><del>-    checkStackPointerAlignment(temp3, 0xbad0dc02)
</del><ins>+    checkStackPointerAlignment(extraTempReg, 0xbad0dc02)
</ins><span class="cx"> 
</span><del>-    makeCall(entry, temp1)
</del><ins>+    makeCall(entry, t3)
</ins><span class="cx"> 
</span><del>-    checkStackPointerAlignment(temp3, 0xbad0dc03)
</del><ins>+    # We may have just made a call into a JS function, so we can't rely on sp
+    # for anything but the fact that our own locals (ie the VMEntryRecord) are
+    # not below it. It also still has to be aligned, though.
+    checkStackPointerAlignment(t2, 0xbad0dc03)
</ins><span class="cx"> 
</span><del>-    vmEntryRecord(cfr, temp2)
</del><ins>+    vmEntryRecord(cfr, t4)
</ins><span class="cx"> 
</span><del>-    loadp VMEntryRecord::m_vm[temp2], vm
-    loadp VMEntryRecord::m_prevTopCallFrame[temp2], temp3
-    storep temp3, VM::topCallFrame[vm]
-    loadp VMEntryRecord::m_prevTopVMEntryFrame[temp2], temp3
-    storep temp3, VM::topVMEntryFrame[vm]
</del><ins>+    loadp VMEntryRecord::m_vm[t4], vm
+    loadp VMEntryRecord::m_prevTopCallFrame[t4], t2
+    storep t2, VM::topCallFrame[vm]
+    loadp VMEntryRecord::m_prevTopVMEntryFrame[t4], t2
+    storep t2, VM::topVMEntryFrame[vm]
</ins><span class="cx"> 
</span><span class="cx">     subp cfr, CalleeRegisterSaveSize, sp
</span><span class="cx"> 
</span><span class="lines">@@ -305,13 +258,7 @@
</span><span class="cx"> macro makeHostFunctionCall(entry, temp)
</span><span class="cx">     move entry, temp
</span><span class="cx">     storep cfr, [sp]
</span><del>-    if X86_64
-        move sp, t4
-    elsif X86_64_WIN
-        move sp, t2
-    elsif ARM64 or C_LOOP
-        move sp, a0
-    end
</del><ins>+    move sp, a0
</ins><span class="cx">     if C_LOOP
</span><span class="cx">         storep lr, 8[sp]
</span><span class="cx">         cloopCallNative temp
</span><span class="lines">@@ -336,10 +283,10 @@
</span><span class="cx">     vmEntryRecord(cfr, t2)
</span><span class="cx"> 
</span><span class="cx">     loadp VMEntryRecord::m_vm[t2], t3
</span><del>-    loadp VMEntryRecord::m_prevTopCallFrame[t2], t5
-    storep t5, VM::topCallFrame[t3]
-    loadp VMEntryRecord::m_prevTopVMEntryFrame[t2], t5
-    storep t5, VM::topVMEntryFrame[t3]
</del><ins>+    loadp VMEntryRecord::m_prevTopCallFrame[t2], extraTempReg
+    storep extraTempReg, VM::topCallFrame[t3]
+    loadp VMEntryRecord::m_prevTopVMEntryFrame[t2], extraTempReg
+    storep extraTempReg, VM::topVMEntryFrame[t3]
</ins><span class="cx"> 
</span><span class="cx">     subp cfr, CalleeRegisterSaveSize, sp
</span><span class="cx"> 
</span><span class="lines">@@ -350,31 +297,39 @@
</span><span class="cx"> 
</span><span class="cx"> macro prepareStateForCCall()
</span><span class="cx">     leap [PB, PC, 8], PC
</span><del>-    move PB, t3
</del><span class="cx"> end
</span><span class="cx"> 
</span><span class="cx"> macro restoreStateAfterCCall()
</span><del>-    move t0, PC
-    move t3, PB
</del><ins>+    move r0, PC
</ins><span class="cx">     subp PB, PC
</span><span class="cx">     rshiftp 3, PC
</span><span class="cx"> end
</span><span class="cx"> 
</span><span class="cx"> macro callSlowPath(slowPath)
</span><span class="cx">     prepareStateForCCall()
</span><del>-    cCall2(slowPath, cfr, PC)
</del><ins>+    move cfr, a0
+    move PC, a1
+    cCall2(slowPath)
</ins><span class="cx">     restoreStateAfterCCall()
</span><span class="cx"> end
</span><span class="cx"> 
</span><span class="cx"> macro traceOperand(fromWhere, operand)
</span><span class="cx">     prepareStateForCCall()
</span><del>-    cCall4(_llint_trace_operand, cfr, PC, fromWhere, operand)
</del><ins>+    move fromWhere, a2
+    move operand, a3
+    move cfr, a0
+    move PC, a1
+    cCall4(_llint_trace_operand)
</ins><span class="cx">     restoreStateAfterCCall()
</span><span class="cx"> end
</span><span class="cx"> 
</span><span class="cx"> macro traceValue(fromWhere, operand)
</span><span class="cx">     prepareStateForCCall()
</span><del>-    cCall4(_llint_trace_value, cfr, PC, fromWhere, operand)
</del><ins>+    move fromWhere, a2
+    move operand, a3
+    move cfr, a0
+    move PC, a1
+    cCall4(_llint_trace_value)
</ins><span class="cx">     restoreStateAfterCCall()
</span><span class="cx"> end
</span><span class="cx"> 
</span><span class="lines">@@ -382,16 +337,19 @@
</span><span class="cx"> macro callCallSlowPath(slowPath, action)
</span><span class="cx">     storei PC, ArgumentCount + TagOffset[cfr]
</span><span class="cx">     prepareStateForCCall()
</span><del>-    cCall2(slowPath, cfr, PC)
-    action(t0)
</del><ins>+    move cfr, a0
+    move PC, a1
+    cCall2(slowPath)
+    action(r0, r1)
</ins><span class="cx"> end
</span><span class="cx"> 
</span><span class="cx"> macro callWatchdogTimerHandler(throwHandler)
</span><span class="cx">     storei PC, ArgumentCount + TagOffset[cfr]
</span><span class="cx">     prepareStateForCCall()
</span><del>-    cCall2(_llint_slow_path_handle_watchdog_timer, cfr, PC)
-    btpnz t0, throwHandler
-    move t3, PB
</del><ins>+    move cfr, a0
+    move PC, a1
+    cCall2(_llint_slow_path_handle_watchdog_timer)
+    btpnz r0, throwHandler
</ins><span class="cx">     loadi ArgumentCount + TagOffset[cfr], PC
</span><span class="cx"> end
</span><span class="cx"> 
</span><span class="lines">@@ -401,12 +359,13 @@
</span><span class="cx">         macro()
</span><span class="cx">             storei PC, ArgumentCount + TagOffset[cfr]
</span><span class="cx">             prepareStateForCCall()
</span><del>-            cCall2(_llint_loop_osr, cfr, PC)
-            btpz t0, .recover
-            move t1, sp
-            jmp t0
</del><ins>+            move cfr, a0
+            move PC, a1
+            cCall2(_llint_loop_osr)
+            btpz r0, .recover
+            move r1, sp
+            jmp r0
</ins><span class="cx">         .recover:
</span><del>-            move t3, PB
</del><span class="cx">             loadi ArgumentCount + TagOffset[cfr], PC
</span><span class="cx">         end)
</span><span class="cx"> end
</span><span class="lines">@@ -447,7 +406,9 @@
</span><span class="cx">             macro(gcData)
</span><span class="cx">                 btbnz gcData, .writeBarrierDone
</span><span class="cx">                 push PB, PC
</span><del>-                cCall2Void(_llint_write_barrier_slow, cfr, t2)
</del><ins>+                move t2, a1 # t2 can be a0 (not on 64 bits, but better safe than sorry)
+                move cfr, a0
+                cCall2Void(_llint_write_barrier_slow)
</ins><span class="cx">                 pop PC, PB
</span><span class="cx">             end
</span><span class="cx">         )
</span><span class="lines">@@ -477,7 +438,9 @@
</span><span class="cx">             macro(gcData)
</span><span class="cx">                 btbnz gcData, .writeBarrierDone
</span><span class="cx">                 push PB, PC
</span><del>-                cCall2Void(_llint_write_barrier_slow, cfr, t3)
</del><ins>+                move cfr, a0
+                move t3, a1
+                cCall2Void(_llint_write_barrier_slow)
</ins><span class="cx">                 pop PC, PB
</span><span class="cx">             end
</span><span class="cx">         )
</span><span class="lines">@@ -538,19 +501,21 @@
</span><span class="cx">     loadi PayloadOffset + ArgumentCount[cfr], t0
</span><span class="cx">     biaeq t0, CodeBlock::m_numParameters[t1], doneLabel
</span><span class="cx">     prepareStateForCCall()
</span><del>-    cCall2(slowPath, cfr, PC)   # This slowPath has the protocol: t0 = 0 =&gt; no error, t0 != 0 =&gt; error
-    btiz t0, .noError
-    move t1, cfr   # t1 contains caller frame
</del><ins>+    move cfr, a0
+    move PC, a1
+    cCall2(slowPath)   # This slowPath has the protocol: r0 = 0 =&gt; no error, r0 != 0 =&gt; error
+    btiz r0, .noError
+    move r1, cfr   # r1 contains caller frame
</ins><span class="cx">     jmp _llint_throw_from_slow_path_trampoline
</span><span class="cx"> 
</span><span class="cx"> .noError:
</span><del>-    # t1 points to ArityCheckData.
-    loadp CommonSlowPaths::ArityCheckData::thunkToCall[t1], t2
-    btpz t2, .proceedInline
</del><ins>+    # r1 points to ArityCheckData.
+    loadp CommonSlowPaths::ArityCheckData::thunkToCall[r1], t3
+    btpz t3, .proceedInline
</ins><span class="cx">     
</span><del>-    loadp CommonSlowPaths::ArityCheckData::returnPC[t1], t7
-    loadp CommonSlowPaths::ArityCheckData::paddedStackSpace[t1], t0
-    call t2
</del><ins>+    loadp CommonSlowPaths::ArityCheckData::paddedStackSpace[r1], a0
+    loadp CommonSlowPaths::ArityCheckData::returnPC[r1], a1
+    call t3
</ins><span class="cx">     if ASSERT_ENABLED
</span><span class="cx">         loadp ReturnPC[cfr], t0
</span><span class="cx">         loadp [t0], t0
</span><span class="lines">@@ -558,7 +523,7 @@
</span><span class="cx">     jmp .continue
</span><span class="cx"> 
</span><span class="cx"> .proceedInline:
</span><del>-    loadi CommonSlowPaths::ArityCheckData::paddedStackSpace[t1], t1
</del><ins>+    loadi CommonSlowPaths::ArityCheckData::paddedStackSpace[r1], t1
</ins><span class="cx">     btiz t1, .continue
</span><span class="cx"> 
</span><span class="cx">     // Move frame up &quot;t1 * 2&quot; slots
</span><span class="lines">@@ -604,7 +569,6 @@
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx"> # Instruction implementations
</span><del>-
</del><span class="cx"> _llint_op_enter:
</span><span class="cx">     traceExecution()
</span><span class="cx">     checkStackPointerAlignment(t2, 0xdead00e1)
</span><span class="lines">@@ -636,14 +600,14 @@
</span><span class="cx">     traceExecution()
</span><span class="cx">     loadisFromInstruction(2, t0)
</span><span class="cx">     loadp [cfr, t0, 8], t0
</span><del>-    loadp JSFunction::m_rareData[t0], t4
-    btpz t4, .opCreateThisSlow
-    loadp FunctionRareData::m_allocationProfile + ObjectAllocationProfile::m_allocator[t4], t1
-    loadp FunctionRareData::m_allocationProfile + ObjectAllocationProfile::m_structure[t4], t2
</del><ins>+    loadp JSFunction::m_rareData[t0], t3
+    btpz t3, .opCreateThisSlow
+    loadp FunctionRareData::m_allocationProfile + ObjectAllocationProfile::m_allocator[t3], t1
+    loadp FunctionRareData::m_allocationProfile + ObjectAllocationProfile::m_structure[t3], t2
</ins><span class="cx">     btpz t1, .opCreateThisSlow
</span><del>-    loadpFromInstruction(4, t4)
-    bpeq t4, 1, .hasSeenMultipleCallee
-    bpneq t4, t0, .opCreateThisSlow
</del><ins>+    loadpFromInstruction(4, t3)
+    bpeq t3, 1, .hasSeenMultipleCallee
+    bpneq t3, t0, .opCreateThisSlow
</ins><span class="cx"> .hasSeenMultipleCallee:
</span><span class="cx">     allocateJSObject(t1, t2, t0, t3, .opCreateThisSlow)
</span><span class="cx">     loadisFromInstruction(1, t1)
</span><span class="lines">@@ -1776,7 +1740,7 @@
</span><span class="cx">     traceExecution()
</span><span class="cx">     checkSwitchToJITForEpilogue()
</span><span class="cx">     loadisFromInstruction(1, t2)
</span><del>-    loadConstantOrVariable(t2, t0)
</del><ins>+    loadConstantOrVariable(t2, r0)
</ins><span class="cx">     doReturn()
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="lines">@@ -1839,7 +1803,7 @@
</span><span class="cx">     checkSwitchToJITForEpilogue()
</span><span class="cx">     loadisFromInstruction(1, t0)
</span><span class="cx">     assertNotConstant(t0)
</span><del>-    loadq [cfr, t0, 8], t0
</del><ins>+    loadq [cfr, t0, 8], r0
</ins><span class="cx">     doReturn()
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="lines">@@ -1864,56 +1828,31 @@
</span><span class="cx"> 
</span><span class="cx">     functionPrologue()
</span><span class="cx">     storep 0, CodeBlock[cfr]
</span><del>-    if X86_64 or X86_64_WIN
-        if X86_64
-            const arg1 = t4  # t4 = rdi
-            const arg2 = t5  # t5 = rsi
-            const temp = t1
-        elsif X86_64_WIN
-            const arg1 = t2  # t2 = rcx
-            const arg2 = t1  # t1 = rdx
-            const temp = t0
-        end
-        loadp Callee[cfr], t0
-        andp MarkedBlockMask, t0, t1
-        loadp MarkedBlock::m_weakSet + WeakSet::m_vm[t1], t1
-        storep cfr, VM::topCallFrame[t1]
-        move cfr, arg1
-        loadp Callee[cfr], arg2
-        loadp JSFunction::m_executable[arg2], temp
-        checkStackPointerAlignment(t3, 0xdead0001)
</del><ins>+    loadp Callee[cfr], t0
+    andp MarkedBlockMask, t0, t1
+    loadp MarkedBlock::m_weakSet + WeakSet::m_vm[t1], t1
+    storep cfr, VM::topCallFrame[t1]
+    if ARM64 or C_LOOP
+        storep lr, ReturnPC[cfr]
+    end
+    move cfr, a0
+    loadp Callee[cfr], t1
+    loadp JSFunction::m_executable[t1], t1
+    checkStackPointerAlignment(t3, 0xdead0001)
+    if C_LOOP
+        cloopCallNative executableOffsetToFunction[t1]
+    else
</ins><span class="cx">         if X86_64_WIN
</span><span class="cx">             subp 32, sp
</span><span class="cx">         end
</span><del>-        call executableOffsetToFunction[temp]
</del><ins>+        call executableOffsetToFunction[t1]
</ins><span class="cx">         if X86_64_WIN
</span><span class="cx">             addp 32, sp
</span><span class="cx">         end
</span><del>-        loadp Callee[cfr], t3
-        andp MarkedBlockMask, t3
-        loadp MarkedBlock::m_weakSet + WeakSet::m_vm[t3], t3
-    elsif ARM64 or C_LOOP
-        loadp Callee[cfr], t0
-        andp MarkedBlockMask, t0, t1
-        loadp MarkedBlock::m_weakSet + WeakSet::m_vm[t1], t1
-        storep cfr, VM::topCallFrame[t1]
-        preserveReturnAddressAfterCall(t3)
-        storep t3, ReturnPC[cfr]
-        move cfr, t0
-        loadp Callee[cfr], t1
-        loadp JSFunction::m_executable[t1], t1
-        if C_LOOP
-            cloopCallNative executableOffsetToFunction[t1]
-        else
-            call executableOffsetToFunction[t1]
-        end
-        restoreReturnAddressBeforeReturn(t3)
-        loadp Callee[cfr], t3
-        andp MarkedBlockMask, t3
-        loadp MarkedBlock::m_weakSet + WeakSet::m_vm[t3], t3
-    else
-        error
</del><span class="cx">     end
</span><ins>+    loadp Callee[cfr], t3
+    andp MarkedBlockMask, t3
+    loadp MarkedBlock::m_weakSet + WeakSet::m_vm[t3], t3
</ins><span class="cx"> 
</span><span class="cx">     functionEpilogue()
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreofflineasmarmrb"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/offlineasm/arm.rb (189292 => 189293)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/offlineasm/arm.rb        2015-09-03 21:55:40 UTC (rev 189292)
+++ trunk/Source/JavaScriptCore/offlineasm/arm.rb        2015-09-03 22:16:23 UTC (rev 189293)
</span><span class="lines">@@ -27,6 +27,34 @@
</span><span class="cx"> require &quot;opt&quot;
</span><span class="cx"> require &quot;risc&quot;
</span><span class="cx"> 
</span><ins>+# GPR conventions, to match the baseline JIT
+#
+#  x0 =&gt; t0, a0, r0
+#  x1 =&gt; t1, a1, r1
+#  x2 =&gt; t2, a2, r2
+#  x3 =&gt; t3, a3, r3
+#  x6 =&gt;            (callee-save scratch)
+#  x7 =&gt; cfr        (ARMv7 only)
+#  x8 =&gt; t4         (callee-save)
+#  x9 =&gt; t5         (callee-save)
+# x10 =&gt;            (callee-save scratch)
+# x11 =&gt; cfr        (ARM and ARMv7 traditional)
+# x12 =&gt;            (callee-save scratch)
+#  lr =&gt; lr
+#  sp =&gt; sp
+#  pc =&gt; pc
+#
+# FPR conventions, to match the baseline JIT
+#
+# d0 =&gt; ft0, fa0, fr
+# d1 =&gt; ft1, fa1
+# d2 =&gt; ft2
+# d3 =&gt; ft3
+# d4 =&gt; ft4
+# d5 =&gt; ft5
+# d6 =&gt;              (scratch)
+# d7 =&gt;              (scratch)
+
</ins><span class="cx"> def isARMv7
</span><span class="cx">     case $activeBackend
</span><span class="cx">     when &quot;ARMv7&quot;
</span><span class="lines">@@ -119,9 +147,9 @@
</span><span class="cx"> class FPRegisterID
</span><span class="cx">     def armOperand
</span><span class="cx">         case name
</span><del>-        when &quot;ft0&quot;, &quot;fr&quot;
</del><ins>+        when &quot;ft0&quot;, &quot;fr&quot;, &quot;fa0&quot;
</ins><span class="cx">             &quot;d0&quot;
</span><del>-        when &quot;ft1&quot;
</del><ins>+        when &quot;ft1&quot;, &quot;fa1&quot;
</ins><span class="cx">             &quot;d1&quot;
</span><span class="cx">         when &quot;ft2&quot;
</span><span class="cx">             &quot;d2&quot;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreofflineasmarm64rb"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/offlineasm/arm64.rb (189292 => 189293)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/offlineasm/arm64.rb        2015-09-03 21:55:40 UTC (rev 189292)
+++ trunk/Source/JavaScriptCore/offlineasm/arm64.rb        2015-09-03 22:16:23 UTC (rev 189293)
</span><span class="lines">@@ -37,32 +37,30 @@
</span><span class="cx"> #
</span><span class="cx"> # GPR conventions, to match the baseline JIT:
</span><span class="cx"> #
</span><del>-#  x0  =&gt; return value, cached result, first argument, t0, a0, r0
</del><ins>+#  x0  =&gt; t0, a0, r0
</ins><span class="cx"> #  x1  =&gt; t1, a1, r1
</span><span class="cx"> #  x2  =&gt; t2, a2
</span><del>-#  x3  =&gt; a3
-#  x5  =&gt; t4
-#  x6  =&gt; t6
-#  x9  =&gt; (nonArgGPR1 in baseline)
-# x13  =&gt; scratch (unused in baseline)
-# x16  =&gt; scratch
-# x17  =&gt; scratch
-# x23  =&gt; t3
-# x24  =&gt; t5
-# x27  =&gt; csr1 (tagTypeNumber)
-# x28  =&gt; csr2 (tagMask)
</del><ins>+#  x3  =&gt; t3, a3
+#  x4  =&gt; t4
+#  x5  =&gt; t5
+# x13  =&gt;                  (scratch)
+# x16  =&gt;                  (scratch)
+# x17  =&gt;                  (scratch)
+# x26  =&gt;             csr0 (PB)
+# x27  =&gt;             csr1 (tagTypeNumber)
+# x28  =&gt;             csr2 (tagMask)
</ins><span class="cx"> # x29  =&gt; cfr
</span><span class="cx"> #  sp  =&gt; sp
</span><span class="cx"> #  lr  =&gt; lr
</span><span class="cx"> #
</span><del>-# FPR conentions, to match the baseline JIT:
</del><ins>+# FPR conventions, to match the baseline JIT:
</ins><span class="cx"> #
</span><del>-#  q0  =&gt; ft0
-#  q1  =&gt; ft1
-#  q2  =&gt; ft2
-#  q3  =&gt; ft3
-#  q4  =&gt; ft4 (unused in baseline)
-#  q5  =&gt; ft5 (unused in baseline)
</del><ins>+#  q0  =&gt; ft0, fa0, fr
+#  q1  =&gt; ft1, fa1
+#  q2  =&gt; ft2, fa2
+#  q3  =&gt; ft3, fa3
+#  q4  =&gt; ft4          (unused in baseline)
+#  q5  =&gt; ft5          (unused in baseline)
</ins><span class="cx"> # q31  =&gt; scratch
</span><span class="cx"> 
</span><span class="cx"> def arm64GPRName(name, kind)
</span><span class="lines">@@ -109,20 +107,16 @@
</span><span class="cx">             arm64GPRName('x1', kind)
</span><span class="cx">         when 't2', 'a2'
</span><span class="cx">             arm64GPRName('x2', kind)
</span><del>-        when 'a3'
</del><ins>+        when 't3', 'a3'
</ins><span class="cx">             arm64GPRName('x3', kind)
</span><del>-        when 't3'
-            arm64GPRName('x23', kind)
</del><span class="cx">         when 't4'
</span><del>-            arm64GPRName('x5', kind)
</del><ins>+            arm64GPRName('x4', kind)
</ins><span class="cx">         when 't5'
</span><del>-            arm64GPRName('x24', kind)
-        when 't6'
-            arm64GPRName('x6', kind)
-        when 't7'
-            arm64GPRName('x7', kind)
</del><ins>+            arm64GPRName('x5', kind)
</ins><span class="cx">         when 'cfr'
</span><span class="cx">             arm64GPRName('x29', kind)
</span><ins>+        when 'csr0'
+            arm64GPRName('x26', kind)
</ins><span class="cx">         when 'csr1'
</span><span class="cx">             arm64GPRName('x27', kind)
</span><span class="cx">         when 'csr2'
</span><span class="lines">@@ -140,13 +134,13 @@
</span><span class="cx"> class FPRegisterID
</span><span class="cx">     def arm64Operand(kind)
</span><span class="cx">         case @name
</span><del>-        when 'ft0'
</del><ins>+        when 'ft0', 'fr', 'fa0'
</ins><span class="cx">             arm64FPRName('q0', kind)
</span><del>-        when 'ft1'
</del><ins>+        when 'ft1', 'fa1'
</ins><span class="cx">             arm64FPRName('q1', kind)
</span><del>-        when 'ft2'
</del><ins>+        when 'ft2', 'fa2'
</ins><span class="cx">             arm64FPRName('q2', kind)
</span><del>-        when 'ft3'
</del><ins>+        when 'ft3', 'fa3'
</ins><span class="cx">             arm64FPRName('q3', kind)
</span><span class="cx">         when 'ft4'
</span><span class="cx">             arm64FPRName('q4', kind)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreofflineasmclooprb"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/offlineasm/cloop.rb (189292 => 189293)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/offlineasm/cloop.rb        2015-09-03 21:55:40 UTC (rev 189292)
+++ trunk/Source/JavaScriptCore/offlineasm/cloop.rb        2015-09-03 22:16:23 UTC (rev 189293)
</span><span class="lines">@@ -70,9 +70,9 @@
</span><span class="cx">         case name
</span><span class="cx">         # The cloop is modelled on the ARM implementation. Hence, the a0-a3
</span><span class="cx">         # registers are aliases for r0-r3 i.e. t0-t3 in our case.
</span><del>-        when &quot;t0&quot;, &quot;a0&quot;
</del><ins>+        when &quot;t0&quot;, &quot;a0&quot;, &quot;r0&quot;
</ins><span class="cx">             &quot;t0&quot;
</span><del>-        when &quot;t1&quot;, &quot;a1&quot;
</del><ins>+        when &quot;t1&quot;, &quot;a1&quot;, &quot;r1&quot;
</ins><span class="cx">             &quot;t1&quot;
</span><span class="cx">         when &quot;t2&quot;, &quot;a2&quot;
</span><span class="cx">             &quot;t2&quot;
</span><span class="lines">@@ -82,10 +82,8 @@
</span><span class="cx">             &quot;pc&quot;
</span><span class="cx">         when &quot;t5&quot;
</span><span class="cx">             &quot;t5&quot;
</span><del>-        when &quot;t6&quot;
</del><ins>+        when &quot;csr0&quot;
</ins><span class="cx">             &quot;pcBase&quot;
</span><del>-        when &quot;t7&quot;
-            &quot;t7&quot;
</del><span class="cx">         when &quot;csr1&quot;
</span><span class="cx">             &quot;tagTypeNumber&quot;
</span><span class="cx">         when &quot;csr2&quot;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreofflineasmmipsrb"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/offlineasm/mips.rb (189292 => 189293)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/offlineasm/mips.rb        2015-09-03 21:55:40 UTC (rev 189292)
+++ trunk/Source/JavaScriptCore/offlineasm/mips.rb        2015-09-03 22:16:23 UTC (rev 189293)
</span><span class="lines">@@ -24,6 +24,41 @@
</span><span class="cx"> 
</span><span class="cx"> require 'risc'
</span><span class="cx"> 
</span><ins>+# GPR conventions, to match the baseline JIT
+#
+# $a0 =&gt; a0
+# $a1 =&gt; a1
+# $a2 =&gt; a2
+# $a3 =&gt; a3
+# $v0 =&gt; t0, r0
+# $v1 =&gt; t1, r1
+# $t2 =&gt;         t2
+# $t3 =&gt;         t3
+# $t4 =&gt;         t4
+# $t5 =&gt;         t5
+# $t6 =&gt;            (scratch)
+# $t7 =&gt;            (scratch)
+# $t8 =&gt;            (scratch)
+# $t9 =&gt;            (stores the callee of a call opcode)
+# $gp =&gt;            (globals)
+# $s4 =&gt;            (callee-save used to preserve $gp across calls)
+# $ra =&gt; lr
+# $sp =&gt; sp
+# $fp =&gt; cfr
+#
+# FPR conventions, to match the baseline JIT
+# We don't have fa2 or fa3!
+#  $f0 =&gt; ft0, fr
+#  $f2 =&gt; ft1
+#  $f4 =&gt; ft2
+#  $f6 =&gt; ft3
+#  $f8 =&gt; ft4
+# $f10 =&gt; ft5
+# $f12 =&gt;        fa0
+# $f14 =&gt;        fa1
+# $f16 =&gt;            (scratch)
+# $f18 =&gt;            (scratch)
+
</ins><span class="cx"> class Assembler
</span><span class="cx">     def putStr(str)
</span><span class="cx">         @outp.puts str
</span><span class="lines">@@ -57,8 +92,7 @@
</span><span class="cx">     end
</span><span class="cx"> end
</span><span class="cx"> 
</span><del>-MIPS_TEMP_GPRS = [SpecialRegister.new(&quot;$t5&quot;), SpecialRegister.new(&quot;$t6&quot;), SpecialRegister.new(&quot;$t7&quot;),
-                    SpecialRegister.new(&quot;$t8&quot;)]
</del><ins>+MIPS_TEMP_GPRS = [SpecialRegister.new(&quot;$t6&quot;), SpecialRegister.new(&quot;$t7&quot;), SpecialRegister.new(&quot;$t8&quot;)]
</ins><span class="cx"> MIPS_ZERO_REG = SpecialRegister.new(&quot;$zero&quot;)
</span><span class="cx"> MIPS_GP_REG = SpecialRegister.new(&quot;$gp&quot;)
</span><span class="cx"> MIPS_GPSAVE_REG = SpecialRegister.new(&quot;$s4&quot;)
</span><span class="lines">@@ -85,24 +119,18 @@
</span><span class="cx">             &quot;$a2&quot;
</span><span class="cx">         when &quot;a3&quot;
</span><span class="cx">             &quot;$a3&quot;
</span><del>-        when &quot;r0&quot;, &quot;t0&quot;
</del><ins>+        when &quot;t0&quot;, &quot;r0&quot;
</ins><span class="cx">             &quot;$v0&quot;
</span><del>-        when &quot;r1&quot;, &quot;t1&quot;
</del><ins>+        when &quot;t1&quot;, &quot;r1&quot;
</ins><span class="cx">             &quot;$v1&quot;
</span><span class="cx">         when &quot;t2&quot;
</span><span class="cx">             &quot;$t2&quot;
</span><span class="cx">         when &quot;t3&quot;
</span><del>-            &quot;$s3&quot;
-        when &quot;t4&quot;   # PC reg in llint
-            &quot;$s2&quot;
</del><ins>+            &quot;$t3&quot;
+        when &quot;t4&quot;
+            &quot;$t4&quot;
</ins><span class="cx">         when &quot;t5&quot;
</span><span class="cx">             &quot;$t5&quot;
</span><del>-        when &quot;t6&quot;
-            &quot;$t6&quot;
-        when &quot;t7&quot;
-            &quot;$t7&quot;
-        when &quot;t8&quot;
-            &quot;$t8&quot;
</del><span class="cx">         when &quot;cfr&quot;
</span><span class="cx">             &quot;$fp&quot;
</span><span class="cx">         when &quot;lr&quot;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreofflineasmregistersrb"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/offlineasm/registers.rb (189292 => 189293)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/offlineasm/registers.rb        2015-09-03 21:55:40 UTC (rev 189292)
+++ trunk/Source/JavaScriptCore/offlineasm/registers.rb        2015-09-03 22:16:23 UTC (rev 189293)
</span><span class="lines">@@ -31,10 +31,6 @@
</span><span class="cx">      &quot;t3&quot;,
</span><span class="cx">      &quot;t4&quot;,
</span><span class="cx">      &quot;t5&quot;,
</span><del>-     &quot;t6&quot;,
-     &quot;t7&quot;,
-     &quot;t8&quot;,
-     &quot;t9&quot;,
</del><span class="cx">      &quot;cfr&quot;,
</span><span class="cx">      &quot;a0&quot;,
</span><span class="cx">      &quot;a1&quot;,
</span><span class="lines">@@ -46,8 +42,13 @@
</span><span class="cx">      &quot;lr&quot;,
</span><span class="cx">      &quot;pc&quot;,
</span><span class="cx">      # 64-bit only registers:
</span><del>-     &quot;csr1&quot;,  # tag type number register
-     &quot;csr2&quot;   # tag mask register
</del><ins>+     &quot;csr0&quot;,
+     &quot;csr1&quot;,
+     &quot;csr2&quot;,
+     &quot;csr3&quot;,
+     &quot;csr4&quot;,
+     &quot;csr5&quot;,
+     &quot;csr6&quot;
</ins><span class="cx">     ]
</span><span class="cx"> 
</span><span class="cx"> FPRS =
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreofflineasmsh4rb"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/offlineasm/sh4.rb (189292 => 189293)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/offlineasm/sh4.rb        2015-09-03 21:55:40 UTC (rev 189292)
+++ trunk/Source/JavaScriptCore/offlineasm/sh4.rb        2015-09-03 22:16:23 UTC (rev 189293)
</span><span class="lines">@@ -24,6 +24,33 @@
</span><span class="cx"> 
</span><span class="cx"> require 'risc'
</span><span class="cx"> 
</span><ins>+# GPR conventions, to match the baseline JIT
+#
+#  r0 =&gt; t0, r0
+#  r1 =&gt; t1, r1
+#  r2 =&gt; t4
+#  r3 =&gt; t5
+#  r4 =&gt;         a0
+#  r5 =&gt;         a1
+#  r6 =&gt; t2,     a2
+#  r7 =&gt; t3,     a3
+# r10 =&gt;            (scratch)
+# r11 =&gt;            (scratch)
+# r13 =&gt;            (scratch)
+# r14 =&gt; cfr
+# r15 =&gt; sp
+#  pr =&gt; lr
+
+# FPR conventions, to match the baseline JIT
+# We don't have fa2 or fa3!
+#  dr0 =&gt; ft0, fr
+#  dr2 =&gt; ft1
+#  dr4 =&gt; ft2,   fa0
+#  dr6 =&gt; ft3,   fa1
+#  dr8 =&gt; ft4
+# dr10 =&gt; ft5
+# dr12 =&gt;             (scratch)
+
</ins><span class="cx"> class Node
</span><span class="cx">     def sh4SingleHi
</span><span class="cx">         doubleOperand = sh4Operand
</span><span class="lines">@@ -51,32 +78,28 @@
</span><span class="cx">     end
</span><span class="cx"> end
</span><span class="cx"> 
</span><del>-SH4_TMP_GPRS = [ SpecialRegister.new(&quot;r3&quot;), SpecialRegister.new(&quot;r11&quot;), SpecialRegister.new(&quot;r13&quot;) ]
-SH4_TMP_FPRS = [ SpecialRegister.new(&quot;dr10&quot;) ]
</del><ins>+SH4_TMP_GPRS = [ SpecialRegister.new(&quot;r10&quot;), SpecialRegister.new(&quot;r11&quot;), SpecialRegister.new(&quot;r13&quot;) ]
+SH4_TMP_FPRS = [ SpecialRegister.new(&quot;dr12&quot;) ]
</ins><span class="cx"> 
</span><span class="cx"> class RegisterID
</span><span class="cx">     def sh4Operand
</span><span class="cx">         case name
</span><del>-        when &quot;t0&quot;
</del><ins>+        when &quot;a0&quot;
+            &quot;r4&quot;
+        when &quot;a1&quot;
+            &quot;r5&quot;
+        when &quot;r0&quot;, &quot;t0&quot;
</ins><span class="cx">             &quot;r0&quot;
</span><del>-        when &quot;t1&quot;
</del><ins>+        when &quot;r1&quot;, &quot;t1&quot;
</ins><span class="cx">             &quot;r1&quot;
</span><del>-        when &quot;t2&quot;
-            &quot;r2&quot;
-        when &quot;t3&quot;
-            &quot;r10&quot;
-        when &quot;t4&quot;, &quot;a0&quot;
-            &quot;r4&quot;
-        when &quot;t5&quot;, &quot;a1&quot;
-            &quot;r5&quot;
-        when &quot;t6&quot;, &quot;a2&quot;
</del><ins>+        when &quot;a2&quot;, &quot;t2&quot;
</ins><span class="cx">             &quot;r6&quot;
</span><del>-        when &quot;t7&quot;, &quot;a3&quot;
</del><ins>+        when &quot;a3&quot;, &quot;t3&quot;
</ins><span class="cx">             &quot;r7&quot;
</span><del>-        when &quot;t8&quot;
-            &quot;r8&quot;
-        when &quot;t9&quot;
-            &quot;r9&quot;
</del><ins>+        when &quot;t4&quot;
+            &quot;r2&quot;
+        when &quot;t5&quot;
+            &quot;r3&quot;
</ins><span class="cx">         when &quot;cfr&quot;
</span><span class="cx">             &quot;r14&quot;
</span><span class="cx">         when &quot;sp&quot;
</span><span class="lines">@@ -96,14 +119,14 @@
</span><span class="cx">             &quot;dr0&quot;
</span><span class="cx">         when &quot;ft1&quot;
</span><span class="cx">             &quot;dr2&quot;
</span><del>-        when &quot;ft2&quot;
</del><ins>+        when &quot;ft2&quot;, &quot;fa0&quot;
</ins><span class="cx">             &quot;dr4&quot;
</span><del>-        when &quot;ft3&quot;
</del><ins>+        when &quot;ft3&quot;, &quot;fa1&quot;
</ins><span class="cx">             &quot;dr6&quot;
</span><span class="cx">         when &quot;ft4&quot;
</span><span class="cx">             &quot;dr8&quot;
</span><del>-        when &quot;fa0&quot;
-            &quot;dr12&quot;
</del><ins>+        when &quot;ft5&quot;
+            &quot;dr10&quot;
</ins><span class="cx">         else
</span><span class="cx">             raise &quot;Bad register #{name} for SH4 at #{codeOriginString}&quot;
</span><span class="cx">         end
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreofflineasmx86rb"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/offlineasm/x86.rb (189292 => 189293)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/offlineasm/x86.rb        2015-09-03 21:55:40 UTC (rev 189292)
+++ trunk/Source/JavaScriptCore/offlineasm/x86.rb        2015-09-03 22:16:23 UTC (rev 189293)
</span><span class="lines">@@ -24,6 +24,62 @@
</span><span class="cx"> 
</span><span class="cx"> require &quot;config&quot;
</span><span class="cx"> 
</span><ins>+# GPR conventions, to match the baseline JIT:
+#
+#
+# On x86-32 bits (windows and non-windows)
+# a0, a1, a2, a3 are only there for ease-of-use of offlineasm; they are not
+# actually considered as such by the ABI and we need to push/pop our arguments
+# on the stack. a0 and a1 are ecx and edx to follow fastcall.
+#
+# eax =&gt; t0, a2, r0
+# edx =&gt; t1, a1, r1
+# ecx =&gt; t2, a0
+# ebx =&gt; t3, a3     (callee-save)
+# esi =&gt; t4         (callee-save)
+# edi =&gt; t5         (callee-save)
+# ebp =&gt; cfr
+# esp =&gt; sp
+#
+# On x86-64 non-windows
+#
+# rax =&gt; t0,     r0
+# rdi =&gt;     a0
+# rsi =&gt; t1, a1
+# rdx =&gt; t2, a2, r1
+# rcx =&gt; t3, a3
+#  r8 =&gt; t4
+# r10 =&gt; t5
+# rbx =&gt;             csr0 (callee-save, PB, unused in baseline)
+# r12 =&gt;             csr1 (callee-save)
+# r13 =&gt;             csr2 (callee-save)
+# r14 =&gt;             csr3 (callee-save, tagTypeNumber)
+# r15 =&gt;             csr4 (callee-save, tagMask)
+# rsp =&gt; sp
+# rbp =&gt; cfr
+# r11 =&gt;                  (scratch)
+#
+# On x86-64 windows
+# Arguments need to be push/pop'd on the stack in addition to being stored in
+# the registers. Also, &gt;8 return types are returned in a weird way.
+#
+# rax =&gt; t0,     r0
+# rcx =&gt;     a0
+# rdx =&gt; t1, a1, r1
+#  r8 =&gt; t2, a2
+#  r9 =&gt; t3, a3
+# r10 =&gt; t4
+# rbx =&gt;             csr0 (callee-save, PB, unused in baseline)
+# rsi =&gt;             csr1 (callee-save)
+# rdi =&gt;             csr2 (callee-save)
+# r12 =&gt;             csr3 (callee-save)
+# r13 =&gt;             csr4 (callee-save)
+# r14 =&gt;             csr5 (callee-save, tagTypeNumber)
+# r15 =&gt;             csr6 (callee-save, tagMask)
+# rsp =&gt; sp
+# rbp =&gt; cfr
+# r11 =&gt;                  (scratch)
+
</ins><span class="cx"> def isX64
</span><span class="cx">     case $activeBackend
</span><span class="cx">     when &quot;X86&quot;
</span><span class="lines">@@ -39,6 +95,21 @@
</span><span class="cx">     end
</span><span class="cx"> end
</span><span class="cx"> 
</span><ins>+def isWin
+    case $activeBackend
+    when &quot;X86&quot;
+        false
+    when &quot;X86_WIN&quot;
+        true
+    when &quot;X86_64&quot;
+        false
+    when &quot;X86_64_WIN&quot;
+        true
+    else
+        raise &quot;bad value for $activeBackend: #{$activeBackend}&quot;
+    end
+end
+
</ins><span class="cx"> def useX87
</span><span class="cx">     case $activeBackend
</span><span class="cx">     when &quot;X86&quot;
</span><span class="lines">@@ -54,20 +125,20 @@
</span><span class="cx">     end
</span><span class="cx"> end
</span><span class="cx"> 
</span><del>-def isWindows
</del><ins>+def isCompilingOnWindows
</ins><span class="cx">     ENV['OS'] == 'Windows_NT'
</span><span class="cx"> end
</span><span class="cx"> 
</span><span class="cx"> def isGCC
</span><del>-    !isWindows
</del><ins>+    !isCompilingOnWindows
</ins><span class="cx"> end
</span><span class="cx"> 
</span><span class="cx"> def isMSVC
</span><del>-    isWindows
</del><ins>+    isCompilingOnWindows
</ins><span class="cx"> end
</span><span class="cx"> 
</span><span class="cx"> def isIntelSyntax
</span><del>-    isWindows
</del><ins>+    isCompilingOnWindows
</ins><span class="cx"> end
</span><span class="cx"> 
</span><span class="cx"> def register(name)
</span><span class="lines">@@ -141,205 +212,133 @@
</span><span class="cx"> 
</span><span class="cx"> X64_SCRATCH_REGISTER = SpecialRegister.new(&quot;r11&quot;)
</span><span class="cx"> 
</span><ins>+def x86GPRName(name, kind)
+    case name
+    when &quot;eax&quot;, &quot;ebx&quot;, &quot;ecx&quot;, &quot;edx&quot;
+        name8 = name[1] + 'l'
+        name16 = name[1..2]
+    when &quot;esi&quot;, &quot;edi&quot;, &quot;ebp&quot;, &quot;esp&quot;
+        name16 = name[1..2]
+        name8 = name16 + 'l'
+    when &quot;rax&quot;, &quot;rbx&quot;, &quot;rcx&quot;, &quot;rdx&quot;
+        raise &quot;bad GPR name #{name} in 32-bit X86&quot; unless isX64
+        name8 = name[1] + 'l'
+        name16 = name[1..2]
+    when &quot;r8&quot;, &quot;r9&quot;, &quot;r10&quot;, &quot;r12&quot;, &quot;r13&quot;, &quot;r14&quot;, &quot;r15&quot;
+        raise &quot;bad GPR name #{name} in 32-bit X86&quot; unless isX64
+        case kind
+        when :half
+            return register(name + &quot;w&quot;)
+        when :int
+            return register(name + &quot;d&quot;)
+        when :ptr
+            return register(name)
+        when :quad
+            return register(name)
+        end
+    else
+        raise &quot;bad GPR name #{name}&quot;
+    end
+    case kind
+    when :byte
+        register(name8)
+    when :half
+        register(name16)
+    when :int
+        register(&quot;e&quot; + name16)
+    when :ptr
+        register((isX64 ? &quot;r&quot; : &quot;e&quot;) + name16)
+    when :quad
+        isX64 ? register(&quot;r&quot; + name16) : raise
+    else
+        raise &quot;invalid kind #{kind} for GPR #{name} in X86&quot;
+    end
+end
+
</ins><span class="cx"> class RegisterID
</span><span class="cx">     def supports8BitOnX86
</span><del>-        case name
-        when &quot;t0&quot;, &quot;a0&quot;, &quot;r0&quot;, &quot;t1&quot;, &quot;a1&quot;, &quot;r1&quot;, &quot;t2&quot;, &quot;t3&quot;, &quot;t4&quot;, &quot;t5&quot;
</del><ins>+        case x86GPR
+        when &quot;eax&quot;, &quot;ebx&quot;, &quot;ecx&quot;, &quot;edx&quot;, &quot;edi&quot;, &quot;esi&quot;, &quot;ebp&quot;, &quot;esp&quot;
</ins><span class="cx">             true
</span><del>-        when &quot;cfr&quot;, &quot;ttnr&quot;, &quot;tmr&quot;
</del><ins>+        when &quot;r8&quot;, &quot;r9&quot;, &quot;r10&quot;, &quot;r12&quot;, &quot;r13&quot;, &quot;r14&quot;, &quot;r15&quot;
</ins><span class="cx">             false
</span><del>-        when &quot;t6&quot;
-            isX64
</del><span class="cx">         else
</span><span class="cx">             raise
</span><span class="cx">         end
</span><span class="cx">     end
</span><del>-    
-    def x86Operand(kind)
-        case name
-        when &quot;t0&quot;, &quot;a0&quot;, &quot;r0&quot;
-            case kind
-            when :byte
-                register(&quot;al&quot;)
-            when :half
-                register(&quot;ax&quot;)
-            when :int
-                register(&quot;eax&quot;)
-            when :ptr
-                isX64 ? register(&quot;rax&quot;) : register(&quot;eax&quot;)
-            when :quad
-                isX64 ? register(&quot;rax&quot;) : raise
</del><ins>+
+    def x86GPR
+        if isX64
+            case name
+            when &quot;t0&quot;, &quot;r0&quot;
+                &quot;eax&quot;
+            when &quot;r1&quot;
+                &quot;edx&quot; # t1 = a1 when isWin, t2 = a2 otherwise
+            when &quot;a0&quot;
+                isWin ? &quot;ecx&quot; : &quot;edi&quot;
+            when &quot;t1&quot;, &quot;a1&quot;
+                isWin ? &quot;edx&quot; : &quot;esi&quot;
+            when &quot;t2&quot;, &quot;a2&quot;
+                isWin ? &quot;r8&quot; : &quot;edx&quot;
+            when &quot;t3&quot;, &quot;a3&quot;
+                isWin ? &quot;r9&quot; : &quot;ecx&quot;
+            when &quot;t4&quot;
+                isWin ? &quot;r10&quot; : &quot;r8&quot;
+            when &quot;t5&quot;
+                raise &quot;cannot use register #{name} on X86-64 Windows&quot; unless not isWin
+                &quot;r10&quot;
+            when &quot;csr0&quot;
+                &quot;ebx&quot;
+            when &quot;csr1&quot;
+                &quot;r12&quot;
+            when &quot;csr2&quot;
+                &quot;r13&quot;
+            when &quot;csr3&quot;
+                isWin ? &quot;esi&quot; : &quot;r14&quot;
+            when &quot;csr4&quot;
+                isWin ? &quot;edi&quot; : &quot;r15&quot;
+                &quot;r15&quot;
+            when &quot;csr5&quot;
+                raise &quot;cannot use register #{name} on X86-64&quot; unless isWin
+                &quot;r14&quot;
+            when &quot;csr6&quot;
+                raise &quot;cannot use register #{name} on X86-64&quot; unless isWin
+                &quot;r15&quot;
+            when &quot;cfr&quot;
+                &quot;ebp&quot;
+            when &quot;sp&quot;
+                &quot;esp&quot;
</ins><span class="cx">             else
</span><del>-                raise &quot;Invalid kind #{kind} for name #{name}&quot;
</del><ins>+                raise &quot;cannot use register #{name} on X86&quot;
</ins><span class="cx">             end
</span><del>-        when &quot;t1&quot;, &quot;a1&quot;, &quot;r1&quot;
-            case kind
-            when :byte
-                register(&quot;dl&quot;)
-            when :half
-                register(&quot;dx&quot;)
-            when :int
-                register(&quot;edx&quot;)
-            when :ptr
-                isX64 ? register(&quot;rdx&quot;) : register(&quot;edx&quot;)
-            when :quad
-                isX64 ? register(&quot;rdx&quot;) : raise
-            else
-                raise
</del><ins>+        else
+            case name
+            when &quot;t0&quot;, &quot;r0&quot;, &quot;a2&quot;
+                &quot;eax&quot;
+            when &quot;t1&quot;, &quot;r1&quot;, &quot;a1&quot;
+                &quot;edx&quot;
+            when &quot;t2&quot;, &quot;a0&quot;
+                &quot;ecx&quot;
+            when &quot;t3&quot;, &quot;a3&quot;
+                &quot;ebx&quot;
+            when &quot;t4&quot;
+                &quot;esi&quot;
+            when &quot;t5&quot;
+                &quot;edi&quot;
+            when &quot;cfr&quot;
+                &quot;ebp&quot;
+            when &quot;sp&quot;
+                &quot;esp&quot;
</ins><span class="cx">             end
</span><del>-        when &quot;t2&quot;
-            case kind
-            when :byte
-                register(&quot;cl&quot;)
-            when :half
-                register(&quot;cx&quot;)
-            when :int
-                register(&quot;ecx&quot;)
-            when :ptr
-                isX64 ? register(&quot;rcx&quot;) : register(&quot;ecx&quot;)
-            when :quad
-                isX64 ? register(&quot;rcx&quot;) : raise
-            else
-                raise
-            end
-        when &quot;t3&quot;
-            case kind
-            when :byte
-                register(&quot;bl&quot;)
-            when :half
-                register(&quot;bx&quot;)
-            when :int
-                register(&quot;ebx&quot;)
-            when :ptr
-                isX64 ? register(&quot;rbx&quot;) : register(&quot;ebx&quot;)
-            when :quad
-                isX64 ? register(&quot;rbx&quot;) : raise
-            else
-                raise
-            end
-        when &quot;t4&quot;
-            case kind
-            when :byte
-                register(&quot;dil&quot;)
-            when :half
-                register(&quot;di&quot;)
-            when :int
-                register(&quot;edi&quot;)
-            when :ptr
-                isX64 ? register(&quot;rdi&quot;) : register(&quot;edi&quot;)
-            when :quad
-                isX64 ? register(&quot;rdi&quot;) : raise
-            else
-                raise
-            end
-        when &quot;cfr&quot;
-            if isX64
-                case kind
-                when :half
-                    register(&quot;bp&quot;)
-                when :int
-                    register(&quot;ebp&quot;)
-                when :ptr
-                    register(&quot;rbp&quot;)
-                when :quad
-                    register(&quot;rbp&quot;)
-                else
-                    raise
-                end
-            else
-                case kind
-                when :half
-                    register(&quot;bp&quot;)
-                when :int
-                    register(&quot;ebp&quot;)
-                when :ptr
-                    register(&quot;ebp&quot;)
-                else
-                    raise
-                end
-            end
-        when &quot;sp&quot;
-            case kind
-            when :byte
-                register(&quot;spl&quot;)
-            when :half
-                register(&quot;sp&quot;)
-            when :int
-                register(&quot;esp&quot;)
-            when :ptr
-                isX64 ? register(&quot;rsp&quot;) : register(&quot;esp&quot;)
-            when :quad
-                isX64 ? register(&quot;rsp&quot;) : raise
-            else
-                raise
-            end
-        when &quot;t5&quot;
-            case kind
-            when :byte
-                register(&quot;sil&quot;)
-            when :half
-                register(&quot;si&quot;)
-            when :int
-                register(&quot;esi&quot;)
-            when :ptr
-                isX64 ? register(&quot;rsi&quot;) : register(&quot;esi&quot;)
-            when :quad
-                isX64 ? register(&quot;rsi&quot;) : raise
-            end
-        when &quot;t6&quot;
-            raise &quot;Cannot use #{name} in 32-bit X86 at #{codeOriginString}&quot; unless isX64
-            case kind
-            when :half
-                register(&quot;r8w&quot;)
-            when :int
-                register(&quot;r8d&quot;)
-            when :ptr
-                register(&quot;r8&quot;)
-            when :quad
-                register(&quot;r8&quot;)
-            end
-        when &quot;t7&quot;
-            raise &quot;Cannot use #{name} in 32-bit X86 at #{codeOriginString}&quot; unless isX64
-            case kind
-            when :half
-                register(&quot;r9w&quot;)
-            when :int
-                register(&quot;r9d&quot;)
-            when :ptr
-                register(&quot;r9&quot;)
-            when :quad
-                register(&quot;r9&quot;)
-            end
-        when &quot;csr1&quot;
-            raise &quot;Cannot use #{name} in 32-bit X86 at #{codeOriginString}&quot; unless isX64
-            case kind
-            when :half
-                register(&quot;r14w&quot;)
-            when :int
-                register(&quot;r14d&quot;)
-            when :ptr
-                register(&quot;r14&quot;)
-            when :quad
-                register(&quot;r14&quot;)
-            end
-        when &quot;csr2&quot;
-            raise &quot;Cannot use #{name} in 32-bit X86 at #{codeOriginString}&quot; unless isX64
-            case kind
-            when :half
-                register(&quot;r15w&quot;)
-            when :int
-                register(&quot;r15d&quot;)
-            when :ptr
-                register(&quot;r15&quot;)
-            when :quad
-                register(&quot;r15&quot;)
-            end
-        else
-            raise &quot;Bad register #{name} for X86 at #{codeOriginString}&quot;
</del><span class="cx">         end
</span><span class="cx">     end
</span><ins>+
+    def x86Operand(kind)
+        x86GPRName(x86GPR, kind)
+    end
+
</ins><span class="cx">     def x86CallOperand(kind)
</span><del>-        isX64 ? &quot;#{callPrefix}#{x86Operand(:quad)}&quot; : &quot;#{callPrefix}#{x86Operand(:ptr)}&quot;
</del><ins>+        &quot;#{callPrefix}#{x86Operand(:ptr)}&quot;
</ins><span class="cx">     end
</span><span class="cx"> end
</span><span class="cx"> 
</span><span class="lines">@@ -597,13 +596,12 @@
</span><span class="cx">     end
</span><span class="cx">     
</span><span class="cx">     def handleX86Shift(opcode, kind)
</span><del>-        if operands[0].is_a? Immediate or operands[0] == RegisterID.forName(nil, &quot;t2&quot;)
</del><ins>+        if operands[0].is_a? Immediate or operands[0].x86GPR == &quot;ecx&quot;
</ins><span class="cx">             $asm.puts &quot;#{opcode} #{orderOperands(operands[0].x86Operand(:byte), operands[1].x86Operand(kind))}&quot;
</span><span class="cx">         else
</span><del>-            cx = RegisterID.forName(nil, &quot;t2&quot;)
-            $asm.puts &quot;xchg#{x86Suffix(:ptr)} #{operands[0].x86Operand(:ptr)}, #{cx.x86Operand(:ptr)}&quot;
</del><ins>+            $asm.puts &quot;xchg#{x86Suffix(:ptr)} #{operands[0].x86Operand(:ptr)}, #{x86GPRName(&quot;ecx&quot;, :ptr)}&quot;
</ins><span class="cx">             $asm.puts &quot;#{opcode} #{orderOperands(register(&quot;cl&quot;), operands[1].x86Operand(kind))}&quot;
</span><del>-            $asm.puts &quot;xchg#{x86Suffix(:ptr)} #{operands[0].x86Operand(:ptr)}, #{cx.x86Operand(:ptr)}&quot;
</del><ins>+            $asm.puts &quot;xchg#{x86Suffix(:ptr)} #{operands[0].x86Operand(:ptr)}, #{x86GPRName(&quot;ecx&quot;, :ptr)}&quot;
</ins><span class="cx">         end
</span><span class="cx">     end
</span><span class="cx">     
</span><span class="lines">@@ -647,10 +645,14 @@
</span><span class="cx">                 $asm.puts &quot;movzx #{orderOperands(operand.x86Operand(:byte), operand.x86Operand(:int))}&quot;
</span><span class="cx">             end
</span><span class="cx">         else
</span><del>-            ax = RegisterID.new(nil, &quot;t0&quot;)
</del><ins>+            ax = RegisterID.new(nil, &quot;r0&quot;)
</ins><span class="cx">             $asm.puts &quot;xchg#{x86Suffix(:ptr)} #{operand.x86Operand(:ptr)}, #{ax.x86Operand(:ptr)}&quot;
</span><del>-            $asm.puts &quot;#{setOpcode} %al&quot;
-            $asm.puts &quot;movzbl %al, %eax&quot;
</del><ins>+            $asm.puts &quot;#{setOpcode} #{ax.x86Operand(:byte)}&quot;
+            if !isIntelSyntax
+                $asm.puts &quot;movzbl #{ax.x86Operand(:byte)}, #{ax.x86Operand(:int)}&quot;
+            else
+                $asm.puts &quot;movzx #{ax.x86Operand(:int)}, #{ax.x86Operand(:byte)}&quot;
+            end
</ins><span class="cx">             $asm.puts &quot;xchg#{x86Suffix(:ptr)} #{operand.x86Operand(:ptr)}, #{ax.x86Operand(:ptr)}&quot;
</span><span class="cx">         end
</span><span class="cx">     end
</span></span></pre>
</div>
</div>

</body>
</html>