working on svp64
authorJacob Lifshay <programmerjake@gmail.com>
Wed, 16 Dec 2020 01:39:56 +0000 (17:39 -0800)
committerJacob Lifshay <programmerjake@gmail.com>
Wed, 16 Dec 2020 01:39:56 +0000 (17:39 -0800)
openpower/sv/svp_rewrite/svp64.mdwn
openpower/sv/svp_rewrite/svp64/discussion.mdwn

index 8c6e8603e7a5086ea980b8c442dd78c382494a6f..838c32cbf6f2fbf97e3ae0c2b2fce9e18fc6a9b6 100644 (file)
@@ -2,7 +2,6 @@
 
 * [[svp64/discussion]]
 
-
 The plan is to create an encoding for SVP64, then to create an encoding for
 SVP48, then to reorganize them both to improve field overlap, reducing the
 amount of decoder hardware necessary.
@@ -13,6 +12,12 @@ counting up as you move to the LSB end). All bit ranges are inclusive (so
 
 64-bit instructions are split into two 32-bit words, the prefix and the suffix. The prefix always comes before the suffix in PC order.
 
+## Definition of Reserved in this spec.
+
+For the new fields added in SVP64, instructions that have any of their fields set to a reserved value must cause an illegal instruction trap, to allow emulation of future instruction sets.
+
+This is unlike OpenPower ISA v3.1, which doesn't require a CPU to trap.
+
 ## Remapped Encoding (`RM[0:23]`)
 
 To allow relatively easy remapping of which portions of the Prefix Opcode Map
@@ -25,49 +30,80 @@ defined in the Prefix Fields section.
 
 ## Remapped Encoding Fields
 
-| Remapped Encoding Field Name | Field bits | Description    |
-|------------------------------|------------|----------------|
-| MASK                         | `0:3`      | Execution Mask |
-| TBD                          | `4:23`     | TBD            |
-
-## MASK Encoding
+| Remapped Encoding Field Name | Field bits | Description                                                            |
+|------------------------------|------------|------------------------------------------------------------------------|
+| MASK_KIND                    | `0`        | Execution Mask Kind                                                    |
+| MASK                         | `1:3`      | Execution Mask                                                         |
+| ELWIDTH                      | `4:5`      | Element Width                                                          |
+| SUBVL                        | `6:7`      | Sub-vector length                                                      |
+| TBD                          | `8:23`     | TBD                                                                    |
+| MASK_SRC                     | TBD        | Execution Mask for Source (only on instructions with twin-predication) |
+
+## ELWIDTH Encoding
+
+| Instruction Kind | ELWIDTH Value | Mnemonic                  | Description                                                                         |
+|------------------|---------------|---------------------------|-------------------------------------------------------------------------------------|
+| Integer          | 00            | `ELWIDTH=b`               | Byte: 8-bit integer                                                                 |
+| Integer          | 01            | `ELWIDTH=h`               | Halfword: 16-bit integer                                                            |
+| Integer          | 10            | `ELWIDTH=w`               | Word: 32-bit integer                                                                |
+| Integer          | 11            | `ELWIDTH=d`               | Doubleword: 64-bit integer                                                          |
+| FP               | 00            | `ELWIDTH=bf16` (Reserved) | Reserved for [`bf16`](https://en.wikipedia.org/wiki/Bfloat16_floating-point_format) |
+| FP               | 01            | `ELWIDTH=f16`             | 16-bit IEEE 754 Half floating-point                                                 |
+| FP               | 10            | `ELWIDTH=f32`             | 32-bit IEEE 754 Single floating-point                                               |
+| FP               | 11            | `ELWIDTH=f64`             | 64-bit IEEE 754 Double floating-point                                               |
+
+## SUBVL Encoding
+
+| SUBVL Value | Mnemonic            | Description            |
+|-------------|---------------------|------------------------|
+| 00          | `SUBVL=4`           | Sub-vector length of 4 |
+| 01          | `SUBVL=1` (default) | Sub-vector length of 1 |
+| 10          | `SUBVL=2`           | Sub-vector length of 2 |
+| 11          | `SUBVL=3`           | Sub-vector length of 3 |
+
+## MASK/MASK_SRC & MASK_KIND Encoding
 
 One bit indicates the mode: CR or Int predication.   The two types may not be mixed.
 
+| MASK_KIND Value | Description                                          |
+|-----------------|------------------------------------------------------|
+| 0               | MASK/MASK_SRC are encoded using Integer Predication  |
+| 1               | MASK/MASK_SRC are encoded using CR-based Predication |
+
 Integer Twin predication has a second set if 3 bits that uses the same encoding thus allowing either the same register (r3 or r10) to be used for both src and dest, or different regs (one for src, one for dest).
 
 Likewise CR based twin predication has a second set of 3 bits, allowing a different test to be applied.
 
-### Integer Predication
+### Integer Predication (MASK_KIND=0)
 
 When the predicate mode bit is zero the 3 bits are interpreted as below. 
 Twin predication has an identical 3 bit field similarly encoded.
 
-| Value | Mnemonic | Description                                            |
-|-------|----------|--------------------------------------------------------|
-| 000  | ALWAYS    | Operation is not masked  see [[discussion]]            |
-| 001  | 1 << R3   | Reserved (causes an illegal instruction trap)          |
-| 010  | R3        | Element `i` is enabled if `R3 & (1 << i)` is non-zero  |
-| 011  | ~R3       | Element `i` is enabled if `R3 & (1 << i)` is zero      |
-| 100  | R10       | Element `i` is enabled if `R10 & (1 << i)` is non-zero |
-| 101  | ~R10      | Element `i` is enabled if `R10 & (1 << i)` is zero     |
-| 110  | R30       | Element `i` is enabled if `R30 & (1 << i)` is non-zero |
-| 111  | ~R30      | Element `i` is enabled if `R30 & (1 << i)` is zero     |
+| MASK/MASK_SRC<br/>Value | Mnemonic | Description                                            |
+|-------------------------|----------|--------------------------------------------------------|
+| 000                     | ALWAYS   | Operation is not masked  see [[discussion]]            |
+| 001                     | 1 << R3  | Element `i` is enabled if `i == R3`                    |
+| 010                     | R3       | Element `i` is enabled if `R3 & (1 << i)` is non-zero  |
+| 011                     | ~R3      | Element `i` is enabled if `R3 & (1 << i)` is zero      |
+| 100                     | R10      | Element `i` is enabled if `R10 & (1 << i)` is non-zero |
+| 101                     | ~R10     | Element `i` is enabled if `R10 & (1 << i)` is zero     |
+| 110                     | R30      | Element `i` is enabled if `R30 & (1 << i)` is non-zero |
+| 111                     | ~R30     | Element `i` is enabled if `R30 & (1 << i)` is zero     |
 
-### CR based predication
+### CR-based Predication (MASK_KIND=1)
 
 When the predicate mode bit is one the 3 bits are interpreted as below.  Twin predication has an identical 3 bit field similarly encoded
 
-| Value | Mnemonic | Description                                            |
-|-------|----------|--------------------------------------------------------|
-| 000  | lt        | Element `i` is enabled if `CR[6+i].LT` is set          |
-| 001  | nl/ge     | Element `i` is enabled if `CR[6+i].LT` is clear        |
-| 010  | gt        | Element `i` is enabled if `CR[6+i].GT` is set          |
-| 011  | ng/le     | Element `i` is enabled if `CR[6+i].GT` is clear        |
-| 100  | eq        | Element `i` is enabled if `CR[6+i].EQ` is set          |
-| 101  | ne        | Element `i` is enabled if `CR[6+i].EQ` is clear        |
-| 110  | so/un     | Element `i` is enabled if `CR[6+i].FU` is set          |
-| 111  | ns/nu     | Element `i` is enabled if `CR[6+i].FU` is clear        |
+| MASK/MASK_SRC<br/>Value | Mnemonic | Description                                     |
+|-------------------------|----------|-------------------------------------------------|
+| 000                     | lt       | Element `i` is enabled if `CR[6+i].LT` is set   |
+| 001                     | nl/ge    | Element `i` is enabled if `CR[6+i].LT` is clear |
+| 010                     | gt       | Element `i` is enabled if `CR[6+i].GT` is set   |
+| 011                     | ng/le    | Element `i` is enabled if `CR[6+i].GT` is clear |
+| 100                     | eq       | Element `i` is enabled if `CR[6+i].EQ` is set   |
+| 101                     | ne       | Element `i` is enabled if `CR[6+i].EQ` is clear |
+| 110                     | so/un    | Element `i` is enabled if `CR[6+i].FU` is set   |
+| 111                     | ns/nu    | Element `i` is enabled if `CR[6+i].FU` is clear |
 
 CR based predication.  TODO: select alternate CR for twin predication? see [[discussion]]  Overlap of the two CR based predicates must be taken into account, so the starting point for one of them must be suitably high, or accept that for twin predication VL must not exceed the range where overlap will occur, *or* that they use the same starting point but select different *bits* of the same CRs
 
@@ -102,16 +138,17 @@ CR based predication.  TODO: select alternate CR for twin predication? see [[dis
 
 SV Registers are numbered using the notation `SV[F]R<N>_<M>` where `<N>` is a decimal integer and `<M>` is a binary integer. Two integers are used to enable future register expansions to add more registers by appending more LSB bits to `<M>`.
 
-for all SV[F|C]R<N>_<M> registers, the N is the
-upper bits in decimal and the M is the lower bits in binary, so SVR5_01 is
-SV int register (5 << 2) + 0b01, and SVCR6_011 is SV cond register (6 << 3)
-+ 0b011
+For all `SV[F|C]R<N>_<M>` registers, the N is the
+upper bits in decimal and the M is the lower bits in binary, so `SVR5_01` is
+SV integer register `(5 << 2) + 0b01`, `SVCR6_011` is SV condition register
+`(6 << 3) + 0b011`, and `SVFR20_10` is SV floating-point register
+`(20 << 2) + 0b10`.
 
-example
+## Example Code
 
 a vectorized 32-bit add:
 
-add SVR3_01, SVR6_10, SVR10_00, elwidth=32, subvl=1, mask=lt
+    add SVR3_01, SVR6_10, SVR10_00, elwidth=w, subvl=1, mask=lt
 
 does the following:
 
@@ -128,17 +165,14 @@ does the following:
 
 ## Integer Registers
 
-```
-setvli ..., VL=7
-add r20, r25, r30, elwidth=64, subvl=1
-```
+    setvli ..., VL=7
+    add r20, r25, r30, elwidth=64, subvl=1
 
 where `r20`, `r25`, and `r30` are standard OpenPower register names.
 Those names correspond to `SVR20_00`, `SVR25_00`, and `SVR30_00`.
 
 pseudocode:
 
-```C++
     const size_t STD_TO_SV_SHIFT = 2; // gets bigger as reg files expand to 256, 512, ... registers
 
     VL = 7; // setvli (omitting maxvl here)
@@ -147,7 +181,6 @@ pseudocode:
         regs[(20 << STD_TO_SV_SHIFT) + i] = regs[(25 << STD_TO_SV_SHIFT) + i]
             + regs[(30 << STD_TO_SV_SHIFT) + i];
     }
-```
 
 Standard PowerISA Integer registers are aliased to some of the SV integer registers:
 
@@ -257,30 +290,29 @@ Standard PowerISA floating-point and VSX registers are aliased to some of the SV
 |                 | VSR\[47\]\.dword\[0\] | SVFR15\_10         |                 | VSR\[63\]\.dword\[0\] | SVFR31\_10         |
 |                 | VSR\[47\]\.dword\[1\] | SVFR15\_11         |                 | VSR\[63\]\.dword\[1\] | SVFR31\_11         |
 
-
 # Operation
 
 ## CR fields as inputs/outputs of vector operations
 
 When vectorized, the CR inputs/outputs are read/written to 4-bit CR fields
-starting from CR6 and incrementing from there. If CR63 is reached, the next CR
-field used wraps around to CR0, then incrementing from there.
-(see [[discussion]].  an alternative scheme is described there)
+starting from SVCR6_000 and incrementing from there. If SVCR7_111 is reached, the next CR
+field used wraps around to SVCR0_000, then incrementing from there.
+(see [[discussion]].  some alternative schemes are described there)
 
-CR6 was chosen to balance avoiding needing to save CR2-CR4 (which are
+SVCR6_000 was chosen to balance avoiding needing to save CR2-CR4 (which are
 callee-saved) just to use SV vectors with VL <= 61 as well as having the first
-few used CR fields readily accessible to standard CR instructions and branches.
-Additionally, CR6 is used as the implicit result of a OpenPower ISA v3.1
-standard vector instruction with Rc=1.
+vector CR field readily accessible to standard CR instructions and branches.
+Additionally, SVCR6_000 is used as the implicit result of a OpenPower ISA v3.1
+standard vector (SIMD) instruction with Rc=1.
 
-## Alternative CR Vectorization Scheme
+## Table of CR fields
 
 CR[i] is the notation used by the OpenPower spec to refer to CR field #i,
 so FP instructions with Rc=1 write to CR[1] aka SVCR1_000.
 
 There are 3 new SPRs for holding CRs: CR_EXT1, CR_EXT2, and CR_EXT3.
 
-Arrange the 64 SV CRs similarly to the way the 128 integer registers are arranged:
+The 64 SV CRs are arranged similarly to the way the 128 integer registers are arranged:
 
 | CR<br/>Register | SPR<br/>Field  | SV CR<br/>Register | CR<br/>Register | SPR<br/>Field  | SV CR<br/>Register |
 |-----------------|----------------|--------------------|-----------------|----------------|--------------------|
index dd5951abb8f1a69b92dd581d2f40f147b2dc723c..2d4c407a943c814ae66bc20c4816dffbc8938b2f 100644 (file)
@@ -176,14 +176,11 @@ Note: considerable care needs to be taken when putting these horiz/vertical CRs
 
 Indexing algorithm illustrating how the H/V modes would work.  Note that BA is the 3 bit CR register field that normsll, in scalar ISA, would reference only CR0-7 as CR[BA].
 
-     for i in range(VL)
-         y = i % 8
-         x = i // 8
-         if verticalmode:
-             CRINDEX = BA + y*8 + x
-         else:
-             CRINDEX = BA*8 + i
-         CR[CRINDEX] = ...
-
-
+    for i in range(VL)
+        y = i % 8
+        x = i // 8
+        if verticalmode:
+            CRINDEX = BA + y*8 + x
+        else:
+            CRINDEX = BA*8 + i
+        CR[CRINDEX] = ...