target/ppc: Split up float_invalid_op_excp

The always_inline trick only works if the function is always
called from the outer-most helper.  But it isn't, so pass in
the outer-most return address.  There's no need for a switch
statement whose argument is always a constant.  Unravel the
switch and goto via more helpers.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
This commit is contained in:
Richard Henderson 2018-10-11 16:41:53 -07:00 committed by David Gibson
parent 0e947a89ce
commit 13c9115fa9

View file

@ -170,96 +170,120 @@ COMPUTE_FPRF(float64)
COMPUTE_FPRF(float128) COMPUTE_FPRF(float128)
/* Floating-point invalid operations exception */ /* Floating-point invalid operations exception */
static inline __attribute__((__always_inline__)) static void finish_invalid_op_excp(CPUPPCState *env, int op, uintptr_t retaddr)
uint64_t float_invalid_op_excp(CPUPPCState *env, int op, int set_fpcc)
{ {
CPUState *cs = CPU(ppc_env_get_cpu(env)); /* Update the floating-point invalid operation summary */
uint64_t ret = 0; env->fpscr |= 1 << FPSCR_VX;
int ve; /* 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; static void finish_invalid_op_arith(CPUPPCState *env, int op,
switch (op) { bool set_fpcc, uintptr_t retaddr)
case POWERPC_EXCP_FP_VXSNAN: {
env->fpscr |= 1 << FPSCR_VXSNAN; env->fpscr &= ~((1 << FPSCR_FR) | (1 << FPSCR_FI));
break; if (fpscr_ve == 0) {
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;
if (set_fpcc) { if (set_fpcc) {
env->fpscr &= ~(0xF << FPSCR_FPCC); env->fpscr &= ~(0xF << FPSCR_FPCC);
env->fpscr |= 0x11 << FPSCR_FPCC; env->fpscr |= 0x11 << FPSCR_FPCC;
} }
/* We must update the target FPR before raising the exception */ }
if (ve != 0) { finish_invalid_op_excp(env, op, retaddr);
cs->exception_index = POWERPC_EXCP_PROGRAM; }
env->error_code = POWERPC_EXCP_FP | POWERPC_EXCP_FP_VXVC;
/* Update the floating-point enabled exception summary */ /* Signalling NaN */
env->fpscr |= 1 << FPSCR_FEX; static void float_invalid_op_vxsnan(CPUPPCState *env, uintptr_t retaddr)
/* Exception is differed */ {
ve = 0; env->fpscr |= 1 << FPSCR_VXSNAN;
} finish_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, retaddr);
break; }
case POWERPC_EXCP_FP_VXSQRT:
/* Square root of a negative number */ /* Magnitude subtraction of infinities */
env->fpscr |= 1 << FPSCR_VXSQRT; static void float_invalid_op_vxisi(CPUPPCState *env, bool set_fpcc,
update_arith: uintptr_t retaddr)
env->fpscr &= ~((1 << FPSCR_FR) | (1 << FPSCR_FI)); {
if (ve == 0) { env->fpscr |= 1 << FPSCR_VXISI;
/* Set the result to quiet NaN */ finish_invalid_op_arith(env, POWERPC_EXCP_FP_VXISI, set_fpcc, retaddr);
ret = 0x7FF8000000000000ULL; }
if (set_fpcc) {
env->fpscr &= ~(0xF << FPSCR_FPCC); /* Division of infinity by infinity */
env->fpscr |= 0x11 << FPSCR_FPCC; static void float_invalid_op_vxidi(CPUPPCState *env, bool set_fpcc,
} uintptr_t retaddr)
} {
break; env->fpscr |= 1 << FPSCR_VXIDI;
case POWERPC_EXCP_FP_VXCVI: finish_invalid_op_arith(env, POWERPC_EXCP_FP_VXIDI, set_fpcc, retaddr);
/* Invalid conversion */ }
env->fpscr |= 1 << FPSCR_VXCVI;
env->fpscr &= ~((1 << FPSCR_FR) | (1 << FPSCR_FI)); /* Division of zero by zero */
if (ve == 0) { static void float_invalid_op_vxzdz(CPUPPCState *env, bool set_fpcc,
/* Set the result to quiet NaN */ uintptr_t retaddr)
ret = 0x7FF8000000000000ULL; {
if (set_fpcc) { env->fpscr |= 1 << FPSCR_VXZDZ;
env->fpscr &= ~(0xF << FPSCR_FPCC); finish_invalid_op_arith(env, POWERPC_EXCP_FP_VXZDZ, set_fpcc, retaddr);
env->fpscr |= 0x11 << FPSCR_FPCC; }
}
} /* Multiplication of zero by infinity */
break; 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 */ /* Update the floating-point invalid operation summary */
env->fpscr |= 1 << FPSCR_VX; env->fpscr |= 1 << FPSCR_VX;
/* Update the floating-point exception summary */ /* Update the floating-point exception summary */
env->fpscr |= FP_FX; 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 */ /* Update the floating-point enabled exception summary */
env->fpscr |= 1 << FPSCR_FEX; env->fpscr |= 1 << FPSCR_FEX;
if (fp_exceptions_enabled(env)) { /* Exception is differed */
/* GETPC() works here because this is inline */ }
raise_exception_err_ra(env, POWERPC_EXCP_PROGRAM, }
POWERPC_EXCP_FP | op, GETPC());
/* 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) static inline void float_zero_divide_excp(CPUPPCState *env, uintptr_t raddr)
@ -632,11 +656,11 @@ float64 helper_fadd(CPUPPCState *env, float64 arg1, float64 arg2)
if (unlikely(status & float_flag_invalid)) { if (unlikely(status & float_flag_invalid)) {
if (float64_is_infinity(arg1) && float64_is_infinity(arg2)) { if (float64_is_infinity(arg1) && float64_is_infinity(arg2)) {
/* Magnitude subtraction of infinities */ /* 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) || } else if (float64_is_signaling_nan(arg1, &env->fp_status) ||
float64_is_signaling_nan(arg2, &env->fp_status)) { float64_is_signaling_nan(arg2, &env->fp_status)) {
/* sNaN addition */ /* sNaN addition */
float_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1); float_invalid_op_vxsnan(env, GETPC());
} }
} }
@ -652,11 +676,11 @@ float64 helper_fsub(CPUPPCState *env, float64 arg1, float64 arg2)
if (unlikely(status & float_flag_invalid)) { if (unlikely(status & float_flag_invalid)) {
if (float64_is_infinity(arg1) && float64_is_infinity(arg2)) { if (float64_is_infinity(arg1) && float64_is_infinity(arg2)) {
/* Magnitude subtraction of infinities */ /* 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) || } else if (float64_is_signaling_nan(arg1, &env->fp_status) ||
float64_is_signaling_nan(arg2, &env->fp_status)) { float64_is_signaling_nan(arg2, &env->fp_status)) {
/* sNaN addition */ /* sNaN addition */
float_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1); float_invalid_op_vxsnan(env, GETPC());
} }
} }
@ -673,11 +697,11 @@ float64 helper_fmul(CPUPPCState *env, float64 arg1, float64 arg2)
if ((float64_is_infinity(arg1) && float64_is_zero(arg2)) || if ((float64_is_infinity(arg1) && float64_is_zero(arg2)) ||
(float64_is_zero(arg1) && float64_is_infinity(arg2))) { (float64_is_zero(arg1) && float64_is_infinity(arg2))) {
/* Multiplication of zero by infinity */ /* 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) || } else if (float64_is_signaling_nan(arg1, &env->fp_status) ||
float64_is_signaling_nan(arg2, &env->fp_status)) { float64_is_signaling_nan(arg2, &env->fp_status)) {
/* sNaN multiplication */ /* sNaN multiplication */
float_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1); float_invalid_op_vxsnan(env, GETPC());
} }
} }
@ -695,14 +719,14 @@ float64 helper_fdiv(CPUPPCState *env, float64 arg1, float64 arg2)
/* Determine what kind of invalid operation was seen. */ /* Determine what kind of invalid operation was seen. */
if (float64_is_infinity(arg1) && float64_is_infinity(arg2)) { if (float64_is_infinity(arg1) && float64_is_infinity(arg2)) {
/* Division of infinity by infinity */ /* 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)) { } else if (float64_is_zero(arg1) && float64_is_zero(arg2)) {
/* Division of zero by zero */ /* 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) || } else if (float64_is_signaling_nan(arg1, &env->fp_status) ||
float64_is_signaling_nan(arg2, &env->fp_status)) { float64_is_signaling_nan(arg2, &env->fp_status)) {
/* sNaN division */ /* sNaN division */
float_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1); float_invalid_op_vxsnan(env, GETPC());
} }
} }
if (status & float_flag_divbyzero) { if (status & float_flag_divbyzero) {
@ -724,14 +748,14 @@ uint64_t helper_##op(CPUPPCState *env, uint64_t arg) \
\ \
if (unlikely(env->fp_status.float_exception_flags)) { \ if (unlikely(env->fp_status.float_exception_flags)) { \
if (float64_is_any_nan(arg)) { \ 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)) { \ 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; \ farg.ll = nanval; \
} else if (env->fp_status.float_exception_flags & \ } else if (env->fp_status.float_exception_flags & \
float_flag_invalid) { \ float_flag_invalid) { \
float_invalid_op_excp(env, POWERPC_EXCP_FP_VXCVI, 1); \ float_invalid_op_vxcvi(env, 1, GETPC()); \
} \ } \
float_check_status(env); \ float_check_status(env); \
} \ } \
@ -776,7 +800,7 @@ static inline uint64_t do_fri(CPUPPCState *env, uint64_t arg,
if (unlikely(float64_is_signaling_nan(farg.d, &env->fp_status))) { if (unlikely(float64_is_signaling_nan(farg.d, &env->fp_status))) {
/* sNaN round */ /* sNaN round */
float_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1); float_invalid_op_vxsnan(env, GETPC());
farg.ll = arg | 0x0008000000000000ULL; farg.ll = arg | 0x0008000000000000ULL;
} else { } else {
int inexact = get_float_exception_flags(&env->fp_status) & int inexact = get_float_exception_flags(&env->fp_status) &
@ -817,18 +841,18 @@ uint64_t helper_frim(CPUPPCState *env, uint64_t arg)
#define FPU_MADDSUB_UPDATE(NAME, TP) \ #define FPU_MADDSUB_UPDATE(NAME, TP) \
static void NAME(CPUPPCState *env, TP arg1, TP arg2, TP arg3, \ 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) || \ if (TP##_is_signaling_nan(arg1, &env->fp_status) || \
TP##_is_signaling_nan(arg2, &env->fp_status) || \ TP##_is_signaling_nan(arg2, &env->fp_status) || \
TP##_is_signaling_nan(arg3, &env->fp_status)) { \ TP##_is_signaling_nan(arg3, &env->fp_status)) { \
/* sNaN operation */ \ /* 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)) || \ if ((TP##_is_infinity(arg1) && TP##_is_zero(arg2)) || \
(TP##_is_zero(arg1) && TP##_is_infinity(arg2))) { \ (TP##_is_zero(arg1) && TP##_is_infinity(arg2))) { \
/* Multiplication of zero by infinity */ \ /* 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)) && \ if ((TP##_is_infinity(arg1) || TP##_is_infinity(arg2)) && \
TP##_is_infinity(arg3)) { \ TP##_is_infinity(arg3)) { \
@ -841,7 +865,7 @@ static void NAME(CPUPPCState *env, TP arg1, TP arg2, TP arg3, \
cSign ^= 1; \ cSign ^= 1; \
} \ } \
if (aSign ^ bSign ^ cSign) { \ if (aSign ^ bSign ^ cSign) { \
float_invalid_op_excp(env, POWERPC_EXCP_FP_VXISI, 1); \ float_invalid_op_vxisi(env, 1, retaddr); \
} \ } \
} \ } \
} }
@ -859,7 +883,7 @@ uint64_t helper_##op(CPUPPCState *env, uint64_t arg1, \
if (flags) { \ if (flags) { \
if (flags & float_flag_invalid) { \ if (flags & float_flag_invalid) { \
float64_maddsub_update_excp(env, arg1, arg2, arg3, \ float64_maddsub_update_excp(env, arg1, arg2, arg3, \
madd_flags); \ madd_flags, GETPC()); \
} \ } \
float_check_status(env); \ float_check_status(env); \
} \ } \
@ -885,8 +909,7 @@ uint64_t helper_frsp(CPUPPCState *env, uint64_t arg)
farg.ll = arg; farg.ll = arg;
if (unlikely(float64_is_signaling_nan(farg.d, &env->fp_status))) { if (unlikely(float64_is_signaling_nan(farg.d, &env->fp_status))) {
/* sNaN square root */ float_invalid_op_vxsnan(env, GETPC());
float_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1);
} }
f32 = float64_to_float32(farg.d, &env->fp_status); f32 = float64_to_float32(farg.d, &env->fp_status);
farg.d = float32_to_float64(f32, &env->fp_status); farg.d = float32_to_float64(f32, &env->fp_status);
@ -904,11 +927,11 @@ float64 helper_fsqrt(CPUPPCState *env, float64 arg)
if (unlikely(float64_is_any_nan(arg))) { if (unlikely(float64_is_any_nan(arg))) {
if (unlikely(float64_is_signaling_nan(arg, &env->fp_status))) { if (unlikely(float64_is_signaling_nan(arg, &env->fp_status))) {
/* sNaN square root */ /* sNaN square root */
float_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1); float_invalid_op_vxsnan(env, GETPC());
} }
} else { } else {
/* Square root of a negative nonzero number */ /* Square root of a negative nonzero number */
float_invalid_op_excp(env, POWERPC_EXCP_FP_VXSQRT, 1); float_invalid_op_vxsqrt(env, 1, GETPC());
} }
} }
@ -926,7 +949,7 @@ float64 helper_fre(CPUPPCState *env, float64 arg)
if (status & float_flag_invalid) { if (status & float_flag_invalid) {
if (float64_is_signaling_nan(arg, &env->fp_status)) { if (float64_is_signaling_nan(arg, &env->fp_status)) {
/* sNaN reciprocal */ /* sNaN reciprocal */
float_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1); float_invalid_op_vxsnan(env, GETPC());
} }
} }
if (status & float_flag_divbyzero) { if (status & float_flag_divbyzero) {
@ -949,7 +972,7 @@ uint64_t helper_fres(CPUPPCState *env, uint64_t arg)
if (unlikely(float64_is_signaling_nan(farg.d, &env->fp_status))) { if (unlikely(float64_is_signaling_nan(farg.d, &env->fp_status))) {
/* sNaN reciprocal */ /* 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); farg.d = float64_div(float64_one, farg.d, &env->fp_status);
f32 = float64_to_float32(farg.d, &env->fp_status); f32 = float64_to_float32(farg.d, &env->fp_status);
@ -970,10 +993,10 @@ float64 helper_frsqrte(CPUPPCState *env, float64 arg)
if (status & float_flag_invalid) { if (status & float_flag_invalid) {
if (float64_is_signaling_nan(arg, &env->fp_status)) { if (float64_is_signaling_nan(arg, &env->fp_status)) {
/* sNaN reciprocal */ /* sNaN reciprocal */
float_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1); float_invalid_op_vxsnan(env, GETPC());
} else { } else {
/* Square root of a negative nonzero number */ /* 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) { if (status & float_flag_divbyzero) {
@ -1095,7 +1118,7 @@ void helper_fcmpu(CPUPPCState *env, uint64_t arg1, uint64_t arg2,
&& (float64_is_signaling_nan(farg1.d, &env->fp_status) || && (float64_is_signaling_nan(farg1.d, &env->fp_status) ||
float64_is_signaling_nan(farg2.d, &env->fp_status)))) { float64_is_signaling_nan(farg2.d, &env->fp_status)))) {
/* sNaN comparison */ /* sNaN comparison */
float_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1); float_invalid_op_vxsnan(env, GETPC());
} }
} }
@ -1123,14 +1146,11 @@ void helper_fcmpo(CPUPPCState *env, uint64_t arg1, uint64_t arg2,
env->fpscr |= ret << FPSCR_FPRF; env->fpscr |= ret << FPSCR_FPRF;
env->crf[crfD] = ret; env->crf[crfD] = ret;
if (unlikely(ret == 0x01UL)) { if (unlikely(ret == 0x01UL)) {
float_invalid_op_vxvc(env, 1, GETPC());
if (float64_is_signaling_nan(farg1.d, &env->fp_status) || if (float64_is_signaling_nan(farg1.d, &env->fp_status) ||
float64_is_signaling_nan(farg2.d, &env->fp_status)) { float64_is_signaling_nan(farg2.d, &env->fp_status)) {
/* sNaN comparison */ /* sNaN comparison */
float_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN | float_invalid_op_vxsnan(env, GETPC());
POWERPC_EXCP_FP_VXVC, 1);
} else {
/* qNaN comparison */
float_invalid_op_excp(env, POWERPC_EXCP_FP_VXVC, 1);
} }
} }
} }
@ -1783,10 +1803,10 @@ void helper_##name(CPUPPCState *env, uint32_t opcode) \
\ \
if (unlikely(tstat.float_exception_flags & float_flag_invalid)) { \ if (unlikely(tstat.float_exception_flags & float_flag_invalid)) { \
if (tp##_is_infinity(xa.fld) && tp##_is_infinity(xb.fld)) { \ 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) || \ } else if (tp##_is_signaling_nan(xa.fld, &tstat) || \
tp##_is_signaling_nan(xb.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()); \
} \ } \
} \ } \
\ \
@ -1832,10 +1852,10 @@ void helper_xsaddqp(CPUPPCState *env, uint32_t opcode)
if (unlikely(tstat.float_exception_flags & float_flag_invalid)) { if (unlikely(tstat.float_exception_flags & float_flag_invalid)) {
if (float128_is_infinity(xa.f128) && float128_is_infinity(xb.f128)) { 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) || } else if (float128_is_signaling_nan(xa.f128, &tstat) ||
float128_is_signaling_nan(xb.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());
} }
} }
@ -1872,10 +1892,10 @@ void helper_##op(CPUPPCState *env, uint32_t opcode) \
if (unlikely(tstat.float_exception_flags & float_flag_invalid)) { \ if (unlikely(tstat.float_exception_flags & float_flag_invalid)) { \
if ((tp##_is_infinity(xa.fld) && tp##_is_zero(xb.fld)) || \ if ((tp##_is_infinity(xa.fld) && tp##_is_zero(xb.fld)) || \
(tp##_is_infinity(xb.fld) && tp##_is_zero(xa.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) || \ } else if (tp##_is_signaling_nan(xa.fld, &tstat) || \
tp##_is_signaling_nan(xb.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()); \
} \ } \
} \ } \
\ \
@ -1919,10 +1939,10 @@ void helper_xsmulqp(CPUPPCState *env, uint32_t opcode)
if (unlikely(tstat.float_exception_flags & float_flag_invalid)) { if (unlikely(tstat.float_exception_flags & float_flag_invalid)) {
if ((float128_is_infinity(xa.f128) && float128_is_zero(xb.f128)) || if ((float128_is_infinity(xa.f128) && float128_is_zero(xb.f128)) ||
(float128_is_infinity(xb.f128) && float128_is_zero(xa.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) || } else if (float128_is_signaling_nan(xa.f128, &tstat) ||
float128_is_signaling_nan(xb.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); helper_compute_fprf_float128(env, xt.f128);
@ -1957,13 +1977,12 @@ void helper_##op(CPUPPCState *env, uint32_t opcode) \
\ \
if (unlikely(tstat.float_exception_flags & float_flag_invalid)) { \ if (unlikely(tstat.float_exception_flags & float_flag_invalid)) { \
if (tp##_is_infinity(xa.fld) && tp##_is_infinity(xb.fld)) { \ if (tp##_is_infinity(xa.fld) && tp##_is_infinity(xb.fld)) { \
float_invalid_op_excp(env, POWERPC_EXCP_FP_VXIDI, sfprf); \ float_invalid_op_vxidi(env, sfprf, GETPC()); \
} else if (tp##_is_zero(xa.fld) && \ } else if (tp##_is_zero(xa.fld) && tp##_is_zero(xb.fld)) { \
tp##_is_zero(xb.fld)) { \ float_invalid_op_vxzdz(env, sfprf, GETPC()); \
float_invalid_op_excp(env, POWERPC_EXCP_FP_VXZDZ, sfprf); \
} else if (tp##_is_signaling_nan(xa.fld, &tstat) || \ } else if (tp##_is_signaling_nan(xa.fld, &tstat) || \
tp##_is_signaling_nan(xb.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_divbyzero)) { \ if (unlikely(tstat.float_exception_flags & float_flag_divbyzero)) { \
@ -2009,13 +2028,12 @@ void helper_xsdivqp(CPUPPCState *env, uint32_t opcode)
if (unlikely(tstat.float_exception_flags & float_flag_invalid)) { if (unlikely(tstat.float_exception_flags & float_flag_invalid)) {
if (float128_is_infinity(xa.f128) && float128_is_infinity(xb.f128)) { if (float128_is_infinity(xa.f128) && float128_is_infinity(xb.f128)) {
float_invalid_op_excp(env, POWERPC_EXCP_FP_VXIDI, 1); float_invalid_op_vxidi(env, 1, GETPC());
} else if (float128_is_zero(xa.f128) && } else if (float128_is_zero(xa.f128) && float128_is_zero(xb.f128)) {
float128_is_zero(xb.f128)) { float_invalid_op_vxzdz(env, 1, GETPC());
float_invalid_op_excp(env, POWERPC_EXCP_FP_VXZDZ, 1);
} else if (float128_is_signaling_nan(xa.f128, &tstat) || } else if (float128_is_signaling_nan(xa.f128, &tstat) ||
float128_is_signaling_nan(xb.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_divbyzero)) { if (unlikely(tstat.float_exception_flags & float_flag_divbyzero)) {
@ -2046,7 +2064,7 @@ void helper_##op(CPUPPCState *env, uint32_t opcode) \
\ \
for (i = 0; i < nels; i++) { \ for (i = 0; i < nels; i++) { \
if (unlikely(tp##_is_signaling_nan(xb.fld, &env->fp_status))) { \ 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); \ xt.fld = tp##_div(tp##_one, xb.fld, &env->fp_status); \
\ \
@ -2093,9 +2111,9 @@ void helper_##op(CPUPPCState *env, uint32_t opcode) \
\ \
if (unlikely(tstat.float_exception_flags & float_flag_invalid)) { \ if (unlikely(tstat.float_exception_flags & float_flag_invalid)) { \
if (tp##_is_neg(xb.fld) && !tp##_is_zero(xb.fld)) { \ 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)) { \ } 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()); \
} \ } \
} \ } \
\ \
@ -2143,9 +2161,9 @@ void helper_##op(CPUPPCState *env, uint32_t opcode) \
\ \
if (unlikely(tstat.float_exception_flags & float_flag_invalid)) { \ if (unlikely(tstat.float_exception_flags & float_flag_invalid)) { \
if (tp##_is_neg(xb.fld) && !tp##_is_zero(xb.fld)) { \ 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)) { \ } 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()); \
} \ } \
} \ } \
\ \
@ -2329,7 +2347,8 @@ void helper_##op(CPUPPCState *env, uint32_t opcode) \
env->fp_status.float_exception_flags |= tstat.float_exception_flags; \ env->fp_status.float_exception_flags |= tstat.float_exception_flags; \
\ \
if (unlikely(tstat.float_exception_flags & float_flag_invalid)) { \ 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) { \ if (r2sp) { \
@ -2407,10 +2426,10 @@ void helper_##op(CPUPPCState *env, uint32_t opcode) \
float64_is_quiet_nan(xb.VsrD(0), &env->fp_status); \ float64_is_quiet_nan(xb.VsrD(0), &env->fp_status); \
} \ } \
if (vxsnan_flag) { \ if (vxsnan_flag) { \
float_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 0); \ float_invalid_op_vxsnan(env, GETPC()); \
} \ } \
if (vxvc_flag) { \ 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); \ vex_flag = fpscr_ve && (vxvc_flag || vxsnan_flag); \
\ \
@ -2522,10 +2541,10 @@ void helper_##op(CPUPPCState *env, uint32_t opcode) \
} \ } \
} \ } \
if (vxsnan_flag) { \ if (vxsnan_flag) { \
float_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 0); \ float_invalid_op_vxsnan(env, GETPC()); \
} \ } \
if (vxvc_flag) { \ 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 (float64_lt(xa.VsrD(0), xb.VsrD(0), &env->fp_status)) { \
@ -2572,10 +2591,10 @@ void helper_##op(CPUPPCState *env, uint32_t opcode) \
} \ } \
} \ } \
if (vxsnan_flag) { \ if (vxsnan_flag) { \
float_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 0); \ float_invalid_op_vxsnan(env, GETPC()); \
} \ } \
if (vxvc_flag) { \ 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)) { \ if (float128_lt(xa.f128, xb.f128, &env->fp_status)) { \
@ -2617,7 +2636,7 @@ void helper_##name(CPUPPCState *env, uint32_t opcode) \
xt.fld = tp##_##op(xa.fld, xb.fld, &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) || \ if (unlikely(tp##_is_signaling_nan(xa.fld, &env->fp_status) || \
tp##_is_signaling_nan(xb.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()); \
} \ } \
} \ } \
\ \
@ -2660,7 +2679,7 @@ void helper_##name(CPUPPCState *env, uint32_t opcode) \
\ \
vex_flag = fpscr_ve & vxsnan_flag; \ vex_flag = fpscr_ve & vxsnan_flag; \
if (vxsnan_flag) { \ if (vxsnan_flag) { \
float_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 0); \ float_invalid_op_vxsnan(env, GETPC()); \
} \ } \
if (!vex_flag) { \ if (!vex_flag) { \
putVSR(rD(opcode) + 32, &xt, env); \ putVSR(rD(opcode) + 32, &xt, env); \
@ -2715,7 +2734,7 @@ void helper_##name(CPUPPCState *env, uint32_t opcode) \
\ \
vex_flag = fpscr_ve & vxsnan_flag; \ vex_flag = fpscr_ve & vxsnan_flag; \
if (vxsnan_flag) { \ if (vxsnan_flag) { \
float_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 0); \ float_invalid_op_vxsnan(env, GETPC()); \
} \ } \
if (!vex_flag) { \ if (!vex_flag) { \
putVSR(rD(opcode) + 32, &xt, env); \ putVSR(rD(opcode) + 32, &xt, env); \
@ -2751,10 +2770,10 @@ void helper_##op(CPUPPCState *env, uint32_t opcode) \
tp##_is_any_nan(xb.fld))) { \ tp##_is_any_nan(xb.fld))) { \
if (tp##_is_signaling_nan(xa.fld, &env->fp_status) || \ if (tp##_is_signaling_nan(xa.fld, &env->fp_status) || \
tp##_is_signaling_nan(xb.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) { \ if (svxvc) { \
float_invalid_op_excp(env, POWERPC_EXCP_FP_VXVC, 0); \ float_invalid_op_vxvc(env, 0, GETPC()); \
} \ } \
xt.fld = 0; \ xt.fld = 0; \
all_true = 0; \ all_true = 0; \
@ -2807,7 +2826,7 @@ void helper_##op(CPUPPCState *env, uint32_t opcode) \
xt.tfld = stp##_to_##ttp(xb.sfld, &env->fp_status); \ xt.tfld = stp##_to_##ttp(xb.sfld, &env->fp_status); \
if (unlikely(stp##_is_signaling_nan(xb.sfld, \ if (unlikely(stp##_is_signaling_nan(xb.sfld, \
&env->fp_status))) { \ &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); \ xt.tfld = ttp##_snan_to_qnan(xt.tfld); \
} \ } \
if (sfprf) { \ if (sfprf) { \
@ -2846,7 +2865,7 @@ void helper_##op(CPUPPCState *env, uint32_t opcode) \
xt.tfld = stp##_to_##ttp(xb.sfld, &env->fp_status); \ xt.tfld = stp##_to_##ttp(xb.sfld, &env->fp_status); \
if (unlikely(stp##_is_signaling_nan(xb.sfld, \ if (unlikely(stp##_is_signaling_nan(xb.sfld, \
&env->fp_status))) { \ &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); \ xt.tfld = ttp##_snan_to_qnan(xt.tfld); \
} \ } \
if (sfprf) { \ if (sfprf) { \
@ -2883,7 +2902,7 @@ void helper_##op(CPUPPCState *env, uint32_t opcode) \
xt.tfld = stp##_to_##ttp(xb.sfld, 1, &env->fp_status); \ xt.tfld = stp##_to_##ttp(xb.sfld, 1, &env->fp_status); \
if (unlikely(stp##_is_signaling_nan(xb.sfld, \ if (unlikely(stp##_is_signaling_nan(xb.sfld, \
&env->fp_status))) { \ &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); \ xt.tfld = ttp##_snan_to_qnan(xt.tfld); \
} \ } \
if (sfprf) { \ if (sfprf) { \
@ -2919,9 +2938,8 @@ void helper_xscvqpdp(CPUPPCState *env, uint32_t opcode)
xt.VsrD(0) = float128_to_float64(xb.f128, &tstat); xt.VsrD(0) = float128_to_float64(xb.f128, &tstat);
env->fp_status.float_exception_flags |= tstat.float_exception_flags; env->fp_status.float_exception_flags |= tstat.float_exception_flags;
if (unlikely(float128_is_signaling_nan(xb.f128, if (unlikely(float128_is_signaling_nan(xb.f128, &tstat))) {
&tstat))) { float_invalid_op_vxsnan(env, GETPC());
float_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 0);
xt.VsrD(0) = float64_snan_to_qnan(xt.VsrD(0)); xt.VsrD(0) = float64_snan_to_qnan(xt.VsrD(0));
} }
helper_compute_fprf_float64(env, xt.VsrD(0)); helper_compute_fprf_float64(env, xt.VsrD(0));
@ -2967,15 +2985,15 @@ void helper_##op(CPUPPCState *env, uint32_t opcode) \
for (i = 0; i < nels; i++) { \ for (i = 0; i < nels; i++) { \
if (unlikely(stp##_is_any_nan(xb.sfld))) { \ if (unlikely(stp##_is_any_nan(xb.sfld))) { \
if (stp##_is_signaling_nan(xb.sfld, &env->fp_status)) { \ 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; \ xt.tfld = rnan; \
} else { \ } else { \
xt.tfld = stp##_to_##ttp##_round_to_zero(xb.sfld, \ xt.tfld = stp##_to_##ttp##_round_to_zero(xb.sfld, \
&env->fp_status); \ &env->fp_status); \
if (env->fp_status.float_exception_flags & float_flag_invalid) { \ 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()); \
} \ } \
} \ } \
} \ } \
@ -3020,15 +3038,15 @@ void helper_##op(CPUPPCState *env, uint32_t opcode) \
\ \
if (unlikely(stp##_is_any_nan(xb.sfld))) { \ if (unlikely(stp##_is_any_nan(xb.sfld))) { \
if (stp##_is_signaling_nan(xb.sfld, &env->fp_status)) { \ 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; \ xt.tfld = rnan; \
} else { \ } else { \
xt.tfld = stp##_to_##ttp##_round_to_zero(xb.sfld, \ xt.tfld = stp##_to_##ttp##_round_to_zero(xb.sfld, \
&env->fp_status); \ &env->fp_status); \
if (env->fp_status.float_exception_flags & float_flag_invalid) { \ 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()); \
} \ } \
} \ } \
\ \
@ -3144,7 +3162,7 @@ void helper_##op(CPUPPCState *env, uint32_t opcode) \
for (i = 0; i < nels; i++) { \ for (i = 0; i < nels; i++) { \
if (unlikely(tp##_is_signaling_nan(xb.fld, \ if (unlikely(tp##_is_signaling_nan(xb.fld, \
&env->fp_status))) { \ &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); \ xt.fld = tp##_snan_to_qnan(xb.fld); \
} else { \ } else { \
xt.fld = tp##_round_to_int(xb.fld, &env->fp_status); \ xt.fld = tp##_round_to_int(xb.fld, &env->fp_status); \
@ -3373,7 +3391,7 @@ void helper_xsrqpi(CPUPPCState *env, uint32_t opcode)
if (unlikely(tstat.float_exception_flags & float_flag_invalid)) { if (unlikely(tstat.float_exception_flags & float_flag_invalid)) {
if (float128_is_signaling_nan(xb.f128, &tstat)) { 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); xt.f128 = float128_snan_to_qnan(xt.f128);
} }
} }
@ -3433,7 +3451,7 @@ void helper_xsrqpxp(CPUPPCState *env, uint32_t opcode)
if (unlikely(tstat.float_exception_flags & float_flag_invalid)) { if (unlikely(tstat.float_exception_flags & float_flag_invalid)) {
if (float128_is_signaling_nan(xb.f128, &tstat)) { 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); xt.f128 = float128_snan_to_qnan(xt.f128);
} }
} }
@ -3464,12 +3482,12 @@ void helper_xssqrtqp(CPUPPCState *env, uint32_t opcode)
if (unlikely(tstat.float_exception_flags & float_flag_invalid)) { if (unlikely(tstat.float_exception_flags & float_flag_invalid)) {
if (float128_is_signaling_nan(xb.f128, &tstat)) { 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); xt.f128 = float128_snan_to_qnan(xb.f128);
} else if (float128_is_quiet_nan(xb.f128, &tstat)) { } else if (float128_is_quiet_nan(xb.f128, &tstat)) {
xt.f128 = xb.f128; xt.f128 = xb.f128;
} else if (float128_is_neg(xb.f128) && !float128_is_zero(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); xt.f128 = float128_default_nan(&env->fp_status);
} }
} }
@ -3500,10 +3518,10 @@ void helper_xssubqp(CPUPPCState *env, uint32_t opcode)
if (unlikely(tstat.float_exception_flags & float_flag_invalid)) { if (unlikely(tstat.float_exception_flags & float_flag_invalid)) {
if (float128_is_infinity(xa.f128) && float128_is_infinity(xb.f128)) { 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) || } else if (float128_is_signaling_nan(xa.f128, &tstat) ||
float128_is_signaling_nan(xb.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());
} }
} }