Commit 81fbf7da authored by LIU Zhiwei's avatar LIU Zhiwei Committed by Alistair Francis
Browse files

target/riscv: set-X-first mask bit



Signed-off-by: default avatarLIU Zhiwei <zhiwei_liu@c-sky.com>
Reviewed-by: default avatarRichard Henderson <richard.henderson@linaro.org>
Message-Id: <20200701152549.1218-53-zhiwei_liu@c-sky.com>
Signed-off-by: default avatarAlistair Francis <alistair.francis@wdc.com>
parent 0db67e1c
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -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)
+3 −0
Original line number Diff line number Diff line
@@ -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
+28 −0
Original line number Diff line number Diff line
@@ -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)
+63 −0
Original line number Diff line number Diff line
@@ -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);
}