mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-05 00:33:55 -06:00
target/loongarch: Implement vsat
This patch includes: - VSAT.{B/H/W/D}[U]. Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Signed-off-by: Song Gao <gaosong@loongson.cn> Message-Id: <20230504122810.4094787-18-gaosong@loongson.cn>
This commit is contained in:
parent
4cc4c0f78b
commit
cbe44190cc
5 changed files with 168 additions and 0 deletions
|
@ -2693,3 +2693,104 @@ TRANS(vmod_bu, gen_vvv, gen_helper_vmod_bu)
|
|||
TRANS(vmod_hu, gen_vvv, gen_helper_vmod_hu)
|
||||
TRANS(vmod_wu, gen_vvv, gen_helper_vmod_wu)
|
||||
TRANS(vmod_du, gen_vvv, gen_helper_vmod_du)
|
||||
|
||||
static void gen_vsat_s(unsigned vece, TCGv_vec t, TCGv_vec a, TCGv_vec max)
|
||||
{
|
||||
TCGv_vec min;
|
||||
|
||||
min = tcg_temp_new_vec_matching(t);
|
||||
tcg_gen_not_vec(vece, min, max);
|
||||
tcg_gen_smax_vec(vece, t, a, min);
|
||||
tcg_gen_smin_vec(vece, t, t, max);
|
||||
}
|
||||
|
||||
static void do_vsat_s(unsigned vece, uint32_t vd_ofs, uint32_t vj_ofs,
|
||||
int64_t imm, uint32_t oprsz, uint32_t maxsz)
|
||||
{
|
||||
static const TCGOpcode vecop_list[] = {
|
||||
INDEX_op_smax_vec, INDEX_op_smin_vec, 0
|
||||
};
|
||||
static const GVecGen2s op[4] = {
|
||||
{
|
||||
.fniv = gen_vsat_s,
|
||||
.fno = gen_helper_vsat_b,
|
||||
.opt_opc = vecop_list,
|
||||
.vece = MO_8
|
||||
},
|
||||
{
|
||||
.fniv = gen_vsat_s,
|
||||
.fno = gen_helper_vsat_h,
|
||||
.opt_opc = vecop_list,
|
||||
.vece = MO_16
|
||||
},
|
||||
{
|
||||
.fniv = gen_vsat_s,
|
||||
.fno = gen_helper_vsat_w,
|
||||
.opt_opc = vecop_list,
|
||||
.vece = MO_32
|
||||
},
|
||||
{
|
||||
.fniv = gen_vsat_s,
|
||||
.fno = gen_helper_vsat_d,
|
||||
.opt_opc = vecop_list,
|
||||
.vece = MO_64
|
||||
},
|
||||
};
|
||||
|
||||
tcg_gen_gvec_2s(vd_ofs, vj_ofs, oprsz, maxsz,
|
||||
tcg_constant_i64((1ll<< imm) -1), &op[vece]);
|
||||
}
|
||||
|
||||
TRANS(vsat_b, gvec_vv_i, MO_8, do_vsat_s)
|
||||
TRANS(vsat_h, gvec_vv_i, MO_16, do_vsat_s)
|
||||
TRANS(vsat_w, gvec_vv_i, MO_32, do_vsat_s)
|
||||
TRANS(vsat_d, gvec_vv_i, MO_64, do_vsat_s)
|
||||
|
||||
static void gen_vsat_u(unsigned vece, TCGv_vec t, TCGv_vec a, TCGv_vec max)
|
||||
{
|
||||
tcg_gen_umin_vec(vece, t, a, max);
|
||||
}
|
||||
|
||||
static void do_vsat_u(unsigned vece, uint32_t vd_ofs, uint32_t vj_ofs,
|
||||
int64_t imm, uint32_t oprsz, uint32_t maxsz)
|
||||
{
|
||||
uint64_t max;
|
||||
static const TCGOpcode vecop_list[] = {
|
||||
INDEX_op_umin_vec, 0
|
||||
};
|
||||
static const GVecGen2s op[4] = {
|
||||
{
|
||||
.fniv = gen_vsat_u,
|
||||
.fno = gen_helper_vsat_bu,
|
||||
.opt_opc = vecop_list,
|
||||
.vece = MO_8
|
||||
},
|
||||
{
|
||||
.fniv = gen_vsat_u,
|
||||
.fno = gen_helper_vsat_hu,
|
||||
.opt_opc = vecop_list,
|
||||
.vece = MO_16
|
||||
},
|
||||
{
|
||||
.fniv = gen_vsat_u,
|
||||
.fno = gen_helper_vsat_wu,
|
||||
.opt_opc = vecop_list,
|
||||
.vece = MO_32
|
||||
},
|
||||
{
|
||||
.fniv = gen_vsat_u,
|
||||
.fno = gen_helper_vsat_du,
|
||||
.opt_opc = vecop_list,
|
||||
.vece = MO_64
|
||||
},
|
||||
};
|
||||
|
||||
max = (imm == 0x3f) ? UINT64_MAX : (1ull << (imm + 1)) - 1;
|
||||
tcg_gen_gvec_2s(vd_ofs, vj_ofs, oprsz, maxsz,
|
||||
tcg_constant_i64(max), &op[vece]);
|
||||
}
|
||||
|
||||
TRANS(vsat_bu, gvec_vv_i, MO_8, do_vsat_u)
|
||||
TRANS(vsat_hu, gvec_vv_i, MO_16, do_vsat_u)
|
||||
TRANS(vsat_wu, gvec_vv_i, MO_32, do_vsat_u)
|
||||
TRANS(vsat_du, gvec_vv_i, MO_64, do_vsat_u)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue