(no commit message)
[libreriscv.git] / simple_v_extension / sv_prefix_proposal.rst
index 327bf0c35d5c0fc350f5fd130ef2887a253c99ee..9cfdd854164087ec888047631c6292d33320239c 100644 (file)
@@ -1,3 +1,5 @@
+[[!tag oldstandards]]
+
 SimpleV Prefix (SVprefix) Proposal v0.3
 =======================================
 
@@ -5,9 +7,14 @@ SimpleV Prefix (SVprefix) Proposal v0.3
 * Copyright (c) Luke Kenneth Casson Leighton, 2019
 
 This proposal is designed to be able to operate without SVorig, but not to
-require the absence of SVorig See Specification_.
+require the absence of SVorig. See Specification_.
+
+Principle: SVprefix embeds (unmodified) RVC and 32-bit scalar opcodes
+into 32, 48 and 64 bit RV formats, to provide Vectorisation context
+on a per-instruction basis.
 
 .. _Specification: http://libre-riscv.org/simple_v_extension/specification/
+.. _Appendix: http://libre-riscv.org/simple_v_extension/appendix/
 
 .. contents::
 
@@ -35,7 +42,7 @@ Options
 The following partial / full implementation options are possible:
 
 * SVPrefix augments the main Specification_
-* SVPregix operates independently, without the main spec VL (and MVL)
+* SVPrefix operates independently, without the main spec VL (and MVL)
   CSRs (in any priv level)
 * SVPrefix operates independently, without the main spec SUBVL CSRs
   (in any priv level)
@@ -50,31 +57,11 @@ that do not support each option.  For example, an implementation that
 has no support for VLtyp that sees an opcode with a nonzero VLtyp must
 raise an illegal instruction exception.
 
-Note that SVPrefix (VLtyp and svlen) and the main spec share (modify) the
-STATE CSR. P48 and P64 opcodes must **NOT** set VLtyp or svlen inside
-loops that also use VL or SUBVL. Doing so will result in undefined
-behaviour, as STATE will be affected by doing so.
-
-However, using VLtyp or svlen in standalone operations, or pushing (and
-restoring) the contents of the STATE CSR to the stack, or just storing
-its contents in a temporary register whilst executing a sequence of P48
-or P64 opcodes, is perfectly fine.
+Note that SVPrefix (VLtyp and svlen) has its own STATE CSR, SVPSTATE. This allows Prefixed operations to be re-entrant on traps, and to not affect VBLOCK use of VL or SUBVL.
 
-If the main Specification_ CSRs are to be supported, the STATE, VL, MVL
-and SUBVL CSRs all operate according to the main specification. Under
-the options above, hypothetically an implementor could choose not to
-support setting of VL, MVL or SUBVL (only allowing them to be set to
-a value of 1). Under such circumstances, where *neither* VL/MVL *nor*
-SUBVL are supported, STATE would then not be required either.
-
-If however support for SUBVL is to be provided, storing of the sub-vector
-offsets and SUBVL itself (and context switching of the same) in the
-STATE CSRs are mandatory.
-
-Likewise if support for VL is to be provided, storing of VL, MVL and the
-dest and src offsets (and context switching of the same) in the STATE
-CSRs are mandatory.
+If the main Specification_ CSRs and features are to be supported (VBLOCK), then when VLtyp or svlen are "default" they utilise the main Specification_ VBLOCK VL and/or SUBVL, and, correspondingly, the main VBLOCK STATE CSR will be updated and used to track hardware loops.
 
+If however VLtyp is set to nondefault, then the SVPSTATE src and destoffs fields are used instead to create the hardware loops, and likewise if svlen is set to nondefault, SVPSTATE's svoffs field is used.
 
 Half-Precision Floating Point (FP16)
 ====================================
@@ -86,12 +73,11 @@ base FP instructions by using 10 (H) in the floating-point format field
 Compressed Instructions
 =======================
 
-This proposal does not include any prefixed RVC instructions, instead,
-it will include 32-bit instructions that are compressed forms of
-SVprefix 48-bit instructions, in the same manner that RVC instructions
-are compressed forms of RVI instructions. The compressed instructions
-will be defined later by considering which 48-bit instructions are the
-most common.
+Compressed instructions are under evaluation by taking the same
+prefix as used in P48, embedding that and standard RVC opcodes (minus
+their RVC prefix) into a 32-bit space.  This by taking the three remaining
+Major "custom" opcodes (0-2), one for each of the three RVC Quadrants.
+see [[discussion]].
 
 48-bit Prefixed Instructions
 ============================
@@ -105,37 +91,37 @@ instructions.
 ============================
 
 The 48 bit format is further extended with the full 128-bit range on all
-source and destination registers, and the option to set both VL and MVL
+source and destination registers, and the option to set both SVSTATE.VL and SVSTATE.MVL
 is provided.
 
 48-bit Instruction Encodings
 ============================
 
-In the following table, *Reserved* entries must be zero.  RV32 equivalent
+In the following table, *Rsvd* (reserved) entries must be zero.  RV32 equivalent
 encodings included for side-by-side comparison (and listed below,
 separately).
 
 First, bits 17:0:
 
-+---------------+--------+------------+------------+-----+------------+-------------+------+------------+--------+
-| Encoding      | 17     | 16         | 15         | 14  | 13         | 12          | 11:7 | 6          | 5:0    |
-+---------------+--------+------------+------------+-----+------------+-------------+------+------------+--------+
-| P48-LD-type   | rd[5]  | rs1[5]     | vitp7[6]   | vd  | vs1        | vitp7[5:0]         | 0          | 011111 |
-+---------------+--------+------------+------------+-----+------------+-------------+------+------------+--------+
-| P48-ST-type   |vitp7[6]| rs1[5]     | rs2[5]     | vs2 | vs1        | vitp7[5:0]         | 0          | 011111 |
-+---------------+--------+------------+------------+-----+------------+-------------+------+------------+--------+
-| P48-R-type    | rd[5]  | rs1[5]     | rs2[5]     | vs2 | vs1        | vitp6              | 0          | 011111 |
-+---------------+--------+------------+------------+-----+------------+--------------------+------------+--------+
-| P48-I-type    | rd[5]  | rs1[5]     | vitp7[6]   | vd  | vs1        | vitp7[5:0]         | 0          | 011111 |
-+---------------+--------+------------+------------+-----+------------+--------------------+------------+--------+
-| P48-U-type    | rd[5]  | *Reserved* | *Reserved* | vd  | *Reserved* | vitp6              | 0          | 011111 |
-+---------------+--------+------------+------------+-----+------------+-------------+------+------------+--------+
-| P48-FR-type   | rd[5]  | rs1[5]     | rs2[5]     | vs2 | vs1        | *Reserved*  | vtp5 | 0          | 011111 |
-+---------------+--------+------------+------------+-----+------------+-------------+------+------------+--------+
-| P48-FI-type   | rd[5]  | rs1[5]     | vitp7[6]   | vd  | vs1        | vitp7[5:0]         | 0          | 011111 |
-+---------------+--------+------------+------------+-----+------------+-------------+------+------------+--------+
-| P48-FR4-type  | rd[5]  | rs1[5]     | rs2[5]     | vs2 | rs3[5]     | vs3 [#fr4]_ | vtp5 | 0          | 011111 |
-+---------------+--------+------------+------------+-----+------------+-------------+------+------------+--------+
++---------------+--------+--------+----------+-----+--------+-------------+------+--------+--------+
+| Encoding      | 17     | 16     | 15       | 14  | 13     | 12          | 11:7 | 6      | 5:0    |
++---------------+--------+--------+----------+-----+--------+-------------+------+--------+--------+
+| P48-LD-type   | rd[5]  | rs1[5] | vitp7[6] | vd  | vs1    | vitp7[5:0]         | *Rsvd* | 011111 |
++---------------+--------+--------+----------+-----+--------+-------------+------+--------+--------+
+| P48-ST-type   |vitp7[6]| rs1[5] | rs2[5]   | vs2 | vs1    | vitp7[5:0]         | *Rsvd* | 011111 |
++---------------+--------+--------+----------+-----+--------+-------------+------+--------+--------+
+| P48-R-type    | rd[5]  | rs1[5] | rs2[5]   | vs2 | vs1    | vitp6              | *Rsvd* | 011111 |
++---------------+--------+--------+----------+-----+--------+--------------------+--------+--------+
+| P48-I-type    | rd[5]  | rs1[5] | vitp7[6] | vd  | vs1    | vitp7[5:0]         | *Rsvd* | 011111 |
++---------------+--------+--------+----------+-----+--------+--------------------+--------+--------+
+| P48-U-type    | rd[5]  | *Rsvd* | *Rsvd*   | vd  | *Rsvd* | vitp6              | *Rsvd* | 011111 |
++---------------+--------+--------+----------+-----+--------+-------------+------+--------+--------+
+| P48-FR-type   | rd[5]  | rs1[5] | rs2[5]   | vs2 | vs1    | *Rsvd*      | vtp5 | *Rsvd* | 011111 |
++---------------+--------+--------+----------+-----+--------+-------------+------+--------+--------+
+| P48-FI-type   | rd[5]  | rs1[5] | vitp7[6] | vd  | vs1    | vitp7[5:0]         | *Rsvd* | 011111 |
++---------------+--------+--------+----------+-----+--------+-------------+------+--------+--------+
+| P48-FR4-type  | rd[5]  | rs1[5] | rs2[5]   | vs2 | rs3[5] | vs3 [#fr4]_ | vtp5 | *Rsvd* | 011111 |
++---------------+--------+--------+----------+-----+--------+-------------+------+--------+--------+
 
 .. [#fr4] Only vs2 and vs3 are included in the P48-FR4-type encoding
           because there is not enough space for vs1 as well, and because
@@ -147,9 +133,9 @@ Table showing correspondance between P48-*-type and RV32-*-type.
 These are bits 47:18 (RV32 shifted up by 16 bits):
 
 +---------------+---------------+
-| Encoding      | 47:18         |
+| Encoding      | RV32 Encoding |
 +---------------+---------------+
-| RV32 Encoding | 31:2          |
+| 47:32         | 31:2          |
 +---------------+---------------+
 | P48-LD-type   | RV32-I-type   |
 +---------------+---------------+
@@ -208,39 +194,39 @@ this is now set to "0b0111111".
 +--------------+-------+--------+--------+--------+--------+
 | Encoding     | 63    | 62     | 61     | 60     | 59:48  |
 +--------------+-------+--------+--------+--------+--------+
-| P64-LD-type  | rd[6] | rs1[6] |        |        | VLtyp  |
+| P64-LD-type  | rd[6] | rs1[6] |        | *Rsvd* | VLtyp  |
 +--------------+-------+--------+--------+--------+--------+
-| P64-ST-type  |       | rs1[6] | rs2[6] |        | VLtyp  |
+| P64-ST-type  |       | rs1[6] | rs2[6] | *Rsvd* | VLtyp  |
 +--------------+-------+--------+--------+--------+--------+
-| P64-R-type   | rd[6] | rs1[6] | rs2[6] |        | VLtyp  |
+| P64-R-type   | rd[6] | rs1[6] | rs2[6] | vd     | VLtyp  |
 +--------------+-------+--------+--------+--------+--------+
-| P64-I-type   | rd[6] | rs1[6] |        |        | VLtyp  |
+| P64-I-type   | rd[6] | rs1[6] |        | *Rsvd* | VLtyp  |
 +--------------+-------+--------+--------+--------+--------+
-| P64-U-type   | rd[6] |        |        |        | VLtyp  |
+| P64-U-type   | rd[6] |        |        | *Rsvd* | VLtyp  |
 +--------------+-------+--------+--------+--------+--------+
-| P64-FR-type  |       | rs1[6] | rs2[6] |        | VLtyp  |
+| P64-FR-type  |       | rs1[6] | rs2[6] | vd     | VLtyp  |
 +--------------+-------+--------+--------+--------+--------+
-| P64-FI-type  | rd[6] | rs1[6] | rs2[6] |        | VLtyp  |
+| P64-FI-type  | rd[6] | rs1[6] | rs2[6] | vd     | VLtyp  |
 +--------------+-------+--------+--------+--------+--------+
 | P64-FR4-type | rd[6] | rs1[6] | rs2[6] | rs3[6] | VLtyp  |
 +--------------+-------+--------+--------+--------+--------+
 
 The extra bit for src and dest registers provides the full range of
 up to 128 registers, when combined with the extra bit from the 48 bit
-prefix as well.  VLtyp encodes how (whether) to set VL and MAXVL.
+prefix as well.  VLtyp encodes how (whether) to set SVPSTATE.VL and SVPSTATE.MAXVL.
 
 VLtyp field encoding
 ====================
 
-NOTE: VL and MVL below are modified (potentially damaging) and so is
-the STATE CSR. It is the responsibility of the programmer to ensure that
-modifications to STATE do not compromise loops or VLIW Group opetations,
-by saving and restoring the STATE CSR (if needed).
+NOTE: VL and MVL below are local to SVPrefix and, if non-default,
+will update the src and dest element offsets in SVPSTATE, not the main
+Specification_ STATE. If default (all zeros) then STATE VL and MVL apply
+to this instruction, and STATE.srcoffs (etc) will be used.
 
 +-----------+-------------+--------------+----------+----------------------+
 | VLtyp[11] | VLtyp[10:6] | VLtyp[5:1]   | VLtyp[0] | comment              |
 +-----------+-------------+--------------+----------+----------------------+
-| 0         |  000000     | 00000        |  0       | no change to VL/MVL  |
+| 0         |  00000      | 00000        |  0       | no change to VL/MVL  |
 +-----------+-------------+--------------+----------+----------------------+
 | 0         |  VLdest     | VLEN         |  vlt     | VL imm/reg mode (vlt)|
 +-----------+-------------+--------------+----------+----------------------+
@@ -249,9 +235,11 @@ by saving and restoring the STATE CSR (if needed).
 | 1         |  VLdest     |  MVL-immed   | 1        | MVL immed mode       |
 +-----------+-------------+--------------+----------+----------------------+
 
-Note: when VLtyp is all zeros, neither VL nor MVL are changed.
+Note: when VLtyp is all zeros, the main Specification_ VL and MVL apply
+to this instruction. If called outside of a VBLOCK or if sv.setvl has
+not set VL, the operation is "scalar".
 
-Just as in the VLIW format, when bit 11 of VLtyp is zero:
+Just as in the VBLOCK format, when bit 11 of VLtyp is zero:
 
 * if vlt is zero, bits 1 to 5 specify the VLEN as a 5 bit immediate
   (offset by 1: 0b00000 represents VL=1, 0b00001 represents VL=2 etc.)
@@ -261,26 +249,55 @@ Just as in the VLIW format, when bit 11 of VLtyp is zero:
 
 When bit 11 of VLtype is 1:
 
-* if VLtyp[0] is zero, both MAXVL and VL are set to (imm+1).  The same
+* if VLtyp[0] is zero, both SVPSTATE.MAXVL and SVPSTATE.VL are set to (imm+1).  The same
   value goes into the scalar register VLdest (if VLdest is not x0)
-* if VLtyp[0] is 1, MAXVL is set to (imm+1).
-  VL will be truncated to within the new range (if VL was greater
+* if VLtyp[0] is 1, SVPSTATE.MAXVL is set to (imm+1).
+  SVPSTATE.VL will be truncated to within the new range (if VL was greater
   than the new MAXVL).  The new VL goes into the scalar register VLdest
   (if VLdest is not x0).
 
-This gives the option to set up VL in a "loop mode" (VLtype[11]=0) or
+This gives the option to set up SVPSTATE.VL in a "loop mode" (VLtype[11]=0) or
 in a "one-off" mode (VLtype[11]=1) which sets both MVL and VL to the
 same immediate value.  This may be most useful for one-off Vectorised
 operations such as LOAD-MULTI / STORE-MULTI, for saving and restoration
 of large batches of registers in context-switches or function calls.
 
-Note that VLtyp's VL and MVL are the same as the main Specification_
-VL or MVL, and that loops will also alter srcoffs and destoffs. It is
-the programmer's responsibility to ensure that STATE is not compromised
-(e.g saved to a temp reg or to the stack).
+Note that VLtyp's VL and MVL are not the same as the main Specification_
+VL or MVL, and that loops will alter srcoffs and destoffs in SVPSTATE in VLtype nondefault mode, but the srcoffs and destoffs in STATE, if VLtype=0.
 
 Furthermore, the execution order and exception handling must be exactly
-the same as in the main spec.
+the same as in the main spec (Program Order must be preserved)
+
+Pseudocode for SVPSTATE.VL:
+
+.. parsed-literal::
+
+    # pseudocode
+
+    regs = [0u64; 128];
+    vl = 0;
+
+    // instruction fields:
+    rd = get_rd_field();
+    vlmax = get_immed_field();
+
+    // handle illegal instruction decoding
+    if vlmax > XLEN {
+        trap()
+    }
+
+    // calculate VL
+    if rs1 == 0 { // rs1 is x0
+        vl = vlmax
+    } else {
+        vl = min(regs[rs1], vlmax)
+    }
+
+    // write rd
+    if rd != 0 {
+        // rd is not x0
+        regs[rd] = vl
+    }
 
 vs#/vd Fields' Encoding
 =======================
@@ -363,8 +380,7 @@ immediate. Should this be considered?
 Sub-Vector Length (svlen) Field Encoding
 ========================================
 
-NOTE: svlen is the same as the main spec SUBVL, and modifies the STATE
-CSR. The same caveats apply to svlen as do to SUBVL.
+NOTE: svlen is not the same as the main spec SUBVL.  When nondefault (not zero) SVPSTATE context is used for Sub vector loops. However is svlen is zero, STATE and SUBVL is used instead.
 
 Bitwidth, from VL's perspective, is a multiple of the elwidth times svlen.
 So within each loop of VL there are svlen sub-elements of elwidth in size,
@@ -421,6 +437,13 @@ Predication (pred) Field Encoding
 Twin-predication (tpred) Field Encoding
 =======================================
 
+Twin-predication (ability to associate two predicate registers with an
+instruction) applies to MV, FCLASS, LD and ST.  The same format also
+applies to integer-branch-compare operations although it is **not** to be
+considered "twin" predication.  In the case of integer-branch-compare
+operations, the second register (if enabled) stores the results of the
+element comparisons.  See Appendix_ for details.
+
 +-------+------------+--------------------+----------------------------------------------+
 | tpred | Mnemonic   | Predicate Register | Meaning                                      |
 +=======+============+====================+==============================================+
@@ -605,41 +628,56 @@ the main specification.
 
 * VL
 * MVL
-* STATE
+* SVPSTATE
 * SUBVL
 
 Associated SET and GET on the CSRs is exactly as in the main spec as well
 (including CSRRWI and CSRRW differences).
 
-Note that if all of VL/MVL, SUBVL, VLtyp and svlen are all chosen by an
-implementor not to be implemented, the STATE CSR is not required.
+Note that if both VLtyp and svlen are not implemented, SVPSTATE is not required. Also if VL and SUBVL are not implemented, STATE from the main Specification_ is not required either.
 
 However if partial functionality is implemented, the unimplemented bits
-in STATE must be zero, and, in the UNIX Platform, an illegal exception
+in STATE and SVPSTATE must be zero, and, in the UNIX Platform, an illegal exception
 **MUST** be raised if unsupported bits are written to.
 
-Additional Instructions
-=======================
+SVPSTATE fields are exactly the same layout as STATE:
 
-Add instructions to convert between integer types.
++----------+----------+----------+----------+----------+---------+---------+
+| (31..28) | (27..26) | (25..24) | (23..18) | (17..12) | (11..6) | (5...0) |
++----------+----------+----------+----------+----------+---------+---------+
+| rsvd     | dsvoffs  | subvl    | destoffs | srcoffs  | vl      | maxvl   |
++----------+----------+----------+----------+----------+---------+---------+
 
-Add instructions to `swizzle`_ elements in sub-vectors. Note that the sub-vector
-lengths of the source and destination won't necessarily match.
+However note that where STATE stores the scalar register number to be used as VL, SVPSTATE.VL actually contains the actual VL value, in an identical fashion to RVV.
 
-.. _swizzle: https://www.khronos.org/opengl/wiki/Data_Type_(GLSL)#Swizzling
+Additional Instructions
+=======================
+
+* Add instructions to convert between integer types.
+* Add instructions to `swizzle`_ elements in sub-vectors. Note that
+  the sub-vector lengths of the source and destination won't necessarily
+  match.
+* Add instructions to transpose (2-4)x(2-4) element matrices.
+* Add instructions to insert or extract a sub-vector from a vector, with
+  the index allowed to be both immediate and from a register (*immediate
+  can be covered by twin-predication, register might be, by virtue of
+  predicates being registers*)
+* Add a register gather instruction (aka MV.X: regfile[rd] =
+  regfile[regfile[rs1]])
 
-Add instructions to transpose (2-4)x(2-4) element matrices.
+subelement swizzle example:
 
-Add instructions to insert or extract a sub-vector from a vector, with
-the index allowed to be both immediate and from a register (*immediate
-can be covered by twin-predication, register might be, by virtue of
-predicates being registers*)
+    velswizzle x32, x64, SRCSUBVL=3, DESTSUBVL=4, ELTYPE=u8, elements=[0, 0, 2, 1]
 
-Add a register gather instruction (aka MV.X: regfile[rd] =
-regfile[regfile[rs1]])
+.. _swizzle: https://www.khronos.org/opengl/wiki/Data_Type_(GLSL)#Swizzling
 
 questions
 =========
 
 Moved to the discussion page (link at top of this page)
 
+TODO
+====
+
+Work out a way to do sub-element swizzling.
+