mirror of https://github.com/xemu-project/xemu.git
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
|
@ -1061,3 +1061,12 @@ INSN_LSX(vmod_bu, vvv)
|
||||||
INSN_LSX(vmod_hu, vvv)
|
INSN_LSX(vmod_hu, vvv)
|
||||||
INSN_LSX(vmod_wu, vvv)
|
INSN_LSX(vmod_wu, vvv)
|
||||||
INSN_LSX(vmod_du, vvv)
|
INSN_LSX(vmod_du, vvv)
|
||||||
|
|
||||||
|
INSN_LSX(vsat_b, vv_i)
|
||||||
|
INSN_LSX(vsat_h, vv_i)
|
||||||
|
INSN_LSX(vsat_w, vv_i)
|
||||||
|
INSN_LSX(vsat_d, vv_i)
|
||||||
|
INSN_LSX(vsat_bu, vv_i)
|
||||||
|
INSN_LSX(vsat_hu, vv_i)
|
||||||
|
INSN_LSX(vsat_wu, vv_i)
|
||||||
|
INSN_LSX(vsat_du, vv_i)
|
||||||
|
|
|
@ -320,3 +320,12 @@ DEF_HELPER_4(vmod_bu, void, env, i32, i32, i32)
|
||||||
DEF_HELPER_4(vmod_hu, void, env, i32, i32, i32)
|
DEF_HELPER_4(vmod_hu, void, env, i32, i32, i32)
|
||||||
DEF_HELPER_4(vmod_wu, void, env, i32, i32, i32)
|
DEF_HELPER_4(vmod_wu, void, env, i32, i32, i32)
|
||||||
DEF_HELPER_4(vmod_du, void, env, i32, i32, i32)
|
DEF_HELPER_4(vmod_du, void, env, i32, i32, i32)
|
||||||
|
|
||||||
|
DEF_HELPER_FLAGS_4(vsat_b, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
|
||||||
|
DEF_HELPER_FLAGS_4(vsat_h, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
|
||||||
|
DEF_HELPER_FLAGS_4(vsat_w, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
|
||||||
|
DEF_HELPER_FLAGS_4(vsat_d, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
|
||||||
|
DEF_HELPER_FLAGS_4(vsat_bu, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
|
||||||
|
DEF_HELPER_FLAGS_4(vsat_hu, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
|
||||||
|
DEF_HELPER_FLAGS_4(vsat_wu, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
|
||||||
|
DEF_HELPER_FLAGS_4(vsat_du, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
|
||||||
|
|
|
@ -2693,3 +2693,104 @@ TRANS(vmod_bu, gen_vvv, gen_helper_vmod_bu)
|
||||||
TRANS(vmod_hu, gen_vvv, gen_helper_vmod_hu)
|
TRANS(vmod_hu, gen_vvv, gen_helper_vmod_hu)
|
||||||
TRANS(vmod_wu, gen_vvv, gen_helper_vmod_wu)
|
TRANS(vmod_wu, gen_vvv, gen_helper_vmod_wu)
|
||||||
TRANS(vmod_du, gen_vvv, gen_helper_vmod_du)
|
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)
|
||||||
|
|
|
@ -499,7 +499,10 @@ dbcl 0000 00000010 10101 ............... @i15
|
||||||
#
|
#
|
||||||
@vv .... ........ ..... ..... vj:5 vd:5 &vv
|
@vv .... ........ ..... ..... vj:5 vd:5 &vv
|
||||||
@vvv .... ........ ..... vk:5 vj:5 vd:5 &vvv
|
@vvv .... ........ ..... vk:5 vj:5 vd:5 &vvv
|
||||||
|
@vv_ui3 .... ........ ..... .. imm:3 vj:5 vd:5 &vv_i
|
||||||
|
@vv_ui4 .... ........ ..... . imm:4 vj:5 vd:5 &vv_i
|
||||||
@vv_ui5 .... ........ ..... imm:5 vj:5 vd:5 &vv_i
|
@vv_ui5 .... ........ ..... imm:5 vj:5 vd:5 &vv_i
|
||||||
|
@vv_ui6 .... ........ .... imm:6 vj:5 vd:5 &vv_i
|
||||||
@vv_i5 .... ........ ..... imm:s5 vj:5 vd:5 &vv_i
|
@vv_i5 .... ........ ..... imm:s5 vj:5 vd:5 &vv_i
|
||||||
|
|
||||||
vadd_b 0111 00000000 10100 ..... ..... ..... @vvv
|
vadd_b 0111 00000000 10100 ..... ..... ..... @vvv
|
||||||
|
@ -757,3 +760,12 @@ vmod_bu 0111 00001110 01100 ..... ..... ..... @vvv
|
||||||
vmod_hu 0111 00001110 01101 ..... ..... ..... @vvv
|
vmod_hu 0111 00001110 01101 ..... ..... ..... @vvv
|
||||||
vmod_wu 0111 00001110 01110 ..... ..... ..... @vvv
|
vmod_wu 0111 00001110 01110 ..... ..... ..... @vvv
|
||||||
vmod_du 0111 00001110 01111 ..... ..... ..... @vvv
|
vmod_du 0111 00001110 01111 ..... ..... ..... @vvv
|
||||||
|
|
||||||
|
vsat_b 0111 00110010 01000 01 ... ..... ..... @vv_ui3
|
||||||
|
vsat_h 0111 00110010 01000 1 .... ..... ..... @vv_ui4
|
||||||
|
vsat_w 0111 00110010 01001 ..... ..... ..... @vv_ui5
|
||||||
|
vsat_d 0111 00110010 0101 ...... ..... ..... @vv_ui6
|
||||||
|
vsat_bu 0111 00110010 10000 01 ... ..... ..... @vv_ui3
|
||||||
|
vsat_hu 0111 00110010 10000 1 .... ..... ..... @vv_ui4
|
||||||
|
vsat_wu 0111 00110010 10001 ..... ..... ..... @vv_ui5
|
||||||
|
vsat_du 0111 00110010 1001 ...... ..... ..... @vv_ui6
|
||||||
|
|
|
@ -590,3 +590,40 @@ VDIV(vmod_bu, 8, UB, DO_REMU)
|
||||||
VDIV(vmod_hu, 16, UH, DO_REMU)
|
VDIV(vmod_hu, 16, UH, DO_REMU)
|
||||||
VDIV(vmod_wu, 32, UW, DO_REMU)
|
VDIV(vmod_wu, 32, UW, DO_REMU)
|
||||||
VDIV(vmod_du, 64, UD, DO_REMU)
|
VDIV(vmod_du, 64, UD, DO_REMU)
|
||||||
|
|
||||||
|
#define VSAT_S(NAME, BIT, E) \
|
||||||
|
void HELPER(NAME)(void *vd, void *vj, uint64_t max, uint32_t v) \
|
||||||
|
{ \
|
||||||
|
int i; \
|
||||||
|
VReg *Vd = (VReg *)vd; \
|
||||||
|
VReg *Vj = (VReg *)vj; \
|
||||||
|
typedef __typeof(Vd->E(0)) TD; \
|
||||||
|
\
|
||||||
|
for (i = 0; i < LSX_LEN/BIT; i++) { \
|
||||||
|
Vd->E(i) = Vj->E(i) > (TD)max ? (TD)max : \
|
||||||
|
Vj->E(i) < (TD)~max ? (TD)~max: Vj->E(i); \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
|
VSAT_S(vsat_b, 8, B)
|
||||||
|
VSAT_S(vsat_h, 16, H)
|
||||||
|
VSAT_S(vsat_w, 32, W)
|
||||||
|
VSAT_S(vsat_d, 64, D)
|
||||||
|
|
||||||
|
#define VSAT_U(NAME, BIT, E) \
|
||||||
|
void HELPER(NAME)(void *vd, void *vj, uint64_t max, uint32_t v) \
|
||||||
|
{ \
|
||||||
|
int i; \
|
||||||
|
VReg *Vd = (VReg *)vd; \
|
||||||
|
VReg *Vj = (VReg *)vj; \
|
||||||
|
typedef __typeof(Vd->E(0)) TD; \
|
||||||
|
\
|
||||||
|
for (i = 0; i < LSX_LEN/BIT; i++) { \
|
||||||
|
Vd->E(i) = Vj->E(i) > (TD)max ? (TD)max : Vj->E(i); \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
|
VSAT_U(vsat_bu, 8, UB)
|
||||||
|
VSAT_U(vsat_hu, 16, UH)
|
||||||
|
VSAT_U(vsat_wu, 32, UW)
|
||||||
|
VSAT_U(vsat_du, 64, UD)
|
||||||
|
|
Loading…
Reference in New Issue