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>
master
Lucas Mateus Castro (alqotel) 2022-05-25 10:49:49 -03:00 committed by Daniel Henrique Barboza
parent 1700f2bf97
commit 9a1f0866a3
2 changed files with 51 additions and 0 deletions

View File

@ -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

View File

@ -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