(no commit message)
[libreriscv.git] / openpower / sv / svp_rewrite / svp64.mdwn
index e1970d82ee2bc311ff297f35d7cf0149fc4fd628..c5d40949f95f8b2691d628923b855462bf8b606c 100644 (file)
@@ -32,33 +32,43 @@ defined in the Prefix Fields section.
 
 ## MASK Encoding
 
-TODO: split out (remove) bit 3 as separate so that twin predication can use the same encoding, and split the table into 2 halves. The bit currently 3 becomes a separate (standalone) field (see [discussion]) that selects *both* src and dest predication as CR based or both as INT based.  This saves one bit and makes things less complex.
-
-Integer based predication.  Twin predication 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)
-
-| Value | Mnemonic          | Description                                            |
-|-------|-------------------|--------------------------------------------------------|
-| 0000  | -                 | Reserved (causes an illegal instruction trap)          |
-| 0001  | ALWAYS (implicit) | Operation is not masked                                |
-| 0010  | R3                | Element `i` is enabled if `R3 & (1 << i)` is non-zero  |
-| 0011  | ~R3               | Element `i` is enabled if `R3 & (1 << i)` is zero      |
-| 0100  | R10               | Element `i` is enabled if `R10 & (1 << i)` is non-zero |
-| 0101  | ~R10              | Element `i` is enabled if `R10 & (1 << i)` is zero     |
-| 0110  | R30               | Element `i` is enabled if `R30 & (1 << i)` is non-zero |
-| 0111  | ~R30              | Element `i` is enabled if `R30 & (1 << i)` is zero     |
-
-CR based predication.  TODO: select alternate CR for twin predication.  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
-
-| Value | Mnemonic          | Description                                            |
-|-------|-------------------|--------------------------------------------------------|
-| 1000  | lt                | Element `i` is enabled if `CR[6+i].LT` is set          |
-| 1001  | nl/ge             | Element `i` is enabled if `CR[6+i].LT` is clear        |
-| 1010  | gt                | Element `i` is enabled if `CR[6+i].GT` is set          |
-| 1011  | ng/le             | Element `i` is enabled if `CR[6+i].GT` is clear        |
-| 1100  | eq                | Element `i` is enabled if `CR[6+i].EQ` is set          |
-| 1101  | ne                | Element `i` is enabled if `CR[6+i].EQ` is clear        |
-| 1110  | so/un             | Element `i` is enabled if `CR[6+i].FU` is set          |
-| 1111  | ns/nu             | Element `i` is enabled if `CR[6+i].FU` is clear        |
+One bit indicates the mode: CR or Int predication.   The two types may not be mixed.
+
+Twin predication 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).
+
+### Integer Predication
+
+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     |
+
+### CR based predication
+
+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        |
+
+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
+
 
 ## Prefix Opcode Map (64-bit instruction encoding) (prefix bits 6:11)
 
@@ -92,6 +102,27 @@ SV Registers are numbered using the notation `SV[F]R<N>_<M>` where `<N>` is a de
 
 ## Integer Registers
 
+```
+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)
+
+    for(size_t i = 0; i < VL; i++) {
+        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:
 
 | Integer<br/>Register | SV Integer<br/>Register | Integer<br/>Register | SV Integer<br/>Register | Integer<br/>Register | SV Integer<br/>Register | Integer<br/>Register | SV Integer<br/>Register |
@@ -208,6 +239,7 @@ Standard PowerISA floating-point and VSX registers are aliased to some of the SV
 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)
 
 CR6 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
@@ -215,10 +247,53 @@ 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.
 
+## Alternative CR Vectorization Scheme
+
+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:
+
+| CR<br/>Register | SPR<br/>Field  | SV CR<br/>Register | CR<br/>Register | SPR<br/>Field  | SV CR<br/>Register |
+|-----------------|----------------|--------------------|-----------------|----------------|--------------------|
+| CR[0]           | CR[32:35]      | SVCR0_000          | CR[4]           | CR[48:51]      | SVCR4_000          |
+|                 | CR_EXT1[32:35] | SVCR0_001          |                 | CR_EXT1[48:51] | SVCR4_001          |
+|                 | CR_EXT2[32:35] | SVCR0_010          |                 | CR_EXT2[48:51] | SVCR4_010          |
+|                 | CR_EXT3[32:35] | SVCR0_011          |                 | CR_EXT3[48:51] | SVCR4_011          |
+| *CR[-8]*        | CR[0:3]        | SVCR0_100          | *CR[-4]*        | CR[16:19]      | SVCR4_100          |
+|                 | CR_EXT1[0:3]   | SVCR0_101          |                 | CR_EXT1[16:19] | SVCR4_101          |
+|                 | CR_EXT2[0:3]   | SVCR0_110          |                 | CR_EXT2[16:19] | SVCR4_110          |
+|                 | CR_EXT3[0:3]   | SVCR0_111          |                 | CR_EXT3[16:19] | SVCR4_111          |
+| CR[1]           | CR[36:39]      | SVCR1_000          | CR[5]           | CR[52:55]      | SVCR5_000          |
+|                 | CR_EXT1[36:39] | SVCR1_001          |                 | CR_EXT1[52:55] | SVCR5_001          |
+|                 | CR_EXT2[36:39] | SVCR1_010          |                 | CR_EXT2[52:55] | SVCR5_010          |
+|                 | CR_EXT3[36:39] | SVCR1_011          |                 | CR_EXT3[52:55] | SVCR5_011          |
+| *CR[-7]*        | CR[4:7]        | SVCR1_100          | *CR[-3]*        | CR[20:23]      | SVCR5_100          |
+|                 | CR_EXT1[4:7]   | SVCR1_101          |                 | CR_EXT1[20:23] | SVCR5_101          |
+|                 | CR_EXT2[4:7]   | SVCR1_110          |                 | CR_EXT2[20:23] | SVCR5_110          |
+|                 | CR_EXT3[4:7]   | SVCR1_111          |                 | CR_EXT3[20:23] | SVCR5_111          |
+| CR[2]           | CR[40:43]      | SVCR2_000          | CR[6]           | CR[56:59]      | SVCR6_000          |
+|                 | CR_EXT1[40:43] | SVCR2_001          |                 | CR_EXT1[56:59] | SVCR6_001          |
+|                 | CR_EXT2[40:43] | SVCR2_010          |                 | CR_EXT2[56:59] | SVCR6_010          |
+|                 | CR_EXT3[40:43] | SVCR2_011          |                 | CR_EXT3[56:59] | SVCR6_011          |
+| *CR[-6]*        | CR[8:11]       | SVCR2_100          | *CR[-2]*        | CR[24:27]      | SVCR6_100          |
+|                 | CR_EXT1[8:11]  | SVCR2_101          |                 | CR_EXT1[24:27] | SVCR6_101          |
+|                 | CR_EXT2[8:11]  | SVCR2_110          |                 | CR_EXT2[24:27] | SVCR6_110          |
+|                 | CR_EXT3[8:11]  | SVCR2_111          |                 | CR_EXT3[24:27] | SVCR6_111          |
+| CR[3]           | CR[44:47]      | SVCR3_000          | CR[7]           | CR[60:63]      | SVCR7_000          |
+|                 | CR_EXT1[44:47] | SVCR3_001          |                 | CR_EXT1[60:63] | SVCR7_001          |
+|                 | CR_EXT2[44:47] | SVCR3_010          |                 | CR_EXT2[60:63] | SVCR7_010          |
+|                 | CR_EXT3[44:47] | SVCR3_011          |                 | CR_EXT3[60:63] | SVCR7_011          |
+| *CR[-5]*        | CR[12:15]      | SVCR3_100          | *CR[-1]*        | CR[28:31]      | SVCR7_100          |
+|                 | CR_EXT1[12:15] | SVCR3_101          |                 | CR_EXT1[28:31] | SVCR7_101          |
+|                 | CR_EXT2[12:15] | SVCR3_110          |                 | CR_EXT2[28:31] | SVCR7_110          |
+|                 | CR_EXT3[12:15] | SVCR3_111          |                 | CR_EXT3[28:31] | SVCR7_111          |
+
+Note: CR[-8] through CR[-1] are not part of OpenPower v3.1, they are the MSB half of the 64-bit CR SPR.
+
 # Register Profiles
 
 Instructions are broken down by Register Profiles as listed in the following auto-generated page:
-[[opcode_regs_deduped]]
+[[opcode_regs_deduped]].  "Non-SV" indicates that the operations with this Register Profile cannot be Vectorised (mtspr, bc, dcbz, twi)
 
 ## LDST-1R-1W-imm
 TBD
@@ -239,19 +314,19 @@ TBD
 ## LDST-3R-1W
 TBD
 ## CRi
-TBD
+non-SV
 ## CRio
 TBD
 ## CR=2R1W
 TBD
 ## 1W
-TBD
+non-SV
 ## 1W-CRi
 TBD
 ## 1R
-TBD
+non-SV
 ## 1R-imm
-TBD
+non-SV
 ## 1R-CRo
 TBD
 ## 1R-CRio
@@ -267,7 +342,7 @@ TBD
 ## 1R-1W-CRio
 TBD
 ## 2R
-TBD
+non-SV
 ## 2R-CRo
 TBD
 ## 2R-CRio