From: "Lucas Mateus Castro (alqotel)" <lucas.ara...@eldorado.org.br>
Implement the following PowerISA v3.1 instructions: vdivsq: Vector Divide Signed Quadword vdivuq: Vector Divide Unsigned Quadword Signed-off-by: Lucas Mateus Castro (alqotel) <lucas.ara...@eldorado.org.br> --- target/ppc/helper.h | 2 ++ target/ppc/insn32.decode | 2 ++ target/ppc/int_helper.c | 21 +++++++++++++++++++++ target/ppc/translate/vmx-impl.c.inc | 2 ++ 4 files changed, 27 insertions(+) diff --git a/target/ppc/helper.h b/target/ppc/helper.h index 57da11c77e..4cfdf7b3ec 100644 --- a/target/ppc/helper.h +++ b/target/ppc/helper.h @@ -171,6 +171,8 @@ DEF_HELPER_FLAGS_3(VMULOSW, TCG_CALL_NO_RWG, void, avr, avr, avr) DEF_HELPER_FLAGS_3(VMULOUB, TCG_CALL_NO_RWG, void, avr, avr, avr) DEF_HELPER_FLAGS_3(VMULOUH, TCG_CALL_NO_RWG, void, avr, avr, avr) DEF_HELPER_FLAGS_3(VMULOUW, TCG_CALL_NO_RWG, void, avr, avr, avr) +DEF_HELPER_FLAGS_3(VDIVSQ, TCG_CALL_NO_RWG, void, avr, avr, avr) +DEF_HELPER_FLAGS_3(VDIVUQ, TCG_CALL_NO_RWG, void, avr, avr, avr) DEF_HELPER_3(vslo, void, avr, avr, avr) DEF_HELPER_3(vsro, void, avr, avr, avr) DEF_HELPER_3(vsrv, void, avr, avr, avr) diff --git a/target/ppc/insn32.decode b/target/ppc/insn32.decode index 597768558b..3a88a0b5bc 100644 --- a/target/ppc/insn32.decode +++ b/target/ppc/insn32.decode @@ -710,3 +710,5 @@ VDIVSW 000100 ..... ..... ..... 00110001011 @VX VDIVUW 000100 ..... ..... ..... 00010001011 @VX VDIVSD 000100 ..... ..... ..... 00111001011 @VX VDIVUD 000100 ..... ..... ..... 00011001011 @VX +VDIVSQ 000100 ..... ..... ..... 00100001011 @VX +VDIVUQ 000100 ..... ..... ..... 00000001011 @VX diff --git a/target/ppc/int_helper.c b/target/ppc/int_helper.c index 492f34c499..ba5d4193ff 100644 --- a/target/ppc/int_helper.c +++ b/target/ppc/int_helper.c @@ -1036,6 +1036,27 @@ void helper_XXPERMX(ppc_vsr_t *t, ppc_vsr_t *s0, ppc_vsr_t *s1, ppc_vsr_t *pcv, *t = tmp; } +void helper_VDIVSQ(ppc_avr_t *t, ppc_avr_t *a, ppc_avr_t *b) +{ + Int128 neg1 = int128_makes64(-1); + Int128 int128_min = int128_make128(0, INT64_MIN); + if (likely(int128_nz(b->s128) && + (int128_ne(a->s128, int128_min) || int128_ne(b->s128, neg1)))) { + t->s128 = int128_divs(a->s128, b->s128); + } else { + t->s128 = a->s128; /* Undefined behavior */ + } +} + +void helper_VDIVUQ(ppc_avr_t *t, ppc_avr_t *a, ppc_avr_t *b) +{ + if (int128_nz(b->s128)) { + t->s128 = int128_divu(a->s128, b->s128); + } else { + t->s128 = a->s128; /* Undefined behavior */ + } +} + void helper_VPERM(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b, ppc_avr_t *c) { ppc_avr_t result; diff --git a/target/ppc/translate/vmx-impl.c.inc b/target/ppc/translate/vmx-impl.c.inc index be35d6fdf3..bac0db7128 100644 --- a/target/ppc/translate/vmx-impl.c.inc +++ b/target/ppc/translate/vmx-impl.c.inc @@ -3292,6 +3292,8 @@ TRANS_VDIV_VMOD(ISA310, VDIVSW, MO_32, do_divsw, NULL) TRANS_VDIV_VMOD(ISA310, VDIVUW, MO_32, do_divuw, NULL) TRANS_VDIV_VMOD(ISA310, VDIVSD, MO_64, NULL, do_divsd) TRANS_VDIV_VMOD(ISA310, VDIVUD, MO_64, NULL, do_divud) +TRANS_FLAGS2(ISA310, VDIVSQ, do_vx_helper, gen_helper_VDIVSQ) +TRANS_FLAGS2(ISA310, VDIVUQ, do_vx_helper, gen_helper_VDIVUQ) #undef DO_VDIV_VMOD -- 2.31.1