aboutsummaryrefslogtreecommitdiff
path: root/target/ppc/fpu_helper.c
diff options
context:
space:
mode:
Diffstat (limited to 'target/ppc/fpu_helper.c')
-rw-r--r--target/ppc/fpu_helper.c841
1 files changed, 362 insertions, 479 deletions
diff --git a/target/ppc/fpu_helper.c b/target/ppc/fpu_helper.c
index ffbd19afa1..f437c88aad 100644
--- a/target/ppc/fpu_helper.c
+++ b/target/ppc/fpu_helper.c
@@ -1801,37 +1801,35 @@ uint32_t helper_efdcmpeq(CPUPPCState *env, uint64_t op1, uint64_t op2)
* sfprf - set FPRF
*/
#define VSX_ADD_SUB(name, op, nels, tp, fld, sfprf, r2sp) \
-void helper_##name(CPUPPCState *env, uint32_t opcode) \
+void helper_##name(CPUPPCState *env, ppc_vsr_t *xt, \
+ ppc_vsr_t *xa, ppc_vsr_t *xb) \
{ \
- ppc_vsr_t xt, xa, xb; \
+ ppc_vsr_t t = *xt; \
int i; \
\
- getVSR(xA(opcode), &xa, env); \
- getVSR(xB(opcode), &xb, env); \
- getVSR(xT(opcode), &xt, env); \
helper_reset_fpstatus(env); \
\
for (i = 0; i < nels; i++) { \
float_status tstat = env->fp_status; \
set_float_exception_flags(0, &tstat); \
- xt.fld = tp##_##op(xa.fld, xb.fld, &tstat); \
+ t.fld = tp##_##op(xa->fld, xb->fld, &tstat); \
env->fp_status.float_exception_flags |= tstat.float_exception_flags; \
\
if (unlikely(tstat.float_exception_flags & float_flag_invalid)) { \
float_invalid_op_addsub(env, sfprf, GETPC(), \
- tp##_classify(xa.fld) | \
- tp##_classify(xb.fld)); \
+ tp##_classify(xa->fld) | \
+ tp##_classify(xb->fld)); \
} \
\
if (r2sp) { \
- xt.fld = helper_frsp(env, xt.fld); \
+ t.fld = helper_frsp(env, t.fld); \
} \
\
if (sfprf) { \
- helper_compute_fprf_float64(env, xt.fld); \
+ helper_compute_fprf_float64(env, t.fld); \
} \
} \
- putVSR(xT(opcode), &xt, env); \
+ *xt = t; \
do_float_check_status(env, GETPC()); \
}
@@ -1844,14 +1842,12 @@ VSX_ADD_SUB(xssubsp, sub, 1, float64, VsrD(0), 1, 1)
VSX_ADD_SUB(xvsubdp, sub, 2, float64, VsrD(i), 0, 0)
VSX_ADD_SUB(xvsubsp, sub, 4, float32, VsrW(i), 0, 0)
-void helper_xsaddqp(CPUPPCState *env, uint32_t opcode)
+void helper_xsaddqp(CPUPPCState *env, uint32_t opcode,
+ ppc_vsr_t *xt, ppc_vsr_t *xa, ppc_vsr_t *xb)
{
- ppc_vsr_t xt, xa, xb;
+ ppc_vsr_t t = *xt;
float_status tstat;
- getVSR(rA(opcode) + 32, &xa, env);
- getVSR(rB(opcode) + 32, &xb, env);
- getVSR(rD(opcode) + 32, &xt, env);
helper_reset_fpstatus(env);
tstat = env->fp_status;
@@ -1860,18 +1856,18 @@ void helper_xsaddqp(CPUPPCState *env, uint32_t opcode)
}
set_float_exception_flags(0, &tstat);
- xt.f128 = float128_add(xa.f128, xb.f128, &tstat);
+ t.f128 = float128_add(xa->f128, xb->f128, &tstat);
env->fp_status.float_exception_flags |= tstat.float_exception_flags;
if (unlikely(tstat.float_exception_flags & float_flag_invalid)) {
float_invalid_op_addsub(env, 1, GETPC(),
- float128_classify(xa.f128) |
- float128_classify(xb.f128));
+ float128_classify(xa->f128) |
+ float128_classify(xb->f128));
}
- helper_compute_fprf_float128(env, xt.f128);
+ helper_compute_fprf_float128(env, t.f128);
- putVSR(rD(opcode) + 32, &xt, env);
+ *xt = t;
do_float_check_status(env, GETPC());
}
@@ -1884,38 +1880,36 @@ void helper_xsaddqp(CPUPPCState *env, uint32_t opcode)
* sfprf - set FPRF
*/
#define VSX_MUL(op, nels, tp, fld, sfprf, r2sp) \
-void helper_##op(CPUPPCState *env, uint32_t opcode) \
+void helper_##op(CPUPPCState *env, ppc_vsr_t *xt, \
+ ppc_vsr_t *xa, ppc_vsr_t *xb) \
{ \
- ppc_vsr_t xt, xa, xb; \
+ ppc_vsr_t t = *xt; \
int i; \
\
- getVSR(xA(opcode), &xa, env); \
- getVSR(xB(opcode), &xb, env); \
- getVSR(xT(opcode), &xt, env); \
helper_reset_fpstatus(env); \
\
for (i = 0; i < nels; i++) { \
float_status tstat = env->fp_status; \
set_float_exception_flags(0, &tstat); \
- xt.fld = tp##_mul(xa.fld, xb.fld, &tstat); \
+ t.fld = tp##_mul(xa->fld, xb->fld, &tstat); \
env->fp_status.float_exception_flags |= tstat.float_exception_flags; \
\
if (unlikely(tstat.float_exception_flags & float_flag_invalid)) { \
float_invalid_op_mul(env, sfprf, GETPC(), \
- tp##_classify(xa.fld) | \
- tp##_classify(xb.fld)); \
+ tp##_classify(xa->fld) | \
+ tp##_classify(xb->fld)); \
} \
\
if (r2sp) { \
- xt.fld = helper_frsp(env, xt.fld); \
+ t.fld = helper_frsp(env, t.fld); \
} \
\
if (sfprf) { \
- helper_compute_fprf_float64(env, xt.fld); \
+ helper_compute_fprf_float64(env, t.fld); \
} \
} \
\
- putVSR(xT(opcode), &xt, env); \
+ *xt = t; \
do_float_check_status(env, GETPC()); \
}
@@ -1924,15 +1918,12 @@ VSX_MUL(xsmulsp, 1, float64, VsrD(0), 1, 1)
VSX_MUL(xvmuldp, 2, float64, VsrD(i), 0, 0)
VSX_MUL(xvmulsp, 4, float32, VsrW(i), 0, 0)
-void helper_xsmulqp(CPUPPCState *env, uint32_t opcode)
+void helper_xsmulqp(CPUPPCState *env, uint32_t opcode,
+ ppc_vsr_t *xt, ppc_vsr_t *xa, ppc_vsr_t *xb)
{
- ppc_vsr_t xt, xa, xb;
+ ppc_vsr_t t = *xt;
float_status tstat;
- getVSR(rA(opcode) + 32, &xa, env);
- getVSR(rB(opcode) + 32, &xb, env);
- getVSR(rD(opcode) + 32, &xt, env);
-
helper_reset_fpstatus(env);
tstat = env->fp_status;
if (unlikely(Rc(opcode) != 0)) {
@@ -1940,17 +1931,17 @@ void helper_xsmulqp(CPUPPCState *env, uint32_t opcode)
}
set_float_exception_flags(0, &tstat);
- xt.f128 = float128_mul(xa.f128, xb.f128, &tstat);
+ t.f128 = float128_mul(xa->f128, xb->f128, &tstat);
env->fp_status.float_exception_flags |= tstat.float_exception_flags;
if (unlikely(tstat.float_exception_flags & float_flag_invalid)) {
float_invalid_op_mul(env, 1, GETPC(),
- float128_classify(xa.f128) |
- float128_classify(xb.f128));
+ float128_classify(xa->f128) |
+ float128_classify(xb->f128));
}
- helper_compute_fprf_float128(env, xt.f128);
+ helper_compute_fprf_float128(env, t.f128);
- putVSR(rD(opcode) + 32, &xt, env);
+ *xt = t;
do_float_check_status(env, GETPC());
}
@@ -1963,41 +1954,39 @@ void helper_xsmulqp(CPUPPCState *env, uint32_t opcode)
* sfprf - set FPRF
*/
#define VSX_DIV(op, nels, tp, fld, sfprf, r2sp) \
-void helper_##op(CPUPPCState *env, uint32_t opcode) \
+void helper_##op(CPUPPCState *env, ppc_vsr_t *xt, \
+ ppc_vsr_t *xa, ppc_vsr_t *xb) \
{ \
- ppc_vsr_t xt, xa, xb; \
+ ppc_vsr_t t = *xt; \
int i; \
\
- getVSR(xA(opcode), &xa, env); \
- getVSR(xB(opcode), &xb, env); \
- getVSR(xT(opcode), &xt, env); \
helper_reset_fpstatus(env); \
\
for (i = 0; i < nels; i++) { \
float_status tstat = env->fp_status; \
set_float_exception_flags(0, &tstat); \
- xt.fld = tp##_div(xa.fld, xb.fld, &tstat); \
+ t.fld = tp##_div(xa->fld, xb->fld, &tstat); \
env->fp_status.float_exception_flags |= tstat.float_exception_flags; \
\
if (unlikely(tstat.float_exception_flags & float_flag_invalid)) { \
float_invalid_op_div(env, sfprf, GETPC(), \
- tp##_classify(xa.fld) | \
- tp##_classify(xb.fld)); \
+ tp##_classify(xa->fld) | \
+ tp##_classify(xb->fld)); \
} \
if (unlikely(tstat.float_exception_flags & float_flag_divbyzero)) { \
float_zero_divide_excp(env, GETPC()); \
} \
\
if (r2sp) { \
- xt.fld = helper_frsp(env, xt.fld); \
+ t.fld = helper_frsp(env, t.fld); \
} \
\
if (sfprf) { \
- helper_compute_fprf_float64(env, xt.fld); \
+ helper_compute_fprf_float64(env, t.fld); \
} \
} \
\
- putVSR(xT(opcode), &xt, env); \
+ *xt = t; \
do_float_check_status(env, GETPC()); \
}
@@ -2006,15 +1995,12 @@ VSX_DIV(xsdivsp, 1, float64, VsrD(0), 1, 1)
VSX_DIV(xvdivdp, 2, float64, VsrD(i), 0, 0)
VSX_DIV(xvdivsp, 4, float32, VsrW(i), 0, 0)
-void helper_xsdivqp(CPUPPCState *env, uint32_t opcode)
+void helper_xsdivqp(CPUPPCState *env, uint32_t opcode,
+ ppc_vsr_t *xt, ppc_vsr_t *xa, ppc_vsr_t *xb)
{
- ppc_vsr_t xt, xa, xb;
+ ppc_vsr_t t = *xt;
float_status tstat;
- getVSR(rA(opcode) + 32, &xa, env);
- getVSR(rB(opcode) + 32, &xb, env);
- getVSR(rD(opcode) + 32, &xt, env);
-
helper_reset_fpstatus(env);
tstat = env->fp_status;
if (unlikely(Rc(opcode) != 0)) {
@@ -2022,20 +2008,20 @@ void helper_xsdivqp(CPUPPCState *env, uint32_t opcode)
}
set_float_exception_flags(0, &tstat);
- xt.f128 = float128_div(xa.f128, xb.f128, &tstat);
+ t.f128 = float128_div(xa->f128, xb->f128, &tstat);
env->fp_status.float_exception_flags |= tstat.float_exception_flags;
if (unlikely(tstat.float_exception_flags & float_flag_invalid)) {
float_invalid_op_div(env, 1, GETPC(),
- float128_classify(xa.f128) |
- float128_classify(xb.f128));
+ float128_classify(xa->f128) |
+ float128_classify(xb->f128));
}
if (unlikely(tstat.float_exception_flags & float_flag_divbyzero)) {
float_zero_divide_excp(env, GETPC());
}
- helper_compute_fprf_float128(env, xt.f128);
- putVSR(rD(opcode) + 32, &xt, env);
+ helper_compute_fprf_float128(env, t.f128);
+ *xt = t;
do_float_check_status(env, GETPC());
}
@@ -2048,31 +2034,29 @@ void helper_xsdivqp(CPUPPCState *env, uint32_t opcode)
* sfprf - set FPRF
*/
#define VSX_RE(op, nels, tp, fld, sfprf, r2sp) \
-void helper_##op(CPUPPCState *env, uint32_t opcode) \
+void helper_##op(CPUPPCState *env, ppc_vsr_t *xt, ppc_vsr_t *xb) \
{ \
- ppc_vsr_t xt, xb; \
+ ppc_vsr_t t = *xt; \
int i; \
\
- getVSR(xB(opcode), &xb, env); \
- getVSR(xT(opcode), &xt, env); \
helper_reset_fpstatus(env); \
\
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_vxsnan(env, GETPC()); \
} \
- xt.fld = tp##_div(tp##_one, xb.fld, &env->fp_status); \
+ t.fld = tp##_div(tp##_one, xb->fld, &env->fp_status); \
\
if (r2sp) { \
- xt.fld = helper_frsp(env, xt.fld); \
+ t.fld = helper_frsp(env, t.fld); \
} \
\
if (sfprf) { \
- helper_compute_fprf_float64(env, xt.fld); \
+ helper_compute_fprf_float64(env, t.fld); \
} \
} \
\
- putVSR(xT(opcode), &xt, env); \
+ *xt = t; \
do_float_check_status(env, GETPC()); \
}
@@ -2090,39 +2074,37 @@ VSX_RE(xvresp, 4, float32, VsrW(i), 0, 0)
* sfprf - set FPRF
*/
#define VSX_SQRT(op, nels, tp, fld, sfprf, r2sp) \
-void helper_##op(CPUPPCState *env, uint32_t opcode) \
+void helper_##op(CPUPPCState *env, ppc_vsr_t *xt, ppc_vsr_t *xb) \
{ \
- ppc_vsr_t xt, xb; \
+ ppc_vsr_t t = *xt; \
int i; \
\
- getVSR(xB(opcode), &xb, env); \
- getVSR(xT(opcode), &xt, env); \
helper_reset_fpstatus(env); \
\
for (i = 0; i < nels; i++) { \
float_status tstat = env->fp_status; \
set_float_exception_flags(0, &tstat); \
- xt.fld = tp##_sqrt(xb.fld, &tstat); \
+ t.fld = tp##_sqrt(xb->fld, &tstat); \
env->fp_status.float_exception_flags |= tstat.float_exception_flags; \
\
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_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_vxsnan(env, GETPC()); \
} \
} \
\
if (r2sp) { \
- xt.fld = helper_frsp(env, xt.fld); \
+ t.fld = helper_frsp(env, t.fld); \
} \
\
if (sfprf) { \
- helper_compute_fprf_float64(env, xt.fld); \
+ helper_compute_fprf_float64(env, t.fld); \
} \
} \
\
- putVSR(xT(opcode), &xt, env); \
+ *xt = t; \
do_float_check_status(env, GETPC()); \
}
@@ -2140,40 +2122,38 @@ VSX_SQRT(xvsqrtsp, 4, float32, VsrW(i), 0, 0)
* sfprf - set FPRF
*/
#define VSX_RSQRTE(op, nels, tp, fld, sfprf, r2sp) \
-void helper_##op(CPUPPCState *env, uint32_t opcode) \
+void helper_##op(CPUPPCState *env, ppc_vsr_t *xt, ppc_vsr_t *xb) \
{ \
- ppc_vsr_t xt, xb; \
+ ppc_vsr_t t = *xt; \
int i; \
\
- getVSR(xB(opcode), &xb, env); \
- getVSR(xT(opcode), &xt, env); \
helper_reset_fpstatus(env); \
\
for (i = 0; i < nels; i++) { \
float_status tstat = env->fp_status; \
set_float_exception_flags(0, &tstat); \
- xt.fld = tp##_sqrt(xb.fld, &tstat); \
- xt.fld = tp##_div(tp##_one, xt.fld, &tstat); \
+ t.fld = tp##_sqrt(xb->fld, &tstat); \
+ t.fld = tp##_div(tp##_one, t.fld, &tstat); \
env->fp_status.float_exception_flags |= tstat.float_exception_flags; \
\
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_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_vxsnan(env, GETPC()); \
} \
} \
\
if (r2sp) { \
- xt.fld = helper_frsp(env, xt.fld); \
+ t.fld = helper_frsp(env, t.fld); \
} \
\
if (sfprf) { \
- helper_compute_fprf_float64(env, xt.fld); \
+ helper_compute_fprf_float64(env, t.fld); \
} \
} \
\
- putVSR(xT(opcode), &xt, env); \
+ *xt = t; \
do_float_check_status(env, GETPC()); \
}
@@ -2193,39 +2173,36 @@ VSX_RSQRTE(xvrsqrtesp, 4, float32, VsrW(i), 0, 0)
* nbits - number of fraction bits
*/
#define VSX_TDIV(op, nels, tp, fld, emin, emax, nbits) \
-void helper_##op(CPUPPCState *env, uint32_t opcode) \
+void helper_##op(CPUPPCState *env, uint32_t opcode, \
+ ppc_vsr_t *xa, ppc_vsr_t *xb) \
{ \
- ppc_vsr_t xa, xb; \
int i; \
int fe_flag = 0; \
int fg_flag = 0; \
\
- getVSR(xA(opcode), &xa, env); \
- getVSR(xB(opcode), &xb, env); \
- \
for (i = 0; i < nels; i++) { \
- if (unlikely(tp##_is_infinity(xa.fld) || \
- tp##_is_infinity(xb.fld) || \
- tp##_is_zero(xb.fld))) { \
+ if (unlikely(tp##_is_infinity(xa->fld) || \
+ tp##_is_infinity(xb->fld) || \
+ tp##_is_zero(xb->fld))) { \
fe_flag = 1; \
fg_flag = 1; \
} else { \
- int e_a = ppc_##tp##_get_unbiased_exp(xa.fld); \
- int e_b = ppc_##tp##_get_unbiased_exp(xb.fld); \
+ int e_a = ppc_##tp##_get_unbiased_exp(xa->fld); \
+ int e_b = ppc_##tp##_get_unbiased_exp(xb->fld); \
\
- if (unlikely(tp##_is_any_nan(xa.fld) || \
- tp##_is_any_nan(xb.fld))) { \
+ if (unlikely(tp##_is_any_nan(xa->fld) || \
+ tp##_is_any_nan(xb->fld))) { \
fe_flag = 1; \
} else if ((e_b <= emin) || (e_b >= (emax - 2))) { \
fe_flag = 1; \
- } else if (!tp##_is_zero(xa.fld) && \
+ } else if (!tp##_is_zero(xa->fld) && \
(((e_a - e_b) >= emax) || \
((e_a - e_b) <= (emin + 1)) || \
(e_a <= (emin + nbits)))) { \
fe_flag = 1; \
} \
\
- if (unlikely(tp##_is_zero_or_denormal(xb.fld))) { \
+ if (unlikely(tp##_is_zero_or_denormal(xb->fld))) { \
/* \
* XB is not zero because of the above check and so \
* must be denormalized. \
@@ -2253,36 +2230,32 @@ VSX_TDIV(xvtdivsp, 4, float32, VsrW(i), -126, 127, 23)
* nbits - number of fraction bits
*/
#define VSX_TSQRT(op, nels, tp, fld, emin, nbits) \
-void helper_##op(CPUPPCState *env, uint32_t opcode) \
+void helper_##op(CPUPPCState *env, uint32_t opcode, ppc_vsr_t *xb) \
{ \
- ppc_vsr_t xa, xb; \
int i; \
int fe_flag = 0; \
int fg_flag = 0; \
\
- getVSR(xA(opcode), &xa, env); \
- getVSR(xB(opcode), &xb, env); \
- \
for (i = 0; i < nels; i++) { \
- if (unlikely(tp##_is_infinity(xb.fld) || \
- tp##_is_zero(xb.fld))) { \
+ if (unlikely(tp##_is_infinity(xb->fld) || \
+ tp##_is_zero(xb->fld))) { \
fe_flag = 1; \
fg_flag = 1; \
} else { \
- int e_b = ppc_##tp##_get_unbiased_exp(xb.fld); \
+ int e_b = ppc_##tp##_get_unbiased_exp(xb->fld); \
\
- if (unlikely(tp##_is_any_nan(xb.fld))) { \
+ if (unlikely(tp##_is_any_nan(xb->fld))) { \
fe_flag = 1; \
- } else if (unlikely(tp##_is_zero(xb.fld))) { \
+ } else if (unlikely(tp##_is_zero(xb->fld))) { \
fe_flag = 1; \
- } else if (unlikely(tp##_is_neg(xb.fld))) { \
+ } else if (unlikely(tp##_is_neg(xb->fld))) { \
fe_flag = 1; \
- } else if (!tp##_is_zero(xb.fld) && \
+ } else if (!tp##_is_zero(xb->fld) && \
(e_b <= (emin + nbits))) { \
fe_flag = 1; \
} \
\
- if (unlikely(tp##_is_zero_or_denormal(xb.fld))) { \
+ if (unlikely(tp##_is_zero_or_denormal(xb->fld))) { \
/* \
* XB is not zero because of the above check and \
* therefore must be denormalized. \
@@ -2307,30 +2280,15 @@ VSX_TSQRT(xvtsqrtsp, 4, float32, VsrW(i), -126, 23)
* fld - vsr_t field (VsrD(*) or VsrW(*))
* maddflgs - flags for the float*muladd routine that control the
* various forms (madd, msub, nmadd, nmsub)
- * afrm - A form (1=A, 0=M)
* sfprf - set FPRF
*/
-#define VSX_MADD(op, nels, tp, fld, maddflgs, afrm, sfprf, r2sp) \
-void helper_##op(CPUPPCState *env, uint32_t opcode) \
+#define VSX_MADD(op, nels, tp, fld, maddflgs, sfprf, r2sp) \
+void helper_##op(CPUPPCState *env, ppc_vsr_t *xt, \
+ ppc_vsr_t *xa, ppc_vsr_t *b, ppc_vsr_t *c) \
{ \
- ppc_vsr_t xt_in, xa, xb, xt_out; \
- ppc_vsr_t *b, *c; \
+ ppc_vsr_t t = *xt; \
int i; \
\
- if (afrm) { /* AxB + T */ \
- b = &xb; \
- c = &xt_in; \
- } else { /* AxT + B */ \
- b = &xt_in; \
- c = &xb; \
- } \
- \
- getVSR(xA(opcode), &xa, env); \
- getVSR(xB(opcode), &xb, env); \
- getVSR(xT(opcode), &xt_in, env); \
- \
- xt_out = xt_in; \
- \
helper_reset_fpstatus(env); \
\
for (i = 0; i < nels; i++) { \
@@ -2342,68 +2300,51 @@ void helper_##op(CPUPPCState *env, uint32_t opcode) \
* result to odd. \
*/ \
set_float_rounding_mode(float_round_to_zero, &tstat); \
- xt_out.fld = tp##_muladd(xa.fld, b->fld, c->fld, \
- maddflgs, &tstat); \
- xt_out.fld |= (get_float_exception_flags(&tstat) & \
- float_flag_inexact) != 0; \
+ t.fld = tp##_muladd(xa->fld, b->fld, c->fld, \
+ maddflgs, &tstat); \
+ t.fld |= (get_float_exception_flags(&tstat) & \
+ float_flag_inexact) != 0; \
} else { \
- xt_out.fld = tp##_muladd(xa.fld, b->fld, c->fld, \
- maddflgs, &tstat); \
+ t.fld = tp##_muladd(xa->fld, b->fld, c->fld, \
+ maddflgs, &tstat); \
} \
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, \
+ tp##_maddsub_update_excp(env, xa->fld, b->fld, \
c->fld, maddflgs, GETPC()); \
} \
\
if (r2sp) { \
- xt_out.fld = helper_frsp(env, xt_out.fld); \
+ t.fld = helper_frsp(env, t.fld); \
} \
\
if (sfprf) { \
- helper_compute_fprf_float64(env, xt_out.fld); \
+ helper_compute_fprf_float64(env, t.fld); \
} \
} \
- putVSR(xT(opcode), &xt_out, env); \
+ *xt = t; \
do_float_check_status(env, GETPC()); \
}
-VSX_MADD(xsmaddadp, 1, float64, VsrD(0), MADD_FLGS, 1, 1, 0)
-VSX_MADD(xsmaddmdp, 1, float64, VsrD(0), MADD_FLGS, 0, 1, 0)
-VSX_MADD(xsmsubadp, 1, float64, VsrD(0), MSUB_FLGS, 1, 1, 0)
-VSX_MADD(xsmsubmdp, 1, float64, VsrD(0), MSUB_FLGS, 0, 1, 0)
-VSX_MADD(xsnmaddadp, 1, float64, VsrD(0), NMADD_FLGS, 1, 1, 0)
-VSX_MADD(xsnmaddmdp, 1, float64, VsrD(0), NMADD_FLGS, 0, 1, 0)
-VSX_MADD(xsnmsubadp, 1, float64, VsrD(0), NMSUB_FLGS, 1, 1, 0)
-VSX_MADD(xsnmsubmdp, 1, float64, VsrD(0), NMSUB_FLGS, 0, 1, 0)
-
-VSX_MADD(xsmaddasp, 1, float64, VsrD(0), MADD_FLGS, 1, 1, 1)
-VSX_MADD(xsmaddmsp, 1, float64, VsrD(0), MADD_FLGS, 0, 1, 1)
-VSX_MADD(xsmsubasp, 1, float64, VsrD(0), MSUB_FLGS, 1, 1, 1)
-VSX_MADD(xsmsubmsp, 1, float64, VsrD(0), MSUB_FLGS, 0, 1, 1)
-VSX_MADD(xsnmaddasp, 1, float64, VsrD(0), NMADD_FLGS, 1, 1, 1)
-VSX_MADD(xsnmaddmsp, 1, float64, VsrD(0), NMADD_FLGS, 0, 1, 1)
-VSX_MADD(xsnmsubasp, 1, float64, VsrD(0), NMSUB_FLGS, 1, 1, 1)
-VSX_MADD(xsnmsubmsp, 1, float64, VsrD(0), NMSUB_FLGS, 0, 1, 1)
-
-VSX_MADD(xvmaddadp, 2, float64, VsrD(i), MADD_FLGS, 1, 0, 0)
-VSX_MADD(xvmaddmdp, 2, float64, VsrD(i), MADD_FLGS, 0, 0, 0)
-VSX_MADD(xvmsubadp, 2, float64, VsrD(i), MSUB_FLGS, 1, 0, 0)
-VSX_MADD(xvmsubmdp, 2, float64, VsrD(i), MSUB_FLGS, 0, 0, 0)
-VSX_MADD(xvnmaddadp, 2, float64, VsrD(i), NMADD_FLGS, 1, 0, 0)
-VSX_MADD(xvnmaddmdp, 2, float64, VsrD(i), NMADD_FLGS, 0, 0, 0)
-VSX_MADD(xvnmsubadp, 2, float64, VsrD(i), NMSUB_FLGS, 1, 0, 0)
-VSX_MADD(xvnmsubmdp, 2, float64, VsrD(i), NMSUB_FLGS, 0, 0, 0)
-
-VSX_MADD(xvmaddasp, 4, float32, VsrW(i), MADD_FLGS, 1, 0, 0)
-VSX_MADD(xvmaddmsp, 4, float32, VsrW(i), MADD_FLGS, 0, 0, 0)
-VSX_MADD(xvmsubasp, 4, float32, VsrW(i), MSUB_FLGS, 1, 0, 0)
-VSX_MADD(xvmsubmsp, 4, float32, VsrW(i), MSUB_FLGS, 0, 0, 0)
-VSX_MADD(xvnmaddasp, 4, float32, VsrW(i), NMADD_FLGS, 1, 0, 0)
-VSX_MADD(xvnmaddmsp, 4, float32, VsrW(i), NMADD_FLGS, 0, 0, 0)
-VSX_MADD(xvnmsubasp, 4, float32, VsrW(i), NMSUB_FLGS, 1, 0, 0)
-VSX_MADD(xvnmsubmsp, 4, float32, VsrW(i), NMSUB_FLGS, 0, 0, 0)
+VSX_MADD(xsmadddp, 1, float64, VsrD(0), MADD_FLGS, 1, 0)
+VSX_MADD(xsmsubdp, 1, float64, VsrD(0), MSUB_FLGS, 1, 0)
+VSX_MADD(xsnmadddp, 1, float64, VsrD(0), NMADD_FLGS, 1, 0)
+VSX_MADD(xsnmsubdp, 1, float64, VsrD(0), NMSUB_FLGS, 1, 0)
+VSX_MADD(xsmaddsp, 1, float64, VsrD(0), MADD_FLGS, 1, 1)
+VSX_MADD(xsmsubsp, 1, float64, VsrD(0), MSUB_FLGS, 1, 1)
+VSX_MADD(xsnmaddsp, 1, float64, VsrD(0), NMADD_FLGS, 1, 1)
+VSX_MADD(xsnmsubsp, 1, float64, VsrD(0), NMSUB_FLGS, 1, 1)
+
+VSX_MADD(xvmadddp, 2, float64, VsrD(i), MADD_FLGS, 0, 0)
+VSX_MADD(xvmsubdp, 2, float64, VsrD(i), MSUB_FLGS, 0, 0)
+VSX_MADD(xvnmadddp, 2, float64, VsrD(i), NMADD_FLGS, 0, 0)
+VSX_MADD(xvnmsubdp, 2, float64, VsrD(i), NMSUB_FLGS, 0, 0)
+
+VSX_MADD(xvmaddsp, 4, float32, VsrW(i), MADD_FLGS, 0, 0)
+VSX_MADD(xvmsubsp, 4, float32, VsrW(i), MSUB_FLGS, 0, 0)
+VSX_MADD(xvnmaddsp, 4, float32, VsrW(i), NMADD_FLGS, 0, 0)
+VSX_MADD(xvnmsubsp, 4, float32, VsrW(i), NMSUB_FLGS, 0, 0)
/*
* VSX_SCALAR_CMP_DP - VSX scalar floating point compare double precision
@@ -2413,24 +2354,21 @@ VSX_MADD(xvnmsubmsp, 4, float32, VsrW(i), NMSUB_FLGS, 0, 0, 0)
* svxvc - set VXVC bit
*/
#define VSX_SCALAR_CMP_DP(op, cmp, exp, svxvc) \
-void helper_##op(CPUPPCState *env, uint32_t opcode) \
+void helper_##op(CPUPPCState *env, ppc_vsr_t *xt, \
+ ppc_vsr_t *xa, ppc_vsr_t *xb) \
{ \
- ppc_vsr_t xt, xa, xb; \
+ ppc_vsr_t t = *xt; \
bool vxsnan_flag = false, vxvc_flag = false, vex_flag = false; \
\
- getVSR(xA(opcode), &xa, env); \
- getVSR(xB(opcode), &xb, env); \
- getVSR(xT(opcode), &xt, env); \
- \
- if (float64_is_signaling_nan(xa.VsrD(0), &env->fp_status) || \
- float64_is_signaling_nan(xb.VsrD(0), &env->fp_status)) { \
+ if (float64_is_signaling_nan(xa->VsrD(0), &env->fp_status) || \
+ float64_is_signaling_nan(xb->VsrD(0), &env->fp_status)) { \
vxsnan_flag = true; \
if (fpscr_ve == 0 && svxvc) { \
vxvc_flag = true; \
} \
} else if (svxvc) { \
- vxvc_flag = float64_is_quiet_nan(xa.VsrD(0), &env->fp_status) || \
- float64_is_quiet_nan(xb.VsrD(0), &env->fp_status); \
+ vxvc_flag = float64_is_quiet_nan(xa->VsrD(0), &env->fp_status) || \
+ float64_is_quiet_nan(xb->VsrD(0), &env->fp_status); \
} \
if (vxsnan_flag) { \
float_invalid_op_vxsnan(env, GETPC()); \
@@ -2441,15 +2379,16 @@ void helper_##op(CPUPPCState *env, uint32_t opcode) \
vex_flag = fpscr_ve && (vxvc_flag || vxsnan_flag); \
\
if (!vex_flag) { \
- if (float64_##cmp(xb.VsrD(0), xa.VsrD(0), &env->fp_status) == exp) { \
- xt.VsrD(0) = -1; \
- xt.VsrD(1) = 0; \
+ if (float64_##cmp(xb->VsrD(0), xa->VsrD(0), \
+ &env->fp_status) == exp) { \
+ t.VsrD(0) = -1; \
+ t.VsrD(1) = 0; \
} else { \
- xt.VsrD(0) = 0; \
- xt.VsrD(1) = 0; \
+ t.VsrD(0) = 0; \
+ t.VsrD(1) = 0; \
} \
} \
- putVSR(xT(opcode), &xt, env); \
+ *xt = t; \
do_float_check_status(env, GETPC()); \
}
@@ -2458,20 +2397,17 @@ VSX_SCALAR_CMP_DP(xscmpgedp, le, 1, 1)
VSX_SCALAR_CMP_DP(xscmpgtdp, lt, 1, 1)
VSX_SCALAR_CMP_DP(xscmpnedp, eq, 0, 0)
-void helper_xscmpexpdp(CPUPPCState *env, uint32_t opcode)
+void helper_xscmpexpdp(CPUPPCState *env, uint32_t opcode,
+ ppc_vsr_t *xa, ppc_vsr_t *xb)
{
- ppc_vsr_t xa, xb;
int64_t exp_a, exp_b;
uint32_t cc;
- getVSR(xA(opcode), &xa, env);
- getVSR(xB(opcode), &xb, env);
-
- exp_a = extract64(xa.VsrD(0), 52, 11);
- exp_b = extract64(xb.VsrD(0), 52, 11);
+ exp_a = extract64(xa->VsrD(0), 52, 11);
+ exp_b = extract64(xb->VsrD(0), 52, 11);
- if (unlikely(float64_is_any_nan(xa.VsrD(0)) ||
- float64_is_any_nan(xb.VsrD(0)))) {
+ if (unlikely(float64_is_any_nan(xa->VsrD(0)) ||
+ float64_is_any_nan(xb->VsrD(0)))) {
cc = CRF_SO;
} else {
if (exp_a < exp_b) {
@@ -2490,20 +2426,17 @@ void helper_xscmpexpdp(CPUPPCState *env, uint32_t opcode)
do_float_check_status(env, GETPC());
}
-void helper_xscmpexpqp(CPUPPCState *env, uint32_t opcode)
+void helper_xscmpexpqp(CPUPPCState *env, uint32_t opcode,
+ ppc_vsr_t *xa, ppc_vsr_t *xb)
{
- ppc_vsr_t xa, xb;
int64_t exp_a, exp_b;
uint32_t cc;
- getVSR(rA(opcode) + 32, &xa, env);
- getVSR(rB(opcode) + 32, &xb, env);
+ exp_a = extract64(xa->VsrD(0), 48, 15);
+ exp_b = extract64(xb->VsrD(0), 48, 15);
- exp_a = extract64(xa.VsrD(0), 48, 15);
- exp_b = extract64(xb.VsrD(0), 48, 15);
-
- if (unlikely(float128_is_any_nan(xa.f128) ||
- float128_is_any_nan(xb.f128))) {
+ if (unlikely(float128_is_any_nan(xa->f128) ||
+ float128_is_any_nan(xb->f128))) {
cc = CRF_SO;
} else {
if (exp_a < exp_b) {
@@ -2523,25 +2456,23 @@ void helper_xscmpexpqp(CPUPPCState *env, uint32_t opcode)
}
#define VSX_SCALAR_CMP(op, ordered) \
-void helper_##op(CPUPPCState *env, uint32_t opcode) \
+void helper_##op(CPUPPCState *env, uint32_t opcode, \
+ ppc_vsr_t *xa, ppc_vsr_t *xb) \
{ \
- ppc_vsr_t xa, xb; \
uint32_t cc = 0; \
bool vxsnan_flag = false, vxvc_flag = false; \
\
helper_reset_fpstatus(env); \
- getVSR(xA(opcode), &xa, env); \
- getVSR(xB(opcode), &xb, env); \
\
- if (float64_is_signaling_nan(xa.VsrD(0), &env->fp_status) || \
- float64_is_signaling_nan(xb.VsrD(0), &env->fp_status)) { \
+ if (float64_is_signaling_nan(xa->VsrD(0), &env->fp_status) || \
+ float64_is_signaling_nan(xb->VsrD(0), &env->fp_status)) { \
vxsnan_flag = true; \
cc = CRF_SO; \
if (fpscr_ve == 0 && ordered) { \
vxvc_flag = true; \
} \
- } else if (float64_is_quiet_nan(xa.VsrD(0), &env->fp_status) || \
- float64_is_quiet_nan(xb.VsrD(0), &env->fp_status)) { \
+ } else if (float64_is_quiet_nan(xa->VsrD(0), &env->fp_status) || \
+ float64_is_quiet_nan(xb->VsrD(0), &env->fp_status)) { \
cc = CRF_SO; \
if (ordered) { \
vxvc_flag = true; \
@@ -2554,9 +2485,9 @@ void helper_##op(CPUPPCState *env, uint32_t opcode) \
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)) { \
cc |= CRF_LT; \
- } else if (!float64_le(xa.VsrD(0), xb.VsrD(0), &env->fp_status)) { \
+ } else if (!float64_le(xa->VsrD(0), xb->VsrD(0), &env->fp_status)) { \
cc |= CRF_GT; \
} else { \
cc |= CRF_EQ; \
@@ -2573,25 +2504,23 @@ VSX_SCALAR_CMP(xscmpodp, 1)
VSX_SCALAR_CMP(xscmpudp, 0)
#define VSX_SCALAR_CMPQ(op, ordered) \
-void helper_##op(CPUPPCState *env, uint32_t opcode) \
+void helper_##op(CPUPPCState *env, uint32_t opcode, \
+ ppc_vsr_t *xa, ppc_vsr_t *xb) \
{ \
- ppc_vsr_t xa, xb; \
uint32_t cc = 0; \
bool vxsnan_flag = false, vxvc_flag = false; \
\
helper_reset_fpstatus(env); \
- getVSR(rA(opcode) + 32, &xa, env); \
- getVSR(rB(opcode) + 32, &xb, env); \
\
- if (float128_is_signaling_nan(xa.f128, &env->fp_status) || \
- float128_is_signaling_nan(xb.f128, &env->fp_status)) { \
+ if (float128_is_signaling_nan(xa->f128, &env->fp_status) || \
+ float128_is_signaling_nan(xb->f128, &env->fp_status)) { \
vxsnan_flag = true; \
cc = CRF_SO; \
if (fpscr_ve == 0 && ordered) { \
vxvc_flag = true; \
} \
- } else if (float128_is_quiet_nan(xa.f128, &env->fp_status) || \
- float128_is_quiet_nan(xb.f128, &env->fp_status)) { \
+ } else if (float128_is_quiet_nan(xa->f128, &env->fp_status) || \
+ float128_is_quiet_nan(xb->f128, &env->fp_status)) { \
cc = CRF_SO; \
if (ordered) { \
vxvc_flag = true; \
@@ -2604,9 +2533,9 @@ void helper_##op(CPUPPCState *env, uint32_t opcode) \
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)) { \
cc |= CRF_LT; \
- } else if (!float128_le(xa.f128, xb.f128, &env->fp_status)) { \
+ } else if (!float128_le(xa->f128, xb->f128, &env->fp_status)) { \
cc |= CRF_GT; \
} else { \
cc |= CRF_EQ; \
@@ -2631,24 +2560,21 @@ VSX_SCALAR_CMPQ(xscmpuqp, 0)
* fld - vsr_t field (VsrD(*) or VsrW(*))
*/
#define VSX_MAX_MIN(name, op, nels, tp, fld) \
-void helper_##name(CPUPPCState *env, uint32_t opcode) \
+void helper_##name(CPUPPCState *env, ppc_vsr_t *xt, \
+ ppc_vsr_t *xa, ppc_vsr_t *xb) \
{ \
- ppc_vsr_t xt, xa, xb; \
+ ppc_vsr_t t = *xt; \
int i; \
\
- getVSR(xA(opcode), &xa, env); \
- getVSR(xB(opcode), &xb, env); \
- getVSR(xT(opcode), &xt, env); \
- \
for (i = 0; i < nels; i++) { \
- 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))) { \
+ t.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_vxsnan(env, GETPC()); \
} \
} \
\
- putVSR(xT(opcode), &xt, env); \
+ *xt = t; \
do_float_check_status(env, GETPC()); \
}
@@ -2660,29 +2586,26 @@ VSX_MAX_MIN(xvmindp, minnum, 2, float64, VsrD(i))
VSX_MAX_MIN(xvminsp, minnum, 4, float32, VsrW(i))
#define VSX_MAX_MINC(name, max) \
-void helper_##name(CPUPPCState *env, uint32_t opcode) \
+void helper_##name(CPUPPCState *env, uint32_t opcode, \
+ ppc_vsr_t *xt, ppc_vsr_t *xa, ppc_vsr_t *xb) \
{ \
- ppc_vsr_t xt, xa, xb; \
+ ppc_vsr_t t = *xt; \
bool vxsnan_flag = false, vex_flag = false; \
\
- getVSR(rA(opcode) + 32, &xa, env); \
- getVSR(rB(opcode) + 32, &xb, env); \
- getVSR(rD(opcode) + 32, &xt, env); \
- \
- if (unlikely(float64_is_any_nan(xa.VsrD(0)) || \
- float64_is_any_nan(xb.VsrD(0)))) { \
- if (float64_is_signaling_nan(xa.VsrD(0), &env->fp_status) || \
- float64_is_signaling_nan(xb.VsrD(0), &env->fp_status)) { \
+ if (unlikely(float64_is_any_nan(xa->VsrD(0)) || \
+ float64_is_any_nan(xb->VsrD(0)))) { \
+ if (float64_is_signaling_nan(xa->VsrD(0), &env->fp_status) || \
+ float64_is_signaling_nan(xb->VsrD(0), &env->fp_status)) { \
vxsnan_flag = true; \
} \
- xt.VsrD(0) = xb.VsrD(0); \
+ t.VsrD(0) = xb->VsrD(0); \
} else if ((max && \
- !float64_lt(xa.VsrD(0), xb.VsrD(0), &env->fp_status)) || \
+ !float64_lt(xa->VsrD(0), xb->VsrD(0), &env->fp_status)) || \
(!max && \
- float64_lt(xa.VsrD(0), xb.VsrD(0), &env->fp_status))) { \
- xt.VsrD(0) = xa.VsrD(0); \
+ float64_lt(xa->VsrD(0), xb->VsrD(0), &env->fp_status))) { \
+ t.VsrD(0) = xa->VsrD(0); \
} else { \
- xt.VsrD(0) = xb.VsrD(0); \
+ t.VsrD(0) = xb->VsrD(0); \
} \
\
vex_flag = fpscr_ve & vxsnan_flag; \
@@ -2690,7 +2613,7 @@ void helper_##name(CPUPPCState *env, uint32_t opcode) \
float_invalid_op_vxsnan(env, GETPC()); \
} \
if (!vex_flag) { \
- putVSR(rD(opcode) + 32, &xt, env); \
+ *xt = t; \
} \
} \
@@ -2698,46 +2621,46 @@ VSX_MAX_MINC(xsmaxcdp, 1);
VSX_MAX_MINC(xsmincdp, 0);
#define VSX_MAX_MINJ(name, max) \
-void helper_##name(CPUPPCState *env, uint32_t opcode) \
+void helper_##name(CPUPPCState *env, uint32_t opcode, \
+ ppc_vsr_t *xt, ppc_vsr_t *xa, ppc_vsr_t *xb) \
{ \
- ppc_vsr_t xt, xa, xb; \
+ ppc_vsr_t t = *xt; \
bool vxsnan_flag = false, vex_flag = false; \
\
- getVSR(rA(opcode) + 32, &xa, env); \
- getVSR(rB(opcode) + 32, &xb, env); \
- getVSR(rD(opcode) + 32, &xt, env); \
- \
- if (unlikely(float64_is_any_nan(xa.VsrD(0)))) { \
- if (float64_is_signaling_nan(xa.VsrD(0), &env->fp_status)) { \
+ if (unlikely(float64_is_any_nan(xa->VsrD(0)))) { \
+ if (float64_is_signaling_nan(xa->VsrD(0), &env->fp_status)) { \
vxsnan_flag = true; \
} \
- xt.VsrD(0) = xa.VsrD(0); \
- } else if (unlikely(float64_is_any_nan(xb.VsrD(0)))) { \
- if (float64_is_signaling_nan(xb.VsrD(0), &env->fp_status)) { \
+ t.VsrD(0) = xa->VsrD(0); \
+ } else if (unlikely(float64_is_any_nan(xb->VsrD(0)))) { \
+ if (float64_is_signaling_nan(xb->VsrD(0), &env->fp_status)) { \
vxsnan_flag = true; \
} \
- xt.VsrD(0) = xb.VsrD(0); \
- } else if (float64_is_zero(xa.VsrD(0)) && float64_is_zero(xb.VsrD(0))) { \
+ t.VsrD(0) = xb->VsrD(0); \
+ } else if (float64_is_zero(xa->VsrD(0)) && \
+ float64_is_zero(xb->VsrD(0))) { \
if (max) { \
- if (!float64_is_neg(xa.VsrD(0)) || !float64_is_neg(xb.VsrD(0))) { \
- xt.VsrD(0) = 0ULL; \
+ if (!float64_is_neg(xa->VsrD(0)) || \
+ !float64_is_neg(xb->VsrD(0))) { \
+ t.VsrD(0) = 0ULL; \
} else { \
- xt.VsrD(0) = 0x8000000000000000ULL; \
+ t.VsrD(0) = 0x8000000000000000ULL; \
} \
} else { \
- if (float64_is_neg(xa.VsrD(0)) || float64_is_neg(xb.VsrD(0))) { \
- xt.VsrD(0) = 0x8000000000000000ULL; \
+ if (float64_is_neg(xa->VsrD(0)) || \
+ float64_is_neg(xb->VsrD(0))) { \
+ t.VsrD(0) = 0x8000000000000000ULL; \
} else { \
- xt.VsrD(0) = 0ULL; \
+ t.VsrD(0) = 0ULL; \
} \
} \
} else if ((max && \
- !float64_lt(xa.VsrD(0), xb.VsrD(0), &env->fp_status)) || \
+ !float64_lt(xa->VsrD(0), xb->VsrD(0), &env->fp_status)) || \
(!max && \
- float64_lt(xa.VsrD(0), xb.VsrD(0), &env->fp_status))) { \
- xt.VsrD(0) = xa.VsrD(0); \
+ float64_lt(xa->VsrD(0), xb->VsrD(0), &env->fp_status))) { \
+ t.VsrD(0) = xa->VsrD(0); \
} else { \
- xt.VsrD(0) = xb.VsrD(0); \
+ t.VsrD(0) = xb->VsrD(0); \
} \
\
vex_flag = fpscr_ve & vxsnan_flag; \
@@ -2745,7 +2668,7 @@ void helper_##name(CPUPPCState *env, uint32_t opcode) \
float_invalid_op_vxsnan(env, GETPC()); \
} \
if (!vex_flag) { \
- putVSR(rD(opcode) + 32, &xt, env); \
+ *xt = t; \
} \
} \
@@ -2763,46 +2686,42 @@ VSX_MAX_MINJ(xsminjdp, 0);
* exp - expected result of comparison
*/
#define VSX_CMP(op, nels, tp, fld, cmp, svxvc, exp) \
-void helper_##op(CPUPPCState *env, uint32_t opcode) \
+uint32_t helper_##op(CPUPPCState *env, ppc_vsr_t *xt, \
+ ppc_vsr_t *xa, ppc_vsr_t *xb) \
{ \
- ppc_vsr_t xt, xa, xb; \
+ ppc_vsr_t t = *xt; \
+ uint32_t crf6 = 0; \
int i; \
int all_true = 1; \
int all_false = 1; \
\
- getVSR(xA(opcode), &xa, env); \
- getVSR(xB(opcode), &xb, env); \
- getVSR(xT(opcode), &xt, env); \
- \
for (i = 0; i < nels; i++) { \
- if (unlikely(tp##_is_any_nan(xa.fld) || \
- 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)) { \
+ if (unlikely(tp##_is_any_nan(xa->fld) || \
+ 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_vxsnan(env, GETPC()); \
} \
if (svxvc) { \
float_invalid_op_vxvc(env, 0, GETPC()); \
} \
- xt.fld = 0; \
+ t.fld = 0; \
all_true = 0; \
} else { \
- if (tp##_##cmp(xb.fld, xa.fld, &env->fp_status) == exp) { \
- xt.fld = -1; \
+ if (tp##_##cmp(xb->fld, xa->fld, &env->fp_status) == exp) { \
+ t.fld = -1; \
all_false = 0; \
} else { \
- xt.fld = 0; \
+ t.fld = 0; \
all_true = 0; \
} \
} \
} \
\
- putVSR(xT(opcode), &xt, env); \
- if ((opcode >> (31 - 21)) & 1) { \
- env->crf[6] = (all_true ? 0x8 : 0) | (all_false ? 0x2 : 0); \
- } \
- do_float_check_status(env, GETPC()); \
- }
+ *xt = t; \
+ crf6 = (all_true ? 0x8 : 0) | (all_false ? 0x2 : 0); \
+ return crf6; \
+}
VSX_CMP(xvcmpeqdp, 2, float64, VsrD(i), eq, 0, 1)
VSX_CMP(xvcmpgedp, 2, float64, VsrD(i), le, 1, 1)
@@ -2824,27 +2743,24 @@ VSX_CMP(xvcmpnesp, 4, float32, VsrW(i), eq, 0, 0)
* sfprf - set FPRF
*/
#define VSX_CVT_FP_TO_FP(op, nels, stp, ttp, sfld, tfld, sfprf) \
-void helper_##op(CPUPPCState *env, uint32_t opcode) \
+void helper_##op(CPUPPCState *env, ppc_vsr_t *xt, ppc_vsr_t *xb) \
{ \
- ppc_vsr_t xt, xb; \
+ ppc_vsr_t t = *xt; \
int i; \
\
- getVSR(xB(opcode), &xb, env); \
- getVSR(xT(opcode), &xt, env); \
- \
for (i = 0; i < nels; i++) { \
- xt.tfld = stp##_to_##ttp(xb.sfld, &env->fp_status); \
- if (unlikely(stp##_is_signaling_nan(xb.sfld, \
+ t.tfld = stp##_to_##ttp(xb->sfld, &env->fp_status); \
+ if (unlikely(stp##_is_signaling_nan(xb->sfld, \
&env->fp_status))) { \
float_invalid_op_vxsnan(env, GETPC()); \
- xt.tfld = ttp##_snan_to_qnan(xt.tfld); \
+ t.tfld = ttp##_snan_to_qnan(t.tfld); \
} \
if (sfprf) { \
- helper_compute_fprf_##ttp(env, xt.tfld); \
+ helper_compute_fprf_##ttp(env, t.tfld); \
} \
} \
\
- putVSR(xT(opcode), &xt, env); \
+ *xt = t; \
do_float_check_status(env, GETPC()); \
}
@@ -2864,27 +2780,25 @@ VSX_CVT_FP_TO_FP(xvcvspdp, 2, float32, float64, VsrW(2 * i), VsrD(i), 0)
* sfprf - set FPRF
*/
#define VSX_CVT_FP_TO_FP_VECTOR(op, nels, stp, ttp, sfld, tfld, sfprf) \
-void helper_##op(CPUPPCState *env, uint32_t opcode) \
+void helper_##op(CPUPPCState *env, uint32_t opcode, \
+ ppc_vsr_t *xt, ppc_vsr_t *xb) \
{ \
- ppc_vsr_t xt, xb; \
+ ppc_vsr_t t = *xt; \
int i; \
\
- getVSR(rB(opcode) + 32, &xb, env); \
- getVSR(rD(opcode) + 32, &xt, env); \
- \
for (i = 0; i < nels; i++) { \
- xt.tfld = stp##_to_##ttp(xb.sfld, &env->fp_status); \
- if (unlikely(stp##_is_signaling_nan(xb.sfld, \
+ t.tfld = stp##_to_##ttp(xb->sfld, &env->fp_status); \
+ if (unlikely(stp##_is_signaling_nan(xb->sfld, \
&env->fp_status))) { \
float_invalid_op_vxsnan(env, GETPC()); \
- xt.tfld = ttp##_snan_to_qnan(xt.tfld); \
+ t.tfld = ttp##_snan_to_qnan(t.tfld); \
} \
if (sfprf) { \
- helper_compute_fprf_##ttp(env, xt.tfld); \
+ helper_compute_fprf_##ttp(env, t.tfld); \
} \
} \
\
- putVSR(rD(opcode) + 32, &xt, env); \
+ *xt = t; \
do_float_check_status(env, GETPC()); \
}
@@ -2902,27 +2816,24 @@ VSX_CVT_FP_TO_FP_VECTOR(xscvdpqp, 1, float64, float128, VsrD(0), f128, 1)
* sfprf - set FPRF
*/
#define VSX_CVT_FP_TO_FP_HP(op, nels, stp, ttp, sfld, tfld, sfprf) \
-void helper_##op(CPUPPCState *env, uint32_t opcode) \
+void helper_##op(CPUPPCState *env, ppc_vsr_t *xt, ppc_vsr_t *xb) \
{ \
- ppc_vsr_t xt, xb; \
+ ppc_vsr_t t = { }; \
int i; \
\
- getVSR(xB(opcode), &xb, env); \
- memset(&xt, 0, sizeof(xt)); \
- \
for (i = 0; i < nels; i++) { \
- xt.tfld = stp##_to_##ttp(xb.sfld, 1, &env->fp_status); \
- if (unlikely(stp##_is_signaling_nan(xb.sfld, \
+ t.tfld = stp##_to_##ttp(xb->sfld, 1, &env->fp_status); \
+ if (unlikely(stp##_is_signaling_nan(xb->sfld, \
&env->fp_status))) { \
float_invalid_op_vxsnan(env, GETPC()); \
- xt.tfld = ttp##_snan_to_qnan(xt.tfld); \
+ t.tfld = ttp##_snan_to_qnan(t.tfld); \
} \
if (sfprf) { \
- helper_compute_fprf_##ttp(env, xt.tfld); \
+ helper_compute_fprf_##ttp(env, t.tfld); \
} \
} \
\
- putVSR(xT(opcode), &xt, env); \
+ *xt = t; \
do_float_check_status(env, GETPC()); \
}
@@ -2935,28 +2846,26 @@ VSX_CVT_FP_TO_FP_HP(xvcvhpsp, 4, float16, float32, VsrH(2 * i + 1), VsrW(i), 0)
* xscvqpdp isn't using VSX_CVT_FP_TO_FP() because xscvqpdpo will be
* added to this later.
*/
-void helper_xscvqpdp(CPUPPCState *env, uint32_t opcode)
+void helper_xscvqpdp(CPUPPCState *env, uint32_t opcode,
+ ppc_vsr_t *xt, ppc_vsr_t *xb)
{
- ppc_vsr_t xt, xb;
+ ppc_vsr_t t = { };
float_status tstat;
- getVSR(rB(opcode) + 32, &xb, env);
- memset(&xt, 0, sizeof(xt));
-
tstat = env->fp_status;
if (unlikely(Rc(opcode) != 0)) {
tstat.float_rounding_mode = float_round_to_odd;
}
- xt.VsrD(0) = float128_to_float64(xb.f128, &tstat);
+ t.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))) {
+ 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));
+ t.VsrD(0) = float64_snan_to_qnan(t.VsrD(0));
}
- helper_compute_fprf_float64(env, xt.VsrD(0));
+ helper_compute_fprf_float64(env, t.VsrD(0));
- putVSR(rD(opcode) + 32, &xt, env);
+ *xt = t;
do_float_check_status(env, GETPC());
}
@@ -2987,27 +2896,24 @@ uint64_t helper_xscvspdpn(CPUPPCState *env, uint64_t xb)
* rnan - resulting NaN
*/
#define VSX_CVT_FP_TO_INT(op, nels, stp, ttp, sfld, tfld, rnan) \
-void helper_##op(CPUPPCState *env, uint32_t opcode) \
+void helper_##op(CPUPPCState *env, ppc_vsr_t *xt, ppc_vsr_t *xb) \
{ \
int all_flags = env->fp_status.float_exception_flags, flags; \
- ppc_vsr_t xt, xb; \
+ ppc_vsr_t t = *xt; \
int i; \
\
- getVSR(xB(opcode), &xb, env); \
- getVSR(xT(opcode), &xt, env); \
- \
for (i = 0; i < nels; i++) { \
env->fp_status.float_exception_flags = 0; \
- xt.tfld = stp##_to_##ttp##_round_to_zero(xb.sfld, &env->fp_status); \
+ t.tfld = stp##_to_##ttp##_round_to_zero(xb->sfld, &env->fp_status); \
flags = env->fp_status.float_exception_flags; \
if (unlikely(flags & float_flag_invalid)) { \
- float_invalid_cvt(env, 0, GETPC(), stp##_classify(xb.sfld)); \
- xt.tfld = rnan; \
+ float_invalid_cvt(env, 0, GETPC(), stp##_classify(xb->sfld)); \
+ t.tfld = rnan; \
} \
all_flags |= flags; \
} \
\
- putVSR(xT(opcode), &xt, env); \
+ *xt = t; \
env->fp_status.float_exception_flags = all_flags; \
do_float_check_status(env, GETPC()); \
}
@@ -3040,20 +2946,18 @@ VSX_CVT_FP_TO_INT(xvcvspuxws, 4, float32, uint32, VsrW(i), VsrW(i), 0U)
* rnan - resulting NaN
*/
#define VSX_CVT_FP_TO_INT_VECTOR(op, stp, ttp, sfld, tfld, rnan) \
-void helper_##op(CPUPPCState *env, uint32_t opcode) \
+void helper_##op(CPUPPCState *env, uint32_t opcode, \
+ ppc_vsr_t *xt, ppc_vsr_t *xb) \
{ \
- ppc_vsr_t xt, xb; \
+ ppc_vsr_t t = { }; \
\
- getVSR(rB(opcode) + 32, &xb, env); \
- memset(&xt, 0, sizeof(xt)); \
- \
- xt.tfld = stp##_to_##ttp##_round_to_zero(xb.sfld, &env->fp_status); \
+ t.tfld = stp##_to_##ttp##_round_to_zero(xb->sfld, &env->fp_status); \
if (env->fp_status.float_exception_flags & float_flag_invalid) { \
- float_invalid_cvt(env, 0, GETPC(), stp##_classify(xb.sfld)); \
- xt.tfld = rnan; \
+ float_invalid_cvt(env, 0, GETPC(), stp##_classify(xb->sfld)); \
+ t.tfld = rnan; \
} \
\
- putVSR(rD(opcode) + 32, &xt, env); \
+ *xt = t; \
do_float_check_status(env, GETPC()); \
}
@@ -3077,25 +2981,22 @@ VSX_CVT_FP_TO_INT_VECTOR(xscvqpuwz, float128, uint32, f128, VsrD(0), 0x0ULL)
* sfprf - set FPRF
*/
#define VSX_CVT_INT_TO_FP(op, nels, stp, ttp, sfld, tfld, sfprf, r2sp) \
-void helper_##op(CPUPPCState *env, uint32_t opcode) \
+void helper_##op(CPUPPCState *env, ppc_vsr_t *xt, ppc_vsr_t *xb) \
{ \
- ppc_vsr_t xt, xb; \
+ ppc_vsr_t t = *xt; \
int i; \
\
- getVSR(xB(opcode), &xb, env); \
- getVSR(xT(opcode), &xt, env); \
- \
for (i = 0; i < nels; i++) { \
- xt.tfld = stp##_to_##ttp(xb.sfld, &env->fp_status); \
+ t.tfld = stp##_to_##ttp(xb->sfld, &env->fp_status); \
if (r2sp) { \
- xt.tfld = helper_frsp(env, xt.tfld); \
+ t.tfld = helper_frsp(env, t.tfld); \
} \
if (sfprf) { \
- helper_compute_fprf_float64(env, xt.tfld); \
+ helper_compute_fprf_float64(env, t.tfld); \
} \
} \
\
- putVSR(xT(opcode), &xt, env); \
+ *xt = t; \
do_float_check_status(env, GETPC()); \
}
@@ -3121,17 +3022,15 @@ VSX_CVT_INT_TO_FP(xvcvuxwsp, 4, uint32, float32, VsrW(i), VsrW(i), 0, 0)
* tfld - target vsr_t field
*/
#define VSX_CVT_INT_TO_FP_VECTOR(op, stp, ttp, sfld, tfld) \
-void helper_##op(CPUPPCState *env, uint32_t opcode) \
+void helper_##op(CPUPPCState *env, uint32_t opcode, \
+ ppc_vsr_t *xt, ppc_vsr_t *xb) \
{ \
- ppc_vsr_t xt, xb; \
+ ppc_vsr_t t = *xt; \
\
- getVSR(rB(opcode) + 32, &xb, env); \
- getVSR(rD(opcode) + 32, &xt, env); \
+ t.tfld = stp##_to_##ttp(xb->sfld, &env->fp_status); \
+ helper_compute_fprf_##ttp(env, t.tfld); \
\
- xt.tfld = stp##_to_##ttp(xb.sfld, &env->fp_status); \
- helper_compute_fprf_##ttp(env, xt.tfld); \
- \
- putVSR(xT(opcode) + 32, &xt, env); \
+ *xt = t; \
do_float_check_status(env, GETPC()); \
}
@@ -3155,27 +3054,25 @@ VSX_CVT_INT_TO_FP_VECTOR(xscvudqp, uint64, float128, VsrD(0), f128)
* sfprf - set FPRF
*/
#define VSX_ROUND(op, nels, tp, fld, rmode, sfprf) \
-void helper_##op(CPUPPCState *env, uint32_t opcode) \
+void helper_##op(CPUPPCState *env, ppc_vsr_t *xt, ppc_vsr_t *xb) \
{ \
- ppc_vsr_t xt, xb; \
+ ppc_vsr_t t = *xt; \
int i; \
- getVSR(xB(opcode), &xb, env); \
- getVSR(xT(opcode), &xt, env); \
\
if (rmode != FLOAT_ROUND_CURRENT) { \
set_float_rounding_mode(rmode, &env->fp_status); \
} \
\
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))) { \
float_invalid_op_vxsnan(env, GETPC()); \
- xt.fld = tp##_snan_to_qnan(xb.fld); \
+ t.fld = tp##_snan_to_qnan(xb->fld); \
} else { \
- xt.fld = tp##_round_to_int(xb.fld, &env->fp_status); \
+ t.fld = tp##_round_to_int(xb->fld, &env->fp_status); \
} \
if (sfprf) { \
- helper_compute_fprf_float64(env, xt.fld); \
+ helper_compute_fprf_float64(env, t.fld); \
} \
} \
\
@@ -3189,7 +3086,7 @@ void helper_##op(CPUPPCState *env, uint32_t opcode) \
env->fp_status.float_exception_flags &= ~float_flag_inexact; \
} \
\
- putVSR(xT(opcode), &xt, env); \
+ *xt = t; \
do_float_check_status(env, GETPC()); \
}
@@ -3223,46 +3120,41 @@ uint64_t helper_xsrsp(CPUPPCState *env, uint64_t xb)
}
#define VSX_XXPERM(op, indexed) \
-void helper_##op(CPUPPCState *env, uint32_t opcode) \
+void helper_##op(CPUPPCState *env, ppc_vsr_t *xt, \
+ ppc_vsr_t *xa, ppc_vsr_t *pcv) \
{ \
- ppc_vsr_t xt, xa, pcv, xto; \
+ ppc_vsr_t t = *xt; \
int i, idx; \
\
- getVSR(xA(opcode), &xa, env); \
- getVSR(xT(opcode), &xt, env); \
- getVSR(xB(opcode), &pcv, env); \
- \
for (i = 0; i < 16; i++) { \
- idx = pcv.VsrB(i) & 0x1F; \
+ idx = pcv->VsrB(i) & 0x1F; \
if (indexed) { \
idx = 31 - idx; \
} \
- xto.VsrB(i) = (idx <= 15) ? xa.VsrB(idx) : xt.VsrB(idx - 16); \
+ t.VsrB(i) = (idx <= 15) ? xa->VsrB(idx) \
+ : xt->VsrB(idx - 16); \
} \
- putVSR(xT(opcode), &xto, env); \
+ *xt = t; \
}
VSX_XXPERM(xxperm, 0)
VSX_XXPERM(xxpermr, 1)
-void helper_xvxsigsp(CPUPPCState *env, uint32_t opcode)
+void helper_xvxsigsp(CPUPPCState *env, ppc_vsr_t *xt, ppc_vsr_t *xb)
{
- ppc_vsr_t xt, xb;
+ ppc_vsr_t t = { };
uint32_t exp, i, fraction;
- getVSR(xB(opcode), &xb, env);
- memset(&xt, 0, sizeof(xt));
-
for (i = 0; i < 4; i++) {
- exp = (xb.VsrW(i) >> 23) & 0xFF;
- fraction = xb.VsrW(i) & 0x7FFFFF;
+ exp = (xb->VsrW(i) >> 23) & 0xFF;
+ fraction = xb->VsrW(i) & 0x7FFFFF;
if (exp != 0 && exp != 255) {
- xt.VsrW(i) = fraction | 0x00800000;
+ t.VsrW(i) = fraction | 0x00800000;
} else {
- xt.VsrW(i) = fraction;
+ t.VsrW(i) = fraction;
}
}
- putVSR(xT(opcode), &xt, env);
+ *xt = t;
}
/*
@@ -3279,27 +3171,28 @@ void helper_xvxsigsp(CPUPPCState *env, uint32_t opcode)
#define VSX_TEST_DC(op, nels, xbn, tp, fld, tfld, fld_max, scrf) \
void helper_##op(CPUPPCState *env, uint32_t opcode) \
{ \
- ppc_vsr_t xt, xb; \
+ ppc_vsr_t *xt = &env->vsr[xT(opcode)]; \
+ ppc_vsr_t *xb = &env->vsr[xbn]; \
+ ppc_vsr_t t = { }; \
uint32_t i, sign, dcmx; \
uint32_t cc, match = 0; \
\
- getVSR(xbn, &xb, env); \
if (!scrf) { \
- memset(&xt, 0, sizeof(xt)); \
dcmx = DCMX_XV(opcode); \
} else { \
+ t = *xt; \
dcmx = DCMX(opcode); \
} \
\
for (i = 0; i < nels; i++) { \
- sign = tp##_is_neg(xb.fld); \
- if (tp##_is_any_nan(xb.fld)) { \
+ sign = tp##_is_neg(xb->fld); \
+ if (tp##_is_any_nan(xb->fld)) { \
match = extract32(dcmx, 6, 1); \
- } else if (tp##_is_infinity(xb.fld)) { \
+ } else if (tp##_is_infinity(xb->fld)) { \
match = extract32(dcmx, 4 + !sign, 1); \
- } else if (tp##_is_zero(xb.fld)) { \
+ } else if (tp##_is_zero(xb->fld)) { \
match = extract32(dcmx, 2 + !sign, 1); \
- } else if (tp##_is_zero_or_denormal(xb.fld)) { \
+ } else if (tp##_is_zero_or_denormal(xb->fld)) { \
match = extract32(dcmx, 0 + !sign, 1); \
} \
\
@@ -3309,12 +3202,12 @@ void helper_##op(CPUPPCState *env, uint32_t opcode) \
env->fpscr |= cc << FPSCR_FPRF; \
env->crf[BF(opcode)] = cc; \
} else { \
- xt.tfld = match ? fld_max : 0; \
+ t.tfld = match ? fld_max : 0; \
} \
match = 0; \
} \
if (!scrf) { \
- putVSR(xT(opcode), &xt, env); \
+ *xt = t; \
} \
}
@@ -3323,31 +3216,29 @@ VSX_TEST_DC(xvtstdcsp, 4, xB(opcode), float32, VsrW(i), VsrW(i), UINT32_MAX, 0)
VSX_TEST_DC(xststdcdp, 1, xB(opcode), float64, VsrD(0), VsrD(0), 0, 1)
VSX_TEST_DC(xststdcqp, 1, (rB(opcode) + 32), float128, f128, VsrD(0), 0, 1)
-void helper_xststdcsp(CPUPPCState *env, uint32_t opcode)
+void helper_xststdcsp(CPUPPCState *env, uint32_t opcode, ppc_vsr_t *xb)
{
- ppc_vsr_t xb;
uint32_t dcmx, sign, exp;
uint32_t cc, match = 0, not_sp = 0;
- getVSR(xB(opcode), &xb, env);
dcmx = DCMX(opcode);
- exp = (xb.VsrD(0) >> 52) & 0x7FF;
+ exp = (xb->VsrD(0) >> 52) & 0x7FF;
- sign = float64_is_neg(xb.VsrD(0));
- if (float64_is_any_nan(xb.VsrD(0))) {
+ sign = float64_is_neg(xb->VsrD(0));
+ if (float64_is_any_nan(xb->VsrD(0))) {
match = extract32(dcmx, 6, 1);
- } else if (float64_is_infinity(xb.VsrD(0))) {
+ } else if (float64_is_infinity(xb->VsrD(0))) {
match = extract32(dcmx, 4 + !sign, 1);
- } else if (float64_is_zero(xb.VsrD(0))) {
+ } else if (float64_is_zero(xb->VsrD(0))) {
match = extract32(dcmx, 2 + !sign, 1);
- } else if (float64_is_zero_or_denormal(xb.VsrD(0)) ||
+ } else if (float64_is_zero_or_denormal(xb->VsrD(0)) ||
(exp > 0 && exp < 0x381)) {
match = extract32(dcmx, 0 + !sign, 1);
}
- not_sp = !float64_eq(xb.VsrD(0),
+ not_sp = !float64_eq(xb->VsrD(0),
float32_to_float64(
- float64_to_float32(xb.VsrD(0), &env->fp_status),
+ float64_to_float32(xb->VsrD(0), &env->fp_status),
&env->fp_status), &env->fp_status);
cc = sign << CRF_LT_BIT | match << CRF_EQ_BIT | not_sp << CRF_SO_BIT;
@@ -3356,18 +3247,16 @@ void helper_xststdcsp(CPUPPCState *env, uint32_t opcode)
env->crf[BF(opcode)] = cc;
}
-void helper_xsrqpi(CPUPPCState *env, uint32_t opcode)
+void helper_xsrqpi(CPUPPCState *env, uint32_t opcode,
+ ppc_vsr_t *xt, ppc_vsr_t *xb)
{
- ppc_vsr_t xb;
- ppc_vsr_t xt;
+ ppc_vsr_t t = { };
uint8_t r = Rrm(opcode);
uint8_t ex = Rc(opcode);
uint8_t rmc = RMC(opcode);
uint8_t rmode = 0;
float_status tstat;
- getVSR(rB(opcode) + 32, &xb, env);
- memset(&xt, 0, sizeof(xt));
helper_reset_fpstatus(env);
if (r == 0 && rmc == 0) {
@@ -3396,13 +3285,13 @@ void helper_xsrqpi(CPUPPCState *env, uint32_t opcode)
tstat = env->fp_status;
set_float_exception_flags(0, &tstat);
set_float_rounding_mode(rmode, &tstat);
- xt.f128 = float128_round_to_int(xb.f128, &tstat);
+ t.f128 = float128_round_to_int(xb->f128, &tstat);
env->fp_status.float_exception_flags |= tstat.float_exception_flags;
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_vxsnan(env, GETPC());
- xt.f128 = float128_snan_to_qnan(xt.f128);
+ t.f128 = float128_snan_to_qnan(t.f128);
}
}
@@ -3410,23 +3299,21 @@ void helper_xsrqpi(CPUPPCState *env, uint32_t opcode)
env->fp_status.float_exception_flags &= ~float_flag_inexact;
}
- helper_compute_fprf_float128(env, xt.f128);
+ helper_compute_fprf_float128(env, t.f128);
do_float_check_status(env, GETPC());
- putVSR(rD(opcode) + 32, &xt, env);
+ *xt = t;
}
-void helper_xsrqpxp(CPUPPCState *env, uint32_t opcode)
+void helper_xsrqpxp(CPUPPCState *env, uint32_t opcode,
+ ppc_vsr_t *xt, ppc_vsr_t *xb)
{
- ppc_vsr_t xb;
- ppc_vsr_t xt;
+ ppc_vsr_t t = { };
uint8_t r = Rrm(opcode);
uint8_t rmc = RMC(opcode);
uint8_t rmode = 0;
floatx80 round_res;
float_status tstat;
- getVSR(rB(opcode) + 32, &xb, env);
- memset(&xt, 0, sizeof(xt));
helper_reset_fpstatus(env);
if (r == 0 && rmc == 0) {
@@ -3455,30 +3342,28 @@ void helper_xsrqpxp(CPUPPCState *env, uint32_t opcode)
tstat = env->fp_status;
set_float_exception_flags(0, &tstat);
set_float_rounding_mode(rmode, &tstat);
- round_res = float128_to_floatx80(xb.f128, &tstat);
- xt.f128 = floatx80_to_float128(round_res, &tstat);
+ round_res = float128_to_floatx80(xb->f128, &tstat);
+ t.f128 = floatx80_to_float128(round_res, &tstat);
env->fp_status.float_exception_flags |= tstat.float_exception_flags;
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_vxsnan(env, GETPC());
- xt.f128 = float128_snan_to_qnan(xt.f128);
+ t.f128 = float128_snan_to_qnan(t.f128);
}
}
- helper_compute_fprf_float128(env, xt.f128);
- putVSR(rD(opcode) + 32, &xt, env);
+ helper_compute_fprf_float128(env, t.f128);
+ *xt = t;
do_float_check_status(env, GETPC());
}
-void helper_xssqrtqp(CPUPPCState *env, uint32_t opcode)
+void helper_xssqrtqp(CPUPPCState *env, uint32_t opcode,
+ ppc_vsr_t *xt, ppc_vsr_t *xb)
{
- ppc_vsr_t xb;
- ppc_vsr_t xt;
+ ppc_vsr_t t = { };
float_status tstat;
- getVSR(rB(opcode) + 32, &xb, env);
- memset(&xt, 0, sizeof(xt));
helper_reset_fpstatus(env);
tstat = env->fp_status;
@@ -3487,34 +3372,32 @@ void helper_xssqrtqp(CPUPPCState *env, uint32_t opcode)
}
set_float_exception_flags(0, &tstat);
- xt.f128 = float128_sqrt(xb.f128, &tstat);
+ t.f128 = float128_sqrt(xb->f128, &tstat);
env->fp_status.float_exception_flags |= tstat.float_exception_flags;
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_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)) {
+ t.f128 = float128_snan_to_qnan(xb->f128);
+ } else if (float128_is_quiet_nan(xb->f128, &tstat)) {
+ t.f128 = xb->f128;
+ } else if (float128_is_neg(xb->f128) && !float128_is_zero(xb->f128)) {
float_invalid_op_vxsqrt(env, 1, GETPC());
- xt.f128 = float128_default_nan(&env->fp_status);
+ t.f128 = float128_default_nan(&env->fp_status);
}
}
- helper_compute_fprf_float128(env, xt.f128);
- putVSR(rD(opcode) + 32, &xt, env);
+ helper_compute_fprf_float128(env, t.f128);
+ *xt = t;
do_float_check_status(env, GETPC());
}
-void helper_xssubqp(CPUPPCState *env, uint32_t opcode)
+void helper_xssubqp(CPUPPCState *env, uint32_t opcode,
+ ppc_vsr_t *xt, ppc_vsr_t *xa, ppc_vsr_t *xb)
{
- ppc_vsr_t xt, xa, xb;
+ ppc_vsr_t t = *xt;
float_status tstat;
- getVSR(rA(opcode) + 32, &xa, env);
- getVSR(rB(opcode) + 32, &xb, env);
- getVSR(rD(opcode) + 32, &xt, env);
helper_reset_fpstatus(env);
tstat = env->fp_status;
@@ -3523,16 +3406,16 @@ void helper_xssubqp(CPUPPCState *env, uint32_t opcode)
}
set_float_exception_flags(0, &tstat);
- xt.f128 = float128_sub(xa.f128, xb.f128, &tstat);
+ t.f128 = float128_sub(xa->f128, xb->f128, &tstat);
env->fp_status.float_exception_flags |= tstat.float_exception_flags;
if (unlikely(tstat.float_exception_flags & float_flag_invalid)) {
float_invalid_op_addsub(env, 1, GETPC(),
- float128_classify(xa.f128) |
- float128_classify(xb.f128));
+ float128_classify(xa->f128) |
+ float128_classify(xb->f128));
}
- helper_compute_fprf_float128(env, xt.f128);
- putVSR(rD(opcode) + 32, &xt, env);
+ helper_compute_fprf_float128(env, t.f128);
+ *xt = t;
do_float_check_status(env, GETPC());
}