diff options
author | Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk> | 2019-09-26 19:57:56 +0100 |
---|---|---|
committer | David Gibson <david@gibson.dropbear.id.au> | 2019-10-04 19:08:21 +1000 |
commit | 33432d7737b53c92791f90ece5dbe3b7bb1c79f5 (patch) | |
tree | 2f116ddceb3faed9c5d67ae8dce2eca72755698c | |
parent | 6a8fbb9bdb7c06b2a73085fd846e22cd3b65242d (diff) | |
download | qemu-33432d7737b53c92791f90ece5dbe3b7bb1c79f5.zip qemu-33432d7737b53c92791f90ece5dbe3b7bb1c79f5.tar.gz qemu-33432d7737b53c92791f90ece5dbe3b7bb1c79f5.tar.bz2 |
target/ppc: introduce set_dfp{64,128}() helper functions
The existing functions (now incorrectly) assume that the MSB and LSB of DFP
numbers are stored as consecutive 64-bit words in memory. Instead of accessing
the DFP numbers directly, introduce set_dfp{64,128}() helper functions to ease
the switch to the correct representation.
Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-Id: <20190926185801.11176-3-mark.cave-ayland@ilande.co.uk>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
-rw-r--r-- | target/ppc/dfp_helper.c | 90 |
1 files changed, 48 insertions, 42 deletions
diff --git a/target/ppc/dfp_helper.c b/target/ppc/dfp_helper.c index e4369eb..3923a07 100644 --- a/target/ppc/dfp_helper.c +++ b/target/ppc/dfp_helper.c @@ -47,6 +47,17 @@ static void get_dfp128(uint64_t *dst, uint64_t *dfp) dst[1] = dfp[LO_IDX]; } +static void set_dfp64(uint64_t *dfp, uint64_t *src) +{ + dfp[0] = src[0]; +} + +static void set_dfp128(uint64_t *dfp, uint64_t *src) +{ + dfp[0] = src[HI_IDX]; + dfp[1] = src[LO_IDX]; +} + struct PPC_DFP { CPUPPCState *env; uint64_t t64[2], a64[2], b64[2]; @@ -413,10 +424,9 @@ void helper_##op(CPUPPCState *env, uint64_t *t, uint64_t *a, uint64_t *b) \ decimal##size##FromNumber((decimal##size *)dfp.t64, &dfp.t, &dfp.context); \ postprocs(&dfp); \ if (size == 64) { \ - t[0] = dfp.t64[0]; \ + set_dfp64(t, dfp.t64); \ } else if (size == 128) { \ - t[0] = dfp.t64[HI_IDX]; \ - t[1] = dfp.t64[LO_IDX]; \ + set_dfp128(t, dfp.t64); \ } \ } @@ -735,10 +745,9 @@ void helper_##op(CPUPPCState *env, uint64_t *t, uint64_t *b, \ QUA_PPs(&dfp); \ \ if (size == 64) { \ - t[0] = dfp.t64[0]; \ + set_dfp64(t, dfp.t64); \ } else if (size == 128) { \ - t[0] = dfp.t64[HI_IDX]; \ - t[1] = dfp.t64[LO_IDX]; \ + set_dfp128(t, dfp.t64); \ } \ } @@ -759,10 +768,9 @@ void helper_##op(CPUPPCState *env, uint64_t *t, uint64_t *a, \ QUA_PPs(&dfp); \ \ if (size == 64) { \ - t[0] = dfp.t64[0]; \ + set_dfp64(t, dfp.t64); \ } else if (size == 128) { \ - t[0] = dfp.t64[HI_IDX]; \ - t[1] = dfp.t64[LO_IDX]; \ + set_dfp128(t, dfp.t64); \ } \ } @@ -843,10 +851,9 @@ void helper_##op(CPUPPCState *env, uint64_t *t, uint64_t *a, \ QUA_PPs(&dfp); \ \ if (size == 64) { \ - t[0] = dfp.t64[0]; \ + set_dfp64(t, dfp.t64); \ } else if (size == 128) { \ - t[0] = dfp.t64[HI_IDX]; \ - t[1] = dfp.t64[LO_IDX]; \ + set_dfp128(t, dfp.t64); \ } \ } @@ -867,10 +874,9 @@ void helper_##op(CPUPPCState *env, uint64_t *t, uint64_t *b, \ postprocs(&dfp); \ \ if (size == 64) { \ - t[0] = dfp.t64[0]; \ + set_dfp64(t, dfp.t64); \ } else if (size == 128) { \ - t[0] = dfp.t64[HI_IDX]; \ - t[1] = dfp.t64[LO_IDX]; \ + set_dfp128(t, dfp.t64); \ } \ } @@ -904,7 +910,8 @@ void helper_dctdp(CPUPPCState *env, uint64_t *t, uint64_t *b) dfp_prepare_decimal64(&dfp, 0, 0, env); decimal32ToNumber((decimal32 *)&b_short, &dfp.t); - decimal64FromNumber((decimal64 *)t, &dfp.t, &dfp.context); + decimal64FromNumber((decimal64 *)&dfp.t64, &dfp.t, &dfp.context); + set_dfp64(t, dfp.t64); dfp_set_FPRF_from_FRT(&dfp); } @@ -920,14 +927,14 @@ void helper_dctqpq(CPUPPCState *env, uint64_t *t, uint64_t *b) dfp_set_FPRF_from_FRT(&dfp); decimal128FromNumber((decimal128 *)&dfp.t64, &dfp.t, &dfp.context); - t[0] = dfp.t64[HI_IDX]; - t[1] = dfp.t64[LO_IDX]; + set_dfp128(t, dfp.t64); } void helper_drsp(CPUPPCState *env, uint64_t *t, uint64_t *b) { struct PPC_DFP dfp; uint32_t t_short = 0; + uint64_t t64; dfp_prepare_decimal64(&dfp, 0, b, env); decimal32FromNumber((decimal32 *)&t_short, &dfp.b, &dfp.context); decimal32ToNumber((decimal32 *)&t_short, &dfp.t); @@ -937,7 +944,8 @@ void helper_drsp(CPUPPCState *env, uint64_t *t, uint64_t *b) dfp_check_for_UX(&dfp); dfp_check_for_XX(&dfp); - *t = t_short; + t64 = (uint64_t)t_short; + set_dfp64(t, &t64); } void helper_drdpq(CPUPPCState *env, uint64_t *t, uint64_t *b) @@ -953,9 +961,9 @@ void helper_drdpq(CPUPPCState *env, uint64_t *t, uint64_t *b) dfp_check_for_UX(&dfp); dfp_check_for_XX(&dfp); + dfp.t64[0] = dfp.t64[1] = 0; decimal64FromNumber((decimal64 *)dfp.t64, &dfp.t, &dfp.context); - t[0] = dfp.t64[0]; - t[1] = 0; + set_dfp128(t, dfp.t64); } #define DFP_HELPER_CFFIX(op, size) \ @@ -970,10 +978,9 @@ void helper_##op(CPUPPCState *env, uint64_t *t, uint64_t *b) \ CFFIX_PPs(&dfp); \ \ if (size == 64) { \ - t[0] = dfp.t64[0]; \ + set_dfp64(t, dfp.t64); \ } else if (size == 128) { \ - t[0] = dfp.t64[HI_IDX]; \ - t[1] = dfp.t64[LO_IDX]; \ + set_dfp128(t, dfp.t64); \ } \ } @@ -1016,7 +1023,7 @@ void helper_##op(CPUPPCState *env, uint64_t *t, uint64_t *b) \ } \ } \ \ - *t = dfp.t64[0]; \ + set_dfp64(t, dfp.t64); \ } DFP_HELPER_CTFIX(dctfix, 64) @@ -1078,10 +1085,9 @@ void helper_##op(CPUPPCState *env, uint64_t *t, uint64_t *b, uint32_t sp) \ } \ \ if (size == 64) { \ - t[0] = dfp.t64[0]; \ + set_dfp64(t, dfp.t64); \ } else if (size == 128) { \ - t[0] = dfp.t64[HI_IDX]; \ - t[1] = dfp.t64[LO_IDX]; \ + set_dfp128(t, dfp.t64); \ } \ } @@ -1150,10 +1156,9 @@ void helper_##op(CPUPPCState *env, uint64_t *t, uint64_t *b, uint32_t s) \ &dfp.context); \ dfp_set_FPRF_from_FRT(&dfp); \ if ((size) == 64) { \ - t[0] = dfp.t64[0]; \ + set_dfp64(t, dfp.t64); \ } else if ((size) == 128) { \ - t[0] = dfp.t64[HI_IDX]; \ - t[1] = dfp.t64[LO_IDX]; \ + set_dfp128(t, dfp.t64); \ } \ } @@ -1164,27 +1169,30 @@ DFP_HELPER_ENBCD(denbcdq, 128) void helper_##op(CPUPPCState *env, uint64_t *t, uint64_t *b) \ { \ struct PPC_DFP dfp; \ + uint64_t t64; \ \ dfp_prepare_decimal##size(&dfp, 0, b, env); \ \ if (unlikely(decNumberIsSpecial(&dfp.b))) { \ if (decNumberIsInfinite(&dfp.b)) { \ - *t = -1; \ + t64 = -1; \ } else if (decNumberIsSNaN(&dfp.b)) { \ - *t = -3; \ + t64 = -3; \ } else if (decNumberIsQNaN(&dfp.b)) { \ - *t = -2; \ + t64 = -2; \ } else { \ assert(0); \ } \ + set_dfp64(t, &t64); \ } else { \ if ((size) == 64) { \ - *t = dfp.b.exponent + 398; \ + t64 = dfp.b.exponent + 398; \ } else if ((size) == 128) { \ - *t = dfp.b.exponent + 6176; \ + t64 = dfp.b.exponent + 6176; \ } else { \ assert(0); \ } \ + set_dfp64(t, &t64); \ } \ } @@ -1251,10 +1259,9 @@ void helper_##op(CPUPPCState *env, uint64_t *t, uint64_t *a, uint64_t *b) \ &dfp.context); \ } \ if (size == 64) { \ - t[0] = dfp.t64[0]; \ + set_dfp64(t, dfp.t64); \ } else if (size == 128) { \ - t[0] = dfp.t64[HI_IDX]; \ - t[1] = dfp.t64[LO_IDX]; \ + set_dfp128(t, dfp.t64); \ } \ } @@ -1344,10 +1351,9 @@ void helper_##op(CPUPPCState *env, uint64_t *t, uint64_t *a, \ } \ \ if ((size) == 64) { \ - t[0] = dfp.t64[0]; \ + set_dfp64(t, dfp.t64); \ } else { \ - t[0] = dfp.t64[HI_IDX]; \ - t[1] = dfp.t64[LO_IDX]; \ + set_dfp128(t, dfp.t64); \ } \ } |