Implement new floating-point instructions (fre, frin, friz, frip, frim)
as defined in the PowerPC 2.04 specification. git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3281 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
parent
477023a603
commit
d7e4b87e53
@ -1701,6 +1701,13 @@ void OPPROTO op_fsqrt (void)
|
|||||||
RETURN();
|
RETURN();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* fre - fre. */
|
||||||
|
void OPPROTO op_fre (void)
|
||||||
|
{
|
||||||
|
do_fre();
|
||||||
|
RETURN();
|
||||||
|
}
|
||||||
|
|
||||||
/* fres - fres. */
|
/* fres - fres. */
|
||||||
void OPPROTO op_fres (void)
|
void OPPROTO op_fres (void)
|
||||||
{
|
{
|
||||||
@ -1806,6 +1813,30 @@ void OPPROTO op_fctidz (void)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
void OPPROTO op_frin (void)
|
||||||
|
{
|
||||||
|
do_frin();
|
||||||
|
RETURN();
|
||||||
|
}
|
||||||
|
|
||||||
|
void OPPROTO op_friz (void)
|
||||||
|
{
|
||||||
|
do_friz();
|
||||||
|
RETURN();
|
||||||
|
}
|
||||||
|
|
||||||
|
void OPPROTO op_frip (void)
|
||||||
|
{
|
||||||
|
do_frip();
|
||||||
|
RETURN();
|
||||||
|
}
|
||||||
|
|
||||||
|
void OPPROTO op_frim (void)
|
||||||
|
{
|
||||||
|
do_frim();
|
||||||
|
RETURN();
|
||||||
|
}
|
||||||
|
|
||||||
/*** Floating-Point compare ***/
|
/*** Floating-Point compare ***/
|
||||||
/* fcmpu */
|
/* fcmpu */
|
||||||
void OPPROTO op_fcmpu (void)
|
void OPPROTO op_fcmpu (void)
|
||||||
|
@ -700,6 +700,36 @@ void do_fctidz (void)
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static inline void do_fri (int rounding_mode)
|
||||||
|
{
|
||||||
|
int curmode;
|
||||||
|
|
||||||
|
curmode = env->fp_status.float_rounding_mode;
|
||||||
|
set_float_rounding_mode(rounding_mode, &env->fp_status);
|
||||||
|
FT0 = float64_round_to_int(FT0, &env->fp_status);
|
||||||
|
set_float_rounding_mode(curmode, &env->fp_status);
|
||||||
|
}
|
||||||
|
|
||||||
|
void do_frin (void)
|
||||||
|
{
|
||||||
|
do_fri(float_round_nearest_even);
|
||||||
|
}
|
||||||
|
|
||||||
|
void do_friz (void)
|
||||||
|
{
|
||||||
|
do_fri(float_round_to_zero);
|
||||||
|
}
|
||||||
|
|
||||||
|
void do_frip (void)
|
||||||
|
{
|
||||||
|
do_fri(float_round_up);
|
||||||
|
}
|
||||||
|
|
||||||
|
void do_frim (void)
|
||||||
|
{
|
||||||
|
do_fri(float_round_down);
|
||||||
|
}
|
||||||
|
|
||||||
#if USE_PRECISE_EMULATION
|
#if USE_PRECISE_EMULATION
|
||||||
void do_fmadd (void)
|
void do_fmadd (void)
|
||||||
{
|
{
|
||||||
@ -789,6 +819,32 @@ void do_fsqrt (void)
|
|||||||
FT0 = float64_sqrt(FT0, &env->fp_status);
|
FT0 = float64_sqrt(FT0, &env->fp_status);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void do_fre (void)
|
||||||
|
{
|
||||||
|
union {
|
||||||
|
double d;
|
||||||
|
uint64_t i;
|
||||||
|
} p;
|
||||||
|
|
||||||
|
if (likely(isnormal(FT0))) {
|
||||||
|
FT0 = float64_div(1.0, FT0, &env->fp_status);
|
||||||
|
} else {
|
||||||
|
p.d = FT0;
|
||||||
|
if (p.i == 0x8000000000000000ULL) {
|
||||||
|
p.i = 0xFFF0000000000000ULL;
|
||||||
|
} else if (p.i == 0x0000000000000000ULL) {
|
||||||
|
p.i = 0x7FF0000000000000ULL;
|
||||||
|
} else if (isnan(FT0)) {
|
||||||
|
p.i = 0x7FF8000000000000ULL;
|
||||||
|
} else if (FT0 < 0.0) {
|
||||||
|
p.i = 0x8000000000000000ULL;
|
||||||
|
} else {
|
||||||
|
p.i = 0x0000000000000000ULL;
|
||||||
|
}
|
||||||
|
FT0 = p.d;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void do_fres (void)
|
void do_fres (void)
|
||||||
{
|
{
|
||||||
union {
|
union {
|
||||||
|
@ -94,6 +94,7 @@ void do_popcntb_64 (void);
|
|||||||
|
|
||||||
/* Floating-point arithmetic helpers */
|
/* Floating-point arithmetic helpers */
|
||||||
void do_fsqrt (void);
|
void do_fsqrt (void);
|
||||||
|
void do_fre (void);
|
||||||
void do_fres (void);
|
void do_fres (void);
|
||||||
void do_frsqrte (void);
|
void do_frsqrte (void);
|
||||||
void do_fsel (void);
|
void do_fsel (void);
|
||||||
@ -110,6 +111,10 @@ void do_fcfid (void);
|
|||||||
void do_fctid (void);
|
void do_fctid (void);
|
||||||
void do_fctidz (void);
|
void do_fctidz (void);
|
||||||
#endif
|
#endif
|
||||||
|
void do_frin (void);
|
||||||
|
void do_friz (void);
|
||||||
|
void do_frip (void);
|
||||||
|
void do_frim (void);
|
||||||
void do_fcmpu (void);
|
void do_fcmpu (void);
|
||||||
void do_fcmpo (void);
|
void do_fcmpo (void);
|
||||||
|
|
||||||
|
@ -476,6 +476,8 @@ enum {
|
|||||||
PPC_RFMCI = 0x0000020000000000ULL,
|
PPC_RFMCI = 0x0000020000000000ULL,
|
||||||
/* user-mode DCR access, implemented in PowerPC 460 */
|
/* user-mode DCR access, implemented in PowerPC 460 */
|
||||||
PPC_DCRUX = 0x0000040000000000ULL,
|
PPC_DCRUX = 0x0000040000000000ULL,
|
||||||
|
/* New floating-point extensions (PowerPC 2.0x) */
|
||||||
|
PPC_FLOAT_EXT = 0x0000080000000000ULL,
|
||||||
};
|
};
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
@ -1660,6 +1662,9 @@ GEN_FLOAT_AB(div, 0x12, 0x000007C0);
|
|||||||
/* fmul - fmuls */
|
/* fmul - fmuls */
|
||||||
GEN_FLOAT_AC(mul, 0x19, 0x0000F800);
|
GEN_FLOAT_AC(mul, 0x19, 0x0000F800);
|
||||||
|
|
||||||
|
/* fre */
|
||||||
|
GEN_FLOAT_BS(re, 0x3F, 0x18, PPC_FLOAT_EXT);
|
||||||
|
|
||||||
/* fres */
|
/* fres */
|
||||||
GEN_FLOAT_BS(res, 0x3B, 0x18, PPC_FLOAT_FRES);
|
GEN_FLOAT_BS(res, 0x3B, 0x18, PPC_FLOAT_FRES);
|
||||||
|
|
||||||
@ -1727,6 +1732,15 @@ GEN_FLOAT_B(ctid, 0x0E, 0x19, PPC_64B);
|
|||||||
GEN_FLOAT_B(ctidz, 0x0F, 0x19, PPC_64B);
|
GEN_FLOAT_B(ctidz, 0x0F, 0x19, PPC_64B);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* frin */
|
||||||
|
GEN_FLOAT_B(rin, 0x08, 0x0C, PPC_FLOAT_EXT);
|
||||||
|
/* friz */
|
||||||
|
GEN_FLOAT_B(riz, 0x08, 0x0D, PPC_FLOAT_EXT);
|
||||||
|
/* frip */
|
||||||
|
GEN_FLOAT_B(rip, 0x08, 0x0E, PPC_FLOAT_EXT);
|
||||||
|
/* frim */
|
||||||
|
GEN_FLOAT_B(rim, 0x08, 0x0F, PPC_FLOAT_EXT);
|
||||||
|
|
||||||
/*** Floating-Point compare ***/
|
/*** Floating-Point compare ***/
|
||||||
/* fcmpo */
|
/* fcmpo */
|
||||||
GEN_HANDLER(fcmpo, 0x3F, 0x00, 0x01, 0x00600001, PPC_FLOAT)
|
GEN_HANDLER(fcmpo, 0x3F, 0x00, 0x01, 0x00600001, PPC_FLOAT)
|
||||||
|
Loading…
Reference in New Issue
Block a user