diff options
Diffstat (limited to 'target')
-rw-r--r-- | target/loongarch/disas.c | 9 | ||||
-rw-r--r-- | target/loongarch/helper.h | 9 | ||||
-rw-r--r-- | target/loongarch/insn_trans/trans_lsx.c.inc | 20 | ||||
-rw-r--r-- | target/loongarch/insns.decode | 9 | ||||
-rw-r--r-- | target/loongarch/lsx_helper.c | 35 |
5 files changed, 82 insertions, 0 deletions
diff --git a/target/loongarch/disas.c b/target/loongarch/disas.c index b04aefe..412c1ce 100644 --- a/target/loongarch/disas.c +++ b/target/loongarch/disas.c @@ -1070,3 +1070,12 @@ INSN_LSX(vsat_bu, vv_i) INSN_LSX(vsat_hu, vv_i) INSN_LSX(vsat_wu, vv_i) INSN_LSX(vsat_du, vv_i) + +INSN_LSX(vexth_h_b, vv) +INSN_LSX(vexth_w_h, vv) +INSN_LSX(vexth_d_w, vv) +INSN_LSX(vexth_q_d, vv) +INSN_LSX(vexth_hu_bu, vv) +INSN_LSX(vexth_wu_hu, vv) +INSN_LSX(vexth_du_wu, vv) +INSN_LSX(vexth_qu_du, vv) diff --git a/target/loongarch/helper.h b/target/loongarch/helper.h index d2b1c9f..005988b 100644 --- a/target/loongarch/helper.h +++ b/target/loongarch/helper.h @@ -329,3 +329,12 @@ 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) + +DEF_HELPER_3(vexth_h_b, void, env, i32, i32) +DEF_HELPER_3(vexth_w_h, void, env, i32, i32) +DEF_HELPER_3(vexth_d_w, void, env, i32, i32) +DEF_HELPER_3(vexth_q_d, void, env, i32, i32) +DEF_HELPER_3(vexth_hu_bu, void, env, i32, i32) +DEF_HELPER_3(vexth_wu_hu, void, env, i32, i32) +DEF_HELPER_3(vexth_du_wu, void, env, i32, i32) +DEF_HELPER_3(vexth_qu_du, void, env, i32, i32) diff --git a/target/loongarch/insn_trans/trans_lsx.c.inc b/target/loongarch/insn_trans/trans_lsx.c.inc index b8f05c6..93ae76b 100644 --- a/target/loongarch/insn_trans/trans_lsx.c.inc +++ b/target/loongarch/insn_trans/trans_lsx.c.inc @@ -28,6 +28,17 @@ static bool gen_vvv(DisasContext *ctx, arg_vvv *a, return true; } +static bool gen_vv(DisasContext *ctx, arg_vv *a, + void (*func)(TCGv_ptr, TCGv_i32, TCGv_i32)) +{ + TCGv_i32 vd = tcg_constant_i32(a->vd); + TCGv_i32 vj = tcg_constant_i32(a->vj); + + CHECK_SXE; + func(cpu_env, vd, vj); + return true; +} + static bool gvec_vvv(DisasContext *ctx, arg_vvv *a, MemOp mop, void (*func)(unsigned, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t)) @@ -2794,3 +2805,12 @@ 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) + +TRANS(vexth_h_b, gen_vv, gen_helper_vexth_h_b) +TRANS(vexth_w_h, gen_vv, gen_helper_vexth_w_h) +TRANS(vexth_d_w, gen_vv, gen_helper_vexth_d_w) +TRANS(vexth_q_d, gen_vv, gen_helper_vexth_q_d) +TRANS(vexth_hu_bu, gen_vv, gen_helper_vexth_hu_bu) +TRANS(vexth_wu_hu, gen_vv, gen_helper_vexth_wu_hu) +TRANS(vexth_du_wu, gen_vv, gen_helper_vexth_du_wu) +TRANS(vexth_qu_du, gen_vv, gen_helper_vexth_qu_du) diff --git a/target/loongarch/insns.decode b/target/loongarch/insns.decode index 3ed61b3..39c582d 100644 --- a/target/loongarch/insns.decode +++ b/target/loongarch/insns.decode @@ -769,3 +769,12 @@ 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 + +vexth_h_b 0111 00101001 11101 11000 ..... ..... @vv +vexth_w_h 0111 00101001 11101 11001 ..... ..... @vv +vexth_d_w 0111 00101001 11101 11010 ..... ..... @vv +vexth_q_d 0111 00101001 11101 11011 ..... ..... @vv +vexth_hu_bu 0111 00101001 11101 11100 ..... ..... @vv +vexth_wu_hu 0111 00101001 11101 11101 ..... ..... @vv +vexth_du_wu 0111 00101001 11101 11110 ..... ..... @vv +vexth_qu_du 0111 00101001 11101 11111 ..... ..... @vv diff --git a/target/loongarch/lsx_helper.c b/target/loongarch/lsx_helper.c index 9ba16ac..b4582a4 100644 --- a/target/loongarch/lsx_helper.c +++ b/target/loongarch/lsx_helper.c @@ -627,3 +627,38 @@ VSAT_U(vsat_bu, 8, UB) VSAT_U(vsat_hu, 16, UH) VSAT_U(vsat_wu, 32, UW) VSAT_U(vsat_du, 64, UD) + +#define VEXTH(NAME, BIT, E1, E2) \ +void HELPER(NAME)(CPULoongArchState *env, uint32_t vd, uint32_t vj) \ +{ \ + int i; \ + VReg *Vd = &(env->fpr[vd].vreg); \ + VReg *Vj = &(env->fpr[vj].vreg); \ + \ + for (i = 0; i < LSX_LEN/BIT; i++) { \ + Vd->E1(i) = Vj->E2(i + LSX_LEN/BIT); \ + } \ +} + +void HELPER(vexth_q_d)(CPULoongArchState *env, uint32_t vd, uint32_t vj) +{ + VReg *Vd = &(env->fpr[vd].vreg); + VReg *Vj = &(env->fpr[vj].vreg); + + Vd->Q(0) = int128_makes64(Vj->D(1)); +} + +void HELPER(vexth_qu_du)(CPULoongArchState *env, uint32_t vd, uint32_t vj) +{ + VReg *Vd = &(env->fpr[vd].vreg); + VReg *Vj = &(env->fpr[vj].vreg); + + Vd->Q(0) = int128_make64((uint64_t)Vj->D(1)); +} + +VEXTH(vexth_h_b, 16, H, B) +VEXTH(vexth_w_h, 32, W, H) +VEXTH(vexth_d_w, 64, D, W) +VEXTH(vexth_hu_bu, 16, UH, UB) +VEXTH(vexth_wu_hu, 32, UW, UH) +VEXTH(vexth_du_wu, 64, UD, UW) |