(no commit message)
[libreriscv.git] / openpower / sv / cr_int_predication.mdwn
index e60f6a92154f490c91174d143cf69352224cc1ca..c30776ef32544e534c19b2a63ecc04e52a6d7372 100644 (file)
@@ -60,21 +60,18 @@ Purpose:
 * To provide a vectorised version of the same, suitable for advanced
   predication
 
-Side-effects:
+Useful side-effects:
 
-* mtcrweird when RA=0 is a means to set or clear arbitrary CR bits
+* mtcrweird when RA=0 is a means to set or clear 
+  multiple arbitrary CR Field bits simultaneously,
   using immediates embedded within the instruction.
-
-(Twin) Predication interactions:
-
-* INT twin predication with zeroing is a way to copy an integer into
-  CRs without necessarily needing the INT register (RA).  if it is, it is
-  effectively ANDed (or negate-and-ANDed) with the INT Predicate
-* CR twin predication with zeroing is likewise a way to interact with
-  the incoming integer
-
-this gets particularly powerful if data-dependent predication is also
-enabled.  further explanation is below.
+* With SVP64 on the weird instructions there is bit-for-bit interaction
+  between GPR predicate masks (r3, r10, r31) and the source
+  or destination GPR, in ways that are not possible with other
+  SVP64 instructions because normal SVP64 is bit-per-element.
+  On these weird instructions the element in effect *is* a bit.
+* `mfcrweird` mitigates a need to add `conflictd`, part of
+  [[sv/vector_ops]], as well as allowing more complex comparisons.
 
 # Bit ordering.
 
@@ -90,21 +87,18 @@ OPF ISA WG):
 |---|---- |--|-----|-----|-----|-----  |-----  |--|----      |
 |19 |RT   |  |mask |BFA  |     |XO[0:4]|XO[5:9]|/ |          |
 |19 |     |  |     |     |     |1 //// |00011  |  |rsvd      |
-|19 |RT   |M |mask |BFA  | 0 0 |1 mode |00011  |Rc|crrweird  |
-|19 |RT   |M |mask |BFA  | 0 1 |1 mode |00011  |Rc|mfcrweird |
-|19 |RA   |M |mask |BF   | 0 0 |0 mode |00011  |1 |mtcrrweird |
-|19 |RA   |M |mask |BF   | 0 1 |0 mode |00011  |0 |mtcrweird |
-|19 |BT   |M |mask |BFA  | 0 1 |0 mode |00011  |1 |crweirder |
-|19 |BF //|M |mask |BFA  | 1 1 |0 mode |00011  |0 |crweird   |
+|19 |RT   |M |mask |BFA  | 0 0 |0 mode |00011  |Rc|crrweird  |
+|19 |RT   |M |mask |BFA  | 0 1 |0 mode |00011  |Rc|mfcrweird |
+|19 |RA   |M |mask |BF   | 1 0 |0 mode |00011  |0 |mtcrrweird |
+|19 |RA   |M |mask |BF   | 1 0 |0 mode |00011  |1 |mtcrweird |
+|19 |BT   |M |mask |BFA  | 1 1 |0 mode |00011  |0 |crweirder |
 |19 |BF //|M |mask |BFA  | 1 1 |0 mode |00011  |1 |mcrfm     |
 
 **crrweird**
 
 mode is encoded in XO and is 4 bits
 
-bit 19=0, bit 20=0
-
-    crrweird: RT, BFA, M, mask.mode
+    crrweird: RT,BFA,M,mask,mode
 
     creg = CR{BFA}
     n0 = mask[0] & (mode[0] == creg[0])
@@ -115,18 +109,20 @@ bit 19=0, bit 20=0
     RT[63] = result # MSB0 numbering, 63 is LSB
     If Rc:
         CR0 = analyse(RT)
+
 When used with SVP64 Prefixing this is a [[openpower/sv/normal]]
 SVP64 type operation and as such can use Rc=1 and RC1 Data-dependent
 Mode capability
 
+Also as noted below, element-width override bits normally used
+on the source is instead used to allow multiple results to be packed
+sequentially into the destination. *Destination elwidth overrides still apply*.
+
 **mfcrrweird**
 
 mode is encoded in XO and is 4 bits
 
-bit 19=0, bit 20=0
-
-    mfcrrweird: RT, BFA, mask.mode
+    mfcrrweird: RT,BFA,mask,mode
 
     creg = CR{BFA}
     n0 = mask[0] & (mode[0] == creg[0])
@@ -150,14 +146,13 @@ into the destination.  *Destination elwidth overrides still apply*
 
 mode is encoded in XO and is 4 bits
 
-bit 19=0, bit 20=0
-
-    mtcrrweird: BF, RA, M, mask.mode
+    mtcrrweird: BF,RA,M,mask,mode
 
-    n0 = mask[0] & (mode[0] == RA[63])
-    n1 = mask[1] & (mode[1] == RA[62])
-    n2 = mask[2] & (mode[2] == RA[61])
-    n3 = mask[3] & (mode[3] == RA[60])
+    a = (RA|0)
+    n0 = mask[0] & (mode[0] == a[63])
+    n1 = mask[1] & (mode[1] == a[62])
+    n2 = mask[2] & (mode[2] == a[61])
+    n3 = mask[3] & (mode[3] == a[60])
     result = n0 || n1 || n2 || n3
     if M:
         result |= CR{BF} & ~mask
@@ -169,9 +164,7 @@ Mode capability
 
 **mtcrweird**
 
-bit 19=0, bit 20=1
-
-    mtcrweird: BF, RA, M, mask.mode
+    mtcrweird: BF,RA,M,mask,mode
 
     reg = (RA|0)
     lsb = reg[63] # MSB0 numbering
@@ -194,37 +187,17 @@ When used with SVP64 Prefixing this is a [[openpower/sv/cr_ops]] SVP64
 type operation that has 3-bit Data-dependent and 3-bit Predicate-result
 capability (BF is 3 bits)
 
-**crweird**
-
-bit 19=1, bit 20=0, bit 30=0
-
-    crweird: BF, BFA, M, mask.mode
-
-    creg = CR{BFA}
-    n0 = mask[0] & (mode[0] == creg[0])
-    n1 = mask[1] & (mode[1] == creg[1])
-    n2 = mask[2] & (mode[2] == creg[2])
-    n3 = mask[3] & (mode[3] == creg[3])
-    result = n0 || n1 || n2 || n3
-    if M:
-        result |= CR{BF} & ~mask
-    CR{BF} = result
-
-Note that when M=1 this operation is a Read-Modify-Write on the CR Field
-BF. Masked-out bits of the 4-bit CR Field BF will not be changed when
-M=1. Correspondingly when M=0 this operation is an overwrite: no read
-of BF is required because the masked-out bits of the BF CR Field are
-set to zero.
-
-When used with SVP64 Prefixing this is a [[openpower/sv/cr_ops]] SVP64
-type operation that has 3-bit Data-dependent and 3-bit Predicate-result
-capability (BF is 3 bits)
-
 **mcrfm** - Move CR Field, masked.
 
-bit 19=1, bit 20=0, bit 30=1
+This instruction copies, sets, or inverts parts of a CR Field
+into another CR Field.  `mcrf` copies only one bit of the CR
+from any arbitrary bit to any other arbitrary bit, whereas
+`mcrfm` copies an entire 4-bit CR Field (or masked parts thereof).
+Unlike `mcrf` the bits of the CR Field may not change position:
+the EQ bit from the source may only go into the EQ bit of the
+destination (optionally inverted, set, or cleared).
 
-    mcrfm: BF, BFA, M, mask.mode
+    mcrfm: BF,BFA,M,mask,mode
 
     result = mask & CR{BFA}
     if M:
@@ -232,7 +205,7 @@ bit 19=1, bit 20=0, bit 30=1
     result ^= mode
     CR{BF} = result
 
-Note that when M=1 this operation is a Read-Modify-Write on the CR Field
+When M=1 this operation is a Read-Modify-Write on the CR Field
 BF. Masked-out bits of the 4-bit CR Field BF will not be changed when
 M=1. Correspondingly when M=0 this operation is an overwrite: no read
 of BF is required because the masked-out bits of the BF CR Field are
@@ -250,9 +223,7 @@ individual bits in BF may be set to 1 by ensuring that the required bit of
 
 **crweirder**
 
-bit 19=1, bit 20=1
-
-    crweirder: BT, BFA, mask.mode
+    crweirder: BT,BFA,mask,mode
 
     creg = CR{BFA}
     n0 = mask[0] & (mode[0] == creg[0])
@@ -270,11 +241,11 @@ capability (BFT is 5 bits)
 
 **Example Pseudo-ops:**
 
-    mtcri BF, mode    mtcrweird BF, r0, 0, 0b1111.~mode
-    mtcrset BF, mask  mtcrweird BF, r0, 1, mask.0b0000
-    mtcrclr BF, mask  mtcrweird BF, r0, 1, mask.0b1111
+    mtcri BF, mode    mtcrweird BF, r0, 0, 0b1111,~mode
+    mtcrset BF, mask  mtcrweird BF, r0, 1, mask,0b0000
+    mtcrclr BF, mask  mtcrweird BF, r0, 1, mask,0b1111
 
-# Vectorised versions
+# Vectorised versions involving GPRs
 
 The name "weird" refers to a minor violation of SV rules when it comes
 to deriving the Vectorised versions of these instructions.
@@ -282,7 +253,10 @@ to deriving the Vectorised versions of these instructions.
 Normally the progression of the SV for-loop would move on to the
 next register.  Instead however in the scalar case these instructions
 **remain in the same register** and insert or transfer between **bits**
-of the scalar integer source or destination.
+of the scalar integer source or destination.  The reason is that when
+using CR Fields as predicate masks and there is a need to transfer
+into a GPR, again for use as a predicate mask, the CR Field bits
+need to be efficiently packed into that one GPR (r3, r10 or r31).
 
 Further useful violation of the normal SV Elwidth override rules allows
 for packing (or unpacking) of multiple CR test results into (or out of)
@@ -292,7 +266,7 @@ bits within the Integer element set to zero) whilst the INT (dest
 operand) elwidth field still sets the Integer element size as usual
 (8/16/32/default)
 
-    crrweird: RT, BB, mask.mode
+**crrweird: RT, BB, mask.mode**
 
     for i in range(VL):
         if BB.isvec:
@@ -337,6 +311,68 @@ Note that:
   of the INT Elements, the packing arrangement depending on both
   elwidth override settings.
 
+**mfcrrweird: RT, BFA, mask.mode**
+
+Unlike `crrweird` the results are 4-bit wide, so the packing
+will begin to spill over to other destination elements.  8 results per
+destination at 4-bits each still fits into destination elwidth at 32-bit,
+but for 16-bit and 8-bit obviously this does not fit, and must split
+across to the next element
+
+When for example destination elwidth is 16-bit (0b10) the following packing
+occurs:
+
+- SVRM bits 6:7 equal to 0b00 - one 4-bit result element packed into the
+  first 4-bits of the 16-bit destination element (in the first 4 LSBs)
+- SVRM bits 6:7 equal to 0b01 - two 4-bit result elements packed into the
+  first 8-bits of the 16-bit destination element (in the first 8 LSBs)
+- SVRM bits 6:7 equal to 0b10 - four 4-bit result elements packed into each
+  16-bit destination element
+- SVRM bits 6:7 equal to 0b11 - eight 4-bit result elements, the first four
+  of which are packed into the first 16-bit destination element, the
+  second four of which are packed into the second 16-bit destination element.
+
+Pseudocode example: note that dest elwidth overrides affect the
+packing of results. BB.elwidth in effect requests how many 4-bit
+result elements would like to be packed, but RT.elwidth determines
+the limit. Any parts of the destination elements not containing
+results are set to zero.
+
+    for i in range(VL):
+        if BB.isvec:
+            creg = CR{BB+i}
+        else:
+            creg = CR{BB}
+        n0 = mask[0] & (mode[0] == creg[0])
+        n1 = mask[1] & (mode[1] == creg[1])
+        n2 = mask[2] & (mode[2] == creg[2])
+        n3 = mask[3] & (mode[3] == creg[3])
+        result = n0||n1||n2||n3 # 4-bit result
+        if RT.isvec:
+            # RT.elwidth override can affect the packing
+            bwid = {0b00:64, 0b01:8, 0b10:16, 0b11:32}[RT.elwidth]
+            t4, t8 = min(4, bwid//2), min(8, bwid//2)
+            # yes, really, the CR's elwidth field determines
+            # the bit-packing into the INT!
+            if BB.elwidth == 0b00:
+                # pack 1 result into 64-bit registers
+                idx, boff = i, 0
+            if BB.elwidth == 0b01:
+                # pack 2 results sequentially into INT registers
+                idx, boff = i//2, i%2
+            if BB.elwidth == 0b10:
+                # pack 4 results sequentially into INT registers
+                idx, boff = i//t4, i%t4
+            if BB.elwidth == 0b11:
+                # pack 8 results sequentially into INT registers
+                idx, boff = i//t8, i%t8
+        else:
+            # exceeding VL=16 is UNDEFINED
+            idx, boff = 0, i
+        iregs[RT+idx][60-boff*4:63-boff*4] = result
+
+
+
 # v3.1 setbc instructions
 
 There are additional setb conditional instructions in v3.1 (p129)