diff options
author | Lucas Mateus Castro (alqotel) | 2022-05-25 15:49:49 +0200 |
---|---|---|
committer | Daniel Henrique Barboza | 2022-06-20 13:38:58 +0200 |
commit | 9a1f0866a3caf0f98ff588ba84da4fa6be2dc39c (patch) | |
tree | 2395e5e8a22f178db05fd5fe0abc575da5b87226 /target | |
parent | target/ppc: Implemented vector divide quadword (diff) | |
download | qemu-9a1f0866a3caf0f98ff588ba84da4fa6be2dc39c.tar.gz qemu-9a1f0866a3caf0f98ff588ba84da4fa6be2dc39c.tar.xz qemu-9a1f0866a3caf0f98ff588ba84da4fa6be2dc39c.zip |
target/ppc: Implemented vector divide extended word
Implement the following PowerISA v3.1 instructions:
vdivesw: Vector Divide Extended Signed Word
vdiveuw: Vector Divide Extended Unsigned Word
Signed-off-by: Lucas Mateus Castro (alqotel) <lucas.araujo@eldorado.org.br>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-Id: <20220525134954.85056-4-lucas.araujo@eldorado.org.br>
Signed-off-by: Daniel Henrique Barboza <danielhb413@gmail.com>
Diffstat (limited to 'target')
-rw-r--r-- | target/ppc/insn32.decode | 3 | ||||
-rw-r--r-- | target/ppc/translate/vmx-impl.c.inc | 48 |
2 files changed, 51 insertions, 0 deletions
diff --git a/target/ppc/insn32.decode b/target/ppc/insn32.decode index 01bfde8c5e..f6d2d4b257 100644 --- a/target/ppc/insn32.decode +++ b/target/ppc/insn32.decode @@ -795,3 +795,6 @@ VDIVSD 000100 ..... ..... ..... 00111001011 @VX VDIVUD 000100 ..... ..... ..... 00011001011 @VX VDIVSQ 000100 ..... ..... ..... 00100001011 @VX VDIVUQ 000100 ..... ..... ..... 00000001011 @VX + +VDIVESW 000100 ..... ..... ..... 01110001011 @VX +VDIVEUW 000100 ..... ..... ..... 01010001011 @VX diff --git a/target/ppc/translate/vmx-impl.c.inc b/target/ppc/translate/vmx-impl.c.inc index 22572e6a79..8c542bcb29 100644 --- a/target/ppc/translate/vmx-impl.c.inc +++ b/target/ppc/translate/vmx-impl.c.inc @@ -3320,6 +3320,54 @@ TRANS_FLAGS2(ISA310, VDIVUD, do_vdiv_vmod, 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) +static void do_dives_i32(TCGv_i32 t, TCGv_i32 a, TCGv_i32 b) +{ + TCGv_i64 val1, val2; + + val1 = tcg_temp_new_i64(); + val2 = tcg_temp_new_i64(); + + tcg_gen_ext_i32_i64(val1, a); + tcg_gen_ext_i32_i64(val2, b); + + /* (a << 32)/b */ + tcg_gen_shli_i64(val1, val1, 32); + tcg_gen_div_i64(val1, val1, val2); + + /* if quotient doesn't fit in 32 bits the result is undefined */ + tcg_gen_extrl_i64_i32(t, val1); + + tcg_temp_free_i64(val1); + tcg_temp_free_i64(val2); +} + +static void do_diveu_i32(TCGv_i32 t, TCGv_i32 a, TCGv_i32 b) +{ + TCGv_i64 val1, val2; + + val1 = tcg_temp_new_i64(); + val2 = tcg_temp_new_i64(); + + tcg_gen_extu_i32_i64(val1, a); + tcg_gen_extu_i32_i64(val2, b); + + /* (a << 32)/b */ + tcg_gen_shli_i64(val1, val1, 32); + tcg_gen_divu_i64(val1, val1, val2); + + /* if quotient doesn't fit in 32 bits the result is undefined */ + tcg_gen_extrl_i64_i32(t, val1); + + tcg_temp_free_i64(val1); + tcg_temp_free_i64(val2); +} + +DIVS32(do_divesw, do_dives_i32) +DIVU32(do_diveuw, do_diveu_i32) + +TRANS_FLAGS2(ISA310, VDIVESW, do_vdiv_vmod, MO_32, do_divesw, NULL) +TRANS_FLAGS2(ISA310, VDIVEUW, do_vdiv_vmod, MO_32, do_diveuw, NULL) + #undef DIVS32 #undef DIVU32 #undef DIVS64 |