title: Adding new instruction to RISCV-32ima: "bad RISCV-opcode"
body: <p>I'm seeking for help concerning the extensions I'm trying to add to <code>riscv</code>.</p>
  
  <h1>GLOBAL SETTING</h1>
  
  <p>My working baseline is a clone of the <a href="https://github.com/riscv/" rel="noreferrer"><code>riscv-tools</code> repo</a>, containing the usual tools, among which are:</p>
  
  <ul>
  <li>riscv-fesvr</li>
  <li>riscv-gnu-toolchain</li>
  <li>riscv-isa-sim </li>
  <li>riscv-opcodes </li>
  <li>riscv-pk</li>
  </ul>
  
  <p>nb: the last commit I cloned from was <code>c6d58cecb3862deb742e1a5cc9d1c682f2c50ba9</code> (2018-04-24). </p>
  
  <p>I base my work on a <code>riscv32-ima</code> core. I want to add one instruction to this processor's <code>ISA</code> that will activate a particular component within my processor. </p>
  
  <p>From the behavior of the proc itself, I have no problem: I modified spike and my instruction (as well as the component I add to the processor) work perfectly well. </p>
  
  <p>In assembler, the instruction would look like: </p>
  
  <pre><code>addi a0, a0, 0
  ...            // other code
  setupcomp      // activate my component ... 
  ...            // other code
  </code></pre>
  
  <p>See that this instruction has no operands whatsoever. </p>
  
  <h1>WHAT I DO</h1>
  
  <p>I duck-ducked-go-ed a while and found the <a href="https://github.com/riscv-mit/riscv-isa-sim/wiki/Adding-and-using-a-new-instruction" rel="noreferrer">this tutorial</a>, which is a bit old. </p>
  
  <p>So, I: </p>
  
  <ol>
  <li>go to <code>riscv-tools/riscv-opcodes/</code></li>
  <li><p>add the <code>opcode</code> and its mask to <code>riscv-tools/riscv-opcodes/opcodes</code>. Mine look like this: </p>
  
  <pre><code>setupcomp 31..28=ignore 27..20=ignore 19..15=ignore 14..12=0 11..7=ignore 6..2=0x1a 1..0=3
  </code></pre></li>
  <li><p>from there, I rebuild the necessary <code>.h</code> files: </p>
  
  <pre><code>make install
  </code></pre></li>
  <li><p>Now, I add the necessary <code>stucts</code> to <code>riscv-tools/riscv-gnu-toolchain/riscv-binutils-gdb/include/opcode/riscv-opc.h</code>, and I also declare the instruction officially: </p>
  
  <pre><code>#define MATCH_SETUPCOMP 0x6b
  #define MASK_SETUPCOMP  0x707f
  DECLARE_INSN(setupcomp, MATCH_SETUPCOMP, MASK_SETUPCOMP)
  </code></pre>
  
  <p>These values, I got from what was generated from the opcodes project. </p></li>
  <li><p>I also add the necessary definitions to: 
  <code>riscv-tools/riscv-gnu-toolchain/riscv-binutils-gdb/opcodes/riscv-opc.c</code>: </p>
  
  <pre><code>{"setupcomp", "I", "", MATCH_SETUPCOMP, MASK_SETUPCOMP, match_opcode, 0 },
  </code></pre></li>
  </ol>
  
  <p>Now, up to here, I believe I've done everything necessary. I still have a doubt on the opcode I want, but I don't believe this has an impact on the behavior I observe and which I describe now. </p>
  
  <h1>PROBLEM I HAVE</h1>
  
  <p>When I build everything with the <code>riscv-tools/build-rv32ima.sh script</code>, near the end of the process (I believe in something like a test suite) I get a message complaining that: </p>
  
  <pre><code>Assembler messages:
  Error: internal: bad RISC-V opcode (bits 0xffffffffffff8f80 undefined): setupcomp 
  Fatal error: Broken assembler.  No assembly attempted.
  make[6]: *** [lib_a-dummy.o] Error 1
  </code></pre>
  
  <p>I think I'm missing something in the declaration of the instruction, probably that this declaration is not "forwarded" properly to every part of the toolchain that actually needs it. 
  But I can't find where/what/how/when and I would very much appreciate any input on this. </p>
  
  <p>Of course, I'm most probably missing something obvious, so be gentle :) </p>