COMPUTE_FPRF(float128)
/* Floating-point invalid operations exception */
-static inline __attribute__((__always_inline__))
-uint64_t float_invalid_op_excp(CPUPPCState *env, int op, int set_fpcc)
+static void finish_invalid_op_excp(CPUPPCState *env, int op, uintptr_t retaddr)
{
- CPUState *cs = CPU(ppc_env_get_cpu(env));
- uint64_t ret = 0;
- int ve;
+ /* Update the floating-point invalid operation summary */
+ env->fpscr |= 1 << FPSCR_VX;
+ /* Update the floating-point exception summary */
+ env->fpscr |= FP_FX;
+ if (fpscr_ve != 0) {
+ /* Update the floating-point enabled exception summary */
+ env->fpscr |= 1 << FPSCR_FEX;
+ if (fp_exceptions_enabled(env)) {
+ raise_exception_err_ra(env, POWERPC_EXCP_PROGRAM,
+ POWERPC_EXCP_FP | op, retaddr);
+ }
+ }
+}
- ve = fpscr_ve;
- switch (op) {
- case POWERPC_EXCP_FP_VXSNAN:
- env->fpscr |= 1 << FPSCR_VXSNAN;
- break;
- case POWERPC_EXCP_FP_VXSOFT:
- env->fpscr |= 1 << FPSCR_VXSOFT;
- break;
- case POWERPC_EXCP_FP_VXISI:
- /* Magnitude subtraction of infinities */
- env->fpscr |= 1 << FPSCR_VXISI;
- goto update_arith;
- case POWERPC_EXCP_FP_VXIDI:
- /* Division of infinity by infinity */
- env->fpscr |= 1 << FPSCR_VXIDI;
- goto update_arith;
- case POWERPC_EXCP_FP_VXZDZ:
- /* Division of zero by zero */
- env->fpscr |= 1 << FPSCR_VXZDZ;
- goto update_arith;
- case POWERPC_EXCP_FP_VXIMZ:
- /* Multiplication of zero by infinity */
- env->fpscr |= 1 << FPSCR_VXIMZ;
- goto update_arith;
- case POWERPC_EXCP_FP_VXVC:
- /* Ordered comparison of NaN */
- env->fpscr |= 1 << FPSCR_VXVC;
+static void finish_invalid_op_arith(CPUPPCState *env, int op,
+ bool set_fpcc, uintptr_t retaddr)
+{
+ env->fpscr &= ~((1 << FPSCR_FR) | (1 << FPSCR_FI));
+ if (fpscr_ve == 0) {
if (set_fpcc) {
env->fpscr &= ~(0xF << FPSCR_FPCC);
env->fpscr |= 0x11 << FPSCR_FPCC;
}
- /* We must update the target FPR before raising the exception */
- if (ve != 0) {
- cs->exception_index = POWERPC_EXCP_PROGRAM;
- env->error_code = POWERPC_EXCP_FP | POWERPC_EXCP_FP_VXVC;
- /* Update the floating-point enabled exception summary */
- env->fpscr |= 1 << FPSCR_FEX;
- /* Exception is differed */
- ve = 0;
- }
- break;
- case POWERPC_EXCP_FP_VXSQRT:
- /* Square root of a negative number */
- env->fpscr |= 1 << FPSCR_VXSQRT;
- update_arith:
- env->fpscr &= ~((1 << FPSCR_FR) | (1 << FPSCR_FI));
- if (ve == 0) {
- /* Set the result to quiet NaN */
- ret = 0x7FF8000000000000ULL;
- if (set_fpcc) {
- env->fpscr &= ~(0xF << FPSCR_FPCC);
- env->fpscr |= 0x11 << FPSCR_FPCC;
- }
- }
- break;
- case POWERPC_EXCP_FP_VXCVI:
- /* Invalid conversion */
- env->fpscr |= 1 << FPSCR_VXCVI;
- env->fpscr &= ~((1 << FPSCR_FR) | (1 << FPSCR_FI));
- if (ve == 0) {
- /* Set the result to quiet NaN */
- ret = 0x7FF8000000000000ULL;
- if (set_fpcc) {
- env->fpscr &= ~(0xF << FPSCR_FPCC);
- env->fpscr |= 0x11 << FPSCR_FPCC;
- }
- }
- break;
+ }
+ finish_invalid_op_excp(env, op, retaddr);
+}
+
+/* Signalling NaN */
+static void float_invalid_op_vxsnan(CPUPPCState *env, uintptr_t retaddr)
+{
+ env->fpscr |= 1 << FPSCR_VXSNAN;
+ finish_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, retaddr);
+}
+
+/* Magnitude subtraction of infinities */
+static void float_invalid_op_vxisi(CPUPPCState *env, bool set_fpcc,
+ uintptr_t retaddr)
+{
+ env->fpscr |= 1 << FPSCR_VXISI;
+ finish_invalid_op_arith(env, POWERPC_EXCP_FP_VXISI, set_fpcc, retaddr);
+}
+
+/* Division of infinity by infinity */
+static void float_invalid_op_vxidi(CPUPPCState *env, bool set_fpcc,
+ uintptr_t retaddr)
+{
+ env->fpscr |= 1 << FPSCR_VXIDI;
+ finish_invalid_op_arith(env, POWERPC_EXCP_FP_VXIDI, set_fpcc, retaddr);
+}
+
+/* Division of zero by zero */
+static void float_invalid_op_vxzdz(CPUPPCState *env, bool set_fpcc,
+ uintptr_t retaddr)
+{
+ env->fpscr |= 1 << FPSCR_VXZDZ;
+ finish_invalid_op_arith(env, POWERPC_EXCP_FP_VXZDZ, set_fpcc, retaddr);
+}
+
+/* Multiplication of zero by infinity */
+static void float_invalid_op_vximz(CPUPPCState *env, bool set_fpcc,
+ uintptr_t retaddr)
+{
+ env->fpscr |= 1 << FPSCR_VXIMZ;
+ finish_invalid_op_arith(env, POWERPC_EXCP_FP_VXIMZ, set_fpcc, retaddr);
+}
+
+/* Square root of a negative number */
+static void float_invalid_op_vxsqrt(CPUPPCState *env, bool set_fpcc,
+ uintptr_t retaddr)
+{
+ env->fpscr |= 1 << FPSCR_VXSQRT;
+ finish_invalid_op_arith(env, POWERPC_EXCP_FP_VXSQRT, set_fpcc, retaddr);
+}
+
+/* Ordered comparison of NaN */
+static void float_invalid_op_vxvc(CPUPPCState *env, bool set_fpcc,
+ uintptr_t retaddr)
+{
+ env->fpscr |= 1 << FPSCR_VXVC;
+ if (set_fpcc) {
+ env->fpscr &= ~(0xF << FPSCR_FPCC);
+ env->fpscr |= 0x11 << FPSCR_FPCC;
}
/* Update the floating-point invalid operation summary */
env->fpscr |= 1 << FPSCR_VX;
/* Update the floating-point exception summary */
env->fpscr |= FP_FX;
- if (ve != 0) {
+ /* We must update the target FPR before raising the exception */
+ if (fpscr_ve != 0) {
+ CPUState *cs = CPU(ppc_env_get_cpu(env));
+
+ cs->exception_index = POWERPC_EXCP_PROGRAM;
+ env->error_code = POWERPC_EXCP_FP | POWERPC_EXCP_FP_VXVC;
/* Update the floating-point enabled exception summary */
env->fpscr |= 1 << FPSCR_FEX;
- if (fp_exceptions_enabled(env)) {
- /* GETPC() works here because this is inline */
- raise_exception_err_ra(env, POWERPC_EXCP_PROGRAM,
- POWERPC_EXCP_FP | op, GETPC());
+ /* Exception is differed */
+ }
+}
+
+/* Invalid conversion */
+static void float_invalid_op_vxcvi(CPUPPCState *env, bool set_fpcc,
+ uintptr_t retaddr)
+{
+ env->fpscr |= 1 << FPSCR_VXCVI;
+ env->fpscr &= ~((1 << FPSCR_FR) | (1 << FPSCR_FI));
+ if (fpscr_ve == 0) {
+ if (set_fpcc) {
+ env->fpscr &= ~(0xF << FPSCR_FPCC);
+ env->fpscr |= 0x11 << FPSCR_FPCC;
}
}
- return ret;
+ finish_invalid_op_excp(env, POWERPC_EXCP_FP_VXCVI, retaddr);
}
static inline void float_zero_divide_excp(CPUPPCState *env, uintptr_t raddr)
if (unlikely(status & float_flag_invalid)) {
if (float64_is_infinity(arg1) && float64_is_infinity(arg2)) {
/* Magnitude subtraction of infinities */
- float_invalid_op_excp(env, POWERPC_EXCP_FP_VXISI, 1);
+ float_invalid_op_vxisi(env, 1, GETPC());
} else if (float64_is_signaling_nan(arg1, &env->fp_status) ||
float64_is_signaling_nan(arg2, &env->fp_status)) {
/* sNaN addition */
- float_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1);
+ float_invalid_op_vxsnan(env, GETPC());
}
}
if (unlikely(status & float_flag_invalid)) {
if (float64_is_infinity(arg1) && float64_is_infinity(arg2)) {
/* Magnitude subtraction of infinities */
- float_invalid_op_excp(env, POWERPC_EXCP_FP_VXISI, 1);
+ float_invalid_op_vxisi(env, 1, GETPC());
} else if (float64_is_signaling_nan(arg1, &env->fp_status) ||
float64_is_signaling_nan(arg2, &env->fp_status)) {
/* sNaN addition */
- float_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1);
+ float_invalid_op_vxsnan(env, GETPC());
}
}
if ((float64_is_infinity(arg1) && float64_is_zero(arg2)) ||
(float64_is_zero(arg1) && float64_is_infinity(arg2))) {
/* Multiplication of zero by infinity */
- float_invalid_op_excp(env, POWERPC_EXCP_FP_VXIMZ, 1);
+ float_invalid_op_vximz(env, 1, GETPC());
} else if (float64_is_signaling_nan(arg1, &env->fp_status) ||
float64_is_signaling_nan(arg2, &env->fp_status)) {
/* sNaN multiplication */
- float_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1);
+ float_invalid_op_vxsnan(env, GETPC());
}
}
/* Determine what kind of invalid operation was seen. */
if (float64_is_infinity(arg1) && float64_is_infinity(arg2)) {
/* Division of infinity by infinity */
- float_invalid_op_excp(env, POWERPC_EXCP_FP_VXIDI, 1);
+ float_invalid_op_vxidi(env, 1, GETPC());
} else if (float64_is_zero(arg1) && float64_is_zero(arg2)) {
/* Division of zero by zero */
- float_invalid_op_excp(env, POWERPC_EXCP_FP_VXZDZ, 1);
+ float_invalid_op_vxzdz(env, 1, GETPC());
} else if (float64_is_signaling_nan(arg1, &env->fp_status) ||
float64_is_signaling_nan(arg2, &env->fp_status)) {
/* sNaN division */
- float_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1);
+ float_invalid_op_vxsnan(env, GETPC());
}
}
if (status & float_flag_divbyzero) {
\
if (unlikely(env->fp_status.float_exception_flags)) { \
if (float64_is_any_nan(arg)) { \
- float_invalid_op_excp(env, POWERPC_EXCP_FP_VXCVI, 1); \
+ float_invalid_op_vxcvi(env, 1, GETPC()); \
if (float64_is_signaling_nan(arg, &env->fp_status)) { \
- float_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1); \
+ float_invalid_op_vxsnan(env, GETPC()); \
} \
farg.ll = nanval; \
} else if (env->fp_status.float_exception_flags & \
float_flag_invalid) { \
- float_invalid_op_excp(env, POWERPC_EXCP_FP_VXCVI, 1); \
+ float_invalid_op_vxcvi(env, 1, GETPC()); \
} \
float_check_status(env); \
} \
if (unlikely(float64_is_signaling_nan(farg.d, &env->fp_status))) {
/* sNaN round */
- float_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1);
+ float_invalid_op_vxsnan(env, GETPC());
farg.ll = arg | 0x0008000000000000ULL;
} else {
int inexact = get_float_exception_flags(&env->fp_status) &
#define FPU_MADDSUB_UPDATE(NAME, TP) \
static void NAME(CPUPPCState *env, TP arg1, TP arg2, TP arg3, \
- unsigned int madd_flags) \
+ unsigned int madd_flags, uintptr_t retaddr) \
{ \
if (TP##_is_signaling_nan(arg1, &env->fp_status) || \
TP##_is_signaling_nan(arg2, &env->fp_status) || \
TP##_is_signaling_nan(arg3, &env->fp_status)) { \
/* sNaN operation */ \
- float_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1); \
+ float_invalid_op_vxsnan(env, retaddr); \
} \
if ((TP##_is_infinity(arg1) && TP##_is_zero(arg2)) || \
(TP##_is_zero(arg1) && TP##_is_infinity(arg2))) { \
/* Multiplication of zero by infinity */ \
- float_invalid_op_excp(env, POWERPC_EXCP_FP_VXIMZ, 1); \
+ float_invalid_op_vximz(env, 1, retaddr); \
} \
if ((TP##_is_infinity(arg1) || TP##_is_infinity(arg2)) && \
TP##_is_infinity(arg3)) { \
cSign ^= 1; \
} \
if (aSign ^ bSign ^ cSign) { \
- float_invalid_op_excp(env, POWERPC_EXCP_FP_VXISI, 1); \
+ float_invalid_op_vxisi(env, 1, retaddr); \
} \
} \
}
if (flags) { \
if (flags & float_flag_invalid) { \
float64_maddsub_update_excp(env, arg1, arg2, arg3, \
- madd_flags); \
+ madd_flags, GETPC()); \
} \
float_check_status(env); \
} \
farg.ll = arg;
if (unlikely(float64_is_signaling_nan(farg.d, &env->fp_status))) {
- /* sNaN square root */
- float_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1);
+ float_invalid_op_vxsnan(env, GETPC());
}
f32 = float64_to_float32(farg.d, &env->fp_status);
farg.d = float32_to_float64(f32, &env->fp_status);
if (unlikely(float64_is_any_nan(arg))) {
if (unlikely(float64_is_signaling_nan(arg, &env->fp_status))) {
/* sNaN square root */
- float_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1);
+ float_invalid_op_vxsnan(env, GETPC());
}
} else {
/* Square root of a negative nonzero number */
- float_invalid_op_excp(env, POWERPC_EXCP_FP_VXSQRT, 1);
+ float_invalid_op_vxsqrt(env, 1, GETPC());
}
}
if (status & float_flag_invalid) {
if (float64_is_signaling_nan(arg, &env->fp_status)) {
/* sNaN reciprocal */
- float_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1);
+ float_invalid_op_vxsnan(env, GETPC());
}
}
if (status & float_flag_divbyzero) {
if (unlikely(float64_is_signaling_nan(farg.d, &env->fp_status))) {
/* sNaN reciprocal */
- float_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1);
+ float_invalid_op_vxsnan(env, GETPC());
}
farg.d = float64_div(float64_one, farg.d, &env->fp_status);
f32 = float64_to_float32(farg.d, &env->fp_status);
if (status & float_flag_invalid) {
if (float64_is_signaling_nan(arg, &env->fp_status)) {
/* sNaN reciprocal */
- float_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1);
+ float_invalid_op_vxsnan(env, GETPC());
} else {
/* Square root of a negative nonzero number */
- float_invalid_op_excp(env, POWERPC_EXCP_FP_VXSQRT, 1);
+ float_invalid_op_vxsqrt(env, 1, GETPC());
}
}
if (status & float_flag_divbyzero) {
&& (float64_is_signaling_nan(farg1.d, &env->fp_status) ||
float64_is_signaling_nan(farg2.d, &env->fp_status)))) {
/* sNaN comparison */
- float_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1);
+ float_invalid_op_vxsnan(env, GETPC());
}
}
env->fpscr |= ret << FPSCR_FPRF;
env->crf[crfD] = ret;
if (unlikely(ret == 0x01UL)) {
+ float_invalid_op_vxvc(env, 1, GETPC());
if (float64_is_signaling_nan(farg1.d, &env->fp_status) ||
float64_is_signaling_nan(farg2.d, &env->fp_status)) {
/* sNaN comparison */
- float_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN |
- POWERPC_EXCP_FP_VXVC, 1);
- } else {
- /* qNaN comparison */
- float_invalid_op_excp(env, POWERPC_EXCP_FP_VXVC, 1);
+ float_invalid_op_vxsnan(env, GETPC());
}
}
}
\
if (unlikely(tstat.float_exception_flags & float_flag_invalid)) { \
if (tp##_is_infinity(xa.fld) && tp##_is_infinity(xb.fld)) { \
- float_invalid_op_excp(env, POWERPC_EXCP_FP_VXISI, sfprf); \
+ float_invalid_op_vxisi(env, sfprf, GETPC()); \
} else if (tp##_is_signaling_nan(xa.fld, &tstat) || \
tp##_is_signaling_nan(xb.fld, &tstat)) { \
- float_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, sfprf); \
+ float_invalid_op_vxsnan(env, GETPC()); \
} \
} \
\
if (unlikely(tstat.float_exception_flags & float_flag_invalid)) {
if (float128_is_infinity(xa.f128) && float128_is_infinity(xb.f128)) {
- float_invalid_op_excp(env, POWERPC_EXCP_FP_VXISI, 1);
+ float_invalid_op_vxisi(env, 1, GETPC());
} else if (float128_is_signaling_nan(xa.f128, &tstat) ||
float128_is_signaling_nan(xb.f128, &tstat)) {
- float_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1);
+ float_invalid_op_vxsnan(env, GETPC());
}
}
if (unlikely(tstat.float_exception_flags & float_flag_invalid)) { \
if ((tp##_is_infinity(xa.fld) && tp##_is_zero(xb.fld)) || \
(tp##_is_infinity(xb.fld) && tp##_is_zero(xa.fld))) { \
- float_invalid_op_excp(env, POWERPC_EXCP_FP_VXIMZ, sfprf); \
+ float_invalid_op_vximz(env, sfprf, GETPC()); \
} else if (tp##_is_signaling_nan(xa.fld, &tstat) || \
tp##_is_signaling_nan(xb.fld, &tstat)) { \
- float_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, sfprf); \
+ float_invalid_op_vxsnan(env, GETPC()); \
} \
} \
\
if (unlikely(tstat.float_exception_flags & float_flag_invalid)) {
if ((float128_is_infinity(xa.f128) && float128_is_zero(xb.f128)) ||
(float128_is_infinity(xb.f128) && float128_is_zero(xa.f128))) {
- float_invalid_op_excp(env, POWERPC_EXCP_FP_VXIMZ, 1);
+ float_invalid_op_vximz(env, 1, GETPC());
} else if (float128_is_signaling_nan(xa.f128, &tstat) ||
float128_is_signaling_nan(xb.f128, &tstat)) {
- float_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1);
+ float_invalid_op_vxsnan(env, GETPC());
}
}
helper_compute_fprf_float128(env, xt.f128);
\
if (unlikely(tstat.float_exception_flags & float_flag_invalid)) { \
if (tp##_is_infinity(xa.fld) && tp##_is_infinity(xb.fld)) { \
- float_invalid_op_excp(env, POWERPC_EXCP_FP_VXIDI, sfprf); \
- } else if (tp##_is_zero(xa.fld) && \
- tp##_is_zero(xb.fld)) { \
- float_invalid_op_excp(env, POWERPC_EXCP_FP_VXZDZ, sfprf); \
+ float_invalid_op_vxidi(env, sfprf, GETPC()); \
+ } else if (tp##_is_zero(xa.fld) && tp##_is_zero(xb.fld)) { \
+ float_invalid_op_vxzdz(env, sfprf, GETPC()); \
} else if (tp##_is_signaling_nan(xa.fld, &tstat) || \
- tp##_is_signaling_nan(xb.fld, &tstat)) { \
- float_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, sfprf); \
+ tp##_is_signaling_nan(xb.fld, &tstat)) { \
+ float_invalid_op_vxsnan(env, GETPC()); \
} \
} \
if (unlikely(tstat.float_exception_flags & float_flag_divbyzero)) { \
if (unlikely(tstat.float_exception_flags & float_flag_invalid)) {
if (float128_is_infinity(xa.f128) && float128_is_infinity(xb.f128)) {
- float_invalid_op_excp(env, POWERPC_EXCP_FP_VXIDI, 1);
- } else if (float128_is_zero(xa.f128) &&
- float128_is_zero(xb.f128)) {
- float_invalid_op_excp(env, POWERPC_EXCP_FP_VXZDZ, 1);
+ float_invalid_op_vxidi(env, 1, GETPC());
+ } else if (float128_is_zero(xa.f128) && float128_is_zero(xb.f128)) {
+ float_invalid_op_vxzdz(env, 1, GETPC());
} else if (float128_is_signaling_nan(xa.f128, &tstat) ||
- float128_is_signaling_nan(xb.f128, &tstat)) {
- float_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1);
+ float128_is_signaling_nan(xb.f128, &tstat)) {
+ float_invalid_op_vxsnan(env, GETPC());
}
}
if (unlikely(tstat.float_exception_flags & float_flag_divbyzero)) {
\
for (i = 0; i < nels; i++) { \
if (unlikely(tp##_is_signaling_nan(xb.fld, &env->fp_status))) { \
- float_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, sfprf); \
+ float_invalid_op_vxsnan(env, GETPC()); \
} \
xt.fld = tp##_div(tp##_one, xb.fld, &env->fp_status); \
\
\
if (unlikely(tstat.float_exception_flags & float_flag_invalid)) { \
if (tp##_is_neg(xb.fld) && !tp##_is_zero(xb.fld)) { \
- float_invalid_op_excp(env, POWERPC_EXCP_FP_VXSQRT, sfprf); \
+ float_invalid_op_vxsqrt(env, sfprf, GETPC()); \
} else if (tp##_is_signaling_nan(xb.fld, &tstat)) { \
- float_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, sfprf); \
+ float_invalid_op_vxsnan(env, GETPC()); \
} \
} \
\
\
if (unlikely(tstat.float_exception_flags & float_flag_invalid)) { \
if (tp##_is_neg(xb.fld) && !tp##_is_zero(xb.fld)) { \
- float_invalid_op_excp(env, POWERPC_EXCP_FP_VXSQRT, sfprf); \
+ float_invalid_op_vxsqrt(env, sfprf, GETPC()); \
} else if (tp##_is_signaling_nan(xb.fld, &tstat)) { \
- float_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, sfprf); \
+ float_invalid_op_vxsnan(env, GETPC()); \
} \
} \
\
env->fp_status.float_exception_flags |= tstat.float_exception_flags; \
\
if (unlikely(tstat.float_exception_flags & float_flag_invalid)) { \
- tp##_maddsub_update_excp(env, xa.fld, b->fld, c->fld, maddflgs); \
+ tp##_maddsub_update_excp(env, xa.fld, b->fld, \
+ c->fld, maddflgs, GETPC()); \
} \
\
if (r2sp) { \
float64_is_quiet_nan(xb.VsrD(0), &env->fp_status); \
} \
if (vxsnan_flag) { \
- float_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 0); \
+ float_invalid_op_vxsnan(env, GETPC()); \
} \
if (vxvc_flag) { \
- float_invalid_op_excp(env, POWERPC_EXCP_FP_VXVC, 0); \
+ float_invalid_op_vxvc(env, 0, GETPC()); \
} \
vex_flag = fpscr_ve && (vxvc_flag || vxsnan_flag); \
\
} \
} \
if (vxsnan_flag) { \
- float_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 0); \
+ float_invalid_op_vxsnan(env, GETPC()); \
} \
if (vxvc_flag) { \
- float_invalid_op_excp(env, POWERPC_EXCP_FP_VXVC, 0); \
+ float_invalid_op_vxvc(env, 0, GETPC()); \
} \
\
if (float64_lt(xa.VsrD(0), xb.VsrD(0), &env->fp_status)) { \
} \
} \
if (vxsnan_flag) { \
- float_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 0); \
+ float_invalid_op_vxsnan(env, GETPC()); \
} \
if (vxvc_flag) { \
- float_invalid_op_excp(env, POWERPC_EXCP_FP_VXVC, 0); \
+ float_invalid_op_vxvc(env, 0, GETPC()); \
} \
\
if (float128_lt(xa.f128, xb.f128, &env->fp_status)) { \
xt.fld = tp##_##op(xa.fld, xb.fld, &env->fp_status); \
if (unlikely(tp##_is_signaling_nan(xa.fld, &env->fp_status) || \
tp##_is_signaling_nan(xb.fld, &env->fp_status))) { \
- float_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 0); \
+ float_invalid_op_vxsnan(env, GETPC()); \
} \
} \
\
\
vex_flag = fpscr_ve & vxsnan_flag; \
if (vxsnan_flag) { \
- float_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 0); \
+ float_invalid_op_vxsnan(env, GETPC()); \
} \
if (!vex_flag) { \
putVSR(rD(opcode) + 32, &xt, env); \
\
vex_flag = fpscr_ve & vxsnan_flag; \
if (vxsnan_flag) { \
- float_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 0); \
+ float_invalid_op_vxsnan(env, GETPC()); \
} \
if (!vex_flag) { \
putVSR(rD(opcode) + 32, &xt, env); \
tp##_is_any_nan(xb.fld))) { \
if (tp##_is_signaling_nan(xa.fld, &env->fp_status) || \
tp##_is_signaling_nan(xb.fld, &env->fp_status)) { \
- float_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 0); \
+ float_invalid_op_vxsnan(env, GETPC()); \
} \
if (svxvc) { \
- float_invalid_op_excp(env, POWERPC_EXCP_FP_VXVC, 0); \
+ float_invalid_op_vxvc(env, 0, GETPC()); \
} \
xt.fld = 0; \
all_true = 0; \
xt.tfld = stp##_to_##ttp(xb.sfld, &env->fp_status); \
if (unlikely(stp##_is_signaling_nan(xb.sfld, \
&env->fp_status))) { \
- float_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 0); \
+ float_invalid_op_vxsnan(env, GETPC()); \
xt.tfld = ttp##_snan_to_qnan(xt.tfld); \
} \
if (sfprf) { \
xt.tfld = stp##_to_##ttp(xb.sfld, &env->fp_status); \
if (unlikely(stp##_is_signaling_nan(xb.sfld, \
&env->fp_status))) { \
- float_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 0); \
+ float_invalid_op_vxsnan(env, GETPC()); \
xt.tfld = ttp##_snan_to_qnan(xt.tfld); \
} \
if (sfprf) { \
xt.tfld = stp##_to_##ttp(xb.sfld, 1, &env->fp_status); \
if (unlikely(stp##_is_signaling_nan(xb.sfld, \
&env->fp_status))) { \
- float_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 0); \
+ float_invalid_op_vxsnan(env, GETPC()); \
xt.tfld = ttp##_snan_to_qnan(xt.tfld); \
} \
if (sfprf) { \
xt.VsrD(0) = float128_to_float64(xb.f128, &tstat);
env->fp_status.float_exception_flags |= tstat.float_exception_flags;
- if (unlikely(float128_is_signaling_nan(xb.f128,
- &tstat))) {
- float_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 0);
+ if (unlikely(float128_is_signaling_nan(xb.f128, &tstat))) {
+ float_invalid_op_vxsnan(env, GETPC());
xt.VsrD(0) = float64_snan_to_qnan(xt.VsrD(0));
}
helper_compute_fprf_float64(env, xt.VsrD(0));
for (i = 0; i < nels; i++) { \
if (unlikely(stp##_is_any_nan(xb.sfld))) { \
if (stp##_is_signaling_nan(xb.sfld, &env->fp_status)) { \
- float_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 0); \
+ float_invalid_op_vxsnan(env, GETPC()); \
} \
- float_invalid_op_excp(env, POWERPC_EXCP_FP_VXCVI, 0); \
+ float_invalid_op_vxcvi(env, 0, GETPC()); \
xt.tfld = rnan; \
} else { \
xt.tfld = stp##_to_##ttp##_round_to_zero(xb.sfld, \
&env->fp_status); \
if (env->fp_status.float_exception_flags & float_flag_invalid) { \
- float_invalid_op_excp(env, POWERPC_EXCP_FP_VXCVI, 0); \
+ float_invalid_op_vxcvi(env, 0, GETPC()); \
} \
} \
} \
\
if (unlikely(stp##_is_any_nan(xb.sfld))) { \
if (stp##_is_signaling_nan(xb.sfld, &env->fp_status)) { \
- float_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 0); \
+ float_invalid_op_vxsnan(env, GETPC()); \
} \
- float_invalid_op_excp(env, POWERPC_EXCP_FP_VXCVI, 0); \
+ float_invalid_op_vxcvi(env, 0, GETPC()); \
xt.tfld = rnan; \
} else { \
xt.tfld = stp##_to_##ttp##_round_to_zero(xb.sfld, \
&env->fp_status); \
if (env->fp_status.float_exception_flags & float_flag_invalid) { \
- float_invalid_op_excp(env, POWERPC_EXCP_FP_VXCVI, 0); \
+ float_invalid_op_vxcvi(env, 0, GETPC()); \
} \
} \
\
for (i = 0; i < nels; i++) { \
if (unlikely(tp##_is_signaling_nan(xb.fld, \
&env->fp_status))) { \
- float_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 0); \
+ float_invalid_op_vxsnan(env, GETPC()); \
xt.fld = tp##_snan_to_qnan(xb.fld); \
} else { \
xt.fld = tp##_round_to_int(xb.fld, &env->fp_status); \
if (unlikely(tstat.float_exception_flags & float_flag_invalid)) {
if (float128_is_signaling_nan(xb.f128, &tstat)) {
- float_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 0);
+ float_invalid_op_vxsnan(env, GETPC());
xt.f128 = float128_snan_to_qnan(xt.f128);
}
}
if (unlikely(tstat.float_exception_flags & float_flag_invalid)) {
if (float128_is_signaling_nan(xb.f128, &tstat)) {
- float_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 0);
+ float_invalid_op_vxsnan(env, GETPC());
xt.f128 = float128_snan_to_qnan(xt.f128);
}
}
if (unlikely(tstat.float_exception_flags & float_flag_invalid)) {
if (float128_is_signaling_nan(xb.f128, &tstat)) {
- float_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1);
+ float_invalid_op_vxsnan(env, GETPC());
xt.f128 = float128_snan_to_qnan(xb.f128);
} else if (float128_is_quiet_nan(xb.f128, &tstat)) {
xt.f128 = xb.f128;
} else if (float128_is_neg(xb.f128) && !float128_is_zero(xb.f128)) {
- float_invalid_op_excp(env, POWERPC_EXCP_FP_VXSQRT, 1);
+ float_invalid_op_vxsqrt(env, 1, GETPC());
xt.f128 = float128_default_nan(&env->fp_status);
}
}
if (unlikely(tstat.float_exception_flags & float_flag_invalid)) {
if (float128_is_infinity(xa.f128) && float128_is_infinity(xb.f128)) {
- float_invalid_op_excp(env, POWERPC_EXCP_FP_VXISI, 1);
+ float_invalid_op_vxisi(env, 1, GETPC());
} else if (float128_is_signaling_nan(xa.f128, &tstat) ||
float128_is_signaling_nan(xb.f128, &tstat)) {
- float_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1);
+ float_invalid_op_vxsnan(env, GETPC());
}
}