5 These are bit manipulation opcodes that, if provided, augment SimpleV for
6 the purposes of efficiently accelerating Vector Processing, 3D Graphics
9 The justification for their inclusion in BitManip is identical to the
10 significant justification that went into their inclusion in the
11 RISC-V Vector Extension (under the "Predicate Mask" opcodes section)
14 <https://github.com/riscv/riscv-v-spec/blob/master/v-spec.adoc#vector-mask-instructions>
19 SV uses standard integer scalar registers as a predicate bitmask. Therefore,
20 the majority of RISC-V RV32I / RV64I bit-level instructions are perfectly
21 adequate. Some exceptions however present themselves from RVV.
23 ## logical bit-wise instructions
25 These are the available bitwise instructions in RVV:
27 vmand.mm vd, vs2, vs1 # vd[i] = vs2[i].LSB && vs1[i].LSB
28 vmnand.mm vd, vs2, vs1 # vd[i] = !(vs2[i].LSB && vs1[i].LSB)
29 vmandnot.mm vd, vs2, vs1 # vd[i] = vs2[i].LSB && !vs1[i].LSB
30 vmxor.mm vd, vs2, vs1 # vd[i] = vs2[i].LSB ^^ vs1[i].LSB
31 vmor.mm vd, vs2, vs1 # vd[i] = vs2[i].LSB || vs1[i].LSB
32 vmnor.mm vd, vs2, vs1 # vd[i] = !(vs2[i[.LSB || vs1[i].LSB)
33 vmornot.mm vd, vs2, vs1 # vd[i] = vs2[i].LSB || !vs1[i].LSB
34 vmxnor.mm vd, vs2, vs1 # vd[i] = !(vs2[i].LSB ^^ vs1[i].LSB)
36 The ones that exist in scalar RISC-V are:
38 AND rd, rs1, rs2 # rd = rs1 & rs2
39 OR rd, rs1, rs2 # rd = rs1 | rs2
40 XOR rd, rs1, rs2 # rd = rs1 ^ rs2
42 The ones in Bitmanip are:
44 ANDN rd, rs1, rs2 # rd = rs1 & ~rs2
45 ORN rd, rs1, rs2 # rd = rs1 | ~rs2
46 XORN rd, rs1, rs2 # rd = rs1 ^ ~rs2
53 These are currently listed as "pseudo-ops" in BitManip-Draft (0.91)
54 They need to be actual opcodes.
57 TODO: there is an extensive table in RVV of bit-level operations:
59 output instruction pseudoinstruction
61 | 0 | 1 | 2 | 3 | instruction | pseudoinstruction |
62 | - | - | - | - | -------------------------- | ----------------- |
63 | 0 | 0 | 0 | 0 | vmxor.mm vd, vd, vd | vmclr.m vd |
64 | 1 | 0 | 0 | 0 | vmnor.mm vd, src1, src2 | |
65 | 0 | 1 | 0 | 0 | vmandnot.mm vd, src2, src1 | |
66 | 1 | 1 | 0 | 0 | vmnand.mm vd, src1, src1 | vmnot.m vd, src1 |
67 | 0 | 0 | 1 | 0 | vmandnot.mm vd, src1, src2 | |
68 | 1 | 0 | 1 | 0 | vmnand.mm vd, src2, src2 | vmnot.m vd, src2 |
69 | 0 | 1 | 1 | 0 | vmxor.mm vd, src1, src2 | |
70 | 1 | 1 | 1 | 0 | vmnand.mm vd, src1, src2 | |
71 | 0 | 0 | 0 | 1 | vmand.mm vd, src1, src2 | |
72 | 1 | 0 | 0 | 1 | vmxnor.mm vd, src1, src2 | |
73 | 0 | 1 | 0 | 1 | vmand.mm vd, src2, src2 | vmcpy.m vd, src2 |
74 | 1 | 1 | 0 | 1 | vmornot.mm vd, src2, src1 | |
75 | 0 | 0 | 1 | 1 | vmand.mm vd, src1, src1 | vmcpy.m vd, src1 |
76 | 1 | 0 | 1 | 1 | vmornot.mm vd, src1, src2 | |
77 | 1 | 1 | 1 | 1 | vmxnor.mm vd, vd, vd | vmset.m vd |
79 ## pcnt - population count
83 ## ffirst - find first bit
85 finds the first bit set as an index.
87 ## sbf - set before first bit
89 Sets all LSBs leading up to where an LSB in the src is set. If the second
90 operand is non-zero, this process begins each time from where 1s are set in the
95 7 6 5 4 3 2 1 0 Bit number
97 1 0 0 1 0 1 0 0 a3 contents
99 0 0 0 0 0 0 1 1 a2 contents
101 1 0 0 1 0 1 0 1 a3 contents
105 0 0 0 0 0 0 0 0 a3 contents
109 1 1 0 0 0 0 1 1 a0 vcontents
110 1 0 0 1 0 1 0 0 a3 contents
112 0 1 0 0 0 0 1 1 a2 contents
116 def sbf(rd, rs1, rs2):
118 setting_mode = rs2 == x0 or (regs[rs2] & 1)
122 if regs[rs1] & bit: # found a bit in rs1: stop setting rd
126 else if rs2 != x0: # searching mode
127 if (regs[rs2] & bit):
128 setting_mode = True # back into "setting" mode
131 ## sif - set including first bit
135 7 6 5 4 3 2 1 0 Element number
137 1 0 0 1 0 1 0 0 a3 contents
139 0 0 0 0 0 1 1 1 a2 contents
141 1 0 0 1 0 1 0 1 a3 contents
145 1 1 0 0 0 0 1 1 a0 vcontents
146 1 0 0 1 0 1 0 0 a3 contents
148 1 1 x x x x 1 1 a2 contents
150 ## sof - set only first bit
154 7 6 5 4 3 2 1 0 Element number
156 1 0 0 1 0 1 0 0 a3 contents
158 0 0 0 0 0 1 0 0 a2 contents
160 1 0 0 1 0 1 0 1 a3 contents
164 1 1 0 0 0 0 1 1 a0 vcontents
165 1 1 0 1 0 1 0 0 a3 contents
167 0 1 x x x x 0 0 a2 contents