(no commit message)
[libreriscv.git] / openpower / sv / cr_int_predication.mdwn
index 5d33915238bfa1d837215d1bea34ea1bc7bb8ac4..c30776ef32544e534c19b2a63ecc04e52a6d7372 100644 (file)
@@ -2,30 +2,55 @@
 
 # New instructions for CR/INT predication
 
+**DRAFT STATUS**
+
 See:
 
-* <https://bugs.libre-soc.org/show_bug.cgi?id=533>
+* main bugreport for crweirds
+  <https://bugs.libre-soc.org/show_bug.cgi?id=533>
 * <https://bugs.libre-soc.org/show_bug.cgi?id=527>
 * <https://bugs.libre-soc.org/show_bug.cgi?id=569>
 * <https://bugs.libre-soc.org/show_bug.cgi?id=558#c47>
 
 Rationale:
 
-Condition Registers are conceptually perfect for use as predicate masks, the only problem being that typical Vector ISAs have quite comprehensive mask-based instructions: set-before-first, popcount and much more.  In fact many Vector ISAs can use Vectors *as* masks, consequently the entire Vector ISA is available for use in creating masks.  This is not practical for SV given the premise to minimise adding of instructions.
-
-With the scalar OpenPOWER v3.0B ISA having already popcnt, cntlz and others normally seen in Vector Mask operations it makes sense to allow *both* scalar integers *and* CR-Vectors to be predicate masks.  That in turn means that much more comprehensive interaction between CRs and scalar Integers is required.
-
-The opportunity is therefore taken to also augment CR logical arithmetic as well, using a mask-based paradigm that takes into consideration multiple bits of each CR (eq/lt/gt/ov).  v3.0B Scalar CR instructions (crand, crxor) only allow a single bit calculation.
+Condition Registers are conceptually perfect for use as predicate masks,
+the only problem being that typical Vector ISAs have quite comprehensive
+mask-based instructions: set-before-first, popcount and much more.
+In fact many Vector ISAs can use Vectors *as* masks, consequently the
+entire Vector ISA is usually available for use in creating masks (one
+exception being AVX512 which has a dedicated Mask regfile and opcodes).
+Duplication of such operations (popcount etc) is not practical for SV
+given the strategy of leveraging pre-existing Scalar instructions in a
+minimalist way.
+
+With the scalar OpenPOWER v3.0B ISA having already popcnt, cntlz and
+others normally seen in Vector Mask operations it makes sense to allow
+*both* scalar integers *and* CR-Vectors to be predicate masks.  That in
+turn means that much more comprehensive interaction between CRs and scalar
+Integers is required, because with the CR Predication Modes designating
+CR *Fields* (not CR bits) as Predicate Elements, fast transfers between
+CR *Fields* and the Integer Register File is needed.
+
+The opportunity is therefore taken to also augment CR logical arithmetic
+as well, using a mask-based paradigm that takes into consideration
+multiple bits of each CR Field (eq/lt/gt/ov).  By contrast v3.0B Scalar
+CR instructions (crand, crxor) only allow a single bit calculation, and
+both mtcr and mfcr are CR-orientated rather than CR *Field* orientated.
+
+Also strangely there is no v3.0 instruction for directly moving CR Fields,
+only CR *bits*, so that is corrected here with `mcrfm`. The opportunity
+is taken to allow inversion of CR Field bits, when copied.
 
 Basic concept:
 
-* CR-based instructions that perform simple AND/OR/XOR from all four bits
-  of a CR to create a single bit value (0/1) in an integer register
+* CR-based instructions that perform simple AND/OR from any four bits
+  of a CR field to create a single bit value (0/1) in an integer register
 * Inverse of the same, taking a single bit value (0/1) from an integer
-  register to selectively target all four bits of a given CR
+  register to selectively target any four bits of a given CR Field
 * CR-to-CR version of the same, allowing multiple bits to be AND/OR/XORed
   in one hit.
-* Vectorisation of the same
+* Optional Vectorisation of the same when SVP64 is implemented
 
 Purpose:
 
@@ -35,103 +60,111 @@ Purpose:
 * To provide a vectorised version of the same, suitable for advanced
   predication
 
-Side-effects:
-
-* mtcrweird when RA=0 is a means to set or clear arbitrary CR bits from immediates
-
-(Twin) Predication interactions:
+Useful side-effects:
 
-* 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.
+* mtcrweird when RA=0 is a means to set or clear 
+  multiple arbitrary CR Field bits simultaneously,
+  using immediates embedded within the instruction.
+* 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.
 
-IBM chose MSB0 for the OpenPOWER v3.0B specification.  This makes things slightly hair-raising.  Our desire initially is therefore to follow the logical progression from the defined behaviour of `mtcr` and `mfcr` etc.  
-In [[isa/sprset]] we see the pseudocode for `mtcrf` for example:
-
-    mtcrf FXM,RS
-
-    do n = 0 to 7
-      if FXM[n] = 1 then
-        CR[4*n+32:4*n+35] <- (RS)[4*n+32:4*n+35]
-
-This places (according to a mask schedule) `CR0` into MSB0-numbered bits 32-35 of the target Integer register `RS`, these bits of `RS` being the 31st down to the 28th.  Unfortunately, even when not Vectorised, this inserts CR numbering inversions on each batch of 8 CRs, massively complicating matters.  Predication when using CRs would have to be morphed to this (unacceptably complex) behaviour:
+Please see [[svp64/appendix]] regarding CR bit ordering and for
+the definition of `CR{n}`
 
-    for i in range(VL):
-       if INTpredmode:
-         predbit = (r3)[63-i] # IBM MSB0 spec sigh
-       else:
-         # completely incomprehensible vertical numbering
-         n = (7-(i%8)) | (i & ~0x7) # total mess
-         CRpredicate = CR{n}        # select CR0, CR1, ....
-         predbit = CRpredicate[offs]  # select eq..ov bit
+# Instruction form and pseudocode
 
-Which is nowhere close to matching the straightforward obvious case:
+**DRAFT** Instruction format (use of MAJOR 19 not approved by
+OPF ISA WG):
 
-    for i in range(VL):
-       if INTpredmode:
-         predbit = (r3)[63-i] # IBM MSB0 spec sigh
-       else:
-         CRpredicate = CR{i} # start at CR0, work up
-         predbit = CRpredicate[offs]
+|0-5|6-10 |11|12-15|16-18|19-20|21-25  |26-30  |31|name      |
+|---|---- |--|-----|-----|-----|-----  |-----  |--|----      |
+|19 |RT   |  |mask |BFA  |     |XO[0:4]|XO[5:9]|/ |          |
+|19 |     |  |     |     |     |1 //// |00011  |  |rsvd      |
+|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     |
 
-In other words unless we do something about this, when we transfer bits from an Integer Predicate into a Vector of CRs, our numbering of CRs, when enumerating them in a CR Vector, would be **CR7** CR6 CR5.... CR0 **CR15** CR14 CR13... CR8 **CR23** CR22 etc. **not** the more natural and obvious CR0 CR1 ... CR23.
+**crrweird**
 
-Therefore the instructions below need to **redefine** the relationship so that CR numbers (CR0, CR1) sequentially match the arithmetically-ordered bits of Integer registers.  By `arithmetic` this is deduced from the fact that the instruction `addi r3, r0, 1` will result in the **LSB** (numbered 63 in IBM MSB0 order) of r3 being set to 1 and all other bits set to zero.  We therefore refer, below, to this LSB as "Arithmetic bit 0", and it is this bit which is used - defined - as being the first bit used in Integer predication (on element 0).
+mode is encoded in XO and is 4 bits
 
-Below is some pseudocode that, given a CR offset `offs` to represent `CR.eq` thru to `CR.ov` respectively, will copy the INT predicate bits in the correct order into the first 8 CRs:
+    crrweird: RT,BFA,M,mask,mode
 
-    do n = 0 to 7
-        CR[4*n+32+offs] <- (RS)[63-n]
+    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 else n0&n1&n2&n3
+    RT[63] = result # MSB0 numbering, 63 is LSB
+    If Rc:
+        CR0 = analyse(RT)
 
-Assuming that `offs` is set to `CR.eq` this results in:
+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
 
-* Arithmetic bit 0 (the LSB, numbered 63 in IBM MSB0 terminology)
-  of RS being inserted into CR0.eq
-* Arithmetic bit 1  of RS being inserted into CR1.eq
-* ...
-* Arithmetic bit 7 of RS being inserted into CR7.eq
+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*.
 
-To clarify, then: all instructions below do **NOT** follow the IBM convention, they follow the natural sequence CR0 CR1 instead.  However it is critically important to note that the offsets **in** a CR (`CR.eq` for example) continue to follow the v3.0B definition and convention.
+**mfcrrweird**
 
+mode is encoded in XO and is 4 bits
 
-# Instruction form and pseudocode
+    mfcrrweird: RT,BFA,mask,mode
 
-Note that `CR{n}` refers to `CR0` when `n=0` and consequently, for CR0-7, is defined, in v3.0B pseudocode, as:
+    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
+    RT[60:63] = result # MSB0 numbering, 63 is LSB
+    If Rc:
+        CR0 = analyse(RT)
 
-     CR{7-n} = CR[32+n*4:35+n*4]
+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.
 
-Instruction format:
+Also as noted below, element-width override bits normally used
+on the source is instead used to allow multiple results to be packed
+into the destination.  *Destination elwidth overrides still apply*
 
-    | 0-5 | 6-10  | 11 | 12-15 | 16-18 | 19-20 | 21-25   | 26-30   | 31 |
-    | --- | ----  | -- | ----- | ----- | ----- | -----   | -----   | -- |
-    | 19  | RT    |    | mask  | BB    |       | XO[0:4] | XO[5:9] | /  |
-    | 19  | RT    | 0  | mask  | BB    |  0 M  | XO[0:4] | 0 mode  | Rc |
-    | 19  | RA    | 1  | mask  | BB    |  0 /  | XO[0:4] | 0 mode  | /  |
-    | 19  | BT // | 0  | mask  | BB    |  1 /  | XO[0:4] | 0 mode  | /  |
-    | 19  | BFT   | 1  | mask  | BB    |  1 M  | XO[0:4] | 0 mode  | /  |
+**mtcrrweird**
 
 mode is encoded in XO and is 4 bits
 
-bit 11=0, bit 19=0
+    mtcrrweird: BF,RA,M,mask,mode
 
-    crrweird: RT, BB, mask.mode
+    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
+    CR{BF} = result
 
-    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 if M else n0&n1&n2&n3
-    RT[63] = result # MSB0 numbering, 63 is LSB
-    If Rc:
-        CR1 = analyse(RT)
+When used with SVP64 Prefixing this is a [[openpower/sv/normal]]
+SVP64 type operation and as such can use RC1 Data-dependent
+Mode capability
 
-bit 11=1, bit 19=0
+**mtcrweird**
 
-    mtcrweird: RA, BB, mask.mode
+    mtcrweird: BF,RA,M,mask,mode
 
     reg = (RA|0)
     lsb = reg[63] # MSB0 numbering
@@ -139,48 +172,101 @@ bit 11=1, bit 19=0
     n1 = mask[1] & (mode[1] == lsb)
     n2 = mask[2] & (mode[2] == lsb)
     n3 = mask[3] & (mode[3] == lsb)
-    CR{BB} = n0 || n1 || n2 || n3
-
-bit 11=0, bit 19=1
-
-    crweird: BT, BB, mask.mode
-
-    creg = CR{BB}
+    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.
+
+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
+
+    result = mask & CR{BFA}
+    if M:
+        result |= CR{BF} & ~mask
+    result ^= mode
+    CR{BF} = result
+
+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)
+
+*Programmer's note: `mode` being XORed onto the result provides
+considerable flexibility. individual bits of BFA may be copied inverted
+to BF by ensuring that `mask` and `mode` have the same bit set.  Also,
+individual bits in BF may be set to 1 by ensuring that the required bit of
+`mask` is set to zero and the same bit in `mode` is set to 1*
+
+**crweirder**
+
+    crweirder: BT,BFA,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])
-    CR{BT} = n0 || n1 || n2 || n3
-
-bit 11=1, bit 19=1
-
-    crweirder: BFT, BB, mask.mode
-
-    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])
-    BF = BFT[2:4] # select CR
-    bit = BFT[0:1] # select bit of CR
+    BF = BT[2:4] # select CR
+    bit = BT[0:1] # select bit of CR
     result = n0|n1|n2|n3 if M else n0&n1&n2&n3
     CR{BF}[bit] = result
 
-Pseudo-op:
+When used with SVP64 Prefixing this is a [[openpower/sv/cr_ops]] SVP64
+type operation that has 5-bit Data-dependent and 5-bit Predicate-result
+capability (BFT is 5 bits)
 
-    mtcri BB, mode    mtcrweird r0, BB, 0b1111.~mode
-    mtcrset BB, mask  mtcrweird r0, BB, mask.0b0000
-    mtcrclr BB, mask  mtcrweird r0, BB, mask.0b1111
+**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
 
-# 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.
+The name "weird" refers to a minor violation of SV rules when it comes
+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.
+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.  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).
 
-    crrweird: RT, BB, mask.mode
+Further useful violation of the normal SV Elwidth override rules allows
+for packing (or unpacking) of multiple CR test results into (or out of)
+an Integer Element. Note that the CR (source operand) elwidth field is
+utilised to determine the bit- packing size (1/2/4/8 with remaining
+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**
 
     for i in range(VL):
         if BB.isvec:
@@ -191,28 +277,145 @@ Instead however in the scalar case these instructions **remain in the same regis
         n1 = mask[1] & (mode[1] == creg[1])
         n2 = mask[2] & (mode[2] == creg[2])
         n3 = mask[3] & (mode[3] == creg[3])
+        # OR or AND to a single bit
         result = n0|n1|n2|n3 if M else n0&n1&n2&n3
         if RT.isvec:
-            iregs[RT+i][63] = result
+            # TODO: RT.elwidth override to be also added here
+            # note, 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
+                iregs[RT+i][0..62] = 0
+                iregs[RT+i][63] = result # sets LSB to result
+            if BB.elwidth == 0b01:
+                # pack 2 results sequentially into INT registers
+                iregs[RT+i//2][0..61] = 0
+                iregs[RT+i//2][63-(i%2)] = result
+            if BB.elwidth == 0b10:
+                # pack 4 results sequentially into INT registers
+                iregs[RT+i//4][0..59] = 0
+                iregs[RT+i//4][63-(i%4)] = result
+            if BB.elwidth == 0b11:
+                # pack 8 results sequentially into INT registers
+                iregs[RT+i//8][0..55] = 0
+                iregs[RT+i//8][63-(i%8)] = result
         else:
-            iregs[RT][63-i] = result
+            iregs[RT][63-i] = result # results also in scalar INT
 
 Note that:
 
 * in the scalar case the CR-Vector assessment
   is stored bit-wise starting at the LSB of the
    destination scalar INT
-* in the INT-vector case the result is stored in the
-  LSB of each element in the result vector
+* in the INT-vector case the results are packed into LSBs
+  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
+
 
-Note that element width overrides are respected on the INT src or destination register (but that elwidth overrides on CRs are meaningless)
 
 # v3.1 setbc instructions
 
-there are additional setb conditional instructions in v3.1 (p129)
+There are additional setb conditional instructions in v3.1 (p129)
 
     RT = (CR[BI] == 1) ? 1 : 0
 
-which also negate that, and also return -1 / 0.  these are similar yo crweird but not the same purpose.
+which also negate that, and also return -1 / 0.  these are similar to
+crweird but not the same purpose.  most notable is that crweird acts on
+CR fields rather than the entire 32 bit CR.
+
+# Predication Examples
+
+Take the following example:
+
+    r10 = 0b00010
+    sv.mtcrweird/dm=r10/dz cr8.v, 0, 0b0011.0000
+
+Here, RA is zero, so the source input is zero. The destination is CR Field
+8, and the destination predicate mask indicates to target the first two
+elements.  Destination predicate zeroing is enabled, and the destination
+predicate is only set in the 2nd bit.  mask is 0b0011, mode is all zeros.
+
+Let us first consider what should go into element 0 (CR Field 8):
+
+* The destination predicate bit is zero, and zeroing is enabled.
+* Therefore, what is in the source is irrelevant: the result must
+  be zero.
+* Therefore all four bits of CR Field 8 are therefore set to zero.
+
+Now the second element, CR Field 9 (CR9):
+
+* Bit 2 of the destination predicate, r10, is 1. Therefore the computation
+  of the result is relevant.
+* RA is zero therefore bit 2 is zero.  mask is 0b0011 and mode is 0b0000
+* When calculating n0 thru n3 we get n0=1, n1=2, n2=0, n3=0
+* Therefore, CR9 is set (using LSB0 ordering) to 0b0011, i.e. to mask.
 
+It should be clear that this instruction uses bits of the integer
+predicate to decide whether to set CR Fields to `(mask & ~mode)` or
+to zero.  Thus, in effect, it is the integer predicate that has been
+copied into the CR Fields.
 
+By using twin predication, zeroing, and inversion (sm=~r3, dm=r10) for
+example, it becomes possible to combine two Integers together in order
+to set bits in CR Fields.  Likewise there are dozens of ways that CR
+Predicates can be used, on the same sv.mtcrweird instruction.