diff options
author | Mark Cave-Ayland | 2019-09-26 20:57:59 +0200 |
---|---|---|
committer | David Gibson | 2019-10-04 11:08:21 +0200 |
commit | 64b8574e143f2287009ad77a12b87e64516a0711 (patch) | |
tree | c371b1303d51680ffaffc9b4eb0ed21ad62e29d7 | |
parent | target/ppc: introduce dfp_finalize_decimal{64,128}() helper functions (diff) | |
download | qemu-64b8574e143f2287009ad77a12b87e64516a0711.tar.gz qemu-64b8574e143f2287009ad77a12b87e64516a0711.tar.xz qemu-64b8574e143f2287009ad77a12b87e64516a0711.zip |
target/ppc: change struct PPC_DFP decimal storage from uint64[2] to ppc_vsr_t
There are several places in dfp_helper.c that access the decimal number
representations in struct PPC_DFP via HI_IDX and LO_IDX defines which are set
at the top of dfp_helper.c according to the host endian.
However we can instead switch to using ppc_vsr_t for decimal numbers and then
make subsequent use of the existing VsrD() macros to access the correct
element regardless of host endian. Note that 64-bit decimals are stored in the
LSB of ppc_vsr_t (equivalent to VsrD(1)).
Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-Id: <20190926185801.11176-6-mark.cave-ayland@ilande.co.uk>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
-rw-r--r-- | target/ppc/dfp_helper.c | 210 |
1 files changed, 108 insertions, 102 deletions
diff --git a/target/ppc/dfp_helper.c b/target/ppc/dfp_helper.c index 8e1ea2971a..b72084d50a 100644 --- a/target/ppc/dfp_helper.c +++ b/target/ppc/dfp_helper.c @@ -36,31 +36,31 @@ #define LO_IDX 0 #endif -static void get_dfp64(uint64_t *dst, ppc_fprp_t *dfp) +static void get_dfp64(ppc_vsr_t *dst, ppc_fprp_t *dfp) { - dst[0] = dfp->VsrD(0); + dst->VsrD(1) = dfp->VsrD(0); } -static void get_dfp128(uint64_t *dst, ppc_fprp_t *dfp) +static void get_dfp128(ppc_vsr_t *dst, ppc_fprp_t *dfp) { - dst[HI_IDX] = dfp[0].VsrD(0); - dst[LO_IDX] = dfp[1].VsrD(0); + dst->VsrD(0) = dfp[0].VsrD(0); + dst->VsrD(1) = dfp[1].VsrD(0); } -static void set_dfp64(ppc_fprp_t *dfp, uint64_t *src) +static void set_dfp64(ppc_fprp_t *dfp, ppc_vsr_t *src) { - dfp->VsrD(0) = src[0]; + dfp->VsrD(0) = src->VsrD(1); } -static void set_dfp128(ppc_fprp_t *dfp, uint64_t *src) +static void set_dfp128(ppc_fprp_t *dfp, ppc_vsr_t *src) { - dfp[0].VsrD(0) = src[HI_IDX]; - dfp[1].VsrD(0) = src[LO_IDX]; + dfp[0].VsrD(0) = src->VsrD(0); + dfp[1].VsrD(0) = src->VsrD(1); } struct PPC_DFP { CPUPPCState *env; - uint64_t t64[2], a64[2], b64[2]; + ppc_vsr_t vt, va, vb; decNumber t, a, b; decContext context; uint8_t crbf; @@ -151,18 +151,18 @@ static void dfp_prepare_decimal64(struct PPC_DFP *dfp, ppc_fprp_t *a, dfp->env = env; if (a) { - get_dfp64(dfp->a64, a); - decimal64ToNumber((decimal64 *)dfp->a64, &dfp->a); + get_dfp64(&dfp->va, a); + decimal64ToNumber((decimal64 *)&dfp->va.VsrD(1), &dfp->a); } else { - dfp->a64[0] = 0; + dfp->va.VsrD(1) = 0; decNumberZero(&dfp->a); } if (b) { - get_dfp64(dfp->b64, b); - decimal64ToNumber((decimal64 *)dfp->b64, &dfp->b); + get_dfp64(&dfp->vb, b); + decimal64ToNumber((decimal64 *)&dfp->vb.VsrD(1), &dfp->b); } else { - dfp->b64[0] = 0; + dfp->vb.VsrD(1) = 0; decNumberZero(&dfp->b); } } @@ -175,30 +175,30 @@ static void dfp_prepare_decimal128(struct PPC_DFP *dfp, ppc_fprp_t *a, dfp->env = env; if (a) { - get_dfp128(dfp->a64, a); - decimal128ToNumber((decimal128 *)dfp->a64, &dfp->a); + get_dfp128(&dfp->va, a); + decimal128ToNumber((decimal128 *)&dfp->va, &dfp->a); } else { - dfp->a64[0] = dfp->a64[1] = 0; + dfp->va.VsrD(0) = dfp->va.VsrD(1) = 0; decNumberZero(&dfp->a); } if (b) { - get_dfp128(dfp->b64, b); - decimal128ToNumber((decimal128 *)dfp->b64, &dfp->b); + get_dfp128(&dfp->vb, b); + decimal128ToNumber((decimal128 *)&dfp->vb, &dfp->b); } else { - dfp->b64[0] = dfp->b64[1] = 0; + dfp->vb.VsrD(0) = dfp->vb.VsrD(1) = 0; decNumberZero(&dfp->b); } } static void dfp_finalize_decimal64(struct PPC_DFP *dfp) { - decimal64FromNumber((decimal64 *)&dfp->t64, &dfp->t, &dfp->context); + decimal64FromNumber((decimal64 *)&dfp->vt.VsrD(1), &dfp->t, &dfp->context); } static void dfp_finalize_decimal128(struct PPC_DFP *dfp) { - decimal128FromNumber((decimal128 *)&dfp->t64, &dfp->t, &dfp->context); + decimal128FromNumber((decimal128 *)&dfp->vt, &dfp->t, &dfp->context); } static void dfp_set_FPSCR_flag(struct PPC_DFP *dfp, uint64_t flag, @@ -435,9 +435,9 @@ void helper_##op(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *a, \ dfp_finalize_decimal##size(&dfp); \ postprocs(&dfp); \ if (size == 64) { \ - set_dfp64(t, dfp.t64); \ + set_dfp64(t, &dfp.vt); \ } else if (size == 128) { \ - set_dfp128(t, dfp.t64); \ + set_dfp128(t, &dfp.vt); \ } \ } @@ -647,12 +647,12 @@ uint32_t helper_##op(CPUPPCState *env, ppc_fprp_t *a, ppc_fprp_t *b) \ { \ struct PPC_DFP dfp; \ unsigned k; \ - uint64_t a64; \ + ppc_vsr_t va; \ \ dfp_prepare_decimal##size(&dfp, 0, b, env); \ \ - get_dfp64(&a64, a); \ - k = a64 & 0x3F; \ + get_dfp64(&va, a); \ + k = va.VsrD(1) & 0x3F; \ \ if (unlikely(decNumberIsSpecial(&dfp.b))) { \ dfp.crbf = 1; \ @@ -755,9 +755,9 @@ void helper_##op(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *b, \ QUA_PPs(&dfp); \ \ if (size == 64) { \ - set_dfp64(t, dfp.t64); \ + set_dfp64(t, &dfp.vt); \ } else if (size == 128) { \ - set_dfp128(t, dfp.t64); \ + set_dfp128(t, &dfp.vt); \ } \ } @@ -777,9 +777,9 @@ void helper_##op(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *a, \ QUA_PPs(&dfp); \ \ if (size == 64) { \ - set_dfp64(t, dfp.t64); \ + set_dfp64(t, &dfp.vt); \ } else if (size == 128) { \ - set_dfp128(t, dfp.t64); \ + set_dfp128(t, &dfp.vt); \ } \ } @@ -845,23 +845,23 @@ void helper_##op(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *a, \ ppc_fprp_t *b, uint32_t rmc) \ { \ struct PPC_DFP dfp; \ - uint64_t a64; \ + ppc_vsr_t va; \ int32_t ref_sig; \ int32_t xmax = ((size) == 64) ? 369 : 6111; \ \ dfp_prepare_decimal##size(&dfp, 0, b, env); \ \ - get_dfp64(&a64, a); \ - ref_sig = a64 & 0x3f; \ + get_dfp64(&va, a); \ + ref_sig = va.VsrD(1) & 0x3f; \ \ _dfp_reround(rmc, ref_sig, xmax, &dfp); \ dfp_finalize_decimal##size(&dfp); \ QUA_PPs(&dfp); \ \ if (size == 64) { \ - set_dfp64(t, dfp.t64); \ + set_dfp64(t, &dfp.vt); \ } else if (size == 128) { \ - set_dfp128(t, dfp.t64); \ + set_dfp128(t, &dfp.vt); \ } \ } @@ -882,9 +882,9 @@ void helper_##op(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *b, \ postprocs(&dfp); \ \ if (size == 64) { \ - set_dfp64(t, dfp.t64); \ + set_dfp64(t, &dfp.vt); \ } else if (size == 128) { \ - set_dfp128(t, dfp.t64); \ + set_dfp128(t, &dfp.vt); \ } \ } @@ -910,39 +910,39 @@ DFP_HELPER_RINT(drintnq, RINTN_PPs, 128) void helper_dctdp(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *b) { struct PPC_DFP dfp; - uint64_t b64; + ppc_vsr_t vb; uint32_t b_short; - get_dfp64(&b64, b); - b_short = (uint32_t)b64; + get_dfp64(&vb, b); + b_short = (uint32_t)vb.VsrD(1); dfp_prepare_decimal64(&dfp, 0, 0, env); decimal32ToNumber((decimal32 *)&b_short, &dfp.t); dfp_finalize_decimal64(&dfp); - set_dfp64(t, dfp.t64); + set_dfp64(t, &dfp.vt); dfp_set_FPRF_from_FRT(&dfp); } void helper_dctqpq(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *b) { struct PPC_DFP dfp; - uint64_t b64; + ppc_vsr_t vb; dfp_prepare_decimal128(&dfp, 0, 0, env); - get_dfp64(&b64, b); - decimal64ToNumber((decimal64 *)&b64, &dfp.t); + get_dfp64(&vb, b); + decimal64ToNumber((decimal64 *)&vb.VsrD(1), &dfp.t); dfp_check_for_VXSNAN_and_convert_to_QNaN(&dfp); dfp_set_FPRF_from_FRT(&dfp); dfp_finalize_decimal128(&dfp); - set_dfp128(t, dfp.t64); + set_dfp128(t, &dfp.vt); } void helper_drsp(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *b) { struct PPC_DFP dfp; uint32_t t_short = 0; - uint64_t t64; + ppc_vsr_t vt; dfp_prepare_decimal64(&dfp, 0, b, env); decimal32FromNumber((decimal32 *)&t_short, &dfp.b, &dfp.context); decimal32ToNumber((decimal32 *)&t_short, &dfp.t); @@ -952,16 +952,16 @@ void helper_drsp(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *b) dfp_check_for_UX(&dfp); dfp_check_for_XX(&dfp); - t64 = (uint64_t)t_short; - set_dfp64(t, &t64); + vt.VsrD(1) = (uint64_t)t_short; + set_dfp64(t, &vt); } void helper_drdpq(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *b) { struct PPC_DFP dfp; dfp_prepare_decimal128(&dfp, 0, b, env); - decimal64FromNumber((decimal64 *)&dfp.t64, &dfp.b, &dfp.context); - decimal64ToNumber((decimal64 *)&dfp.t64, &dfp.t); + decimal64FromNumber((decimal64 *)&dfp.vt.VsrD(1), &dfp.b, &dfp.context); + decimal64ToNumber((decimal64 *)&dfp.vt.VsrD(1), &dfp.t); dfp_check_for_VXSNAN_and_convert_to_QNaN(&dfp); dfp_set_FPRF_from_FRT_long(&dfp); @@ -969,26 +969,26 @@ void helper_drdpq(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *b) dfp_check_for_UX(&dfp); dfp_check_for_XX(&dfp); - dfp.t64[0] = dfp.t64[1] = 0; + dfp.vt.VsrD(0) = dfp.vt.VsrD(1) = 0; dfp_finalize_decimal64(&dfp); - set_dfp128(t, dfp.t64); + set_dfp128(t, &dfp.vt); } #define DFP_HELPER_CFFIX(op, size) \ void helper_##op(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *b) \ { \ struct PPC_DFP dfp; \ - uint64_t b64; \ + ppc_vsr_t vb; \ dfp_prepare_decimal##size(&dfp, 0, b, env); \ - get_dfp64(&b64, b); \ - decNumberFromInt64(&dfp.t, (int64_t)b64); \ + get_dfp64(&vb, b); \ + decNumberFromInt64(&dfp.t, (int64_t)vb.VsrD(1)); \ dfp_finalize_decimal##size(&dfp); \ CFFIX_PPs(&dfp); \ \ if (size == 64) { \ - set_dfp64(t, dfp.t64); \ + set_dfp64(t, &dfp.vt); \ } else if (size == 128) { \ - set_dfp128(t, dfp.t64); \ + set_dfp128(t, &dfp.vt); \ } \ } @@ -1010,28 +1010,30 @@ void helper_##op(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *b) \ if (unlikely(decNumberIsSpecial(&dfp.b))) { \ uint64_t invalid_flags = FP_VX | FP_VXCVI; \ if (decNumberIsInfinite(&dfp.b)) { \ - dfp.t64[0] = decNumberIsNegative(&dfp.b) ? INT64_MIN : INT64_MAX; \ + dfp.vt.VsrD(1) = decNumberIsNegative(&dfp.b) ? INT64_MIN : \ + INT64_MAX; \ } else { /* NaN */ \ - dfp.t64[0] = INT64_MIN; \ + dfp.vt.VsrD(1) = INT64_MIN; \ if (decNumberIsSNaN(&dfp.b)) { \ invalid_flags |= FP_VXSNAN; \ } \ } \ dfp_set_FPSCR_flag(&dfp, invalid_flags, FP_VE); \ } else if (unlikely(decNumberIsZero(&dfp.b))) { \ - dfp.t64[0] = 0; \ + dfp.vt.VsrD(1) = 0; \ } else { \ decNumberToIntegralExact(&dfp.b, &dfp.b, &dfp.context); \ - dfp.t64[0] = decNumberIntegralToInt64(&dfp.b, &dfp.context); \ + dfp.vt.VsrD(1) = decNumberIntegralToInt64(&dfp.b, &dfp.context); \ if (decContextTestStatus(&dfp.context, DEC_Invalid_operation)) { \ - dfp.t64[0] = decNumberIsNegative(&dfp.b) ? INT64_MIN : INT64_MAX; \ + dfp.vt.VsrD(1) = decNumberIsNegative(&dfp.b) ? INT64_MIN : \ + INT64_MAX; \ dfp_set_FPSCR_flag(&dfp, FP_VX | FP_VXCVI, FP_VE); \ } else { \ dfp_check_for_XX(&dfp); \ } \ } \ \ - set_dfp64(t, dfp.t64); \ + set_dfp64(t, &dfp.vt); \ } DFP_HELPER_CTFIX(dctfix, 64) @@ -1075,11 +1077,11 @@ void helper_##op(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *b, \ dfp_prepare_decimal##size(&dfp, 0, b, env); \ \ decNumberGetBCD(&dfp.b, digits); \ - dfp.t64[0] = dfp.t64[1] = 0; \ + dfp.vt.VsrD(0) = dfp.vt.VsrD(1) = 0; \ N = dfp.b.digits; \ \ for (i = 0; (i < N) && (i < (size)/4); i++) { \ - dfp_set_bcd_digit_##size(dfp.t64, digits[N-i-1], i); \ + dfp_set_bcd_digit_##size(&dfp.vt.u64[0], digits[N - i - 1], i); \ } \ \ if (sp & 2) { \ @@ -1090,13 +1092,13 @@ void helper_##op(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *b, \ } else { \ sgn = ((sp & 1) ? 0xF : 0xC); \ } \ - dfp_set_sign_##size(dfp.t64, sgn); \ + dfp_set_sign_##size(&dfp.vt.u64[0], sgn); \ } \ \ if (size == 64) { \ - set_dfp64(t, dfp.t64); \ + set_dfp64(t, &dfp.vt); \ } else if (size == 128) { \ - set_dfp128(t, dfp.t64); \ + set_dfp128(t, &dfp.vt); \ } \ } @@ -1126,7 +1128,8 @@ void helper_##op(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *b, \ decNumberZero(&dfp.t); \ \ if (s) { \ - uint8_t sgnNibble = dfp_get_bcd_digit_##size(dfp.b64, offset++); \ + uint8_t sgnNibble = dfp_get_bcd_digit_##size(&dfp.vb.u64[0], \ + offset++); \ switch (sgnNibble) { \ case 0xD: \ case 0xB: \ @@ -1146,7 +1149,8 @@ void helper_##op(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *b, \ \ while (offset < (size) / 4) { \ n++; \ - digits[(size) / 4 - n] = dfp_get_bcd_digit_##size(dfp.b64, offset++); \ + digits[(size) / 4 - n] = dfp_get_bcd_digit_##size(&dfp.vb.u64[0], \ + offset++); \ if (digits[(size) / 4 - n] > 10) { \ dfp_set_FPSCR_flag(&dfp, FP_VX | FP_VXCVI, FPSCR_VE); \ return; \ @@ -1165,9 +1169,9 @@ void helper_##op(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *b, \ dfp_finalize_decimal##size(&dfp); \ dfp_set_FPRF_from_FRT(&dfp); \ if ((size) == 64) { \ - set_dfp64(t, dfp.t64); \ + set_dfp64(t, &dfp.vt); \ } else if ((size) == 128) { \ - set_dfp128(t, dfp.t64); \ + set_dfp128(t, &dfp.vt); \ } \ } @@ -1178,30 +1182,30 @@ DFP_HELPER_ENBCD(denbcdq, 128) void helper_##op(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *b) \ { \ struct PPC_DFP dfp; \ - uint64_t t64; \ + ppc_vsr_t vt; \ \ dfp_prepare_decimal##size(&dfp, 0, b, env); \ \ if (unlikely(decNumberIsSpecial(&dfp.b))) { \ if (decNumberIsInfinite(&dfp.b)) { \ - t64 = -1; \ + vt.VsrD(1) = -1; \ } else if (decNumberIsSNaN(&dfp.b)) { \ - t64 = -3; \ + vt.VsrD(1) = -3; \ } else if (decNumberIsQNaN(&dfp.b)) { \ - t64 = -2; \ + vt.VsrD(1) = -2; \ } else { \ assert(0); \ } \ - set_dfp64(t, &t64); \ + set_dfp64(t, &vt); \ } else { \ if ((size) == 64) { \ - t64 = dfp.b.exponent + 398; \ + vt.VsrD(1) = dfp.b.exponent + 398; \ } else if ((size) == 128) { \ - t64 = dfp.b.exponent + 6176; \ + vt.VsrD(1) = dfp.b.exponent + 6176; \ } else { \ assert(0); \ } \ - set_dfp64(t, &t64); \ + set_dfp64(t, &vt); \ } \ } @@ -1225,12 +1229,13 @@ void helper_##op(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *a, \ ppc_fprp_t *b) \ { \ struct PPC_DFP dfp; \ - uint64_t raw_qnan, raw_snan, raw_inf, max_exp, a64; \ + uint64_t raw_qnan, raw_snan, raw_inf, max_exp; \ + ppc_vsr_t va; \ int bias; \ int64_t exp; \ \ - get_dfp64(&a64, a); \ - exp = (int64_t)a64; \ + get_dfp64(&va, a); \ + exp = (int64_t)va.VsrD(1); \ dfp_prepare_decimal##size(&dfp, 0, b, env); \ \ if ((size) == 64) { \ @@ -1250,14 +1255,14 @@ void helper_##op(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *a, \ } \ \ if (unlikely((exp < 0) || (exp > max_exp))) { \ - dfp.t64[0] = dfp.b64[0]; \ - dfp.t64[1] = dfp.b64[1]; \ + dfp.vt.VsrD(0) = dfp.vb.VsrD(0); \ + dfp.vt.VsrD(1) = dfp.vb.VsrD(1); \ if (exp == -1) { \ - dfp_set_raw_exp_##size(dfp.t64, raw_inf); \ + dfp_set_raw_exp_##size(&dfp.vt.u64[0], raw_inf); \ } else if (exp == -3) { \ - dfp_set_raw_exp_##size(dfp.t64, raw_snan); \ + dfp_set_raw_exp_##size(&dfp.vt.u64[0], raw_snan); \ } else { \ - dfp_set_raw_exp_##size(dfp.t64, raw_qnan); \ + dfp_set_raw_exp_##size(&dfp.vt.u64[0], raw_qnan); \ } \ } else { \ dfp.t = dfp.b; \ @@ -1268,9 +1273,9 @@ void helper_##op(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *a, \ dfp_finalize_decimal##size(&dfp); \ } \ if (size == 64) { \ - set_dfp64(t, dfp.t64); \ + set_dfp64(t, &dfp.vt); \ } else if (size == 128) { \ - set_dfp128(t, dfp.t64); \ + set_dfp128(t, &dfp.vt); \ } \ } @@ -1348,20 +1353,21 @@ void helper_##op(CPUPPCState *env, ppc_fprp_t *t, ppc_fprp_t *a, \ dfp_finalize_decimal##size(&dfp); \ } else { \ if ((size) == 64) { \ - dfp.t64[0] = dfp.a64[0] & 0xFFFC000000000000ULL; \ - dfp_clear_lmd_from_g5msb(dfp.t64); \ + dfp.vt.VsrD(1) = dfp.va.VsrD(1) & \ + 0xFFFC000000000000ULL; \ + dfp_clear_lmd_from_g5msb(&dfp.vt.VsrD(1)); \ } else { \ - dfp.t64[HI_IDX] = dfp.a64[HI_IDX] & \ - 0xFFFFC00000000000ULL; \ - dfp_clear_lmd_from_g5msb(dfp.t64 + HI_IDX); \ - dfp.t64[LO_IDX] = 0; \ + dfp.vt.VsrD(0) = dfp.va.VsrD(0) & \ + 0xFFFFC00000000000ULL; \ + dfp_clear_lmd_from_g5msb(&dfp.vt.VsrD(0)); \ + dfp.vt.VsrD(1) = 0; \ } \ } \ \ if ((size) == 64) { \ - set_dfp64(t, dfp.t64); \ + set_dfp64(t, &dfp.vt); \ } else { \ - set_dfp128(t, dfp.t64); \ + set_dfp128(t, &dfp.vt); \ } \ } |