diff options
author | Lucas Coutinho <lucas.coutinho@eldorado.org.br> | 2022-03-20 23:35:27 +0100 |
---|---|---|
committer | Cédric Le Goater <clg@kaod.org> | 2022-03-20 23:35:27 +0100 |
commit | 3515553bf625ad48aa90210379c4f387c2596093 (patch) | |
tree | 2b0de8f4019521c31af91295b07b95b5c88ab95d /target/ppc/fpu_helper.c | |
parent | 217979d33e78ee64978295962c33d8525973c760 (diff) |
target/ppc: Replicate Double->Single-Precision result
Power ISA v3.1 formalizes the previously undefined result in
words 1 and 3 to be a copy of the result in words 0 and 2.
This affects: xvcvsxdsp, xvcvuxdsp, xvcvdpsp.
And the previously undefined result in word 1 to be a copy of
the result in word 0.
This affects: xscvdpsp.
Signed-off-by: Lucas Coutinho <lucas.coutinho@eldorado.org.br>
Message-Id: <20220316200427.3410437-1-lucas.coutinho@eldorado.org.br>
Signed-off-by: Cédric Le Goater <clg@kaod.org>
Diffstat (limited to 'target/ppc/fpu_helper.c')
-rw-r--r-- | target/ppc/fpu_helper.c | 48 |
1 files changed, 44 insertions, 4 deletions
diff --git a/target/ppc/fpu_helper.c b/target/ppc/fpu_helper.c index 564f2ec353..7e8be99cc0 100644 --- a/target/ppc/fpu_helper.c +++ b/target/ppc/fpu_helper.c @@ -2691,11 +2691,35 @@ void helper_##op(CPUPPCState *env, ppc_vsr_t *xt, ppc_vsr_t *xb) \ do_float_check_status(env, GETPC()); \ } -VSX_CVT_FP_TO_FP(xscvdpsp, 1, float64, float32, VsrD(0), VsrW(0), 1) VSX_CVT_FP_TO_FP(xscvspdp, 1, float32, float64, VsrW(0), VsrD(0), 1) -VSX_CVT_FP_TO_FP(xvcvdpsp, 2, float64, float32, VsrD(i), VsrW(2 * i), 0) VSX_CVT_FP_TO_FP(xvcvspdp, 2, float32, float64, VsrW(2 * i), VsrD(i), 0) +#define VSX_CVT_FP_TO_FP2(op, nels, stp, ttp, sfprf) \ +void helper_##op(CPUPPCState *env, ppc_vsr_t *xt, ppc_vsr_t *xb) \ +{ \ + ppc_vsr_t t = { }; \ + int i; \ + \ + for (i = 0; i < nels; i++) { \ + t.VsrW(2 * i) = stp##_to_##ttp(xb->VsrD(i), &env->fp_status); \ + if (unlikely(stp##_is_signaling_nan(xb->VsrD(i), \ + &env->fp_status))) { \ + float_invalid_op_vxsnan(env, GETPC()); \ + t.VsrW(2 * i) = ttp##_snan_to_qnan(t.VsrW(2 * i)); \ + } \ + if (sfprf) { \ + helper_compute_fprf_##ttp(env, t.VsrW(2 * i)); \ + } \ + t.VsrW(2 * i + 1) = t.VsrW(2 * i); \ + } \ + \ + *xt = t; \ + do_float_check_status(env, GETPC()); \ +} + +VSX_CVT_FP_TO_FP2(xvcvdpsp, 2, float64, float32, 0) +VSX_CVT_FP_TO_FP2(xscvdpsp, 1, float64, float32, 1) + /* * VSX_CVT_FP_TO_FP_VECTOR - VSX floating point/floating point conversion * op - instruction mnemonic @@ -3013,11 +3037,27 @@ VSX_CVT_INT_TO_FP(xvcvsxddp, 2, int64, float64, VsrD(i), VsrD(i), 0, 0) VSX_CVT_INT_TO_FP(xvcvuxddp, 2, uint64, float64, VsrD(i), VsrD(i), 0, 0) VSX_CVT_INT_TO_FP(xvcvsxwdp, 2, int32, float64, VsrW(2 * i), VsrD(i), 0, 0) VSX_CVT_INT_TO_FP(xvcvuxwdp, 2, uint64, float64, VsrW(2 * i), VsrD(i), 0, 0) -VSX_CVT_INT_TO_FP(xvcvsxdsp, 2, int64, float32, VsrD(i), VsrW(2 * i), 0, 0) -VSX_CVT_INT_TO_FP(xvcvuxdsp, 2, uint64, float32, VsrD(i), VsrW(2 * i), 0, 0) VSX_CVT_INT_TO_FP(xvcvsxwsp, 4, int32, float32, VsrW(i), VsrW(i), 0, 0) VSX_CVT_INT_TO_FP(xvcvuxwsp, 4, uint32, float32, VsrW(i), VsrW(i), 0, 0) +#define VSX_CVT_INT_TO_FP2(op, stp, ttp) \ +void helper_##op(CPUPPCState *env, ppc_vsr_t *xt, ppc_vsr_t *xb) \ +{ \ + ppc_vsr_t t = { }; \ + int i; \ + \ + for (i = 0; i < 2; i++) { \ + t.VsrW(2 * i) = stp##_to_##ttp(xb->VsrD(i), &env->fp_status); \ + t.VsrW(2 * i + 1) = t.VsrW(2 * i); \ + } \ + \ + *xt = t; \ + do_float_check_status(env, GETPC()); \ +} + +VSX_CVT_INT_TO_FP2(xvcvsxdsp, int64, float32) +VSX_CVT_INT_TO_FP2(xvcvuxdsp, uint64, float32) + /* * VSX_CVT_INT_TO_FP_VECTOR - VSX integer to floating point conversion * op - instruction mnemonic |