target/s390x: Emulate CVDG
CVDG is the same as CVD, except that it converts 64 bits into 128, rather than 32 into 64. Create a new helper, which uses Int128 wrappers. Reported-by: Ido Plat <Ido.Plat@ibm.com> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com> Message-ID: <20240205205830.6425-2-iii@linux.ibm.com> Signed-off-by: Thomas Huth <thuth@redhat.com>
This commit is contained in:
parent
6a41a62171
commit
a6e55a82e9
@ -89,6 +89,7 @@ DEF_HELPER_FLAGS_2(sqeb, TCG_CALL_NO_WG, i64, env, i64)
|
||||
DEF_HELPER_FLAGS_2(sqdb, TCG_CALL_NO_WG, i64, env, i64)
|
||||
DEF_HELPER_FLAGS_2(sqxb, TCG_CALL_NO_WG, i128, env, i128)
|
||||
DEF_HELPER_FLAGS_1(cvd, TCG_CALL_NO_RWG_SE, i64, s32)
|
||||
DEF_HELPER_FLAGS_1(cvdg, TCG_CALL_NO_RWG_SE, i128, s64)
|
||||
DEF_HELPER_FLAGS_4(pack, TCG_CALL_NO_WG, void, env, i32, i64, i64)
|
||||
DEF_HELPER_FLAGS_4(pka, TCG_CALL_NO_WG, void, env, i64, i64, i32)
|
||||
DEF_HELPER_FLAGS_4(pku, TCG_CALL_NO_WG, void, env, i64, i64, i32)
|
||||
|
@ -296,6 +296,7 @@
|
||||
/* CONVERT TO DECIMAL */
|
||||
C(0x4e00, CVD, RX_a, Z, r1_o, a2, 0, 0, cvd, 0)
|
||||
C(0xe326, CVDY, RXY_a, LD, r1_o, a2, 0, 0, cvd, 0)
|
||||
C(0xe32e, CVDG, RXY_a, Z, r1_o, a2, 0, 0, cvdg, 0)
|
||||
/* CONVERT TO FIXED */
|
||||
F(0xb398, CFEBR, RRF_e, Z, 0, e2, new, r1_32, cfeb, 0, IF_BFP)
|
||||
F(0xb399, CFDBR, RRF_e, Z, 0, f2, new, r1_32, cfdb, 0, IF_BFP)
|
||||
|
@ -118,6 +118,27 @@ uint64_t HELPER(cvd)(int32_t reg)
|
||||
return dec;
|
||||
}
|
||||
|
||||
Int128 HELPER(cvdg)(int64_t reg)
|
||||
{
|
||||
/* positive 0 */
|
||||
Int128 dec = int128_make64(0x0c);
|
||||
Int128 bin = int128_makes64(reg);
|
||||
Int128 base = int128_make64(10);
|
||||
int shift;
|
||||
|
||||
if (!int128_nonneg(bin)) {
|
||||
bin = int128_neg(bin);
|
||||
dec = int128_make64(0x0d);
|
||||
}
|
||||
|
||||
for (shift = 4; (shift < 128) && int128_nz(bin); shift += 4) {
|
||||
dec = int128_or(dec, int128_lshift(int128_remu(bin, base), shift));
|
||||
bin = int128_divu(bin, base);
|
||||
}
|
||||
|
||||
return dec;
|
||||
}
|
||||
|
||||
uint64_t HELPER(popcnt)(uint64_t val)
|
||||
{
|
||||
/* Note that we don't fold past bytes. */
|
||||
|
@ -2233,6 +2233,14 @@ static DisasJumpType op_cvd(DisasContext *s, DisasOps *o)
|
||||
return DISAS_NEXT;
|
||||
}
|
||||
|
||||
static DisasJumpType op_cvdg(DisasContext *s, DisasOps *o)
|
||||
{
|
||||
TCGv_i128 t = tcg_temp_new_i128();
|
||||
gen_helper_cvdg(t, o->in1);
|
||||
tcg_gen_qemu_st_i128(t, o->in2, get_mem_index(s), MO_TE | MO_128);
|
||||
return DISAS_NEXT;
|
||||
}
|
||||
|
||||
static DisasJumpType op_ct(DisasContext *s, DisasOps *o)
|
||||
{
|
||||
int m3 = get_field(s, m3);
|
||||
|
Loading…
Reference in New Issue
Block a user