<!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>[162705] branches/jsCStack/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/162705">162705</a></dd>
<dt>Author</dt> <dd>msaboff@apple.com</dd>
<dt>Date</dt> <dd>2014-01-24 10:06:47 -0800 (Fri, 24 Jan 2014)</dd>
</dl>

<h3>Log Message</h3>
<pre>CStack Branch: Get ARM working
https://bugs.webkit.org/show_bug.cgi?id=127510

Reviewed by Geoffrey Garen.

Fixed nativeCallTrampoline in the LLInt to account for the prior changes made for running on the
C stack.

Updated maxFrameExtentForSlowPathCall to take into account the stack aligning that needs
to happen as well.

In LowLevelInterpreter.asm::callToJavaScriptPrologue() for 32 bit variants of ARM,
we align the stack to a 16 byte boundary since the ARM calling convention allows any
4 byte alignment.  Added code in callToJavaScriptEpilogue() to restore the unaligned
stack pointer before returning.

Added pop and push register list opcodes to ARMv7 assember and added popPair and pushPair in the
ARMv7 macro assembler for use saving and restoring lr &amp; fp.  Also add the ARM only &quot;clrbp&quot;
(stands for clear bits for pointer) that maps to the bic (bit clear) instruction used to
align the stack.

Fixed ARMv7 add instructions where the destination is the stack pointer.  Some instructions
only allow the &quot;Rn&quot; source to be the stack pointer.  In those cases, the source register is
moved into the stack pointer and then an &quot;add sp, ...&quot; or &quot;add sp, sp, ...&quot; instruction is used.

Fixed the test32 macro instruction handle the case where we want to test the stack pointer.
The instruction set doesn't allow that directly, so we move the stack pointer into a temp
register first.

Reviewed by Geoffrey Garen.

* assembler/ARMv7Assembler.h:
(JSC::ARMv7Assembler::add):
(JSC::ARMv7Assembler::pop):
(JSC::ARMv7Assembler::push):
(JSC::ARMv7Assembler::ARMInstructionFormatter::twoWordOp16Imm16):
* assembler/MacroAssemblerARMv7.h:
(JSC::MacroAssemblerARMv7::add32):
(JSC::MacroAssemblerARMv7::popPair):
(JSC::MacroAssemblerARMv7::pushPair):
(JSC::MacroAssemblerARMv7::test32):
* assembler/MaxFrameExtentForSlowPathCall.h:
* llint/LLIntData.cpp:
(JSC::LLInt::Data::performAssertions):
* llint/LowLevelInterpreter.asm:
* llint/LowLevelInterpreter32_64.asm:
* offlineasm/arm.rb:
* offlineasm/instructions.rb:</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#branchesjsCStackSourceJavaScriptCoreChangeLog">branches/jsCStack/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#branchesjsCStackSourceJavaScriptCoreassemblerARMv7Assemblerh">branches/jsCStack/Source/JavaScriptCore/assembler/ARMv7Assembler.h</a></li>
<li><a href="#branchesjsCStackSourceJavaScriptCoreassemblerMacroAssemblerARMv7h">branches/jsCStack/Source/JavaScriptCore/assembler/MacroAssemblerARMv7.h</a></li>
<li><a href="#branchesjsCStackSourceJavaScriptCoreassemblerMaxFrameExtentForSlowPathCallh">branches/jsCStack/Source/JavaScriptCore/assembler/MaxFrameExtentForSlowPathCall.h</a></li>
<li><a href="#branchesjsCStackSourceJavaScriptCorellintLLIntDatacpp">branches/jsCStack/Source/JavaScriptCore/llint/LLIntData.cpp</a></li>
<li><a href="#branchesjsCStackSourceJavaScriptCorellintLowLevelInterpreterasm">branches/jsCStack/Source/JavaScriptCore/llint/LowLevelInterpreter.asm</a></li>
<li><a href="#branchesjsCStackSourceJavaScriptCorellintLowLevelInterpreter32_64asm">branches/jsCStack/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm</a></li>
<li><a href="#branchesjsCStackSourceJavaScriptCoreofflineasmarmrb">branches/jsCStack/Source/JavaScriptCore/offlineasm/arm.rb</a></li>
<li><a href="#branchesjsCStackSourceJavaScriptCoreofflineasminstructionsrb">branches/jsCStack/Source/JavaScriptCore/offlineasm/instructions.rb</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="branchesjsCStackSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/JavaScriptCore/ChangeLog (162704 => 162705)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/ChangeLog        2014-01-24 17:49:54 UTC (rev 162704)
+++ branches/jsCStack/Source/JavaScriptCore/ChangeLog        2014-01-24 18:06:47 UTC (rev 162705)
</span><span class="lines">@@ -1,5 +1,56 @@
</span><span class="cx"> 2014-01-24  Michael Saboff  &lt;msaboff@apple.com&gt;
</span><span class="cx"> 
</span><ins>+        CStack Branch: Get ARM working
+        https://bugs.webkit.org/show_bug.cgi?id=127510
+
+        Reviewed by Geoffrey Garen.
+
+        Fixed nativeCallTrampoline in the LLInt to account for the prior changes made for running on the
+        C stack.
+
+        Updated maxFrameExtentForSlowPathCall to take into account the stack aligning that needs
+        to happen as well.
+
+        In LowLevelInterpreter.asm::callToJavaScriptPrologue() for 32 bit variants of ARM,
+        we align the stack to a 16 byte boundary since the ARM calling convention allows any
+        4 byte alignment.  Added code in callToJavaScriptEpilogue() to restore the unaligned
+        stack pointer before returning.
+
+        Added pop and push register list opcodes to ARMv7 assember and added popPair and pushPair in the
+        ARMv7 macro assembler for use saving and restoring lr &amp; fp.  Also add the ARM only &quot;clrbp&quot;
+        (stands for clear bits for pointer) that maps to the bic (bit clear) instruction used to
+        align the stack.
+
+        Fixed ARMv7 add instructions where the destination is the stack pointer.  Some instructions
+        only allow the &quot;Rn&quot; source to be the stack pointer.  In those cases, the source register is
+        moved into the stack pointer and then an &quot;add sp, ...&quot; or &quot;add sp, sp, ...&quot; instruction is used.
+
+        Fixed the test32 macro instruction handle the case where we want to test the stack pointer.
+        The instruction set doesn't allow that directly, so we move the stack pointer into a temp
+        register first.
+
+        Reviewed by Geoffrey Garen.
+
+        * assembler/ARMv7Assembler.h:
+        (JSC::ARMv7Assembler::add):
+        (JSC::ARMv7Assembler::pop):
+        (JSC::ARMv7Assembler::push):
+        (JSC::ARMv7Assembler::ARMInstructionFormatter::twoWordOp16Imm16):
+        * assembler/MacroAssemblerARMv7.h:
+        (JSC::MacroAssemblerARMv7::add32):
+        (JSC::MacroAssemblerARMv7::popPair):
+        (JSC::MacroAssemblerARMv7::pushPair):
+        (JSC::MacroAssemblerARMv7::test32):
+        * assembler/MaxFrameExtentForSlowPathCall.h:
+        * llint/LLIntData.cpp:
+        (JSC::LLInt::Data::performAssertions):
+        * llint/LowLevelInterpreter.asm:
+        * llint/LowLevelInterpreter32_64.asm:
+        * offlineasm/arm.rb:
+        * offlineasm/instructions.rb:
+
+2014-01-24  Michael Saboff  &lt;msaboff@apple.com&gt;
+
</ins><span class="cx">         Merge trunk change set r162701.
</span><span class="cx"> 
</span><span class="cx"> 2014-01-23  Mark Hahnenberg  &lt;mhahnenberg@apple.com&gt;
</span></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCoreassemblerARMv7Assemblerh"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/JavaScriptCore/assembler/ARMv7Assembler.h (162704 => 162705)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/assembler/ARMv7Assembler.h        2014-01-24 17:49:54 UTC (rev 162704)
+++ branches/jsCStack/Source/JavaScriptCore/assembler/ARMv7Assembler.h        2014-01-24 18:06:47 UTC (rev 162705)
</span><span class="lines">@@ -654,6 +654,8 @@
</span><span class="cx">     typedef enum {
</span><span class="cx">         OP_B_T1         = 0xD000,
</span><span class="cx">         OP_B_T2         = 0xE000,
</span><ins>+        OP_POP_T2       = 0xE8BD,
+        OP_PUSH_T2      = 0xE92D,
</ins><span class="cx">         OP_AND_reg_T2   = 0xEA00,
</span><span class="cx">         OP_TST_reg_T2   = 0xEA10,
</span><span class="cx">         OP_ORR_reg_T2   = 0xEA40,
</span><span class="lines">@@ -894,6 +896,11 @@
</span><span class="cx">     // NOTE: In an IT block, add doesn't modify the flags register.
</span><span class="cx">     ALWAYS_INLINE void add(RegisterID rd, RegisterID rn, RegisterID rm)
</span><span class="cx">     {
</span><ins>+        if (rd == ARMRegisters::sp) {
+            mov(rd, rn);
+            rn = rd;
+        }
+
</ins><span class="cx">         if (rd == rn)
</span><span class="cx">             m_formatter.oneWordOp8RegReg143(OP_ADD_reg_T2, rm, rd);
</span><span class="cx">         else if (rd == rm)
</span><span class="lines">@@ -1488,6 +1495,22 @@
</span><span class="cx">         m_formatter.twoWordOp12Reg4FourFours(OP_ROR_reg_T2, rn, FourFours(0xf, rd, 0, rm));
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    ALWAYS_INLINE void pop(uint32_t registerList)
+    {
+        ASSERT(WTF::bitCount(registerList) &gt; 1);
+        ASSERT(!((1 &lt;&lt; ARMRegisters::pc) &amp; registerList) || !((1 &lt;&lt; ARMRegisters::lr) &amp; registerList));
+        ASSERT(!((1 &lt;&lt; ARMRegisters::sp) &amp; registerList));
+        m_formatter.twoWordOp16Imm16(OP_POP_T2, registerList);
+    }
+
+    ALWAYS_INLINE void push(uint32_t registerList)
+    {
+        ASSERT(WTF::bitCount(registerList) &gt; 1);
+        ASSERT(!((1 &lt;&lt; ARMRegisters::pc) &amp; registerList));
+        ASSERT(!((1 &lt;&lt; ARMRegisters::sp) &amp; registerList));
+        m_formatter.twoWordOp16Imm16(OP_PUSH_T2, registerList);
+    }
+
</ins><span class="cx"> #if CPU(APPLE_ARMV7S)
</span><span class="cx">     ALWAYS_INLINE void sdiv(RegisterID rd, RegisterID rn, RegisterID rm)
</span><span class="cx">     {
</span><span class="lines">@@ -2791,6 +2814,12 @@
</span><span class="cx">             m_buffer.putShort(op2);
</span><span class="cx">         }
</span><span class="cx"> 
</span><ins>+        ALWAYS_INLINE void twoWordOp16Imm16(OpcodeID1 op1, uint16_t imm)
+        {
+            m_buffer.putShort(op1);
+            m_buffer.putShort(imm);
+        }
+        
</ins><span class="cx">         ALWAYS_INLINE void twoWordOp5i6Imm4Reg4EncodedImm(OpcodeID1 op, int imm4, RegisterID rd, ARMThumbImmediate imm)
</span><span class="cx">         {
</span><span class="cx">             ARMThumbImmediate newImm = imm;
</span></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCoreassemblerMacroAssemblerARMv7h"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/JavaScriptCore/assembler/MacroAssemblerARMv7.h (162704 => 162705)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/assembler/MacroAssemblerARMv7.h        2014-01-24 17:49:54 UTC (rev 162704)
+++ branches/jsCStack/Source/JavaScriptCore/assembler/MacroAssemblerARMv7.h        2014-01-24 18:06:47 UTC (rev 162705)
</span><span class="lines">@@ -170,6 +170,14 @@
</span><span class="cx">     void add32(TrustedImm32 imm, RegisterID src, RegisterID dest)
</span><span class="cx">     {
</span><span class="cx">         ARMThumbImmediate armImm = ARMThumbImmediate::makeUInt12OrEncodedImm(imm.m_value);
</span><ins>+
+        // For adds with stack pointer destination, moving the src first to sp is
+        // needed to avoid unpredictable instruction
+        if (dest == ARMRegisters::sp &amp;&amp; src != dest) {
+            move(src, ARMRegisters::sp);
+            src = ARMRegisters::sp;
+        }
+
</ins><span class="cx">         if (armImm.isValid())
</span><span class="cx">             m_assembler.add(dest, src, armImm);
</span><span class="cx">         else {
</span><span class="lines">@@ -1160,6 +1168,16 @@
</span><span class="cx">         push(dataTempRegister);
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    void popPair(RegisterID dest1, RegisterID dest2)
+    {
+        m_assembler.pop(1 &lt;&lt; dest1 | 1 &lt;&lt; dest2);
+    }
+    
+    void pushPair(RegisterID src1, RegisterID src2)
+    {
+        m_assembler.push(1 &lt;&lt; src1 | 1 &lt;&lt; src2);
+    }
+    
</ins><span class="cx">     // Register move operations:
</span><span class="cx">     //
</span><span class="cx">     // Move values in registers.
</span><span class="lines">@@ -1281,11 +1299,19 @@
</span><span class="cx">             m_assembler.tst(reg, reg);
</span><span class="cx">         else {
</span><span class="cx">             ARMThumbImmediate armImm = ARMThumbImmediate::makeEncodedImm(imm);
</span><del>-            if (armImm.isValid())
-                m_assembler.tst(reg, armImm);
-            else {
</del><ins>+            if (armImm.isValid()) {
+                if (reg == ARMRegisters::sp) {
+                    move(reg, addressTempRegister);
+                    m_assembler.tst(addressTempRegister, armImm);
+                } else
+                    m_assembler.tst(reg, armImm);
+            } else {
</ins><span class="cx">                 move(mask, dataTempRegister);
</span><del>-                m_assembler.tst(reg, dataTempRegister);
</del><ins>+                if (reg == ARMRegisters::sp) {
+                    move(reg, addressTempRegister);
+                    m_assembler.tst(addressTempRegister, dataTempRegister);
+                } else
+                    m_assembler.tst(reg, dataTempRegister);
</ins><span class="cx">             }
</span><span class="cx">         }
</span><span class="cx">     }
</span></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCoreassemblerMaxFrameExtentForSlowPathCallh"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/JavaScriptCore/assembler/MaxFrameExtentForSlowPathCall.h (162704 => 162705)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/assembler/MaxFrameExtentForSlowPathCall.h        2014-01-24 17:49:54 UTC (rev 162704)
+++ branches/jsCStack/Source/JavaScriptCore/assembler/MaxFrameExtentForSlowPathCall.h        2014-01-24 18:06:47 UTC (rev 162705)
</span><span class="lines">@@ -58,11 +58,11 @@
</span><span class="cx"> 
</span><span class="cx"> #elif CPU(ARM)
</span><span class="cx"> // First four args in registers, remaining 4 args on stack.
</span><del>-static const size_t maxFrameExtentForSlowPathCall = 16;
</del><ins>+static const size_t maxFrameExtentForSlowPathCall = 24;
</ins><span class="cx"> 
</span><span class="cx"> #elif CPU(SH4)
</span><span class="cx"> // First four args in registers, remaining 4 args on stack.
</span><del>-static const size_t maxFrameExtentForSlowPathCall = 16;
</del><ins>+static const size_t maxFrameExtentForSlowPathCall = 24;
</ins><span class="cx"> 
</span><span class="cx"> #elif CPU(MIPS)
</span><span class="cx"> // Though args are in registers, there need to be space on the stack for all args.
</span></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCorellintLLIntDatacpp"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/JavaScriptCore/llint/LLIntData.cpp (162704 => 162705)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/llint/LLIntData.cpp        2014-01-24 17:49:54 UTC (rev 162704)
+++ branches/jsCStack/Source/JavaScriptCore/llint/LLIntData.cpp        2014-01-24 18:06:47 UTC (rev 162705)
</span><span class="lines">@@ -128,7 +128,7 @@
</span><span class="cx"> #if CPU(X86_64) || CPU(ARM64) || ENABLE(LLINT_C_LOOP)
</span><span class="cx">     ASSERT(maxFrameExtentForSlowPathCall == 0);
</span><span class="cx"> #elif CPU(ARM) || CPU(SH4)
</span><del>-    ASSERT(maxFrameExtentForSlowPathCall == 16);
</del><ins>+    ASSERT(maxFrameExtentForSlowPathCall == 24);
</ins><span class="cx"> #elif CPU(X86) || CPU(MIPS)
</span><span class="cx">     ASSERT(maxFrameExtentForSlowPathCall == 40);
</span><span class="cx"> #endif
</span></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCorellintLowLevelInterpreterasm"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/JavaScriptCore/llint/LowLevelInterpreter.asm (162704 => 162705)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/llint/LowLevelInterpreter.asm        2014-01-24 17:49:54 UTC (rev 162704)
+++ branches/jsCStack/Source/JavaScriptCore/llint/LowLevelInterpreter.asm        2014-01-24 18:06:47 UTC (rev 162705)
</span><span class="lines">@@ -77,7 +77,7 @@
</span><span class="cx"> if X86_64 or ARM64 or C_LOOP
</span><span class="cx"> const maxFrameExtentForSlowPathCall = 0
</span><span class="cx"> elsif ARM or ARMv7_TRADITIONAL or ARMv7 or SH4
</span><del>-const maxFrameExtentForSlowPathCall = 16
</del><ins>+const maxFrameExtentForSlowPathCall = 24
</ins><span class="cx"> elsif X86
</span><span class="cx"> const maxFrameExtentForSlowPathCall = 40
</span><span class="cx"> elsif MIPS
</span><span class="lines">@@ -229,7 +229,13 @@
</span><span class="cx">         # C_LOOP does not need the alignment, and can use a little perf
</span><span class="cx">         # improvement from avoiding useless work.
</span><span class="cx">     else
</span><del>-        andp sp, 0xf, tempReg
</del><ins>+        if ARM or ARMv7 or ARMv7_TRADITIONAL
+            # ARM can't do logical ops with the sp as a source
+            move sp, tempReg
+            andp 0xf, tempReg
+        else
+            andp sp, 0xf, tempReg
+        end
</ins><span class="cx">         btpz tempReg, .stackPointerOkay
</span><span class="cx">         move location, tempReg
</span><span class="cx">         break
</span><span class="lines">@@ -323,6 +329,12 @@
</span><span class="cx">     pushCalleeSaves
</span><span class="cx">     if X86
</span><span class="cx">         subp 12, sp
</span><ins>+    elsif ARM or ARMv7 or ARMv7_TRADITIONAL
+        subp 4, sp
+        move sp, t4
+        clrbp t4, 0xf, t5
+        move t5, sp
+        storep t4, [sp]
</ins><span class="cx">     end
</span><span class="cx"> end
</span><span class="cx"> 
</span><span class="lines">@@ -332,6 +344,10 @@
</span><span class="cx"> 
</span><span class="cx">     if X86
</span><span class="cx">         addp 12, sp
</span><ins>+    elsif ARM or ARMv7 or ARMv7_TRADITIONAL
+        pop t4
+        move t4, sp
+        addp 4, sp
</ins><span class="cx">     end
</span><span class="cx"> 
</span><span class="cx">     popCalleeSaves
</span></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCorellintLowLevelInterpreter32_64asm"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm (162704 => 162705)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm        2014-01-24 17:49:54 UTC (rev 162704)
+++ branches/jsCStack/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm        2014-01-24 18:06:47 UTC (rev 162705)
</span><span class="lines">@@ -2176,13 +2176,11 @@
</span><span class="cx">         loadp MarkedBlock::m_weakSet + WeakSet::m_vm[t3], t3
</span><span class="cx">         addp 8, sp
</span><span class="cx">     elsif ARM or ARMv7 or ARMv7_TRADITIONAL or C_LOOP or MIPS or SH4
</span><ins>+        subp 8, sp # align stack pointer
</ins><span class="cx">         # t1 already contains the ScopeChain.
</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>-        move t0, t2 # t0 contains callerFrame
-        preserveReturnAddressAfterCall(t3)
-        storep t3, ReturnPC[cfr]
</del><span class="cx">         if MIPS or SH4
</span><span class="cx">             move cfr, a0
</span><span class="cx">         else
</span><span class="lines">@@ -2190,16 +2188,16 @@
</span><span class="cx">         end
</span><span class="cx">         loadi Callee + PayloadOffset[cfr], t1
</span><span class="cx">         loadp JSFunction::m_executable[t1], t1
</span><del>-        move t2, cfr
</del><ins>+        checkStackPointerAlignment(t3, 0xdead0001)
</ins><span class="cx">         if C_LOOP
</span><span class="cx">             cloopCallNative executableOffsetToFunction[t1]
</span><span class="cx">         else
</span><span class="cx">             call executableOffsetToFunction[t1]
</span><span class="cx">         end
</span><del>-        restoreReturnAddressBeforeReturn(t3)
</del><span class="cx">         loadp ScopeChain[cfr], t3
</span><span class="cx">         andp MarkedBlockMask, t3
</span><span class="cx">         loadp MarkedBlock::m_weakSet + WeakSet::m_vm[t3], t3
</span><ins>+        addp 8, sp
</ins><span class="cx">     else
</span><span class="cx">         error
</span><span class="cx">     end
</span></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCoreofflineasmarmrb"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/JavaScriptCore/offlineasm/arm.rb (162704 => 162705)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/offlineasm/arm.rb        2014-01-24 17:49:54 UTC (rev 162704)
+++ branches/jsCStack/Source/JavaScriptCore/offlineasm/arm.rb        2014-01-24 18:06:47 UTC (rev 162705)
</span><span class="lines">@@ -601,6 +601,8 @@
</span><span class="cx">             $asm.puts &quot;smull #{operands[2].armOperand}, #{operands[3].armOperand}, #{operands[0].armOperand}, #{operands[1].armOperand}&quot;
</span><span class="cx">         when &quot;memfence&quot;
</span><span class="cx">             $asm.puts &quot;dmb sy&quot;
</span><ins>+        when &quot;clrbp&quot;
+            $asm.puts &quot;bic #{operands[2].armOperand}, #{operands[0].armOperand}, #{operands[1].armOperand}&quot;
</ins><span class="cx">         else
</span><span class="cx">             lowerDefault
</span><span class="cx">         end
</span></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCoreofflineasminstructionsrb"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/JavaScriptCore/offlineasm/instructions.rb (162704 => 162705)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/offlineasm/instructions.rb        2014-01-24 17:49:54 UTC (rev 162704)
+++ branches/jsCStack/Source/JavaScriptCore/offlineasm/instructions.rb        2014-01-24 18:06:47 UTC (rev 162705)
</span><span class="lines">@@ -258,6 +258,11 @@
</span><span class="cx">      &quot;idivi&quot;
</span><span class="cx">     ]
</span><span class="cx"> 
</span><ins>+ARM_INSTRUCTIONS =
+    [
+     &quot;clrbp&quot;
+    ]
+
</ins><span class="cx"> ARM64_INSTRUCTIONS =
</span><span class="cx">     [
</span><span class="cx">      &quot;popLRAndFP&quot;,   # ARM64 requires registers to be pushed and popped in pairs,
</span><span class="lines">@@ -313,7 +318,7 @@
</span><span class="cx">      &quot;cloopDo&quot;,              # no operands
</span><span class="cx">     ]
</span><span class="cx"> 
</span><del>-INSTRUCTIONS = MACRO_INSTRUCTIONS + X86_INSTRUCTIONS + ARM64_INSTRUCTIONS + RISC_INSTRUCTIONS + MIPS_INSTRUCTIONS + SH4_INSTRUCTIONS + CXX_INSTRUCTIONS
</del><ins>+INSTRUCTIONS = MACRO_INSTRUCTIONS + X86_INSTRUCTIONS + ARM_INSTRUCTIONS + ARM64_INSTRUCTIONS + RISC_INSTRUCTIONS + MIPS_INSTRUCTIONS + SH4_INSTRUCTIONS + CXX_INSTRUCTIONS
</ins><span class="cx"> 
</span><span class="cx"> INSTRUCTION_PATTERN = Regexp.new('\\A((' + INSTRUCTIONS.join(')|(') + '))\\Z')
</span><span class="cx"> 
</span></span></pre>
</div>
</div>

</body>
</html>