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:
parent
e8a4846031
commit
297666eba0
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user