<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>QEMU on 0xc0de</title>
    <link>https://0xc0de.xyz/categories/qemu/</link>
    <description>Recent content in QEMU on 0xc0de</description>
    <image>
      <title>0xc0de</title>
      <url>https://0xc0de.xyz/%3Clink%20or%20path%20of%20image%20for%20opengraph,%20twitter-cards%3E</url>
      <link>https://0xc0de.xyz/%3Clink%20or%20path%20of%20image%20for%20opengraph,%20twitter-cards%3E</link>
    </image>
    <generator>Hugo</generator>
    <language>zh-tw</language>
    <lastBuildDate>Sun, 16 Feb 2020 09:30:23 +0800</lastBuildDate>
    <atom:link href="https://0xc0de.xyz/categories/qemu/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>QEMU: 使用 Decodetree 新增 RISC-V 指令</title>
      <link>https://0xc0de.xyz/posts/qemu-decodetree-new-insn/</link>
      <pubDate>Sun, 16 Feb 2020 09:30:23 +0800</pubDate>
      <guid>https://0xc0de.xyz/posts/qemu-decodetree-new-insn/</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;⚠️ 本文所使用的 QEMU 版本為：&lt;code&gt;v4.2.0&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;在之前的文章中 (&lt;a href=&#34;https://0xc0de.xyz/posts/qemu-decodetree-part1/&#34;&gt;Part 1.&lt;/a&gt;, &lt;a href=&#34;https://0xc0de.xyz/posts/qemu-decodetree-part2/&#34;&gt;Part 2.&lt;/a&gt;) 我們提到了如何使用 &lt;code&gt;Decodetree&lt;/code&gt; 來定義指令的 decoder。本篇文章就實際使用 &lt;code&gt;Decodetree&lt;/code&gt; 來定義一個 QEMU RISC-V 目前尚未支援的指令 - &lt;code&gt;B(itmanip) Extension&lt;/code&gt; 中的 &lt;code&gt;pcnt&lt;/code&gt; 指令，並實做其行為。&lt;/p&gt;
&lt;hr&gt;
&lt;h1 id=&#34;pcnt-指令&#34;&gt;pcnt 指令&lt;/h1&gt;
&lt;p&gt;&lt;code&gt;pcnt&lt;/code&gt; 指令的定義如下：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;This instruction counts the number of 1 bits in a register. This operations is known as population
count, popcount, sideways sum, bit summation, or Hamming weight.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;其指令格式為：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;
&lt;table style=&#34;border-spacing:0;padding:0;margin:0;border:0;&#34;&gt;&lt;tr&gt;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;&#34;&gt;
&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34; id=&#34;hl-0-1&#34;&gt;&lt;a style=&#34;outline:none;text-decoration:none;color:inherit&#34; href=&#34;#hl-0-1&#34;&gt;1&lt;/a&gt;
&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34; id=&#34;hl-0-2&#34;&gt;&lt;a style=&#34;outline:none;text-decoration:none;color:inherit&#34; href=&#34;#hl-0-2&#34;&gt;2&lt;/a&gt;
&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34; id=&#34;hl-0-3&#34;&gt;&lt;a style=&#34;outline:none;text-decoration:none;color:inherit&#34; href=&#34;#hl-0-3&#34;&gt;3&lt;/a&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;;width:100%&#34;&gt;
&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;| 1 0 9 8 7 6 5 | 4 3 2 1 0 | 9 8 7 6 5 | 4 3 2 | 1 0 9 8 7 | 6 5 4 3 2 1 0 |
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;|===========================================================================|
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;|    0110000    |   00010   |    rs1    |  001  |     rd    |    0010011    | PCNT
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;hr&gt;
&lt;h1 id=&#34;安裝-toolchain&#34;&gt;安裝 toolchain&lt;/h1&gt;
&lt;p&gt;由於 &lt;code&gt;B Extension&lt;/code&gt; 尚未正式定稿 (Draft)，因此必須至 &lt;a href=&#34;https://github.com/riscv/riscv-bitmanip/tree/master/tools&#34;&gt;riscv-bitmanip repo&lt;/a&gt; 下載 toolchain，並依照該 repo 的指示安裝：&lt;/p&gt;</description>
      <content:encoded><![CDATA[<blockquote>
<p>⚠️ 本文所使用的 QEMU 版本為：<code>v4.2.0</code></p>
</blockquote>
<p>在之前的文章中 (<a href="/posts/qemu-decodetree-part1/">Part 1.</a>, <a href="/posts/qemu-decodetree-part2/">Part 2.</a>) 我們提到了如何使用 <code>Decodetree</code> 來定義指令的 decoder。本篇文章就實際使用 <code>Decodetree</code> 來定義一個 QEMU RISC-V 目前尚未支援的指令 - <code>B(itmanip) Extension</code> 中的 <code>pcnt</code> 指令，並實做其行為。</p>
<hr>
<h1 id="pcnt-指令">pcnt 指令</h1>
<p><code>pcnt</code> 指令的定義如下：</p>
<blockquote>
<p>This instruction counts the number of 1 bits in a register. This operations is known as population
count, popcount, sideways sum, bit summation, or Hamming weight.</p>
</blockquote>
<p>其指令格式為：</p>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-0-1"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-0-1">1</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-0-2"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-0-2">2</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-0-3"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-0-3">3</a>
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-text" data-lang="text"><span style="display:flex;"><span>| 1 0 9 8 7 6 5 | 4 3 2 1 0 | 9 8 7 6 5 | 4 3 2 | 1 0 9 8 7 | 6 5 4 3 2 1 0 |
</span></span><span style="display:flex;"><span>|===========================================================================|
</span></span><span style="display:flex;"><span>|    0110000    |   00010   |    rs1    |  001  |     rd    |    0010011    | PCNT
</span></span></code></pre></td></tr></table>
</div>
</div><hr>
<h1 id="安裝-toolchain">安裝 toolchain</h1>
<p>由於 <code>B Extension</code> 尚未正式定稿 (Draft)，因此必須至 <a href="https://github.com/riscv/riscv-bitmanip/tree/master/tools">riscv-bitmanip repo</a> 下載 toolchain，並依照該 repo 的指示安裝：</p>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-1-1"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-1-1">1</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-1-2"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-1-2">2</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-1-3"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-1-3">3</a>
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>sudo mkdir /opt/riscv64b
</span></span><span style="display:flex;"><span>sudo chown $USER: /opt/riscv64b
</span></span><span style="display:flex;"><span>bash build-all.sh
</span></span></code></pre></td></tr></table>
</div>
</div><p>此安裝除了 toolchain 外，還會安裝支援 <code>B Extension</code> 的 <code>Spike (riscv-isa-sim)</code> 及 <code>riscv-pk</code> (P.S. 目前的 script 是寫死安裝路徑為：<code>/opt/riscv64b</code>)。</p>
<hr>
<h1 id="範例程式">範例程式</h1>
<p>在安裝好後，我們可以寫一個範例程式，並搭配 Spike 來做測試：</p>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-2-1"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-2-1"> 1</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-2-2"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-2-2"> 2</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-2-3"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-2-3"> 3</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-2-4"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-2-4"> 4</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-2-5"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-2-5"> 5</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-2-6"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-2-6"> 6</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-2-7"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-2-7"> 7</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-2-8"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-2-8"> 8</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-2-9"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-2-9"> 9</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-2-10"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-2-10">10</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-2-11"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-2-11">11</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-2-12"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-2-12">12</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-2-13"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-2-13">13</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-2-14"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-2-14">14</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-2-15"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-2-15">15</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-2-16"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-2-16">16</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-2-17"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-2-17">17</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-2-18"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-2-18">18</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-2-19"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-2-19">19</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-2-20"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-2-20">20</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-2-21"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-2-21">21</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-2-22"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-2-22">22</a>
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-c" data-lang="c"><span style="display:flex;"><span><span style="color:#75715e">#include</span> <span style="color:#75715e">&amp;lt;stdio.h&amp;gt;</span><span style="color:#75715e">
</span></span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">int</span> <span style="color:#a6e22e">count_set_bits</span>(<span style="color:#66d9ef">int</span> num)
</span></span><span style="display:flex;"><span>{
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">int</span> count;
</span></span><span style="display:flex;"><span>    <span style="color:#a6e22e">__asm__</span>(<span style="color:#e6db74">&#34;pcnt %0, %1</span><span style="color:#ae81ff">\n</span><span style="color:#e6db74">&#34;</span>
</span></span><span style="display:flex;"><span>            <span style="color:#f92672">:</span> <span style="color:#e6db74">&#34;=r&#34;</span>(count)
</span></span><span style="display:flex;"><span>            <span style="color:#f92672">:</span> <span style="color:#e6db74">&#34;r&#34;</span>(num)
</span></span><span style="display:flex;"><span>            <span style="color:#f92672">:</span>);
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">return</span> count;
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">int</span> <span style="color:#a6e22e">main</span>(<span style="color:#66d9ef">void</span>)
</span></span><span style="display:flex;"><span>{
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">int</span> num <span style="color:#f92672">=</span> <span style="color:#ae81ff">187</span>;
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">int</span> result <span style="color:#f92672">=</span> <span style="color:#a6e22e">count_set_bits</span>(num);
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#a6e22e">printf</span>(<span style="color:#e6db74">&#34;num = %d</span><span style="color:#ae81ff">\n</span><span style="color:#e6db74">&#34;</span>, num);
</span></span><span style="display:flex;"><span>    <span style="color:#a6e22e">printf</span>(<span style="color:#e6db74">&#34;# of set bits = %d</span><span style="color:#ae81ff">\n</span><span style="color:#e6db74">&#34;</span>, result);
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">return</span> <span style="color:#ae81ff">0</span>;
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></td></tr></table>
</div>
</div><p>此範例程式做的事情很簡單，透過 inline assembly：<code>pcnt</code> 指令，將 <code>int num = 187</code> 的 <code>1 bits</code> 個數給計算出來。</p>
<p>透過剛剛的 toolchain 編譯此程式：</p>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-3-1"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-3-1">1</a>
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>/opt/riscv64b/bin/riscv64-unknown-elf-gcc -Wall -march<span style="color:#f92672">=</span>rv64gb -Os -o pcnt_example pcnt_example.c
</span></span></code></pre></td></tr></table>
</div>
</div><ul>
<li>-march=rv64gb：指定 target ISA 為 <code>RISC-V 64-bit</code> + <code>g (IMAFD base)</code> + <code>b (B Extension)</code>。</li>
</ul>
<p>透過 objdump 觀看其反組譯碼：</p>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-4-1"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-4-1">1</a>
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>/opt/riscv64b/bin/riscv64-unknown-elf-objdump -S pcnt_example &gt; pcnt_example.s
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-5-1"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-5-1"> 1</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-5-2"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-5-2"> 2</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-5-3"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-5-3"> 3</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-5-4"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-5-4"> 4</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-5-5"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-5-5"> 5</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-5-6"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-5-6"> 6</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-5-7"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-5-7"> 7</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-5-8"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-5-8"> 8</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-5-9"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-5-9"> 9</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-5-10"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-5-10">10</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-5-11"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-5-11">11</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-5-12"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-5-12">12</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-5-13"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-5-13">13</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-5-14"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-5-14">14</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-5-15"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-5-15">15</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-5-16"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-5-16">16</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-5-17"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-5-17">17</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-5-18"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-5-18">18</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-5-19"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-5-19">19</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-5-20"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-5-20">20</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-5-21"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-5-21">21</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-5-22"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-5-22">22</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-5-23"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-5-23">23</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-5-24"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-5-24">24</a>
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-text" data-lang="text"><span style="display:flex;"><span>pcnt_example:     file format elf64-littleriscv
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>Disassembly of section .text:
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>00000000000100b0 &amp;lt; main &amp;gt;:
</span></span><span style="display:flex;"><span>   100b0:       00017537                lui     a0,0x17
</span></span><span style="display:flex;"><span>   100b4:       ff010113                addi    sp,sp,-16
</span></span><span style="display:flex;"><span>   100b8:       0bb00593                li      a1,187
</span></span><span style="display:flex;"><span>   100bc:       8b850513                addi    a0,a0,-1864 # 168b8 &lt;__trunctfdf2+0x2ce&gt;
</span></span><span style="display:flex;"><span>   100c0:       00113423                sd      ra,8(sp)
</span></span><span style="display:flex;"><span>   100c4:       00813023                sd      s0,0(sp)
</span></span><span style="display:flex;"><span>   100c8:       2ac000ef                jal     ra,10374 &lt;printf&gt;
</span></span><span style="display:flex;"><span>   100cc:       0bb00413                li      s0,187
</span></span><span style="display:flex;"><span>   100d0:       00017537                lui     a0,0x17
</span></span><span style="display:flex;"><span>   100d4:       60241413                pcnt    s0,s0
</span></span><span style="display:flex;"><span>   100d8:       0004041b                sext.w  s0,s0
</span></span><span style="display:flex;"><span>   100dc:       00040593                mv      a1,s0
</span></span><span style="display:flex;"><span>   100e0:       8c850513                addi    a0,a0,-1848 # 168c8 &lt;__trunctfdf2+0x2de&gt;
</span></span><span style="display:flex;"><span>   100e4:       290000ef                jal     ra,10374 &lt;printf&gt;
</span></span><span style="display:flex;"><span>   100e8:       00813083                ld      ra,8(sp)
</span></span><span style="display:flex;"><span>   100ec:       00013403                ld      s0,0(sp)
</span></span><span style="display:flex;"><span>   100f0:       00000513                li      a0,0
</span></span><span style="display:flex;"><span>   100f4:       01010113                addi    sp,sp,16
</span></span><span style="display:flex;"><span>   100f8:       00008067                ret
</span></span></code></pre></td></tr></table>
</div>
</div><p>可以看到 <code>Line:15</code> 呼叫了 <code>pcnt</code> 指令：<code>pcnt s0, s0</code>。</p>
<p>透過 Spike 執行程式：</p>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-6-1"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-6-1">1</a>
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>/opt/riscv64b/bin/spike --isa<span style="color:#f92672">=</span>RV64GCB pk pcnt_example
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-7-1"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-7-1">1</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-7-2"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-7-2">2</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-7-3"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-7-3">3</a>
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-text" data-lang="text"><span style="display:flex;"><span>bbl loader
</span></span><span style="display:flex;"><span>num = 187
</span></span><span style="display:flex;"><span># of set bits = 6
</span></span></code></pre></td></tr></table>
</div>
</div><p><code>187</code> 的二進位為 <code>10111011</code>，<code>1 bits</code> 個數為 <code>6</code>，與程式輸出的結果一致。</p>
<p>同樣的程式，我們使用 QEMU 來執行：</p>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-8-1"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-8-1">1</a>
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>./qemu/riscv64-linux-user/qemu-riscv64 pcnt_example
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-9-1"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-9-1">1</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-9-2"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-9-2">2</a>
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-text" data-lang="text"><span style="display:flex;"><span>num = 187
</span></span><span style="display:flex;"><span>Illegal instruction
</span></span></code></pre></td></tr></table>
</div>
</div><p>可以看到，目前 QEMU 尚未支援 <code>pcnt</code> 指令，因此當執行到 <code>pcnt</code> 指令時，便會噴 <code>Illegal instruction</code> 的錯誤訊息。</p>
<hr>
<h1 id="在-qemu-中新增-pcnt-指令">在 QEMU 中新增 pcnt 指令</h1>
<p>根據前述 <code>B Extension</code> spec. 所列的 <code>pcnt</code> 指令格式，參考目前 QEMU RISC-V 現有的 <code>Decodetree</code>：<code>target/riscv/insn32.decode</code>，<code>pcnt</code> 的 <code>Pattern</code> 可以搭配 <code>@r2</code> 的 <code>Format</code> (只有 <code>rs1</code> 及 <code>rd</code> 這兩個 <code>Fields</code>)，其完整定義如下：</p>
<h3 id="field">Field</h3>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-10-22"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-10-22">22</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-10-23"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-10-23">23</a>
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-text" data-lang="text"><span style="display:flex;"><span>%rs1       15:5
</span></span><span style="display:flex;"><span>%rd        7:5
</span></span></code></pre></td></tr></table>
</div>
</div><h3 id="format">Format</h3>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-11-64"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-11-64">64</a>
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-text" data-lang="text"><span style="display:flex;"><span>@r2      .......   ..... ..... ... ..... ....... %rs1 %rd
</span></span></code></pre></td></tr></table>
</div>
</div><h3 id="pattern">Pattern</h3>
<p>我們可以定義 <code>pcnt</code> 的 <code>Pattern</code> 如下：</p>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-12-207"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-12-207">207</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-12-208"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-12-208">208</a>
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-text" data-lang="text"><span style="display:flex;"><span># *** RV32B Standard Extension ***
</span></span><span style="display:flex;"><span>pcnt       0110000  00010 ..... 001 ..... 0010011 @r2
</span></span></code></pre></td></tr></table>
</div>
</div><p>所會產生的 decoder 如下：</p>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-13-38"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-13-38">38</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-13-39"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-13-39">39</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-13-40"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-13-40">40</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-13-41"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-13-41">41</a>
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-c" data-lang="c"><span style="display:flex;"><span><span style="color:#66d9ef">typedef</span> <span style="color:#66d9ef">struct</span> {
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">int</span> rd;
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">int</span> rs1;
</span></span><span style="display:flex;"><span>} arg_decode_insn3213;
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-14-491"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-14-491">491</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-14-492"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-14-492">492</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-14-493"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-14-493">493</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-14-494"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-14-494">494</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-14-495"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-14-495">495</a>
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-c" data-lang="c"><span style="display:flex;"><span><span style="color:#66d9ef">static</span> <span style="color:#66d9ef">void</span> <span style="color:#a6e22e">decode_insn32_extract_r2</span>(DisasContext <span style="color:#f92672">*</span>ctx, arg_decode_insn3213 <span style="color:#f92672">*</span>a, <span style="color:#66d9ef">uint32_t</span> insn)
</span></span><span style="display:flex;"><span>{
</span></span><span style="display:flex;"><span>    a<span style="color:#f92672">-&gt;</span>rs1 <span style="color:#f92672">=</span> <span style="color:#a6e22e">extract32</span>(insn, <span style="color:#ae81ff">15</span>, <span style="color:#ae81ff">5</span>);
</span></span><span style="display:flex;"><span>    a<span style="color:#f92672">-&gt;</span>rd <span style="color:#f92672">=</span> <span style="color:#a6e22e">extract32</span>(insn, <span style="color:#ae81ff">7</span>, <span style="color:#ae81ff">5</span>);
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-15-673"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-15-673">673</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-15-674"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-15-674">674</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-15-675"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-15-675">675</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-15-676"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-15-676">676</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-15-677"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-15-677">677</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-15-678"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-15-678">678</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-15-679"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-15-679">679</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-15-680"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-15-680">680</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-15-681"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-15-681">681</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-15-682"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-15-682">682</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-15-683"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-15-683">683</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-15-684"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-15-684">684</a>
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-c" data-lang="c"><span style="display:flex;"><span>            <span style="color:#66d9ef">case</span> <span style="color:#ae81ff">0x1</span><span style="color:#f92672">:</span>
</span></span><span style="display:flex;"><span>                <span style="color:#75715e">/* 01...... ........ .001.... .0010011 */</span>
</span></span><span style="display:flex;"><span>                <span style="color:#a6e22e">decode_insn32_extract_r2</span>(ctx, <span style="color:#f92672">&amp;</span>u.f_decode_insn3213, insn);
</span></span><span style="display:flex;"><span>                <span style="color:#66d9ef">switch</span> ((insn <span style="color:#f92672">&gt;&gt;</span> <span style="color:#ae81ff">20</span>) <span style="color:#f92672">&amp;</span> <span style="color:#ae81ff">0x3ff</span>) {
</span></span><span style="display:flex;"><span>                <span style="color:#66d9ef">case</span> <span style="color:#ae81ff">0x202</span><span style="color:#f92672">:</span>
</span></span><span style="display:flex;"><span>                    <span style="color:#75715e">/* 01100000 0010.... .001.... .0010011 */</span>
</span></span><span style="display:flex;"><span>                    <span style="color:#75715e">/* /home/frankchang/qemu/target/riscv/insn32.decode:208 */</span>
</span></span><span style="display:flex;"><span>                    <span style="color:#66d9ef">if</span> (<span style="color:#a6e22e">trans_pcnt</span>(ctx, <span style="color:#f92672">&amp;</span>u.f_decode_insn3213)) <span style="color:#66d9ef">return</span> true;
</span></span><span style="display:flex;"><span>                    <span style="color:#66d9ef">return</span> false;
</span></span><span style="display:flex;"><span>                }
</span></span><span style="display:flex;"><span>                <span style="color:#66d9ef">return</span> false;
</span></span><span style="display:flex;"><span>            }
</span></span></code></pre></td></tr></table>
</div>
</div><p>由於 <code>@r2 Format</code> 並沒有參考任何的 <code>Argument Set</code>，因此 <code>Decodetree</code> 會自動根據 <code>Format</code> 所參考到的 <code>Fields</code> (<code>rs1</code>、<code>rd</code>) 動態產生 <code>argument set struct</code>: <code>arg_decode_insn3213</code>。</p>
<p>此外，由 <code>pcnt Pattern</code> 所產生的 decode function 會呼叫 <code>decode_insn32_extract_r2()</code> 這個 extract function 來解析指令中 <code>rs2</code> 及 <code>rd</code> 欄位的值，並更新所傳入 <code>arg_decode_insn3213</code> 對應的欄位，而後再呼叫 <code>trans_pcnt()</code> 來執行 <code>pcnt</code> 指令 (產生對應的 <code>TCG ops</code>)。因此，我們還必須定義 <code>trans_pcnt()</code> 來實作 <code>pcnt</code> 的指令行為。</p>
<hr>
<p>參考 <code>B Extension</code> spec. 中，<code>pcnt</code> 指令的實作：</p>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-16-1"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-16-1">1</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-16-2"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-16-2">2</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-16-3"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-16-3">3</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-16-4"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-16-4">4</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-16-5"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-16-5">5</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-16-6"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-16-6">6</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-16-7"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-16-7">7</a>
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-c" data-lang="c"><span style="display:flex;"><span><span style="color:#66d9ef">uint_xlen_t</span> <span style="color:#a6e22e">pcnt</span>(<span style="color:#66d9ef">uint_xlen_t</span> rs1)
</span></span><span style="display:flex;"><span>{
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">int</span> count <span style="color:#f92672">=</span> <span style="color:#ae81ff">0</span>;
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">for</span> (<span style="color:#66d9ef">int</span> index <span style="color:#f92672">=</span> <span style="color:#ae81ff">0</span>; index <span style="color:#f92672">&lt;</span> XLEN; index<span style="color:#f92672">++</span>)
</span></span><span style="display:flex;"><span>    count <span style="color:#f92672">+=</span> (rs1 <span style="color:#f92672">&gt;&gt;</span> index) <span style="color:#f92672">&amp;</span> <span style="color:#ae81ff">1</span>;
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">return</span> count;
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></td></tr></table>
</div>
</div><p>及 Spike 中，<code>pcnt</code> 指令的實作：</p>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-17-1"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-17-1">1</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-17-2"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-17-2">2</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-17-3"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-17-3">3</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-17-4"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-17-4">4</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-17-5"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-17-5">5</a>
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-c" data-lang="c"><span style="display:flex;"><span><span style="color:#a6e22e">require_extension</span>(<span style="color:#e6db74">&#39;B&#39;</span>);
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">reg_t</span> x <span style="color:#f92672">=</span> <span style="color:#ae81ff">0</span>;
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">for</span> (<span style="color:#66d9ef">int</span> i <span style="color:#f92672">=</span> <span style="color:#ae81ff">0</span>; i <span style="color:#f92672">&lt;</span> xlen; i<span style="color:#f92672">++</span>)
</span></span><span style="display:flex;"><span>  <span style="color:#66d9ef">if</span> (<span style="color:#ae81ff">1</span> <span style="color:#f92672">&amp;</span> (RS1 <span style="color:#f92672">&gt;&gt;</span> i)) x<span style="color:#f92672">++</span>;
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">WRITE_RD</span>(<span style="color:#a6e22e">sext_xlen</span>(x));
</span></span></code></pre></td></tr></table>
</div>
</div><p>實作很簡單，每次迴圈 right shift <code>rs1</code> <code>i</code> 個 bits 並與 <code>1</code> 做 <code>AND</code>，若為 <code>true</code> 就將 <code>count</code> 加 <code>1</code>，最後回傳的 <code>count</code> 就是 <code>1 bits</code> 個數。</p>
<hr>
<p><code>trans_pcnt()</code> 實作了 <code>pcnt</code> 指令對應的 <code>TCG ops</code>。QEMU 在執行時，會將 <code>target instructions</code> (e.g. RISC-V instructions) 轉譯成 <code>TCG ops</code>，而 <code>TCG ops</code> 則會再轉譯為 <code>host instructions</code> (e.g. x86 instruction)。</p>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-18-1"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-18-1">1</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-18-2"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-18-2">2</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-18-3"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-18-3">3</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-18-4"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-18-4">4</a>
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-text" data-lang="text"><span style="display:flex;"><span>+---------------------+      +---------+      +-------------------+
</span></span><span style="display:flex;"><span>| Target Instructions | ---&gt; | TCG ops | ---&gt; | Host instructions |
</span></span><span style="display:flex;"><span>+---------------------+      +---------+      +-------------------+
</span></span><span style="display:flex;"><span>     (e.g. RISC-V)                                  (e.g. x86)
</span></span></code></pre></td></tr></table>
</div>
</div><p>關於 <code>TCG</code> 的說明，可以參考 QEMU 的 documentations：<a href="https://github.com/qemu/qemu/blob/master/docs/devel/tcg.rst">Translator Internals</a>、<a href="https://github.com/qemu/qemu/blob/master/tcg/README">TCG README</a>。</p>
<p>新增一檔案：<code>./target/riscv/insn_trans/trans_rvb.inc.c</code> 來定義 <code>B Extension</code> 指令的實作 (當然，目前只有 <code>pcnt</code> 指令)：</p>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-19-1"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-19-1"> 1</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-19-2"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-19-2"> 2</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-19-3"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-19-3"> 3</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-19-4"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-19-4"> 4</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-19-5"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-19-5"> 5</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-19-6"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-19-6"> 6</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-19-7"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-19-7"> 7</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-19-8"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-19-8"> 8</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-19-9"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-19-9"> 9</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-19-10"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-19-10">10</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-19-11"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-19-11">11</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-19-12"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-19-12">12</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-19-13"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-19-13">13</a>
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-c" data-lang="c"><span style="display:flex;"><span><span style="color:#75715e">/*
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"> * RISC-V translation routines for the RVB Standard Extension.
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"> */</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">static</span> <span style="color:#66d9ef">bool</span> <span style="color:#a6e22e">trans_pcnt</span>(DisasContext <span style="color:#f92672">*</span>ctx, arg_pcnt <span style="color:#f92672">*</span>a) {
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">if</span> (a<span style="color:#f92672">-&gt;</span>rd <span style="color:#f92672">!=</span> <span style="color:#ae81ff">0</span>) {
</span></span><span style="display:flex;"><span>        TCGv t0 <span style="color:#f92672">=</span> <span style="color:#a6e22e">tcg_temp_new</span>();
</span></span><span style="display:flex;"><span>        <span style="color:#a6e22e">gen_get_gpr</span>(t0, a<span style="color:#f92672">-&gt;</span>rs1);
</span></span><span style="display:flex;"><span>        <span style="color:#a6e22e">gen_helper_pcnt</span>(cpu_gpr[a<span style="color:#f92672">-&gt;</span>rd], t0);
</span></span><span style="display:flex;"><span>        <span style="color:#a6e22e">tcg_temp_free</span>(t0);
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">return</span> true;
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></td></tr></table>
</div>
</div><p>由於對 <code>x0</code> (<code>zero register</code>) 的寫入都會被忽略，因此首先判斷 <code>rd</code> 是否為 <code>0</code>，若為 <code>0</code> 則不做任何的事情。</p>
<p>再來宣告一 TCG variable：<code>t0</code>，並透過 <code>gen_get_gpr()</code> 將 <code>rs1</code> 暫存器的值 (如 <code>pcnt_example</code> 中 <code>pcnt s0, s0</code> 指令，<code>rs1</code> 即為 <code>s0</code>，也就是 <code>x8</code>)，載入到 <code>t0</code>。</p>
<p>這邊還呼叫了我們所定義幫我們處理 <code>pcnt</code> 計算 <code>1 bits</code> 個數的 <code>pcnt</code> helper function：<code>gen_helper_pcnt()</code>。該 helper function 會在計算完後，將最後的結果存至 <code>rd</code> (i.e. <code>cpu_gpr[a-&gt;rd]</code>) 暫存器中。</p>
<p>最後別忘了要釋放之前所宣告的 TCG variable：<code>t0</code>。</p>
<p>P.S. 其實這邊可以更簡單的直接將 <code>cpu_gpr[a-&gt;rs1]</code> 傳入，省略 TCG variable：<code>t0</code> 的宣告：</p>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-20-1"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-20-1"> 1</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-20-2"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-20-2"> 2</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-20-3"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-20-3"> 3</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-20-4"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-20-4"> 4</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-20-5"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-20-5"> 5</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-20-6"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-20-6"> 6</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-20-7"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-20-7"> 7</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-20-8"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-20-8"> 8</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-20-9"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-20-9"> 9</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-20-10"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-20-10">10</a>
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-c" data-lang="c"><span style="display:flex;"><span><span style="color:#75715e">/*
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"> * RISC-V translation routines for the RVB Standard Extension.
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"> */</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">static</span> <span style="color:#66d9ef">bool</span> <span style="color:#a6e22e">trans_pcnt</span>(DisasContext <span style="color:#f92672">*</span>ctx, arg_pcnt <span style="color:#f92672">*</span>a) {
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">if</span> (a<span style="color:#f92672">-&gt;</span>rd <span style="color:#f92672">!=</span> <span style="color:#ae81ff">0</span>) {
</span></span><span style="display:flex;"><span>        <span style="color:#a6e22e">gen_helper_pcnt</span>(cpu_gpr[a<span style="color:#f92672">-&gt;</span>rd], cpu_gpr[a<span style="color:#f92672">-&gt;</span>rs1]);
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">return</span> true;
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></td></tr></table>
</div>
</div><p><code>pcnt</code> 的 helper function 定義如下：</p>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-21-1"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-21-1">1</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-21-2"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-21-2">2</a>
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-c" data-lang="c"><span style="display:flex;"><span><span style="color:#75715e">/* Bitmanip Extension */</span>
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">DEF_HELPER_1</span>(pcnt, tl, tl)
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-22-1"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-22-1"> 1</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-22-2"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-22-2"> 2</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-22-3"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-22-3"> 3</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-22-4"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-22-4"> 4</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-22-5"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-22-5"> 5</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-22-6"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-22-6"> 6</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-22-7"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-22-7"> 7</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-22-8"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-22-8"> 8</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-22-9"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-22-9"> 9</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-22-10"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-22-10">10</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-22-11"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-22-11">11</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-22-12"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-22-12">12</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-22-13"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-22-13">13</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-22-14"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-22-14">14</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-22-15"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-22-15">15</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-22-16"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-22-16">16</a>
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-c" data-lang="c"><span style="display:flex;"><span><span style="color:#75715e">/*
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"> * RISC-V Bitmanip Extension Helpers for QEMU.
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"> */</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">#include</span> <span style="color:#75715e">&#34;qemu/osdep.h&#34;</span><span style="color:#75715e">
</span></span></span><span style="display:flex;"><span><span style="color:#75715e">#include</span> <span style="color:#75715e">&#34;cpu.h&#34;</span><span style="color:#75715e">
</span></span></span><span style="display:flex;"><span><span style="color:#75715e">#include</span> <span style="color:#75715e">&#34;exec/exec-all.h&#34;</span><span style="color:#75715e">
</span></span></span><span style="display:flex;"><span><span style="color:#75715e">#include</span> <span style="color:#75715e">&#34;exec/helper-proto.h&#34;</span><span style="color:#75715e">
</span></span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>target_ulong <span style="color:#a6e22e">HELPER</span>(pcnt)(target_ulong rs1)
</span></span><span style="display:flex;"><span>{
</span></span><span style="display:flex;"><span>    target_ulong count <span style="color:#f92672">=</span> <span style="color:#ae81ff">0</span>;
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">for</span> (<span style="color:#66d9ef">int</span> i <span style="color:#f92672">=</span> <span style="color:#ae81ff">0</span>; i <span style="color:#f92672">&lt;</span> TARGET_LONG_BITS; i<span style="color:#f92672">++</span>) {
</span></span><span style="display:flex;"><span>        count <span style="color:#f92672">+=</span> (rs1 <span style="color:#f92672">&gt;&gt;</span> i) <span style="color:#f92672">&amp;</span> <span style="color:#ae81ff">1</span>;;
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">return</span> count;
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></td></tr></table>
</div>
</div><p>基本上就是實作先前在 <code>B Extension</code> spec. 及 Spike 中所看到的 <code>1 bits</code> 個數計算方式。由於 <code>pcnt</code> helper function 只需接收 <code>rs1</code> 暫存器的值，並回傳最後 <code>1 bits</code> 個數的結果，因此，我們定義 <code>pcnt</code> 的 helper function 為接收一 <code>target_ulong</code> 型態的 <code>rs1</code> 並回傳 <code>target_ulong</code> 型態的 <code>1 bits</code> 個數結果。</p>
<p>最後別忘了將我們新增的 <code>bitmanip_helper.o</code> 加入 compile objects 列表：</p>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-23-1"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-23-1">1</a>
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-make" data-lang="make"><span style="display:flex;"><span>obj-y <span style="color:#f92672">+=</span> translate.o op_helper.o cpu_helper.o cpu.o csr.o fpu_helper.o bitmanip_helper.o gdbstub.o
</span></span></code></pre></td></tr></table>
</div>
</div><hr>
<p>重新編譯 QEMU，再次執行 <code>pcnt_example</code>：</p>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-24-1"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-24-1">1</a>
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>./qemu/riscv64-linux-user/qemu-riscv64 pcnt_example
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-25-1"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-25-1">1</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-25-2"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-25-2">2</a>
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-text" data-lang="text"><span style="display:flex;"><span>num = 187
</span></span><span style="display:flex;"><span># of set bits = 6
</span></span></code></pre></td></tr></table>
</div>
</div><p>這次 QEMU 就可以正確的 decode 並執行 <code>pcnt</code> 指令了。</p>
<hr>
<p>在 QEMU 中新增指令的流程大致就如同本文所介紹，不過由於 <code>pcnt</code> 指令只是單純的 bit operation 指令，沒有像 <code>csr</code> 相關指令會涉及 <code>CPURISCVState</code> 的更新，以及像 <code>jal</code> 指令會涉及 <code>DisasContext</code> 的判斷，因此實作起來相對簡單。若欲讓 QEMU 支援不論是 <code>B Extension</code> 或是 <code>V Extension</code> 的其他指令，就是得好好 K spec. 並一個一個新增了。</p>
<p>另外最近剛好 C-Sky Microsystems 的 <code>LIU Zhiwei &amp;lt;zhiwei_liu@c-sky.com&amp;gt;</code> 在實作 <code>V Extension</code> 的 configure instructions：<code>vsetvl</code> 及 <code>vsetvli</code>，比起本文所介紹之 <code>B Extension</code> 的 <code>pcnt</code> 指令要來得複雜得多，<a href="https://github.com/patchew-project/qemu/commit/04f8d9c87bf88fabd1221f8758187ba1fa5628f0">patches</a> 仍在被 reviewed 中，也可以做為參考。</p>
<p>本文所對 QEMU 做的修正，可以參考此 <a href="https://github.com/frankchang0125/qemu/commit/3ca50fb830ab3f2b9a1b806e2240ea5bff9dfabf">commit</a>。</p>
]]></content:encoded>
    </item>
    <item>
      <title>QEMU Decodetree 語法介紹 (Part 2.)</title>
      <link>https://0xc0de.xyz/posts/qemu-decodetree-part2/</link>
      <pubDate>Sat, 01 Feb 2020 14:57:43 +0800</pubDate>
      <guid>https://0xc0de.xyz/posts/qemu-decodetree-part2/</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;⚠️ 本文所使用的 QEMU 版本為：&lt;code&gt;v4.2.0&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;延續 &lt;a href=&#34;https://0xc0de.xyz/posts/qemu-decodetree-part1/&#34;&gt;Part 1.&lt;/a&gt; 一文，本文將繼續介紹 &lt;code&gt;Decodetree&lt;/code&gt; 中的 &lt;code&gt;Patterns&lt;/code&gt; 及 &lt;code&gt;Pattern Groups&lt;/code&gt; 語法。&lt;/p&gt;
&lt;hr&gt;
&lt;h1 id=&#34;patterns&#34;&gt;Patterns&lt;/h1&gt;
&lt;p&gt;&lt;code&gt;Pattern&lt;/code&gt; 實際定義了一個指令的 decode 方式。&lt;code&gt;Decodetree&lt;/code&gt; 會根據 &lt;code&gt;Patterns&lt;/code&gt; 的定義，來動態產生出對應的 &lt;code&gt;switch-case&lt;/code&gt; decode 判斷式。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;
&lt;table style=&#34;border-spacing:0;padding:0;margin:0;border:0;&#34;&gt;&lt;tr&gt;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;&#34;&gt;
&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34; id=&#34;hl-0-1&#34;&gt;&lt;a style=&#34;outline:none;text-decoration:none;color:inherit&#34; href=&#34;#hl-0-1&#34;&gt;1&lt;/a&gt;
&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34; id=&#34;hl-0-2&#34;&gt;&lt;a style=&#34;outline:none;text-decoration:none;color:inherit&#34; href=&#34;#hl-0-2&#34;&gt;2&lt;/a&gt;
&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34; id=&#34;hl-0-3&#34;&gt;&lt;a style=&#34;outline:none;text-decoration:none;color:inherit&#34; href=&#34;#hl-0-3&#34;&gt;3&lt;/a&gt;
&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34; id=&#34;hl-0-4&#34;&gt;&lt;a style=&#34;outline:none;text-decoration:none;color:inherit&#34; href=&#34;#hl-0-4&#34;&gt;4&lt;/a&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;;width:100%&#34;&gt;
&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;pat_def      := identifier ( pat_elt )+
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;pat_elt      := fixedbit_elt | field_elt | field_ref | args_ref | fmt_ref | const_elt
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;fmt_ref      := &amp;#39;@&amp;#39; identifier
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;const_elt    := identifier &amp;#39;=&amp;#39; number
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;其語法由使用者所定義的 &lt;code&gt;identifier&lt;/code&gt;，隨後緊接著一個以上的 &lt;code&gt;pat_elt&lt;/code&gt;。&lt;/p&gt;</description>
      <content:encoded><![CDATA[<blockquote>
<p>⚠️ 本文所使用的 QEMU 版本為：<code>v4.2.0</code></p>
</blockquote>
<p>延續 <a href="/posts/qemu-decodetree-part1/">Part 1.</a> 一文，本文將繼續介紹 <code>Decodetree</code> 中的 <code>Patterns</code> 及 <code>Pattern Groups</code> 語法。</p>
<hr>
<h1 id="patterns">Patterns</h1>
<p><code>Pattern</code> 實際定義了一個指令的 decode 方式。<code>Decodetree</code> 會根據 <code>Patterns</code> 的定義，來動態產生出對應的 <code>switch-case</code> decode 判斷式。</p>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-0-1"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-0-1">1</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-0-2"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-0-2">2</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-0-3"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-0-3">3</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-0-4"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-0-4">4</a>
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-text" data-lang="text"><span style="display:flex;"><span>pat_def      := identifier ( pat_elt )+
</span></span><span style="display:flex;"><span>pat_elt      := fixedbit_elt | field_elt | field_ref | args_ref | fmt_ref | const_elt
</span></span><span style="display:flex;"><span>fmt_ref      := &#39;@&#39; identifier
</span></span><span style="display:flex;"><span>const_elt    := identifier &#39;=&#39; number
</span></span></code></pre></td></tr></table>
</div>
</div><p>其語法由使用者所定義的 <code>identifier</code>，隨後緊接著一個以上的 <code>pat_elt</code>。</p>
<ul>
<li><code>identifier</code> 可由開發者自訂，如：<code>addl_r</code>、<code>addli</code> &hellip; 等。</li>
<li><code>pat_elt</code> 則可以採用以下不同的語法：
<ul>
<li><code>fixedbit_elt</code> 與在 <code>Format</code> 中 <code>fixedbit_elt</code> 的定義相同。</li>
<li><code>field_elt</code> 與在 <code>Format</code> 中 <code>field_elt</code> 的定義相同。</li>
<li><code>field_ref</code> 與在 <code>Format</code> 中 <code>field_ref</code> 的定義相同。</li>
<li><code>args_ref</code> 與在 <code>Format</code> 中 <code>args_ref</code> 的定義相同。</li>
<li><code>fmt_ref</code> 直接參考一個被定義過的 <a href="/posts/qemu-decodetree-part1/#formats">Format</a>。</li>
<li><code>const_elt</code> 可以直接指定某一個 <code>argument</code> 的值。</li>
</ul>
</li>
</ul>
<p>由於 <code>Pattern</code> 實際定義了一個指令的 decode 方式，因此<strong>所有的 bits</strong> 及 <strong>arguments (如果有參考 args_ref 的話)</strong>  都必須明確的被定義，如果在搭配了所有的 <code>pat_elt</code> 後還有未定義的 bits 或是 arguments 的話，<code>Decodetree</code> 便會報錯。</p>
<p>此外，<code>Pattern</code> 所產生出來的 decoder，最後還會呼叫對應的 <code>translator function</code>。</p>
<ul>
<li><code>translator function</code> 需開發者自行定義。</li>
</ul>
<h3 id="examples">Examples</h3>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-1-1"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-1-1">1</a>
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-text" data-lang="text"><span style="display:flex;"><span>addl_i   010000 ..... ..... .... 0000000 ..... @opi
</span></span></code></pre></td></tr></table>
</div>
</div><p>定義了 <code>addl_i</code> 這個指令的 <code>Pattern</code>，其中：</p>
<ul>
<li>insn[31:26] 為 <code>010000</code>。</li>
<li>insn[11:5] 為 <code>0000000</code>。</li>
<li>參考了 <a href="/posts/qemu-decodetree-part1/#examples-2">Part 1. Examples</a> 定義的 <code>@opi</code> <code>Format</code>。</li>
<li>由於 <code>Pattern</code> 的<strong>所有 bits</strong> 都必須明確的被定義，因此 <code>@opi</code> 必須包含其餘 <code>insn[25:12]</code> 及 <code>insn[4:0]</code> 的格式定義，否則 <code>Decodetree</code> 便會報錯。</li>
</ul>
<p>最後 <code>addl_i</code> 的 decoder 還會呼叫 <code>trans_addl_i()</code> 這個 <code>translator function</code>。</p>
<p>搭配之前介紹的 <a href="/posts/qemu-decodetree-part1/#fields">Fields</a>、<a href="/posts/qemu-decodetree-part1/#argument-sets">Argument Sets</a> 及 <a href="/posts/qemu-decodetree-part1/#formats">Formats</a>，讓我們再看幾個完整的例子應該會更清楚 <code>Decodetree</code> 是怎產生一個指令的 decoder 的。</p>
<hr>
<p>首先是 RISC-V 的 <code>lui</code> 及 <code>auipc</code> 指令：</p>
<p><img alt="LUI &amp; AUIPC instruction formats" loading="lazy" src="/posts/qemu-decodetree-part2/lui_auipc.png"></p>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-2-1"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-2-1"> 1</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-2-2"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-2-2"> 2</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-2-3"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-2-3"> 3</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-2-4"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-2-4"> 4</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-2-5"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-2-5"> 5</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-2-6"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-2-6"> 6</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-2-7"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-2-7"> 7</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-2-8"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-2-8"> 8</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-2-9"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-2-9"> 9</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-2-10"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-2-10">10</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-2-11"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-2-11">11</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-2-12"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-2-12">12</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-2-13"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-2-13">13</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-2-14"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-2-14">14</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-2-15"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-2-15">15</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-2-16"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-2-16">16</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-2-17"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-2-17">17</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-2-18"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-2-18">18</a>
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-text" data-lang="text"><span style="display:flex;"><span># Fields:
</span></span><span style="display:flex;"><span>%rd        7:5
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span># immediates:
</span></span><span style="display:flex;"><span>%imm_u    12:s20                 !function=ex_shift_12
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span># Argument sets:
</span></span><span style="display:flex;"><span>&amp;u    imm rd
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span># Formats:
</span></span><span style="display:flex;"><span>@u       ....................      ..... ....... &amp;u      imm=%imm_u          %rd
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span># Patterns
</span></span><span style="display:flex;"><span>lui      ....................       ..... 0110111 @u
</span></span><span style="display:flex;"><span>auipc    ....................       ..... 0010111 @u
</span></span></code></pre></td></tr></table>
</div>
</div><p>會產生以下 <code>lui</code> 及 <code>auipc</code> 的 decoder：</p>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-3-1"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-3-1"> 1</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-3-2"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-3-2"> 2</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-3-3"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-3-3"> 3</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-3-4"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-3-4"> 4</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-3-5"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-3-5"> 5</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-3-6"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-3-6"> 6</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-3-7"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-3-7"> 7</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-3-8"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-3-8"> 8</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-3-9"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-3-9"> 9</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-3-10"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-3-10">10</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-3-11"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-3-11">11</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-3-12"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-3-12">12</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-3-13"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-3-13">13</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-3-14"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-3-14">14</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-3-15"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-3-15">15</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-3-16"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-3-16">16</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-3-17"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-3-17">17</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-3-18"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-3-18">18</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-3-19"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-3-19">19</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-3-20"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-3-20">20</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-3-21"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-3-21">21</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-3-22"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-3-22">22</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-3-23"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-3-23">23</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-3-24"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-3-24">24</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-3-25"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-3-25">25</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-3-26"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-3-26">26</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-3-27"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-3-27">27</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-3-28"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-3-28">28</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-3-29"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-3-29">29</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-3-30"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-3-30">30</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-3-31"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-3-31">31</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-3-32"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-3-32">32</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-3-33"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-3-33">33</a>
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-c" data-lang="c"><span style="display:flex;"><span><span style="color:#66d9ef">typedef</span> <span style="color:#66d9ef">struct</span> {
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">int</span> imm;
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">int</span> rd;
</span></span><span style="display:flex;"><span>} arg_u;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">static</span> <span style="color:#66d9ef">void</span> <span style="color:#a6e22e">decode_insn32_extract_u</span>(DisasContext <span style="color:#f92672">*</span>ctx, arg_u <span style="color:#f92672">*</span>a, <span style="color:#66d9ef">uint32_t</span> insn)
</span></span><span style="display:flex;"><span>{
</span></span><span style="display:flex;"><span>    a<span style="color:#f92672">-&gt;</span>imm <span style="color:#f92672">=</span> <span style="color:#a6e22e">ex_shift_12</span>(ctx, <span style="color:#a6e22e">sextract32</span>(insn, <span style="color:#ae81ff">12</span>, <span style="color:#ae81ff">20</span>));
</span></span><span style="display:flex;"><span>    a<span style="color:#f92672">-&gt;</span>rd <span style="color:#f92672">=</span> <span style="color:#a6e22e">extract32</span>(insn, <span style="color:#ae81ff">7</span>, <span style="color:#ae81ff">5</span>);
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">static</span> <span style="color:#66d9ef">bool</span> <span style="color:#a6e22e">decode_insn32</span>(DisasContext <span style="color:#f92672">*</span>ctx, <span style="color:#66d9ef">uint32_t</span> insn)
</span></span><span style="display:flex;"><span>{
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">union</span> {
</span></span><span style="display:flex;"><span>        arg_u f_u;
</span></span><span style="display:flex;"><span>    } u;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#a6e22e">decode_insn32_extract_u</span>(ctx, <span style="color:#f92672">&amp;</span>u.f_u, insn);
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">switch</span> (insn <span style="color:#f92672">&amp;</span> <span style="color:#ae81ff">0x0000007f</span>) {
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">case</span> <span style="color:#ae81ff">0x00000017</span><span style="color:#f92672">:</span>
</span></span><span style="display:flex;"><span>        <span style="color:#75715e">/* ........ ........ ........ .0010111 */</span>
</span></span><span style="display:flex;"><span>        <span style="color:#75715e">/* ./insn32.decode:18 */</span>
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">if</span> (<span style="color:#a6e22e">trans_auipc</span>(ctx, <span style="color:#f92672">&amp;</span>u.f_u)) <span style="color:#66d9ef">return</span> true;
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">return</span> false;
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">case</span> <span style="color:#ae81ff">0x00000037</span><span style="color:#f92672">:</span>
</span></span><span style="display:flex;"><span>        <span style="color:#75715e">/* ........ ........ ........ .0110111 */</span>
</span></span><span style="display:flex;"><span>        <span style="color:#75715e">/* ./insn32.decode:17 */</span>
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">if</span> (<span style="color:#a6e22e">trans_lui</span>(ctx, <span style="color:#f92672">&amp;</span>u.f_u)) <span style="color:#66d9ef">return</span> true;
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">return</span> false;
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">return</span> false;
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></td></tr></table>
</div>
</div><p>回顧到目前為止所介紹的：</p>
<ul>
<li>
<p><code>Argument Sets</code>：<code>&amp;u</code> 這個 <code>argument set</code> 包含了 <code>imm</code> 及 <code>rd</code> 這兩個 <code>arguments</code>。</p>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-4-1"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-4-1">1</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-4-2"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-4-2">2</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-4-3"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-4-3">3</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-4-4"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-4-4">4</a>
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-c" data-lang="c"><span style="display:flex;"><span><span style="color:#66d9ef">typedef</span> <span style="color:#66d9ef">struct</span> {
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">int</span> imm;
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">int</span> rd;
</span></span><span style="display:flex;"><span>} arg_u;
</span></span></code></pre></td></tr></table>
</div>
</div></li>
<li>
<p><code>Fields</code>： <code>imm</code> 及 <code>rd</code>  分別位在 insn[31:12] 及 insn[11:7]，且 <code>imm</code> 為 <code>sign-extended</code>。最後在擷取出 <code>imm</code> 的值後，還會呼叫 <code>ex_shift_12()</code>。</p>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-5-1"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-5-1">1</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-5-2"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-5-2">2</a>
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-c" data-lang="c"><span style="display:flex;"><span>a<span style="color:#f92672">-&gt;</span>imm <span style="color:#f92672">=</span> <span style="color:#a6e22e">ex_shift_12</span>(ctx, <span style="color:#a6e22e">sextract32</span>(insn, <span style="color:#ae81ff">12</span>, <span style="color:#ae81ff">20</span>));
</span></span><span style="display:flex;"><span>a<span style="color:#f92672">-&gt;</span>rd <span style="color:#f92672">=</span> <span style="color:#a6e22e">extract32</span>(insn, <span style="color:#ae81ff">7</span>, <span style="color:#ae81ff">5</span>);
</span></span></code></pre></td></tr></table>
</div>
</div></li>
<li>
<p><code>Formats</code>：<code>@u</code> 定義了 RISC-V <code>U-type</code> 指令的格式</p>
<ul>
<li>參考了 <code>&amp;u</code> 這個 <code>Argument Set</code>，因此 decode function 會傳入 <code>arg_u</code> 作為參數。</li>
<li>insn[31:12] 參考了 <code>imm_u</code> 這個 <code>Field</code> (並重新命名為 <code>imm</code>)</li>
<li>insn[11:7] 參考了 <code>rd</code> 這個 <code>Field</code>。</li>
</ul>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-6-1"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-6-1">1</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-6-2"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-6-2">2</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-6-3"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-6-3">3</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-6-4"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-6-4">4</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-6-5"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-6-5">5</a>
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-c" data-lang="c"><span style="display:flex;"><span><span style="color:#66d9ef">static</span> <span style="color:#66d9ef">void</span> <span style="color:#a6e22e">decode_insn32_extract_u</span>(DisasContext <span style="color:#f92672">*</span>ctx, arg_u <span style="color:#f92672">*</span>a, <span style="color:#66d9ef">uint32_t</span> insn)
</span></span><span style="display:flex;"><span>{
</span></span><span style="display:flex;"><span>    a<span style="color:#f92672">-&gt;</span>imm <span style="color:#f92672">=</span> <span style="color:#a6e22e">ex_shift_12</span>(ctx, <span style="color:#a6e22e">sextract32</span>(insn, <span style="color:#ae81ff">12</span>, <span style="color:#ae81ff">20</span>));
</span></span><span style="display:flex;"><span>    a<span style="color:#f92672">-&gt;</span>rd <span style="color:#f92672">=</span> <span style="color:#a6e22e">extract32</span>(insn, <span style="color:#ae81ff">7</span>, <span style="color:#ae81ff">5</span>);
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></td></tr></table>
</div>
</div></li>
<li>
<p><code>Patterns</code>：</p>
<ul>
<li><code>lui</code> 的 <code>opcode</code> (insn[6:0]) 為 <code>0010111</code>，也就是 <code>0x17</code>，在產生出來的 <code>switch-case</code> 中可以看到其對應的 <code>case</code>。</li>
<li><code>lui</code> 的 decoder 最後呼叫了 <code>trans_lui()</code>，並傳入 <code>DisasContext</code> 及經由 <code>decode_insn32_extract_u()</code> 所解析出來的 <code>arg_u</code>。</li>
<li><code>auipc</code> 的 <code>opcode</code> (insn[6:0]) 為 <code>0110111</code>，也就是 <code>0x37</code>，在產生出來的 <code>switch-case</code> 中可以看到其對應的 <code>case</code>。</li>
<li><code>auipc</code> 的 decoder 最後呼叫了 <code>trans_auipc()</code>，並傳入 <code>DisasContext</code> 及經由 <code>decode_insn32_extract_u()</code> 所解析出來的 <code>arg_u</code>。</li>
<li>P.S. 這邊由於 <code>Decodetree</code> 發現 <code>lui</code> 及 <code>auipc</code> 可以共用 <code>decode_insn32_extract_u()</code>，因此將其提到了 <code>switch-case</code> 之外。</li>
</ul>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-7-1"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-7-1"> 1</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-7-2"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-7-2"> 2</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-7-3"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-7-3"> 3</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-7-4"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-7-4"> 4</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-7-5"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-7-5"> 5</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-7-6"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-7-6"> 6</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-7-7"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-7-7"> 7</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-7-8"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-7-8"> 8</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-7-9"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-7-9"> 9</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-7-10"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-7-10">10</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-7-11"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-7-11">11</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-7-12"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-7-12">12</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-7-13"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-7-13">13</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-7-14"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-7-14">14</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-7-15"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-7-15">15</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-7-16"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-7-16">16</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-7-17"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-7-17">17</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-7-18"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-7-18">18</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-7-19"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-7-19">19</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-7-20"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-7-20">20</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-7-21"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-7-21">21</a>
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-c" data-lang="c"><span style="display:flex;"><span><span style="color:#66d9ef">static</span> <span style="color:#66d9ef">bool</span> <span style="color:#a6e22e">decode_insn32</span>(DisasContext <span style="color:#f92672">*</span>ctx, <span style="color:#66d9ef">uint32_t</span> insn)
</span></span><span style="display:flex;"><span>{
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">union</span> {
</span></span><span style="display:flex;"><span>        arg_u f_u;
</span></span><span style="display:flex;"><span>    } u;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#a6e22e">decode_insn32_extract_u</span>(ctx, <span style="color:#f92672">&amp;</span>u.f_u, insn);
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">switch</span> (insn <span style="color:#f92672">&amp;</span> <span style="color:#ae81ff">0x0000007f</span>) {
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">case</span> <span style="color:#ae81ff">0x00000017</span><span style="color:#f92672">:</span>
</span></span><span style="display:flex;"><span>        <span style="color:#75715e">/* ........ ........ ........ .0010111 */</span>
</span></span><span style="display:flex;"><span>        <span style="color:#75715e">/* ./insn32.decode:18 */</span>
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">if</span> (<span style="color:#a6e22e">trans_auipc</span>(ctx, <span style="color:#f92672">&amp;</span>u.f_u)) <span style="color:#66d9ef">return</span> true;
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">return</span> false;
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">case</span> <span style="color:#ae81ff">0x00000037</span><span style="color:#f92672">:</span>
</span></span><span style="display:flex;"><span>        <span style="color:#75715e">/* ........ ........ ........ .0110111 */</span>
</span></span><span style="display:flex;"><span>        <span style="color:#75715e">/* ./insn32.decode:17 */</span>
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">if</span> (<span style="color:#a6e22e">trans_lui</span>(ctx, <span style="color:#f92672">&amp;</span>u.f_u)) <span style="color:#66d9ef">return</span> true;
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">return</span> false;
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">return</span> false;
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></td></tr></table>
</div>
</div><p>我們另外可以發現，<code>Pattern</code> + <code>Format</code> 把所有的 32-bits 都給了明確的定義：</p>
<ul>
<li><code>Pattern</code> 定義了 <code>opcode</code> (insn[6:0])。</li>
<li><code>Format</code> 參考了 <code>imm</code> (insn[31:12]) 及 <code>rd</code> (insn[11:7])。</li>
</ul>
<p>如果有任何未明確定義的 bits 的話，<code>Decodetree</code> 便會報錯，例如如果我們將 <code>lui</code> 的 <code>opcode</code> 最高 2 個 bits (insn[6:5]) 由 <code>01</code> 改成 <code>..</code>：</p>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-8-1"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-8-1">1</a>
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-text" data-lang="text"><span style="display:flex;"><span>lui      ....................       ..... ..10111 @u
</span></span></code></pre></td></tr></table>
</div>
</div><p><code>Decodetree</code> 在解析時，便會報錯：</p>
<blockquote>
<p>./insn32.decode:17: error: (&lsquo;bits left unspecified (0x00000060)&rsquo;,)</p>
</blockquote>
<p><code>Decodetree</code> 提醒我們，insn[6:5] (<code>0x00000060</code>) 尚未給出明確定義，並會顯示出其錯誤的行數。</p>
<p><code>trans_lui()</code> 和 <code>trans_auipc()</code> 被定義在 <code>target/riscv/insn_trans/trans_rvi.inc.c</code>：</p>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-9-1"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-9-1"> 1</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-9-2"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-9-2"> 2</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-9-3"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-9-3"> 3</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-9-4"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-9-4"> 4</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-9-5"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-9-5"> 5</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-9-6"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-9-6"> 6</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-9-7"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-9-7"> 7</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-9-8"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-9-8"> 8</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-9-9"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-9-9"> 9</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-9-10"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-9-10">10</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-9-11"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-9-11">11</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-9-12"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-9-12">12</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-9-13"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-9-13">13</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-9-14"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-9-14">14</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-9-15"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-9-15">15</a>
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-c" data-lang="c"><span style="display:flex;"><span><span style="color:#66d9ef">static</span> <span style="color:#66d9ef">bool</span> <span style="color:#a6e22e">trans_lui</span>(DisasContext <span style="color:#f92672">*</span>ctx, arg_lui <span style="color:#f92672">*</span>a)
</span></span><span style="display:flex;"><span>{
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">if</span> (a<span style="color:#f92672">-&gt;</span>rd <span style="color:#f92672">!=</span> <span style="color:#ae81ff">0</span>) {
</span></span><span style="display:flex;"><span>        <span style="color:#a6e22e">tcg_gen_movi_tl</span>(cpu_gpr[a<span style="color:#f92672">-&gt;</span>rd], a<span style="color:#f92672">-&gt;</span>imm);
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">return</span> true;
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">static</span> <span style="color:#66d9ef">bool</span> <span style="color:#a6e22e">trans_auipc</span>(DisasContext <span style="color:#f92672">*</span>ctx, arg_auipc <span style="color:#f92672">*</span>a)
</span></span><span style="display:flex;"><span>{
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">if</span> (a<span style="color:#f92672">-&gt;</span>rd <span style="color:#f92672">!=</span> <span style="color:#ae81ff">0</span>) {
</span></span><span style="display:flex;"><span>        <span style="color:#a6e22e">tcg_gen_movi_tl</span>(cpu_gpr[a<span style="color:#f92672">-&gt;</span>rd], a<span style="color:#f92672">-&gt;</span>imm <span style="color:#f92672">+</span> ctx<span style="color:#f92672">-&gt;</span>base.pc_next);
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">return</span> true;
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></td></tr></table>
</div>
</div><p>可以看到 <code>trans_*()</code> 負責實際指令的 business logics 及產生對應的 <code>TCG codes</code>。</p>
</li>
</ul>
<hr>
<p>如同先前所介紹，<code>Patterns</code> 的 <code>pat_elt</code> 也可以採用 <code>field_elt</code> 語法，如 RISC-V 的 <code>fence</code> 指令：</p>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-10-1"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-10-1">1</a>
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-text" data-lang="text"><span style="display:flex;"><span>fence    ---- pred:4 succ:4 ----- 000 ----- 0001111
</span></span></code></pre></td></tr></table>
</div>
</div><ul>
<li>insn[27:24] 為 <code>pred</code>。</li>
<li>insn[23:20] 為 <code>succ</code>。</li>
<li>insn[14:12] 固定為 <code>000</code>。</li>
<li>insn[6:0] 為 <code>opcode</code> (<code>0001111</code>)。</li>
<li>沒有參考任何的 <code>Format</code>。</li>
<li>剩下的 insn[31:28]、insn[19:15]、insn[11:7] 被宣告為 <code>-</code>，因此就算沒有被明確定義也沒有關係。</li>
</ul>
<p>所生成 <code>fence</code> 的 decoder 如下：</p>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-11-1"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-11-1"> 1</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-11-2"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-11-2"> 2</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-11-3"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-11-3"> 3</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-11-4"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-11-4"> 4</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-11-5"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-11-5"> 5</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-11-6"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-11-6"> 6</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-11-7"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-11-7"> 7</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-11-8"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-11-8"> 8</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-11-9"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-11-9"> 9</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-11-10"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-11-10">10</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-11-11"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-11-11">11</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-11-12"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-11-12">12</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-11-13"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-11-13">13</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-11-14"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-11-14">14</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-11-15"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-11-15">15</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-11-16"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-11-16">16</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-11-17"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-11-17">17</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-11-18"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-11-18">18</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-11-19"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-11-19">19</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-11-20"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-11-20">20</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-11-21"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-11-21">21</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-11-22"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-11-22">22</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-11-23"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-11-23">23</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-11-24"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-11-24">24</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-11-25"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-11-25">25</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-11-26"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-11-26">26</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-11-27"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-11-27">27</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-11-28"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-11-28">28</a>
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-c" data-lang="c"><span style="display:flex;"><span><span style="color:#66d9ef">typedef</span> <span style="color:#66d9ef">struct</span> {
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">int</span> pred;
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">int</span> succ;
</span></span><span style="display:flex;"><span>} arg_decode_insn320;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">static</span> <span style="color:#66d9ef">void</span> <span style="color:#a6e22e">decode_insn32_extract_decode_insn32_Fmt_0</span>(DisasContext <span style="color:#f92672">*</span>ctx, arg_decode_insn320 <span style="color:#f92672">*</span>a, <span style="color:#66d9ef">uint32_t</span> insn)
</span></span><span style="display:flex;"><span>{
</span></span><span style="display:flex;"><span>    a<span style="color:#f92672">-&gt;</span>pred <span style="color:#f92672">=</span> <span style="color:#a6e22e">extract32</span>(insn, <span style="color:#ae81ff">24</span>, <span style="color:#ae81ff">4</span>);
</span></span><span style="display:flex;"><span>    a<span style="color:#f92672">-&gt;</span>succ <span style="color:#f92672">=</span> <span style="color:#a6e22e">extract32</span>(insn, <span style="color:#ae81ff">20</span>, <span style="color:#ae81ff">4</span>);
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">static</span> <span style="color:#66d9ef">bool</span> <span style="color:#a6e22e">decode_insn32</span>(DisasContext <span style="color:#f92672">*</span>ctx, <span style="color:#66d9ef">uint32_t</span> insn)
</span></span><span style="display:flex;"><span>{
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">union</span> {
</span></span><span style="display:flex;"><span>        arg_decode_insn320 f_decode_insn320;
</span></span><span style="display:flex;"><span>    } u;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#a6e22e">decode_insn32_extract_decode_insn32_Fmt_0</span>(ctx, <span style="color:#f92672">&amp;</span>u.f_decode_insn320, insn);
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">switch</span> (insn <span style="color:#f92672">&amp;</span> <span style="color:#ae81ff">0x0000707f</span>) {
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">case</span> <span style="color:#ae81ff">0x0000000f</span><span style="color:#f92672">:</span>
</span></span><span style="display:flex;"><span>        <span style="color:#75715e">/* ........ ........ .000.... .0001111 */</span>
</span></span><span style="display:flex;"><span>        <span style="color:#75715e">/* ./insn32.decode:2 */</span>
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">if</span> (<span style="color:#a6e22e">trans_fence</span>(ctx, <span style="color:#f92672">&amp;</span>u.f_decode_insn320)) <span style="color:#66d9ef">return</span> true;
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">return</span> false;
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">return</span> false;
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></td></tr></table>
</div>
</div><p>值得注意的是，雖然這次我們沒有參考任何的 <code>Argument Set</code>，但 <code>Decodetree</code> 還是替我們生成了一個包含 <code>pred</code> 和 <code>succ</code> 的 <code>arg_decode_insn320</code> 。</p>
<p><code>trans_fence()</code> 同樣是被定義在 <code>./target/riscv/insn_trans/trans_rvi.inc.c</code>：</p>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-12-1"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-12-1">1</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-12-2"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-12-2">2</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-12-3"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-12-3">3</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-12-4"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-12-4">4</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-12-5"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-12-5">5</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-12-6"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-12-6">6</a>
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-c" data-lang="c"><span style="display:flex;"><span><span style="color:#66d9ef">static</span> <span style="color:#66d9ef">bool</span> <span style="color:#a6e22e">trans_fence</span>(DisasContext <span style="color:#f92672">*</span>ctx, arg_fence <span style="color:#f92672">*</span>a)
</span></span><span style="display:flex;"><span>{
</span></span><span style="display:flex;"><span>    <span style="color:#75715e">/* FENCE is a full memory barrier. */</span>
</span></span><span style="display:flex;"><span>    <span style="color:#a6e22e">tcg_gen_mb</span>(TCG_MO_ALL <span style="color:#f92672">|</span> TCG_BAR_SC);
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">return</span> true;
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></td></tr></table>
</div>
</div><hr>
<h1 id="pattern-groups">Pattern Groups</h1>
<p><code>Pattern Groups</code> 由一個以上的 <code>Patterns</code> 所組成，其主要差別是不同 <code>Patterns</code> 之間的 bits 可以 overlap。當同組中有多個 <code>Patterns</code> 時，會依據該組中各 <code>Pattern</code> 的宣告順序依序判斷目前的指令是否符合其定義。除此之外，當符合的 <code>Pattern</code> 其 <code>trans_*()</code> 回傳值為 <code>false</code> 時，也會被視為<strong>不相符</strong>，而繼續判斷該組中的下一個 <code>Pattern</code>。因此 <code>Pattern Groups</code> 非常適合將多個相似格式的指令給組成同一個 <code>Pattern Group</code>。</p>
<p>原文說明如下：</p>
<blockquote>
<p>Unlike ungrouped patterns, grouped patterns are allowed to overlap. Conflicts are resolved by selecting the patterns in order.  If all of the <code>fixedbits</code> for a pattern match, its translate function will be called.  If the translate function returns <code>false</code>, then subsequent patterns within the group will be matched.</p>
</blockquote>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-13-1"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-13-1">1</a>
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-text" data-lang="text"><span style="display:flex;"><span>group    := &#39;{&#39; ( pat_def | group )+ &#39;}&#39;
</span></span></code></pre></td></tr></table>
</div>
</div><p>各 <code>Pattern Group</code> 以 <code>{</code> 開頭，並以 <code>}</code> 結尾，且允許 <code>nested pattern groups</code> 的存在，其他語法皆與 <code>Pattern</code> 相同。</p>
<h3 id="examples-1">Examples</h3>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-14-1"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-14-1">1</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-14-2"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-14-2">2</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-14-3"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-14-3">3</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-14-4"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-14-4">4</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-14-5"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-14-5">5</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-14-6"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-14-6">6</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-14-7"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-14-7">7</a>
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-text" data-lang="text"><span style="display:flex;"><span>{
</span></span><span style="display:flex;"><span>  {
</span></span><span style="display:flex;"><span>    nop   000010 ----- ----- 0000 001001 0 00000
</span></span><span style="display:flex;"><span>    copy  000010 00000 r1:5  0000 001001 0 rt:5
</span></span><span style="display:flex;"><span>  }
</span></span><span style="display:flex;"><span>  or      000010 rt2:5 r1:5  cf:4 001001 0 rt:5
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></td></tr></table>
</div>
</div><p>會產生以下的 decoder：</p>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-15-1"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-15-1"> 1</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-15-2"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-15-2"> 2</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-15-3"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-15-3"> 3</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-15-4"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-15-4"> 4</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-15-5"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-15-5"> 5</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-15-6"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-15-6"> 6</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-15-7"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-15-7"> 7</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-15-8"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-15-8"> 8</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-15-9"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-15-9"> 9</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-15-10"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-15-10">10</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-15-11"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-15-11">11</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-15-12"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-15-12">12</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-15-13"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-15-13">13</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-15-14"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-15-14">14</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-15-15"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-15-15">15</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-15-16"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-15-16">16</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-15-17"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-15-17">17</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-15-18"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-15-18">18</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-15-19"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-15-19">19</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-15-20"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-15-20">20</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-15-21"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-15-21">21</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-15-22"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-15-22">22</a>
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-c" data-lang="c"><span style="display:flex;"><span><span style="color:#66d9ef">switch</span> (insn <span style="color:#f92672">&amp;</span> <span style="color:#ae81ff">0xfc000fe0</span>) {
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">case</span> <span style="color:#ae81ff">0x08000240</span><span style="color:#f92672">:</span>
</span></span><span style="display:flex;"><span>    <span style="color:#75715e">/* 000010.. ........ ....0010 010..... */</span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">if</span> ((insn <span style="color:#f92672">&amp;</span> <span style="color:#ae81ff">0x0000f000</span>) <span style="color:#f92672">==</span> <span style="color:#ae81ff">0x00000000</span>) {
</span></span><span style="display:flex;"><span>        <span style="color:#75715e">/* 000010.. ........ 00000010 010..... */</span>
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">if</span> ((insn <span style="color:#f92672">&amp;</span> <span style="color:#ae81ff">0x0000001f</span>) <span style="color:#f92672">==</span> <span style="color:#ae81ff">0x00000000</span>) {
</span></span><span style="display:flex;"><span>            <span style="color:#75715e">/* 000010.. ........ 00000010 01000000 */</span>
</span></span><span style="display:flex;"><span>            <span style="color:#a6e22e">extract_decode_Fmt_0</span>(<span style="color:#f92672">&amp;</span>u.f_decode0, insn);
</span></span><span style="display:flex;"><span>            <span style="color:#66d9ef">if</span> (<span style="color:#a6e22e">trans_nop</span>(ctx, <span style="color:#f92672">&amp;</span>u.f_decode0)) <span style="color:#66d9ef">return</span> true;
</span></span><span style="display:flex;"><span>						<span style="color:#75715e">// 這邊沒有直接回傳 false，讓 switch-case 繼續往下執行
</span></span></span><span style="display:flex;"><span>      }
</span></span><span style="display:flex;"><span>      <span style="color:#66d9ef">if</span> ((insn <span style="color:#f92672">&amp;</span> <span style="color:#ae81ff">0x03e00000</span>) <span style="color:#f92672">==</span> <span style="color:#ae81ff">0x00000000</span>) {
</span></span><span style="display:flex;"><span>          <span style="color:#75715e">/* 00001000 000..... 00000010 010..... */</span>
</span></span><span style="display:flex;"><span>          <span style="color:#a6e22e">extract_decode_Fmt_1</span>(<span style="color:#f92672">&amp;</span>u.f_decode1, insn);
</span></span><span style="display:flex;"><span>          <span style="color:#66d9ef">if</span> (<span style="color:#a6e22e">trans_copy</span>(ctx, <span style="color:#f92672">&amp;</span>u.f_decode1)) <span style="color:#66d9ef">return</span> true;
</span></span><span style="display:flex;"><span>				　<span style="color:#75715e">// 這邊沒有直接回傳 false，讓 switch-case 繼續往下執行
</span></span></span><span style="display:flex;"><span>      }
</span></span><span style="display:flex;"><span>  }
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">extract_decode_Fmt_2</span>(<span style="color:#f92672">&amp;</span>u.f_decode2, insn);
</span></span><span style="display:flex;"><span>  <span style="color:#66d9ef">if</span> (<span style="color:#a6e22e">trans_or</span>(ctx, <span style="color:#f92672">&amp;</span>u.f_decode2)) <span style="color:#66d9ef">return</span> true;
</span></span><span style="display:flex;"><span>  <span style="color:#66d9ef">return</span> false;
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></td></tr></table>
</div>
</div><p>當指令的值符合 <code>nop</code> 及 <code>copy</code> 這個內層 <code>Pattern Group</code> 時，會先判斷該指令是否符合 <code>nop</code> 指令的定義，且 <code>trans_nop()</code> 的回傳值為 <code>true</code>。否則的話，就會繼續判斷是否符合同組中的 <code>copy</code> 指令。若都不符，就會再判斷是否符合外層 <code>Pattern Group</code> 的 <code>or</code> 指令。若仍不符，才會回傳 <code>false</code> 表示 decode 失敗。</p>
<p>與單純使用 <code>Pattern</code> 最大不同的是，當一 <code>Pattern</code> 的 <code>trans_*()</code> 回傳值為 <code>false</code> 時，不會直接回傳 <code>false</code> (代表 decode 失敗)，而是會接續著判斷後續的 <code>Patterns</code> 是否相符。</p>
<hr>
<p>RISC-V Compressed-Extension 中的 <code>c.ebreak</code>、<code>c.jalr</code>、及 <code>c.add</code> 指令，由於這三個指令的格式非常相似，因此非常適合使用 <code>Pattern Group</code> 來定義：</p>
<p><img alt="RISC-V Compressed-Extension instruction formats" loading="lazy" src="/posts/qemu-decodetree-part2/risc_v_c_insn.png"></p>
<p>RISC-V spec. 中定義：</p>
<p><code>C.EBREAK</code> shares the <code>opcode</code> with the <code>C.ADD</code> instruction, but with <code>rd</code> and <code>rs2</code> both <code>zero</code>, thus can also use the <code>CR</code> format.</p>
<p><code>C.JALR</code> is only valid when <code>rs1≠x0</code>; the code point with <code>rs1=x0</code> corresponds to the <code>C.EBREAK</code> instruction.</p>
<p><code>C.ADD</code> is only valid when <code>rs2≠x0</code>; the code points with <code>rs2=x0</code> correspond to the <code>C.JALR</code> and <code>C.EBREAK</code> instructions. The code points with <code>rs2̸=x0</code> and <code>rd=x0</code> are <code>HINTs</code>.</p>
<p><code>c.ebreak</code>、<code>c.jalr</code>、<code>c.add</code> 三個指令：</p>
<ul>
<li>insn[15:13]、insn[12]、insn[1:0] 的值皆相同。</li>
<li>當 insn[11:7] 且 insn[6:2] 的值皆為 <code>0</code> (<code>rs1=0</code> 且 <code>rs2=0</code>) 時為 <code>c.ebreak</code> 指令。</li>
<li>當只有 insn[11:7] 的值為 <code>0</code> (<code>rs1=0</code> 且 <code>rs2≠0</code>) 時為 <code>c.jalr</code> 指令。</li>
<li>否則為 <code>c.add</code> 指令 (<code>rs1≠x0</code> 且 <code>rs2≠0</code>)。</li>
</ul>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-16-1"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-16-1"> 1</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-16-2"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-16-2"> 2</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-16-3"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-16-3"> 3</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-16-4"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-16-4"> 4</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-16-5"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-16-5"> 5</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-16-6"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-16-6"> 6</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-16-7"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-16-7"> 7</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-16-8"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-16-8"> 8</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-16-9"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-16-9"> 9</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-16-10"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-16-10">10</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-16-11"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-16-11">11</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-16-12"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-16-12">12</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-16-13"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-16-13">13</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-16-14"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-16-14">14</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-16-15"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-16-15">15</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-16-16"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-16-16">16</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-16-17"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-16-17">17</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-16-18"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-16-18">18</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-16-19"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-16-19">19</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-16-20"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-16-20">20</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-16-21"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-16-21">21</a>
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-text" data-lang="text"><span style="display:flex;"><span># Fields
</span></span><span style="display:flex;"><span>%rd        7:5
</span></span><span style="display:flex;"><span>%rs2_5     2:5
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span># Argument Sets
</span></span><span style="display:flex;"><span>&amp;r         rd rs1 rs2   !extern
</span></span><span style="display:flex;"><span>&amp;i         imm rs1 rd   !extern
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span># Formats
</span></span><span style="display:flex;"><span>@cr        ....  ..... .....  .. &amp;r      rs2=%rs2_5       rs1=%rd     %rd
</span></span><span style="display:flex;"><span>@c_jalr    ... . .....  ..... .. &amp;i      imm=0 rs1=%rd
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span># Pattern Groups
</span></span><span style="display:flex;"><span>{
</span></span><span style="display:flex;"><span>  ebreak          100 1  00000  00000 10
</span></span><span style="display:flex;"><span>  jalr            100 1  .....  00000 10 @c_jalr rd=1  # C.JALR
</span></span><span style="display:flex;"><span>  add             100 1  .....  ..... 10 @cr
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></td></tr></table>
</div>
</div><p>所生成的 decoder 如下：</p>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-17-1"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-17-1"> 1</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-17-2"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-17-2"> 2</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-17-3"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-17-3"> 3</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-17-4"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-17-4"> 4</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-17-5"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-17-5"> 5</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-17-6"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-17-6"> 6</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-17-7"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-17-7"> 7</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-17-8"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-17-8"> 8</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-17-9"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-17-9"> 9</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-17-10"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-17-10">10</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-17-11"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-17-11">11</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-17-12"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-17-12">12</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-17-13"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-17-13">13</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-17-14"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-17-14">14</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-17-15"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-17-15">15</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-17-16"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-17-16">16</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-17-17"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-17-17">17</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-17-18"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-17-18">18</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-17-19"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-17-19">19</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-17-20"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-17-20">20</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-17-21"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-17-21">21</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-17-22"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-17-22">22</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-17-23"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-17-23">23</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-17-24"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-17-24">24</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-17-25"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-17-25">25</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-17-26"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-17-26">26</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-17-27"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-17-27">27</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-17-28"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-17-28">28</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-17-29"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-17-29">29</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-17-30"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-17-30">30</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-17-31"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-17-31">31</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-17-32"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-17-32">32</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-17-33"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-17-33">33</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-17-34"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-17-34">34</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-17-35"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-17-35">35</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-17-36"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-17-36">36</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-17-37"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-17-37">37</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-17-38"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-17-38">38</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-17-39"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-17-39">39</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-17-40"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-17-40">40</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-17-41"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-17-41">41</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-17-42"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-17-42">42</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-17-43"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-17-43">43</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-17-44"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-17-44">44</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-17-45"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-17-45">45</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-17-46"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-17-46">46</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-17-47"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-17-47">47</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-17-48"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-17-48">48</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-17-49"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-17-49">49</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-17-50"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-17-50">50</a>
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-c" data-lang="c"><span style="display:flex;"><span><span style="color:#66d9ef">static</span> <span style="color:#66d9ef">void</span> <span style="color:#a6e22e">decode_insn16_extract_c_jalr</span>(DisasContext <span style="color:#f92672">*</span>ctx, arg_i <span style="color:#f92672">*</span>a, <span style="color:#66d9ef">uint16_t</span> insn)
</span></span><span style="display:flex;"><span>{
</span></span><span style="display:flex;"><span>    a<span style="color:#f92672">-&gt;</span>imm <span style="color:#f92672">=</span> <span style="color:#ae81ff">0</span>; <span style="color:#75715e">// 在 c_jalr 的 Format 中指定 imm 的值為 0
</span></span></span><span style="display:flex;"><span>    a<span style="color:#f92672">-&gt;</span>rs1 <span style="color:#f92672">=</span> <span style="color:#a6e22e">extract32</span>(insn, <span style="color:#ae81ff">7</span>, <span style="color:#ae81ff">5</span>);
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">static</span> <span style="color:#66d9ef">void</span> <span style="color:#a6e22e">decode_insn16_extract_cr</span>(DisasContext <span style="color:#f92672">*</span>ctx, arg_r <span style="color:#f92672">*</span>a, <span style="color:#66d9ef">uint16_t</span> insn)
</span></span><span style="display:flex;"><span>{
</span></span><span style="display:flex;"><span>    a<span style="color:#f92672">-&gt;</span>rs2 <span style="color:#f92672">=</span> <span style="color:#a6e22e">extract32</span>(insn, <span style="color:#ae81ff">2</span>, <span style="color:#ae81ff">5</span>);
</span></span><span style="display:flex;"><span>    a<span style="color:#f92672">-&gt;</span>rs1 <span style="color:#f92672">=</span> <span style="color:#a6e22e">extract32</span>(insn, <span style="color:#ae81ff">7</span>, <span style="color:#ae81ff">5</span>);
</span></span><span style="display:flex;"><span>    a<span style="color:#f92672">-&gt;</span>rd <span style="color:#f92672">=</span> <span style="color:#a6e22e">extract32</span>(insn, <span style="color:#ae81ff">7</span>, <span style="color:#ae81ff">5</span>);
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">static</span> <span style="color:#66d9ef">void</span> <span style="color:#a6e22e">decode_insn16_extract_decode_insn16_Fmt_2</span>(DisasContext <span style="color:#f92672">*</span>ctx, arg_decode_insn162 <span style="color:#f92672">*</span>a, <span style="color:#66d9ef">uint16_t</span> insn)
</span></span><span style="display:flex;"><span>{
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">static</span> <span style="color:#66d9ef">bool</span> <span style="color:#a6e22e">decode_insn16</span>(DisasContext <span style="color:#f92672">*</span>ctx, <span style="color:#66d9ef">uint16_t</span> insn)
</span></span><span style="display:flex;"><span>{
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">union</span> {
</span></span><span style="display:flex;"><span>        arg_decode_insn162 f_decode_insn162;
</span></span><span style="display:flex;"><span>        arg_i f_i;
</span></span><span style="display:flex;"><span>        arg_r f_r;
</span></span><span style="display:flex;"><span>    } u;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">switch</span> (insn <span style="color:#f92672">&amp;</span> <span style="color:#ae81ff">0x0000f003</span>) {
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">case</span> <span style="color:#ae81ff">0x00009002</span><span style="color:#f92672">:</span>
</span></span><span style="display:flex;"><span>        <span style="color:#75715e">/* 1001.... ......10 */</span>
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">if</span> ((insn <span style="color:#f92672">&amp;</span> <span style="color:#ae81ff">0x00000ffc</span>) <span style="color:#f92672">==</span> <span style="color:#ae81ff">0x00000000</span>) {
</span></span><span style="display:flex;"><span>            <span style="color:#75715e">/* 10010000 00000010 */</span>
</span></span><span style="display:flex;"><span>            <span style="color:#75715e">/* ./insn16.decode:20 */</span>
</span></span><span style="display:flex;"><span>            <span style="color:#a6e22e">decode_insn16_extract_decode_insn16_Fmt_2</span>(ctx, <span style="color:#f92672">&amp;</span>u.f_decode_insn162, insn);
</span></span><span style="display:flex;"><span>            <span style="color:#66d9ef">if</span> (<span style="color:#a6e22e">trans_ebreak</span>(ctx, <span style="color:#f92672">&amp;</span>u.f_decode_insn162)) <span style="color:#66d9ef">return</span> true;
</span></span><span style="display:flex;"><span>            <span style="color:#75715e">// 這邊沒有直接回傳 false，讓 switch-case 繼續往下執行
</span></span></span><span style="display:flex;"><span>        }
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">if</span> ((insn <span style="color:#f92672">&amp;</span> <span style="color:#ae81ff">0x0000007c</span>) <span style="color:#f92672">==</span> <span style="color:#ae81ff">0x00000000</span>) {
</span></span><span style="display:flex;"><span>            <span style="color:#75715e">/* 1001.... .0000010 */</span>
</span></span><span style="display:flex;"><span>            <span style="color:#75715e">/* ./insn16.decode:21 */</span>
</span></span><span style="display:flex;"><span>            <span style="color:#a6e22e">decode_insn16_extract_c_jalr</span>(ctx, <span style="color:#f92672">&amp;</span>u.f_i, insn);
</span></span><span style="display:flex;"><span>            u.f_i.rd <span style="color:#f92672">=</span> <span style="color:#ae81ff">1</span>; <span style="color:#75715e">// 在 jalr 的 Pattern 中指定 rd 的值為 0。
</span></span></span><span style="display:flex;"><span>            <span style="color:#66d9ef">if</span> (<span style="color:#a6e22e">trans_jalr</span>(ctx, <span style="color:#f92672">&amp;</span>u.f_i)) <span style="color:#66d9ef">return</span> true;
</span></span><span style="display:flex;"><span>            <span style="color:#75715e">// 這邊沒有直接回傳 false，讓 switch-case 繼續往下執行
</span></span></span><span style="display:flex;"><span>        }
</span></span><span style="display:flex;"><span>        <span style="color:#75715e">/* ./insn16.decode:22 */</span>
</span></span><span style="display:flex;"><span>        <span style="color:#a6e22e">decode_insn16_extract_cr</span>(ctx, <span style="color:#f92672">&amp;</span>u.f_r, insn);
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">if</span> (<span style="color:#a6e22e">trans_add</span>(ctx, <span style="color:#f92672">&amp;</span>u.f_r)) <span style="color:#66d9ef">return</span> true;
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">return</span> false;
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">return</span> false;
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></td></tr></table>
</div>
</div><p>當指令格式符合 <code>c.ebreak</code>、<code>c.jalr</code>、<code>c.add</code> 的 <code>Pattern Group</code> 時，會依序判斷該指令是否符合 <code>c.ebreak</code>、<code>c.jalr</code>、<code>c.add</code> 的定義以及其對應的 <code>trans_*()</code>。</p>
<p>另外值得一提的是，在 <code>c_jalr</code> <code>Format</code> 和 <code>jalr</code> <code>Pattern</code> 中有分別指定其 <code>imm</code> 及 <code>rd</code> 的值為 <code>0</code>，所生成的 codes 也會分別在對應的地方將該值設為 <code>0</code> (見 codes 註解說明)。</p>
<hr>
<p>以上就是 <code>Decodetree</code> 的語法說明。透過 <code>Decodetree</code>，我們不用再像以前以樣寫一大包的 <code>switch-case</code> 來 decode 指令。將不同類型的指令寫至不同的 decode 檔，不僅方便維護，閱讀起來也更為容易。</p>
]]></content:encoded>
    </item>
    <item>
      <title>QEMU Decodetree 語法介紹 (Part 1.)</title>
      <link>https://0xc0de.xyz/posts/qemu-decodetree-part1/</link>
      <pubDate>Fri, 31 Jan 2020 13:53:40 +0800</pubDate>
      <guid>https://0xc0de.xyz/posts/qemu-decodetree-part1/</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;⚠️ 本文所使用的 QEMU 版本為：&lt;code&gt;v4.2.0&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;QEMU 在 decode 指令的時候，需要呼叫各平台所定義的 instruction decoders 來解析指令。如在 ARM 平台下，就定義了：&lt;code&gt;disas_arm_insn()&lt;/code&gt;、&lt;code&gt;disas_thumb_insn()&lt;/code&gt; 及 &lt;code&gt;disas_thumb2_insn()&lt;/code&gt; 等來分別負責 ARM 32-bits 指令、ARM Thumb 指令及 ARM Thumb2 指令的解析。&lt;/p&gt;
&lt;p&gt;而 &lt;code&gt;Decodetree&lt;/code&gt; 則是由 &lt;code&gt;Bastian Koppelmann&lt;/code&gt; 於 2017 年在 porting RISC-V QEMU 的時候所提出來的機制 (詳見：&lt;a href=&#34;https://lists.gnu.org/archive/html/qemu-devel/2017-07/msg07735.html&#34;&gt;討論串 1&lt;/a&gt;、&lt;a href=&#34;https://lists.gnu.org/archive/html/qemu-devel/2017-10/msg05046.html&#34;&gt;討論串 2&lt;/a&gt;)。主因是過往的 instruction decoders (如：ARM) 都是採用一大包的 &lt;code&gt;switch-case&lt;/code&gt; 來做判斷。不僅難閱讀，也難以維護。&lt;/p&gt;
&lt;p&gt;因此 &lt;code&gt;Bastian Koppelmann&lt;/code&gt; 就提出了 &lt;code&gt;Decodetree&lt;/code&gt; 的機制，開發者只需要透過 &lt;code&gt;Decodetree&lt;/code&gt; 的語法定義各個指令的格式，便可交由 &lt;code&gt;Decodetree&lt;/code&gt; 來動態生成對應包含 &lt;code&gt;switch-case&lt;/code&gt; 的 instruction decoder &lt;code&gt;.c&lt;/code&gt; 檔。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;Decodetree&lt;/code&gt; 特別適合像 RISC-V 這種具有&lt;strong&gt;固定指令格式&lt;/strong&gt;的 ISA&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;因為各欄位都在固定的位置，(如 RISC-V 的 &lt;code&gt;opcode&lt;/code&gt; 都是固定在 &lt;code&gt;bits[6..0]&lt;/code&gt; 的位置)，各指令可重複使用的定義相較於其他的 ISA 來得多。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img alt=&#34;RISC-V instruction formats&#34; loading=&#34;lazy&#34; src=&#34;https://0xc0de.xyz/posts/qemu-decodetree-part1/riscv_insn_format.png&#34;&gt;&lt;/p&gt;</description>
      <content:encoded><![CDATA[<blockquote>
<p>⚠️ 本文所使用的 QEMU 版本為：<code>v4.2.0</code></p>
</blockquote>
<p>QEMU 在 decode 指令的時候，需要呼叫各平台所定義的 instruction decoders 來解析指令。如在 ARM 平台下，就定義了：<code>disas_arm_insn()</code>、<code>disas_thumb_insn()</code> 及 <code>disas_thumb2_insn()</code> 等來分別負責 ARM 32-bits 指令、ARM Thumb 指令及 ARM Thumb2 指令的解析。</p>
<p>而 <code>Decodetree</code> 則是由 <code>Bastian Koppelmann</code> 於 2017 年在 porting RISC-V QEMU 的時候所提出來的機制 (詳見：<a href="https://lists.gnu.org/archive/html/qemu-devel/2017-07/msg07735.html">討論串 1</a>、<a href="https://lists.gnu.org/archive/html/qemu-devel/2017-10/msg05046.html">討論串 2</a>)。主因是過往的 instruction decoders (如：ARM) 都是採用一大包的 <code>switch-case</code> 來做判斷。不僅難閱讀，也難以維護。</p>
<p>因此 <code>Bastian Koppelmann</code> 就提出了 <code>Decodetree</code> 的機制，開發者只需要透過 <code>Decodetree</code> 的語法定義各個指令的格式，便可交由 <code>Decodetree</code> 來動態生成對應包含 <code>switch-case</code> 的 instruction decoder <code>.c</code> 檔。</p>
<p><code>Decodetree</code> 特別適合像 RISC-V 這種具有<strong>固定指令格式</strong>的 ISA<sup id="fnref:1"><a href="#fn:1" class="footnote-ref" role="doc-noteref">1</a></sup>。</p>
<ul>
<li>因為各欄位都在固定的位置，(如 RISC-V 的 <code>opcode</code> 都是固定在 <code>bits[6..0]</code> 的位置)，各指令可重複使用的定義相較於其他的 ISA 來得多。</li>
</ul>
<p><img alt="RISC-V instruction formats" loading="lazy" src="/posts/qemu-decodetree-part1/riscv_insn_format.png"></p>
<p><code>Decodetree</code> 其實是由 Python script (<code>./scripts/decodetree.py</code>) 所撰寫的。其規格說明檔案可以參考：<code>./docs/devel/decodetree.rst</code>，裡面有詳細定義了其語法的格式。QEMU 在編譯時，會呼叫 <code>Decodetree</code>，根據各平台所定義的 decode 檔，動態生成對應的 decoder。</p>
<ul>
<li>
<p>如 RISC-V 的 instruction decoders 就是被定義在：<code>./target/riscv/*.decode</code> 中。其 <code>Makefile.obj</code> 就有如下的宣告：</p>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-0-1"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-0-1"> 1</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-0-2"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-0-2"> 2</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-0-3"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-0-3"> 3</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-0-4"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-0-4"> 4</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-0-5"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-0-5"> 5</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-0-6"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-0-6"> 6</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-0-7"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-0-7"> 7</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-0-8"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-0-8"> 8</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-0-9"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-0-9"> 9</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-0-10"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-0-10">10</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-0-11"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-0-11">11</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-0-12"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-0-12">12</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-0-13"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-0-13">13</a>
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-text" data-lang="text"><span style="display:flex;"><span>...
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>DECODETREE = $(SRC_PATH)/scripts/decodetree.py
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>decode32-y = $(SRC_PATH)/target/riscv/insn32.decode
</span></span><span style="display:flex;"><span>decode32-$(TARGET_RISCV64) += $(SRC_PATH)/target/riscv/insn32-64.decode
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>...
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>target/riscv/decode_insn32.inc.c: $(decode32-y) $(DECODETREE)
</span></span><span style="display:flex;"><span>	$(call quiet-command, \
</span></span><span style="display:flex;"><span>	  $(PYTHON) $(DECODETREE) -o $@ --static-decode decode_insn32 \
</span></span><span style="display:flex;"><span>          $(decode32-y), &#34;GEN&#34;, $(TARGET_DIR)$@)
</span></span></code></pre></td></tr></table>
</div>
</div><p>(實際參數說明請見 <a href="#decodetree-%E5%8F%83%E6%95%B8">decodetree 參數</a>)</p>
</li>
</ul>
<p><code>Decodetree</code> 的語法共分為：<a href="#fields">Fields</a>、<a href="#argument-sets">Argument Sets</a>、<a href="#formats">Formats</a>、<a href="/posts/qemu-decodetree-part2/#patterns">Patterns</a>、<a href="/posts/qemu-decodetree-part2/#pattern-groups">Pattern Groups</a> 五部分。本文將介紹如何透過 <code>Decodetree</code> 的語法，來動態生成一個指令的 decoder。</p>
<hr>
<h1 id="fields">Fields</h1>
<p><code>Field</code> 定義如何取出一指令中，各<strong>欄位</strong> (eg: <code>rd</code>, <code>rs1</code>, <code>rs2</code>, <code>imm</code>) 的值。</p>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-1-1"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-1-1">1</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-1-2"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-1-2">2</a>
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-text" data-lang="text"><span style="display:flex;"><span>field_def     := &#39;%&#39; identifier ( unnamed_field )* ( !function=identifier )?
</span></span><span style="display:flex;"><span>unnamed_field := number &#39;:&#39; ( &#39;s&#39; ) number
</span></span></code></pre></td></tr></table>
</div>
</div><p>其語法由 <code>%</code> 開頭，隨後緊接著一個 <code>identifier</code> 及零個或多個 <code>unamed_field</code>，並可再加上可選的 <code>!function</code>。</p>
<ul>
<li><code>identifier</code> 可由開發者自訂，如：<code>rd</code>、<code>imm</code>&hellip; 等。</li>
<li><code>unamed_field</code> 定義了該欄位的所在位元。第一個數字定義了該欄位的 <code>least-significant bit position</code>，第二個數字則定義了該欄位的<code>位元長度</code>。另外可加上可選的 <code>s</code> 字元來標明在取出該欄位後，是否需要做 <code>sign-extended</code>。
<ul>
<li>Eg：<code>%rd  7:5</code> 代表 <code>rd</code> 佔了指令中 bits 7 ~ bits 11 的位置 (insn[11:7])，共 5 bits。</li>
</ul>
</li>
<li><code>!function</code> 定義在擷取出該欄位的值後，所會再呼叫的 function。</li>
</ul>
<p><code>Field</code> (32-bits 指令) 最後會生成對應的 <code>extract32()</code> 及 <code>sextract32()</code> 程式碼<sup id="fnref:2"><a href="#fn:2" class="footnote-ref" role="doc-noteref">2</a></sup>，以用來取得指令中各欄位的值：</p>
<h3 id="examples">Examples</h3>
<table>
	<thead>
			<tr>
					<th>Input</th>
					<th>Generated code</th>
			</tr>
	</thead>
	<tbody>
			<tr>
					<td>%disp 0:s16</td>
					<td>sextract(i, 0, 16)</td>
			</tr>
			<tr>
					<td>%imm9 16:6 10:3</td>
					<td>extract(i, 16, 6) &laquo; 3 | extract(i, 10, 3)</td>
			</tr>
			<tr>
					<td>%disp12 0:s1 1:1 2:10</td>
					<td>sextract(i, 0, 1) &laquo; 11 | extract(i, 1, 1) &laquo; 10 | extract(i, 2, 10)</td>
			</tr>
			<tr>
					<td>%shimm8 5:s8 13:1 !function=expand_shimm8</td>
					<td>expand_shimm8(sextract(i, 5, 8) &laquo; 1 | extract(i, 13, 1))</td>
			</tr>
	</tbody>
</table>
<p>以 RISC-V 的 <code>U-type</code> 指令為例：</p>
<p><img alt="RISC-V U-type instruction" loading="lazy" src="/posts/qemu-decodetree-part1/riscv_u_type_insn.png"></p>
<p>其中，<code>imm</code> 佔 <code>insn[31:12]</code>，<code>rd</code> 佔 <code>insn[11:7]</code>，且 <code>imm</code> 需要做 <code>sign-extended</code>  後 <code>左移 12 位</code> (<code>20-bit immediate is shifted left by 12 bits to form U immediates</code>)。因此，如果我們要定義 RISC-V 的 <code>U-type</code> 指令，則可以宣告成：</p>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-2-1"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-2-1">1</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-2-2"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-2-2">2</a>
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-text" data-lang="text"><span style="display:flex;"><span>%rd       7:5
</span></span><span style="display:flex;"><span>%imm_u    12:s20                 !function=ex_shift_12
</span></span></code></pre></td></tr></table>
</div>
</div><p>最後會生成如下的程式碼：</p>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-3-1"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-3-1">1</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-3-2"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-3-2">2</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-3-3"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-3-3">3</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-3-4"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-3-4">4</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-3-5"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-3-5">5</a>
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-c" data-lang="c"><span style="display:flex;"><span><span style="color:#66d9ef">static</span> <span style="color:#66d9ef">void</span> <span style="color:#a6e22e">decode_insn32_extract_u</span>(DisasContext <span style="color:#f92672">*</span>ctx, arg_u <span style="color:#f92672">*</span>a, <span style="color:#66d9ef">uint32_t</span> insn)
</span></span><span style="display:flex;"><span>{
</span></span><span style="display:flex;"><span>    a<span style="color:#f92672">-&gt;</span>imm <span style="color:#f92672">=</span> <span style="color:#a6e22e">ex_shift_12</span>(ctx, <span style="color:#a6e22e">sextract32</span>(insn, <span style="color:#ae81ff">12</span>, <span style="color:#ae81ff">20</span>));
</span></span><span style="display:flex;"><span>    a<span style="color:#f92672">-&gt;</span>rd <span style="color:#f92672">=</span> <span style="color:#a6e22e">extract32</span>(insn, <span style="color:#ae81ff">7</span>, <span style="color:#ae81ff">5</span>);
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></td></tr></table>
</div>
</div><p>(P.S. <code>static void decode_insn32_extract_u()</code> 是由 <a href="#formats">Format</a> 定義所生成的，而 <code>arg_u *a</code> 則是由 <a href="#argument-sets">Argument Set</a> 定義所生成的，將會在後面的部分再做說明)</p>
<p>可以看到：</p>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-4-1"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-4-1">1</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-4-2"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-4-2">2</a>
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-c" data-lang="c"><span style="display:flex;"><span>a<span style="color:#f92672">-&gt;</span>imm <span style="color:#f92672">=</span> <span style="color:#a6e22e">ex_shift_12</span>(ctx, <span style="color:#a6e22e">sextract32</span>(insn, <span style="color:#ae81ff">12</span>, <span style="color:#ae81ff">20</span>));
</span></span><span style="display:flex;"><span>a<span style="color:#f92672">-&gt;</span>rd <span style="color:#f92672">=</span> <span style="color:#a6e22e">extract32</span>(insn, <span style="color:#ae81ff">7</span>, <span style="color:#ae81ff">5</span>);
</span></span></code></pre></td></tr></table>
</div>
</div><ul>
<li>
<p><code>a-&gt;imm</code> 是由 <code>insn[31:12]</code> 所取得並做 <code>sign-extended</code>，且會再呼叫 <code>ex_shift_12()</code> 來 <code>左移 12 個 bits</code>。</p>
<ul>
<li>P.S. RISC-V 的 <code>ex_shift_12()</code> 是透過定義在<code>./target/riscv/translate.c</code> 中 <code>EX_SH</code> 這個 macro 所展開的：</li>
</ul>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-5-1"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-5-1"> 1</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-5-2"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-5-2"> 2</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-5-3"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-5-3"> 3</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-5-4"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-5-4"> 4</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-5-5"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-5-5"> 5</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-5-6"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-5-6"> 6</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-5-7"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-5-7"> 7</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-5-8"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-5-8"> 8</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-5-9"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-5-9"> 9</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-5-10"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-5-10">10</a>
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-c" data-lang="c"><span style="display:flex;"><span><span style="color:#75715e">#define EX_SH(amount) \
</span></span></span><span style="display:flex;"><span><span style="color:#75715e">    static int ex_shift_##amount(DisasContext *ctx, int imm) \
</span></span></span><span style="display:flex;"><span><span style="color:#75715e">    {                                         \
</span></span></span><span style="display:flex;"><span><span style="color:#75715e">        return imm &lt;&lt; amount;                 \
</span></span></span><span style="display:flex;"><span><span style="color:#75715e">    }
</span></span></span><span style="display:flex;"><span><span style="color:#a6e22e">EX_SH</span>(<span style="color:#ae81ff">1</span>)
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">EX_SH</span>(<span style="color:#ae81ff">2</span>)
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">EX_SH</span>(<span style="color:#ae81ff">3</span>)
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">EX_SH</span>(<span style="color:#ae81ff">4</span>)
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">EX_SH</span>(<span style="color:#ae81ff">12</span>)
</span></span></code></pre></td></tr></table>
</div>
</div></li>
<li>
<p><code>a-&gt;rd</code> 是由 <code>insn[11:7]</code> 所取得。</p>
</li>
</ul>
<p>此外，在 <code>Decodetree</code> 的 spec. 中也有提到，我們可以透過只定義 <code>!function</code> 來直接呼叫該 function。在這種情況下，只有 <code>DisasContext</code> 會被傳入該 function。</p>
<p>One may use <code>!function</code> with zero <code>unnamed_fields</code>.  This case is called
a <strong>parameter</strong>, and the named function is only passed the <code>DisasContext</code>
and returns an integral value extracted from there.</p>
<p>如 ARM Thumb <code>./target/arm/t16.decode</code> 就有定義：</p>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-6-1"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-6-1">1</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-6-2"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-6-2">2</a>
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-text" data-lang="text"><span style="display:flex;"><span># Set S if the instruction is outside of an IT block.
</span></span><span style="display:flex;"><span>%s               !function=t16_setflags
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-7-1"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-7-1">1</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-7-2"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-7-2">2</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-7-3"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-7-3">3</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-7-4"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-7-4">4</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-7-5"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-7-5">5</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-7-6"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-7-6">6</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-7-7"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-7-7">7</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-7-8"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-7-8">8</a>
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-c" data-lang="c"><span style="display:flex;"><span><span style="color:#66d9ef">static</span> <span style="color:#66d9ef">void</span> <span style="color:#a6e22e">disas_t16_extract_addsub_2i</span>(DisasContext <span style="color:#f92672">*</span>ctx, arg_s_rri_rot <span style="color:#f92672">*</span>a, <span style="color:#66d9ef">uint16_t</span> insn)
</span></span><span style="display:flex;"><span>{
</span></span><span style="display:flex;"><span>    a<span style="color:#f92672">-&gt;</span>imm <span style="color:#f92672">=</span> <span style="color:#a6e22e">extract32</span>(insn, <span style="color:#ae81ff">6</span>, <span style="color:#ae81ff">3</span>);
</span></span><span style="display:flex;"><span>    a<span style="color:#f92672">-&gt;</span>rn <span style="color:#f92672">=</span> <span style="color:#a6e22e">extract32</span>(insn, <span style="color:#ae81ff">3</span>, <span style="color:#ae81ff">3</span>);
</span></span><span style="display:flex;"><span>    a<span style="color:#f92672">-&gt;</span>rd <span style="color:#f92672">=</span> <span style="color:#a6e22e">extract32</span>(insn, <span style="color:#ae81ff">0</span>, <span style="color:#ae81ff">3</span>);
</span></span><span style="display:flex;"><span>    a<span style="color:#f92672">-&gt;</span>s <span style="color:#f92672">=</span> <span style="color:#a6e22e">t16_setflags</span>(ctx); <span style="color:#75715e">// 呼叫 t16_setflags()，並傳入 DisasContext
</span></span></span><span style="display:flex;"><span>    a<span style="color:#f92672">-&gt;</span>rot <span style="color:#f92672">=</span> <span style="color:#ae81ff">0</span>;
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></td></tr></table>
</div>
</div><p>未包含任何 <code>unnamed_fields</code> 或 <code>!function</code> 的 <code>Field</code> 會被視為錯誤。</p>
<p>A field with no <code>unnamed_fields</code> and no <code>!function</code> is in error.</p>
<hr>
<h1 id="argument-sets">Argument Sets</h1>
<p><code>Argument Set</code> 定義用來保存從指令中所擷取出來各欄位的值。</p>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-8-1"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-8-1">1</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-8-2"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-8-2">2</a>
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-text" data-lang="text"><span style="display:flex;"><span>args_def    := &#39;&amp;&#39; identifier ( args_elt )+ ( !extern )?
</span></span><span style="display:flex;"><span>args_elt    := identifier
</span></span></code></pre></td></tr></table>
</div>
</div><p>其語法由 <code>&amp;</code> 開頭，隨後緊接著一個或多個的 <code>identifier</code> ，並可再加上可選的 <code>!extern</code> 。</p>
<ul>
<li><code>identifier</code> 可由開發者自訂，如：<code>regs</code>、<code>loadstore</code>&hellip; 等。</li>
<li><code>!extern</code> 則表示是否在其他地方已經由其他的 decoder 定義過。如果加上的話，就<strong>不會</strong>再次生成對應的 <code>argument set struct</code>。</li>
</ul>
<h3 id="examples-1">Examples</h3>
<hr>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-9-1"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-9-1">1</a>
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-text" data-lang="text"><span style="display:flex;"><span>&amp;ampreg3 ra rb rc
</span></span></code></pre></td></tr></table>
</div>
</div><p>會生成以下的 <code>argument set struct</code>：</p>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-10-1"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-10-1">1</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-10-2"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-10-2">2</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-10-3"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-10-3">3</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-10-4"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-10-4">4</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-10-5"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-10-5">5</a>
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-c" data-lang="c"><span style="display:flex;"><span><span style="color:#66d9ef">typedef</span> <span style="color:#66d9ef">struct</span> {
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">int</span> ra;
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">int</span> rb;
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">int</span> rc;
</span></span><span style="display:flex;"><span>} arg_reg3;
</span></span></code></pre></td></tr></table>
</div>
</div><hr>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-11-1"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-11-1">1</a>
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-text" data-lang="text"><span style="display:flex;"><span>&amp;loadstore reg base offset
</span></span></code></pre></td></tr></table>
</div>
</div><p>則會生成以下的 <code>argument set struct</code>：</p>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-12-1"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-12-1">1</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-12-2"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-12-2">2</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-12-3"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-12-3">3</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-12-4"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-12-4">4</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-12-5"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-12-5">5</a>
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-c" data-lang="c"><span style="display:flex;"><span><span style="color:#66d9ef">typedef</span> <span style="color:#66d9ef">struct</span> {
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">int</span> base;
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">int</span> offset;
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">int</span> reg;
</span></span><span style="display:flex;"><span>} arg_loadstore;
</span></span></code></pre></td></tr></table>
</div>
</div><hr>
<p>因此，以剛剛的 RISC-V <code>U-type</code> 指令為例，我們需要從指令中擷取 <code>imm</code> 及 <code>rd</code> 欄位的值，可以宣告其 <code>argument set</code> 如下：</p>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-13-1"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-13-1">1</a>
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-text" data-lang="text"><span style="display:flex;"><span>&amp;u    imm rd
</span></span></code></pre></td></tr></table>
</div>
</div><p>最後會生成以下的 <code>argument set struct</code>：</p>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-14-1"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-14-1">1</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-14-2"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-14-2">2</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-14-3"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-14-3">3</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-14-4"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-14-4">4</a>
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-c" data-lang="c"><span style="display:flex;"><span><span style="color:#66d9ef">typedef</span> <span style="color:#66d9ef">struct</span> {
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">int</span> imm;
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">int</span> rd;
</span></span><span style="display:flex;"><span>} arg_u;
</span></span></code></pre></td></tr></table>
</div>
</div><p>此 <code>argument set struct</code> 會被傳入由 <code>Format</code> 定義所生成的 extract function：</p>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-15-1"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-15-1">1</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-15-2"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-15-2">2</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-15-3"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-15-3">3</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-15-4"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-15-4">4</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-15-5"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-15-5">5</a>
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-c" data-lang="c"><span style="display:flex;"><span><span style="color:#66d9ef">static</span> <span style="color:#66d9ef">void</span> <span style="color:#a6e22e">decode_insn32_extract_u</span>(DisasContext <span style="color:#f92672">*</span>ctx, arg_u <span style="color:#f92672">*</span>a, <span style="color:#66d9ef">uint32_t</span> insn)
</span></span><span style="display:flex;"><span>{
</span></span><span style="display:flex;"><span>    a<span style="color:#f92672">-&gt;</span>imm <span style="color:#f92672">=</span> <span style="color:#a6e22e">ex_shift_12</span>(ctx, <span style="color:#a6e22e">sextract32</span>(insn, <span style="color:#ae81ff">12</span>, <span style="color:#ae81ff">20</span>));
</span></span><span style="display:flex;"><span>    a<span style="color:#f92672">-&gt;</span>rd <span style="color:#f92672">=</span> <span style="color:#a6e22e">extract32</span>(insn, <span style="color:#ae81ff">7</span>, <span style="color:#ae81ff">5</span>);
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></td></tr></table>
</div>
</div><p>所傳入的<code>arg_u</code> 會保存從指令中擷取出的 <code>imm</code> 及 <code>rd</code> 欄位的值，待後續使用。</p>
<hr>
<h1 id="formats">Formats</h1>
<p><code>Format</code> 定義了指令的格式 (如 RISC-V 中的 <code>R</code>、<code>I</code>、<code>S</code>、<code>B</code>、<code>U</code>、<code>J-type</code>)，並會生成對應的 decode function。</p>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-16-1"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-16-1">1</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-16-2"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-16-2">2</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-16-3"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-16-3">3</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-16-4"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-16-4">4</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-16-5"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-16-5">5</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-16-6"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-16-6">6</a>
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-text" data-lang="text"><span style="display:flex;"><span>fmt_def      := &#39;@&#39; identifier ( fmt_elt )+
</span></span><span style="display:flex;"><span>fmt_elt      := fixedbit_elt | field_elt | field_ref | args_ref
</span></span><span style="display:flex;"><span>fixedbit_elt := [01.-]+
</span></span><span style="display:flex;"><span>field_elt    := identifier &#39;:&#39; &#39;s&#39;? number
</span></span><span style="display:flex;"><span>field_ref    := &#39;%&#39; identifier | identifier &#39;=&#39; &#39;%&#39; identifier
</span></span><span style="display:flex;"><span>args_ref     := &#39;&amp;&#39; identifier
</span></span></code></pre></td></tr></table>
</div>
</div><p>其語法由 <code>@</code> 開頭，隨後緊接著一個 <code>identifier</code> 及一個以上的 <code>fmt_elt</code>。</p>
<ul>
<li><code>identifier</code> 可由開發者自訂，如：<code>opr</code>、<code>opi</code>&hellip; 等。</li>
<li><code>fmt_elt</code> 則可以採用以下不同的語法：
<ul>
<li>
<p><code>fixedbit_elt</code> 包含一個或多個  <code>0</code>、<code>1</code>、<code>.</code>、<code>-</code>，每一個代表指令中的 1 個 bit。</p>
<ul>
<li><code>.</code> 代表該 bit 可以用 <code>0</code> 或是 <code>1</code> 來表示。</li>
<li><code>-</code> 代表該 bit 完全被忽略。</li>
</ul>
</li>
<li>
<p><code>field_elt</code> 可以用 <a href="#fields">Field</a> 的語法來宣告。</p>
<ul>
<li>Eg：<code>ra:5</code>、<code>rb:5</code>、<code>lit:8</code></li>
</ul>
</li>
<li>
<p><code>field_ref</code> 有下列兩種格式 (以下範例參考上文所定義之 <a href="#fields">Field</a>)：</p>
<ul>
<li>
<p><code>'%' identifier</code>：直接參考一個被定義過的 <code>Field</code>。</p>
<ul>
<li>
<p>如：<code>%rd</code>，會生成：</p>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-17-1"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-17-1">1</a>
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-c" data-lang="c"><span style="display:flex;"><span>a<span style="color:#f92672">-&gt;</span>rd <span style="color:#f92672">=</span> <span style="color:#a6e22e">extract32</span>(insn, <span style="color:#ae81ff">7</span>, <span style="color:#ae81ff">5</span>);
</span></span></code></pre></td></tr></table>
</div>
</div></li>
</ul>
</li>
<li>
<p><code>identifier '=' '%' identifier</code>：直接參考一個被定義過的 <code>Field</code>，但透過第一個 <code>identifier</code> 來重新命名其所對應的 <code>argument</code> 名稱。此方式可以用來指定不同的 <code>argument</code> 名稱來參考至同一個 <code>Field</code>。</p>
<ul>
<li>
<p>如：<code>my_rd=%rd</code>，會生成：</p>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-18-1"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-18-1">1</a>
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-c" data-lang="c"><span style="display:flex;"><span>a<span style="color:#f92672">-&gt;</span>my_rd <span style="color:#f92672">=</span> <span style="color:#a6e22e">extract32</span>(insn, <span style="color:#ae81ff">7</span>, <span style="color:#ae81ff">5</span>); <span style="color:#75715e">// rd 被重新命名為 my_rd
</span></span></span></code></pre></td></tr></table>
</div>
</div></li>
</ul>
</li>
</ul>
</li>
<li>
<p><code>args_ref</code> 指定所傳入 decode function 的 <code>Argument Set</code>。若沒有指定 <code>args_ref</code> 的話，<code>Decodetree</code> 會根據 <code>field_elt</code> 或 <code>field_ref</code> 自動生成一個 <code>Argument Set</code>。此外，一個 <code>Format</code> 最多隻能包含一個 <code>args_ref</code>。</p>
</li>
</ul>
</li>
</ul>
<p>當 <code>fixedbit_elt</code> 或 <code>field_ref</code> 被定義時，該 <code>Foramt</code> 的所有的 bits 都必須被定義 (可透過 <code>fixedbit_elt</code> 或 <code>.</code> 來定義各個 bits，<code>空格</code>會被忽略)。</p>
<h3 id="examples-2">Examples</h3>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-19-1"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-19-1">1</a>
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-text" data-lang="text"><span style="display:flex;"><span>@opi    ...... ra:5 lit:8    1 ....... rc:5
</span></span></code></pre></td></tr></table>
</div>
</div><p>定義了 <code>op1</code> 這個 <code>Format</code>，其中：</p>
<ul>
<li>insn[31:26] 可為 <code>0</code> 或 <code>1</code>。</li>
<li>insn[25:21] 為 <code>ra</code>。</li>
<li>insn[20:13] 為 <code>lit</code>。</li>
<li>insn[12] 固定為 <code>1</code>。</li>
<li>insn[11:5] 可為 <code>0</code> 或 <code>1</code>。</li>
<li>insn[4:0] 為 <code>rc</code>。</li>
</ul>
<p>此 <code>Format</code> 會生成以下的 decode function：</p>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-20-1"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-20-1"> 1</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-20-2"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-20-2"> 2</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-20-3"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-20-3"> 3</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-20-4"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-20-4"> 4</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-20-5"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-20-5"> 5</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-20-6"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-20-6"> 6</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-20-7"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-20-7"> 7</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-20-8"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-20-8"> 8</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-20-9"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-20-9"> 9</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-20-10"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-20-10">10</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-20-11"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-20-11">11</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-20-12"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-20-12">12</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-20-13"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-20-13">13</a>
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-c" data-lang="c"><span style="display:flex;"><span><span style="color:#66d9ef">typedef</span> <span style="color:#66d9ef">struct</span> {
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">int</span> lit;
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">int</span> ra;
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">int</span> rc;
</span></span><span style="display:flex;"><span>} arg_decode_insn320;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">static</span> <span style="color:#66d9ef">void</span> <span style="color:#a6e22e">decode_insn32_extract_opi</span>(DisasContext <span style="color:#f92672">*</span>ctx, arg_decode_insn320 <span style="color:#f92672">*</span>a, <span style="color:#66d9ef">uint32_t</span> insn)
</span></span><span style="display:flex;"><span>{
</span></span><span style="display:flex;"><span>    a<span style="color:#f92672">-&gt;</span>ra <span style="color:#f92672">=</span> <span style="color:#a6e22e">extract32</span>(insn, <span style="color:#ae81ff">21</span>, <span style="color:#ae81ff">5</span>);
</span></span><span style="display:flex;"><span>    a<span style="color:#f92672">-&gt;</span>lit <span style="color:#f92672">=</span> <span style="color:#a6e22e">extract32</span>(insn, <span style="color:#ae81ff">13</span>, <span style="color:#ae81ff">8</span>);
</span></span><span style="display:flex;"><span>    a<span style="color:#f92672">-&gt;</span>rc <span style="color:#f92672">=</span> <span style="color:#a6e22e">extract32</span>(insn, <span style="color:#ae81ff">0</span>, <span style="color:#ae81ff">5</span>);
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></td></tr></table>
</div>
</div><p>由於我們沒有指定 <code>args_ref</code>，因此 <code>Decodetree</code> 根據了 <code>field_elt</code> 的定義，自動生成了 <code>arg_decode_insn320</code> 這個 <code>Argument Set</code>。</p>
<hr>
<p>以 RISC-V <code>I-type</code> 指令為例：</p>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-21-1"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-21-1"> 1</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-21-2"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-21-2"> 2</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-21-3"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-21-3"> 3</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-21-4"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-21-4"> 4</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-21-5"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-21-5"> 5</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-21-6"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-21-6"> 6</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-21-7"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-21-7"> 7</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-21-8"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-21-8"> 8</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-21-9"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-21-9"> 9</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-21-10"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-21-10">10</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-21-11"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-21-11">11</a>
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-text" data-lang="text"><span style="display:flex;"><span># Fields:
</span></span><span style="display:flex;"><span>%rs1       15:5
</span></span><span style="display:flex;"><span>%rd        7:5
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span># immediates:
</span></span><span style="display:flex;"><span>%imm_i    20:s12
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span># Argment sets:
</span></span><span style="display:flex;"><span>&amp;i    imm rs1 rd
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>@i       ........ ........ ........ ........ &amp;i      imm=%imm_i     %rs1 %rd
</span></span></code></pre></td></tr></table>
</div>
</div><p>定義了 <code>i</code> 這個 <code>Format</code>，其中：</p>
<ul>
<li>insn[31:20] 為 <code>imm</code>，且為 <code>sign-extended</code>。</li>
<li>insn[19:5] 為 <code>rs1</code>。</li>
<li>insn[11:7] 為 <code>rd</code>。</li>
</ul>
<p>此外，我們可以看到：</p>
<ul>
<li>此 <code>Format</code> 指定了 <code>Argument Set</code>：<code>&amp;i</code>。 <code>&amp;i</code> 中必須包含所有有用到的 <code>arguments</code> (也就是：<code>imm</code>、<code>rs1</code> 及 <code>rd</code>)</li>
<li><code>imm</code> 是透過重新命名的方式來參考 <code>%imm_i</code> 這個 <code>Field</code>。</li>
</ul>
<p>此範例會生成以下的 decode function：</p>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-22-1"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-22-1"> 1</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-22-2"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-22-2"> 2</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-22-3"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-22-3"> 3</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-22-4"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-22-4"> 4</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-22-5"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-22-5"> 5</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-22-6"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-22-6"> 6</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-22-7"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-22-7"> 7</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-22-8"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-22-8"> 8</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-22-9"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-22-9"> 9</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-22-10"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-22-10">10</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-22-11"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-22-11">11</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-22-12"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-22-12">12</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-22-13"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-22-13">13</a>
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-c" data-lang="c"><span style="display:flex;"><span><span style="color:#66d9ef">typedef</span> <span style="color:#66d9ef">struct</span> {
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">int</span> imm;
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">int</span> rd;
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">int</span> rs1;
</span></span><span style="display:flex;"><span>} arg_i;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">static</span> <span style="color:#66d9ef">void</span> <span style="color:#a6e22e">decode_insn32extract_i</span>(DisasContext <span style="color:#f92672">*</span>ctx, arg_i <span style="color:#f92672">*</span>a, <span style="color:#66d9ef">uint32_t</span> insn)
</span></span><span style="display:flex;"><span>{
</span></span><span style="display:flex;"><span>    a<span style="color:#f92672">-&gt;</span>imm <span style="color:#f92672">=</span> <span style="color:#a6e22e">sextract32</span>(insn, <span style="color:#ae81ff">20</span>, <span style="color:#ae81ff">12</span>); <span style="color:#75715e">// imm_i 被重新命名為 imm
</span></span></span><span style="display:flex;"><span>    a<span style="color:#f92672">-&gt;</span>rs1 <span style="color:#f92672">=</span> <span style="color:#a6e22e">extract32</span>(insn, <span style="color:#ae81ff">15</span>, <span style="color:#ae81ff">5</span>);
</span></span><span style="display:flex;"><span>    a<span style="color:#f92672">-&gt;</span>rd <span style="color:#f92672">=</span> <span style="color:#a6e22e">extract32</span>(insn, <span style="color:#ae81ff">7</span>, <span style="color:#ae81ff">5</span>);
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></td></tr></table>
</div>
</div><p>相比於第一個範例，由於這次我們有指定 <code>args_ref</code>：<code>&amp;i</code>，因此對應的 <code>arg_i</code> 會被傳入 decode function。</p>
<hr>
<p>回到先前的 RISC-V <code>U-type</code> 指令，我們可以如同 <code>I-type</code> 指令定義其格式：</p>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-23-1"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-23-1"> 1</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-23-2"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-23-2"> 2</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-23-3"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-23-3"> 3</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-23-4"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-23-4"> 4</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-23-5"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-23-5"> 5</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-23-6"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-23-6"> 6</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-23-7"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-23-7"> 7</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-23-8"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-23-8"> 8</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-23-9"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-23-9"> 9</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-23-10"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-23-10">10</a>
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-text" data-lang="text"><span style="display:flex;"><span># Fields:
</span></span><span style="display:flex;"><span>%rd        7:5
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span># immediates:
</span></span><span style="display:flex;"><span>%imm_u    12:s20                 !function=ex_shift_12
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span># Argument sets:
</span></span><span style="display:flex;"><span>&amp;u    imm rd
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>@u       ....................      ..... ....... &amp;u      imm=%imm_u          %rd
</span></span></code></pre></td></tr></table>
</div>
</div><p>定義了 <code>u</code> 這個 <code>Format</code>，其中：</p>
<ul>
<li>insn[31:12] 為 <code>imm</code>，且為 <code>sign-extended</code>。</li>
<li>insn[11:7] 為 <code>rd</code>。</li>
</ul>
<p>會生成以下的 decode function：</p>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-24-1"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-24-1"> 1</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-24-2"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-24-2"> 2</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-24-3"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-24-3"> 3</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-24-4"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-24-4"> 4</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-24-5"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-24-5"> 5</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-24-6"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-24-6"> 6</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-24-7"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-24-7"> 7</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-24-8"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-24-8"> 8</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-24-9"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-24-9"> 9</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-24-10"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-24-10">10</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-24-11"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-24-11">11</a>
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-c" data-lang="c"><span style="display:flex;"><span><span style="color:#66d9ef">typedef</span> <span style="color:#66d9ef">struct</span> {
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">int</span> imm;
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">int</span> rd;
</span></span><span style="display:flex;"><span>} arg_u;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">static</span> <span style="color:#66d9ef">void</span> <span style="color:#a6e22e">decode_insn32_extract_u</span>(DisasContext <span style="color:#f92672">*</span>ctx, arg_u <span style="color:#f92672">*</span>a, <span style="color:#66d9ef">uint32_t</span> insn)
</span></span><span style="display:flex;"><span>{
</span></span><span style="display:flex;"><span>    a<span style="color:#f92672">-&gt;</span>imm <span style="color:#f92672">=</span> <span style="color:#a6e22e">ex_shift_12</span>(ctx, <span style="color:#a6e22e">sextract32</span>(insn, <span style="color:#ae81ff">12</span>, <span style="color:#ae81ff">20</span>));
</span></span><span style="display:flex;"><span>    a<span style="color:#f92672">-&gt;</span>rd <span style="color:#f92672">=</span> <span style="color:#a6e22e">extract32</span>(insn, <span style="color:#ae81ff">7</span>, <span style="color:#ae81ff">5</span>);
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></td></tr></table>
</div>
</div><p>我們可以看到：</p>
<ul>
<li>此 <code>Format</code> 指定了 <code>Argument Set</code>：<code>&amp;u</code>。 <code>&amp;u</code> 中必須包含所有有用到的 <code>arguments</code> (也就是：<code>imm</code>、<code>rd</code>)</li>
<li><code>imm</code> 是透過重新命名的方式來參考 <code>%imm_u</code> 這個 <code>Field</code>。</li>
</ul>
<hr>
<p>以上就是 <code>Decodetree</code> 的 <a href="#fields">Fields</a>、<a href="#argument-sets">Argument Sets</a> 及 <a href="#formats">Formats</a> 語法的簡介。剩下的 <a href="/posts/qemu-decodetree-part2/#patterns">Patterns</a> 及 <a href="/posts/qemu-decodetree-part2/#pattern-groups">Pattern Groups</a> 就留到 <a href="/posts/qemu-decodetree-part2/">Part 2.</a> 再做介紹。</p>
<hr>
<h1 id="decodetree-參數">decodetree 參數</h1>
<ul>
<li><code>--translate</code>：translator function 的 prefix，預設為 <code>trans</code>。一旦指定後，translator function 的 scope 就不會再是 <code>static</code>。</li>
<li><code>--decode</code>：decode function 的 prefix，預設為 <code>decode</code>，且 scope 為 <code>static</code>。一旦指定後，decode function 的 scope 就不會再是 <code>static</code>。</li>
<li><code>--static-decode</code>：如同 <code>--decode</code>，不過 decode function 的 scope 仍維持為 <code>static</code>。</li>
<li><code>-o</code> / <code>--output</code>：指定生成的 decoder <code>.c</code> 檔路徑。</li>
<li><code>-w</code> / <code>--insnwidth</code>：指令長度，eg：<code>32</code> or <code>16</code>，預設為 <code>32</code>。</li>
<li><code>--varinsnwidth</code>：指令為不定長度。</li>
<li><code>最後一個參數</code>為輸入的 decode 檔路徑。</li>
</ul>
<p>執行範例：</p>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-25-1"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-25-1">1</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-25-2"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-25-2">2</a>
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>./decodetree.py -o target/riscv/decode_insn16.inc.c --static-decode decode_insn16 <span style="color:#ae81ff">\
</span></span></span><span style="display:flex;"><span>    -w <span style="color:#ae81ff">16</span> ./insn16.decode
</span></span></code></pre></td></tr></table>
</div>
</div><div class="footnotes" role="doc-endnotes">
<hr>
<ol>
<li id="fn:1">
<p>ARM 其實在 <code>Decodetree</code> 引進後，也有部分的 instructions 改採用 <code>Decodetree</code> 來動態生成對應的 instruction decoders，如 Thumb 指令：<code>./target/arm/t32.decode</code> 及 <code>./target/arm/t16.decode</code>。&#160;<a href="#fnref:1" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
<li id="fn:2">
<p><code>extract32()</code> 及 <code>sextract32()</code> 被定義在 <code>include/qemu/bitops.h</code>：</p>
<div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-26-1"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-26-1"> 1</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-26-2"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-26-2"> 2</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-26-3"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-26-3"> 3</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-26-4"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-26-4"> 4</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-26-5"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-26-5"> 5</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-26-6"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-26-6"> 6</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-26-7"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-26-7"> 7</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-26-8"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-26-8"> 8</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-26-9"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-26-9"> 9</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-26-10"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-26-10">10</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-26-11"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-26-11">11</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-26-12"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-26-12">12</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-26-13"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-26-13">13</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-26-14"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-26-14">14</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-26-15"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-26-15">15</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-26-16"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-26-16">16</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-26-17"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-26-17">17</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-26-18"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-26-18">18</a>
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-c" data-lang="c"><span style="display:flex;"><span><span style="color:#75715e">/**
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"> * extract32:
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"> * @value: the value to extract the bit field from
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"> * @start: the lowest bit in the bit field (numbered from 0)
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"> * @length: the length of the bit field
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"> *
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"> * Extract from the 32 bit input @value the bit field specified by the
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"> * @start and @length parameters, and return it. The bit field must
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"> * lie entirely within the 32 bit word. It is valid to request that
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"> * all 32 bits are returned (ie @length 32 and @start 0).
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"> *
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"> * Returns: the value of the bit field extracted from the input value.
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"> */</span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">static</span> <span style="color:#66d9ef">inline</span> <span style="color:#66d9ef">uint32_t</span> <span style="color:#a6e22e">extract32</span>(<span style="color:#66d9ef">uint32_t</span> value, <span style="color:#66d9ef">int</span> start, <span style="color:#66d9ef">int</span> length)
</span></span><span style="display:flex;"><span>{
</span></span><span style="display:flex;"><span>    <span style="color:#a6e22e">assert</span>(start <span style="color:#f92672">&gt;=</span> <span style="color:#ae81ff">0</span> <span style="color:#f92672">&amp;&amp;</span> length <span style="color:#f92672">&gt;</span> <span style="color:#ae81ff">0</span> <span style="color:#f92672">&amp;&amp;</span> length <span style="color:#f92672">&lt;=</span> <span style="color:#ae81ff">32</span> <span style="color:#f92672">-</span> start);
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">return</span> (value <span style="color:#f92672">&gt;&gt;</span> start) <span style="color:#f92672">&amp;</span> (<span style="color:#f92672">~</span><span style="color:#ae81ff">0U</span> <span style="color:#f92672">&gt;&gt;</span> (<span style="color:#ae81ff">32</span> <span style="color:#f92672">-</span> length));
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-27-1"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-27-1"> 1</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-27-2"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-27-2"> 2</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-27-3"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-27-3"> 3</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-27-4"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-27-4"> 4</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-27-5"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-27-5"> 5</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-27-6"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-27-6"> 6</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-27-7"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-27-7"> 7</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-27-8"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-27-8"> 8</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-27-9"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-27-9"> 9</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-27-10"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-27-10">10</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-27-11"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-27-11">11</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-27-12"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-27-12">12</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-27-13"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-27-13">13</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-27-14"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-27-14">14</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-27-15"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-27-15">15</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-27-16"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-27-16">16</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-27-17"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-27-17">17</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-27-18"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-27-18">18</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-27-19"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-27-19">19</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-27-20"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-27-20">20</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-27-21"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-27-21">21</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-27-22"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-27-22">22</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-27-23"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-27-23">23</a>
</span><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f" id="hl-27-24"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-27-24">24</a>
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-c" data-lang="c"><span style="display:flex;"><span><span style="color:#75715e">/**
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"> * sextract32:
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"> * @value: the value to extract the bit field from
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"> * @start: the lowest bit in the bit field (numbered from 0)
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"> * @length: the length of the bit field
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"> *
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"> * Extract from the 32 bit input @value the bit field specified by the
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"> * @start and @length parameters, and return it, sign extended to
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"> * an int32_t (ie with the most significant bit of the field propagated
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"> * to all the upper bits of the return value). The bit field must lie
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"> * entirely within the 32 bit word. It is valid to request that
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"> * all 32 bits are returned (ie @length 32 and @start 0).
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"> *
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"> * Returns: the sign extended value of the bit field extracted from the
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"> * input value.
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"> */</span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">static</span> <span style="color:#66d9ef">inline</span> <span style="color:#66d9ef">int32_t</span> <span style="color:#a6e22e">sextract32</span>(<span style="color:#66d9ef">uint32_t</span> value, <span style="color:#66d9ef">int</span> start, <span style="color:#66d9ef">int</span> length)
</span></span><span style="display:flex;"><span>{
</span></span><span style="display:flex;"><span>    <span style="color:#a6e22e">assert</span>(start <span style="color:#f92672">&gt;=</span> <span style="color:#ae81ff">0</span> <span style="color:#f92672">&amp;&amp;</span> length <span style="color:#f92672">&gt;</span> <span style="color:#ae81ff">0</span> <span style="color:#f92672">&amp;&amp;</span> length <span style="color:#f92672">&lt;=</span> <span style="color:#ae81ff">32</span> <span style="color:#f92672">-</span> start);
</span></span><span style="display:flex;"><span>    <span style="color:#75715e">/* Note that this implementation relies on right shift of signed
</span></span></span><span style="display:flex;"><span><span style="color:#75715e">     * integers being an arithmetic shift.
</span></span></span><span style="display:flex;"><span><span style="color:#75715e">     */</span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">return</span> ((<span style="color:#66d9ef">int32_t</span>)(value <span style="color:#f92672">&lt;&lt;</span> (<span style="color:#ae81ff">32</span> <span style="color:#f92672">-</span> length <span style="color:#f92672">-</span> start))) <span style="color:#f92672">&gt;&gt;</span> (<span style="color:#ae81ff">32</span> <span style="color:#f92672">-</span> length);
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></td></tr></table>
</div>
</div>&#160;<a href="#fnref:2" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></li>
</ol>
</div>
]]></content:encoded>
    </item>
  </channel>
</rss>
