(no commit message)
[libreriscv.git] / simple_v_extension / vblock_format / discussion.mdwn
1 # Alternative (SVPrefix) format
2
3 This VBLOCK mode effectively extends [[sv_prefix_proposal]] to cover multiple
4 registers. The basic principle: the "prefix" specifies which of source and
5 destination registers are to be considered "vectors" (or scalars), however
6 where in SVPrefix that applies to only one instruction, the "vector" tag
7 designations *continue to cascade* into subsequent instructions within the
8 VBLOCK.
9
10 Its advantage over the main format is that the main format requires
11 explicit naming of the registers to be tagged (taking up 5 bits each time).
12
13 | 15 | 14:12 | 11:10 | 9 | 8:7 | 6:0 |
14 | - | ----- | ----- | ----- | --------| ------- |
15 | rsvd | 16xil | rsvd | rsvd | SVPMode | 1111111 |
16
17 | SVPMode | 1:0 |
18 | ------- | --- |
19 | non-SVP | 0b00 |
20 | P48 Mode | 0b01 |
21 | P64 Mode | 0b10 |
22 | Twin-SVP | 0b11 |
23
24 non-SVP mode uses the extended format (see main VBLOCK spec [[vblock_format]])
25
26 When P48 Mode is enabled (0b01), the P48 prefix follows the VBLOCK header
27
28 | 15:11 | 10:0 |
29 | - | ---------- |
30 | rsvd | P48-Prefix |
31
32 When P64 Mode is enabled (0b10), the P64 prefix also follows:
33
34 | 31:16 | 15:11 | 10:0 |
35 | ---------- | - | ---------- |
36 | P64-prefix | rsvd | P48-Prefix |
37
38 When Twin-SVP Mode is enabled (0b11), a *second* P48 prefix follows after a P48-P64 pair,
39 in the VBLOCK (another 16 bits after the 32 bit P48/P64 block), which applies vector-context from the *second* instruction's
40 registers. The reason why Twin-SVP's prefix is only P48 is because P64 can change VL and MVL. It makes no srnse to try to reset VL/MVL twice in succession.
41
42 VL/MVL from a P64 prefix is applied as if a [[specification/sv.setvl]] instruction had been executed as a hidden (first, implicit) instruction in the VBLOCK. This *includes* modification of SV CSR STATE.
43
44 # Rules
45
46 * SVP-VBLOCK is read (48/64), and indicates that certain registers are
47 to be "tagged". Element widths and predication are also specified
48 * The very first instruction (RVC, OP32) within the VBLOCk says **which**
49 registers those tags are to be associated with
50 * Those registers **remain** tagged with that context *for the entire duration
51 of the VBLOCK*.
52 * At the end of the VBLOCK the context terminates and the tags are discarded.
53 * There is rule in SVP about vs#/vd# fields, if they are not present in
54 a given P48/P64 prefix, an "implicit" field is created for that src or
55 dest register in the form of a bitwise "OR" of all present vs#/vd# fields.
56 *This rule continues to apply* to the instructions following the first
57 (and second, if applicable)
58 in the VBLOCK, however the ORing rule
59 *stops* i.e does not cascade via rd in the following instructions.
60 * If an instruction is used where registers are implicitly determined to be
61 scalars, they *remain* scalars when used in subsequent instructions.
62
63 Example (contrived):
64
65 * VBLOCK, P48 prefix only (SVPMode=0b01), vs1=1, vs2=0
66 * 1st instruction in VBLOCK: ADD x3, x5, x12
67 * 2nd instruction in VBLOCK: ADD x7, x5, x3
68 * 3rd instruction in VBLOCK: ADD x9, x4, x4
69 * 4th instruction in VBLOCK: ADD x7, x5, x4
70
71 * vs1=1 indicates that the source register rs1 is to be considered a vector,
72 whilst rs2 is to be a "scalar".
73 * The first instruction has "x5" as rs1. It is therefore "marked" as a vector
74 * However with there being no "specifier" for vd in the P48 prefix, vd is
75 calculated as "vd = vs1 | vs2" and is therefore set to "1".
76 * The "full" specification for the 1st add is therefore
77 "ADD vector-x3, vector-x5, scalar-x12".
78 * The second instruction also uses x5, however x3 is also now considered
79 a "vector", and, consequently, so is x7.
80 * The "full" specification for the 2nd add is therefore
81 "ADD vector-x7, vector-x5, vector-x3".
82 * The 3rd instruction has no context applied to any of its registers, therefore
83 x9 and x4 are determined to be "scalar"
84 * The specification for the 3rd add is therefore
85 "ADD scalar-x9, scalar-x4, scalar-x4"
86 * The 4th instruction. **despite** using x7 as vector in instruction 2, x7 is **not** listed in the 1st instruction's operands. Likewise for x4. Therefore the "OR" rule applies to them.
87 * x5 on the other hand *is* in the 1st instruction's operands, and, given that x4 and x7 have the "OR" rule applied, are also marked as "vector" *despite x4 being fornerly scalar in the 3rd instruction*.
88 * Therefore, the "full" specification for the 4th add is:
89 "ADD vector-x7, vector-x5, vector-x4"
90
91 Writing those out separately, for clarity:
92
93 ADD vector-x3, vector-x5, scalar-x12 # from vs1=1, vs2=0, vd=vs1|vs2
94 ADD vector-x7, vector-x5, vector-x3 # x7: v-x5 | v-x3
95 ADD scalar-x9, scalar-x4, scalar-x4 # x9, x4 not prefixed, therefore scalar
96 ADD vector-x7, vector-x5, vector-x4 # x4, x7, x5 vector
97
98 Twin-SVP mode allows even more registers to be explicitly marked, including some specifically as "scalar",
99 where the rules might otherwise start to cascade through and cause
100 registers to be come undesirably marked as "vectors".
101
102 The reason why the OR rule cannot cascade onwards is because if a trap occurs and the context has to be reestablished on return, it may be reestablished purely with the VBLOCK header and by decoding the first (and second) instruction.
103
104 If the cascade of what was marked "vector" was allowed to continue, it would require re-reading of every opcode up to the point where execution of the VBLOCK left off, in order to reestablish the full cascade context.
105
106 # Discussion
107
108 * <https://groups.google.com/forum/#!topic/comp.arch/l2nzme2sCR0>
109 * <http://lists.libre-riscv.org/pipermail/libre-riscv-dev/2019-September/002622.html>