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_wu, 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_wu, 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_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)
|
||||
|
@ -499,7 +499,10 @@ dbcl 0000 00000010 10101 ............... @i15
|
||||
#
|
||||
@vv .... ........ ..... ..... vj:5 vd:5 &vv
|
||||
@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_ui6 .... ........ .... imm:6 vj:5 vd:5 &vv_i
|
||||
@vv_i5 .... ........ ..... imm:s5 vj:5 vd:5 &vv_i
|
||||
|
||||
vadd_b 0111 00000000 10100 ..... ..... ..... @vvv
|
||||
@ -757,3 +760,12 @@ vmod_bu 0111 00001110 01100 ..... ..... ..... @vvv
|
||||
vmod_hu 0111 00001110 01101 ..... ..... ..... @vvv
|
||||
vmod_wu 0111 00001110 01110 ..... ..... ..... @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_wu, 32, UW, 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…
x
Reference in New Issue
Block a user