{
CPUState *cs = env_cpu(env);
- env->fpscr |= FP_FI;
env->fpscr |= FP_XX;
/* Update the floating-point exception summary */
env->fpscr |= FP_FX;
}
}
-static void do_float_check_status(CPUPPCState *env, uintptr_t raddr)
+static void do_float_check_status(CPUPPCState *env, bool change_fi,
+ uintptr_t raddr)
{
CPUState *cs = env_cpu(env);
int status = get_float_exception_flags(&env->fp_status);
}
if (status & float_flag_inexact) {
float_inexact_excp(env);
- } else {
- env->fpscr &= ~FP_FI; /* clear the FPSCR[FI] bit */
+ }
+ if (change_fi) {
+ env->fpscr = FIELD_DP64(env->fpscr, FPSCR, FI,
+ !!(status & float_flag_inexact));
}
if (cs->exception_index == POWERPC_EXCP_PROGRAM &&
void helper_float_check_status(CPUPPCState *env)
{
- do_float_check_status(env, GETPC());
+ do_float_check_status(env, true, GETPC());
}
void helper_reset_fpstatus(CPUPPCState *env)
} else { \
farg.d = cvtr(arg, &env->fp_status); \
} \
- do_float_check_status(env, GETPC()); \
+ do_float_check_status(env, true, GETPC()); \
return farg.ll; \
}
/* fri* does not set FPSCR[XX] */
set_float_exception_flags(flags & ~float_flag_inexact, &env->fp_status);
- do_float_check_status(env, GETPC());
+ do_float_check_status(env, true, GETPC());
return arg;
}
} \
} \
*xt = t; \
- do_float_check_status(env, GETPC()); \
+ do_float_check_status(env, sfprf, GETPC()); \
}
VSX_ADD_SUB(xsadddp, add, 1, float64, VsrD(0), 1, 0)
helper_compute_fprf_float128(env, t.f128);
*xt = t;
- do_float_check_status(env, GETPC());
+ do_float_check_status(env, true, GETPC());
}
/*
} \
\
*xt = t; \
- do_float_check_status(env, GETPC()); \
+ do_float_check_status(env, sfprf, GETPC()); \
}
VSX_MUL(xsmuldp, 1, float64, VsrD(0), 1, 0)
helper_compute_fprf_float128(env, t.f128);
*xt = t;
- do_float_check_status(env, GETPC());
+ do_float_check_status(env, true, GETPC());
}
/*
} \
\
*xt = t; \
- do_float_check_status(env, GETPC()); \
+ do_float_check_status(env, sfprf, GETPC()); \
}
VSX_DIV(xsdivdp, 1, float64, VsrD(0), 1, 0)
helper_compute_fprf_float128(env, t.f128);
*xt = t;
- do_float_check_status(env, GETPC());
+ do_float_check_status(env, true, GETPC());
}
/*
} \
\
*xt = t; \
- do_float_check_status(env, GETPC()); \
+ do_float_check_status(env, sfprf, GETPC()); \
}
VSX_RE(xsredp, 1, float64, VsrD(0), 1, 0)
} \
\
*xt = t; \
- do_float_check_status(env, GETPC()); \
+ do_float_check_status(env, sfprf, GETPC()); \
}
VSX_SQRT(xssqrtdp, 1, float64, VsrD(0), 1, 0)
} \
\
*xt = t; \
- do_float_check_status(env, GETPC()); \
+ do_float_check_status(env, sfprf, GETPC()); \
}
VSX_RSQRTE(xsrsqrtedp, 1, float64, VsrD(0), 1, 0)
} \
} \
*xt = t; \
- do_float_check_status(env, GETPC()); \
+ do_float_check_status(env, sfprf, GETPC()); \
}
VSX_MADD(XSMADDDP, 1, float64, VsrD(0), MADD_FLGS, 1)
\
helper_compute_fprf_float128(env, t.f128); \
*xt = t; \
- do_float_check_status(env, GETPC()); \
+ do_float_check_status(env, true, GETPC()); \
}
VSX_MADDQ(XSMADDQP, MADD_FLGS, 0)
\
memset(xt, 0, sizeof(*xt)); \
memset(&xt->fld, -r, sizeof(xt->fld)); \
- do_float_check_status(env, GETPC()); \
+ do_float_check_status(env, false, GETPC()); \
}
VSX_SCALAR_CMP(XSCMPEQDP, float64, eq, VsrD(0), 0)
env->fpscr |= cc << FPSCR_FPCC;
env->crf[BF(opcode)] = cc;
- do_float_check_status(env, GETPC());
+ do_float_check_status(env, false, GETPC());
}
void helper_xscmpexpqp(CPUPPCState *env, uint32_t opcode,
env->fpscr |= cc << FPSCR_FPCC;
env->crf[BF(opcode)] = cc;
- do_float_check_status(env, GETPC());
+ do_float_check_status(env, false, GETPC());
}
static inline void do_scalar_cmp(CPUPPCState *env, ppc_vsr_t *xa, ppc_vsr_t *xb,
float_invalid_op_vxvc(env, 0, GETPC());
}
- do_float_check_status(env, GETPC());
+ do_float_check_status(env, false, GETPC());
}
void helper_xscmpodp(CPUPPCState *env, uint32_t opcode, ppc_vsr_t *xa,
float_invalid_op_vxvc(env, 0, GETPC());
}
- do_float_check_status(env, GETPC());
+ do_float_check_status(env, false, GETPC());
}
void helper_xscmpoqp(CPUPPCState *env, uint32_t opcode, ppc_vsr_t *xa,
} \
\
*xt = t; \
- do_float_check_status(env, GETPC()); \
+ do_float_check_status(env, false, GETPC()); \
}
VSX_MAX_MIN(xsmaxdp, maxnum, 1, float64, VsrD(0))
} \
\
*xt = t; \
- do_float_check_status(env, GETPC()); \
+ do_float_check_status(env, sfprf, GETPC()); \
}
VSX_CVT_FP_TO_FP(xscvspdp, 1, float32, float64, VsrW(0), VsrD(0), 1)
} \
\
*xt = t; \
- do_float_check_status(env, GETPC()); \
+ do_float_check_status(env, sfprf, GETPC()); \
}
VSX_CVT_FP_TO_FP2(xvcvdpsp, 2, float64, float32, 0)
} \
\
*xt = t; \
- do_float_check_status(env, GETPC()); \
+ do_float_check_status(env, true, GETPC()); \
}
VSX_CVT_FP_TO_FP_VECTOR(xscvdpqp, 1, float64, float128, VsrD(0), f128, 1)
} \
\
*xt = t; \
- do_float_check_status(env, GETPC()); \
+ do_float_check_status(env, sfprf, GETPC()); \
}
VSX_CVT_FP_TO_FP_HP(xscvdphp, 1, float64, float16, VsrD(0), VsrH(3), 1)
}
*xt = t;
- do_float_check_status(env, GETPC());
+ do_float_check_status(env, false, GETPC());
}
void helper_XSCVQPDP(CPUPPCState *env, uint32_t ro, ppc_vsr_t *xt,
helper_compute_fprf_float64(env, t.VsrD(0));
*xt = t;
- do_float_check_status(env, GETPC());
+ do_float_check_status(env, true, GETPC());
}
uint64_t helper_xscvdpspn(CPUPPCState *env, uint64_t xb)
* ttp - target type (int32, uint32, int64 or uint64)
* sfld - source vsr_t field
* tfld - target vsr_t field
+ * sfi - set FI
* rnan - resulting NaN
*/
-#define VSX_CVT_FP_TO_INT(op, nels, stp, ttp, sfld, tfld, rnan) \
+#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; \
\
*xt = t; \
env->fp_status.float_exception_flags = all_flags; \
- do_float_check_status(env, GETPC()); \
+ do_float_check_status(env, sfi, GETPC()); \
}
-VSX_CVT_FP_TO_INT(xscvdpsxds, 1, float64, int64, VsrD(0), VsrD(0), \
+VSX_CVT_FP_TO_INT(xscvdpsxds, 1, float64, int64, VsrD(0), VsrD(0), true, \
0x8000000000000000ULL)
-VSX_CVT_FP_TO_INT(xscvdpuxds, 1, float64, uint64, VsrD(0), VsrD(0), 0ULL)
-VSX_CVT_FP_TO_INT(xvcvdpsxds, 2, float64, int64, VsrD(i), VsrD(i), \
+VSX_CVT_FP_TO_INT(xscvdpuxds, 1, float64, uint64, VsrD(0), VsrD(0), true, 0ULL)
+VSX_CVT_FP_TO_INT(xvcvdpsxds, 2, float64, int64, VsrD(i), VsrD(i), false, \
0x8000000000000000ULL)
-VSX_CVT_FP_TO_INT(xvcvdpuxds, 2, float64, uint64, VsrD(i), VsrD(i), 0ULL)
-VSX_CVT_FP_TO_INT(xvcvspsxds, 2, float32, int64, VsrW(2 * i), VsrD(i), \
+VSX_CVT_FP_TO_INT(xvcvdpuxds, 2, float64, uint64, VsrD(i), VsrD(i), false, \
+ 0ULL)
+VSX_CVT_FP_TO_INT(xvcvspsxds, 2, float32, int64, VsrW(2 * i), VsrD(i), false, \
0x8000000000000000ULL)
-VSX_CVT_FP_TO_INT(xvcvspsxws, 4, float32, int32, VsrW(i), VsrW(i), 0x80000000U)
-VSX_CVT_FP_TO_INT(xvcvspuxds, 2, float32, uint64, VsrW(2 * i), VsrD(i), 0ULL)
-VSX_CVT_FP_TO_INT(xvcvspuxws, 4, float32, uint32, VsrW(i), VsrW(i), 0U)
+VSX_CVT_FP_TO_INT(xvcvspsxws, 4, float32, int32, VsrW(i), VsrW(i), false, \
+ 0x80000000ULL)
+VSX_CVT_FP_TO_INT(xvcvspuxds, 2, float32, uint64, VsrW(2 * i), VsrD(i), \
+ false, 0ULL)
+VSX_CVT_FP_TO_INT(xvcvspuxws, 4, float32, uint32, VsrW(i), VsrW(i), false, 0U)
#define VSX_CVT_FP_TO_INT128(op, tp, rnan) \
void helper_##op(CPUPPCState *env, ppc_vsr_t *xt, ppc_vsr_t *xb) \
} \
\
*xt = t; \
- do_float_check_status(env, GETPC()); \
+ do_float_check_status(env, true, GETPC()); \
}
VSX_CVT_FP_TO_INT128(XSCVQPUQZ, uint128, 0)
* words 0 and 1 (and words 2 and 3) of the result register, as
* is required by this version of the architecture.
*/
-#define VSX_CVT_FP_TO_INT2(op, nels, stp, ttp, rnan) \
+#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; \
\
*xt = t; \
env->fp_status.float_exception_flags = all_flags; \
- do_float_check_status(env, GETPC()); \
+ do_float_check_status(env, sfi, GETPC()); \
}
-VSX_CVT_FP_TO_INT2(xscvdpsxws, 1, float64, int32, 0x80000000U)
-VSX_CVT_FP_TO_INT2(xscvdpuxws, 1, float64, uint32, 0U)
-VSX_CVT_FP_TO_INT2(xvcvdpsxws, 2, float64, int32, 0x80000000U)
-VSX_CVT_FP_TO_INT2(xvcvdpuxws, 2, float64, uint32, 0U)
+VSX_CVT_FP_TO_INT2(xscvdpsxws, 1, float64, int32, true, 0x80000000U)
+VSX_CVT_FP_TO_INT2(xscvdpuxws, 1, float64, uint32, true, 0U)
+VSX_CVT_FP_TO_INT2(xvcvdpsxws, 2, float64, int32, false, 0x80000000U)
+VSX_CVT_FP_TO_INT2(xvcvdpuxws, 2, float64, uint32, false, 0U)
/*
* VSX_CVT_FP_TO_INT_VECTOR - VSX floating point to integer conversion
} \
\
*xt = t; \
- do_float_check_status(env, GETPC()); \
+ do_float_check_status(env, true, GETPC()); \
}
VSX_CVT_FP_TO_INT_VECTOR(xscvqpsdz, float128, int64, f128, VsrD(0), \
} \
\
*xt = t; \
- do_float_check_status(env, GETPC()); \
+ do_float_check_status(env, sfprf, GETPC()); \
}
VSX_CVT_INT_TO_FP(xscvsxddp, 1, int64, float64, VsrD(0), VsrD(0), 1, 0)
} \
\
*xt = t; \
- do_float_check_status(env, GETPC()); \
+ do_float_check_status(env, false, GETPC()); \
}
VSX_CVT_INT_TO_FP2(xvcvsxdsp, int64, float32)
helper_reset_fpstatus(env); \
xt->f128 = tp##_to_float128(xb->s128, &env->fp_status); \
helper_compute_fprf_float128(env, xt->f128); \
- do_float_check_status(env, GETPC()); \
+ do_float_check_status(env, true, GETPC()); \
}
VSX_CVT_INT128_TO_FP(XSCVUQQP, uint128);
helper_compute_fprf_##ttp(env, t.tfld); \
\
*xt = t; \
- do_float_check_status(env, GETPC()); \
+ do_float_check_status(env, true, GETPC()); \
}
VSX_CVT_INT_TO_FP_VECTOR(xscvsdqp, int64, float128, VsrD(0), f128)
} \
\
*xt = t; \
- do_float_check_status(env, GETPC()); \
+ do_float_check_status(env, sfprf, GETPC()); \
}
VSX_ROUND(xsrdpi, 1, float64, VsrD(0), float_round_ties_away, 1)
uint64_t xt = do_frsp(env, xb, GETPC());
helper_compute_fprf_float64(env, xt);
- do_float_check_status(env, GETPC());
+ do_float_check_status(env, true, GETPC());
return xt;
}
}
helper_compute_fprf_float128(env, t.f128);
- do_float_check_status(env, GETPC());
+ do_float_check_status(env, true, GETPC());
*xt = t;
}
helper_compute_fprf_float128(env, t.f128);
*xt = t;
- do_float_check_status(env, GETPC());
+ do_float_check_status(env, true, GETPC());
}
void helper_xssqrtqp(CPUPPCState *env, uint32_t opcode,
helper_compute_fprf_float128(env, t.f128);
*xt = t;
- do_float_check_status(env, GETPC());
+ do_float_check_status(env, true, GETPC());
}
void helper_xssubqp(CPUPPCState *env, uint32_t opcode,
helper_compute_fprf_float128(env, t.f128);
*xt = t;
- do_float_check_status(env, GETPC());
+ do_float_check_status(env, true, GETPC());
}