aboutsummaryrefslogtreecommitdiff
path: root/riscv/insns/viota_m.h
diff options
context:
space:
mode:
Diffstat (limited to 'riscv/insns/viota_m.h')
-rw-r--r--riscv/insns/viota_m.h51
1 files changed, 51 insertions, 0 deletions
diff --git a/riscv/insns/viota_m.h b/riscv/insns/viota_m.h
new file mode 100644
index 0000000..7aae89a
--- /dev/null
+++ b/riscv/insns/viota_m.h
@@ -0,0 +1,51 @@
+// vmpopc rd, vs2, vm
+require(p->VU.vsew >= e8 && p->VU.vsew <= e64);
+require(!p->VU.vill);
+reg_t vl = p->VU.vl;
+reg_t sew = p->VU.vsew;
+reg_t rd_num = insn.rd();
+reg_t rs1_num = insn.rs1();
+reg_t rs2_num = insn.rs2();
+require(p->VU.vstart == 0);
+
+int cnt = 0;
+for (reg_t i = 0 ; i < P.VU.vlmax; ++i) {
+ const int mlen = p->VU.vmlen;
+ const int midx = (mlen * i) / 32;
+ const int mpos = (mlen * i) % 32;
+ const uint32_t mmask = ((1ul << mlen) - 1) << mpos;
+
+ bool vs2_lsb = ((p->VU.elt<uint32_t>(rs2_num, midx ) >> mpos) & 0x1) == 1;
+ bool do_mask = (p->VU.elt<uint32_t>(0, midx) >> mpos) & 0x1;
+ uint32_t &vd = P.VU.elt<uint32_t>(rd_num, midx);
+
+ bool has_one = false;
+ if (insn.v_vm() == 1 || (insn.v_vm() == 0 && do_mask)) {
+ if (vs2_lsb) {
+ has_one = true;
+ }
+ }
+
+ bool use_ori = (insn.v_vm() == 0) && !do_mask;
+ switch (sew) {
+ case e8:
+ P.VU.elt<uint8_t>(rd_num, i) = use_ori ?
+ P.VU.elt<uint8_t>(rs2_num, i) : cnt;
+ break;
+ case e16:
+ P.VU.elt<uint16_t>(rd_num, i) = use_ori ?
+ P.VU.elt<uint16_t>(rs2_num, i) : cnt;
+ break;
+ case e32:
+ P.VU.elt<uint32_t>(rd_num, i) = use_ori ?
+ P.VU.elt<uint32_t>(rs2_num, i) : cnt;
+ break;
+ default:
+ P.VU.elt<uint64_t>(rd_num, i) = use_ori ?
+ P.VU.elt<uint64_t>(rs2_num, i) : cnt;
+ break;
+ }
+
+ if (has_one)
+ cnt++;
+}