This patch adds the Floating Point Test for Square Root instruction which was introduced in Power ISA 2.06.
Signed-off-by: Tom Musta <tommu...@gmail.com> --- target-ppc/fpu_helper.c | 31 +++++++++++++++++++++++++++++++ target-ppc/helper.h | 1 + target-ppc/translate.c | 14 ++++++++++++++ 3 files changed, 46 insertions(+), 0 deletions(-) diff --git a/target-ppc/fpu_helper.c b/target-ppc/fpu_helper.c index 82ff0db..d5eb4ef 100644 --- a/target-ppc/fpu_helper.c +++ b/target-ppc/fpu_helper.c @@ -1034,6 +1034,37 @@ void helper_ftdiv(CPUPPCState *env, uint32_t bf, uint64_t fra, uint64_t frb) env->crf[bf] = 0x8 | (fg_flag ? 4 : 0) | (fe_flag ? 2 : 0); } +void helper_ftsqrt(CPUPPCState *env, uint32_t bf, uint64_t frb) +{ + int fe_flag = 0; + int fg_flag = 0; + + if (unlikely(float64_is_infinity(frb) || float64_is_zero(frb))) { + fe_flag = 1; + fg_flag = 1; + } else { + int e_b = ppc_float64_get_unbiased_exp(frb); + + if (unlikely(float64_is_any_nan(frb))) { + fe_flag = 1; + } else if (unlikely(float64_is_zero(frb))) { + fe_flag = 1; + } else if (unlikely(float64_is_neg(frb))) { + fe_flag = 1; + } else if (!float64_is_zero(frb) && (e_b <= (-1022+52))) { + fe_flag = 1; + } + + if (unlikely(float64_is_zero_or_denormal(frb))) { + /* XB is not zero because of the above check and */ + /* therefore must be denormalized. */ + fg_flag = 1; + } + } + + env->crf[bf] = 0x8 | (fg_flag ? 4 : 0) | (fe_flag ? 2 : 0); +} + void helper_fcmpu(CPUPPCState *env, uint64_t arg1, uint64_t arg2, uint32_t crfD) { diff --git a/target-ppc/helper.h b/target-ppc/helper.h index 5f5d3f6..ccf5711 100644 --- a/target-ppc/helper.h +++ b/target-ppc/helper.h @@ -98,6 +98,7 @@ DEF_HELPER_2(frsqrte, i64, env, i64) DEF_HELPER_4(fsel, i64, env, i64, i64, i64) DEF_HELPER_4(ftdiv, void, env, i32, i64, i64) +DEF_HELPER_3(ftsqrt, void, env, i32, i64) #define dh_alias_avr ptr #define dh_ctype_avr ppc_avr_t * diff --git a/target-ppc/translate.c b/target-ppc/translate.c index 403e274..0833606 100644 --- a/target-ppc/translate.c +++ b/target-ppc/translate.c @@ -2313,6 +2313,19 @@ static void gen_ftdiv(DisasContext *ctx) cpu_fpr[rB(ctx->opcode)]); } +static void gen_ftsqrt(DisasContext *ctx) +{ + TCGv_i32 bf; + if (unlikely(!ctx->fpu_enabled)) { + gen_exception(ctx, POWERPC_EXCP_FPU); + return; + } + /* NIP cannot be restored if the memory exception comes from an helper */ + gen_update_nip(ctx, ctx->nip - 4); + bf = tcg_const_i32(crfD(ctx->opcode)); + gen_helper_ftsqrt(cpu_env, bf, cpu_fpr[rB(ctx->opcode)]); +} + /*** Floating-Point compare ***/ @@ -9818,6 +9831,7 @@ GEN_FLOAT_ACB(msub, 0x1C, 1, PPC_FLOAT), GEN_FLOAT_ACB(nmadd, 0x1F, 1, PPC_FLOAT), GEN_FLOAT_ACB(nmsub, 0x1E, 1, PPC_FLOAT), GEN_HANDLER_E(ftdiv, 0x3F, 0x00, 0x04, 1, PPC_NONE, PPC2_ISA206), +GEN_HANDLER_E(ftsqrt, 0x3F, 0x00, 0x05, 1, PPC_NONE, PPC2_ISA206), GEN_FLOAT_B(ctiw, 0x0E, 0x00, 0, PPC_FLOAT), GEN_HANDLER_E(fctiwu, 0x3F, 0x0E, 0x04, 0x00000000, PPC_NONE, PPC2_ISA206), GEN_FLOAT_B(ctiwz, 0x0F, 0x00, 0, PPC_FLOAT), -- 1.7.1