add explanatory comment
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Tue, 9 Oct 2018 15:02:00 +0000 (16:02 +0100)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Tue, 9 Oct 2018 15:02:00 +0000 (16:02 +0100)
riscv/insn_template_sv.cc

index d2f3500a1cd3871ea32fe33fb33b2e42b9df31c6..27634e14087afbb18eb3bfabb3db123818041aac 100644 (file)
@@ -1,5 +1,60 @@
 // See LICENSE for license details.
 
+/* state-machine for Simple-V "hardware-macro-loop-unroller".
+
+   yes, it's an absolute non-obvious mess, thankfully a reasonbly short one.
+   the mess is down to being a macro-top-heavy re-entrant state machine
+   that copes with all of the different formats of instructions, including
+   some quirks (branches, twin predication, compressed overloads are TODO).
+
+   the re-entrancy is required in case of exceptions.  the SV "STATE" CSR
+   includes the two element offsets (two because twin-predication for
+   c.mv and fcvt and friends needs two predicates, therefore two element
+   offsets, therefore can implement a vector-version of bitwise gather/scatter)
+
+   there is a lot going on here: id_regs.py (see riscv.mk.in) is responsible
+   for generating the regs_{insn}.h file, such that this template can just
+   #include the *standard scalar implementation, unmodified*.  that's the
+   whole point of SV.  exceptions to changes of behaviour are branches
+   (hence the alternative #define for set_pc, below).
+
+   also it is important to appreciate that id_regs.py generates #defines
+   for which predicate and offset that each instruction will use for
+   each register.  again, unfortunately, c.lwsp / c.fldsp here is an
+   exception to that rule (TODO).  the "if xlen == 32" test has to
+   be explicitly replicated, and the predication type/target explicitly
+   changed depending on that test, where in other cases it can be
+   determined by id_regs.py.
+
+   in case you're wondering: yes, really, id_regs.py actually parses
+   the actual riscv/insns/*.h implementations (all of them), looking
+   for uses of "RVC_RS1" and "WRITE_RD" and so on, as an indicator
+   of the register usage for that specific opcode.  whilst it was
+   hypothetically possible to use this repo, kindly written by michael clark:
+       https://github.com/michaeljclark/riscv-meta
+   it was instead decided that instead of having an extra dependency,
+   and then having to write parsers for those files, dealing with the
+   various quirks would be better done by just... parsing the actual spike
+   scalar instrucion implementation(s).  they contain the same information...
+   just in an easier-to-identify format.
+
+   the actual redirection (lookups of the register indices from the opcode
+   through the CSR tables) is done in sv_insn_t, through overloads on
+   rd, rs1-3, rvc_rs1, and for c.lwsp and friends, rvc_lwsp_imm.
+
+   the state machine is made more complex due to it coping with scalar-scalar,
+   scalar-vector, vector-scalar *and* vector-vector, dynamically, at runtime.
+   it also (for now) is disabled in hypervisor mode.  this is why the vlen is
+   set initially to 0, then later is set to a minimum of 1.
+
+   the state machine *also* copes with cases where registers are marked
+   *specifically* as "redirected but still scalar", and the twin-predication
+   version can also skip forward so that a scalar can be matched up with
+   a single bit-predicated vector.
+
+   it's *really* comprehensive in other words, for just 200 or so lines.
+ */
+
 #define xstr(s) str(s)
 #define str(s) #s