Skip to content

Commit 3d70cd5

Browse files
committed
target/ppc: Fix FPSCR.FI flag for VSX_MADD helper
Signed-off-by: Víctor Colombo <victor.colombo@eldorado.org.br>
1 parent b11b5f2 commit 3d70cd5

1 file changed

Lines changed: 73 additions & 29 deletions

File tree

target/ppc/fpu_helper.c

Lines changed: 73 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -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 */
247260
static 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 */
269289
static 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 */
293320
static 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) \
22412273
void 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

Comments
 (0)