This patch includes: - VSLL[I].{B/H/W/D}; - VSRL[I].{B/H/W/D}; - VSRA[I].{B/H/W/D}; - VROTR[I].{B/H/W/D}.
Signed-off-by: Song Gao <gaos...@loongson.cn> --- target/loongarch/disas.c | 36 ++++ target/loongarch/helper.h | 36 ++++ target/loongarch/insn_trans/trans_lsx.c.inc | 36 ++++ target/loongarch/insns.decode | 36 ++++ target/loongarch/lsx_helper.c | 213 ++++++++++++++++++++ 5 files changed, 357 insertions(+) diff --git a/target/loongarch/disas.c b/target/loongarch/disas.c index 3e8015ac0e..a422c9dfc8 100644 --- a/target/loongarch/disas.c +++ b/target/loongarch/disas.c @@ -1074,3 +1074,39 @@ INSN_LSX(vandi_b, vv_i) INSN_LSX(vori_b, vv_i) INSN_LSX(vxori_b, vv_i) INSN_LSX(vnori_b, vv_i) + +INSN_LSX(vsll_b, vvv) +INSN_LSX(vsll_h, vvv) +INSN_LSX(vsll_w, vvv) +INSN_LSX(vsll_d, vvv) +INSN_LSX(vslli_b, vv_i) +INSN_LSX(vslli_h, vv_i) +INSN_LSX(vslli_w, vv_i) +INSN_LSX(vslli_d, vv_i) + +INSN_LSX(vsrl_b, vvv) +INSN_LSX(vsrl_h, vvv) +INSN_LSX(vsrl_w, vvv) +INSN_LSX(vsrl_d, vvv) +INSN_LSX(vsrli_b, vv_i) +INSN_LSX(vsrli_h, vv_i) +INSN_LSX(vsrli_w, vv_i) +INSN_LSX(vsrli_d, vv_i) + +INSN_LSX(vsra_b, vvv) +INSN_LSX(vsra_h, vvv) +INSN_LSX(vsra_w, vvv) +INSN_LSX(vsra_d, vvv) +INSN_LSX(vsrai_b, vv_i) +INSN_LSX(vsrai_h, vv_i) +INSN_LSX(vsrai_w, vv_i) +INSN_LSX(vsrai_d, vv_i) + +INSN_LSX(vrotr_b, vvv) +INSN_LSX(vrotr_h, vvv) +INSN_LSX(vrotr_w, vvv) +INSN_LSX(vrotr_d, vvv) +INSN_LSX(vrotri_b, vv_i) +INSN_LSX(vrotri_h, vv_i) +INSN_LSX(vrotri_w, vv_i) +INSN_LSX(vrotri_d, vv_i) diff --git a/target/loongarch/helper.h b/target/loongarch/helper.h index 77b576f22f..c7733a7180 100644 --- a/target/loongarch/helper.h +++ b/target/loongarch/helper.h @@ -429,3 +429,39 @@ DEF_HELPER_4(vandi_b, void, env, i32, i32, i32) DEF_HELPER_4(vori_b, void, env, i32, i32, i32) DEF_HELPER_4(vxori_b, void, env, i32, i32, i32) DEF_HELPER_4(vnori_b, void, env, i32, i32, i32) + +DEF_HELPER_4(vsll_b, void, env, i32, i32, i32) +DEF_HELPER_4(vsll_h, void, env, i32, i32, i32) +DEF_HELPER_4(vsll_w, void, env, i32, i32, i32) +DEF_HELPER_4(vsll_d, void, env, i32, i32, i32) +DEF_HELPER_4(vslli_b, void, env, i32, i32, i32) +DEF_HELPER_4(vslli_h, void, env, i32, i32, i32) +DEF_HELPER_4(vslli_w, void, env, i32, i32, i32) +DEF_HELPER_4(vslli_d, void, env, i32, i32, i32) + +DEF_HELPER_4(vsrl_b, void, env, i32, i32, i32) +DEF_HELPER_4(vsrl_h, void, env, i32, i32, i32) +DEF_HELPER_4(vsrl_w, void, env, i32, i32, i32) +DEF_HELPER_4(vsrl_d, void, env, i32, i32, i32) +DEF_HELPER_4(vsrli_b, void, env, i32, i32, i32) +DEF_HELPER_4(vsrli_h, void, env, i32, i32, i32) +DEF_HELPER_4(vsrli_w, void, env, i32, i32, i32) +DEF_HELPER_4(vsrli_d, void, env, i32, i32, i32) + +DEF_HELPER_4(vsra_b, void, env, i32, i32, i32) +DEF_HELPER_4(vsra_h, void, env, i32, i32, i32) +DEF_HELPER_4(vsra_w, void, env, i32, i32, i32) +DEF_HELPER_4(vsra_d, void, env, i32, i32, i32) +DEF_HELPER_4(vsrai_b, void, env, i32, i32, i32) +DEF_HELPER_4(vsrai_h, void, env, i32, i32, i32) +DEF_HELPER_4(vsrai_w, void, env, i32, i32, i32) +DEF_HELPER_4(vsrai_d, void, env, i32, i32, i32) + +DEF_HELPER_4(vrotr_b, void, env, i32, i32, i32) +DEF_HELPER_4(vrotr_h, void, env, i32, i32, i32) +DEF_HELPER_4(vrotr_w, void, env, i32, i32, i32) +DEF_HELPER_4(vrotr_d, void, env, i32, i32, i32) +DEF_HELPER_4(vrotri_b, void, env, i32, i32, i32) +DEF_HELPER_4(vrotri_h, void, env, i32, i32, i32) +DEF_HELPER_4(vrotri_w, void, env, i32, i32, i32) +DEF_HELPER_4(vrotri_d, 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 c12de1d3d4..62aac7713b 100644 --- a/target/loongarch/insn_trans/trans_lsx.c.inc +++ b/target/loongarch/insn_trans/trans_lsx.c.inc @@ -345,3 +345,39 @@ TRANS(vandi_b, gen_vv_i, gen_helper_vandi_b) TRANS(vori_b, gen_vv_i, gen_helper_vori_b) TRANS(vxori_b, gen_vv_i, gen_helper_vxori_b) TRANS(vnori_b, gen_vv_i, gen_helper_vnori_b) + +TRANS(vsll_b, gen_vvv, gen_helper_vsll_b) +TRANS(vsll_h, gen_vvv, gen_helper_vsll_h) +TRANS(vsll_w, gen_vvv, gen_helper_vsll_w) +TRANS(vsll_d, gen_vvv, gen_helper_vsll_d) +TRANS(vslli_b, gen_vv_i, gen_helper_vslli_b) +TRANS(vslli_h, gen_vv_i, gen_helper_vslli_h) +TRANS(vslli_w, gen_vv_i, gen_helper_vslli_w) +TRANS(vslli_d, gen_vv_i, gen_helper_vslli_d) + +TRANS(vsrl_b, gen_vvv, gen_helper_vsrl_b) +TRANS(vsrl_h, gen_vvv, gen_helper_vsrl_h) +TRANS(vsrl_w, gen_vvv, gen_helper_vsrl_w) +TRANS(vsrl_d, gen_vvv, gen_helper_vsrl_d) +TRANS(vsrli_b, gen_vv_i, gen_helper_vsrli_b) +TRANS(vsrli_h, gen_vv_i, gen_helper_vsrli_h) +TRANS(vsrli_w, gen_vv_i, gen_helper_vsrli_w) +TRANS(vsrli_d, gen_vv_i, gen_helper_vsrli_d) + +TRANS(vsra_b, gen_vvv, gen_helper_vsra_b) +TRANS(vsra_h, gen_vvv, gen_helper_vsra_h) +TRANS(vsra_w, gen_vvv, gen_helper_vsra_w) +TRANS(vsra_d, gen_vvv, gen_helper_vsra_d) +TRANS(vsrai_b, gen_vv_i, gen_helper_vsrai_b) +TRANS(vsrai_h, gen_vv_i, gen_helper_vsrai_h) +TRANS(vsrai_w, gen_vv_i, gen_helper_vsrai_w) +TRANS(vsrai_d, gen_vv_i, gen_helper_vsrai_d) + +TRANS(vrotr_b, gen_vvv, gen_helper_vrotr_b) +TRANS(vrotr_h, gen_vvv, gen_helper_vrotr_h) +TRANS(vrotr_w, gen_vvv, gen_helper_vrotr_w) +TRANS(vrotr_d, gen_vvv, gen_helper_vrotr_d) +TRANS(vrotri_b, gen_vv_i, gen_helper_vrotri_b) +TRANS(vrotri_h, gen_vv_i, gen_helper_vrotri_h) +TRANS(vrotri_w, gen_vv_i, gen_helper_vrotri_w) +TRANS(vrotri_d, gen_vv_i, gen_helper_vrotri_d) diff --git a/target/loongarch/insns.decode b/target/loongarch/insns.decode index 03b7f76712..aca3267206 100644 --- a/target/loongarch/insns.decode +++ b/target/loongarch/insns.decode @@ -802,3 +802,39 @@ vandi_b 0111 00111101 00 ........ ..... ..... @vv_ui8 vori_b 0111 00111101 01 ........ ..... ..... @vv_ui8 vxori_b 0111 00111101 10 ........ ..... ..... @vv_ui8 vnori_b 0111 00111101 11 ........ ..... ..... @vv_ui8 + +vsll_b 0111 00001110 10000 ..... ..... ..... @vvv +vsll_h 0111 00001110 10001 ..... ..... ..... @vvv +vsll_w 0111 00001110 10010 ..... ..... ..... @vvv +vsll_d 0111 00001110 10011 ..... ..... ..... @vvv +vslli_b 0111 00110010 11000 01 ... ..... ..... @vv_ui3 +vslli_h 0111 00110010 11000 1 .... ..... ..... @vv_ui4 +vslli_w 0111 00110010 11001 ..... ..... ..... @vv_ui5 +vslli_d 0111 00110010 1101 ...... ..... ..... @vv_ui6 + +vsrl_b 0111 00001110 10100 ..... ..... ..... @vvv +vsrl_h 0111 00001110 10101 ..... ..... ..... @vvv +vsrl_w 0111 00001110 10110 ..... ..... ..... @vvv +vsrl_d 0111 00001110 10111 ..... ..... ..... @vvv +vsrli_b 0111 00110011 00000 01 ... ..... ..... @vv_ui3 +vsrli_h 0111 00110011 00000 1 .... ..... ..... @vv_ui4 +vsrli_w 0111 00110011 00001 ..... ..... ..... @vv_ui5 +vsrli_d 0111 00110011 0001 ...... ..... ..... @vv_ui6 + +vsra_b 0111 00001110 11000 ..... ..... ..... @vvv +vsra_h 0111 00001110 11001 ..... ..... ..... @vvv +vsra_w 0111 00001110 11010 ..... ..... ..... @vvv +vsra_d 0111 00001110 11011 ..... ..... ..... @vvv +vsrai_b 0111 00110011 01000 01 ... ..... ..... @vv_ui3 +vsrai_h 0111 00110011 01000 1 .... ..... ..... @vv_ui4 +vsrai_w 0111 00110011 01001 ..... ..... ..... @vv_ui5 +vsrai_d 0111 00110011 0101 ...... ..... ..... @vv_ui6 + +vrotr_b 0111 00001110 11100 ..... ..... ..... @vvv +vrotr_h 0111 00001110 11101 ..... ..... ..... @vvv +vrotr_w 0111 00001110 11110 ..... ..... ..... @vvv +vrotr_d 0111 00001110 11111 ..... ..... ..... @vvv +vrotri_b 0111 00101010 00000 01 ... ..... ..... @vv_ui3 +vrotri_h 0111 00101010 00000 1 .... ..... ..... @vv_ui4 +vrotri_w 0111 00101010 00001 ..... ..... ..... @vv_ui5 +vrotri_d 0111 00101010 0001 ...... ..... ..... @vv_ui6 diff --git a/target/loongarch/lsx_helper.c b/target/loongarch/lsx_helper.c index c61479bf74..d8282b670e 100644 --- a/target/loongarch/lsx_helper.c +++ b/target/loongarch/lsx_helper.c @@ -1974,3 +1974,216 @@ DO_HELPER_VV_I(vandi_b, 8, helper_vv_i, do_vandi_b) DO_HELPER_VV_I(vori_b, 8, helper_vv_i, do_vori_b) DO_HELPER_VV_I(vxori_b, 8, helper_vv_i, do_vxori_b) DO_HELPER_VV_I(vnori_b, 8, helper_vv_i, do_vnori_b) + +static void do_vsll(vec_t *Vd, vec_t *Vj, vec_t *Vk, int bit, int n) +{ + switch (bit) { + case 8: + Vd->B[n] = Vj->B[n] << ((uint64_t)(Vk->B[n]) % bit); + break; + case 16: + Vd->H[n] = Vj->H[n] << ((uint64_t)(Vk->H[n]) % bit); + break; + case 32: + Vd->W[n] = Vj->W[n] << ((uint64_t)(Vk->W[n]) % bit); + break; + case 64: + Vd->D[n] = Vj->D[n] << ((uint64_t)(Vk->D[n]) % bit); + break; + default: + g_assert_not_reached(); + } +} + +static void do_vslli(vec_t *Vd, vec_t *Vj, uint32_t imm, int bit, int n) +{ + switch (bit) { + case 8: + Vd->B[n] = Vj->B[n] << ((uint64_t)(imm) % bit); + break; + case 16: + Vd->H[n] = Vj->H[n] << ((uint64_t)(imm) % bit); + break; + case 32: + Vd->W[n] = Vj->W[n] << ((uint64_t)(imm) % bit); + break; + case 64: + Vd->D[n] = Vj->D[n] << ((uint64_t)(imm) % bit); + break; + default: + g_assert_not_reached(); + } +} + +DO_HELPER_VVV(vsll_b, 8, helper_vvv, do_vsll) +DO_HELPER_VVV(vsll_h, 16, helper_vvv, do_vsll) +DO_HELPER_VVV(vsll_w, 32, helper_vvv, do_vsll) +DO_HELPER_VVV(vsll_d, 64, helper_vvv, do_vsll) +DO_HELPER_VV_I(vslli_b, 8, helper_vv_i, do_vslli) +DO_HELPER_VV_I(vslli_h, 16, helper_vv_i, do_vslli) +DO_HELPER_VV_I(vslli_w, 32, helper_vv_i, do_vslli) +DO_HELPER_VV_I(vslli_d, 64, helper_vv_i, do_vslli) + +static int64_t vsrl(int64_t s1, int64_t s2, int bit) +{ + uint64_t umax = MAKE_64BIT_MASK(0, bit); + uint64_t u1 = s1 & umax; + + return u1 >> ((uint64_t)(s2) % bit); +} + +static void do_vsrl(vec_t *Vd, vec_t *Vj, vec_t *Vk, int bit, int n) +{ + switch (bit) { + case 8: + Vd->B[n] = vsrl(Vj->B[n], Vk->B[n], bit); + break; + case 16: + Vd->H[n] = vsrl(Vj->H[n], Vk->H[n], bit); + break; + case 32: + Vd->W[n] = vsrl(Vj->W[n], Vk->W[n], bit); + break; + case 64: + Vd->D[n] = vsrl(Vj->D[n], Vk->D[n], bit); + break; + default: + g_assert_not_reached(); + } +} + +static void do_vsrli(vec_t *Vd, vec_t *Vj, uint32_t imm, int bit, int n) +{ + switch (bit) { + case 8: + Vd->B[n] = vsrl(Vj->B[n], imm, bit); + break; + case 16: + Vd->H[n] = vsrl(Vj->H[n], imm, bit); + break; + case 32: + Vd->W[n] = vsrl(Vj->W[n], imm, bit); + break; + case 64: + Vd->D[n] = vsrl(Vj->D[n], imm, bit); + break; + default: + g_assert_not_reached(); + } +} + +DO_HELPER_VVV(vsrl_b, 8, helper_vvv, do_vsrl) +DO_HELPER_VVV(vsrl_h, 16, helper_vvv, do_vsrl) +DO_HELPER_VVV(vsrl_w, 32, helper_vvv, do_vsrl) +DO_HELPER_VVV(vsrl_d, 64, helper_vvv, do_vsrl) +DO_HELPER_VV_I(vsrli_b, 8, helper_vv_i, do_vsrli) +DO_HELPER_VV_I(vsrli_h, 16, helper_vv_i, do_vsrli) +DO_HELPER_VV_I(vsrli_w, 32, helper_vv_i, do_vsrli) +DO_HELPER_VV_I(vsrli_d, 64, helper_vv_i, do_vsrli) + +static void do_vsra(vec_t *Vd, vec_t *Vj, vec_t *Vk, int bit, int n) +{ + switch (bit) { + case 8: + Vd->B[n] = Vj->B[n] >> ((uint64_t)(Vk->B[n]) % bit); + break; + case 16: + Vd->H[n] = Vj->H[n] >> ((uint64_t)(Vk->H[n]) % bit); + break; + case 32: + Vd->W[n] = Vj->W[n] >> ((uint64_t)(Vk->W[n]) % bit); + break; + case 64: + Vd->D[n] = Vj->D[n] >> ((uint64_t)(Vk->D[n]) % bit); + break; + default: + g_assert_not_reached(); + } +} + +static void do_vsrai(vec_t *Vd, vec_t *Vj, uint32_t imm, int bit, int n) +{ + switch (bit) { + case 8: + Vd->B[n] = Vj->B[n] >> ((uint64_t)(imm) % bit); + break; + case 16: + Vd->H[n] = Vj->H[n] >> ((uint64_t)(imm) % bit); + break; + case 32: + Vd->W[n] = Vj->W[n] >> ((uint64_t)(imm) % bit); + break; + case 64: + Vd->D[n] = Vj->D[n] >> ((uint64_t)(imm) % bit); + break; + default: + g_assert_not_reached(); + } +} + +DO_HELPER_VVV(vsra_b, 8, helper_vvv, do_vsra) +DO_HELPER_VVV(vsra_h, 16, helper_vvv, do_vsra) +DO_HELPER_VVV(vsra_w, 32, helper_vvv, do_vsra) +DO_HELPER_VVV(vsra_d, 64, helper_vvv, do_vsra) +DO_HELPER_VV_I(vsrai_b, 8, helper_vv_i, do_vsrai) +DO_HELPER_VV_I(vsrai_h, 16, helper_vv_i, do_vsrai) +DO_HELPER_VV_I(vsrai_w, 32, helper_vv_i, do_vsrai) +DO_HELPER_VV_I(vsrai_d, 64, helper_vv_i, do_vsrai) + +static uint64_t vrotr(int64_t s1, int64_t s2, int bit) +{ + uint64_t umax = MAKE_64BIT_MASK(0, bit); + uint64_t u1 = s1 & umax; + int32_t n = (uint64_t)(s2) % bit; + + return u1 >> n | u1 << (bit - n); +} + +static void do_vrotr(vec_t *Vd, vec_t *Vj, vec_t *Vk, int bit, int n) +{ + switch (bit) { + case 8: + Vd->B[n] = vrotr(Vj->B[n], Vk->B[n], bit); + break; + case 16: + Vd->H[n] = vrotr(Vj->H[n], Vk->H[n], bit); + break; + case 32: + Vd->W[n] = vrotr(Vj->W[n], Vk->W[n], bit); + break; + case 64: + Vd->D[n] = vrotr(Vj->D[n], Vk->D[n], bit); + break; + default: + g_assert_not_reached(); + } +} + +static void do_vrotri(vec_t *Vd, vec_t *Vj, uint32_t imm, int bit, int n) +{ + switch (bit) { + case 8: + Vd->B[n] = vrotr(Vj->B[n], imm, bit); + break; + case 16: + Vd->H[n] = vrotr(Vj->H[n], imm, bit); + break; + case 32: + Vd->W[n] = vrotr(Vj->W[n], imm, bit); + break; + case 64: + Vd->D[n] = vrotr(Vj->D[n], imm, bit); + break; + default: + g_assert_not_reached(); + } +} + +DO_HELPER_VVV(vrotr_b, 8, helper_vvv, do_vrotr) +DO_HELPER_VVV(vrotr_h, 16, helper_vvv, do_vrotr) +DO_HELPER_VVV(vrotr_w, 32, helper_vvv, do_vrotr) +DO_HELPER_VVV(vrotr_d, 64, helper_vvv, do_vrotr) +DO_HELPER_VV_I(vrotri_b, 8, helper_vv_i, do_vrotri) +DO_HELPER_VV_I(vrotri_h, 16, helper_vv_i, do_vrotri) +DO_HELPER_VV_I(vrotri_w, 32, helper_vv_i, do_vrotri) +DO_HELPER_VV_I(vrotri_d, 64, helper_vv_i, do_vrotri) -- 2.31.1