<?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>Emulator on 0xc0de</title>
    <link>https://0xc0de.xyz/categories/emulator/</link>
    <description>Recent content in Emulator 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/emulator/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">&lt;stdio.h&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 &lt; main &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-text" data-lang="text"><span style="display:flex;"><span>obj-y += 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 &lt;zhiwei_liu@c-sky.com&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/image.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/image%201.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/image.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/image.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/image%201.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>
    <item>
      <title>Cross-build RISC-V QEMU</title>
      <link>https://0xc0de.xyz/posts/cross-build-riscv-qemu/</link>
      <pubDate>Sun, 26 Jan 2020 00:00:00 +0800</pubDate>
      <guid>https://0xc0de.xyz/posts/cross-build-riscv-qemu/</guid>
      <description>&lt;h2 id=&#34;在-x86-64-上-cross-build-risc-v-qemu&#34;&gt;在 x86-64 上 cross-build RISC-V QEMU&lt;/h2&gt;
&lt;p&gt;&lt;em&gt;OS 為 Ubuntu 22.04&lt;/em&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;dpkg 加入 RISC-V 架構：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;sudo dpkg --add-architecture riscv64&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;新增 RISC-V package sources：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;sudo vim /etc/apt/sources.list&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;新增以下 RISC-V sources：&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;deb [arch=riscv64] http://ports.ubuntu.com jammy main restricted universe multiverse
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;deb [arch=riscv64] http://ports.ubuntu.com jammy-updates main restricted universe multiverse
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;deb [arch=riscv64] http://ports.ubuntu.com jammy-security main restricted universe multiverse
&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;/li&gt;
&lt;li&gt;
&lt;p&gt;並限制以下的 sources 為 amd64 (加上：&lt;code&gt;[arch=amd64]&lt;/code&gt;)：&lt;/p&gt;</description>
      <content:encoded><![CDATA[<h2 id="在-x86-64-上-cross-build-risc-v-qemu">在 x86-64 上 cross-build RISC-V QEMU</h2>
<p><em>OS 為 Ubuntu 22.04</em></p>
<ol>
<li>
<p>dpkg 加入 RISC-V 架構：</p>
<ul>
<li><code>sudo dpkg --add-architecture riscv64</code></li>
</ul>
</li>
<li>
<p>新增 RISC-V package sources：</p>
<ul>
<li>
<p><code>sudo vim /etc/apt/sources.list</code></p>
</li>
<li>
<p>新增以下 RISC-V sources：</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>deb [arch=riscv64] http://ports.ubuntu.com jammy main restricted universe multiverse
</span></span><span style="display:flex;"><span>deb [arch=riscv64] http://ports.ubuntu.com jammy-updates main restricted universe multiverse
</span></span><span style="display:flex;"><span>deb [arch=riscv64] http://ports.ubuntu.com jammy-security main restricted universe multiverse
</span></span></code></pre></td></tr></table>
</div>
</div></li>
<li>
<p>並限制以下的 sources 為 amd64 (加上：<code>[arch=amd64]</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><span style="white-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-text" data-lang="text"><span style="display:flex;"><span>deb [arch=amd64] http://security.ubuntu.com/ubuntu jammy-security main restricted
</span></span><span style="display:flex;"><span>deb [arch=amd64] http://security.ubuntu.com/ubuntu jammy-security universe
</span></span><span style="display:flex;"><span>deb [arch=amd64] http://security.ubuntu.com/ubuntu jammy-security multiverse
</span></span></code></pre></td></tr></table>
</div>
</div></li>
</ul>
</li>
<li>
<p>更新套件清單：</p>
<ul>
<li><code>sudo apt update</code></li>
</ul>
</li>
<li>
<p>安裝開發套件：</p>
<ul>
<li><code>sudo apt install crossbuild-essential-riscv64</code></li>
<li><code>sudo apt install zlib1g-dev:riscv64 libglib2.0-dev:riscv64 libpixman-1-dev:riscv64 libpcre2-dev:riscv64 libffi-dev:riscv64 libselinux1-dev:riscv64</code></li>
</ul>
</li>
<li>
<p>由於 Ubuntu 沒提供 <code>libmount.a</code>，需手動編譯 <code>util-linux</code> 並處理 <code>crc32c</code> 符號衝突：</p>
<ol>
<li>下載 <code>util-linux</code> source codes：
<ul>
<li><code>git clone git@github.com:util-linux/util-linux.git</code></li>
</ul>
</li>
<li><code>cd util-linux</code></li>
<li><code>./autogen.sh</code></li>
<li><code>./configure --host=riscv64-linux-gnu --enable-static --disable-shared --disable-all-programs --enable-libmount --enable-libblkid CFLAGS=&quot;-Dcrc32c=util_linux_crc32c&quot;</code></li>
<li><code>make -j</code></li>
</ol>
</li>
<li>
<p>複製 <code>libmount.a</code> 及 <code>libblkid.a</code> 至系統交叉編譯路徑：</p>
<ul>
<li><code>sudo cp .libs/libmount.a .libs/libblkid.a /usr/lib/riscv64-linux-gnu/</code></li>
</ul>
</li>
<li>
<p>設定環境變數：</p>
<ul>
<li><code>export PKG_CONFIG=pkg-config</code></li>
<li><code>export PKG_CONFIG_LIBDIR=/usr/lib/riscv64-linux-gnu/pkgconfig:/usr/share/pkgconfig</code></li>
<li><code>export PKG_CONFIG_SYSROOT_DIR=/</code></li>
</ul>
</li>
<li>
<p>切到 QEMU 的資料夾並 configure QEMU (with debug info and SLiRP)：</p>
<ul>
<li><code>./configure --cross-prefix=riscv64-linux-gnu- --cpu=riscv64 --target-list=riscv64-softmmu --static --enable-debug --enable-slirp -Ddefault_library=static</code>
<ul>
<li><code>default_library</code> 是 meson built-in 的參數用來控制當使用 <code>library()</code> 的時候要怎麼編譯：
<ul>
<li><code>shared</code>：將 library 編譯成 shared library (e.g., <code>.so</code>)</li>
<li><code>static</code>：將 library 編譯成 static library (e.g., <code>.a</code>)</li>
<li><code>both</code>：同時將 library 編譯成 shared 及 static libraries</li>
</ul>
</li>
<li><code>-Ddefault_library=static</code> 可以指定將 subprojects 編譯成 static libraries (e.g., <code>libslirp.a</code>)</li>
</ul>
</li>
</ul>
</li>
<li>
<p>編譯 QEMU：</p>
<ul>
<li><code>make -j</code></li>
</ul>
</li>
<li>
<p>最後 QEMU 的執行檔會在：<code>./build/qemu-system-riscv64</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-sh" data-lang="sh"><span style="display:flex;"><span>$ file build/qemu-system-riscv64
</span></span><span style="display:flex;"><span>build/qemu-system-riscv64: ELF 64-bit LSB executable, UCB RISC-V, RVC, double-float ABI, version <span style="color:#ae81ff">1</span> <span style="color:#f92672">(</span>SYSV<span style="color:#f92672">)</span>, statically linked, BuildID<span style="color:#f92672">[</span>sha1<span style="color:#f92672">]=</span>e5fb33b2ec9617aaae8890df5979b12e245f4f00, <span style="color:#66d9ef">for</span> GNU/Linux 4.15.0, with debug_info, not stripped
</span></span></code></pre></td></tr></table>
</div>
</div></li>
</ol>
]]></content:encoded>
    </item>
    <item>
      <title>Build QEMU environments</title>
      <link>https://0xc0de.xyz/posts/build-qemu-envs/</link>
      <pubDate>Sat, 25 Jan 2020 00:00:00 +0800</pubDate>
      <guid>https://0xc0de.xyz/posts/build-qemu-envs/</guid>
      <description>&lt;h1 id=&#34;build-qemu&#34;&gt;Build QEMU&lt;/h1&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;安裝所需的套件：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;sudo apt install autoconf automake autotools-dev curl libmpc-dev libmpfr-dev libgmp-dev gawk build-essential bison flex xinfo gperf libtool patchutils bc zlib1g-dev libexpat-dev git libncurses5-dev libpixman-1-dev&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;下載 QEMU source codes：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;git clone --recursive git@github.com:qemu/qemu.git&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;cd qemu&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;./configure --target-list=riscv64-softmmu,riscv32-softmmu,riscv64-linux-user,riscv32-linux-user&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;make -j&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;幾個好用的 debug configure 參數：
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;--extra-cflags=CFLAGS&lt;/code&gt;：append extra C compiler flags QEMU_CFLAGS
&lt;ul&gt;
&lt;li&gt;e.g. &lt;code&gt;--extra-cflags=&amp;quot;-g3 --save-temps&amp;quot;&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--extra-ldflags=LDFLAGS&lt;/code&gt;：append extra linker flags LDFLAGS&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--enable-debug-tcg&lt;/code&gt;：enable TCG debugging&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--disable-debug-tcg&lt;/code&gt;：disable TCG debugging (default)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--disable-debug-info&lt;/code&gt;：disable debugging information&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--enable-debug&lt;/code&gt;：enable common debug build options&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--disable-strip&lt;/code&gt;：disable stripping binaries&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--disable-werror&lt;/code&gt;：disable compilation abort on warning&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--enable-pie&lt;/code&gt;：build Position Independent Executables&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--disable-pie&lt;/code&gt;：do not build Position Independent Executables&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;幾個好用的執行參數：
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;-d item1,...&lt;/code&gt;：enable logging of specified items&lt;/p&gt;</description>
      <content:encoded><![CDATA[<h1 id="build-qemu">Build QEMU</h1>
<ol>
<li>
<p>安裝所需的套件：</p>
<ul>
<li><code>sudo apt install autoconf automake autotools-dev curl libmpc-dev libmpfr-dev libgmp-dev gawk build-essential bison flex xinfo gperf libtool patchutils bc zlib1g-dev libexpat-dev git libncurses5-dev libpixman-1-dev</code></li>
</ul>
</li>
<li>
<p>下載 QEMU source codes：</p>
<ul>
<li><code>git clone --recursive git@github.com:qemu/qemu.git</code></li>
</ul>
</li>
<li>
<p><code>cd qemu</code></p>
</li>
<li>
<p><code>./configure --target-list=riscv64-softmmu,riscv32-softmmu,riscv64-linux-user,riscv32-linux-user</code></p>
</li>
<li>
<p><code>make -j</code></p>
</li>
</ol>
<ul>
<li>幾個好用的 debug configure 參數：
<ul>
<li><code>--extra-cflags=CFLAGS</code>：append extra C compiler flags QEMU_CFLAGS
<ul>
<li>e.g. <code>--extra-cflags=&quot;-g3 --save-temps&quot;</code></li>
</ul>
</li>
<li><code>--extra-ldflags=LDFLAGS</code>：append extra linker flags LDFLAGS</li>
<li><code>--enable-debug-tcg</code>：enable TCG debugging</li>
<li><code>--disable-debug-tcg</code>：disable TCG debugging (default)</li>
<li><code>--disable-debug-info</code>：disable debugging information</li>
<li><code>--enable-debug</code>：enable common debug build options</li>
<li><code>--disable-strip</code>：disable stripping binaries</li>
<li><code>--disable-werror</code>：disable compilation abort on warning</li>
<li><code>--enable-pie</code>：build Position Independent Executables</li>
<li><code>--disable-pie</code>：do not build Position Independent Executables</li>
</ul>
</li>
<li>幾個好用的執行參數：
<ul>
<li>
<p><code>-d item1,...</code>：enable logging of specified items</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><span style="white-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-14"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-0-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-0-15"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-0-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-0-16"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-0-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-0-17"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-0-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-0-18"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-0-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-0-19"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-0-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-0-20"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-0-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-0-21"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-0-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-fallback" data-lang="fallback"><span style="display:flex;"><span>Log items (comma separated):
</span></span><span style="display:flex;"><span>out_asm         show generated host assembly code for each compiled TB
</span></span><span style="display:flex;"><span>in_asm          show target assembly code for each compiled TB
</span></span><span style="display:flex;"><span>op              show micro ops for each compiled TB
</span></span><span style="display:flex;"><span>op_opt          show micro ops after optimization
</span></span><span style="display:flex;"><span>op_ind          show micro ops before indirect lowering
</span></span><span style="display:flex;"><span>int             show interrupts/exceptions in short format
</span></span><span style="display:flex;"><span>exec            show trace before each executed TB (lots of logs)
</span></span><span style="display:flex;"><span>cpu             show CPU registers before entering a TB (lots of logs)
</span></span><span style="display:flex;"><span>fpu             include FPU registers in the &#39;cpu&#39; logging
</span></span><span style="display:flex;"><span>mmu             log MMU-related activities
</span></span><span style="display:flex;"><span>pcall           x86 only: show protected mode far calls/returns/exceptions
</span></span><span style="display:flex;"><span>cpu_reset       show CPU state before CPU resets
</span></span><span style="display:flex;"><span>unimp           log unimplemented functionality
</span></span><span style="display:flex;"><span>guest_errors    log when the guest OS does something invalid (eg accessing a
</span></span><span style="display:flex;"><span>non-existent register)
</span></span><span style="display:flex;"><span>page            dump pages at beginning of user mode emulation
</span></span><span style="display:flex;"><span>nochain         do not chain compiled TBs so that &#34;exec&#34; and &#34;cpu&#34; show
</span></span><span style="display:flex;"><span>complete traces
</span></span><span style="display:flex;"><span>strace          log every user-mode syscall, its input, and its result
</span></span><span style="display:flex;"><span>trace:PATTERN   enable trace events
</span></span></code></pre></td></tr></table>
</div>
</div></li>
<li>
<p><code>-D logfile</code>：output log to logfile (default stderr)</p>
</li>
</ul>
</li>
<li>References：
<ul>
<li><a href="https://github.com/riscv/riscv-qemu/wiki">RISC-V QEMU Wiki</a></li>
<li><a href="https://www.cnblogs.com/root-wang/p/8005212.html">QEMU Build Considerations For Debugging</a></li>
</ul>
</li>
</ul>
<hr>
<h1 id="build-risc-v-toolchains">Build RISC-V toolchains</h1>
<ol>
<li>
<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-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><span style="white-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-4"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-1-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-gdscript3" data-lang="gdscript3"><span style="display:flex;"><span>sudo apt<span style="color:#f92672">-</span>get install autoconf automake autotools<span style="color:#f92672">-</span>dev curl libmpc<span style="color:#f92672">-</span>dev \
</span></span><span style="display:flex;"><span>                     libmpfr<span style="color:#f92672">-</span>dev libgmp<span style="color:#f92672">-</span>dev gawk build<span style="color:#f92672">-</span>essential bison \
</span></span><span style="display:flex;"><span>                     flex texinfo gperf libtool patchutils bc zlib1g<span style="color:#f92672">-</span>dev \
</span></span><span style="display:flex;"><span>                     libexpat<span style="color:#f92672">-</span>dev
</span></span></code></pre></td></tr></table>
</div>
</div></li>
<li>
<p>下載 toolchains source codes：</p>
<ul>
<li><code>git clone --recursive [git@github.com](mailto:git@github.com):riscv/riscv-gnu-toolchain.git</code></li>
</ul>
</li>
<li>
<p><code>cd riscv-gnu-toolchain</code></p>
</li>
<li>
<p>Install：</p>
<ul>
<li>Newlib：
<ol>
<li><code>./configure --prefix=/opt/riscv</code></li>
<li><code>make</code></li>
</ol>
</li>
<li>Linux：
<ol>
<li><code>./configure --prefix=/opt/riscv</code></li>
<li><code>make linux</code></li>
</ol>
</li>
</ul>
</li>
<li>
<p>將 RISC-V toolchain binary 路徑加入 <code>PATH</code> 環境變數：</p>
<ul>
<li><code>export PATH=/opt/riscv/bin:$PATH</code></li>
</ul>
</li>
</ol>
<hr>
<h1 id="build-buildroot">Build Buildroot</h1>
<ol>
<li>下載 Buildroot source codes：
<ul>
<li><code>git clone [git@github.com](mailto:git@github.com):buildroot/buildroot.git</code></li>
</ul>
</li>
<li><code>make qemu_riscv64_virt_defconfig menuconfig</code>
<ul>
<li>如果不想由 bulidroot 編譯 Linux Kernel：
<ul>
<li>取消勾選：Kernel → Linux Kernel (<code>BR2_LINUX_KERNEL</code>)</li>
</ul>
</li>
<li>如果不想由 bulidroot 編譯 OpenSBI：
<ul>
<li>取消勾選：Bootloaders → opensbi (<code>BR2_TARGET_OPENSBI</code>)</li>
</ul>
</li>
<li>如果不想由 bulidroot 編譯 U-Boot：
<ul>
<li>取消勾選：Bootloaders →U-Boot (<code>BR2_TARGET_UBOOT</code>)</li>
</ul>
</li>
<li>如果不想由 buildroot 編譯 QEMU：
<ul>
<li>取消勾選：Host utilities → host qemu (<code>BR2_PACKAGE_HOST_QEMU</code>)</li>
</ul>
</li>
<li>如果想使用自行編譯的 toolchain：
<ul>
<li>Toolchain →Toolchain type → 選擇：External toolchain (<code>BR2_TOOLCHAIN_EXTERNAL</code>)</li>
<li>Toolchain → Toolchain → 選擇：Custom toolchain (<code>BR2_TOOLCHAIN_EXTERNAL_CUSTOM</code>)</li>
<li>Toolchain → Toolchain origin → 選擇：Pre-installed toolchain (<code>BR2_TOOLCHAIN_EXTERNAL_PREINSTALLED</code>)</li>
<li>設置 toolchain 的路徑：
<ul>
<li>Toolchain → Toolchain path (<code>BR2_TOOLCHAIN_EXTERNAL_PATH</code>)：
<ul>
<li>e.g. <code>/scratch3/yihaoc/sifive/toolchains/riscv64-unknown-linux-gnu-toolsuite-4.2.0-x86_64-linux-redhat8</code></li>
</ul>
</li>
</ul>
</li>
<li>設置 toolchain 的 prefix：
<ul>
<li>Toolchain → Toolchain prefix (<code>BR2_TOOLCHAIN_EXTERNAL_CUSTOM_PREFIX</code>)：
<ul>
<li>e.g. <code>$(ARCH)-unknown-linux-gnu</code></li>
</ul>
</li>
</ul>
</li>
<li>此外，還需根據所使用的 toolchain 設定其他的選項：
<ul>
<li>選擇 toolchain 的 gcc 版本：
<ul>
<li>Toolchain → External toolchain gcc version：
<ul>
<li>e.g. <code>14.x</code> (<code>BR2_TOOLCHAIN_EXTERNAL_GCC_14</code>)</li>
</ul>
</li>
</ul>
</li>
<li>選擇 toolchain 的 Kernel headers series：
<ul>
<li>Toolchain → External toolchain kernel headers series：
<ul>
<li>e.g. <code>6.18.x</code> (<code>BR2_TOOLCHAIN_EXTERNAL_HEADERS_6_18</code>)</li>
</ul>
</li>
</ul>
</li>
<li>選擇 toolchain 的 C library：
<ul>
<li>Toolchain → External toolchain C library：
<ul>
<li>e.g. <code>glibc</code> (<code>BR2_TOOLCHAIN_EXTERNAL_CUSTOM_GLIBC</code>)</li>
</ul>
</li>
</ul>
</li>
<li>選擇 toolchain 是否支援 RPC：
<ul>
<li>Toolchain → Toolchain has RPC support? (<code>BR2_TOOLCHAIN_EXTERNAL_INET_RPC</code>)
<ul>
<li>SiFive toolchain → <strong>No</strong></li>
</ul>
</li>
</ul>
</li>
<li>選擇 toolchain 是否支援 C++：
<ul>
<li>Toolchain → Toolchain has C++ support? (<code>BR2_TOOLCHAIN_EXTERNAL_CXX</code>)
<ul>
<li>SiFive toolchain → <strong>Yes</strong></li>
</ul>
</li>
</ul>
</li>
<li>選擇 toolchain 是否支援 Fortran：
<ul>
<li>Toolchain → Toolchain has Fortran support? (<code>BR2_TOOLCHAIN_EXTERNAL_FORTRAN</code>)
<ul>
<li>SiFive toolchain → <strong>Yes</strong></li>
</ul>
</li>
</ul>
</li>
<li>選擇 toolchain 是否支援 OpenMP：
<ul>
<li>Toolchain → Toolchain has OpenMP support?(<code>BR2_TOOLCHAIN_EXTERNAL_OPENMP</code>)
<ul>
<li>SiFive toolchain → <strong>Yes</strong></li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li>如果想使用 initramfs：
<ul>
<li>勾選：Filesystem images →cpio the root filesystem (for use as an initial RAM filesystem) (<code>BR2_TARGET_ROOTFS_CPIO</code>)</li>
</ul>
</li>
<li>編譯 rootfs 以及選擇 rootfs 的格式：
<ul>
<li>Filesystem images → ext2/3/4 root filesystem (<code>BR2_TARGET_ROOTFS_EXT2</code>)</li>
<li>Filesystem images → ext2/3/4 root filesystem → ext2/3/4 variant：
<ul>
<li>e.g. ext4 (<code>BR2_TARGET_ROOTFS_EXT2_4</code>)</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li><code>make -j</code></li>
</ol>
<hr>
<h1 id="build-busybox">Build Busybox</h1>
<ol>
<li>下載 Busybox source codes：
<ul>
<li><code>git clone [git@github.com](mailto:git@github.com):mirror/busybox.git</code></li>
</ul>
</li>
<li>編譯 Busybox：
<ul>
<li><code>make ARCH=riscv CROSS_COMPILE=riscv64-unknown-linux-gnu- menuconfig</code></li>
<li>勾選：<code>Settings</code> → <code>Build static binary (no shared libs)</code> <code>(CONFIG_STATIC)</code>，以 statically linked 的方式編譯 Busybox
<ul>
<li>若無勾選，則預設會採用 dynamic linked 的方式編譯 Busybox，在建立 rootfs 的時候需要將所需的 library files 複製至 libs 資料夾，否則 Linux Kernel boot up 的時候會出現： <code>kernel panic - not syncing: No working init found.</code> 的錯誤訊息 (此訊息不一定是代表 <code>init</code>檔案找不到，無法正確執行 <code>init</code> 程式亦會顯示同樣的錯誤訊息)。</li>
</ul>
</li>
<li><code>make ARCH=riscv CROSS_COMPILE=riscv64-unknown-linux-gnu- -j</code></li>
</ul>
</li>
<li>將 Busybox 安裝至 <code>_install</code> 資料夾：
<ul>
<li><code>make ARCH=riscv CROSS_COMPILE=riscv64-unknown-linux-gnu- install</code></li>
</ul>
</li>
</ol>
<hr>
<h1 id="build-rootfs-from-busybox-if-rootfs-is-not-built-in-linux-kernel-image">Build rootfs from busybox (if rootfs is not built in Linux Kernel image)</h1>
<ol>
<li>
<p>建立大小為 10 MB 的 disk image：</p>
<ul>
<li><code>dd if=/dev/zero of=root.ext2 bs=1M count=10</code></li>
</ul>
</li>
<li>
<p>將 disk image 格式化為 <code>ext2</code>格式：</p>
<ul>
<li><code>mkfs.ext2 -F root.ext2</code></li>
</ul>
</li>
<li>
<p>掛載 rootfs：</p>
<ul>
<li><code>mkdir rootfs</code></li>
<li><code>sudo mount root.ext2 rootfs</code></li>
</ul>
</li>
<li>
<p><code>cd rootfs</code></p>
</li>
<li>
<p>複製 Busybox 至 rootfs：</p>
<ul>
<li><code>sudo cp -r ../busybox/_install/* .</code>
<ul>
<li>(假設 Busybox 的路徑為：<code>../busybox</code>)</li>
</ul>
</li>
</ul>
</li>
<li>
<p>建立所需的資料夾：</p>
<ul>
<li><code>sudo mkdir etc dev proc sys tmp</code></li>
</ul>
</li>
<li>
<p>建立 <code>etc/inittab</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><span style="white-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></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-fallback" data-lang="fallback"><span style="display:flex;"><span>::sysinit:/bin/busybox mount -t proc proc /proc
</span></span><span style="display:flex;"><span>::sysinit:/bin/busybox mount -t tmpfs tmpfs /tmp
</span></span><span style="display:flex;"><span>::sysinit:/bin/busybox --install -s
</span></span><span style="display:flex;"><span>::shutdown:/bin/umount -a -r
</span></span><span style="display:flex;"><span>::shutdown:/sbin/swapoff -a
</span></span><span style="display:flex;"><span>/dev/console::sysinit:-/bin/ash
</span></span></code></pre></td></tr></table>
</div>
</div></li>
<li>
<p>建立所需的裝置檔案：</p>
<ul>
<li><code>sudo mknod dev/console c 5 1</code></li>
<li><code>sudo mknod dev/null c 1 3</code></li>
</ul>
</li>
<li>
<p>解除掛載：</p>
<ul>
<li><code>cd .. &amp;&amp; sudo umount rootfs</code></li>
</ul>
</li>
</ol>
<hr>
<h1 id="bulid-opensbi">Bulid OpenSBI</h1>
<ol>
<li>下載 OpenSBI source codes：
<ul>
<li><code>git clone [git@github.com](mailto:git@github.com):riscv-software-src/opensbi.git</code></li>
</ul>
</li>
<li><code>make CROSS_COMPILE=riscv64-unknown-linux-gnu- PLATFORM=generic FW_TEXT_START=0x80000000 -j</code></li>
</ol>
<hr>
<h1 id="build-u-boot">Build U-Boot</h1>
<ol>
<li>下載 U-Boot source codes：
<ul>
<li><code>git clone [git@github.com](mailto:git@github.com):u-boot/u-boot.git</code></li>
</ul>
</li>
<li><strong>TODO</strong></li>
</ol>
<hr>
<h1 id="build-linux-kernel">Build Linux Kernel</h1>
<ol>
<li>下載 Linux Kernel source codes：
<ul>
<li><code>git clone [git@github.com](mailto:git@github.com):torvalds/linux.git</code></li>
</ul>
</li>
<li><code>make ARCH=riscv CROSS_COMPILE=riscv64-unknown-linux-gnu- menuconfig</code>
<ul>
<li>如果要使用 initramfs，且將 rootfs 直接編譯至核心中，則需：
<ul>
<li>勾選：General setup → Initial RAM filesystem and RAM disk (initramfs/initrd) support (<code>CONFIG_BLK_DEV_INITRD</code>)</li>
<li>並設置 initramfs rootfs 路徑 (<code>CONFIG_INITRAMFS_SOURCE</code>)
<ul>
<li>e.g. <code>/home/yihaoc/frankchang/buildroot/output/images/rootfs.cpio</code></li>
</ul>
</li>
</ul>
</li>
<li>如果想包含 debug symbols：
<ul>
<li>開啟 Kernel debugging：
<ul>
<li>Kernel hacking → Kernel debugging (<code>DEBUG_KERNEL</code>)</li>
</ul>
</li>
<li>選擇 DWARF debug info 版本：
<ul>
<li>Kernel hacking → Compile-time checks and compiler options → Debug information
<ul>
<li>e.g. Rely on the toolchain’s implicit default DWARF version (<code>DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT</code>)</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li>如果想要包含 devmem：
<ul>
<li>Device Drivers → Character devices → /dev/mem virtual device support (<code>CONFIG_DEVMEM</code>)</li>
</ul>
</li>
<li>切換 Compiler optimization level 為 Optimize for size (<code>-Os</code>)
<ul>
<li>勾選：General setup →Compiler optimization level → Optimize for size (-Os) (<code>CONFIG_CC_OPTIMIZE_FOR_SIZE</code>)</li>
</ul>
</li>
</ul>
</li>
<li><code>make ARCH=riscv CROSS_COMPILE=riscv64-unknown-linux-gnu- -j</code></li>
</ol>
<hr>
<h1 id="boot-qemu-with-linux-kernel-and-rootfs">Boot QEMU with Linux Kernel and rootfs</h1>
<h2 id="method-1-rootfs-built-in-in-linux-kernel-image">Method 1: rootfs built-in in Linux Kernel image:</h2>
<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></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-fallback" data-lang="fallback"><span style="display:flex;"><span>./qemu/build/qemu-system-riscv64 \
</span></span><span style="display:flex;"><span>        -nographic \
</span></span><span style="display:flex;"><span>        -machine virt \
</span></span><span style="display:flex;"><span>        -smp 4 \
</span></span><span style="display:flex;"><span>        -m 2G \
</span></span><span style="display:flex;"><span>        -bios ./opensbi/build/platform/generic/firmware/fw_jump.elf \
</span></span><span style="display:flex;"><span>        -kernel ./linux/arch/riscv/boot/Image \
</span></span><span style="display:flex;"><span>        -append &#34;root=/dev/vda ro console=ttyS0 earlycon&#34; \
</span></span><span style="display:flex;"><span>        -device virtio-net-device,netdev=usernet \
</span></span><span style="display:flex;"><span>        -netdev user,id=usernet,hostfwd=tcp::10000-:22
</span></span></code></pre></td></tr></table>
</div>
</div><ul>
<li>(假設 QEMU 執行檔的路徑為：<code>./qemu/build/qemu-system-riscv64</code>)</li>
<li>(假設 OpenSBI image 的路徑為：<code>./opensbi/build/platform/generic/firmware/fw_jump.elf</code>)</li>
<li>(假設 Linux Kernel image 的路徑為：<code>./linux/arch/riscv/boot/Image</code>)</li>
</ul>
<hr>
<h2 id="method-2-load-rootfs-from-disk">Method 2: Load rootfs from disk:</h2>
<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><span style="white-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-5"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-4-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-4-6"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-4-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-4-7"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-4-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-4-8"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-4-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-4-9"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-4-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-4-10"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-4-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-4-11"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-4-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-4-12"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-4-12">12</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-fallback" data-lang="fallback"><span style="display:flex;"><span>./qemu/build/qemu-system-riscv64 \
</span></span><span style="display:flex;"><span>        -nographic \
</span></span><span style="display:flex;"><span>        -machine virt \
</span></span><span style="display:flex;"><span>        -smp 4 \
</span></span><span style="display:flex;"><span>        -m 2G \
</span></span><span style="display:flex;"><span>        -bios ./opensbi/build/platform/generic/firmware/fw_jump.elf \
</span></span><span style="display:flex;"><span>        -kernel ./linux/arch/riscv/boot/Image \
</span></span><span style="display:flex;"><span>        -append &#34;root=/dev/vda ro console=ttyS0 earlycon&#34; \
</span></span><span style="display:flex;"><span>        -device virtio-blk-device,drive=hd0 \
</span></span><span style="display:flex;"><span>        -drive file=./images/root.ext2,format=raw,id=hd0 \
</span></span><span style="display:flex;"><span>        -device virtio-net-device,netdev=usernet \
</span></span><span style="display:flex;"><span>        -netdev user,id=usernet,hostfwd=tcp::10000-:22
</span></span></code></pre></td></tr></table>
</div>
</div><ul>
<li>(假設 QEMU 執行檔的路徑為：<code>./qemu/build/qemu-system-riscv64</code>)</li>
<li>(假設 OpenSBI image 的路徑為：<code>./opensbi/build/platform/generic/firmware/fw_jump.elf</code>)</li>
<li>(假設 Linux Kernel image 的路徑為：<code>./linux/arch/riscv/boot/Image</code>)</li>
<li>(假設 rootfs disk image 的路徑為：<code>./images/root.ext2</code>)</li>
<li>References：
<ul>
<li><a href="https://ithelp.ithome.com.tw/articles/10192454">第二日：環境架設及過程解析 - iT 邦幫忙 - iThome</a></li>
<li><a href="https://coldnew.github.io/6cc46ece/">使用 Busybox 建立 RISC-V 的迷你系統</a></li>
</ul>
</li>
</ul>
<hr>
<h1 id="debug-linux-kernel-with-gdb-with-qemu">Debug Linux Kernel with GDB with QEMU</h1>
<ul>
<li>
<p>Linux Kernel 需要勾選：</p>
<ul>
<li><code>Kernel hacking</code> → <code>Kernel debugging</code> <code>(CONFIG_DEBUG_KERNEL)</code></li>
<li><code>Kernel hacking</code> → <code>Compile-time checks and compiler options</code> → <code>Compile the kernel with debug info</code> <code>(CONFIG_DEBUG_INFO)</code></li>
<li><code>Kernel hacking</code> → <code>Compile-time checks and compiler options</code> → <code>Provide GDB scripts for kernel debugging</code> <code>(CONFIG_GDB_SCRIPTS)</code></li>
</ul>
</li>
<li>
<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-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></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-fallback" data-lang="fallback"><span style="display:flex;"><span>./qemu/riscv64-softmmu/qemu-system-riscv64 \
</span></span><span style="display:flex;"><span>        -nographic \
</span></span><span style="display:flex;"><span>        -machine virt \
</span></span><span style="display:flex;"><span>        -smp 4 \
</span></span><span style="display:flex;"><span>        -m 2G \
</span></span><span style="display:flex;"><span>        -kernel ./riscv-pk/build/bbl \
</span></span><span style="display:flex;"><span>        -append &#34;root=/dev/vda ro console=ttyS0 earlycon&#34; \
</span></span><span style="display:flex;"><span>        -device virtio-blk-device,drive=hd0 \
</span></span><span style="display:flex;"><span>        -drive file=root.ext2,format=raw,id=hd0 \
</span></span><span style="display:flex;"><span>        -device virtio-net-device,netdev=usernet \
</span></span><span style="display:flex;"><span>        -netdev user,id=usernet,hostfwd=tcp::10000-:22 \
</span></span><span style="display:flex;"><span>        -s -S
</span></span></code></pre></td></tr></table>
</div>
</div><ul>
<li><code>-S</code>：Freeze CPU at startup (use &lsquo;c&rsquo; to start execution).</li>
<li><code>-s</code>：Shorthand for <code>-gdb tcp::1234</code>.</li>
<li><code>-gdb dev</code>：Wait for gdb connection on <code>dev</code>.</li>
</ul>
</li>
<li>
<p>使用 GDB debug Linux Kernel：</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-fallback" data-lang="fallback"><span style="display:flex;"><span>riscv64-unknown-linux-gnu-gdb vmlinux
</span></span><span style="display:flex;"><span>&gt; (gdb) target remote :1234
</span></span></code></pre></td></tr></table>
</div>
</div></li>
<li>
<p>使用 CGDB debug Linux Kernel：</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-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></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-fallback" data-lang="fallback"><span style="display:flex;"><span>cgdb -d riscv64-unknown-linux-gnu-gdb vmlinux
</span></span><span style="display:flex;"><span>&gt; (gdb) target remote :1234
</span></span></code></pre></td></tr></table>
</div>
</div></li>
<li>
<p>References：</p>
<ul>
<li><a href="https://en.wikibooks.org/wiki/QEMU/Debugging_with_QEMU">QEMU/Debugging with QEMU</a></li>
<li><a href="https://consen.github.io/2018/01/17/debug-linux-kernel-with-qemu-and-gdb/">使用QEMU和GDB調試Linux內核</a></li>
</ul>
</li>
</ul>
<hr>
<h1 id="debug-qemu">Debug QEMU</h1>
<ul>
<li>
<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><span style="white-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><span style="white-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-3"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-8-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-8-4"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-8-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-8-5"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-8-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-8-6"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-8-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-8-7"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-8-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-8-8"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-8-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-8-9"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-8-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-8-10"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-8-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-8-11"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-8-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-8-12"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-8-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-8-13"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-8-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-8-14"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-8-14">14</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-fallback" data-lang="fallback"><span style="display:flex;"><span>./configure --help
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>Advanced options (experts only):
</span></span><span style="display:flex;"><span>  --extra-cflags=CFLAGS     append extra C compiler flags QEMU_CFLAGS
</span></span><span style="display:flex;"><span>  --extra-cxxflags=CXXFLAGS append extra C++ compiler flags QEMU_CXXFLAGS
</span></span><span style="display:flex;"><span>  --extra-ldflags=LDFLAGS   append extra linker flags LDFLAGS
</span></span><span style="display:flex;"><span>  --enable-debug            enable common debug build options
</span></span><span style="display:flex;"><span>  --disable-strip           disable stripping binaries
</span></span><span style="display:flex;"><span>  --enable-gprof            QEMU profiling with gprof
</span></span><span style="display:flex;"><span>  --enable-profiler         profiler support
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>Optional features, enabled with --enable-FEATURE and
</span></span><span style="display:flex;"><span>disabled with --disable-FEATURE, default is enabled if available:
</span></span><span style="display:flex;"><span>  pie                       Position Independent Executables (--disable-pie)
</span></span></code></pre></td></tr></table>
</div>
</div><ul>
<li><code>./configure --target-list=riscv64-softmmu --enable-debug</code></li>
<li><code>./configure --target-list=riscv64-softmmu --enable-debug --extra-cflags=&quot;-g3 --save-temps&quot; --extra-ldflags=&quot;-g3&quot; --disable-strip --disable-pie</code></li>
</ul>
</li>
<li>
<p>使用 GDB：</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></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-fallback" data-lang="fallback"><span style="display:flex;"><span>gdb --args ./qemu/riscv64-softmmu/qemu-system-riscv64 \
</span></span><span style="display:flex;"><span>        -nographic \
</span></span><span style="display:flex;"><span>        -machine virt \
</span></span><span style="display:flex;"><span>        -smp 4 \
</span></span><span style="display:flex;"><span>        -m 2G \
</span></span><span style="display:flex;"><span>        -kernel ./riscv-pk/build/bbl \
</span></span><span style="display:flex;"><span>        -append &#34;root=/dev/vda ro console=ttyS0&#34; \
</span></span><span style="display:flex;"><span>        -device virtio-blk-device,drive=hd0 \
</span></span><span style="display:flex;"><span>        -drive file=root.ext2,format=raw,id=hd0 \
</span></span><span style="display:flex;"><span>        -device virtio-net-device,netdev=usernet \
</span></span><span style="display:flex;"><span>        -netdev user,id=usernet,hostfwd=tcp::10000-:22
</span></span></code></pre></td></tr></table>
</div>
</div></li>
<li>
<p>使用 CGDB：</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><span style="white-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-6"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-10-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-10-7"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-10-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-10-8"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-10-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-10-9"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-10-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-10-10"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-10-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-10-11"><a style="outline:none;text-decoration:none;color:inherit" href="#hl-10-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-fallback" data-lang="fallback"><span style="display:flex;"><span>cgdb --args ./qemu/riscv64-softmmu/qemu-system-riscv64 \
</span></span><span style="display:flex;"><span>        -nographic \
</span></span><span style="display:flex;"><span>        -machine virt \
</span></span><span style="display:flex;"><span>        -smp 4 \
</span></span><span style="display:flex;"><span>        -m 2G \
</span></span><span style="display:flex;"><span>        -kernel ./riscv-pk/build/bbl \
</span></span><span style="display:flex;"><span>        -append &#34;root=/dev/vda ro console=ttyS0&#34; \
</span></span><span style="display:flex;"><span>        -device virtio-blk-device,drive=hd0 \
</span></span><span style="display:flex;"><span>        -drive file=root.ext2,format=raw,id=hd0 \
</span></span><span style="display:flex;"><span>        -device virtio-net-device,netdev=usernet \
</span></span><span style="display:flex;"><span>        -netdev user,id=usernet,hostfwd=tcp::10000-:22
</span></span></code></pre></td></tr></table>
</div>
</div></li>
<li>
<p>References：</p>
<ul>
<li><a href="https://www.cnblogs.com/root-wang/p/8005212.html">Setups For Debugging QEMU with GDB and DDD</a></li>
<li><a href="https://translatedcode.wordpress.com/2015/05/30/tricks-for-debugging-qemu-rr/">Tricks for debugging QEMU — rr</a></li>
</ul>
</li>
</ul>
<hr>
<h1 id="gdb--cgdb">GDB / CGDB</h1>
<ul>
<li><a href="https://github.com/hellogcc/100-gdb-tips">《100個gdb小技巧》</a></li>
<li><a href="https://cgdb.github.io/">cgdb</a></li>
<li><a href="https://tech.mozilla.com.tw/?p=3826">CGDB – 更好用的 GDB</a></li>
</ul>
<hr>
<h1 id="build-bbl-berkery-boot-loader">Build bbl (Berkery Boot Loader)</h1>
<ol>
<li>下載 riscv-pk source codes：
<ul>
<li><code>git clone [git@github.com](mailto:git@github.com):riscv/riscv-pk.git</code></li>
</ul>
</li>
<li><code>cd riscv-pk</code></li>
<li><code>mkdir build</code></li>
<li><code>cd build</code></li>
<li><code>../configure --enable-logo --with-payload=../../linux/vmlinux --host=riscv64-unknown-linux-gnu</code>
<ul>
<li>(假設 Linux Kernel vmlinux 的路徑為：<code>../../linux/vmlinux</code>)</li>
</ul>
</li>
<li><code>make -j</code></li>
</ol>
<p>P.S. 如果要使用 BBL 開機的話，QEMU 的 -kernel 參數要指定 BBL image：</p>
<p>e.g. <code>-kernel ./riscv-pk/build/bbl</code></p>
<ul>
<li>(假設 bbl 的路徑為： <code>./riscv-pk/build/bbl</code>)</li>
<li>References：
<ul>
<li><a href="https://github.com/riscv/riscv-pk">RISC-V Proxy Kernel and Boot Loader Github</a></li>
</ul>
</li>
</ul>
]]></content:encoded>
    </item>
  </channel>
</rss>
