aboutsummaryrefslogtreecommitdiff
path: root/target
diff options
context:
space:
mode:
authorLIU Zhiwei <zhiwei_liu@c-sky.com>2020-07-01 23:25:40 +0800
committerAlistair Francis <alistair.francis@wdc.com>2020-07-02 09:19:33 -0700
commit81fbf7daf2eccadd6480b90db95a2e8c410d4414 (patch)
tree907d309659d3294b6f04b4cfedd76faded12f4ab /target
parent0db67e1c0c49011eb09c4f5b790eef15a2b4c351 (diff)
downloadqemu-81fbf7daf2eccadd6480b90db95a2e8c410d4414.zip
qemu-81fbf7daf2eccadd6480b90db95a2e8c410d4414.tar.gz
qemu-81fbf7daf2eccadd6480b90db95a2e8c410d4414.tar.bz2
target/riscv: set-X-first mask bit
Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-Id: <20200701152549.1218-53-zhiwei_liu@c-sky.com> Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
Diffstat (limited to 'target')
-rw-r--r--target/riscv/helper.h4
-rw-r--r--target/riscv/insn32.decode3
-rw-r--r--target/riscv/insn_trans/trans_rvv.inc.c28
-rw-r--r--target/riscv/vector_helper.c63
4 files changed, 98 insertions, 0 deletions
diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index 28aeb74..0f9012b 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -1105,3 +1105,7 @@ DEF_HELPER_6(vmxnor_mm, void, ptr, ptr, ptr, ptr, env, i32)
DEF_HELPER_4(vmpopc_m, tl, ptr, ptr, env, i32)
DEF_HELPER_4(vmfirst_m, tl, ptr, ptr, env, i32)
+
+DEF_HELPER_5(vmsbf_m, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(vmsif_m, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(vmsof_m, void, ptr, ptr, ptr, env, i32)
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index a0f3315..fab4a0b 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -557,6 +557,9 @@ vmornot_mm 011100 - ..... ..... 010 ..... 1010111 @r
vmxnor_mm 011111 - ..... ..... 010 ..... 1010111 @r
vmpopc_m 010100 . ..... ----- 010 ..... 1010111 @r2_vm
vmfirst_m 010101 . ..... ----- 010 ..... 1010111 @r2_vm
+vmsbf_m 010110 . ..... 00001 010 ..... 1010111 @r2_vm
+vmsif_m 010110 . ..... 00011 010 ..... 1010111 @r2_vm
+vmsof_m 010110 . ..... 00010 010 ..... 1010111 @r2_vm
vsetvli 0 ........... ..... 111 ..... 1010111 @r2_zimm
vsetvl 1000000 ..... ..... 111 ..... 1010111 @r
diff --git a/target/riscv/insn_trans/trans_rvv.inc.c b/target/riscv/insn_trans/trans_rvv.inc.c
index 01c32a3..33ffe5d 100644
--- a/target/riscv/insn_trans/trans_rvv.inc.c
+++ b/target/riscv/insn_trans/trans_rvv.inc.c
@@ -2453,3 +2453,31 @@ static bool trans_vmfirst_m(DisasContext *s, arg_rmr *a)
}
return false;
}
+
+/* vmsbf.m set-before-first mask bit */
+/* vmsif.m set-includ-first mask bit */
+/* vmsof.m set-only-first mask bit */
+#define GEN_M_TRANS(NAME) \
+static bool trans_##NAME(DisasContext *s, arg_rmr *a) \
+{ \
+ if (vext_check_isa_ill(s)) { \
+ uint32_t data = 0; \
+ gen_helper_gvec_3_ptr *fn = gen_helper_##NAME; \
+ TCGLabel *over = gen_new_label(); \
+ tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over); \
+ \
+ data = FIELD_DP32(data, VDATA, MLEN, s->mlen); \
+ data = FIELD_DP32(data, VDATA, VM, a->vm); \
+ data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \
+ tcg_gen_gvec_3_ptr(vreg_ofs(s, a->rd), \
+ vreg_ofs(s, 0), vreg_ofs(s, a->rs2), \
+ cpu_env, 0, s->vlen / 8, data, fn); \
+ gen_set_label(over); \
+ return true; \
+ } \
+ return false; \
+}
+
+GEN_M_TRANS(vmsbf_m)
+GEN_M_TRANS(vmsif_m)
+GEN_M_TRANS(vmsof_m)
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index e0ec02c..a58809a 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -4581,3 +4581,66 @@ target_ulong HELPER(vmfirst_m)(void *v0, void *vs2, CPURISCVState *env,
}
return -1LL;
}
+
+enum set_mask_type {
+ ONLY_FIRST = 1,
+ INCLUDE_FIRST,
+ BEFORE_FIRST,
+};
+
+static void vmsetm(void *vd, void *v0, void *vs2, CPURISCVState *env,
+ uint32_t desc, enum set_mask_type type)
+{
+ uint32_t mlen = vext_mlen(desc);
+ uint32_t vlmax = env_archcpu(env)->cfg.vlen / mlen;
+ uint32_t vm = vext_vm(desc);
+ uint32_t vl = env->vl;
+ int i;
+ bool first_mask_bit = false;
+
+ for (i = 0; i < vl; i++) {
+ if (!vm && !vext_elem_mask(v0, mlen, i)) {
+ continue;
+ }
+ /* write a zero to all following active elements */
+ if (first_mask_bit) {
+ vext_set_elem_mask(vd, mlen, i, 0);
+ continue;
+ }
+ if (vext_elem_mask(vs2, mlen, i)) {
+ first_mask_bit = true;
+ if (type == BEFORE_FIRST) {
+ vext_set_elem_mask(vd, mlen, i, 0);
+ } else {
+ vext_set_elem_mask(vd, mlen, i, 1);
+ }
+ } else {
+ if (type == ONLY_FIRST) {
+ vext_set_elem_mask(vd, mlen, i, 0);
+ } else {
+ vext_set_elem_mask(vd, mlen, i, 1);
+ }
+ }
+ }
+ for (; i < vlmax; i++) {
+ vext_set_elem_mask(vd, mlen, i, 0);
+ }
+}
+
+void HELPER(vmsbf_m)(void *vd, void *v0, void *vs2, CPURISCVState *env,
+ uint32_t desc)
+{
+ vmsetm(vd, v0, vs2, env, desc, BEFORE_FIRST);
+}
+
+void HELPER(vmsif_m)(void *vd, void *v0, void *vs2, CPURISCVState *env,
+ uint32_t desc)
+{
+ vmsetm(vd, v0, vs2, env, desc, INCLUDE_FIRST);
+}
+
+void HELPER(vmsof_m)(void *vd, void *v0, void *vs2, CPURISCVState *env,
+ uint32_t desc)
+{
+ vmsetm(vd, v0, vs2, env, desc, ONLY_FIRST);
+}