From: Luke Kenneth Casson Leighton Date: Tue, 9 Oct 2018 15:02:00 +0000 (+0100) Subject: add explanatory comment X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=7babc26b493d83ac7f3dd7d8f06a4fecd659d354;p=riscv-isa-sim.git add explanatory comment --- diff --git a/riscv/insn_template_sv.cc b/riscv/insn_template_sv.cc index d2f3500..27634e1 100644 --- a/riscv/insn_template_sv.cc +++ b/riscv/insn_template_sv.cc @@ -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