Commit 8e703949 authored by Blue Swirl's avatar Blue Swirl Committed by Alexander Graf
Browse files

ppc: Avoid AREG0 for FPU and SPE helpers



Add an explicit CPUPPCState parameter instead of relying on AREG0.

Signed-off-by: default avatarBlue Swirl <blauwirbel@gmail.com>
Signed-off-by: default avatarAlexander Graf <agraf@suse.de>
Signed-off-by: default avatarAndreas Färber <afaerber@suse.de>
Signed-off-by: default avatarAlexander Graf <agraf@suse.de>
parent bd23cd45
Loading
Loading
Loading
Loading
+0 −1
Original line number Diff line number Diff line
@@ -5,5 +5,4 @@ obj-y += op_helper.o helper.o
obj-y += excp_helper.o
obj-y += fpu_helper.o

$(obj)/fpu_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS)
$(obj)/op_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS)
+179 −171

File changed.

Preview size limit exceeded, changes collapsed.

+102 −102
Original line number Diff line number Diff line
@@ -50,47 +50,47 @@ DEF_HELPER_FLAGS_1(cntlsw32, TCG_CALL_CONST | TCG_CALL_PURE, i32, i32)
DEF_HELPER_FLAGS_1(cntlzw32, TCG_CALL_CONST | TCG_CALL_PURE, i32, i32)
DEF_HELPER_FLAGS_2(brinc, TCG_CALL_CONST | TCG_CALL_PURE, tl, tl, tl)

DEF_HELPER_0(float_check_status, void)
DEF_HELPER_0(reset_fpstatus, void)
DEF_HELPER_2(compute_fprf, i32, i64, i32)
DEF_HELPER_2(store_fpscr, void, i64, i32)
DEF_HELPER_1(fpscr_clrbit, void, i32)
DEF_HELPER_1(fpscr_setbit, void, i32)
DEF_HELPER_1(float64_to_float32, i32, i64)
DEF_HELPER_1(float32_to_float64, i64, i32)
DEF_HELPER_1(float_check_status, void, env)
DEF_HELPER_1(reset_fpstatus, void, env)
DEF_HELPER_3(compute_fprf, i32, env, i64, i32)
DEF_HELPER_3(store_fpscr, void, env, i64, i32)
DEF_HELPER_2(fpscr_clrbit, void, env, i32)
DEF_HELPER_2(fpscr_setbit, void, env, i32)
DEF_HELPER_2(float64_to_float32, i32, env, i64)
DEF_HELPER_2(float32_to_float64, i64, env, i32)

DEF_HELPER_3(fcmpo, void, i64, i64, i32)
DEF_HELPER_3(fcmpu, void, i64, i64, i32)
DEF_HELPER_4(fcmpo, void, env, i64, i64, i32)
DEF_HELPER_4(fcmpu, void, env, i64, i64, i32)

DEF_HELPER_1(fctiw, i64, i64)
DEF_HELPER_1(fctiwz, i64, i64)
DEF_HELPER_2(fctiw, i64, env, i64)
DEF_HELPER_2(fctiwz, i64, env, i64)
#if defined(TARGET_PPC64)
DEF_HELPER_1(fcfid, i64, i64)
DEF_HELPER_1(fctid, i64, i64)
DEF_HELPER_1(fctidz, i64, i64)
DEF_HELPER_2(fcfid, i64, env, i64)
DEF_HELPER_2(fctid, i64, env, i64)
DEF_HELPER_2(fctidz, i64, env, i64)
#endif
DEF_HELPER_1(frsp, i64, i64)
DEF_HELPER_1(frin, i64, i64)
DEF_HELPER_1(friz, i64, i64)
DEF_HELPER_1(frip, i64, i64)
DEF_HELPER_1(frim, i64, i64)
DEF_HELPER_2(frsp, i64, env, i64)
DEF_HELPER_2(frin, i64, env, i64)
DEF_HELPER_2(friz, i64, env, i64)
DEF_HELPER_2(frip, i64, env, i64)
DEF_HELPER_2(frim, i64, env, i64)

DEF_HELPER_2(fadd, i64, i64, i64)
DEF_HELPER_2(fsub, i64, i64, i64)
DEF_HELPER_2(fmul, i64, i64, i64)
DEF_HELPER_2(fdiv, i64, i64, i64)
DEF_HELPER_3(fmadd, i64, i64, i64, i64)
DEF_HELPER_3(fmsub, i64, i64, i64, i64)
DEF_HELPER_3(fnmadd, i64, i64, i64, i64)
DEF_HELPER_3(fnmsub, i64, i64, i64, i64)
DEF_HELPER_1(fabs, i64, i64)
DEF_HELPER_1(fnabs, i64, i64)
DEF_HELPER_1(fneg, i64, i64)
DEF_HELPER_1(fsqrt, i64, i64)
DEF_HELPER_1(fre, i64, i64)
DEF_HELPER_1(fres, i64, i64)
DEF_HELPER_1(frsqrte, i64, i64)
DEF_HELPER_3(fsel, i64, i64, i64, i64)
DEF_HELPER_3(fadd, i64, env, i64, i64)
DEF_HELPER_3(fsub, i64, env, i64, i64)
DEF_HELPER_3(fmul, i64, env, i64, i64)
DEF_HELPER_3(fdiv, i64, env, i64, i64)
DEF_HELPER_4(fmadd, i64, env, i64, i64, i64)
DEF_HELPER_4(fmsub, i64, env, i64, i64, i64)
DEF_HELPER_4(fnmadd, i64, env, i64, i64, i64)
DEF_HELPER_4(fnmsub, i64, env, i64, i64, i64)
DEF_HELPER_2(fabs, i64, env, i64)
DEF_HELPER_2(fnabs, i64, env, i64)
DEF_HELPER_2(fneg, i64, env, i64)
DEF_HELPER_2(fsqrt, i64, env, i64)
DEF_HELPER_2(fre, i64, env, i64)
DEF_HELPER_2(fres, i64, env, i64)
DEF_HELPER_2(frsqrte, i64, env, i64)
DEF_HELPER_4(fsel, i64, env, i64, i64, i64)

#define dh_alias_avr ptr
#define dh_ctype_avr ppc_avr_t *
@@ -256,72 +256,72 @@ DEF_HELPER_3(vcfsx, void, avr, avr, i32)
DEF_HELPER_3(vctuxs, void, avr, avr, i32)
DEF_HELPER_3(vctsxs, void, avr, avr, i32)

DEF_HELPER_1(efscfsi, i32, i32)
DEF_HELPER_1(efscfui, i32, i32)
DEF_HELPER_1(efscfuf, i32, i32)
DEF_HELPER_1(efscfsf, i32, i32)
DEF_HELPER_1(efsctsi, i32, i32)
DEF_HELPER_1(efsctui, i32, i32)
DEF_HELPER_1(efsctsiz, i32, i32)
DEF_HELPER_1(efsctuiz, i32, i32)
DEF_HELPER_1(efsctsf, i32, i32)
DEF_HELPER_1(efsctuf, i32, i32)
DEF_HELPER_1(evfscfsi, i64, i64)
DEF_HELPER_1(evfscfui, i64, i64)
DEF_HELPER_1(evfscfuf, i64, i64)
DEF_HELPER_1(evfscfsf, i64, i64)
DEF_HELPER_1(evfsctsi, i64, i64)
DEF_HELPER_1(evfsctui, i64, i64)
DEF_HELPER_1(evfsctsiz, i64, i64)
DEF_HELPER_1(evfsctuiz, i64, i64)
DEF_HELPER_1(evfsctsf, i64, i64)
DEF_HELPER_1(evfsctuf, i64, i64)
DEF_HELPER_2(efsadd, i32, i32, i32)
DEF_HELPER_2(efssub, i32, i32, i32)
DEF_HELPER_2(efsmul, i32, i32, i32)
DEF_HELPER_2(efsdiv, i32, i32, i32)
DEF_HELPER_2(evfsadd, i64, i64, i64)
DEF_HELPER_2(evfssub, i64, i64, i64)
DEF_HELPER_2(evfsmul, i64, i64, i64)
DEF_HELPER_2(evfsdiv, i64, i64, i64)
DEF_HELPER_2(efststlt, i32, i32, i32)
DEF_HELPER_2(efststgt, i32, i32, i32)
DEF_HELPER_2(efststeq, i32, i32, i32)
DEF_HELPER_2(efscmplt, i32, i32, i32)
DEF_HELPER_2(efscmpgt, i32, i32, i32)
DEF_HELPER_2(efscmpeq, i32, i32, i32)
DEF_HELPER_2(evfststlt, i32, i64, i64)
DEF_HELPER_2(evfststgt, i32, i64, i64)
DEF_HELPER_2(evfststeq, i32, i64, i64)
DEF_HELPER_2(evfscmplt, i32, i64, i64)
DEF_HELPER_2(evfscmpgt, i32, i64, i64)
DEF_HELPER_2(evfscmpeq, i32, i64, i64)
DEF_HELPER_1(efdcfsi, i64, i32)
DEF_HELPER_1(efdcfsid, i64, i64)
DEF_HELPER_1(efdcfui, i64, i32)
DEF_HELPER_1(efdcfuid, i64, i64)
DEF_HELPER_1(efdctsi, i32, i64)
DEF_HELPER_1(efdctui, i32, i64)
DEF_HELPER_1(efdctsiz, i32, i64)
DEF_HELPER_1(efdctsidz, i64, i64)
DEF_HELPER_1(efdctuiz, i32, i64)
DEF_HELPER_1(efdctuidz, i64, i64)
DEF_HELPER_1(efdcfsf, i64, i32)
DEF_HELPER_1(efdcfuf, i64, i32)
DEF_HELPER_1(efdctsf, i32, i64)
DEF_HELPER_1(efdctuf, i32, i64)
DEF_HELPER_1(efscfd, i32, i64)
DEF_HELPER_1(efdcfs, i64, i32)
DEF_HELPER_2(efdadd, i64, i64, i64)
DEF_HELPER_2(efdsub, i64, i64, i64)
DEF_HELPER_2(efdmul, i64, i64, i64)
DEF_HELPER_2(efddiv, i64, i64, i64)
DEF_HELPER_2(efdtstlt, i32, i64, i64)
DEF_HELPER_2(efdtstgt, i32, i64, i64)
DEF_HELPER_2(efdtsteq, i32, i64, i64)
DEF_HELPER_2(efdcmplt, i32, i64, i64)
DEF_HELPER_2(efdcmpgt, i32, i64, i64)
DEF_HELPER_2(efdcmpeq, i32, i64, i64)
DEF_HELPER_2(efscfsi, i32, env, i32)
DEF_HELPER_2(efscfui, i32, env, i32)
DEF_HELPER_2(efscfuf, i32, env, i32)
DEF_HELPER_2(efscfsf, i32, env, i32)
DEF_HELPER_2(efsctsi, i32, env, i32)
DEF_HELPER_2(efsctui, i32, env, i32)
DEF_HELPER_2(efsctsiz, i32, env, i32)
DEF_HELPER_2(efsctuiz, i32, env, i32)
DEF_HELPER_2(efsctsf, i32, env, i32)
DEF_HELPER_2(efsctuf, i32, env, i32)
DEF_HELPER_2(evfscfsi, i64, env, i64)
DEF_HELPER_2(evfscfui, i64, env, i64)
DEF_HELPER_2(evfscfuf, i64, env, i64)
DEF_HELPER_2(evfscfsf, i64, env, i64)
DEF_HELPER_2(evfsctsi, i64, env, i64)
DEF_HELPER_2(evfsctui, i64, env, i64)
DEF_HELPER_2(evfsctsiz, i64, env, i64)
DEF_HELPER_2(evfsctuiz, i64, env, i64)
DEF_HELPER_2(evfsctsf, i64, env, i64)
DEF_HELPER_2(evfsctuf, i64, env, i64)
DEF_HELPER_3(efsadd, i32, env, i32, i32)
DEF_HELPER_3(efssub, i32, env, i32, i32)
DEF_HELPER_3(efsmul, i32, env, i32, i32)
DEF_HELPER_3(efsdiv, i32, env, i32, i32)
DEF_HELPER_3(evfsadd, i64, env, i64, i64)
DEF_HELPER_3(evfssub, i64, env, i64, i64)
DEF_HELPER_3(evfsmul, i64, env, i64, i64)
DEF_HELPER_3(evfsdiv, i64, env, i64, i64)
DEF_HELPER_3(efststlt, i32, env, i32, i32)
DEF_HELPER_3(efststgt, i32, env, i32, i32)
DEF_HELPER_3(efststeq, i32, env, i32, i32)
DEF_HELPER_3(efscmplt, i32, env, i32, i32)
DEF_HELPER_3(efscmpgt, i32, env, i32, i32)
DEF_HELPER_3(efscmpeq, i32, env, i32, i32)
DEF_HELPER_3(evfststlt, i32, env, i64, i64)
DEF_HELPER_3(evfststgt, i32, env, i64, i64)
DEF_HELPER_3(evfststeq, i32, env, i64, i64)
DEF_HELPER_3(evfscmplt, i32, env, i64, i64)
DEF_HELPER_3(evfscmpgt, i32, env, i64, i64)
DEF_HELPER_3(evfscmpeq, i32, env, i64, i64)
DEF_HELPER_2(efdcfsi, i64, env, i32)
DEF_HELPER_2(efdcfsid, i64, env, i64)
DEF_HELPER_2(efdcfui, i64, env, i32)
DEF_HELPER_2(efdcfuid, i64, env, i64)
DEF_HELPER_2(efdctsi, i32, env, i64)
DEF_HELPER_2(efdctui, i32, env, i64)
DEF_HELPER_2(efdctsiz, i32, env, i64)
DEF_HELPER_2(efdctsidz, i64, env, i64)
DEF_HELPER_2(efdctuiz, i32, env, i64)
DEF_HELPER_2(efdctuidz, i64, env, i64)
DEF_HELPER_2(efdcfsf, i64, env, i32)
DEF_HELPER_2(efdcfuf, i64, env, i32)
DEF_HELPER_2(efdctsf, i32, env, i64)
DEF_HELPER_2(efdctuf, i32, env, i64)
DEF_HELPER_2(efscfd, i32, env, i64)
DEF_HELPER_2(efdcfs, i64, env, i32)
DEF_HELPER_3(efdadd, i64, env, i64, i64)
DEF_HELPER_3(efdsub, i64, env, i64, i64)
DEF_HELPER_3(efdmul, i64, env, i64, i64)
DEF_HELPER_3(efddiv, i64, env, i64, i64)
DEF_HELPER_3(efdtstlt, i32, env, i64, i64)
DEF_HELPER_3(efdtstgt, i32, env, i64, i64)
DEF_HELPER_3(efdtsteq, i32, env, i64, i64)
DEF_HELPER_3(efdcmplt, i32, env, i64, i64)
DEF_HELPER_3(efdcmpgt, i32, env, i64, i64)
DEF_HELPER_3(efdcmpeq, i32, env, i64, i64)

#if !defined(CONFIG_USER_ONLY)
DEF_HELPER_1(4xx_tlbre_hi, tl, tl)
+65 −48
Original line number Diff line number Diff line
@@ -219,7 +219,7 @@ struct opc_handler_t {

static inline void gen_reset_fpstatus(void)
{
    gen_helper_reset_fpstatus();
    gen_helper_reset_fpstatus(cpu_env);
}

static inline void gen_compute_fprf(TCGv_i64 arg, int set_fprf, int set_rc)
@@ -229,15 +229,15 @@ static inline void gen_compute_fprf(TCGv_i64 arg, int set_fprf, int set_rc)
    if (set_fprf != 0) {
        /* This case might be optimized later */
        tcg_gen_movi_i32(t0, 1);
        gen_helper_compute_fprf(t0, arg, t0);
        gen_helper_compute_fprf(t0, cpu_env, arg, t0);
        if (unlikely(set_rc)) {
            tcg_gen_mov_i32(cpu_crf[1], t0);
        }
        gen_helper_float_check_status();
        gen_helper_float_check_status(cpu_env);
    } else if (unlikely(set_rc)) {
        /* We always need to compute fpcc */
        tcg_gen_movi_i32(t0, 0);
        gen_helper_compute_fprf(t0, arg, t0);
        gen_helper_compute_fprf(t0, cpu_env, arg, t0);
        tcg_gen_mov_i32(cpu_crf[1], t0);
    }

@@ -2027,10 +2027,12 @@ static void gen_f##name(DisasContext *ctx) \
    /* NIP cannot be restored if the memory exception comes from an helper */ \
    gen_update_nip(ctx, ctx->nip - 4);                                        \
    gen_reset_fpstatus();                                                     \
    gen_helper_f##op(cpu_fpr[rD(ctx->opcode)], cpu_fpr[rA(ctx->opcode)],      \
    gen_helper_f##op(cpu_fpr[rD(ctx->opcode)], cpu_env,                       \
                     cpu_fpr[rA(ctx->opcode)],                                \
                     cpu_fpr[rC(ctx->opcode)], cpu_fpr[rB(ctx->opcode)]);     \
    if (isfloat) {                                                            \
        gen_helper_frsp(cpu_fpr[rD(ctx->opcode)], cpu_fpr[rD(ctx->opcode)]);  \
        gen_helper_frsp(cpu_fpr[rD(ctx->opcode)], cpu_env,                    \
                        cpu_fpr[rD(ctx->opcode)]);                            \
    }                                                                         \
    gen_compute_fprf(cpu_fpr[rD(ctx->opcode)], set_fprf,                      \
                     Rc(ctx->opcode) != 0);                                   \
@@ -2050,10 +2052,12 @@ static void gen_f##name(DisasContext *ctx) \
    /* NIP cannot be restored if the memory exception comes from an helper */ \
    gen_update_nip(ctx, ctx->nip - 4);                                        \
    gen_reset_fpstatus();                                                     \
    gen_helper_f##op(cpu_fpr[rD(ctx->opcode)], cpu_fpr[rA(ctx->opcode)],      \
    gen_helper_f##op(cpu_fpr[rD(ctx->opcode)], cpu_env,                       \
                     cpu_fpr[rA(ctx->opcode)],                                \
                     cpu_fpr[rB(ctx->opcode)]);                               \
    if (isfloat) {                                                            \
        gen_helper_frsp(cpu_fpr[rD(ctx->opcode)], cpu_fpr[rD(ctx->opcode)]);  \
        gen_helper_frsp(cpu_fpr[rD(ctx->opcode)], cpu_env,                    \
                        cpu_fpr[rD(ctx->opcode)]);                            \
    }                                                                         \
    gen_compute_fprf(cpu_fpr[rD(ctx->opcode)],                                \
                     set_fprf, Rc(ctx->opcode) != 0);                         \
@@ -2072,10 +2076,12 @@ static void gen_f##name(DisasContext *ctx) \
    /* NIP cannot be restored if the memory exception comes from an helper */ \
    gen_update_nip(ctx, ctx->nip - 4);                                        \
    gen_reset_fpstatus();                                                     \
    gen_helper_f##op(cpu_fpr[rD(ctx->opcode)], cpu_fpr[rA(ctx->opcode)],      \
    gen_helper_f##op(cpu_fpr[rD(ctx->opcode)], cpu_env,                       \
                     cpu_fpr[rA(ctx->opcode)],                                \
                     cpu_fpr[rC(ctx->opcode)]);                               \
    if (isfloat) {                                                            \
        gen_helper_frsp(cpu_fpr[rD(ctx->opcode)], cpu_fpr[rD(ctx->opcode)]);  \
        gen_helper_frsp(cpu_fpr[rD(ctx->opcode)], cpu_env,                    \
                        cpu_fpr[rD(ctx->opcode)]);                            \
    }                                                                         \
    gen_compute_fprf(cpu_fpr[rD(ctx->opcode)],                                \
                     set_fprf, Rc(ctx->opcode) != 0);                         \
@@ -2094,7 +2100,8 @@ static void gen_f##name(DisasContext *ctx) \
    /* NIP cannot be restored if the memory exception comes from an helper */ \
    gen_update_nip(ctx, ctx->nip - 4);                                        \
    gen_reset_fpstatus();                                                     \
    gen_helper_f##name(cpu_fpr[rD(ctx->opcode)], cpu_fpr[rB(ctx->opcode)]);   \
    gen_helper_f##name(cpu_fpr[rD(ctx->opcode)], cpu_env,                     \
                       cpu_fpr[rB(ctx->opcode)]);                             \
    gen_compute_fprf(cpu_fpr[rD(ctx->opcode)],                                \
                     set_fprf, Rc(ctx->opcode) != 0);                         \
}
@@ -2109,7 +2116,8 @@ static void gen_f##name(DisasContext *ctx) \
    /* NIP cannot be restored if the memory exception comes from an helper */ \
    gen_update_nip(ctx, ctx->nip - 4);                                        \
    gen_reset_fpstatus();                                                     \
    gen_helper_f##name(cpu_fpr[rD(ctx->opcode)], cpu_fpr[rB(ctx->opcode)]);   \
    gen_helper_f##name(cpu_fpr[rD(ctx->opcode)], cpu_env,                     \
                       cpu_fpr[rB(ctx->opcode)]);                             \
    gen_compute_fprf(cpu_fpr[rD(ctx->opcode)],                                \
                     set_fprf, Rc(ctx->opcode) != 0);                         \
}
@@ -2140,8 +2148,10 @@ static void gen_frsqrtes(DisasContext *ctx)
    /* NIP cannot be restored if the memory exception comes from an helper */
    gen_update_nip(ctx, ctx->nip - 4);
    gen_reset_fpstatus();
    gen_helper_frsqrte(cpu_fpr[rD(ctx->opcode)], cpu_fpr[rB(ctx->opcode)]);
    gen_helper_frsp(cpu_fpr[rD(ctx->opcode)], cpu_fpr[rD(ctx->opcode)]);
    gen_helper_frsqrte(cpu_fpr[rD(ctx->opcode)], cpu_env,
                       cpu_fpr[rB(ctx->opcode)]);
    gen_helper_frsp(cpu_fpr[rD(ctx->opcode)], cpu_env,
                    cpu_fpr[rD(ctx->opcode)]);
    gen_compute_fprf(cpu_fpr[rD(ctx->opcode)], 1, Rc(ctx->opcode) != 0);
}

@@ -2161,7 +2171,8 @@ static void gen_fsqrt(DisasContext *ctx)
    /* NIP cannot be restored if the memory exception comes from an helper */
    gen_update_nip(ctx, ctx->nip - 4);
    gen_reset_fpstatus();
    gen_helper_fsqrt(cpu_fpr[rD(ctx->opcode)], cpu_fpr[rB(ctx->opcode)]);
    gen_helper_fsqrt(cpu_fpr[rD(ctx->opcode)], cpu_env,
                     cpu_fpr[rB(ctx->opcode)]);
    gen_compute_fprf(cpu_fpr[rD(ctx->opcode)], 1, Rc(ctx->opcode) != 0);
}

@@ -2174,8 +2185,10 @@ static void gen_fsqrts(DisasContext *ctx)
    /* NIP cannot be restored if the memory exception comes from an helper */
    gen_update_nip(ctx, ctx->nip - 4);
    gen_reset_fpstatus();
    gen_helper_fsqrt(cpu_fpr[rD(ctx->opcode)], cpu_fpr[rB(ctx->opcode)]);
    gen_helper_frsp(cpu_fpr[rD(ctx->opcode)], cpu_fpr[rD(ctx->opcode)]);
    gen_helper_fsqrt(cpu_fpr[rD(ctx->opcode)], cpu_env,
                     cpu_fpr[rB(ctx->opcode)]);
    gen_helper_frsp(cpu_fpr[rD(ctx->opcode)], cpu_env,
                    cpu_fpr[rD(ctx->opcode)]);
    gen_compute_fprf(cpu_fpr[rD(ctx->opcode)], 1, Rc(ctx->opcode) != 0);
}

@@ -2228,9 +2241,10 @@ static void gen_fcmpo(DisasContext *ctx)
    gen_update_nip(ctx, ctx->nip - 4);
    gen_reset_fpstatus();
    crf = tcg_const_i32(crfD(ctx->opcode));
    gen_helper_fcmpo(cpu_fpr[rA(ctx->opcode)], cpu_fpr[rB(ctx->opcode)], crf);
    gen_helper_fcmpo(cpu_env, cpu_fpr[rA(ctx->opcode)],
                     cpu_fpr[rB(ctx->opcode)], crf);
    tcg_temp_free_i32(crf);
    gen_helper_float_check_status();
    gen_helper_float_check_status(cpu_env);
}

/* fcmpu */
@@ -2245,9 +2259,10 @@ static void gen_fcmpu(DisasContext *ctx)
    gen_update_nip(ctx, ctx->nip - 4);
    gen_reset_fpstatus();
    crf = tcg_const_i32(crfD(ctx->opcode));
    gen_helper_fcmpu(cpu_fpr[rA(ctx->opcode)], cpu_fpr[rB(ctx->opcode)], crf);
    gen_helper_fcmpu(cpu_env, cpu_fpr[rA(ctx->opcode)],
                     cpu_fpr[rB(ctx->opcode)], crf);
    tcg_temp_free_i32(crf);
    gen_helper_float_check_status();
    gen_helper_float_check_status(cpu_env);
}

/***                         Floating-point move                           ***/
@@ -2319,7 +2334,7 @@ static void gen_mtfsb0(DisasContext *ctx)
        /* NIP cannot be restored if the memory exception comes from an helper */
        gen_update_nip(ctx, ctx->nip - 4);
        t0 = tcg_const_i32(crb);
        gen_helper_fpscr_clrbit(t0);
        gen_helper_fpscr_clrbit(cpu_env, t0);
        tcg_temp_free_i32(t0);
    }
    if (unlikely(Rc(ctx->opcode) != 0)) {
@@ -2344,14 +2359,14 @@ static void gen_mtfsb1(DisasContext *ctx)
        /* NIP cannot be restored if the memory exception comes from an helper */
        gen_update_nip(ctx, ctx->nip - 4);
        t0 = tcg_const_i32(crb);
        gen_helper_fpscr_setbit(t0);
        gen_helper_fpscr_setbit(cpu_env, t0);
        tcg_temp_free_i32(t0);
    }
    if (unlikely(Rc(ctx->opcode) != 0)) {
        tcg_gen_shri_i32(cpu_crf[1], cpu_fpscr, FPSCR_OX);
    }
    /* We can raise a differed exception */
    gen_helper_float_check_status();
    gen_helper_float_check_status(cpu_env);
}

/* mtfsf */
@@ -2371,13 +2386,13 @@ static void gen_mtfsf(DisasContext *ctx)
        t0 = tcg_const_i32(0xff);
    else
        t0 = tcg_const_i32(FM(ctx->opcode));
    gen_helper_store_fpscr(cpu_fpr[rB(ctx->opcode)], t0);
    gen_helper_store_fpscr(cpu_env, cpu_fpr[rB(ctx->opcode)], t0);
    tcg_temp_free_i32(t0);
    if (unlikely(Rc(ctx->opcode) != 0)) {
        tcg_gen_shri_i32(cpu_crf[1], cpu_fpscr, FPSCR_OX);
    }
    /* We can raise a differed exception */
    gen_helper_float_check_status();
    gen_helper_float_check_status(cpu_env);
}

/* mtfsfi */
@@ -2398,14 +2413,14 @@ static void gen_mtfsfi(DisasContext *ctx)
    gen_reset_fpstatus();
    t0 = tcg_const_i64(FPIMM(ctx->opcode) << (4 * sh));
    t1 = tcg_const_i32(1 << sh);
    gen_helper_store_fpscr(t0, t1);
    gen_helper_store_fpscr(cpu_env, t0, t1);
    tcg_temp_free_i64(t0);
    tcg_temp_free_i32(t1);
    if (unlikely(Rc(ctx->opcode) != 0)) {
        tcg_gen_shri_i32(cpu_crf[1], cpu_fpscr, FPSCR_OX);
    }
    /* We can raise a differed exception */
    gen_helper_float_check_status();
    gen_helper_float_check_status(cpu_env);
}

/***                           Addressing modes                            ***/
@@ -3303,7 +3318,7 @@ static inline void gen_qemu_ld32fs(DisasContext *ctx, TCGv_i64 arg1, TCGv arg2)
    gen_qemu_ld32u(ctx, t0, arg2);
    tcg_gen_trunc_tl_i32(t1, t0);
    tcg_temp_free(t0);
    gen_helper_float32_to_float64(arg1, t1);
    gen_helper_float32_to_float64(arg1, cpu_env, t1);
    tcg_temp_free_i32(t1);
}

@@ -3393,7 +3408,7 @@ static inline void gen_qemu_st32fs(DisasContext *ctx, TCGv_i64 arg1, TCGv arg2)
{
    TCGv_i32 t0 = tcg_temp_new_i32();
    TCGv t1 = tcg_temp_new();
    gen_helper_float64_to_float32(t0, arg1);
    gen_helper_float64_to_float32(t0, cpu_env, arg1);
    tcg_gen_extu_i32_tl(t1, t0);
    tcg_temp_free_i32(t0);
    gen_qemu_st32(ctx, t1, arg2);
@@ -8010,7 +8025,7 @@ static inline void gen_##name(DisasContext *ctx) \
    TCGv t1;                                                                  \
    t0 = tcg_temp_new_i32();                                                  \
    tcg_gen_trunc_tl_i32(t0, cpu_gpr[rB(ctx->opcode)]);                       \
    gen_helper_##name(t0, t0);                                                \
    gen_helper_##name(t0, cpu_env, t0);                                       \
    t1 = tcg_temp_new();                                                      \
    tcg_gen_extu_i32_tl(t1, t0);                                              \
    tcg_temp_free_i32(t0);                                                    \
@@ -8025,7 +8040,7 @@ static inline void gen_##name(DisasContext *ctx) \
    TCGv_i32 t0;                                                              \
    TCGv t1;                                                                  \
    t0 = tcg_temp_new_i32();                                                  \
    gen_helper_##name(t0, cpu_gpr[rB(ctx->opcode)]);                          \
    gen_helper_##name(t0, cpu_env, cpu_gpr[rB(ctx->opcode)]);                 \
    t1 = tcg_temp_new();                                                      \
    tcg_gen_extu_i32_tl(t1, t0);                                              \
    tcg_temp_free_i32(t0);                                                    \
@@ -8039,13 +8054,14 @@ static inline void gen_##name(DisasContext *ctx) \
{                                                                             \
    TCGv_i32 t0 = tcg_temp_new_i32();                                         \
    tcg_gen_trunc_tl_i32(t0, cpu_gpr[rB(ctx->opcode)]);                       \
    gen_helper_##name(cpu_gpr[rD(ctx->opcode)], t0);                          \
    gen_helper_##name(cpu_gpr[rD(ctx->opcode)], cpu_env, t0);                 \
    tcg_temp_free_i32(t0);                                                    \
}
#define GEN_SPEFPUOP_CONV_64_64(name)                                         \
static inline void gen_##name(DisasContext *ctx)                              \
{                                                                             \
    gen_helper_##name(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);    \
    gen_helper_##name(cpu_gpr[rD(ctx->opcode)], cpu_env,                      \
                      cpu_gpr[rB(ctx->opcode)]);                              \
}
#define GEN_SPEFPUOP_ARITH2_32_32(name)                                       \
static inline void gen_##name(DisasContext *ctx)                              \
@@ -8060,7 +8076,7 @@ static inline void gen_##name(DisasContext *ctx) \
    t1 = tcg_temp_new_i32();                                                  \
    tcg_gen_trunc_tl_i32(t0, cpu_gpr[rA(ctx->opcode)]);                       \
    tcg_gen_trunc_tl_i32(t1, cpu_gpr[rB(ctx->opcode)]);                       \
    gen_helper_##name(t0, t0, t1);                                            \
    gen_helper_##name(t0, cpu_env, t0, t1);                                   \
    tcg_temp_free_i32(t1);                                                    \
    t2 = tcg_temp_new();                                                      \
    tcg_gen_extu_i32_tl(t2, t0);                                              \
@@ -8077,8 +8093,8 @@ static inline void gen_##name(DisasContext *ctx) \
        gen_exception(ctx, POWERPC_EXCP_SPEU);                                \
        return;                                                               \
    }                                                                         \
    gen_helper_##name(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)],     \
                      cpu_gpr[rB(ctx->opcode)]);                              \
    gen_helper_##name(cpu_gpr[rD(ctx->opcode)], cpu_env,                      \
                      cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);    \
}
#define GEN_SPEFPUOP_COMP_32(name)                                            \
static inline void gen_##name(DisasContext *ctx)                              \
@@ -8092,7 +8108,7 @@ static inline void gen_##name(DisasContext *ctx) \
    t1 = tcg_temp_new_i32();                                                  \
    tcg_gen_trunc_tl_i32(t0, cpu_gpr[rA(ctx->opcode)]);                       \
    tcg_gen_trunc_tl_i32(t1, cpu_gpr[rB(ctx->opcode)]);                       \
    gen_helper_##name(cpu_crf[crfD(ctx->opcode)], t0, t1);                    \
    gen_helper_##name(cpu_crf[crfD(ctx->opcode)], cpu_env, t0, t1);           \
    tcg_temp_free_i32(t0);                                                    \
    tcg_temp_free_i32(t1);                                                    \
}
@@ -8103,28 +8119,29 @@ static inline void gen_##name(DisasContext *ctx) \
        gen_exception(ctx, POWERPC_EXCP_SPEU);                                \
        return;                                                               \
    }                                                                         \
    gen_helper_##name(cpu_crf[crfD(ctx->opcode)],                             \
    gen_helper_##name(cpu_crf[crfD(ctx->opcode)], cpu_env,                    \
                      cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);    \
}
#else
#define GEN_SPEFPUOP_CONV_32_32(name)                                         \
static inline void gen_##name(DisasContext *ctx)                              \
{                                                                             \
    gen_helper_##name(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);    \
    gen_helper_##name(cpu_gpr[rD(ctx->opcode)], cpu_env,                      \
                      cpu_gpr[rB(ctx->opcode)]);                              \
}
#define GEN_SPEFPUOP_CONV_32_64(name)                                         \
static inline void gen_##name(DisasContext *ctx)                              \
{                                                                             \
    TCGv_i64 t0 = tcg_temp_new_i64();                                         \
    gen_load_gpr64(t0, rB(ctx->opcode));                                      \
    gen_helper_##name(cpu_gpr[rD(ctx->opcode)], t0);                          \
    gen_helper_##name(cpu_gpr[rD(ctx->opcode)], cpu_env, t0);                 \
    tcg_temp_free_i64(t0);                                                    \
}
#define GEN_SPEFPUOP_CONV_64_32(name)                                         \
static inline void gen_##name(DisasContext *ctx)                              \
{                                                                             \
    TCGv_i64 t0 = tcg_temp_new_i64();                                         \
    gen_helper_##name(t0, cpu_gpr[rB(ctx->opcode)]);                          \
    gen_helper_##name(t0, cpu_env, cpu_gpr[rB(ctx->opcode)]);                 \
    gen_store_gpr64(rD(ctx->opcode), t0);                                     \
    tcg_temp_free_i64(t0);                                                    \
}
@@ -8133,7 +8150,7 @@ static inline void gen_##name(DisasContext *ctx) \
{                                                                             \
    TCGv_i64 t0 = tcg_temp_new_i64();                                         \
    gen_load_gpr64(t0, rB(ctx->opcode));                                      \
    gen_helper_##name(t0, t0);                                                \
    gen_helper_##name(t0, cpu_env, t0);                                       \
    gen_store_gpr64(rD(ctx->opcode), t0);                                     \
    tcg_temp_free_i64(t0);                                                    \
}
@@ -8144,7 +8161,7 @@ static inline void gen_##name(DisasContext *ctx) \
        gen_exception(ctx, POWERPC_EXCP_SPEU);                                \
        return;                                                               \
    }                                                                         \
    gen_helper_##name(cpu_gpr[rD(ctx->opcode)],                               \
    gen_helper_##name(cpu_gpr[rD(ctx->opcode)], cpu_env,                      \
                      cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);    \
}
#define GEN_SPEFPUOP_ARITH2_64_64(name)                                       \
@@ -8159,7 +8176,7 @@ static inline void gen_##name(DisasContext *ctx) \
    t1 = tcg_temp_new_i64();                                                  \
    gen_load_gpr64(t0, rA(ctx->opcode));                                      \
    gen_load_gpr64(t1, rB(ctx->opcode));                                      \
    gen_helper_##name(t0, t0, t1);                                            \
    gen_helper_##name(t0, cpu_env, t0, t1);                                   \
    gen_store_gpr64(rD(ctx->opcode), t0);                                     \
    tcg_temp_free_i64(t0);                                                    \
    tcg_temp_free_i64(t1);                                                    \
@@ -8171,7 +8188,7 @@ static inline void gen_##name(DisasContext *ctx) \
        gen_exception(ctx, POWERPC_EXCP_SPEU);                                \
        return;                                                               \
    }                                                                         \
    gen_helper_##name(cpu_crf[crfD(ctx->opcode)],                             \
    gen_helper_##name(cpu_crf[crfD(ctx->opcode)], cpu_env,                    \
                      cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);    \
}
#define GEN_SPEFPUOP_COMP_64(name)                                            \
@@ -8186,7 +8203,7 @@ static inline void gen_##name(DisasContext *ctx) \
    t1 = tcg_temp_new_i64();                                                  \
    gen_load_gpr64(t0, rA(ctx->opcode));                                      \
    gen_load_gpr64(t1, rB(ctx->opcode));                                      \
    gen_helper_##name(cpu_crf[crfD(ctx->opcode)], t0, t1);                    \
    gen_helper_##name(cpu_crf[crfD(ctx->opcode)], cpu_env, t0, t1);           \
    tcg_temp_free_i64(t0);                                                    \
    tcg_temp_free_i64(t1);                                                    \
}