From: Matheus Ferst <matheus.fe...@eldorado.org.br> Signed-off-by: Matheus Ferst <matheus.fe...@eldorado.org.br> --- target/ppc/insn32.decode | 8 +++ target/ppc/translate/vmx-impl.c.inc | 78 +++++++++++++++++++++++++++++ 2 files changed, 86 insertions(+)
diff --git a/target/ppc/insn32.decode b/target/ppc/insn32.decode index 4666c06f55..257b11113d 100644 --- a/target/ppc/insn32.decode +++ b/target/ppc/insn32.decode @@ -38,6 +38,9 @@ %dx_d 6:s10 16:5 0:1 @DX ...... rt:5 ..... .......... ..... . &DX d=%dx_d +&VN vrt vra vrb sh +@VN ...... vrt:5 vra:5 vrb:5 .. sh:3 ...... &VN + &VX vrt vra vrb @VX ...... vrt:5 vra:5 vrb:5 .......... . &VX @@ -338,3 +341,8 @@ VCLZDM 000100 ..... ..... ..... 11110000100 @VX VCTZDM 000100 ..... ..... ..... 11111000100 @VX VPDEPD 000100 ..... ..... ..... 10111001101 @VX VPEXTD 000100 ..... ..... ..... 10110001101 @VX + +## Vector Permute and Formatting Instruction + +VSLDBI 000100 ..... ..... ..... 00 ... 010110 @VN +VSRDBI 000100 ..... ..... ..... 01 ... 010110 @VN diff --git a/target/ppc/translate/vmx-impl.c.inc b/target/ppc/translate/vmx-impl.c.inc index b240fd5fc6..e19793f295 100644 --- a/target/ppc/translate/vmx-impl.c.inc +++ b/target/ppc/translate/vmx-impl.c.inc @@ -1257,6 +1257,84 @@ static void gen_vsldoi(DisasContext *ctx) tcg_temp_free_i32(sh); } +static bool trans_VSLDBI(DisasContext *ctx, arg_VN *a) +{ + TCGv_i64 t0, t1, t2; + + REQUIRE_INSNS_FLAGS2(ctx, ISA310); + REQUIRE_VECTOR(ctx); + + t0 = tcg_temp_new_i64(); + t1 = tcg_temp_new_i64(); + + get_avr64(t0, a->vra, true); + get_avr64(t1, a->vra, false); + + if (a->sh != 0) { + t2 = tcg_temp_new_i64(); + + /* vrt.h = (vra.h << sh) | (vra.l >> (64 - sh)) */ + tcg_gen_shli_i64(t0, t0, a->sh); + tcg_gen_shri_i64(t2, t1, 64 - a->sh); + tcg_gen_or_i64(t0, t0, t2); + + /* vrt.l = (vra.l << sh) | (vrb.h >> (64 - sh)) */ + get_avr64(t2, a->vrb, true); + tcg_gen_shli_i64(t1, t1, a->sh); + tcg_gen_shri_i64(t2, t2, 64 - a->sh); + tcg_gen_or_i64(t1, t1, t2); + + tcg_temp_free_i64(t2); + } + + set_avr64(a->vrt, t0, true); + set_avr64(a->vrt, t1, false); + + tcg_temp_free_i64(t0); + tcg_temp_free_i64(t1); + + return true; +} + +static bool trans_VSRDBI(DisasContext *ctx, arg_VN *a) +{ + TCGv_i64 t2, t1, t0; + + REQUIRE_INSNS_FLAGS2(ctx, ISA310); + REQUIRE_VECTOR(ctx); + + t0 = tcg_temp_new_i64(); + t1 = tcg_temp_new_i64(); + + get_avr64(t0, a->vrb, false); + get_avr64(t1, a->vrb, true); + + if (a->sh != 0) { + t2 = tcg_temp_new_i64(); + + /* vrt.l = (vrb.l >> sh) | (vrb.h << (64 - sh)) */ + tcg_gen_shri_i64(t0, t0, a->sh); + tcg_gen_shli_i64(t2, t1, 64 - a->sh); + tcg_gen_or_i64(t0, t0, t2); + + /* vrt.h = (vrb.h >> sh) | (vra.l << (64 - sh)) */ + get_avr64(t2, a->vra, false); + tcg_gen_shri_i64(t1, t1, a->sh); + tcg_gen_shli_i64(t2, t2, 64 - a->sh); + tcg_gen_or_i64(t1, t1, t2); + + tcg_temp_free_i64(t2); + } + + set_avr64(a->vrt, t0, false); + set_avr64(a->vrt, t1, true); + + tcg_temp_free_i64(t0); + tcg_temp_free_i64(t1); + + return true; +} + #define GEN_VAFORM_PAIRED(name0, name1, opc2) \ static void glue(gen_, name0##_##name1)(DisasContext *ctx) \ { \ -- 2.25.1