mirror of https://gitee.com/openkylin/qemu.git
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>
This commit is contained in:
parent
6a8fbb9bdb
commit
33432d7737
|
@ -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); \
|
||||
} \
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue