This patch includes: - VMAX[I].{B/H/W/D}[U]; - VMIN[I].{B/H/W/D}[U]. Signed-off-by: Song Gao <gaos...@loongson.cn> --- target/loongarch/disas.c | 33 +++ target/loongarch/helper.h | 34 +++ target/loongarch/insn_trans/trans_lsx.c.inc | 33 +++ target/loongarch/insns.decode | 35 ++++ target/loongarch/lsx_helper.c | 219 ++++++++++++++++++++ 5 files changed, 354 insertions(+)
diff --git a/target/loongarch/disas.c b/target/loongarch/disas.c index ff5d9e0e5b..2e86c48f4d 100644 --- a/target/loongarch/disas.c +++ b/target/loongarch/disas.c @@ -910,3 +910,36 @@ INSN_LSX(vadda_b, vvv) INSN_LSX(vadda_h, vvv) INSN_LSX(vadda_w, vvv) INSN_LSX(vadda_d, vvv) + +INSN_LSX(vmax_b, vvv) +INSN_LSX(vmax_h, vvv) +INSN_LSX(vmax_w, vvv) +INSN_LSX(vmax_d, vvv) +INSN_LSX(vmin_b, vvv) +INSN_LSX(vmin_h, vvv) +INSN_LSX(vmin_w, vvv) +INSN_LSX(vmin_d, vvv) +INSN_LSX(vmax_bu, vvv) +INSN_LSX(vmax_hu, vvv) +INSN_LSX(vmax_wu, vvv) +INSN_LSX(vmax_du, vvv) +INSN_LSX(vmin_bu, vvv) +INSN_LSX(vmin_hu, vvv) +INSN_LSX(vmin_wu, vvv) +INSN_LSX(vmin_du, vvv) +INSN_LSX(vmaxi_b, vv_i) +INSN_LSX(vmaxi_h, vv_i) +INSN_LSX(vmaxi_w, vv_i) +INSN_LSX(vmaxi_d, vv_i) +INSN_LSX(vmini_b, vv_i) +INSN_LSX(vmini_h, vv_i) +INSN_LSX(vmini_w, vv_i) +INSN_LSX(vmini_d, vv_i) +INSN_LSX(vmaxi_bu, vv_i) +INSN_LSX(vmaxi_hu, vv_i) +INSN_LSX(vmaxi_wu, vv_i) +INSN_LSX(vmaxi_du, vv_i) +INSN_LSX(vmini_bu, vv_i) +INSN_LSX(vmini_hu, vv_i) +INSN_LSX(vmini_wu, vv_i) +INSN_LSX(vmini_du, vv_i) diff --git a/target/loongarch/helper.h b/target/loongarch/helper.h index 85321c8874..04afc93dc1 100644 --- a/target/loongarch/helper.h +++ b/target/loongarch/helper.h @@ -264,3 +264,37 @@ DEF_HELPER_4(vadda_b, void, env, i32, i32, i32) DEF_HELPER_4(vadda_h, void, env, i32, i32, i32) DEF_HELPER_4(vadda_w, void, env, i32, i32, i32) DEF_HELPER_4(vadda_d, void, env, i32, i32, i32) + +DEF_HELPER_4(vmax_b, void, env, i32, i32, i32) +DEF_HELPER_4(vmax_h, void, env, i32, i32, i32) +DEF_HELPER_4(vmax_w, void, env, i32, i32, i32) +DEF_HELPER_4(vmax_d, void, env, i32, i32, i32) +DEF_HELPER_4(vmaxi_b, void, env, i32, i32, i32) +DEF_HELPER_4(vmaxi_h, void, env, i32, i32, i32) +DEF_HELPER_4(vmaxi_w, void, env, i32, i32, i32) +DEF_HELPER_4(vmaxi_d, void, env, i32, i32, i32) +DEF_HELPER_4(vmax_bu, void, env, i32, i32, i32) +DEF_HELPER_4(vmax_hu, void, env, i32, i32, i32) +DEF_HELPER_4(vmax_wu, void, env, i32, i32, i32) +DEF_HELPER_4(vmax_du, void, env, i32, i32, i32) +DEF_HELPER_4(vmaxi_bu, void, env, i32, i32, i32) +DEF_HELPER_4(vmaxi_hu, void, env, i32, i32, i32) +DEF_HELPER_4(vmaxi_wu, void, env, i32, i32, i32) +DEF_HELPER_4(vmaxi_du, void, env, i32, i32, i32) + +DEF_HELPER_4(vmin_b, void, env, i32, i32, i32) +DEF_HELPER_4(vmin_h, void, env, i32, i32, i32) +DEF_HELPER_4(vmin_w, void, env, i32, i32, i32) +DEF_HELPER_4(vmin_d, void, env, i32, i32, i32) +DEF_HELPER_4(vmini_b, void, env, i32, i32, i32) +DEF_HELPER_4(vmini_h, void, env, i32, i32, i32) +DEF_HELPER_4(vmini_w, void, env, i32, i32, i32) +DEF_HELPER_4(vmini_d, void, env, i32, i32, i32) +DEF_HELPER_4(vmin_bu, void, env, i32, i32, i32) +DEF_HELPER_4(vmin_hu, void, env, i32, i32 ,i32) +DEF_HELPER_4(vmin_wu, void, env, i32, i32, i32) +DEF_HELPER_4(vmin_du, void, env, i32, i32, i32) +DEF_HELPER_4(vmini_bu, void, env, i32, i32, i32) +DEF_HELPER_4(vmini_hu, void, env, i32, i32, i32) +DEF_HELPER_4(vmini_wu, void, env, i32, i32, i32) +DEF_HELPER_4(vmini_du, void, env, i32, i32, i32) diff --git a/target/loongarch/insn_trans/trans_lsx.c.inc b/target/loongarch/insn_trans/trans_lsx.c.inc index a90fc44ba7..8bece985f1 100644 --- a/target/loongarch/insn_trans/trans_lsx.c.inc +++ b/target/loongarch/insn_trans/trans_lsx.c.inc @@ -182,3 +182,36 @@ TRANS(vadda_b, gen_vvv, gen_helper_vadda_b) TRANS(vadda_h, gen_vvv, gen_helper_vadda_h) TRANS(vadda_w, gen_vvv, gen_helper_vadda_w) TRANS(vadda_d, gen_vvv, gen_helper_vadda_d) + +TRANS(vmax_b, gen_vvv, gen_helper_vmax_b) +TRANS(vmax_h, gen_vvv, gen_helper_vmax_h) +TRANS(vmax_w, gen_vvv, gen_helper_vmax_w) +TRANS(vmax_d, gen_vvv, gen_helper_vmax_d) +TRANS(vmaxi_b, gen_vv_i, gen_helper_vmaxi_b) +TRANS(vmaxi_h, gen_vv_i, gen_helper_vmaxi_h) +TRANS(vmaxi_w, gen_vv_i, gen_helper_vmaxi_w) +TRANS(vmaxi_d, gen_vv_i, gen_helper_vmaxi_d) +TRANS(vmax_bu, gen_vvv, gen_helper_vmax_bu) +TRANS(vmax_hu, gen_vvv, gen_helper_vmax_hu) +TRANS(vmax_wu, gen_vvv, gen_helper_vmax_wu) +TRANS(vmax_du, gen_vvv, gen_helper_vmax_du) +TRANS(vmaxi_bu, gen_vv_i, gen_helper_vmaxi_bu) +TRANS(vmaxi_hu, gen_vv_i, gen_helper_vmaxi_hu) +TRANS(vmaxi_wu, gen_vv_i, gen_helper_vmaxi_wu) +TRANS(vmaxi_du, gen_vv_i, gen_helper_vmaxi_du) +TRANS(vmin_b, gen_vvv, gen_helper_vmin_b) +TRANS(vmin_h, gen_vvv, gen_helper_vmin_h) +TRANS(vmin_w, gen_vvv, gen_helper_vmin_w) +TRANS(vmin_d, gen_vvv, gen_helper_vmin_d) +TRANS(vmini_b, gen_vv_i, gen_helper_vmini_b) +TRANS(vmini_h, gen_vv_i, gen_helper_vmini_h) +TRANS(vmini_w, gen_vv_i, gen_helper_vmini_w) +TRANS(vmini_d, gen_vv_i, gen_helper_vmini_d) +TRANS(vmin_bu, gen_vvv, gen_helper_vmin_bu) +TRANS(vmin_hu, gen_vvv, gen_helper_vmin_hu) +TRANS(vmin_wu, gen_vvv, gen_helper_vmin_wu) +TRANS(vmin_du, gen_vvv, gen_helper_vmin_du) +TRANS(vmini_bu, gen_vv_i, gen_helper_vmini_bu) +TRANS(vmini_hu, gen_vv_i, gen_helper_vmini_hu) +TRANS(vmini_wu, gen_vv_i, gen_helper_vmini_wu) +TRANS(vmini_du, gen_vv_i, gen_helper_vmini_du) diff --git a/target/loongarch/insns.decode b/target/loongarch/insns.decode index 9529ffe970..c5d8859db2 100644 --- a/target/loongarch/insns.decode +++ b/target/loongarch/insns.decode @@ -499,6 +499,7 @@ dbcl 0000 00000010 10101 ............... @i15 @vv .... ........ ..... ..... vj:5 vd:5 &vv @vvv .... ........ ..... vk:5 vj:5 vd:5 &vvv @vv_ui5 .... ........ ..... imm:5 vj:5 vd:5 &vv_i +@vv_i5 .... ........ ..... imm:s5 vj:5 vd:5 &vv_i vadd_b 0111 00000000 10100 ..... ..... ..... @vvv vadd_h 0111 00000000 10101 ..... ..... ..... @vvv @@ -632,3 +633,37 @@ vadda_b 0111 00000101 11000 ..... ..... ..... @vvv vadda_h 0111 00000101 11001 ..... ..... ..... @vvv vadda_w 0111 00000101 11010 ..... ..... ..... @vvv vadda_d 0111 00000101 11011 ..... ..... ..... @vvv + +vmax_b 0111 00000111 00000 ..... ..... ..... @vvv +vmax_h 0111 00000111 00001 ..... ..... ..... @vvv +vmax_w 0111 00000111 00010 ..... ..... ..... @vvv +vmax_d 0111 00000111 00011 ..... ..... ..... @vvv +vmaxi_b 0111 00101001 00000 ..... ..... ..... @vv_i5 +vmaxi_h 0111 00101001 00001 ..... ..... ..... @vv_i5 +vmaxi_w 0111 00101001 00010 ..... ..... ..... @vv_i5 +vmaxi_d 0111 00101001 00011 ..... ..... ..... @vv_i5 +vmax_bu 0111 00000111 01000 ..... ..... ..... @vvv +vmax_hu 0111 00000111 01001 ..... ..... ..... @vvv +vmax_wu 0111 00000111 01010 ..... ..... ..... @vvv +vmax_du 0111 00000111 01011 ..... ..... ..... @vvv +vmaxi_bu 0111 00101001 01000 ..... ..... ..... @vv_ui5 +vmaxi_hu 0111 00101001 01001 ..... ..... ..... @vv_ui5 +vmaxi_wu 0111 00101001 01010 ..... ..... ..... @vv_ui5 +vmaxi_du 0111 00101001 01011 ..... ..... ..... @vv_ui5 + +vmin_b 0111 00000111 00100 ..... ..... ..... @vvv +vmin_h 0111 00000111 00101 ..... ..... ..... @vvv +vmin_w 0111 00000111 00110 ..... ..... ..... @vvv +vmin_d 0111 00000111 00111 ..... ..... ..... @vvv +vmini_b 0111 00101001 00100 ..... ..... ..... @vv_i5 +vmini_h 0111 00101001 00101 ..... ..... ..... @vv_i5 +vmini_w 0111 00101001 00110 ..... ..... ..... @vv_i5 +vmini_d 0111 00101001 00111 ..... ..... ..... @vv_i5 +vmin_bu 0111 00000111 01100 ..... ..... ..... @vvv +vmin_hu 0111 00000111 01101 ..... ..... ..... @vvv +vmin_wu 0111 00000111 01110 ..... ..... ..... @vvv +vmin_du 0111 00000111 01111 ..... ..... ..... @vvv +vmini_bu 0111 00101001 01100 ..... ..... ..... @vv_ui5 +vmini_hu 0111 00101001 01101 ..... ..... ..... @vv_ui5 +vmini_wu 0111 00101001 01110 ..... ..... ..... @vv_ui5 +vmini_du 0111 00101001 01111 ..... ..... ..... @vv_ui5 diff --git a/target/loongarch/lsx_helper.c b/target/loongarch/lsx_helper.c index a9a0b01fd7..5bccb3111b 100644 --- a/target/loongarch/lsx_helper.c +++ b/target/loongarch/lsx_helper.c @@ -936,3 +936,222 @@ DO_HELPER_VVV(vadda_b, 8, helper_vvv, do_vadda_s) DO_HELPER_VVV(vadda_h, 16, helper_vvv, do_vadda_s) DO_HELPER_VVV(vadda_w, 32, helper_vvv, do_vadda_s) DO_HELPER_VVV(vadda_d, 64, helper_vvv, do_vadda_s) + +static int64_t vmax_s(int64_t s1, int64_t s2) +{ + return s1 > s2 ? s1 : s2; +} + +static void do_vmax_s(vec_t *Vd, vec_t *Vj, vec_t *Vk, int bit, int n) +{ + switch (bit) { + case 8: + Vd->B[n] = vmax_s(Vj->B[n], Vk->B[n]); + break; + case 16: + Vd->H[n] = vmax_s(Vj->H[n], Vk->H[n]); + break; + case 32: + Vd->W[n] = vmax_s(Vj->W[n], Vk->W[n]); + break; + case 64: + Vd->D[n] = vmax_s(Vj->D[n], Vk->D[n]); + break; + default: + g_assert_not_reached(); + } +} + +static void do_vmaxi_s(vec_t *Vd, vec_t *Vj, uint32_t imm, int bit , int n) +{ + switch (bit) { + case 8: + Vd->B[n] = vmax_s(Vj->B[n], imm); + break; + case 16: + Vd->H[n] = vmax_s(Vj->H[n], imm); + break; + case 32: + Vd->W[n] = vmax_s(Vj->W[n], imm); + break; + case 64: + Vd->D[n] = vmax_s(Vj->D[n], imm); + break; + default: + g_assert_not_reached(); + } +} + +static uint64_t vmax_u(int64_t s1, int64_t s2, int bit) +{ + uint64_t umax = MAKE_64BIT_MASK(0, bit); + uint64_t u1 = s1 & umax; + uint64_t u2 = s2 & umax; + return u1 > u2 ? u1 : u2; +} + +static void do_vmax_u(vec_t *Vd, vec_t *Vj, vec_t *Vk, int bit, int n) +{ + switch (bit) { + case 8: + Vd->B[n] = vmax_u(Vj->B[n], Vk->B[n], bit); + break; + case 16: + Vd->H[n] = vmax_u(Vj->H[n], Vk->H[n], bit); + break; + case 32: + Vd->W[n] = vmax_u(Vj->W[n], Vk->W[n], bit); + break; + case 64: + Vd->D[n] = vmax_u(Vj->D[n], Vk->D[n], bit); + break; + default: + g_assert_not_reached(); + } +} + +static void do_vmaxi_u(vec_t *Vd, vec_t *Vj, uint32_t imm , int bit, int n) +{ + switch (bit) { + case 8: + Vd->B[n] = vmax_u(Vj->B[n], imm, bit); + break; + case 16: + Vd->H[n] = vmax_u(Vj->H[n], imm, bit); + break; + case 32: + Vd->W[n] = vmax_u(Vj->W[n], imm, bit); + break; + case 64: + Vd->D[n] = vmax_u(Vj->D[n], imm, bit); + break; + default: + g_assert_not_reached(); + } +} + +static int64_t vmin_s(int64_t s1, int64_t s2) +{ + return s1 < s2 ? s1 : s2; +} + +static void do_vmin_s(vec_t *Vd, vec_t *Vj, vec_t *Vk, int bit, int n) +{ + switch (bit) { + case 8: + Vd->B[n] = vmin_s(Vj->B[n], Vk->B[n]); + break; + case 16: + Vd->H[n] = vmin_s(Vj->H[n], Vk->H[n]); + break; + case 32: + Vd->W[n] = vmin_s(Vj->W[n], Vk->W[n]); + break; + case 64: + Vd->D[n] = vmin_s(Vj->D[n], Vk->D[n]); + break; + default: + g_assert_not_reached(); + } +} + +static void do_vmini_s(vec_t *Vd, vec_t *Vj, uint32_t imm, int bit, int n) +{ + switch (bit) { + case 8: + Vd->B[n] = vmin_s(Vj->B[n], imm); + break; + case 16: + Vd->H[n] = vmin_s(Vj->H[n], imm); + break; + case 32: + Vd->W[n] = vmin_s(Vj->W[n], imm); + break; + case 64: + Vd->D[n] = vmin_s(Vj->D[n], imm); + break; + default: + g_assert_not_reached(); + } +} + +static uint64_t vmin_u(int64_t s1, int64_t s2, int bit) +{ + uint64_t umax = MAKE_64BIT_MASK(0, bit); + uint64_t u1 = s1 & umax; + uint64_t u2 = s2 & umax; + return u1 < u2 ? u1 : u2; +} + +static void do_vmin_u(vec_t *Vd, vec_t *Vj, vec_t *Vk, int bit, int n) +{ + switch (bit) { + case 8: + Vd->B[n] = vmin_u(Vj->B[n], Vk->B[n], bit); + break; + case 16: + Vd->H[n] = vmin_u(Vj->H[n], Vk->H[n], bit); + break; + case 32: + Vd->W[n] = vmin_u(Vj->W[n], Vk->W[n], bit); + break; + case 64: + Vd->D[n] = vmin_u(Vj->D[n], Vk->D[n], bit); + break; + default: + g_assert_not_reached(); + } +} + +static void do_vmini_u(vec_t *Vd, vec_t *Vj, uint32_t imm, int bit, int n) +{ + switch (bit) { + case 8: + Vd->B[n] = vmin_u(Vj->B[n], imm, bit); + break; + case 16: + Vd->H[n] = vmin_u(Vj->H[n], imm, bit); + break; + case 32: + Vd->W[n] = vmin_u(Vj->W[n], imm, bit); + break; + case 64: + Vd->D[n] = vmin_u(Vj->D[n], imm, bit); + break; + default: + g_assert_not_reached(); + } +} + +DO_HELPER_VVV(vmax_b, 8, helper_vvv, do_vmax_s) +DO_HELPER_VVV(vmax_h, 16, helper_vvv, do_vmax_s) +DO_HELPER_VVV(vmax_w, 32, helper_vvv, do_vmax_s) +DO_HELPER_VVV(vmax_d, 64, helper_vvv, do_vmax_s) +DO_HELPER_VV_I(vmaxi_b, 8, helper_vv_i, do_vmaxi_s) +DO_HELPER_VV_I(vmaxi_h, 16, helper_vv_i, do_vmaxi_s) +DO_HELPER_VV_I(vmaxi_w, 32, helper_vv_i, do_vmaxi_s) +DO_HELPER_VV_I(vmaxi_d, 64, helper_vv_i, do_vmaxi_s) +DO_HELPER_VVV(vmax_bu, 8, helper_vvv, do_vmax_u) +DO_HELPER_VVV(vmax_hu, 16, helper_vvv, do_vmax_u) +DO_HELPER_VVV(vmax_wu, 32, helper_vvv, do_vmax_u) +DO_HELPER_VVV(vmax_du, 64, helper_vvv, do_vmax_u) +DO_HELPER_VV_I(vmaxi_bu, 8, helper_vv_i, do_vmaxi_u) +DO_HELPER_VV_I(vmaxi_hu, 16, helper_vv_i, do_vmaxi_u) +DO_HELPER_VV_I(vmaxi_wu, 32, helper_vv_i, do_vmaxi_u) +DO_HELPER_VV_I(vmaxi_du, 64, helper_vv_i, do_vmaxi_u) +DO_HELPER_VVV(vmin_b, 8, helper_vvv, do_vmin_s) +DO_HELPER_VVV(vmin_h, 16, helper_vvv, do_vmin_s) +DO_HELPER_VVV(vmin_w, 32, helper_vvv, do_vmin_s) +DO_HELPER_VVV(vmin_d, 64, helper_vvv, do_vmin_s) +DO_HELPER_VV_I(vmini_b, 8, helper_vv_i, do_vmini_s) +DO_HELPER_VV_I(vmini_h, 16, helper_vv_i, do_vmini_s) +DO_HELPER_VV_I(vmini_w, 32, helper_vv_i, do_vmini_s) +DO_HELPER_VV_I(vmini_d, 64, helper_vv_i, do_vmini_s) +DO_HELPER_VVV(vmin_bu, 8, helper_vvv, do_vmin_u) +DO_HELPER_VVV(vmin_hu, 16, helper_vvv, do_vmin_u) +DO_HELPER_VVV(vmin_wu, 32, helper_vvv, do_vmin_u) +DO_HELPER_VVV(vmin_du, 64, helper_vvv, do_vmin_u) +DO_HELPER_VV_I(vmini_bu, 8, helper_vv_i, do_vmini_u) +DO_HELPER_VV_I(vmini_hu, 16, helper_vv_i, do_vmini_u) +DO_HELPER_VV_I(vmini_wu, 32, helper_vv_i, do_vmini_u) +DO_HELPER_VV_I(vmini_du, 64, helper_vv_i, do_vmini_u) -- 2.31.1