From 903f84eb88c8d43fa2e46d4c30969de30dbb5297 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Colombo?= Date: Fri, 15 Jul 2022 17:54:37 -0300 Subject: [PATCH 01/17] target/ppc: Add HASHKEYR and HASHPKEYR SPRs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add the Special Purpose Registers HASHKEYR and HASHPKEYR, which were introduced by the Power ISA 3.1B. They are used by the new instructions hashchk(p) and hashst(p). The ISA states that the Operating System should generate the value for these registers when creating a process, so it's its responsability to do so. We initialize it with 0 for qemu-softmmu, and set a random 64 bits value for linux-user. Signed-off-by: Víctor Colombo Reviewed-by: Lucas Mateus Castro Message-Id: <20220715205439.161110-2-victor.colombo@eldorado.org.br> Signed-off-by: Daniel Henrique Barboza --- target/ppc/cpu.h | 2 ++ target/ppc/cpu_init.c | 28 ++++++++++++++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h index a4c893cfad..4551d81b5f 100644 --- a/target/ppc/cpu.h +++ b/target/ppc/cpu.h @@ -1676,6 +1676,8 @@ void ppc_compat_add_property(Object *obj, const char *name, #define SPR_BOOKE_GIVOR14 (0x1BD) #define SPR_TIR (0x1BE) #define SPR_PTCR (0x1D0) +#define SPR_HASHKEYR (0x1D4) +#define SPR_HASHPKEYR (0x1D5) #define SPR_BOOKE_SPEFSCR (0x200) #define SPR_Exxx_BBEAR (0x201) #define SPR_Exxx_BBTAR (0x202) diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c index 899c4a586e..6e080ebda0 100644 --- a/target/ppc/cpu_init.c +++ b/target/ppc/cpu_init.c @@ -5700,6 +5700,33 @@ static void register_power9_mmu_sprs(CPUPPCState *env) #endif } +static void register_power10_hash_sprs(CPUPPCState *env) +{ + /* + * it's the OS responsability to generate a random value for the registers + * in each process' context. So, initialize it with 0 here. + */ + uint64_t hashkeyr_initial_value = 0, hashpkeyr_initial_value = 0; +#if defined(CONFIG_USER_ONLY) + /* in linux-user, setup the hash register with a random value */ + GRand *rand = g_rand_new(); + hashkeyr_initial_value = + ((uint64_t)g_rand_int(rand) << 32) | (uint64_t)g_rand_int(rand); + hashpkeyr_initial_value = + ((uint64_t)g_rand_int(rand) << 32) | (uint64_t)g_rand_int(rand); + g_rand_free(rand); +#endif + spr_register(env, SPR_HASHKEYR, "HASHKEYR", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + hashkeyr_initial_value); + spr_register_hv(env, SPR_HASHPKEYR, "HASHPKEYR", + SPR_NOACCESS, SPR_NOACCESS, + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + hashpkeyr_initial_value); +} + /* * Initialize PMU counter overflow timers for Power8 and * newer Power chips when using TCG. @@ -6518,6 +6545,7 @@ static void init_proc_POWER10(CPUPPCState *env) register_power8_book4_sprs(env); register_power8_rpr_sprs(env); register_power9_mmu_sprs(env); + register_power10_hash_sprs(env); /* FIXME: Filter fields properly based on privilege level */ spr_register_kvm_hv(env, SPR_PSSCR, "PSSCR", NULL, NULL, NULL, NULL, From 670f1da374d9e9a7d509ef6f03d871144284f8d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Colombo?= Date: Fri, 15 Jul 2022 17:54:38 -0300 Subject: [PATCH 02/17] target/ppc: Implement hashst and hashchk MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Implementation for instructions hashst and hashchk, which were added in Power ISA 3.1B. It was decided to implement the hash algorithm from ground up in this patch exactly as described in Power ISA. Signed-off-by: Víctor Colombo Reviewed-by: Lucas Mateus Castro Message-Id: <20220715205439.161110-3-victor.colombo@eldorado.org.br> [danielhb: fix block comment in excp_helper.c] Signed-off-by: Daniel Henrique Barboza --- target/ppc/excp_helper.c | 81 ++++++++++++++++++++++ target/ppc/helper.h | 2 + target/ppc/insn32.decode | 8 +++ target/ppc/translate.c | 5 ++ target/ppc/translate/fixedpoint-impl.c.inc | 32 +++++++++ 5 files changed, 128 insertions(+) diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c index 7550aafed6..7a16991f3d 100644 --- a/target/ppc/excp_helper.c +++ b/target/ppc/excp_helper.c @@ -2173,6 +2173,87 @@ void helper_td(CPUPPCState *env, target_ulong arg1, target_ulong arg2, #endif #endif +static uint32_t helper_SIMON_LIKE_32_64(uint32_t x, uint64_t key, uint32_t lane) +{ + const uint16_t c = 0xfffc; + const uint64_t z0 = 0xfa2561cdf44ac398ULL; + uint16_t z = 0, temp; + uint16_t k[32], eff_k[32], xleft[33], xright[33], fxleft[32]; + + for (int i = 3; i >= 0; i--) { + k[i] = key & 0xffff; + key >>= 16; + } + xleft[0] = x & 0xffff; + xright[0] = (x >> 16) & 0xffff; + + for (int i = 0; i < 28; i++) { + z = (z0 >> (63 - i)) & 1; + temp = ror16(k[i + 3], 3) ^ k[i + 1]; + k[i + 4] = c ^ z ^ k[i] ^ temp ^ ror16(temp, 1); + } + + for (int i = 0; i < 8; i++) { + eff_k[4 * i + 0] = k[4 * i + ((0 + lane) % 4)]; + eff_k[4 * i + 1] = k[4 * i + ((1 + lane) % 4)]; + eff_k[4 * i + 2] = k[4 * i + ((2 + lane) % 4)]; + eff_k[4 * i + 3] = k[4 * i + ((3 + lane) % 4)]; + } + + for (int i = 0; i < 32; i++) { + fxleft[i] = (rol16(xleft[i], 1) & + rol16(xleft[i], 8)) ^ rol16(xleft[i], 2); + xleft[i + 1] = xright[i] ^ fxleft[i] ^ eff_k[i]; + xright[i + 1] = xleft[i]; + } + + return (((uint32_t)xright[32]) << 16) | xleft[32]; +} + +static uint64_t hash_digest(uint64_t ra, uint64_t rb, uint64_t key) +{ + uint64_t stage0_h = 0ULL, stage0_l = 0ULL; + uint64_t stage1_h, stage1_l; + + for (int i = 0; i < 4; i++) { + stage0_h |= ror64(rb & 0xff, 8 * (2 * i + 1)); + stage0_h |= ((ra >> 32) & 0xff) << (8 * 2 * i); + stage0_l |= ror64((rb >> 32) & 0xff, 8 * (2 * i + 1)); + stage0_l |= (ra & 0xff) << (8 * 2 * i); + rb >>= 8; + ra >>= 8; + } + + stage1_h = (uint64_t)helper_SIMON_LIKE_32_64(stage0_h >> 32, key, 0) << 32; + stage1_h |= helper_SIMON_LIKE_32_64(stage0_h, key, 1); + stage1_l = (uint64_t)helper_SIMON_LIKE_32_64(stage0_l >> 32, key, 2) << 32; + stage1_l |= helper_SIMON_LIKE_32_64(stage0_l, key, 3); + + return stage1_h ^ stage1_l; +} + +#include "qemu/guest-random.h" + +#define HELPER_HASH(op, key, store) \ +void helper_##op(CPUPPCState *env, target_ulong ea, target_ulong ra, \ + target_ulong rb) \ +{ \ + uint64_t calculated_hash = hash_digest(ra, rb, key), loaded_hash; \ + \ + if (store) { \ + cpu_stq_data_ra(env, ea, calculated_hash, GETPC()); \ + } else { \ + loaded_hash = cpu_ldq_data_ra(env, ea, GETPC()); \ + if (loaded_hash != calculated_hash) { \ + raise_exception_err_ra(env, POWERPC_EXCP_PROGRAM, \ + POWERPC_EXCP_TRAP, GETPC()); \ + } \ + } \ +} + +HELPER_HASH(HASHST, env->spr[SPR_HASHKEYR], true) +HELPER_HASH(HASHCHK, env->spr[SPR_HASHKEYR], false) + #if !defined(CONFIG_USER_ONLY) #ifdef CONFIG_TCG diff --git a/target/ppc/helper.h b/target/ppc/helper.h index 159b352f6e..5817af632b 100644 --- a/target/ppc/helper.h +++ b/target/ppc/helper.h @@ -4,6 +4,8 @@ DEF_HELPER_FLAGS_4(tw, TCG_CALL_NO_WG, void, env, tl, tl, i32) #if defined(TARGET_PPC64) DEF_HELPER_FLAGS_4(td, TCG_CALL_NO_WG, void, env, tl, tl, i32) #endif +DEF_HELPER_4(HASHST, void, env, tl, tl, tl) +DEF_HELPER_4(HASHCHK, void, env, tl, tl, tl) #if !defined(CONFIG_USER_ONLY) DEF_HELPER_2(store_msr, void, env, tl) DEF_HELPER_1(rfi, void, env) diff --git a/target/ppc/insn32.decode b/target/ppc/insn32.decode index eb41efc100..544514565c 100644 --- a/target/ppc/insn32.decode +++ b/target/ppc/insn32.decode @@ -172,6 +172,9 @@ @X_TSX ...... ..... ra:5 rb:5 .......... . &X rt=%x_rt_tsx @X_TSXP ...... ..... ra:5 rb:5 .......... . &X rt=%rt_tsxp +%x_dw 0:1 21:5 !function=dw_compose_ea +@X_DW ...... ..... ra:5 rb:5 .......... . &X rt=%x_dw + &X_frtp_vrb frtp vrb @X_frtp_vrb ...... ....0 ..... vrb:5 .......... . &X_frtp_vrb frtp=%x_frtp @@ -323,6 +326,11 @@ CNTTZDM 011111 ..... ..... ..... 1000111011 - @X PDEPD 011111 ..... ..... ..... 0010011100 - @X PEXTD 011111 ..... ..... ..... 0010111100 - @X +# Fixed-Point Hash Instructions + +HASHST 011111 ..... ..... ..... 1011010010 . @X_DW +HASHCHK 011111 ..... ..... ..... 1011110010 . @X_DW + ## BCD Assist ADDG6S 011111 ..... ..... ..... - 001001010 - @X diff --git a/target/ppc/translate.c b/target/ppc/translate.c index 000b1e518d..29939bd923 100644 --- a/target/ppc/translate.c +++ b/target/ppc/translate.c @@ -6473,6 +6473,11 @@ static int times_16(DisasContext *ctx, int x) return x * 16; } +static int64_t dw_compose_ea(DisasContext *ctx, int x) +{ + return deposit64(0xfffffffffffffe00, 3, 6, x); +} + /* * Helpers for trans_* functions to check for specific insns flags. * Use token pasting to ensure that we use the proper flag with the diff --git a/target/ppc/translate/fixedpoint-impl.c.inc b/target/ppc/translate/fixedpoint-impl.c.inc index db14d3bebc..41c06de8a2 100644 --- a/target/ppc/translate/fixedpoint-impl.c.inc +++ b/target/ppc/translate/fixedpoint-impl.c.inc @@ -540,3 +540,35 @@ static bool trans_CBCDTD(DisasContext *ctx, arg_X_sa *a) gen_helper_CBCDTD(cpu_gpr[a->ra], cpu_gpr[a->rs]); return true; } + +static bool do_hash(DisasContext *ctx, arg_X *a, bool priv, + void (*helper)(TCGv_ptr, TCGv, TCGv, TCGv)) +{ + TCGv ea; + + if (!(ctx->insns_flags2 & PPC2_ISA310)) { + /* if version is before v3.1, this operation is a nop */ + return true; + } + + if (priv) { + /* if instruction is privileged but the context is in user space */ + REQUIRE_SV(ctx); + } + + if (unlikely(a->ra == 0)) { + /* if RA=0, the instruction form is invalid */ + gen_invalid(ctx); + return true; + } + + ea = do_ea_calc(ctx, a->ra, tcg_constant_tl(a->rt)); + helper(cpu_env, ea, cpu_gpr[a->ra], cpu_gpr[a->rb]); + + tcg_temp_free(ea); + + return true; +} + +TRANS(HASHST, do_hash, false, gen_helper_HASHST) +TRANS(HASHCHK, do_hash, false, gen_helper_HASHCHK) From 53ae2aeb940729d7f6f42ce734dc65d5332260c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Colombo?= Date: Fri, 15 Jul 2022 17:54:39 -0300 Subject: [PATCH 03/17] target/ppc: Implement hashstp and hashchkp MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Implementation for instructions hashstp and hashchkp, the privileged versions of hashst and hashchk, which were added in Power ISA 3.1B. Signed-off-by: Víctor Colombo Reviewed-by: Lucas Mateus Castro Message-Id: <20220715205439.161110-4-victor.colombo@eldorado.org.br> Signed-off-by: Daniel Henrique Barboza --- target/ppc/excp_helper.c | 2 ++ target/ppc/helper.h | 2 ++ target/ppc/insn32.decode | 2 ++ target/ppc/translate/fixedpoint-impl.c.inc | 2 ++ 4 files changed, 8 insertions(+) diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c index 7a16991f3d..214acf5ac4 100644 --- a/target/ppc/excp_helper.c +++ b/target/ppc/excp_helper.c @@ -2253,6 +2253,8 @@ void helper_##op(CPUPPCState *env, target_ulong ea, target_ulong ra, \ HELPER_HASH(HASHST, env->spr[SPR_HASHKEYR], true) HELPER_HASH(HASHCHK, env->spr[SPR_HASHKEYR], false) +HELPER_HASH(HASHSTP, env->spr[SPR_HASHPKEYR], true) +HELPER_HASH(HASHCHKP, env->spr[SPR_HASHPKEYR], false) #if !defined(CONFIG_USER_ONLY) diff --git a/target/ppc/helper.h b/target/ppc/helper.h index 5817af632b..122b2e9359 100644 --- a/target/ppc/helper.h +++ b/target/ppc/helper.h @@ -6,6 +6,8 @@ DEF_HELPER_FLAGS_4(td, TCG_CALL_NO_WG, void, env, tl, tl, i32) #endif DEF_HELPER_4(HASHST, void, env, tl, tl, tl) DEF_HELPER_4(HASHCHK, void, env, tl, tl, tl) +DEF_HELPER_4(HASHSTP, void, env, tl, tl, tl) +DEF_HELPER_4(HASHCHKP, void, env, tl, tl, tl) #if !defined(CONFIG_USER_ONLY) DEF_HELPER_2(store_msr, void, env, tl) DEF_HELPER_1(rfi, void, env) diff --git a/target/ppc/insn32.decode b/target/ppc/insn32.decode index 544514565c..da08960fca 100644 --- a/target/ppc/insn32.decode +++ b/target/ppc/insn32.decode @@ -330,6 +330,8 @@ PEXTD 011111 ..... ..... ..... 0010111100 - @X HASHST 011111 ..... ..... ..... 1011010010 . @X_DW HASHCHK 011111 ..... ..... ..... 1011110010 . @X_DW +HASHSTP 011111 ..... ..... ..... 1010010010 . @X_DW +HASHCHKP 011111 ..... ..... ..... 1010110010 . @X_DW ## BCD Assist diff --git a/target/ppc/translate/fixedpoint-impl.c.inc b/target/ppc/translate/fixedpoint-impl.c.inc index 41c06de8a2..1ba56cbed5 100644 --- a/target/ppc/translate/fixedpoint-impl.c.inc +++ b/target/ppc/translate/fixedpoint-impl.c.inc @@ -572,3 +572,5 @@ static bool do_hash(DisasContext *ctx, arg_X *a, bool priv, TRANS(HASHST, do_hash, false, gen_helper_HASHST) TRANS(HASHCHK, do_hash, false, gen_helper_HASHCHK) +TRANS(HASHSTP, do_hash, true, gen_helper_HASHSTP) +TRANS(HASHCHKP, do_hash, true, gen_helper_HASHCHKP) From 6a8654d6c215f410cfd5c7dd853e6cf311156b5f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Colombo?= Date: Mon, 5 Sep 2022 09:37:44 -0300 Subject: [PATCH 04/17] target/ppc: Move fsqrt to decodetree MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Víctor Colombo Reviewed-by: Richard Henderson Message-Id: <20220905123746.54659-2-victor.colombo@eldorado.org.br> Signed-off-by: Daniel Henrique Barboza --- target/ppc/insn32.decode | 7 +++++++ target/ppc/translate/fp-impl.c.inc | 29 +++++++++++++++++------------ target/ppc/translate/fp-ops.c.inc | 1 - 3 files changed, 24 insertions(+), 13 deletions(-) diff --git a/target/ppc/insn32.decode b/target/ppc/insn32.decode index da08960fca..33aa27bd4f 100644 --- a/target/ppc/insn32.decode +++ b/target/ppc/insn32.decode @@ -20,6 +20,9 @@ &A frt fra frb frc rc:bool @A ...... frt:5 fra:5 frb:5 frc:5 ..... rc:1 &A +&A_tb frt frb rc:bool +@A_tb ...... frt:5 ..... frb:5 ..... ..... rc:1 &A_tb + &D rt ra si:int64_t @D ...... rt:5 ra:5 si:s16 &D @@ -363,6 +366,10 @@ STFDU 110111 ..... ...... ............... @D STFDX 011111 ..... ...... .... 1011010111 - @X STFDUX 011111 ..... ...... .... 1011110111 - @X +### Floating-Point Arithmetic Instructions + +FSQRT 111111 ..... ----- ..... ----- 10110 . @A_tb + ### Floating-Point Select Instruction FSEL 111111 ..... ..... ..... ..... 10111 . @A diff --git a/target/ppc/translate/fp-impl.c.inc b/target/ppc/translate/fp-impl.c.inc index 0e893eafa7..e8359af005 100644 --- a/target/ppc/translate/fp-impl.c.inc +++ b/target/ppc/translate/fp-impl.c.inc @@ -254,29 +254,34 @@ static bool trans_FSEL(DisasContext *ctx, arg_A *a) GEN_FLOAT_AB(sub, 0x14, 0x000007C0, 1, PPC_FLOAT); /* Optional: */ -/* fsqrt */ -static void gen_fsqrt(DisasContext *ctx) +static bool do_helper_fsqrt(DisasContext *ctx, arg_A_tb *a, + void (*helper)(TCGv_i64, TCGv_ptr, TCGv_i64)) { - TCGv_i64 t0; - TCGv_i64 t1; - if (unlikely(!ctx->fpu_enabled)) { - gen_exception(ctx, POWERPC_EXCP_FPU); - return; - } + TCGv_i64 t0, t1; + + REQUIRE_INSNS_FLAGS(ctx, FLOAT_FSQRT); + REQUIRE_FPU(ctx); + t0 = tcg_temp_new_i64(); t1 = tcg_temp_new_i64(); + gen_reset_fpstatus(); - get_fpr(t0, rB(ctx->opcode)); - gen_helper_fsqrt(t1, cpu_env, t0); - set_fpr(rD(ctx->opcode), t1); + get_fpr(t0, a->frb); + helper(t1, cpu_env, t0); + set_fpr(a->frt, t1); gen_compute_fprf_float64(t1); - if (unlikely(Rc(ctx->opcode) != 0)) { + if (unlikely(a->rc != 0)) { gen_set_cr1_from_fpscr(ctx); } + tcg_temp_free_i64(t0); tcg_temp_free_i64(t1); + + return true; } +TRANS(FSQRT, do_helper_fsqrt, gen_helper_fsqrt); + static void gen_fsqrts(DisasContext *ctx) { TCGv_i64 t0; diff --git a/target/ppc/translate/fp-ops.c.inc b/target/ppc/translate/fp-ops.c.inc index 1b65f5ab73..38759f5939 100644 --- a/target/ppc/translate/fp-ops.c.inc +++ b/target/ppc/translate/fp-ops.c.inc @@ -62,7 +62,6 @@ GEN_HANDLER_E(stfdepx, 0x1F, 0x1F, 0x16, 0x00000001, PPC_NONE, PPC2_BOOKE206), GEN_HANDLER_E(stfdpx, 0x1F, 0x17, 0x1C, 0x00200001, PPC_NONE, PPC2_ISA205), GEN_HANDLER(frsqrtes, 0x3B, 0x1A, 0xFF, 0x001F07C0, PPC_FLOAT_FRSQRTES), -GEN_HANDLER(fsqrt, 0x3F, 0x16, 0xFF, 0x001F07C0, PPC_FLOAT_FSQRT), GEN_HANDLER(fsqrts, 0x3B, 0x16, 0xFF, 0x001F07C0, PPC_FLOAT_FSQRT), GEN_HANDLER(fcmpo, 0x3F, 0x00, 0x01, 0x00600001, PPC_FLOAT), GEN_HANDLER(fcmpu, 0x3F, 0x00, 0x00, 0x00600001, PPC_FLOAT), From 4896c15bc36591436f02c3bfc4c828099be2b1f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Colombo?= Date: Mon, 5 Sep 2022 09:37:45 -0300 Subject: [PATCH 05/17] target/ppc: Move fsqrts to decodetree MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Víctor Colombo Reviewed-by: Richard Henderson Message-Id: <20220905123746.54659-3-victor.colombo@eldorado.org.br> Signed-off-by: Daniel Henrique Barboza --- target/ppc/insn32.decode | 1 + target/ppc/translate/fp-impl.c.inc | 23 +---------------------- target/ppc/translate/fp-ops.c.inc | 1 - 3 files changed, 2 insertions(+), 23 deletions(-) diff --git a/target/ppc/insn32.decode b/target/ppc/insn32.decode index 33aa27bd4f..a5249ee32c 100644 --- a/target/ppc/insn32.decode +++ b/target/ppc/insn32.decode @@ -369,6 +369,7 @@ STFDUX 011111 ..... ...... .... 1011110111 - @X ### Floating-Point Arithmetic Instructions FSQRT 111111 ..... ----- ..... ----- 10110 . @A_tb +FSQRTS 111011 ..... ----- ..... ----- 10110 . @A_tb ### Floating-Point Select Instruction diff --git a/target/ppc/translate/fp-impl.c.inc b/target/ppc/translate/fp-impl.c.inc index e8359af005..7a90c0e350 100644 --- a/target/ppc/translate/fp-impl.c.inc +++ b/target/ppc/translate/fp-impl.c.inc @@ -281,28 +281,7 @@ static bool do_helper_fsqrt(DisasContext *ctx, arg_A_tb *a, } TRANS(FSQRT, do_helper_fsqrt, gen_helper_fsqrt); - -static void gen_fsqrts(DisasContext *ctx) -{ - TCGv_i64 t0; - TCGv_i64 t1; - if (unlikely(!ctx->fpu_enabled)) { - gen_exception(ctx, POWERPC_EXCP_FPU); - return; - } - t0 = tcg_temp_new_i64(); - t1 = tcg_temp_new_i64(); - gen_reset_fpstatus(); - get_fpr(t0, rB(ctx->opcode)); - gen_helper_fsqrts(t1, cpu_env, t0); - set_fpr(rD(ctx->opcode), t1); - gen_compute_fprf_float64(t1); - if (unlikely(Rc(ctx->opcode) != 0)) { - gen_set_cr1_from_fpscr(ctx); - } - tcg_temp_free_i64(t0); - tcg_temp_free_i64(t1); -} +TRANS(FSQRTS, do_helper_fsqrt, gen_helper_fsqrts); /*** Floating-Point multiply-and-add ***/ /* fmadd - fmadds */ diff --git a/target/ppc/translate/fp-ops.c.inc b/target/ppc/translate/fp-ops.c.inc index 38759f5939..d4c6c4bed1 100644 --- a/target/ppc/translate/fp-ops.c.inc +++ b/target/ppc/translate/fp-ops.c.inc @@ -62,7 +62,6 @@ GEN_HANDLER_E(stfdepx, 0x1F, 0x1F, 0x16, 0x00000001, PPC_NONE, PPC2_BOOKE206), GEN_HANDLER_E(stfdpx, 0x1F, 0x17, 0x1C, 0x00200001, PPC_NONE, PPC2_ISA205), GEN_HANDLER(frsqrtes, 0x3B, 0x1A, 0xFF, 0x001F07C0, PPC_FLOAT_FRSQRTES), -GEN_HANDLER(fsqrts, 0x3B, 0x16, 0xFF, 0x001F07C0, PPC_FLOAT_FSQRT), GEN_HANDLER(fcmpo, 0x3F, 0x00, 0x01, 0x00600001, PPC_FLOAT), GEN_HANDLER(fcmpu, 0x3F, 0x00, 0x00, 0x00600001, PPC_FLOAT), GEN_HANDLER(fabs, 0x3F, 0x08, 0x08, 0x001F0000, PPC_FLOAT), From 74177ec661cc3d8553cc645632a9b6fdfe1b85e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Colombo?= Date: Mon, 5 Sep 2022 09:37:46 -0300 Subject: [PATCH 06/17] target/ppc: Merge fsqrt and fsqrts helpers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit These two helpers are almost identical, differing only by the softfloat operation it calls. Merge them into one using a macro. Also, take this opportunity to capitalize the helper name as we moved the instruction to decodetree in a previous patch. Signed-off-by: Víctor Colombo Reviewed-by: Richard Henderson Message-Id: <20220905123746.54659-4-victor.colombo@eldorado.org.br> Signed-off-by: Daniel Henrique Barboza --- target/ppc/fpu_helper.c | 35 +++++++++++------------------- target/ppc/helper.h | 4 ++-- target/ppc/translate/fp-impl.c.inc | 4 ++-- 3 files changed, 17 insertions(+), 26 deletions(-) diff --git a/target/ppc/fpu_helper.c b/target/ppc/fpu_helper.c index 0f045b70f8..32995179b5 100644 --- a/target/ppc/fpu_helper.c +++ b/target/ppc/fpu_helper.c @@ -830,30 +830,21 @@ static void float_invalid_op_sqrt(CPUPPCState *env, int flags, } } -/* fsqrt - fsqrt. */ -float64 helper_fsqrt(CPUPPCState *env, float64 arg) -{ - float64 ret = float64_sqrt(arg, &env->fp_status); - int flags = get_float_exception_flags(&env->fp_status); - - if (unlikely(flags & float_flag_invalid)) { - float_invalid_op_sqrt(env, flags, 1, GETPC()); - } - - return ret; +#define FPU_FSQRT(name, op) \ +float64 helper_##name(CPUPPCState *env, float64 arg) \ +{ \ + float64 ret = op(arg, &env->fp_status); \ + int flags = get_float_exception_flags(&env->fp_status); \ + \ + if (unlikely(flags & float_flag_invalid)) { \ + float_invalid_op_sqrt(env, flags, 1, GETPC()); \ + } \ + \ + return ret; \ } -/* fsqrts - fsqrts. */ -float64 helper_fsqrts(CPUPPCState *env, float64 arg) -{ - float64 ret = float64r32_sqrt(arg, &env->fp_status); - int flags = get_float_exception_flags(&env->fp_status); - - if (unlikely(flags & float_flag_invalid)) { - float_invalid_op_sqrt(env, flags, 1, GETPC()); - } - return ret; -} +FPU_FSQRT(FSQRT, float64_sqrt) +FPU_FSQRT(FSQRTS, float64r32_sqrt) /* fre - fre. */ float64 helper_fre(CPUPPCState *env, float64 arg) diff --git a/target/ppc/helper.h b/target/ppc/helper.h index 122b2e9359..57eee07256 100644 --- a/target/ppc/helper.h +++ b/target/ppc/helper.h @@ -120,8 +120,8 @@ DEF_HELPER_4(fmadds, i64, env, i64, i64, i64) DEF_HELPER_4(fmsubs, i64, env, i64, i64, i64) DEF_HELPER_4(fnmadds, i64, env, i64, i64, i64) DEF_HELPER_4(fnmsubs, i64, env, i64, i64, i64) -DEF_HELPER_2(fsqrt, f64, env, f64) -DEF_HELPER_2(fsqrts, f64, env, f64) +DEF_HELPER_2(FSQRT, f64, env, f64) +DEF_HELPER_2(FSQRTS, f64, env, f64) DEF_HELPER_2(fre, i64, env, i64) DEF_HELPER_2(fres, i64, env, i64) DEF_HELPER_2(frsqrte, i64, env, i64) diff --git a/target/ppc/translate/fp-impl.c.inc b/target/ppc/translate/fp-impl.c.inc index 7a90c0e350..8d5cf0f982 100644 --- a/target/ppc/translate/fp-impl.c.inc +++ b/target/ppc/translate/fp-impl.c.inc @@ -280,8 +280,8 @@ static bool do_helper_fsqrt(DisasContext *ctx, arg_A_tb *a, return true; } -TRANS(FSQRT, do_helper_fsqrt, gen_helper_fsqrt); -TRANS(FSQRTS, do_helper_fsqrt, gen_helper_fsqrts); +TRANS(FSQRT, do_helper_fsqrt, gen_helper_FSQRT); +TRANS(FSQRTS, do_helper_fsqrt, gen_helper_FSQRTS); /*** Floating-Point multiply-and-add ***/ /* fmadd - fmadds */ From 676696f428202b8f2dcd34ec8ff84baa38a14e61 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Colombo?= Date: Tue, 6 Sep 2022 09:55:16 -0300 Subject: [PATCH 07/17] target/ppc: Remove extra space from s128 field in ppc_vsr_t MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Very trivial rogue space removal. There are two spaces between Int128 and s128 in ppc_vsr_t struct, where it should be only one. Signed-off-by: Víctor Colombo Reviewed-by: Daniel Henrique Barboza Message-Id: <20220906125523.38765-2-victor.colombo@eldorado.org.br> Signed-off-by: Daniel Henrique Barboza --- target/ppc/cpu.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h index 4551d81b5f..602ea77914 100644 --- a/target/ppc/cpu.h +++ b/target/ppc/cpu.h @@ -246,7 +246,7 @@ typedef union _ppc_vsr_t { #ifdef CONFIG_INT128 __uint128_t u128; #endif - Int128 s128; + Int128 s128; } ppc_vsr_t; typedef ppc_vsr_t ppc_avr_t; From 228ab1451d2b4a731d00d4ff42c6e367afbbabdd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Colombo?= Date: Tue, 6 Sep 2022 09:55:17 -0300 Subject: [PATCH 08/17] target/ppc: Remove unused xer_* macros MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The macros xer_ov, xer_ca, xer_ov32, and xer_ca32 are both unused and hiding the usage of env. Remove them. Signed-off-by: Víctor Colombo Reviewed-by: Daniel Henrique Barboza Message-Id: <20220906125523.38765-3-victor.colombo@eldorado.org.br> Signed-off-by: Daniel Henrique Barboza --- target/ppc/cpu.h | 4 ---- 1 file changed, 4 deletions(-) diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h index 602ea77914..7f73e2ac81 100644 --- a/target/ppc/cpu.h +++ b/target/ppc/cpu.h @@ -1506,10 +1506,6 @@ void ppc_compat_add_property(Object *obj, const char *name, #define XER_CMP 8 #define XER_BC 0 #define xer_so (env->so) -#define xer_ov (env->ov) -#define xer_ca (env->ca) -#define xer_ov32 (env->ov) -#define xer_ca32 (env->ca) #define xer_cmp ((env->xer >> XER_CMP) & 0xFF) #define xer_bc ((env->xer >> XER_BC) & 0x7F) From 34f760bac2c9a32afae150fbcc56ceba399d61de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Colombo?= Date: Tue, 6 Sep 2022 09:55:18 -0300 Subject: [PATCH 09/17] target/ppc: Zero second doubleword in DFP instructions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Starting at PowerISA v3.1, the second doubleword of the registers used to store results in DFP instructions are supposed to be zeroed. From the ISA, chapter 7.2.1.1 Floating-Point Registers: """ Chapter 4. Floating-Point Facility provides 32 64-bit FPRs. Chapter 5. Decimal Floating-Point also employs FPRs in decimal floating-point (DFP) operations. When VSX is implemented, the 32 FPRs are mapped to doubleword 0 of VSRs 0-31. (...) All instructions that operate on an FPR are redefined to operate on doubleword element 0 of the corresponding VSR. (...) and the contents of doubleword element 1 of the VSR corresponding to the target FPR or FPR pair for these instructions are set to 0. """ Before, the result stored at doubleword 1 was said to be undefined. With that, this patch changes the DFP facility to zero doubleword 1 when using set_dfp64 and set_dfp128. This fixes the behavior for ISA 3.1 while keeping the behavior correct for previous ones. Signed-off-by: Víctor Colombo Reviewed-by: Daniel Henrique Barboza Message-Id: <20220906125523.38765-4-victor.colombo@eldorado.org.br> Signed-off-by: Daniel Henrique Barboza --- target/ppc/dfp_helper.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/target/ppc/dfp_helper.c b/target/ppc/dfp_helper.c index 5ba74b2124..be7aa5357a 100644 --- a/target/ppc/dfp_helper.c +++ b/target/ppc/dfp_helper.c @@ -42,13 +42,16 @@ static void get_dfp128(ppc_vsr_t *dst, ppc_fprp_t *dfp) static void set_dfp64(ppc_fprp_t *dfp, ppc_vsr_t *src) { - dfp->VsrD(0) = src->VsrD(1); + dfp[0].VsrD(0) = src->VsrD(1); + dfp[0].VsrD(1) = 0ULL; } static void set_dfp128(ppc_fprp_t *dfp, ppc_vsr_t *src) { dfp[0].VsrD(0) = src->VsrD(0); dfp[1].VsrD(0) = src->VsrD(1); + dfp[0].VsrD(1) = 0ULL; + dfp[1].VsrD(1) = 0ULL; } static void set_dfp128_to_avr(ppc_avr_t *dst, ppc_vsr_t *src) From 3ecec4c0429f65de1822b881ea732689cf647254 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Colombo?= Date: Tue, 6 Sep 2022 09:55:19 -0300 Subject: [PATCH 10/17] target/ppc: Set result to QNaN for DENBCD when VXCVI occurs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit According to the ISA, for instruction DENBCD: "If an invalid BCD digit or sign code is detected in the source operand, an invalid-operation exception (VXCVI) occurs." In the Invalid Operation Exception section, there is the situation: "When Invalid Operation Exception is disabled (VE=0) and Invalid Operation occurs (...) If the operation is an (...) or format the target FPR is set to a Quiet NaN". This was not being done in QEMU. This patch sets the result to QNaN when the instruction DENBCD causes an Invalid Operation Exception. Signed-off-by: Víctor Colombo Reviewed-by: Daniel Henrique Barboza Message-Id: <20220906125523.38765-5-victor.colombo@eldorado.org.br> Signed-off-by: Daniel Henrique Barboza --- target/ppc/dfp_helper.c | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/target/ppc/dfp_helper.c b/target/ppc/dfp_helper.c index be7aa5357a..cc024316d5 100644 --- a/target/ppc/dfp_helper.c +++ b/target/ppc/dfp_helper.c @@ -1147,6 +1147,26 @@ static inline uint8_t dfp_get_bcd_digit_128(ppc_vsr_t *t, unsigned n) return t->VsrD((n & 0x10) ? 0 : 1) >> ((n << 2) & 63) & 15; } +static inline void dfp_invalid_op_vxcvi_64(struct PPC_DFP *dfp) +{ + /* TODO: fpscr is incorrectly not being saved to env */ + dfp_set_FPSCR_flag(dfp, FP_VX | FP_VXCVI, FPSCR_VE); + if ((dfp->env->fpscr & FP_VE) == 0) { + dfp->vt.VsrD(1) = 0x7c00000000000000; /* QNaN */ + } +} + + +static inline void dfp_invalid_op_vxcvi_128(struct PPC_DFP *dfp) +{ + /* TODO: fpscr is incorrectly not being saved to env */ + dfp_set_FPSCR_flag(dfp, FP_VX | FP_VXCVI, FPSCR_VE); + if ((dfp->env->fpscr & FP_VE) == 0) { + dfp->vt.VsrD(0) = 0x7c00000000000000; /* QNaN */ + dfp->vt.VsrD(1) = 0x0; + } +} + #define DFP_HELPER_ENBCD(op, size) \ void helper_##op(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *b, \ uint32_t s) \ @@ -1173,7 +1193,8 @@ void helper_##op(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *b, \ sgn = 0; \ break; \ default: \ - dfp_set_FPSCR_flag(&dfp, FP_VX | FP_VXCVI, FPSCR_VE); \ + dfp_invalid_op_vxcvi_##size(&dfp); \ + set_dfp##size(t, &dfp.vt); \ return; \ } \ } \ @@ -1183,7 +1204,8 @@ void helper_##op(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *b, \ digits[(size) / 4 - n] = dfp_get_bcd_digit_##size(&dfp.vb, \ offset++); \ if (digits[(size) / 4 - n] > 10) { \ - dfp_set_FPSCR_flag(&dfp, FP_VX | FP_VXCVI, FPSCR_VE); \ + dfp_invalid_op_vxcvi_##size(&dfp); \ + set_dfp##size(t, &dfp.vt); \ return; \ } else { \ nonzero |= (digits[(size) / 4 - n] > 0); \ From 9f097daa5483cdb7d745740606232c931d32b796 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Colombo?= Date: Tue, 6 Sep 2022 09:55:20 -0300 Subject: [PATCH 11/17] target/ppc: Zero second doubleword for VSX madd instructions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In 205eb5a89e we updated most VSX instructions to zero the second doubleword, as is requested by PowerISA since v3.1. However, VSX_MADD helper was left behind unchanged, while it is also affected and should be fixed as well. This patch applies the fix for MADD instructions. Fixes: 205eb5a89e ("target/ppc: Change VSX instructions behavior to fill with zeros") Signed-off-by: Víctor Colombo Reviewed-by: Daniel Henrique Barboza Message-Id: <20220906125523.38765-6-victor.colombo@eldorado.org.br> Signed-off-by: Daniel Henrique Barboza --- target/ppc/fpu_helper.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/target/ppc/fpu_helper.c b/target/ppc/fpu_helper.c index 32995179b5..f07330ffc1 100644 --- a/target/ppc/fpu_helper.c +++ b/target/ppc/fpu_helper.c @@ -2167,7 +2167,7 @@ VSX_TSQRT(xvtsqrtsp, 4, float32, VsrW(i), -126, 23) void helper_##op(CPUPPCState *env, ppc_vsr_t *xt, \ ppc_vsr_t *s1, ppc_vsr_t *s2, ppc_vsr_t *s3) \ { \ - ppc_vsr_t t = *xt; \ + ppc_vsr_t t = { }; \ int i; \ \ helper_reset_fpstatus(env); \ From af721a31696a1e08d8dcdabcd14c4cb09f9a5e16 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Colombo?= Date: Tue, 6 Sep 2022 09:55:21 -0300 Subject: [PATCH 12/17] target/ppc: Set OV32 when OV is set MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit According to PowerISA: "OV32 is set whenever OV is implicitly set, and is set to the same value that OV is defined to be set to in 32-bit mode". This patch changes helper_update_ov_legacy to set/clear ov32 when applicable. Signed-off-by: Víctor Colombo Reviewed-by: Daniel Henrique Barboza Message-Id: <20220906125523.38765-7-victor.colombo@eldorado.org.br> Signed-off-by: Daniel Henrique Barboza --- target/ppc/int_helper.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/target/ppc/int_helper.c b/target/ppc/int_helper.c index d905f07d02..696096100b 100644 --- a/target/ppc/int_helper.c +++ b/target/ppc/int_helper.c @@ -37,9 +37,9 @@ static inline void helper_update_ov_legacy(CPUPPCState *env, int ov) { if (unlikely(ov)) { - env->so = env->ov = 1; + env->so = env->ov = env->ov32 = 1; } else { - env->ov = 0; + env->ov = env->ov32 = 0; } } From 4b65b6e76977895fe43eb340c54b552fd16fe1ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Colombo?= Date: Tue, 6 Sep 2022 09:55:22 -0300 Subject: [PATCH 13/17] target/ppc: Zero second doubleword of VSR registers for FPR insns MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit FPR register are mapped to the first doubleword of the VSR registers. Since PowerISA v3.1, the second doubleword of the target register must be zeroed for FP instructions. This patch does it by writting 0 to the second dw everytime the first dw is being written using set_fpr. Signed-off-by: Víctor Colombo Reviewed-by: Daniel Henrique Barboza Message-Id: <20220906125523.38765-8-victor.colombo@eldorado.org.br> Signed-off-by: Daniel Henrique Barboza --- target/ppc/translate.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/target/ppc/translate.c b/target/ppc/translate.c index 29939bd923..e810842925 100644 --- a/target/ppc/translate.c +++ b/target/ppc/translate.c @@ -6443,6 +6443,14 @@ static inline void get_fpr(TCGv_i64 dst, int regno) static inline void set_fpr(int regno, TCGv_i64 src) { tcg_gen_st_i64(src, cpu_env, fpr_offset(regno)); + /* + * Before PowerISA v3.1 the result of doubleword 1 of the VSR + * corresponding to the target FPR was undefined. However, + * most (if not all) real hardware were setting the result to 0. + * Starting at ISA v3.1, the result for doubleword 1 is now defined + * to be 0. + */ + tcg_gen_st_i64(tcg_constant_i64(0), cpu_env, vsr64_offset(regno, false)); } static inline void get_avr64(TCGv_i64 dst, int regno, bool high) From c3f24257e3c094122a82611db3d7c3e8b25d9153 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Colombo?= Date: Tue, 6 Sep 2022 09:55:23 -0300 Subject: [PATCH 14/17] target/ppc: Clear fpstatus flags on helpers missing it MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In ppc emulation, exception flags are not cleared at the end of an instruction. Instead, the next instruction is responsible to clear it before its emulation. However, some helpers are not doing it, causing an issue where the previously set exception flags are being used and leading to incorrect values being set in FPSCR. Fix this by clearing fp_status before doing the instruction 'real' work for the following helpers that were missing this behavior: - VSX_CVT_INT_TO_FP_VECTOR - VSX_CVT_FP_TO_FP - VSX_CVT_FP_TO_INT_VECTOR - VSX_CVT_FP_TO_INT2 - VSX_CVT_FP_TO_INT - VSX_CVT_FP_TO_FP_HP - VSX_CVT_FP_TO_FP_VECTOR - VSX_CMP - VSX_ROUND - xscvqpdp - xscvdpsp[n] Signed-off-by: Víctor Colombo Reviewed-by: Daniel Henrique Barboza Message-Id: <20220906125523.38765-9-victor.colombo@eldorado.org.br> Signed-off-by: Daniel Henrique Barboza --- target/ppc/fpu_helper.c | 37 ++++++++++++++++++++++++++----------- 1 file changed, 26 insertions(+), 11 deletions(-) diff --git a/target/ppc/fpu_helper.c b/target/ppc/fpu_helper.c index f07330ffc1..ae25f32d6e 100644 --- a/target/ppc/fpu_helper.c +++ b/target/ppc/fpu_helper.c @@ -2628,6 +2628,8 @@ uint32_t helper_##op(CPUPPCState *env, ppc_vsr_t *xt, \ int all_true = 1; \ int all_false = 1; \ \ + helper_reset_fpstatus(env); \ + \ for (i = 0; i < nels; i++) { \ if (unlikely(tp##_is_any_nan(xa->fld) || \ tp##_is_any_nan(xb->fld))) { \ @@ -2681,6 +2683,8 @@ void helper_##op(CPUPPCState *env, ppc_vsr_t *xt, ppc_vsr_t *xb) \ ppc_vsr_t t = { }; \ int i; \ \ + helper_reset_fpstatus(env); \ + \ for (i = 0; i < nels; i++) { \ t.tfld = stp##_to_##ttp(xb->sfld, &env->fp_status); \ if (unlikely(stp##_is_signaling_nan(xb->sfld, \ @@ -2706,6 +2710,8 @@ void helper_##op(CPUPPCState *env, ppc_vsr_t *xt, ppc_vsr_t *xb) \ ppc_vsr_t t = { }; \ int i; \ \ + helper_reset_fpstatus(env); \ + \ for (i = 0; i < nels; i++) { \ t.VsrW(2 * i) = stp##_to_##ttp(xb->VsrD(i), &env->fp_status); \ if (unlikely(stp##_is_signaling_nan(xb->VsrD(i), \ @@ -2743,6 +2749,8 @@ void helper_##op(CPUPPCState *env, uint32_t opcode, \ ppc_vsr_t t = *xt; \ int i; \ \ + helper_reset_fpstatus(env); \ + \ for (i = 0; i < nels; i++) { \ t.tfld = stp##_to_##ttp(xb->sfld, &env->fp_status); \ if (unlikely(stp##_is_signaling_nan(xb->sfld, \ @@ -2778,6 +2786,8 @@ void helper_##op(CPUPPCState *env, ppc_vsr_t *xt, ppc_vsr_t *xb) \ ppc_vsr_t t = { }; \ int i; \ \ + helper_reset_fpstatus(env); \ + \ for (i = 0; i < nels; i++) { \ t.tfld = stp##_to_##ttp(xb->sfld, 1, &env->fp_status); \ if (unlikely(stp##_is_signaling_nan(xb->sfld, \ @@ -2825,6 +2835,8 @@ void helper_XSCVQPDP(CPUPPCState *env, uint32_t ro, ppc_vsr_t *xt, ppc_vsr_t t = { }; float_status tstat; + helper_reset_fpstatus(env); + tstat = env->fp_status; if (ro != 0) { tstat.float_rounding_mode = float_round_to_odd; @@ -2846,6 +2858,7 @@ uint64_t helper_xscvdpspn(CPUPPCState *env, uint64_t xb) { uint64_t result, sign, exp, frac; + helper_reset_fpstatus(env); float_status tstat = env->fp_status; set_float_exception_flags(0, &tstat); @@ -2901,22 +2914,20 @@ uint64_t helper_XSCVSPDPN(uint64_t xb) #define VSX_CVT_FP_TO_INT(op, nels, stp, ttp, sfld, tfld, sfi, rnan) \ void helper_##op(CPUPPCState *env, ppc_vsr_t *xt, ppc_vsr_t *xb) \ { \ - int all_flags = env->fp_status.float_exception_flags, flags; \ ppc_vsr_t t = { }; \ - int i; \ + int i, flags; \ + \ + helper_reset_fpstatus(env); \ \ for (i = 0; i < nels; i++) { \ - env->fp_status.float_exception_flags = 0; \ t.tfld = stp##_to_##ttp##_round_to_zero(xb->sfld, &env->fp_status); \ flags = env->fp_status.float_exception_flags; \ if (unlikely(flags & float_flag_invalid)) { \ t.tfld = float_invalid_cvt(env, flags, t.tfld, rnan, 0, GETPC());\ } \ - all_flags |= flags; \ } \ \ *xt = t; \ - env->fp_status.float_exception_flags = all_flags; \ do_float_check_status(env, sfi, GETPC()); \ } @@ -2968,12 +2979,12 @@ VSX_CVT_FP_TO_INT128(XSCVQPSQZ, int128, 0x8000000000000000ULL); #define VSX_CVT_FP_TO_INT2(op, nels, stp, ttp, sfi, rnan) \ void helper_##op(CPUPPCState *env, ppc_vsr_t *xt, ppc_vsr_t *xb) \ { \ - int all_flags = env->fp_status.float_exception_flags, flags; \ ppc_vsr_t t = { }; \ - int i; \ + int i, flags; \ + \ + helper_reset_fpstatus(env); \ \ for (i = 0; i < nels; i++) { \ - env->fp_status.float_exception_flags = 0; \ t.VsrW(2 * i) = stp##_to_##ttp##_round_to_zero(xb->VsrD(i), \ &env->fp_status); \ flags = env->fp_status.float_exception_flags; \ @@ -2982,11 +2993,9 @@ void helper_##op(CPUPPCState *env, ppc_vsr_t *xt, ppc_vsr_t *xb) \ rnan, 0, GETPC()); \ } \ t.VsrW(2 * i + 1) = t.VsrW(2 * i); \ - all_flags |= flags; \ } \ \ *xt = t; \ - env->fp_status.float_exception_flags = all_flags; \ do_float_check_status(env, sfi, GETPC()); \ } @@ -3011,6 +3020,8 @@ void helper_##op(CPUPPCState *env, uint32_t opcode, \ ppc_vsr_t t = { }; \ int flags; \ \ + helper_reset_fpstatus(env); \ + \ t.tfld = stp##_to_##ttp##_round_to_zero(xb->sfld, &env->fp_status); \ flags = get_float_exception_flags(&env->fp_status); \ if (flags & float_flag_invalid) { \ @@ -3023,7 +3034,6 @@ void helper_##op(CPUPPCState *env, uint32_t opcode, \ VSX_CVT_FP_TO_INT_VECTOR(xscvqpsdz, float128, int64, f128, VsrD(0), \ 0x8000000000000000ULL) - VSX_CVT_FP_TO_INT_VECTOR(xscvqpswz, float128, int32, f128, VsrD(0), \ 0xffffffff80000000ULL) VSX_CVT_FP_TO_INT_VECTOR(xscvqpudz, float128, uint64, f128, VsrD(0), 0x0ULL) @@ -3046,6 +3056,8 @@ void helper_##op(CPUPPCState *env, ppc_vsr_t *xt, ppc_vsr_t *xb) \ ppc_vsr_t t = { }; \ int i; \ \ + helper_reset_fpstatus(env); \ + \ for (i = 0; i < nels; i++) { \ t.tfld = stp##_to_##ttp(xb->sfld, &env->fp_status); \ if (r2sp) { \ @@ -3115,6 +3127,7 @@ void helper_##op(CPUPPCState *env, uint32_t opcode, \ { \ ppc_vsr_t t = *xt; \ \ + helper_reset_fpstatus(env); \ t.tfld = stp##_to_##ttp(xb->sfld, &env->fp_status); \ helper_compute_fprf_##ttp(env, t.tfld); \ \ @@ -3148,6 +3161,8 @@ void helper_##op(CPUPPCState *env, ppc_vsr_t *xt, ppc_vsr_t *xb) \ int i; \ FloatRoundMode curr_rounding_mode; \ \ + helper_reset_fpstatus(env); \ + \ if (rmode != FLOAT_ROUND_CURRENT) { \ curr_rounding_mode = get_float_rounding_mode(&env->fp_status); \ set_float_rounding_mode(rmode, &env->fp_status); \ From cb5b5ab9a516ce5ecddfc50971bf6f690300fd74 Mon Sep 17 00:00:00 2001 From: Xuzhou Cheng Date: Tue, 20 Sep 2022 18:31:47 +0800 Subject: [PATCH 15/17] hw/ppc: spapr: Use qemu_vfree() to free spapr->htab MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit spapr->htab is allocated by qemu_memalign(), hence we should use qemu_vfree() to free it. Fixes: c5f54f3e31bf ("pseries: Move hash page table allocation to reset time") Fixes: b4db54132ffe ("target/ppc: Implement H_REGISTER_PROCESS_TABLE H_CALL"") Signed-off-by: Xuzhou Cheng Signed-off-by: Bin Meng Reviewed-by: Daniel Henrique Barboza Reviewed-by: Marc-André Lureau Message-Id: <20220920103159.1865256-28-bmeng.cn@gmail.com> Signed-off-by: Daniel Henrique Barboza --- hw/ppc/spapr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index fb790b61e4..cc1adc23fa 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -1522,7 +1522,7 @@ int spapr_hpt_shift_for_ramsize(uint64_t ramsize) void spapr_free_hpt(SpaprMachineState *spapr) { - g_free(spapr->htab); + qemu_vfree(spapr->htab); spapr->htab = NULL; spapr->htab_shift = 0; close_htab_fd(spapr); From 90865af7d901a2aa5eeadfb488f3a9d4aaf70605 Mon Sep 17 00:00:00 2001 From: Xuzhou Cheng Date: Tue, 20 Sep 2022 18:31:48 +0800 Subject: [PATCH 16/17] hw/pci-host: pnv_phb{3, 4}: Fix heap out-of-bound access failure MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit pnv_phb3_root_bus_info and pnv_phb4_root_bus_info are missing the instance_size initialization. This results in accessing out-of-bound memory when setting 'chip-id' and 'phb-id', and eventually crashes glib's malloc functionality with the following message: "qemu-system-ppc64: GLib: ../glib-2.72.3/glib/gmem.c:131: failed to allocate 3232 bytes" This issue was noticed only when running qtests with QEMU Windows 32-bit executable. Windows 64-bit, Linux 32/64-bit do not expose this bug though. Fixes: 9ae1329ee2fe ("ppc/pnv: Add models for POWER8 PHB3 PCIe Host bridge") Fixes: 4f9924c4d4cf ("ppc/pnv: Add models for POWER9 PHB4 PCIe Host bridge") Reviewed-by: Cédric Le Goater Signed-off-by: Xuzhou Cheng Signed-off-by: Bin Meng Message-Id: <20220920103159.1865256-29-bmeng.cn@gmail.com> Signed-off-by: Daniel Henrique Barboza --- hw/pci-host/pnv_phb3.c | 1 + hw/pci-host/pnv_phb4.c | 1 + 2 files changed, 2 insertions(+) diff --git a/hw/pci-host/pnv_phb3.c b/hw/pci-host/pnv_phb3.c index af8575c007..9054c393a2 100644 --- a/hw/pci-host/pnv_phb3.c +++ b/hw/pci-host/pnv_phb3.c @@ -1169,6 +1169,7 @@ static void pnv_phb3_root_bus_class_init(ObjectClass *klass, void *data) static const TypeInfo pnv_phb3_root_bus_info = { .name = TYPE_PNV_PHB3_ROOT_BUS, .parent = TYPE_PCIE_BUS, + .instance_size = sizeof(PnvPHB3RootBus), .class_init = pnv_phb3_root_bus_class_init, }; diff --git a/hw/pci-host/pnv_phb4.c b/hw/pci-host/pnv_phb4.c index 824e1a73fb..ccbde841fc 100644 --- a/hw/pci-host/pnv_phb4.c +++ b/hw/pci-host/pnv_phb4.c @@ -1773,6 +1773,7 @@ static void pnv_phb4_root_bus_class_init(ObjectClass *klass, void *data) static const TypeInfo pnv_phb4_root_bus_info = { .name = TYPE_PNV_PHB4_ROOT_BUS, .parent = TYPE_PCIE_BUS, + .instance_size = sizeof(PnvPHB4RootBus), .class_init = pnv_phb4_root_bus_class_init, }; From 6b5cf264ee76d24b357a60b69b0635a533c1f647 Mon Sep 17 00:00:00 2001 From: Bernhard Beschow Date: Tue, 20 Sep 2022 01:17:15 +0200 Subject: [PATCH 17/17] hw/ppc/spapr: Fix code style problems reported by checkpatch Reviewed-by: Daniel Henrique Barboza Signed-off-by: Bernhard Beschow Message-Id: <20220919231720.163121-5-shentey@gmail.com> Signed-off-by: Daniel Henrique Barboza --- include/hw/ppc/spapr.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h index 530d739b1d..04a95669ab 100644 --- a/include/hw/ppc/spapr.h +++ b/include/hw/ppc/spapr.h @@ -848,7 +848,8 @@ static inline uint64_t ppc64_phys_to_real(uint64_t addr) static inline uint32_t rtas_ld(target_ulong phys, int n) { - return ldl_be_phys(&address_space_memory, ppc64_phys_to_real(phys + 4*n)); + return ldl_be_phys(&address_space_memory, + ppc64_phys_to_real(phys + 4 * n)); } static inline uint64_t rtas_ldq(target_ulong phys, int n) @@ -858,7 +859,7 @@ static inline uint64_t rtas_ldq(target_ulong phys, int n) static inline void rtas_st(target_ulong phys, int n, uint32_t val) { - stl_be_phys(&address_space_memory, ppc64_phys_to_real(phys + 4*n), val); + stl_be_phys(&address_space_memory, ppc64_phys_to_real(phys + 4 * n), val); } typedef void (*spapr_rtas_fn)(PowerPCCPU *cpu, SpaprMachineState *sm,