<!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>[161318] 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/161318">161318</a></dd>
<dt>Author</dt> <dd>msaboff@apple.com</dd>
<dt>Date</dt> <dd>2014-01-04 23:29:27 -0800 (Sat, 04 Jan 2014)</dd>
</dl>

<h3>Log Message</h3>
<pre>CStack Branch: ARM64 needs push/pop pair macro assembler instructions
https://bugs.webkit.org/show_bug.cgi?id=126474

Reviewed by Mark Lam.

Added templated ldp() and stp() instruction generators to the ARM64 assembler.
Added popPair() and pushPair() to the ARM64 macro assembler.  Added ARM64
version of emitFunctionPrologue() and emitFunctionEpilogue() to AssemblyHelpers.h
that use the pushPair() and popPair() macro instructions.  Added disassembler support
for the newly added load/store pair instructions.

Verified that we correctly generate the new instructions and that they disassemble
the same as what the debugger shows.

* assembler/ARM64Assembler.h:
(JSC::isInt7):
(JSC::isInt11):
(JSC::PairPostIndex::PairPostIndex):
(JSC::PairPostIndex::operator int):
(JSC::PairPreIndex::PairPreIndex):
(JSC::PairPreIndex::operator int):
(JSC::ARM64Assembler::memPairOffsetShift):
(JSC::ARM64Assembler::ldp):
(JSC::ARM64Assembler::stp):
(JSC::ARM64Assembler::loadStoreRegisterPairPostIndex):
(JSC::ARM64Assembler::loadStoreRegisterPairPreIndex):
* assembler/MacroAssemblerARM64.h:
(JSC::MacroAssemblerARM64::popPair):
(JSC::MacroAssemblerARM64::pushPair):
* disassembler/ARM64/A64DOpcode.cpp:
(JSC::ARM64Disassembler::A64DOpcode::appendRegisterName):
(JSC::ARM64Disassembler::A64DOpcodeLoadStoreRegisterPair::opName):
(JSC::ARM64Disassembler::A64DOpcodeLoadStoreRegisterPair::format):
* disassembler/ARM64/A64DOpcode.h:
(JSC::ARM64Disassembler::A64DOpcodeLoadStoreRegisterPair::rt2):
(JSC::ARM64Disassembler::A64DOpcodeLoadStoreRegisterPair::immediate7):
(JSC::ARM64Disassembler::A64DOpcodeLoadStoreRegisterPair::offsetMode):
(JSC::ARM64Disassembler::A64DOpcodeLoadStoreRegisterPair::lBit):
* jit/AssemblyHelpers.h:
(JSC::AssemblyHelpers::emitFunctionPrologue):
(JSC::AssemblyHelpers::emitFunctionEpilogue):</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#branchesjsCStackSourceJavaScriptCoreChangeLog">branches/jsCStack/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#branchesjsCStackSourceJavaScriptCoreassemblerARM64Assemblerh">branches/jsCStack/Source/JavaScriptCore/assembler/ARM64Assembler.h</a></li>
<li><a href="#branchesjsCStackSourceJavaScriptCoreassemblerMacroAssemblerARM64h">branches/jsCStack/Source/JavaScriptCore/assembler/MacroAssemblerARM64.h</a></li>
<li><a href="#branchesjsCStackSourceJavaScriptCoredisassemblerARM64A64DOpcodecpp">branches/jsCStack/Source/JavaScriptCore/disassembler/ARM64/A64DOpcode.cpp</a></li>
<li><a href="#branchesjsCStackSourceJavaScriptCoredisassemblerARM64A64DOpcodeh">branches/jsCStack/Source/JavaScriptCore/disassembler/ARM64/A64DOpcode.h</a></li>
<li><a href="#branchesjsCStackSourceJavaScriptCorejitAssemblyHelpersh">branches/jsCStack/Source/JavaScriptCore/jit/AssemblyHelpers.h</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="branchesjsCStackSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/JavaScriptCore/ChangeLog (161317 => 161318)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/ChangeLog        2014-01-05 02:15:25 UTC (rev 161317)
+++ branches/jsCStack/Source/JavaScriptCore/ChangeLog        2014-01-05 07:29:27 UTC (rev 161318)
</span><span class="lines">@@ -1,5 +1,49 @@
</span><span class="cx"> 2014-01-04  Michael Saboff  &lt;msaboff@apple.com&gt;
</span><span class="cx"> 
</span><ins>+        CStack Branch: ARM64 needs push/pop pair macro assembler instructions
+        https://bugs.webkit.org/show_bug.cgi?id=126474
+
+        Reviewed by Mark Lam.
+
+        Added templated ldp() and stp() instruction generators to the ARM64 assembler.
+        Added popPair() and pushPair() to the ARM64 macro assembler.  Added ARM64
+        version of emitFunctionPrologue() and emitFunctionEpilogue() to AssemblyHelpers.h
+        that use the pushPair() and popPair() macro instructions.  Added disassembler support
+        for the newly added load/store pair instructions.
+
+        Verified that we correctly generate the new instructions and that they disassemble
+        the same as what the debugger shows.
+
+        * assembler/ARM64Assembler.h:
+        (JSC::isInt7):
+        (JSC::isInt11):
+        (JSC::PairPostIndex::PairPostIndex):
+        (JSC::PairPostIndex::operator int):
+        (JSC::PairPreIndex::PairPreIndex):
+        (JSC::PairPreIndex::operator int):
+        (JSC::ARM64Assembler::memPairOffsetShift):
+        (JSC::ARM64Assembler::ldp):
+        (JSC::ARM64Assembler::stp):
+        (JSC::ARM64Assembler::loadStoreRegisterPairPostIndex):
+        (JSC::ARM64Assembler::loadStoreRegisterPairPreIndex):
+        * assembler/MacroAssemblerARM64.h:
+        (JSC::MacroAssemblerARM64::popPair):
+        (JSC::MacroAssemblerARM64::pushPair):
+        * disassembler/ARM64/A64DOpcode.cpp:
+        (JSC::ARM64Disassembler::A64DOpcode::appendRegisterName):
+        (JSC::ARM64Disassembler::A64DOpcodeLoadStoreRegisterPair::opName):
+        (JSC::ARM64Disassembler::A64DOpcodeLoadStoreRegisterPair::format):
+        * disassembler/ARM64/A64DOpcode.h:
+        (JSC::ARM64Disassembler::A64DOpcodeLoadStoreRegisterPair::rt2):
+        (JSC::ARM64Disassembler::A64DOpcodeLoadStoreRegisterPair::immediate7):
+        (JSC::ARM64Disassembler::A64DOpcodeLoadStoreRegisterPair::offsetMode):
+        (JSC::ARM64Disassembler::A64DOpcodeLoadStoreRegisterPair::lBit):
+        * jit/AssemblyHelpers.h:
+        (JSC::AssemblyHelpers::emitFunctionPrologue):
+        (JSC::AssemblyHelpers::emitFunctionEpilogue):
+
+2014-01-04  Michael Saboff  &lt;msaboff@apple.com&gt;
+
</ins><span class="cx">         CStack Branch: ARM64 add of stack pointer not valid as second source operand
</span><span class="cx">         https://bugs.webkit.org/show_bug.cgi?id=126486
</span><span class="cx"> 
</span></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCoreassemblerARM64Assemblerh"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/JavaScriptCore/assembler/ARM64Assembler.h (161317 => 161318)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/assembler/ARM64Assembler.h        2014-01-05 02:15:25 UTC (rev 161317)
+++ branches/jsCStack/Source/JavaScriptCore/assembler/ARM64Assembler.h        2014-01-05 07:29:27 UTC (rev 161318)
</span><span class="lines">@@ -40,14 +40,26 @@
</span><span class="cx"> #define DATASIZE DATASIZE_OF(datasize)
</span><span class="cx"> #define MEMOPSIZE MEMOPSIZE_OF(datasize)
</span><span class="cx"> #define CHECK_FP_MEMOP_DATASIZE() ASSERT(datasize == 8 || datasize == 16 || datasize == 32 || datasize == 64 || datasize == 128)
</span><ins>+#define MEMPAIROPSIZE_INT(datasize) ((datasize == 64) ? MemPairOp_64 : MemPairOp_32)
+#define MEMPAIROPSIZE_FP(datasize) ((datasize == 128) ? MemPairOp_V128 : (datasize == 64) ? MemPairOp_V64 : MemPairOp_32)
</ins><span class="cx"> 
</span><span class="cx"> namespace JSC {
</span><span class="cx"> 
</span><ins>+ALWAYS_INLINE bool isInt7(int32_t value)
+{
+    return value == ((value &lt;&lt; 25) &gt;&gt; 25);
+}
+
</ins><span class="cx"> ALWAYS_INLINE bool isInt9(int32_t value)
</span><span class="cx"> {
</span><span class="cx">     return value == ((value &lt;&lt; 23) &gt;&gt; 23);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+ALWAYS_INLINE bool isInt11(int32_t value)
+{
+    return value == ((value &lt;&lt; 21) &gt;&gt; 21);
+}
+
</ins><span class="cx"> ALWAYS_INLINE bool isUInt5(int32_t value)
</span><span class="cx"> {
</span><span class="cx">     return !(value &amp; ~0x1f);
</span><span class="lines">@@ -119,6 +131,34 @@
</span><span class="cx">     int m_value;
</span><span class="cx"> };
</span><span class="cx"> 
</span><ins>+class PairPostIndex {
+public:
+    explicit PairPostIndex(int value)
+        : m_value(value)
+    {
+        ASSERT(isInt11(value));
+    }
+
+    operator int() { return m_value; }
+
+private:
+    int m_value;
+};
+
+class PairPreIndex {
+public:
+    explicit PairPreIndex(int value)
+        : m_value(value)
+    {
+        ASSERT(isInt11(value));
+    }
+
+    operator int() { return m_value; }
+
+private:
+    int m_value;
+};
+
</ins><span class="cx"> class LogicalImmediate {
</span><span class="cx"> public:
</span><span class="cx">     static LogicalImmediate create32(uint32_t value)
</span><span class="lines">@@ -823,6 +863,16 @@
</span><span class="cx">         MemOp_LOAD_signed32 = 3 // size may be 0 or 1
</span><span class="cx">     };
</span><span class="cx"> 
</span><ins>+    enum MemPairOpSize {
+        MemPairOp_32 = 0,
+        MemPairOp_LoadSigned_32 = 1,
+        MemPairOp_64 = 2,
+
+        MemPairOp_V32 = MemPairOp_32,
+        MemPairOp_V64 = 1,
+        MemPairOp_V128 = 2
+    };
+
</ins><span class="cx">     enum MoveWideOp {
</span><span class="cx">         MoveWideOp_N = 0,
</span><span class="cx">         MoveWideOp_Z = 2,
</span><span class="lines">@@ -836,6 +886,14 @@
</span><span class="cx">         LdrLiteralOp_128BIT = 2
</span><span class="cx">     };
</span><span class="cx"> 
</span><ins>+    static unsigned memPairOffsetShift(bool V, MemPairOpSize size)
+    {
+        // return the log2 of the size in bytes, e.g. 64 bit size returns 3
+        if (V)
+            return size + 2;
+        return (size &gt;&gt; 1) + 2;
+    }
+
</ins><span class="cx"> public:
</span><span class="cx">     // Integer Instructions:
</span><span class="cx"> 
</span><span class="lines">@@ -1216,6 +1274,20 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     template&lt;int datasize&gt;
</span><ins>+    ALWAYS_INLINE void ldp(RegisterID rt, RegisterID rt2, RegisterID rn, PairPostIndex simm)
+    {
+        CHECK_DATASIZE();
+        insn(loadStoreRegisterPairPostIndex(MEMPAIROPSIZE_INT(datasize), false, MemOp_LOAD, simm, rn, rt, rt2));
+    }
+
+    template&lt;int datasize&gt;
+    ALWAYS_INLINE void ldp(RegisterID rt, RegisterID rt2, RegisterID rn, PairPreIndex simm)
+    {
+        CHECK_DATASIZE();
+        insn(loadStoreRegisterPairPreIndex(MEMPAIROPSIZE_INT(datasize), false, MemOp_LOAD, simm, rn, rt, rt2));
+    }
+
+    template&lt;int datasize&gt;
</ins><span class="cx">     ALWAYS_INLINE void ldr(RegisterID rt, RegisterID rn, RegisterID rm)
</span><span class="cx">     {
</span><span class="cx">         ldr&lt;datasize&gt;(rt, rn, rm, UXTX, 0);
</span><span class="lines">@@ -1748,6 +1820,20 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     template&lt;int datasize&gt;
</span><ins>+    ALWAYS_INLINE void stp(RegisterID rt, RegisterID rt2, RegisterID rn, PairPostIndex simm)
+    {
+        CHECK_DATASIZE();
+        insn(loadStoreRegisterPairPostIndex(MEMPAIROPSIZE_INT(datasize), false, MemOp_STORE, simm, rn, rt, rt2));
+    }
+
+    template&lt;int datasize&gt;
+    ALWAYS_INLINE void stp(RegisterID rt, RegisterID rt2, RegisterID rn, PairPreIndex simm)
+    {
+        CHECK_DATASIZE();
+        insn(loadStoreRegisterPairPreIndex(MEMPAIROPSIZE_INT(datasize), false, MemOp_STORE, simm, rn, rt, rt2));
+    }
+
+    template&lt;int datasize&gt;
</ins><span class="cx">     ALWAYS_INLINE void str(RegisterID rt, RegisterID rn, RegisterID rm)
</span><span class="cx">     {
</span><span class="cx">         str&lt;datasize&gt;(rt, rn, rm, UXTX, 0);
</span><span class="lines">@@ -3361,6 +3447,23 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     // 'V' means vector
</span><ins>+    ALWAYS_INLINE static int loadStoreRegisterPairPostIndex(MemPairOpSize size, bool V, MemOp opc, int immediate, RegisterID rn, FPRegisterID rt, FPRegisterID rt2)
+    {
+        ASSERT(size &lt; 3);
+        ASSERT(opc == (opc &amp; 1)); // Only load or store, load signed 64 is handled via size.
+        ASSERT(V || (size != MemPairOp_LoadSigned_32) || (opc == MemOp_LOAD)); // There isn't an integer store signed.
+        unsigned immedShiftAmount = memPairOffsetShift(V, size);
+        int imm7 = immediate &gt;&gt; immedShiftAmount;
+        ASSERT((imm7 &lt;&lt; immedShiftAmount) == immediate &amp;&amp; isInt7(imm7));
+        return (0x28800000 | size &lt;&lt; 30 | V &lt;&lt; 26 | opc &lt;&lt; 22 | (imm7 &amp; 0x7f) &lt;&lt; 15 | rt2 &lt;&lt; 10 | xOrSp(rn) &lt;&lt; 5 | rt);
+    }
+
+    ALWAYS_INLINE static int loadStoreRegisterPairPostIndex(MemPairOpSize size, bool V, MemOp opc, int immediate, RegisterID rn, RegisterID rt, RegisterID rt2)
+    {
+        return loadStoreRegisterPairPostIndex(size, V, opc, immediate, rn, xOrZrAsFPR(rt), xOrZrAsFPR(rt2));
+    }
+
+    // 'V' means vector
</ins><span class="cx">     ALWAYS_INLINE static int loadStoreRegisterPreIndex(MemOpSize size, bool V, MemOp opc, int imm9, RegisterID rn, FPRegisterID rt)
</span><span class="cx">     {
</span><span class="cx">         ASSERT(!(size &amp;&amp; V &amp;&amp; (opc &amp; 2))); // Maximum vector size is 128 bits.
</span><span class="lines">@@ -3375,6 +3478,23 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     // 'V' means vector
</span><ins>+    ALWAYS_INLINE static int loadStoreRegisterPairPreIndex(MemPairOpSize size, bool V, MemOp opc, int immediate, RegisterID rn, FPRegisterID rt, FPRegisterID rt2)
+    {
+        ASSERT(size &lt; 3);
+        ASSERT(opc == (opc &amp; 1)); // Only load or store, load signed 64 is handled via size.
+        ASSERT(V || (size != MemPairOp_LoadSigned_32) || (opc == MemOp_LOAD)); // There isn't an integer store signed.
+        unsigned immedShiftAmount = memPairOffsetShift(V, size);
+        int imm7 = immediate &gt;&gt; immedShiftAmount;
+        ASSERT((imm7 &lt;&lt; immedShiftAmount) == immediate &amp;&amp; isInt7(imm7));
+        return (0x29800000 | size &lt;&lt; 30 | V &lt;&lt; 26 | opc &lt;&lt; 22 | (imm7 &amp; 0x7f) &lt;&lt; 15 | rt2 &lt;&lt; 10 | xOrSp(rn) &lt;&lt; 5 | rt);
+    }
+
+    ALWAYS_INLINE static int loadStoreRegisterPairPreIndex(MemPairOpSize size, bool V, MemOp opc, int immediate, RegisterID rn, RegisterID rt, RegisterID rt2)
+    {
+        return loadStoreRegisterPairPreIndex(size, V, opc, immediate, rn, xOrZrAsFPR(rt), xOrZrAsFPR(rt2));
+    }
+
+    // 'V' means vector
</ins><span class="cx">     // 'S' means shift rm
</span><span class="cx">     ALWAYS_INLINE static int loadStoreRegisterRegisterOffset(MemOpSize size, bool V, MemOp opc, RegisterID rm, ExtendType option, bool S, RegisterID rn, FPRegisterID rt)
</span><span class="cx">     {
</span></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCoreassemblerMacroAssemblerARM64h"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/JavaScriptCore/assembler/MacroAssemblerARM64.h (161317 => 161318)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/assembler/MacroAssemblerARM64.h        2014-01-05 02:15:25 UTC (rev 161317)
+++ branches/jsCStack/Source/JavaScriptCore/assembler/MacroAssemblerARM64.h        2014-01-05 07:29:27 UTC (rev 161318)
</span><span class="lines">@@ -1427,6 +1427,16 @@
</span><span class="cx">         CRASH();
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    void popPair(RegisterID dest1, RegisterID dest2)
+    {
+        m_assembler.ldp&lt;64&gt;(dest1, dest2, ARM64Registers::sp, PairPostIndex(16));
+    }
+
+    void pushPair(RegisterID src1, RegisterID src2)
+    {
+        m_assembler.stp&lt;64&gt;(src1, src2, ARM64Registers::sp, PairPreIndex(-16));
+    }
+
</ins><span class="cx">     void popToRestore(RegisterID dest)
</span><span class="cx">     {
</span><span class="cx">         m_assembler.ldr&lt;64&gt;(dest, ARM64Registers::sp, PostIndex(16));
</span></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCoredisassemblerARM64A64DOpcodecpp"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/JavaScriptCore/disassembler/ARM64/A64DOpcode.cpp (161317 => 161318)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/disassembler/ARM64/A64DOpcode.cpp        2014-01-05 02:15:25 UTC (rev 161317)
+++ branches/jsCStack/Source/JavaScriptCore/disassembler/ARM64/A64DOpcode.cpp        2014-01-05 07:29:27 UTC (rev 161318)
</span><span class="lines">@@ -62,6 +62,8 @@
</span><span class="cx"> { groupIndex, groupClass::mask, groupClass::pattern, groupClass::format }
</span><span class="cx"> 
</span><span class="cx"> static OpcodeGroupInitializer opcodeGroupList[] = {
</span><ins>+    OPCODE_GROUP_ENTRY(0x08, A64DOpcodeLoadStoreRegisterPair),
+    OPCODE_GROUP_ENTRY(0x09, A64DOpcodeLoadStoreRegisterPair),
</ins><span class="cx">     OPCODE_GROUP_ENTRY(0x0a, A64DOpcodeLogicalShiftedRegister),
</span><span class="cx">     OPCODE_GROUP_ENTRY(0x0b, A64DOpcodeAddSubtractExtendedRegister),
</span><span class="cx">     OPCODE_GROUP_ENTRY(0x0b, A64DOpcodeAddSubtractShiftedRegister),
</span><span class="lines">@@ -172,6 +174,11 @@
</span><span class="cx"> 
</span><span class="cx"> void A64DOpcode::appendRegisterName(unsigned registerNumber, bool is64Bit)
</span><span class="cx"> {
</span><ins>+    if (registerNumber == 29) {
+        bufferPrintf(is64Bit ? &quot;fp&quot; : &quot;wfp&quot;);
+        return;
+    }
+
</ins><span class="cx">     if (registerNumber == 30) {
</span><span class="cx">         bufferPrintf(is64Bit ? &quot;lr&quot; : &quot;wlr&quot;);
</span><span class="cx">         return;
</span><span class="lines">@@ -939,6 +946,63 @@
</span><span class="cx">     return m_formatBuffer;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+const char* A64DOpcodeLoadStoreRegisterPair::opName()
+{
+    if (!vBit() &amp;&amp; lBit() &amp;&amp; size() == 0x1)
+        return &quot;ldpsw&quot;;
+    if (lBit())
+        return &quot;ldp&quot;;
+    return &quot;stp&quot;;
+}
+
+const char* A64DOpcodeLoadStoreRegisterPair::format()
+{
+    const char* thisOpName = opName();
+    
+    if (size() == 0x3)
+        return A64DOpcode::format();
+
+    if ((offsetMode() &lt; 0x1) || (offsetMode() &gt; 0x3))
+        return A64DOpcode::format();
+
+    if ((offsetMode() == 0x1) &amp;&amp; !vBit() &amp;&amp; !lBit())
+        return A64DOpcode::format();
+
+    appendInstructionName(thisOpName);
+    unsigned offsetShift;
+    if (vBit()) {
+        appendFPRegisterName(rt(), size());
+        appendSeparator();
+        appendFPRegisterName(rt2(), size());
+        offsetShift = size() + 2;
+    } else {
+        appendRegisterName(rt(), is64Bit());
+        appendSeparator();
+        appendRegisterName(rt2(), is64Bit());
+        offsetShift = (size() &gt;&gt; 1) + 2;
+    }
+
+    appendSeparator();
+    appendCharacter('[');
+    appendSPOrRegisterName(rn());
+
+    int offset = immediate7() &lt;&lt; offsetShift;
+
+    if (offsetMode() == 1) {
+        appendCharacter(']');
+        appendSeparator();
+        appendSignedImmediate(offset);
+    } else {
+        appendSeparator();
+        appendSignedImmediate(offset);
+        appendCharacter(']');
+        if (offsetMode() == 0x3)
+            appendCharacter('!');
+    }
+
+    return m_formatBuffer;
+}
+
</ins><span class="cx"> const char* A64DOpcodeLoadStoreUnsignedImmediate::format()
</span><span class="cx"> {
</span><span class="cx">     const char* thisOpName = opName();
</span></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCoredisassemblerARM64A64DOpcodeh"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/JavaScriptCore/disassembler/ARM64/A64DOpcode.h (161317 => 161318)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/disassembler/ARM64/A64DOpcode.h        2014-01-05 02:15:25 UTC (rev 161317)
+++ branches/jsCStack/Source/JavaScriptCore/disassembler/ARM64/A64DOpcode.h        2014-01-05 07:29:27 UTC (rev 161318)
</span><span class="lines">@@ -565,6 +565,22 @@
</span><span class="cx">     int sBit() { return (m_opcode &gt;&gt; 12) &amp; 0x1; }
</span><span class="cx"> };
</span><span class="cx"> 
</span><ins>+class A64DOpcodeLoadStoreRegisterPair : public A64DOpcodeLoadStore {
+public:
+    static const uint32_t mask = 0x3a000000;
+    static const uint32_t pattern = 0x28000000;
+
+    DEFINE_STATIC_FORMAT(A64DOpcodeLoadStoreRegisterPair, thisObj);
+
+    const char* format();
+    const char* opName();
+
+    unsigned rt2() { return (m_opcode &gt;&gt; 10) &amp; 0x1f; }
+    int immediate7() { return (static_cast&lt;int&gt;((m_opcode &gt;&gt; 15) &amp; 0x7f) &lt;&lt; 25) &gt;&gt; 25; }
+    unsigned offsetMode() { return (m_opcode &gt;&gt; 23) &amp; 0x7; }
+    int lBit() { return (m_opcode &gt;&gt; 22) &amp; 0x1; }
+};
+
</ins><span class="cx"> class A64DOpcodeLoadStoreUnsignedImmediate : public A64DOpcodeLoadStore {
</span><span class="cx"> public:
</span><span class="cx">     static const uint32_t mask = 0x3b000000;
</span></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCorejitAssemblyHelpersh"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/JavaScriptCore/jit/AssemblyHelpers.h (161317 => 161318)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/jit/AssemblyHelpers.h        2014-01-05 02:15:25 UTC (rev 161317)
+++ branches/jsCStack/Source/JavaScriptCore/jit/AssemblyHelpers.h        2014-01-05 07:29:27 UTC (rev 161318)
</span><span class="lines">@@ -110,6 +110,18 @@
</span><span class="cx">         return 2 * sizeof(void*);
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    void emitFunctionPrologue()
+    {
+        pushPair(framePointerRegister, linkRegister);
+        move(stackPointerRegister, framePointerRegister);
+    }
+
+    void emitFunctionEpilogue()
+    {
+        move(framePointerRegister, stackPointerRegister);
+        popPair(framePointerRegister, linkRegister);
+    }
+
</ins><span class="cx">     ALWAYS_INLINE void preserveReturnAddressAfterCall(RegisterID reg)
</span><span class="cx">     {
</span><span class="cx">         move(linkRegister, reg);
</span></span></pre>
</div>
</div>

</body>
</html>