-[[!tag standards]]
# Bitmanip opcodes
## pcnt - population count
-population-count
+population-count.
Pseudocode:
v &= v - 1; // clear the least significant bit set
}
+This instruction is present in BitManip.
+
## ffirst - find first bit
finds the first bit set as an index.
+Pseudocode:
+
+
+ uint_xlen_t clz(uint_xlen_t rs1)
+ {
+ for (int count = 0; count < XLEN; count++)
+ if ((rs1 << count) >> (XLEN - 1))
+ return count;
+ return XLEN; // -1
+ }
+
+This is similar but not identical to BitManip "CLZ". CLZ returns XLEN when no bits are set, whereas RVV returns -1.
+
## sbf - set before first bit
-Sets all LSBs leading up to where an LSB in the src is set. If the second
-operand is non-zero, this process begins each time from where 1s are set in the
-second operand.
+Sets all LSBs leading up to (excluding) where an LSB in the src is set,
+and sets zeros including and following the src bit found.
+If the second operand is non-zero, this process continues the search
+(in the same LSB to MSB order) beginning each time (including the first time)
+from where 1s are set in the second operand.
+
+A side-effect of the search is that when src is zero, the output is all ones.
+If the second operand is non-zero and the src is zero, the output is a
+copy of the second operand.
# Example
Pseudo-code:
+ def sof(rd, rs1, rs2):
+ rd = 0
+ setting_mode = rs2 == x0 or (regs[rs2] & 1)
+
+ while i < XLEN:
+ bit = 1<<i
+
+ # only reenable when predicate in use, and bit valid
+ if !setting_mode && rs2 != x0:
+ if (regs[rs2] & bit):
+ # back into "setting" mode
+ setting_mode = True
+
+ # skipping mode
+ if !setting_mode:
+ # skip any more 1s
+ if regs[rs1] & bit == 1:
+ i += 1
+ continue
+
+ # setting mode, search for 1
+ if regs[rs1] & bit: # found a bit in rs1:
+ setting_mode = False
+ # next loop starts skipping
+ else:
+ regs[rd] |= bit # always set except when search succeeds
+
+ i += 1
+
def sbf(rd, rs1, rs2):
rd = 0
+ # start setting if no predicate or if 1st predicate bit set
setting_mode = rs2 == x0 or (regs[rs2] & 1)
while i < XLEN:
bit = 1<<i
+ if rs2 != x0 and (regs[rs2] & bit):
+ # reset searching
+ setting_mode = False
if setting_mode:
if regs[rs1] & bit: # found a bit in rs1: stop setting rd
setting_mode = False
## sif - set including first bit
+Similar to sbf except including the bit which ends a run. i.e:
+Sets all LSBs leading up to *and including* where an LSB in the src is set,
+and sets zeros following the point where the src bit is found.
+
+The side-effect of when the src is zero is also the same as for sbf:
+output is all 1s if src2 is zero, and output is equal to src2 if src2
+is non-zero.
+
+
# Example
7 6 5 4 3 2 1 0 Element number
sif a2, a3, a0
1 1 x x x x 1 1 a2 contents
+Pseudo-code:
+
+ def sif(rd, rs1, rs2):
+ rd = 0
+ setting_mode = rs2 == x0 or (regs[rs2] & 1)
+
+ while i < XLEN:
+ bit = 1<<i
+
+ # only reenable when predicate in use, and bit valid
+ if !setting_mode && rs2 != x0:
+ if (regs[rs2] & bit):
+ # back into "setting" mode
+ setting_mode = True
+
+ # skipping mode
+ if !setting_mode:
+ # skip any more 1s
+ if regs[rs1] & bit == 1:
+ i += 1
+ continue
+
+ # setting mode, search for 1
+ regs[rd] |= bit # always set during search
+ if regs[rs1] & bit: # found a bit in rs1:
+ setting_mode = False
+ # next loop starts skipping
+
+ i += 1
+
## sof - set only first bit
+Similar to sbf and sif except *only* set the bit which ends a run.
+
+Unlike sbf and sif however, if the src is zero then the output is
+also guaranteed to be zero, irrespective of src2's contents.
+
# Example
7 6 5 4 3 2 1 0 Element number
1 1 0 1 0 1 0 0 a3 contents
sof a2, a3, a0
0 1 x x x x 0 0 a2 contents
+
+Pseudo-code:
+
+ def sof(rd, rs1, rs2):
+ rd = 0
+ setting_mode = rs2 == x0 or (regs[rs2] & 1)
+
+ while i < XLEN:
+ bit = 1<<i
+
+ # only reenable when predicate in use, and bit valid
+ if !setting_mode && rs2 != x0:
+ if (regs[rs2] & bit):
+ # back into "setting" mode
+ setting_mode = True
+
+ # skipping mode
+ if !setting_mode:
+ # skip any more 1s
+ if regs[rs1] & bit == 1:
+ i += 1
+ continue
+
+ # setting mode, search for 1
+ if regs[rs1] & bit: # found a bit in rs1:
+ regs[rd] |= bit # only set when search succeeds
+ setting_mode = False
+ # next loop starts skipping
+
+ i += 1
+