@@ -243,6 +243,19 @@ static void finish_invalid_op_arith(CPUPPCState *env, int op,
243243 finish_invalid_op_excp (env , op , retaddr );
244244}
245245
246+ /* TODO: this is not a 'finish' anymore, find a better name */
247+ static void finish_invalid_op_arith2 (CPUPPCState * env , int op , bool set_fpcc )
248+ {
249+ env -> fpscr &= ~(FP_FR | FP_FI );
250+ if (fpscr_ve == 0 ) {
251+ if (set_fpcc ) {
252+ env -> fpscr &= ~FP_FPCC ;
253+ env -> fpscr |= (FP_C | FP_FU );
254+ }
255+ }
256+ finish_invalid_op_excp2 (env , op );
257+ }
258+
246259/* Signalling NaN */
247260static void float_invalid_op_vxsnan (CPUPPCState * env , uintptr_t retaddr )
248261{
@@ -265,6 +278,13 @@ static void float_invalid_op_vxisi(CPUPPCState *env, bool set_fpcc,
265278 finish_invalid_op_arith (env , POWERPC_EXCP_FP_VXISI , set_fpcc , retaddr );
266279}
267280
281+ /* TODO: Rename this to float_invalid_op_vxisi when conversion is over */
282+ static void float_invalid_op_vxisi2 (CPUPPCState * env , bool set_fpcc )
283+ {
284+ env -> fpscr |= FP_VXISI ;
285+ finish_invalid_op_arith2 (env , POWERPC_EXCP_FP_VXISI , set_fpcc );
286+ }
287+
268288/* Division of infinity by infinity */
269289static void float_invalid_op_vxidi (CPUPPCState * env , bool set_fpcc ,
270290 uintptr_t retaddr )
@@ -289,6 +309,13 @@ static void float_invalid_op_vximz(CPUPPCState *env, bool set_fpcc,
289309 finish_invalid_op_arith (env , POWERPC_EXCP_FP_VXIMZ , set_fpcc , retaddr );
290310}
291311
312+ /* TODO: Rename this to float_invalid_op_vximz when conversion is over */
313+ static void float_invalid_op_vximz2 (CPUPPCState * env , bool set_fpcc )
314+ {
315+ env -> fpscr |= FP_VXIMZ ;
316+ finish_invalid_op_arith2 (env , POWERPC_EXCP_FP_VXIMZ , set_fpcc );
317+ }
318+
292319/* Square root of a negative number */
293320static void float_invalid_op_vxsqrt (CPUPPCState * env , bool set_fpcc ,
294321 uintptr_t retaddr )
@@ -509,6 +536,12 @@ static void finish_fp_operation(CPUPPCState *env, int mask, uintptr_t raddr)
509536 int flags = get_float_exception_flags (& env -> fp_status );
510537
511538 if (flags & float_flag_invalid ) {
539+ if ((mask & FP_VXIMZ ) && (flags & float_flag_invalid_imz )) {
540+ float_invalid_op_vximz2 (env , mask & FP_FPRF );
541+ }
542+ if ((mask & FP_VXISI ) && (flags & float_flag_invalid_isi )) {
543+ float_invalid_op_vxisi2 (env , mask & FP_FPRF );
544+ }
512545 if ((mask & FP_VXSNAN ) && (flags & float_flag_invalid_snan )) {
513546 float_invalid_op_vxsnan2 (env );
514547 }
@@ -2235,9 +2268,8 @@ VSX_TSQRT(xvtsqrtsp, 4, float32, VsrW(i), -126, 23)
22352268 * fld - vsr_t field (VsrD(*) or VsrW(*))
22362269 * maddflgs - flags for the float*muladd routine that control the
22372270 * various forms (madd, msub, nmadd, nmsub)
2238- * sfprf - set FPRF
22392271 */
2240- #define VSX_MADD (op , nels , tp , fld , maddflgs , sfprf ) \
2272+ #define VSX_MADD (op , nels , tp , fld , maddflgs , fpscr_mask ) \
22412273void helper_##op(CPUPPCState *env, ppc_vsr_t *xt, \
22422274 ppc_vsr_t *s1, ppc_vsr_t *s2, ppc_vsr_t *s3) \
22432275{ \
@@ -2252,37 +2284,49 @@ void helper_##op(CPUPPCState *env, ppc_vsr_t *xt, \
22522284 t.fld = tp##_muladd(s1->fld, s3->fld, s2->fld, maddflgs, &tstat); \
22532285 env->fp_status.float_exception_flags |= tstat.float_exception_flags; \
22542286 \
2255- if (unlikely(tstat.float_exception_flags & float_flag_invalid)) { \
2256- float_invalid_op_madd(env, tstat.float_exception_flags, \
2257- sfprf, GETPC()); \
2258- } \
2259- \
2260- if (sfprf) { \
2287+ if (fpscr_mask & FP_FPRF) { \
22612288 helper_compute_fprf_float64(env, t.fld); \
22622289 } \
22632290 } \
2291+ \
22642292 *xt = t; \
2265- do_float_check_status(env, GETPC()); \
2266- }
2267-
2268- VSX_MADD (XSMADDDP , 1 , float64 , VsrD (0 ), MADD_FLGS , 1 )
2269- VSX_MADD (XSMSUBDP , 1 , float64 , VsrD (0 ), MSUB_FLGS , 1 )
2270- VSX_MADD (XSNMADDDP , 1 , float64 , VsrD (0 ), NMADD_FLGS , 1 )
2271- VSX_MADD (XSNMSUBDP , 1 , float64 , VsrD (0 ), NMSUB_FLGS , 1 )
2272- VSX_MADD (XSMADDSP , 1 , float64r32 , VsrD (0 ), MADD_FLGS , 1 )
2273- VSX_MADD (XSMSUBSP , 1 , float64r32 , VsrD (0 ), MSUB_FLGS , 1 )
2274- VSX_MADD (XSNMADDSP , 1 , float64r32 , VsrD (0 ), NMADD_FLGS , 1 )
2275- VSX_MADD (XSNMSUBSP , 1 , float64r32 , VsrD (0 ), NMSUB_FLGS , 1 )
2276-
2277- VSX_MADD (xvmadddp , 2 , float64 , VsrD (i ), MADD_FLGS , 0 )
2278- VSX_MADD (xvmsubdp , 2 , float64 , VsrD (i ), MSUB_FLGS , 0 )
2279- VSX_MADD (xvnmadddp , 2 , float64 , VsrD (i ), NMADD_FLGS , 0 )
2280- VSX_MADD (xvnmsubdp , 2 , float64 , VsrD (i ), NMSUB_FLGS , 0 )
2281-
2282- VSX_MADD (xvmaddsp , 4 , float32 , VsrW (i ), MADD_FLGS , 0 )
2283- VSX_MADD (xvmsubsp , 4 , float32 , VsrW (i ), MSUB_FLGS , 0 )
2284- VSX_MADD (xvnmaddsp , 4 , float32 , VsrW (i ), NMADD_FLGS , 0 )
2285- VSX_MADD (xvnmsubsp , 4 , float32 , VsrW (i ), NMSUB_FLGS , 0 )
2293+ finish_fp_operation(env, fpscr_mask, GETPC()); \
2294+ }
2295+
2296+ VSX_MADD (XSMADDDP , 1 , float64 , VsrD (0 ), MADD_FLGS , \
2297+ (FP_FPRF | FP_VXSNAN | FP_VXISI | FP_VXIMZ | FP_FI | FP_XX | FP_UX | FP_OX ))
2298+ VSX_MADD (XSMSUBDP , 1 , float64 , VsrD (0 ), MSUB_FLGS , \
2299+ (FP_FPRF | FP_VXSNAN | FP_VXISI | FP_VXIMZ | FP_FI | FP_XX | FP_UX | FP_OX ))
2300+ VSX_MADD (XSNMADDDP , 1 , float64 , VsrD (0 ), NMADD_FLGS , \
2301+ (FP_FPRF | FP_VXSNAN | FP_VXISI | FP_VXIMZ | FP_FI | FP_XX | FP_UX | FP_OX ))
2302+ VSX_MADD (XSNMSUBDP , 1 , float64 , VsrD (0 ), NMSUB_FLGS , \
2303+ (FP_FPRF | FP_VXSNAN | FP_VXISI | FP_VXIMZ | FP_FI | FP_XX | FP_UX | FP_OX ))
2304+ VSX_MADD (XSMADDSP , 1 , float64r32 , VsrD (0 ), MADD_FLGS , \
2305+ (FP_FPRF | FP_VXSNAN | FP_VXISI | FP_VXIMZ | FP_FI | FP_XX | FP_UX | FP_OX ))
2306+ VSX_MADD (XSMSUBSP , 1 , float64r32 , VsrD (0 ), MSUB_FLGS , \
2307+ (FP_FPRF | FP_VXSNAN | FP_VXISI | FP_VXIMZ | FP_FI | FP_XX | FP_UX | FP_OX ))
2308+ VSX_MADD (XSNMADDSP , 1 , float64r32 , VsrD (0 ), NMADD_FLGS , \
2309+ (FP_FPRF | FP_VXSNAN | FP_VXISI | FP_VXIMZ | FP_FI | FP_XX | FP_UX | FP_OX ))
2310+ VSX_MADD (XSNMSUBSP , 1 , float64r32 , VsrD (0 ), NMSUB_FLGS , \
2311+ (FP_FPRF | FP_VXSNAN | FP_VXISI | FP_VXIMZ | FP_FI | FP_XX | FP_UX | FP_OX ))
2312+
2313+ VSX_MADD (xvmadddp , 2 , float64 , VsrD (i ), MADD_FLGS , \
2314+ (FP_VXSNAN | FP_VXISI | FP_VXIMZ | FP_XX | FP_UX | FP_OX ))
2315+ VSX_MADD (xvmsubdp , 2 , float64 , VsrD (i ), MSUB_FLGS , \
2316+ (FP_VXSNAN | FP_VXISI | FP_VXIMZ | FP_XX | FP_UX | FP_OX ))
2317+ VSX_MADD (xvnmadddp , 2 , float64 , VsrD (i ), NMADD_FLGS , \
2318+ (FP_VXSNAN | FP_VXISI | FP_VXIMZ | FP_XX | FP_UX | FP_OX ))
2319+ VSX_MADD (xvnmsubdp , 2 , float64 , VsrD (i ), NMSUB_FLGS , \
2320+ (FP_VXSNAN | FP_VXISI | FP_VXIMZ | FP_XX | FP_UX | FP_OX ))
2321+
2322+ VSX_MADD (xvmaddsp , 4 , float32 , VsrW (i ), MADD_FLGS , \
2323+ (FP_VXSNAN | FP_VXISI | FP_VXIMZ | FP_XX | FP_UX | FP_OX ))
2324+ VSX_MADD (xvmsubsp , 4 , float32 , VsrW (i ), MSUB_FLGS , \
2325+ (FP_VXSNAN | FP_VXISI | FP_VXIMZ | FP_XX | FP_UX | FP_OX ))
2326+ VSX_MADD (xvnmaddsp , 4 , float32 , VsrW (i ), NMADD_FLGS , \
2327+ (FP_VXSNAN | FP_VXISI | FP_VXIMZ | FP_XX | FP_UX | FP_OX ))
2328+ VSX_MADD (xvnmsubsp , 4 , float32 , VsrW (i ), NMSUB_FLGS , \
2329+ (FP_VXSNAN | FP_XX | FP_UX | FP_OX ))
22862330
22872331/*
22882332 * VSX_MADDQ - VSX floating point quad-precision muliply/add
0 commit comments