<!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>[212592] 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/212592">212592</a></dd>
<dt>Author</dt> <dd>msaboff@apple.com</dd>
<dt>Date</dt> <dd>2017-02-17 15:52:17 -0800 (Fri, 17 Feb 2017)</dd>
</dl>

<h3>Log Message</h3>
<pre>Improve ARM64 disassembler handling of pseudo ops, unsupported opcodes and zero reg
https://bugs.webkit.org/show_bug.cgi?id=168527

Reviewed by Filip Pizlo.

Added support for data processing 1 source instructions like rbit, rev, clz and cls.
Added support for the FP conditional select instruction, fcsel.  Consolidated the
two classes for handling dmb instructions into one class.  Fixed the instruction
selection mask in the integer conditional select class, A64DOpcodeConditionalSelect.
Fixed the processing of extract instruction (extr) including the rotate right (ror)
pseudo instruction.  Changed the printing of x31 and w31 to xzr and wzr as operands
according to the spec.  Added support for common pseudo instructions.  This includes:
- mvn x1, X2 in place of orn x1, xzr, x2
- lsl x3, x4, #count in place of ubfiz x3, x4, #count, #count
- smull x5, w6, w7 in place of smaddl x5, w6, w7, XZR
- More understandable mov x8, #-304 in place of movn x8, #0x12f
- Eliminated xzr from register index loads and stores, outputing
  ldr x10, [x11] instead of ldr x10, [x11, xzr]

Changed the move wide instructions to use hex literals for movz and movk.
This makes it much easier to decifer sequences of wide moves for large literals.
        Before                       After
  movz   x17, #26136           movz   x17, #0x6618
  movk   x17, #672, lsl #16    movk   x17, #0x2a0, lsl #16
  movk   x17, #1, lsl #32      movk   x17, #0x1, lsl #32

Verified that all instructions currently generated by the JSC stress tests are
disassembled.

* disassembler/ARM64/A64DOpcode.cpp:
(JSC::ARM64Disassembler::A64DOpcodeBitfield::format):
(JSC::ARM64Disassembler::A64DOpcodeDataProcessing1Source::format):
(JSC::ARM64Disassembler::A64DOpcodeDataProcessing2Source::format):
(JSC::ARM64Disassembler::A64DOpcodeDataProcessing3Source::format):
(JSC::ARM64Disassembler::A64DOpcodeExtract::format):
(JSC::ARM64Disassembler::A64DOpcodeFloatingPointConditionalSelect::format):
(JSC::ARM64Disassembler::A64DOpcodeFloatingPointIntegerConversions::format):
(JSC::ARM64Disassembler::A64DOpcodeDmb::format):
(JSC::ARM64Disassembler::A64DOpcodeLoadStoreImmediate::format):
(JSC::ARM64Disassembler::A64DOpcodeLoadStoreRegisterOffset::format):
(JSC::ARM64Disassembler::A64DOpcodeLoadStoreRegisterPair::format):
(JSC::ARM64Disassembler::A64DOpcodeLoadStoreUnsignedImmediate::format):
(JSC::ARM64Disassembler::A64DOpcodeLogicalShiftedRegister::format):
(JSC::ARM64Disassembler::A64DOpcodeMoveWide::format):
(JSC::ARM64Disassembler::A64DOpcodeDmbIsh::format): Deleted.
(JSC::ARM64Disassembler::A64DOpcodeDmbIshSt::format): Deleted.
* disassembler/ARM64/A64DOpcode.h:
(JSC::ARM64Disassembler::A64DOpcode::appendSignedImmediate64):
(JSC::ARM64Disassembler::A64DOpcode::appendUnsignedHexImmediate):
(JSC::ARM64Disassembler::A64DOpcodeDataProcessing1Source::opName):
(JSC::ARM64Disassembler::A64DOpcodeDataProcessing1Source::sBit):
(JSC::ARM64Disassembler::A64DOpcodeDataProcessing1Source::opCode):
(JSC::ARM64Disassembler::A64DOpcodeDataProcessing1Source::opCode2):
(JSC::ARM64Disassembler::A64DOpcodeDataProcessing1Source::opNameIndex):
(JSC::ARM64Disassembler::A64DOpcodeDataProcessing3Source::opName):
(JSC::ARM64Disassembler::A64DOpcodeFloatingPointConditionalSelect::opName):
(JSC::ARM64Disassembler::A64DOpcodeFloatingPointConditionalSelect::condition):
(JSC::ARM64Disassembler::A64DOpcodeDmb::option):
(JSC::ARM64Disassembler::A64DOpcodeDmb::crM):
(JSC::ARM64Disassembler::A64DOpcodeLogicalShiftedRegister::isMov):
(JSC::ARM64Disassembler::A64DOpcodeDmbIsh::opName): Deleted.
(JSC::ARM64Disassembler::A64DOpcodeDmbIshSt::opName): Deleted.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceJavaScriptCoreChangeLog">trunk/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCoredisassemblerARM64A64DOpcodecpp">trunk/Source/JavaScriptCore/disassembler/ARM64/A64DOpcode.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredisassemblerARM64A64DOpcodeh">trunk/Source/JavaScriptCore/disassembler/ARM64/A64DOpcode.h</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (212591 => 212592)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2017-02-17 23:49:59 UTC (rev 212591)
+++ trunk/Source/JavaScriptCore/ChangeLog        2017-02-17 23:52:17 UTC (rev 212592)
</span><span class="lines">@@ -1,3 +1,68 @@
</span><ins>+2017-02-17  Michael Saboff  &lt;msaboff@apple.com&gt;
+
+        Improve ARM64 disassembler handling of pseudo ops, unsupported opcodes and zero reg
+        https://bugs.webkit.org/show_bug.cgi?id=168527
+
+        Reviewed by Filip Pizlo.
+
+        Added support for data processing 1 source instructions like rbit, rev, clz and cls.
+        Added support for the FP conditional select instruction, fcsel.  Consolidated the
+        two classes for handling dmb instructions into one class.  Fixed the instruction
+        selection mask in the integer conditional select class, A64DOpcodeConditionalSelect.
+        Fixed the processing of extract instruction (extr) including the rotate right (ror)
+        pseudo instruction.  Changed the printing of x31 and w31 to xzr and wzr as operands
+        according to the spec.  Added support for common pseudo instructions.  This includes:
+        - mvn x1, X2 in place of orn x1, xzr, x2
+        - lsl x3, x4, #count in place of ubfiz x3, x4, #count, #count
+        - smull x5, w6, w7 in place of smaddl x5, w6, w7, XZR
+        - More understandable mov x8, #-304 in place of movn x8, #0x12f
+        - Eliminated xzr from register index loads and stores, outputing
+          ldr x10, [x11] instead of ldr x10, [x11, xzr]
+
+        Changed the move wide instructions to use hex literals for movz and movk.
+        This makes it much easier to decifer sequences of wide moves for large literals.
+                Before                       After
+          movz   x17, #26136           movz   x17, #0x6618
+          movk   x17, #672, lsl #16    movk   x17, #0x2a0, lsl #16
+          movk   x17, #1, lsl #32      movk   x17, #0x1, lsl #32
+
+        Verified that all instructions currently generated by the JSC stress tests are
+        disassembled.
+
+        * disassembler/ARM64/A64DOpcode.cpp:
+        (JSC::ARM64Disassembler::A64DOpcodeBitfield::format):
+        (JSC::ARM64Disassembler::A64DOpcodeDataProcessing1Source::format):
+        (JSC::ARM64Disassembler::A64DOpcodeDataProcessing2Source::format):
+        (JSC::ARM64Disassembler::A64DOpcodeDataProcessing3Source::format):
+        (JSC::ARM64Disassembler::A64DOpcodeExtract::format):
+        (JSC::ARM64Disassembler::A64DOpcodeFloatingPointConditionalSelect::format):
+        (JSC::ARM64Disassembler::A64DOpcodeFloatingPointIntegerConversions::format):
+        (JSC::ARM64Disassembler::A64DOpcodeDmb::format):
+        (JSC::ARM64Disassembler::A64DOpcodeLoadStoreImmediate::format):
+        (JSC::ARM64Disassembler::A64DOpcodeLoadStoreRegisterOffset::format):
+        (JSC::ARM64Disassembler::A64DOpcodeLoadStoreRegisterPair::format):
+        (JSC::ARM64Disassembler::A64DOpcodeLoadStoreUnsignedImmediate::format):
+        (JSC::ARM64Disassembler::A64DOpcodeLogicalShiftedRegister::format):
+        (JSC::ARM64Disassembler::A64DOpcodeMoveWide::format):
+        (JSC::ARM64Disassembler::A64DOpcodeDmbIsh::format): Deleted.
+        (JSC::ARM64Disassembler::A64DOpcodeDmbIshSt::format): Deleted.
+        * disassembler/ARM64/A64DOpcode.h:
+        (JSC::ARM64Disassembler::A64DOpcode::appendSignedImmediate64):
+        (JSC::ARM64Disassembler::A64DOpcode::appendUnsignedHexImmediate):
+        (JSC::ARM64Disassembler::A64DOpcodeDataProcessing1Source::opName):
+        (JSC::ARM64Disassembler::A64DOpcodeDataProcessing1Source::sBit):
+        (JSC::ARM64Disassembler::A64DOpcodeDataProcessing1Source::opCode):
+        (JSC::ARM64Disassembler::A64DOpcodeDataProcessing1Source::opCode2):
+        (JSC::ARM64Disassembler::A64DOpcodeDataProcessing1Source::opNameIndex):
+        (JSC::ARM64Disassembler::A64DOpcodeDataProcessing3Source::opName):
+        (JSC::ARM64Disassembler::A64DOpcodeFloatingPointConditionalSelect::opName):
+        (JSC::ARM64Disassembler::A64DOpcodeFloatingPointConditionalSelect::condition):
+        (JSC::ARM64Disassembler::A64DOpcodeDmb::option):
+        (JSC::ARM64Disassembler::A64DOpcodeDmb::crM):
+        (JSC::ARM64Disassembler::A64DOpcodeLogicalShiftedRegister::isMov):
+        (JSC::ARM64Disassembler::A64DOpcodeDmbIsh::opName): Deleted.
+        (JSC::ARM64Disassembler::A64DOpcodeDmbIshSt::opName): Deleted.
+
</ins><span class="cx"> 2017-02-17  Zan Dobersek  &lt;zdobersek@igalia.com&gt;
</span><span class="cx"> 
</span><span class="cx">         [GLib] GCActivityCallback::scheduleTimer() keeps pushing dispatch into the future
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredisassemblerARM64A64DOpcodecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/disassembler/ARM64/A64DOpcode.cpp (212591 => 212592)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/disassembler/ARM64/A64DOpcode.cpp        2017-02-17 23:49:59 UTC (rev 212591)
+++ trunk/Source/JavaScriptCore/disassembler/ARM64/A64DOpcode.cpp        2017-02-17 23:52:17 UTC (rev 212592)
</span><span class="lines">@@ -83,8 +83,7 @@
</span><span class="cx">     OPCODE_GROUP_ENTRY(0x15, A64DOpcodeConditionalBranchImmediate),
</span><span class="cx">     OPCODE_GROUP_ENTRY(0x15, A64DOpcodeCompareAndBranchImmediate),
</span><span class="cx">     OPCODE_GROUP_ENTRY(0x15, A64DOpcodeHint),
</span><del>-    OPCODE_GROUP_ENTRY(0x15, A64DOpcodeDmbIsh),
-    OPCODE_GROUP_ENTRY(0x15, A64DOpcodeDmbIshSt),
</del><ins>+    OPCODE_GROUP_ENTRY(0x15, A64DOpcodeDmb),
</ins><span class="cx">     OPCODE_GROUP_ENTRY(0x16, A64DOpcodeUnconditionalBranchImmediate),
</span><span class="cx">     OPCODE_GROUP_ENTRY(0x16, A64DOpcodeUnconditionalBranchRegister),
</span><span class="cx">     OPCODE_GROUP_ENTRY(0x16, A64DOpcodeTestAndBranchImmediate),
</span><span class="lines">@@ -95,6 +94,7 @@
</span><span class="cx">     OPCODE_GROUP_ENTRY(0x18, A64DOpcodeLoadStoreRegisterOffset),
</span><span class="cx">     OPCODE_GROUP_ENTRY(0x19, A64DOpcodeLoadStoreUnsignedImmediate),
</span><span class="cx">     OPCODE_GROUP_ENTRY(0x1a, A64DOpcodeConditionalSelect),
</span><ins>+    OPCODE_GROUP_ENTRY(0x1a, A64DOpcodeDataProcessing1Source),
</ins><span class="cx">     OPCODE_GROUP_ENTRY(0x1a, A64DOpcodeDataProcessing2Source),
</span><span class="cx">     OPCODE_GROUP_ENTRY(0x1b, A64DOpcodeDataProcessing3Source),
</span><span class="cx">     OPCODE_GROUP_ENTRY(0x1c, A64DOpcodeLoadStoreImmediate),
</span><span class="lines">@@ -101,6 +101,7 @@
</span><span class="cx">     OPCODE_GROUP_ENTRY(0x1c, A64DOpcodeLoadStoreRegisterOffset),
</span><span class="cx">     OPCODE_GROUP_ENTRY(0x1d, A64DOpcodeLoadStoreUnsignedImmediate),
</span><span class="cx">     OPCODE_GROUP_ENTRY(0x1e, A64DOpcodeFloatingPointCompare),
</span><ins>+    OPCODE_GROUP_ENTRY(0x1e, A64DOpcodeFloatingPointConditionalSelect),
</ins><span class="cx">     OPCODE_GROUP_ENTRY(0x1e, A64DOpcodeFloatingPointDataProcessing2Source),
</span><span class="cx">     OPCODE_GROUP_ENTRY(0x1e, A64DOpcodeFloatingPointDataProcessing1Source),
</span><span class="cx">     OPCODE_GROUP_ENTRY(0x1e, A64DOpcodeFloatingFixedPointConversions),
</span><span class="lines">@@ -288,7 +289,7 @@
</span><span class="cx"> const char* const A64DOpcodeBitfield::s_extendPseudoOpNames[3][3] = {
</span><span class="cx">     { &quot;sxtb&quot;, &quot;sxth&quot;, &quot;sxtw&quot; }, { 0, 0, 0} , { &quot;uxtb&quot;, &quot;uxth&quot;, &quot;uxtw&quot; } };
</span><span class="cx"> const char* const A64DOpcodeBitfield::s_insertOpNames[3] = { &quot;sbfiz&quot;, &quot;bfi&quot;, &quot;ubfiz&quot; };
</span><del>-const char* const A64DOpcodeBitfield::s_extractOpNames[3] = { &quot;sbfx&quot;, &quot;bf&quot;, &quot;ubfx&quot; };
</del><ins>+const char* const A64DOpcodeBitfield::s_extractOpNames[3] = { &quot;sbfx&quot;, &quot;bfxil&quot;, &quot;ubfx&quot; };
</ins><span class="cx"> 
</span><span class="cx"> const char* A64DOpcodeBitfield::format()
</span><span class="cx"> {
</span><span class="lines">@@ -310,7 +311,7 @@
</span><span class="cx">         } else if (immediateS() == 15) {
</span><span class="cx">             appendInstructionName(extendPseudoOpNames(1));
</span><span class="cx">             isSTXType = true;
</span><del>-        } else if (immediateS() == 31 &amp;&amp; is64Bit()) {
</del><ins>+        } else if (immediateS() == 31 &amp;&amp; is64Bit() &amp;&amp; !opc()) {
</ins><span class="cx">             appendInstructionName(extendPseudoOpNames(2));
</span><span class="cx">             isSTXType = true;
</span><span class="cx">         }
</span><span class="lines">@@ -324,17 +325,7 @@
</span><span class="cx">         }
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    if (opc() == 0x2 &amp;&amp; immediateS() == (immediateR() + 1)) {
-        // lsl
-        appendInstructionName(&quot;lsl&quot;);
-        appendRegisterName(rd(), is64Bit());
-        appendSeparator();
-        appendRegisterName(rn(), is64Bit());
-        appendSeparator();
-        appendUnsignedImmediate((is64Bit() ? 63u : 31u) - immediateR());
-
-        return m_formatBuffer;
-    } else if (!(opc() &amp; 0x1) &amp;&amp; ((immediateS() &amp; 0x1f) == 0x1f) &amp;&amp; (is64Bit() == (immediateS() &gt;&gt; 5))) {
</del><ins>+    if (!(opc() &amp; 0x1) &amp;&amp; ((immediateS() &amp; 0x1f) == 0x1f) &amp;&amp; (is64Bit() == (immediateS() &gt;&gt; 5))) {
</ins><span class="cx">         // asr/lsr
</span><span class="cx">         appendInstructionName(!opc() ? &quot;ars&quot; : &quot;lsr&quot;);
</span><span class="cx"> 
</span><span class="lines">@@ -345,23 +336,37 @@
</span><span class="cx">         appendUnsignedImmediate(immediateR());
</span><span class="cx"> 
</span><span class="cx">         return m_formatBuffer;
</span><del>-    } else if (immediateS() &lt; immediateR()) {
-        // bit field insert
-        appendInstructionName(insertOpNames());
</del><ins>+    }
</ins><span class="cx"> 
</span><ins>+    if (opc() == 0x2 &amp;&amp; (immediateS() + 1) == immediateR()) {
+        // lsl
+        appendInstructionName(&quot;lsl&quot;);
</ins><span class="cx">         appendRegisterName(rd(), is64Bit());
</span><span class="cx">         appendSeparator();
</span><span class="cx">         appendRegisterName(rn(), is64Bit());
</span><span class="cx">         appendSeparator();
</span><span class="cx">         appendUnsignedImmediate((is64Bit() ? 64u : 32u) - immediateR());
</span><del>-        appendSeparator();
-        appendUnsignedImmediate(immediateS() + 1);
-
</del><ins>+        
</ins><span class="cx">         return m_formatBuffer;
</span><del>-    } else {
-        // bit field extract
-        appendInstructionName(extractOpNames());
</del><ins>+    }
+    
+    if (immediateS() &lt; immediateR()) {
+        if (opc() != 1 || rn() != 0x1f) {
+            // bit field insert
+            appendInstructionName(insertOpNames());
</ins><span class="cx"> 
</span><ins>+            appendRegisterName(rd(), is64Bit());
+            appendSeparator();
+            appendRegisterName(rn(), is64Bit());
+            appendSeparator();
+            appendUnsignedImmediate((is64Bit() ? 64u : 32u) - immediateR());
+            appendSeparator();
+            appendUnsignedImmediate(immediateS() + 1);
+
+            return m_formatBuffer;
+        }
+        
+        appendInstructionName(opName());
</ins><span class="cx">         appendRegisterName(rd(), is64Bit());
</span><span class="cx">         appendSeparator();
</span><span class="cx">         appendRegisterName(rn(), is64Bit());
</span><span class="lines">@@ -368,12 +373,14 @@
</span><span class="cx">         appendSeparator();
</span><span class="cx">         appendUnsignedImmediate(immediateR());
</span><span class="cx">         appendSeparator();
</span><del>-        appendUnsignedImmediate(immediateS() - immediateR() + 1);
-
</del><ins>+        appendUnsignedImmediate(immediateS());
+        
</ins><span class="cx">         return m_formatBuffer;
</span><span class="cx">     }
</span><ins>+    
+    // bit field extract
+    appendInstructionName(extractOpNames());
</ins><span class="cx"> 
</span><del>-    appendInstructionName(opName());
</del><span class="cx">     appendRegisterName(rd(), is64Bit());
</span><span class="cx">     appendSeparator();
</span><span class="cx">     appendRegisterName(rn(), is64Bit());
</span><span class="lines">@@ -380,7 +387,7 @@
</span><span class="cx">     appendSeparator();
</span><span class="cx">     appendUnsignedImmediate(immediateR());
</span><span class="cx">     appendSeparator();
</span><del>-    appendUnsignedImmediate(immediateS());
</del><ins>+    appendUnsignedImmediate(immediateS() - immediateR() + 1);
</ins><span class="cx"> 
</span><span class="cx">     return m_formatBuffer;
</span><span class="cx"> }
</span><span class="lines">@@ -442,6 +449,38 @@
</span><span class="cx"> 
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+const char* const A64DOpcodeDataProcessing1Source::s_opNames[8] = {
+    &quot;rbit&quot;, &quot;rev16&quot;, &quot;rev32&quot;, &quot;rev&quot;, &quot;clz&quot;, &quot;cls&quot;, 0, 0
+};
+
+const char* A64DOpcodeDataProcessing1Source::format()
+{
+    if (sBit())
+        return A64DOpcode::format();
+
+    if (opCode2())
+        return A64DOpcode::format();
+
+    if (opCode() &amp; 0x38)
+        return A64DOpcode::format();
+
+    if ((opCode() &amp; 0x3e) == 0x6)
+        return A64DOpcode::format();
+
+    if (is64Bit() &amp;&amp; opCode() == 0x3)
+        return A64DOpcode::format();
+
+    if (!is64Bit() &amp;&amp; opCode() == 0x2)
+        appendInstructionName(&quot;rev&quot;);
+    else
+        appendInstructionName(opName());
+    appendZROrRegisterName(rd(), is64Bit());
+    appendSeparator();
+    appendZROrRegisterName(rn(), is64Bit());
+    
+    return m_formatBuffer;
+}
+
</ins><span class="cx"> const char* const A64DOpcodeDataProcessing2Source::s_opNames[8] = {
</span><span class="cx">     0, 0, &quot;udiv&quot;, &quot;sdiv&quot;, &quot;lsl&quot;, &quot;lsr&quot;, &quot;asr&quot;, &quot;ror&quot; // We use the pseudo-op names for the shift/rotate instructions
</span><span class="cx"> };
</span><span class="lines">@@ -461,11 +500,11 @@
</span><span class="cx">         return A64DOpcode::format();
</span><span class="cx"> 
</span><span class="cx">     appendInstructionName(opName());
</span><del>-    appendRegisterName(rd(), is64Bit());
</del><ins>+    appendZROrRegisterName(rd(), is64Bit());
</ins><span class="cx">     appendSeparator();
</span><del>-    appendRegisterName(rn(), is64Bit());
</del><ins>+    appendZROrRegisterName(rn(), is64Bit());
</ins><span class="cx">     appendSeparator();
</span><del>-    appendRegisterName(rm(), is64Bit());
</del><ins>+    appendZROrRegisterName(rm(), is64Bit());
</ins><span class="cx"> 
</span><span class="cx">     return m_formatBuffer;
</span><span class="cx"> }
</span><span class="lines">@@ -494,15 +533,18 @@
</span><span class="cx">     if (!opName())
</span><span class="cx">         return A64DOpcode::format();
</span><span class="cx"> 
</span><ins>+    if ((opNum() &amp; 0x4) &amp;&amp; (ra() != 31))
+        return A64DOpcode::format();
+
</ins><span class="cx">     appendInstructionName(opName());
</span><del>-    appendRegisterName(rd(), is64Bit());
</del><ins>+    appendZROrRegisterName(rd(), is64Bit());
</ins><span class="cx">     appendSeparator();
</span><span class="cx">     bool srcOneAndTwoAre64Bit = is64Bit() &amp; !(opNum() &amp; 0x2);
</span><del>-    appendRegisterName(rn(), srcOneAndTwoAre64Bit);
</del><ins>+    appendZROrRegisterName(rn(), srcOneAndTwoAre64Bit);
</ins><span class="cx">     appendSeparator();
</span><del>-    appendRegisterName(rm(), srcOneAndTwoAre64Bit);
</del><ins>+    appendZROrRegisterName(rm(), srcOneAndTwoAre64Bit);
</ins><span class="cx"> 
</span><del>-    if ((ra() != 31) || !(opNum() &amp; 0x4)) {
</del><ins>+    if (ra() != 31) {
</ins><span class="cx">         appendSeparator();
</span><span class="cx">         appendRegisterName(ra(), is64Bit());
</span><span class="cx">     }
</span><span class="lines">@@ -562,24 +604,27 @@
</span><span class="cx"> 
</span><span class="cx"> const char* A64DOpcodeExtract::format()
</span><span class="cx"> {
</span><del>-    if (!op21() || !o0Bit())
</del><ins>+    if (op21() || o0Bit())
</ins><span class="cx">         return A64DOpcode::format();
</span><span class="cx"> 
</span><span class="cx">     if (is64Bit() != nBit())
</span><span class="cx">         return A64DOpcode::format();
</span><span class="cx"> 
</span><del>-    if (is64Bit() &amp;&amp; (immediateS() &amp; 0x20))
</del><ins>+    if (!is64Bit() &amp;&amp; (immediateS() &amp; 0x20))
</ins><span class="cx">         return A64DOpcode::format();
</span><span class="cx"> 
</span><del>-    const char* opName = (rn() == rm()) ? &quot;ror&quot; : &quot;extr&quot;;
</del><ins>+    bool isROR = rn() == rm();
+    const char* opName = (isROR) ? &quot;ror&quot; : &quot;extr&quot;;
</ins><span class="cx"> 
</span><span class="cx">     appendInstructionName(opName);
</span><del>-    appendRegisterName(rd(), is64Bit());
</del><ins>+    appendZROrRegisterName(rd(), is64Bit());
</ins><span class="cx">     appendSeparator();
</span><del>-    appendRegisterName(rn(), is64Bit());
</del><ins>+    appendZROrRegisterName(rn(), is64Bit());
+    if (!isROR) {
+        appendSeparator();
+        appendZROrRegisterName(rm(), is64Bit());
+    }
</ins><span class="cx">     appendSeparator();
</span><del>-    appendRegisterName(rm(), is64Bit());
-    appendSeparator();
</del><span class="cx">     appendUnsignedImmediate(immediateS());
</span><span class="cx"> 
</span><span class="cx">     return m_formatBuffer;
</span><span class="lines">@@ -614,6 +659,30 @@
</span><span class="cx">     return m_formatBuffer;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+const char* A64DOpcodeFloatingPointConditionalSelect::format()
+{
+    if (mBit())
+        return A64DOpcode::format();
+    
+    if (sBit())
+        return A64DOpcode::format();
+    
+    if (type() &amp; 0x2)
+        return A64DOpcode::format();
+
+    appendInstructionName(opName());
+    unsigned registerSize = type() + 2;
+    appendFPRegisterName(rd(), registerSize);
+    appendSeparator();
+    appendFPRegisterName(rn(), registerSize);
+    appendSeparator();
+    appendFPRegisterName(rm(), registerSize);
+    appendSeparator();
+    appendString(conditionName(condition()));
+    
+    return m_formatBuffer;
+}
+
</ins><span class="cx"> const char* const A64DOpcodeFloatingPointDataProcessing1Source::s_opNames[16] = {
</span><span class="cx">     &quot;fmov&quot;, &quot;fabs&quot;, &quot;fneg&quot;, &quot;fsqrt&quot;, &quot;fcvt&quot;, &quot;fcvt&quot;, 0, &quot;fcvt&quot;,
</span><span class="cx">     &quot;frintn&quot;, &quot;frintp&quot;, &quot;frintm&quot;, &quot;frintz&quot;, &quot;frinta&quot;, 0, &quot;frintx&quot;, &quot;frinti&quot;
</span><span class="lines">@@ -782,10 +851,10 @@
</span><span class="cx">             // fmov Vd.D[1], Xn
</span><span class="cx">             bufferPrintf(&quot;V%u.D[1]&quot;, rd());
</span><span class="cx">             appendSeparator();
</span><del>-            appendRegisterName(rn());
</del><ins>+            appendZROrRegisterName(rn());
</ins><span class="cx">         } else {
</span><span class="cx">             // fmov Xd, Vn.D[1]
</span><del>-            appendRegisterName(rd());
</del><ins>+            appendZROrRegisterName(rd());
</ins><span class="cx">             appendSeparator();
</span><span class="cx">             bufferPrintf(&quot;V%u.D[1]&quot;, rn());
</span><span class="cx">         }
</span><span class="lines">@@ -800,9 +869,9 @@
</span><span class="cx">     if (destIsFP) {
</span><span class="cx">         appendFPRegisterName(rd(), FPRegisterSize);
</span><span class="cx">         appendSeparator();
</span><del>-        appendRegisterName(rn(), is64Bit());
</del><ins>+        appendZROrRegisterName(rn(), is64Bit());
</ins><span class="cx">     } else {
</span><del>-        appendRegisterName(rd(), is64Bit());
</del><ins>+        appendZROrRegisterName(rd(), is64Bit());
</ins><span class="cx">         appendSeparator();
</span><span class="cx">         appendFPRegisterName(rn(), FPRegisterSize);
</span><span class="cx">     }
</span><span class="lines">@@ -824,17 +893,20 @@
</span><span class="cx">     return m_formatBuffer;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-const char* A64DOpcodeDmbIsh::format()
</del><ins>+const char* const A64DOpcodeDmb::s_optionNames[16] = {
+    0, &quot;oshld&quot;, &quot;oshst&quot;, &quot;osh&quot;, 0, &quot;nshld&quot;, &quot;nshst&quot;, &quot;nsh&quot;,
+    0, &quot;ishld&quot;, &quot;ishst&quot;, &quot;ish&quot;, 0, &quot;ld&quot;, &quot;st&quot;, &quot;sy&quot;
+};
+
+const char* A64DOpcodeDmb::format()
</ins><span class="cx"> {
</span><del>-    appendInstructionName(&quot;dmb&quot;);
-    appendString(&quot;ish&quot;);
-    return m_formatBuffer;
-}
</del><ins>+    appendInstructionName(opName());
+    const char* thisOption = option();
+    if (thisOption)
+        appendString(thisOption);
+    else
+        appendUnsignedImmediate(crM());
</ins><span class="cx"> 
</span><del>-const char* A64DOpcodeDmbIshSt::format()
-{
-    appendInstructionName(&quot;dmb&quot;);
-    appendString(&quot;ishst&quot;);
</del><span class="cx">     return m_formatBuffer;
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -879,6 +951,8 @@
</span><span class="cx">     appendInstructionName(thisOpName);
</span><span class="cx">     if (vBit())
</span><span class="cx">         appendFPRegisterName(rt(), size());
</span><ins>+    else if (!opc())
+        appendZROrRegisterName(rt(), is64BitRT());
</ins><span class="cx">     else
</span><span class="cx">         appendRegisterName(rt(), is64BitRT());
</span><span class="cx">     appendSeparator();
</span><span class="lines">@@ -936,28 +1010,33 @@
</span><span class="cx">         appendFPRegisterName(rt(), size());
</span><span class="cx">         scale = ((opc() &amp; 2)&lt;&lt;1) | size();
</span><span class="cx">     } else {
</span><del>-        appendRegisterName(rt(), is64BitRT());
</del><ins>+        if (!opc())
+            appendZROrRegisterName(rt(), is64BitRT());
+        else
+            appendRegisterName(rt(), is64BitRT());
</ins><span class="cx">         scale = size();
</span><span class="cx">     }
</span><span class="cx">     appendSeparator();
</span><span class="cx">     appendCharacter('[');
</span><span class="cx">     appendSPOrRegisterName(rn());
</span><del>-    appendSeparator();
-    appendZROrRegisterName(rm(), (option() &amp; 0x3) == 0x3);
</del><ins>+    if (rm() != 31) {
+        appendSeparator();
+        appendRegisterName(rm(), (option() &amp; 0x3) == 0x3);
</ins><span class="cx"> 
</span><del>-    unsigned shift = sBit() ? scale : 0;
</del><ins>+        unsigned shift = sBit() ? scale : 0;
</ins><span class="cx"> 
</span><del>-    if (option() == 0x3) {
-        if (shift) {
</del><ins>+        if (option() == 0x3) {
+            if (shift) {
+                appendSeparator();
+                appendString(&quot;lsl &quot;);
+                appendUnsignedImmediate(shift);
+            }
+        } else {
</ins><span class="cx">             appendSeparator();
</span><del>-            appendString(&quot;lsl &quot;);
-            appendUnsignedImmediate(shift);
</del><ins>+            appendString(optionName());
+            if (shift)
+                appendUnsignedImmediate(shift);
</ins><span class="cx">         }
</span><del>-    } else {
-        appendSeparator();
-        appendString(optionName());
-        if (shift)
-            appendUnsignedImmediate(shift);
</del><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     appendCharacter(']');
</span><span class="lines">@@ -995,9 +1074,15 @@
</span><span class="cx">         appendFPRegisterName(rt2(), size());
</span><span class="cx">         offsetShift = size() + 2;
</span><span class="cx">     } else {
</span><del>-        appendRegisterName(rt(), is64Bit());
</del><ins>+        if (!lBit())
+            appendZROrRegisterName(rt(), is64Bit());
+        else
+            appendRegisterName(rt(), is64Bit());
</ins><span class="cx">         appendSeparator();
</span><del>-        appendRegisterName(rt2(), is64Bit());
</del><ins>+        if (!lBit())
+            appendZROrRegisterName(rt2(), is64Bit());
+        else
+            appendRegisterName(rt2(), is64Bit());
</ins><span class="cx">         offsetShift = (size() &gt;&gt; 1) + 2;
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="lines">@@ -1035,7 +1120,10 @@
</span><span class="cx">         appendFPRegisterName(rt(), size());
</span><span class="cx">         scale = ((opc() &amp; 2)&lt;&lt;1) | size();
</span><span class="cx">     } else {
</span><del>-        appendRegisterName(rt(), is64BitRT());
</del><ins>+        if (!opc())
+            appendZROrRegisterName(rt(), is64BitRT());
+        else
+            appendRegisterName(rt(), is64BitRT());
</ins><span class="cx">         scale = size();
</span><span class="cx">     }
</span><span class="cx">     appendSeparator();
</span><span class="lines">@@ -1066,15 +1154,15 @@
</span><span class="cx">         appendInstructionName(&quot;tst&quot;);
</span><span class="cx">     else {
</span><span class="cx">         if (isMov())
</span><del>-            appendInstructionName(&quot;mov&quot;);
</del><ins>+            appendInstructionName(nBit() ? &quot;mvn&quot; : &quot;mov&quot;);
</ins><span class="cx">         else
</span><span class="cx">             appendInstructionName(opName(opNumber()));
</span><del>-        appendSPOrRegisterName(rd(), is64Bit());
</del><ins>+        appendZROrRegisterName(rd(), is64Bit());
</ins><span class="cx">         appendSeparator();
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     if (!isMov()) {
</span><del>-        appendRegisterName(rn(), is64Bit());
</del><ins>+        appendZROrRegisterName(rn(), is64Bit());
</ins><span class="cx">         appendSeparator();
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="lines">@@ -1158,22 +1246,39 @@
</span><span class="cx">     return m_formatBuffer;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-const char* const A64DOpcodeMoveWide::s_opNames[4] = { &quot;movn&quot;, &quot;&quot;, &quot;movz&quot;, &quot;movk&quot; };
</del><ins>+const char* const A64DOpcodeMoveWide::s_opNames[4] = { &quot;movn&quot;, 0, &quot;movz&quot;, &quot;movk&quot; };
</ins><span class="cx"> 
</span><span class="cx"> const char* A64DOpcodeMoveWide::format()
</span><span class="cx"> {
</span><span class="cx">     if (opc() == 1)
</span><span class="cx">         return A64DOpcode::format();
</span><del>-    if (!size() &amp;&amp; hw() &gt;= 2)
</del><ins>+    if (!is64Bit() &amp;&amp; hw() &gt;= 2)
</ins><span class="cx">         return A64DOpcode::format();
</span><span class="cx"> 
</span><del>-    appendInstructionName(opName());
-    appendRegisterName(rd(), is64Bit());
-    appendSeparator();
-    appendUnsignedImmediate(immediate16());
-    if (hw()) {
</del><ins>+    if (!opc() &amp;&amp; (!immediate16() || !hw()) &amp;&amp; (is64Bit() || immediate16() != 0xffff)) {
+        // MOV pseudo op for MOVN
+        appendInstructionName(&quot;mov&quot;);
+        appendRegisterName(rd(), is64Bit());
</ins><span class="cx">         appendSeparator();
</span><del>-        appendShiftAmount(hw());
</del><ins>+
+        if (is64Bit()) {
+            int64_t amount = immediate16() &lt;&lt; (hw() * 16);
+            amount = ~amount;
+            appendSignedImmediate64(amount);
+        } else {
+            int32_t amount = immediate16() &lt;&lt; (hw() * 16);
+            amount = ~amount;
+            appendSignedImmediate(amount);
+        }
+    } else {
+        appendInstructionName(opName());
+        appendRegisterName(rd(), is64Bit());
+        appendSeparator();
+        appendUnsignedHexImmediate(immediate16());
+        if (hw()) {
+            appendSeparator();
+            appendShiftAmount(hw());
+        }
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     return m_formatBuffer;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredisassemblerARM64A64DOpcodeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/disassembler/ARM64/A64DOpcode.h (212591 => 212592)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/disassembler/ARM64/A64DOpcode.h        2017-02-17 23:49:59 UTC (rev 212591)
+++ trunk/Source/JavaScriptCore/disassembler/ARM64/A64DOpcode.h        2017-02-17 23:52:17 UTC (rev 212592)
</span><span class="lines">@@ -164,11 +164,21 @@
</span><span class="cx">         bufferPrintf(&quot;#%d&quot;, immediate);
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    void appendSignedImmediate64(int64_t immediate)
+    {
+        bufferPrintf(&quot;#%&quot; PRIi64, immediate);
+    }
+    
</ins><span class="cx">     void appendUnsignedImmediate(unsigned immediate)
</span><span class="cx">     {
</span><span class="cx">         bufferPrintf(&quot;#%u&quot;, immediate);
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    void appendUnsignedHexImmediate(unsigned immediate)
+    {
+        bufferPrintf(&quot;#0x%x&quot;, immediate);
+    }
+    
</ins><span class="cx">     void appendUnsignedImmediate64(uint64_t immediate)
</span><span class="cx">     {
</span><span class="cx">         bufferPrintf(&quot;#0x%&quot; PRIx64, immediate);
</span><span class="lines">@@ -312,7 +322,7 @@
</span><span class="cx">     static const char* const s_opNames[4];
</span><span class="cx"> 
</span><span class="cx"> public:
</span><del>-    static const uint32_t mask = 0x1fe00010;
</del><ins>+    static const uint32_t mask = 0x1fe00000;
</ins><span class="cx">     static const uint32_t pattern = 0x1a800000;
</span><span class="cx"> 
</span><span class="cx">     DEFINE_STATIC_FORMAT(A64DOpcodeConditionalSelect, thisObj);
</span><span class="lines">@@ -327,6 +337,25 @@
</span><span class="cx">     unsigned op2() { return (m_opcode &gt;&gt; 10) &amp; 0x3; }
</span><span class="cx"> };
</span><span class="cx"> 
</span><ins>+class A64DOpcodeDataProcessing1Source : public A64DOpcode {
+private:
+    static const char* const s_opNames[8];
+    
+public:
+    static const uint32_t mask = 0x5fe00000;
+    static const uint32_t pattern = 0x5ac00000;
+    
+    DEFINE_STATIC_FORMAT(A64DOpcodeDataProcessing1Source, thisObj);
+    
+    const char* format();
+    
+    const char* opName() { return s_opNames[opNameIndex()]; }
+    unsigned sBit() { return (m_opcode &gt;&gt; 29) &amp; 0x1; }
+    unsigned opCode() { return (m_opcode &gt;&gt; 10) &amp; 0x3f; }
+    unsigned opCode2() { return (m_opcode &gt;&gt; 16) &amp; 0x1f; }
+    unsigned opNameIndex() { return (opCode() &amp; 0x7); }
+};
+
</ins><span class="cx"> class A64DOpcodeDataProcessing2Source : public A64DOpcode {
</span><span class="cx"> private:
</span><span class="cx">     static const char* const s_opNames[8];
</span><span class="lines">@@ -358,7 +387,7 @@
</span><span class="cx"> 
</span><span class="cx">     const char* format();
</span><span class="cx"> 
</span><del>-    const char* opName() { return ra() == 31 ? s_opNames[opNum() &amp; 0xf] : s_pseudoOpNames[opNum() &amp; 0xf]; }
</del><ins>+    const char* opName() { return ra() == 31 ? s_pseudoOpNames[opNum() &amp; 0xf] : s_opNames[opNum() &amp; 0xf]; }
</ins><span class="cx">     unsigned ra() { return (m_opcode &gt;&gt; 10) &amp; 0x1f; }
</span><span class="cx">     unsigned op54() { return (m_opcode &gt;&gt; 29) &amp; 0x3; }
</span><span class="cx">     unsigned op31() { return (m_opcode &gt;&gt; 21) &amp; 0x7; }
</span><span class="lines">@@ -368,7 +397,7 @@
</span><span class="cx"> 
</span><span class="cx"> class A64OpcodeExceptionGeneration : public A64DOpcode {
</span><span class="cx"> public:
</span><del>-    static const uint32_t mask = 0xff000010;
</del><ins>+    static const uint32_t mask = 0xff000000;
</ins><span class="cx">     static const uint32_t pattern = 0xd4000000;
</span><span class="cx"> 
</span><span class="cx">     DEFINE_STATIC_FORMAT(A64OpcodeExceptionGeneration, thisObj);
</span><span class="lines">@@ -422,6 +451,20 @@
</span><span class="cx">     unsigned opNum() { return (m_opcode &gt;&gt; 3) &amp; 0x3; }
</span><span class="cx"> };
</span><span class="cx"> 
</span><ins>+class A64DOpcodeFloatingPointConditionalSelect : public A64DOpcodeFloatingPointOps {
+public:
+    static const uint32_t mask = 0x5f200c00;
+    static const uint32_t pattern = 0x1e200c00;
+    
+    DEFINE_STATIC_FORMAT(A64DOpcodeFloatingPointConditionalSelect, thisObj);
+    
+    const char* format();
+    
+    const char* opName() { return &quot;fcsel&quot;; }
+    
+    unsigned condition() { return (m_opcode &gt;&gt; 12) &amp; 0xf; }
+};
+
</ins><span class="cx"> class A64DOpcodeFloatingPointDataProcessing1Source : public A64DOpcodeFloatingPointOps {
</span><span class="cx"> private:
</span><span class="cx">     static const char* const s_opNames[16];
</span><span class="lines">@@ -509,28 +552,20 @@
</span><span class="cx">     unsigned immediate7() { return (m_opcode &gt;&gt; 5) &amp; 0x7f; }
</span><span class="cx"> };
</span><span class="cx"> 
</span><del>-class A64DOpcodeDmbIsh : public A64DOpcode {
-public:
-    static const uint32_t mask = 0xffffffff;
-    static const uint32_t pattern = 0xd5033bbf;
</del><ins>+class A64DOpcodeDmb : public A64DOpcode {
+    static const char* const s_optionNames[16];
</ins><span class="cx"> 
</span><del>-    DEFINE_STATIC_FORMAT(A64DOpcodeDmbIsh, thisObj);
-
-    const char* format();
-
-    const char* opName() { return &quot;dmb&quot;; }
-};
-
-class A64DOpcodeDmbIshSt : public A64DOpcode {
</del><span class="cx"> public:
</span><del>-    static const uint32_t mask = 0xffffffff;
-    static const uint32_t pattern = 0xd5033abf;
</del><ins>+    static const uint32_t mask = 0xfffff0ff;
+    static const uint32_t pattern = 0xd50330bf;
</ins><span class="cx"> 
</span><del>-    DEFINE_STATIC_FORMAT(A64DOpcodeDmbIshSt, thisObj);
</del><ins>+    DEFINE_STATIC_FORMAT(A64DOpcodeDmb, thisObj);
</ins><span class="cx"> 
</span><span class="cx">     const char* format();
</span><span class="cx"> 
</span><span class="cx">     const char* opName() { return &quot;dmb&quot;; }
</span><ins>+    const char* option() { return s_optionNames[crM()]; }
+    unsigned crM() { return (m_opcode &gt;&gt; 8) &amp; 0xf; }
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> class A64DOpcodeLoadStore : public A64DOpcode {
</span><span class="lines">@@ -657,7 +692,7 @@
</span><span class="cx">     const char* format();
</span><span class="cx"> 
</span><span class="cx">     bool isTst() { return ((opNumber() == 6) &amp;&amp; (rd() == 31)); }
</span><del>-    bool isMov() { return ((opNumber() == 2) &amp;&amp; (rn() == 31)); }
</del><ins>+    bool isMov() { return ((opc() == 1) &amp;&amp; (rn() == 31)); }
</ins><span class="cx">     unsigned opNumber() { return (opc() &lt;&lt; 1) | nBit(); }
</span><span class="cx">     unsigned shift() { return (m_opcode &gt;&gt; 22) &amp; 0x3; }
</span><span class="cx">     int immediate6() { return (static_cast&lt;int&gt;((m_opcode &gt;&gt; 10) &amp; 0x3f) &lt;&lt; 26) &gt;&gt; 26; }
</span></span></pre>
</div>
</div>

</body>
</html>