aboutsummaryrefslogtreecommitdiff
path: root/target/ppc/dfp_helper.c
diff options
context:
space:
mode:
authorMark Cave-Ayland <mark.cave-ayland@ilande.co.uk>2019-09-26 19:57:55 +0100
committerDavid Gibson <david@gibson.dropbear.id.au>2019-10-04 19:08:20 +1000
commit6a8fbb9bdb7c06b2a73085fd846e22cd3b65242d (patch)
tree403949c292aa635b1b641d1380163c9eafb132db /target/ppc/dfp_helper.c
parent85164ad4ed9960cac842fa4cc067c6b6699b0994 (diff)
target/ppc: introduce get_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 get_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-2-mark.cave-ayland@ilande.co.uk> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Diffstat (limited to 'target/ppc/dfp_helper.c')
-rw-r--r--target/ppc/dfp_helper.c52
1 files changed, 39 insertions, 13 deletions
diff --git a/target/ppc/dfp_helper.c b/target/ppc/dfp_helper.c
index 753399177c..e4369ebe9b 100644
--- a/target/ppc/dfp_helper.c
+++ b/target/ppc/dfp_helper.c
@@ -36,6 +36,17 @@
#define LO_IDX 0
#endif
+static void get_dfp64(uint64_t *dst, uint64_t *dfp)
+{
+ dst[0] = dfp[0];
+}
+
+static void get_dfp128(uint64_t *dst, uint64_t *dfp)
+{
+ dst[0] = dfp[HI_IDX];
+ dst[1] = dfp[LO_IDX];
+}
+
struct PPC_DFP {
CPUPPCState *env;
uint64_t t64[2], a64[2], b64[2];
@@ -129,7 +140,7 @@ static void dfp_prepare_decimal64(struct PPC_DFP *dfp, uint64_t *a,
dfp->env = env;
if (a) {
- dfp->a64[0] = *a;
+ get_dfp64(dfp->a64, a);
decimal64ToNumber((decimal64 *)dfp->a64, &dfp->a);
} else {
dfp->a64[0] = 0;
@@ -137,7 +148,7 @@ static void dfp_prepare_decimal64(struct PPC_DFP *dfp, uint64_t *a,
}
if (b) {
- dfp->b64[0] = *b;
+ get_dfp64(dfp->b64, b);
decimal64ToNumber((decimal64 *)dfp->b64, &dfp->b);
} else {
dfp->b64[0] = 0;
@@ -153,8 +164,7 @@ static void dfp_prepare_decimal128(struct PPC_DFP *dfp, uint64_t *a,
dfp->env = env;
if (a) {
- dfp->a64[0] = a[HI_IDX];
- dfp->a64[1] = a[LO_IDX];
+ get_dfp128(dfp->a64, a);
decimal128ToNumber((decimal128 *)dfp->a64, &dfp->a);
} else {
dfp->a64[0] = dfp->a64[1] = 0;
@@ -162,8 +172,7 @@ static void dfp_prepare_decimal128(struct PPC_DFP *dfp, uint64_t *a,
}
if (b) {
- dfp->b64[0] = b[HI_IDX];
- dfp->b64[1] = b[LO_IDX];
+ get_dfp128(dfp->b64, b);
decimal128ToNumber((decimal128 *)dfp->b64, &dfp->b);
} else {
dfp->b64[0] = dfp->b64[1] = 0;
@@ -617,10 +626,12 @@ uint32_t helper_##op(CPUPPCState *env, uint64_t *a, uint64_t *b) \
{ \
struct PPC_DFP dfp; \
unsigned k; \
+ uint64_t a64; \
\
dfp_prepare_decimal##size(&dfp, 0, b, env); \
\
- k = *a & 0x3F; \
+ get_dfp64(&a64, a); \
+ k = a64 & 0x3F; \
\
if (unlikely(decNumberIsSpecial(&dfp.b))) { \
dfp.crbf = 1; \
@@ -817,11 +828,15 @@ void helper_##op(CPUPPCState *env, uint64_t *t, uint64_t *a, \
uint64_t *b, uint32_t rmc) \
{ \
struct PPC_DFP dfp; \
- int32_t ref_sig = *a & 0x3F; \
+ uint64_t a64; \
+ 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; \
+ \
_dfp_reround(rmc, ref_sig, xmax, &dfp); \
decimal##size##FromNumber((decimal##size *)dfp.t64, &dfp.t, \
&dfp.context); \
@@ -881,7 +896,12 @@ DFP_HELPER_RINT(drintnq, RINTN_PPs, 128)
void helper_dctdp(CPUPPCState *env, uint64_t *t, uint64_t *b)
{
struct PPC_DFP dfp;
- uint32_t b_short = *b;
+ uint64_t b64;
+ uint32_t b_short;
+
+ get_dfp64(&b64, b);
+ b_short = (uint32_t)b64;
+
dfp_prepare_decimal64(&dfp, 0, 0, env);
decimal32ToNumber((decimal32 *)&b_short, &dfp.t);
decimal64FromNumber((decimal64 *)t, &dfp.t, &dfp.context);
@@ -891,8 +911,10 @@ void helper_dctdp(CPUPPCState *env, uint64_t *t, uint64_t *b)
void helper_dctqpq(CPUPPCState *env, uint64_t *t, uint64_t *b)
{
struct PPC_DFP dfp;
+ uint64_t b64;
dfp_prepare_decimal128(&dfp, 0, 0, env);
- decimal64ToNumber((decimal64 *)b, &dfp.t);
+ get_dfp64(&b64, b);
+ decimal64ToNumber((decimal64 *)&b64, &dfp.t);
dfp_check_for_VXSNAN_and_convert_to_QNaN(&dfp);
dfp_set_FPRF_from_FRT(&dfp);
@@ -940,8 +962,10 @@ void helper_drdpq(CPUPPCState *env, uint64_t *t, uint64_t *b)
void helper_##op(CPUPPCState *env, uint64_t *t, uint64_t *b) \
{ \
struct PPC_DFP dfp; \
+ uint64_t b64; \
dfp_prepare_decimal##size(&dfp, 0, b, env); \
- decNumberFromInt64(&dfp.t, (int64_t)(*b)); \
+ get_dfp64(&b64, b); \
+ decNumberFromInt64(&dfp.t, (int64_t)b64); \
decimal##size##FromNumber((decimal##size *)dfp.t64, &dfp.t, &dfp.context); \
CFFIX_PPs(&dfp); \
\
@@ -1183,10 +1207,12 @@ static void dfp_set_raw_exp_128(uint64_t *t, uint64_t raw)
void helper_##op(CPUPPCState *env, uint64_t *t, uint64_t *a, uint64_t *b) \
{ \
struct PPC_DFP dfp; \
- uint64_t raw_qnan, raw_snan, raw_inf, max_exp; \
+ uint64_t raw_qnan, raw_snan, raw_inf, max_exp, a64; \
int bias; \
- int64_t exp = *((int64_t *)a); \
+ int64_t exp; \
\
+ get_dfp64(&a64, a); \
+ exp = (int64_t)a64; \
dfp_prepare_decimal##size(&dfp, 0, b, env); \
\
if ((size) == 64) { \