Skip to content

Commit

Permalink
target/ppc: introduce get_dfp{64,128}() helper functions
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
mcayland authored and dgibson committed Oct 4, 2019
1 parent 85164ad commit 6a8fbb9
Showing 1 changed file with 39 additions and 13 deletions.
52 changes: 39 additions & 13 deletions target/ppc/dfp_helper.c
Expand Up @@ -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];
Expand Down Expand Up @@ -129,15 +140,15 @@ 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;
decNumberZero(&dfp->a);
}

if (b) {
dfp->b64[0] = *b;
get_dfp64(dfp->b64, b);
decimal64ToNumber((decimal64 *)dfp->b64, &dfp->b);
} else {
dfp->b64[0] = 0;
Expand All @@ -153,17 +164,15 @@ 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;
decNumberZero(&dfp->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;
Expand Down Expand Up @@ -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; \
Expand Down Expand Up @@ -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); \
Expand Down Expand Up @@ -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);
Expand All @@ -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);
Expand Down Expand Up @@ -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); \
\
Expand Down Expand Up @@ -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) { \
Expand Down

0 comments on commit 6a8fbb9

Please sign in to comment.