target-ppc: Introduce DFP Insert Biased Exponent

Add emulation of the PowerPC Decimal Floating Point Insert Biased
Exponent instructions diex[q][.].

Signed-off-by: Tom Musta <tommusta@gmail.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
This commit is contained in:
Tom Musta 2014-04-21 15:55:20 -05:00 committed by Alexander Graf
parent e8a4846031
commit 297666eba0
3 changed files with 74 additions and 0 deletions

View File

@ -1152,3 +1152,71 @@ void helper_##op(CPUPPCState *env, uint64_t *t, uint64_t *b) \
DFP_HELPER_XEX(dxex, 64)
DFP_HELPER_XEX(dxexq, 128)
static void dfp_set_raw_exp_64(uint64_t *t, uint64_t raw)
{
*t &= 0x8003ffffffffffffULL;
*t |= (raw << (63-13));
}
static void dfp_set_raw_exp_128(uint64_t *t, uint64_t raw)
{
t[HI_IDX] &= 0x80003fffffffffffULL;
t[HI_IDX] |= (raw << (63-17));
}
#define DFP_HELPER_IEX(op, size) \
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; \
int bias; \
int64_t exp = *((int64_t *)a); \
\
dfp_prepare_decimal##size(&dfp, 0, b, env); \
\
if ((size) == 64) { \
max_exp = 767; \
raw_qnan = 0x1F00; \
raw_snan = 0x1F80; \
raw_inf = 0x1E00; \
bias = 398; \
} else if ((size) == 128) { \
max_exp = 12287; \
raw_qnan = 0x1f000; \
raw_snan = 0x1f800; \
raw_inf = 0x1e000; \
bias = 6176; \
} else { \
assert(0); \
} \
\
if (unlikely((exp < 0) || (exp > max_exp))) { \
dfp.t64[0] = dfp.b64[0]; \
dfp.t64[1] = dfp.b64[1]; \
if (exp == -1) { \
dfp_set_raw_exp_##size(dfp.t64, raw_inf); \
} else if (exp == -3) { \
dfp_set_raw_exp_##size(dfp.t64, raw_snan); \
} else { \
dfp_set_raw_exp_##size(dfp.t64, raw_qnan); \
} \
} else { \
dfp.t = dfp.b; \
if (unlikely(decNumberIsSpecial(&dfp.t))) { \
dfp.t.bits &= ~DECSPECIAL; \
} \
dfp.t.exponent = exp - bias; \
decimal##size##FromNumber((decimal##size *)dfp.t64, &dfp.t, \
&dfp.context); \
} \
if (size == 64) { \
t[0] = dfp.t64[0]; \
} else if (size == 128) { \
t[0] = dfp.t64[HI_IDX]; \
t[1] = dfp.t64[LO_IDX]; \
} \
}
DFP_HELPER_IEX(diex, 64)
DFP_HELPER_IEX(diexq, 128)

View File

@ -660,3 +660,5 @@ DEF_HELPER_4(denbcd, void, env, fprp, fprp, i32)
DEF_HELPER_4(denbcdq, void, env, fprp, fprp, i32)
DEF_HELPER_3(dxex, void, env, fprp, fprp)
DEF_HELPER_3(dxexq, void, env, fprp, fprp)
DEF_HELPER_4(diex, void, env, fprp, fprp, fprp)
DEF_HELPER_4(diexq, void, env, fprp, fprp, fprp)

View File

@ -8400,6 +8400,8 @@ GEN_DFP_T_FPR_I32_Rc(denbcd, rB, SP)
GEN_DFP_T_FPR_I32_Rc(denbcdq, rB, SP)
GEN_DFP_T_B_Rc(dxex)
GEN_DFP_T_B_Rc(dxexq)
GEN_DFP_T_A_B_Rc(diex)
GEN_DFP_T_A_B_Rc(diexq)
/*** SPE extension ***/
/* Register moves */
@ -11371,6 +11373,8 @@ GEN_DFP_S_T_B_Rc(denbcd, 0x02, 0x1a),
GEN_DFP_S_Tp_Bp_Rc(denbcdq, 0x02, 0x1a),
GEN_DFP_T_B_Rc(dxex, 0x02, 0x0b),
GEN_DFP_T_Bp_Rc(dxexq, 0x02, 0x0b),
GEN_DFP_T_A_B_Rc(diex, 0x02, 0x1b),
GEN_DFP_Tp_A_Bp_Rc(diexq, 0x02, 0x1b),
#undef GEN_SPE
#define GEN_SPE(name0, name1, opc2, opc3, inval0, inval1, type) \
GEN_OPCODE_DUAL(name0##_##name1, 0x04, opc2, opc3, inval0, inval1, type, PPC_NONE)