PPCDRC: Generate some FPSCR flags [Phil Bennett]

This commit is contained in:
R. Belmont 2009-07-02 05:48:07 +00:00
parent 35f7dd5c6d
commit f9cff0ed71
4 changed files with 213 additions and 0 deletions

View File

@ -20,6 +20,17 @@
/***************************************************************************
CONSTANTS
***************************************************************************/
#define DOUBLE_SIGN (U64(0x8000000000000000))
#define DOUBLE_EXP (U64(0x7ff0000000000000))
#define DOUBLE_FRAC (U64(0x000fffffffffffff))
#define DOUBLE_ZERO (0)
/*************************************************************************** /***************************************************************************
FUNCTION PROTOTYPES FUNCTION PROTOTYPES
***************************************************************************/ ***************************************************************************/
@ -174,6 +185,98 @@ INLINE void set_decrementer(powerpc_state *ppc, UINT32 newdec)
} }
/*-------------------------------------------------
is_nan_double - is a double value a NaN
-------------------------------------------------*/
INLINE int is_nan_double(double x)
{
UINT64 xi = *(UINT64*)&x;
return( ((xi & DOUBLE_EXP) == DOUBLE_EXP) &&
((xi & DOUBLE_FRAC) != DOUBLE_ZERO) );
}
/*-------------------------------------------------
is_qnan_double - is a double value a
quiet NaN
-------------------------------------------------*/
INLINE int is_qnan_double(double x)
{
UINT64 xi = *(UINT64*)&x;
return( ((xi & DOUBLE_EXP) == DOUBLE_EXP) &&
((xi & U64(0x0007fffffffffff)) == U64(0x000000000000000)) &&
((xi & U64(0x000800000000000)) == U64(0x000800000000000)) );
}
/*-------------------------------------------------
is_snan_double - is a double value a
signaling NaN
-------------------------------------------------*/
INLINE int is_snan_double(double x)
{
UINT64 xi = *(UINT64*)&x;
return( ((xi & DOUBLE_EXP) == DOUBLE_EXP) &&
((xi & DOUBLE_FRAC) != DOUBLE_ZERO) &&
((xi & U64(0x0008000000000000)) == DOUBLE_ZERO) );
}
/*-------------------------------------------------
is_infinity_double - is a double value
infinity
-------------------------------------------------*/
INLINE int is_infinity_double(double x)
{
UINT64 xi = *(UINT64*)&x;
return( ((xi & DOUBLE_EXP) == DOUBLE_EXP) &&
((xi & DOUBLE_FRAC) == DOUBLE_ZERO) );
}
/*-------------------------------------------------
is_normalized_double - is a double value
normalized
-------------------------------------------------*/
INLINE int is_normalized_double(double x)
{
UINT64 exp;
UINT64 xi = *(UINT64*)&x;
exp = (xi & DOUBLE_EXP) >> 52;
return (exp >= 1) && (exp <= 2046);
}
/*-------------------------------------------------
is_denormalized_double - is a double value
denormalized
-------------------------------------------------*/
INLINE int is_denormalized_double(double x)
{
UINT64 xi = *(UINT64*)&x;
return( ((xi & DOUBLE_EXP) == 0) &&
((xi & DOUBLE_FRAC) != DOUBLE_ZERO) );
}
/*-------------------------------------------------
sign_double - return sign of a double value
-------------------------------------------------*/
INLINE int sign_double(double x)
{
UINT64 xi = *(UINT64*)&x;
return ((xi & DOUBLE_SIGN) != 0);
}
/*************************************************************************** /***************************************************************************
INITIALIZATION AND SHUTDOWN INITIALIZATION AND SHUTDOWN
@ -996,6 +1099,59 @@ void ppccom_execute_mtdcr(powerpc_state *ppc)
/***************************************************************************
FLOATING POINT STATUS FLAGS HANDLING
***************************************************************************/
/*-------------------------------------------------
ppccom_update_fprf - update the FPRF field
of the FPSCR register
-------------------------------------------------*/
void ppccom_update_fprf(powerpc_state *ppc)
{
UINT32 fprf;
double f = ppc->f[ppc->param0];
if (is_qnan_double(f))
{
fprf = 0x11;
}
else if (is_infinity_double(f))
{
if (sign_double(f)) /* -Infinity */
fprf = 0x09;
else /* +Infinity */
fprf = 0x05;
}
else if (is_normalized_double(f))
{
if (sign_double(f)) /* -Normalized */
fprf = 0x08;
else /* +Normalized */
fprf = 0x04;
}
else if (is_denormalized_double(f))
{
if (sign_double(f)) /* -Denormalized */
fprf = 0x18;
else /* +Denormalized */
fprf = 0x14;
}
else
{
if (sign_double(f)) /* -Zero */
fprf = 0x12;
else /* +Zero */
fprf = 0x02;
}
ppc->fpscr &= ~0x0001f000;
ppc->fpscr |= fprf << 12;
}
/*************************************************************************** /***************************************************************************
COMMON GET/SET INFO COMMON GET/SET INFO
***************************************************************************/ ***************************************************************************/

View File

@ -596,6 +596,8 @@ void ppccom_execute_mtspr(powerpc_state *ppc);
void ppccom_execute_mfdcr(powerpc_state *ppc); void ppccom_execute_mfdcr(powerpc_state *ppc);
void ppccom_execute_mtdcr(powerpc_state *ppc); void ppccom_execute_mtdcr(powerpc_state *ppc);
void ppccom_update_fprf(powerpc_state *ppc);
void ppc4xx_set_info(powerpc_state *ppc, UINT32 state, cpuinfo *info); void ppc4xx_set_info(powerpc_state *ppc, UINT32 state, cpuinfo *info);
void ppc4xx_get_info(powerpc_state *ppc, UINT32 state, cpuinfo *info); void ppc4xx_get_info(powerpc_state *ppc, UINT32 state, cpuinfo *info);

View File

@ -2334,6 +2334,20 @@ static void generate_compute_flags(powerpc_state *ppc, drcuml_block *block, cons
UML_OR(block, CR32(0), IREG(1), XERSO32); // or [cr0],i1,[xerso] UML_OR(block, CR32(0), IREG(1), XERSO32); // or [cr0],i1,[xerso]
} }
/*-------------------------------------------------
generate_fp_flags - compute FPSCR floating
point status flags
-------------------------------------------------*/
static void generate_fp_flags(powerpc_state *ppc, drcuml_block *block, const opcode_desc *desc, int updatefprf)
{
/* for now, only handle the FPRF field */
if (updatefprf)
{
UML_MOV(block, MEM(&ppc->param0), IMM(G_RD(desc->opptr.l[0])));
UML_CALLC(block, ppccom_update_fprf, ppc);
}
}
/*------------------------------------------------- /*-------------------------------------------------
generate_branch - generate an unconditional generate_branch - generate an unconditional
@ -3795,6 +3809,7 @@ static int generate_instruction_3b(powerpc_state *ppc, drcuml_block *block, comp
return generate_instruction_3f(ppc, block, compiler, desc); return generate_instruction_3f(ppc, block, compiler, desc);
UML_FDADD(block, FREG(0), F64(G_RA(op)), F64(G_RB(op))); // fdadd f0,ra,rb UML_FDADD(block, FREG(0), F64(G_RA(op)), F64(G_RB(op))); // fdadd f0,ra,rb
UML_FDRNDS(block, F64(G_RD(op)), FREG(0)); // fdrnds rd,f0 UML_FDRNDS(block, F64(G_RD(op)), FREG(0)); // fdrnds rd,f0
generate_fp_flags(ppc, block, desc, TRUE);
return TRUE; return TRUE;
case 0x14: /* FSUBSx */ case 0x14: /* FSUBSx */
@ -3802,6 +3817,7 @@ static int generate_instruction_3b(powerpc_state *ppc, drcuml_block *block, comp
return generate_instruction_3f(ppc, block, compiler, desc); return generate_instruction_3f(ppc, block, compiler, desc);
UML_FDSUB(block, FREG(0), F64(G_RA(op)), F64(G_RB(op))); // fdsub f0,ra,rb UML_FDSUB(block, FREG(0), F64(G_RA(op)), F64(G_RB(op))); // fdsub f0,ra,rb
UML_FDRNDS(block, F64(G_RD(op)), FREG(0)); // fdrnds rd,f0 UML_FDRNDS(block, F64(G_RD(op)), FREG(0)); // fdrnds rd,f0
generate_fp_flags(ppc, block, desc, TRUE);
return TRUE; return TRUE;
case 0x19: /* FMULSx */ case 0x19: /* FMULSx */
@ -3809,6 +3825,7 @@ static int generate_instruction_3b(powerpc_state *ppc, drcuml_block *block, comp
return generate_instruction_3f(ppc, block, compiler, desc); return generate_instruction_3f(ppc, block, compiler, desc);
UML_FDMUL(block, FREG(0), F64(G_RA(op)), F64(G_REGC(op))); // fdmul f0,ra,rc UML_FDMUL(block, FREG(0), F64(G_RA(op)), F64(G_REGC(op))); // fdmul f0,ra,rc
UML_FDRNDS(block, F64(G_RD(op)), FREG(0)); // fdrnds rd,f0 UML_FDRNDS(block, F64(G_RD(op)), FREG(0)); // fdrnds rd,f0
generate_fp_flags(ppc, block, desc, TRUE);
return TRUE; return TRUE;
case 0x12: /* FDIVSx */ case 0x12: /* FDIVSx */
@ -3816,6 +3833,7 @@ static int generate_instruction_3b(powerpc_state *ppc, drcuml_block *block, comp
return generate_instruction_3f(ppc, block, compiler, desc); return generate_instruction_3f(ppc, block, compiler, desc);
UML_FDDIV(block, FREG(0), F64(G_RA(op)), F64(G_RB(op))); // fddiv f0,ra,rb UML_FDDIV(block, FREG(0), F64(G_RA(op)), F64(G_RB(op))); // fddiv f0,ra,rb
UML_FDRNDS(block, F64(G_RD(op)), FREG(0)); // fdrnds rd,f0 UML_FDRNDS(block, F64(G_RD(op)), FREG(0)); // fdrnds rd,f0
generate_fp_flags(ppc, block, desc, TRUE);
return TRUE; return TRUE;
case 0x16: /* FSQRTSx */ case 0x16: /* FSQRTSx */
@ -3823,12 +3841,14 @@ static int generate_instruction_3b(powerpc_state *ppc, drcuml_block *block, comp
return generate_instruction_3f(ppc, block, compiler, desc); return generate_instruction_3f(ppc, block, compiler, desc);
UML_FDSQRT(block, FREG(0), F64(G_RB(op))); // fdsqrt f0,rb UML_FDSQRT(block, FREG(0), F64(G_RB(op))); // fdsqrt f0,rb
UML_FDRNDS(block, F64(G_RD(op)), FREG(0)); // fdrnds rd,f0 UML_FDRNDS(block, F64(G_RD(op)), FREG(0)); // fdrnds rd,f0
generate_fp_flags(ppc, block, desc, TRUE);
return TRUE; return TRUE;
case 0x18: /* FRESx */ case 0x18: /* FRESx */
UML_FSFRFLT(block, FREG(0), F64(G_RB(op)), QWORD); // fsfrlt f0,rb,qword UML_FSFRFLT(block, FREG(0), F64(G_RB(op)), QWORD); // fsfrlt f0,rb,qword
UML_FSRECIP(block, FREG(0), FREG(0)); // fsrecip f0,f0 UML_FSRECIP(block, FREG(0), FREG(0)); // fsrecip f0,f0
UML_FDFRFLT(block, F64(G_RD(op)), FREG(0), DWORD); // fdfrflt rd,f0,dword UML_FDFRFLT(block, F64(G_RD(op)), FREG(0), DWORD); // fdfrflt rd,f0,dword
generate_fp_flags(ppc, block, desc, TRUE);
return TRUE; return TRUE;
case 0x1d: /* FMADDSx */ case 0x1d: /* FMADDSx */
@ -3837,6 +3857,7 @@ static int generate_instruction_3b(powerpc_state *ppc, drcuml_block *block, comp
UML_FDMUL(block, FREG(0), F64(G_RA(op)), F64(G_REGC(op))); // fdmul f0,ra,rc UML_FDMUL(block, FREG(0), F64(G_RA(op)), F64(G_REGC(op))); // fdmul f0,ra,rc
UML_FDADD(block, FREG(0), FREG(0), F64(G_RB(op))); // fdadd f0,f0,rb UML_FDADD(block, FREG(0), FREG(0), F64(G_RB(op))); // fdadd f0,f0,rb
UML_FDRNDS(block, F64(G_RD(op)), FREG(0)); // fdrnds rd,f0 UML_FDRNDS(block, F64(G_RD(op)), FREG(0)); // fdrnds rd,f0
generate_fp_flags(ppc, block, desc, TRUE);
return TRUE; return TRUE;
case 0x1c: /* FMSUBSx */ case 0x1c: /* FMSUBSx */
@ -3845,6 +3866,7 @@ static int generate_instruction_3b(powerpc_state *ppc, drcuml_block *block, comp
UML_FDMUL(block, FREG(0), F64(G_RA(op)), F64(G_REGC(op))); // fdmul f0,ra,rc UML_FDMUL(block, FREG(0), F64(G_RA(op)), F64(G_REGC(op))); // fdmul f0,ra,rc
UML_FDSUB(block, FREG(0), FREG(0), F64(G_RB(op))); // fdsub f0,f0,rb UML_FDSUB(block, FREG(0), FREG(0), F64(G_RB(op))); // fdsub f0,f0,rb
UML_FDRNDS(block, F64(G_RD(op)), FREG(0)); // fdrnds rd,f0 UML_FDRNDS(block, F64(G_RD(op)), FREG(0)); // fdrnds rd,f0
generate_fp_flags(ppc, block, desc, TRUE);
return TRUE; return TRUE;
case 0x1f: /* FNMADDSx */ case 0x1f: /* FNMADDSx */
@ -3854,6 +3876,7 @@ static int generate_instruction_3b(powerpc_state *ppc, drcuml_block *block, comp
UML_FDADD(block, FREG(0), FREG(0), F64(G_RB(op))); // fdadd f0,f0,rb UML_FDADD(block, FREG(0), FREG(0), F64(G_RB(op))); // fdadd f0,f0,rb
UML_FDNEG(block, FREG(0), FREG(0)); // fdneg f0,f0 UML_FDNEG(block, FREG(0), FREG(0)); // fdneg f0,f0
UML_FDRNDS(block, F64(G_RD(op)), FREG(0)); // fdrnds rd,f0 UML_FDRNDS(block, F64(G_RD(op)), FREG(0)); // fdrnds rd,f0
generate_fp_flags(ppc, block, desc, TRUE);
return TRUE; return TRUE;
case 0x1e: /* FNMSUBSx */ case 0x1e: /* FNMSUBSx */
@ -3862,6 +3885,7 @@ static int generate_instruction_3b(powerpc_state *ppc, drcuml_block *block, comp
UML_FDMUL(block, FREG(0), F64(G_RA(op)), F64(G_REGC(op))); // fdmul f0,ra,rc UML_FDMUL(block, FREG(0), F64(G_RA(op)), F64(G_REGC(op))); // fdmul f0,ra,rc
UML_FDSUB(block, FREG(0), F64(G_RB(op)), FREG(0)); // fdsub f0,rb,f0 UML_FDSUB(block, FREG(0), F64(G_RB(op)), FREG(0)); // fdsub f0,rb,f0
UML_FDRNDS(block, F64(G_RD(op)), FREG(0)); // fdrnds rd,f0 UML_FDRNDS(block, F64(G_RD(op)), FREG(0)); // fdrnds rd,f0
generate_fp_flags(ppc, block, desc, TRUE);
return TRUE; return TRUE;
} }
@ -3887,26 +3911,32 @@ static int generate_instruction_3f(powerpc_state *ppc, drcuml_block *block, comp
{ {
case 0x15: /* FADDx */ case 0x15: /* FADDx */
UML_FDADD(block, F64(G_RD(op)), F64(G_RA(op)), F64(G_RB(op))); // fdadd rd,ra,rb UML_FDADD(block, F64(G_RD(op)), F64(G_RA(op)), F64(G_RB(op))); // fdadd rd,ra,rb
generate_fp_flags(ppc, block, desc, TRUE);
return TRUE; return TRUE;
case 0x14: /* FSUBx */ case 0x14: /* FSUBx */
UML_FDSUB(block, F64(G_RD(op)), F64(G_RA(op)), F64(G_RB(op))); // fdsub rd,ra,rb UML_FDSUB(block, F64(G_RD(op)), F64(G_RA(op)), F64(G_RB(op))); // fdsub rd,ra,rb
generate_fp_flags(ppc, block, desc, TRUE);
return TRUE; return TRUE;
case 0x19: /* FMULx */ case 0x19: /* FMULx */
UML_FDMUL(block, F64(G_RD(op)), F64(G_RA(op)), F64(G_REGC(op))); // fdmul rd,ra,rc UML_FDMUL(block, F64(G_RD(op)), F64(G_RA(op)), F64(G_REGC(op))); // fdmul rd,ra,rc
generate_fp_flags(ppc, block, desc, TRUE);
return TRUE; return TRUE;
case 0x12: /* FDIVx */ case 0x12: /* FDIVx */
UML_FDDIV(block, F64(G_RD(op)), F64(G_RA(op)), F64(G_RB(op))); // fddiv rd,ra,rb UML_FDDIV(block, F64(G_RD(op)), F64(G_RA(op)), F64(G_RB(op))); // fddiv rd,ra,rb
generate_fp_flags(ppc, block, desc, TRUE);
return TRUE; return TRUE;
case 0x16: /* FSQRTx */ case 0x16: /* FSQRTx */
UML_FDSQRT(block, F64(G_RD(op)), F64(G_RB(op))); // fdsqrt rd,rb UML_FDSQRT(block, F64(G_RD(op)), F64(G_RB(op))); // fdsqrt rd,rb
generate_fp_flags(ppc, block, desc, TRUE);
return TRUE; return TRUE;
case 0x1a: /* FRSQRTEx */ case 0x1a: /* FRSQRTEx */
UML_FDRSQRT(block, F64(G_RD(op)), F64(G_RB(op))); // fdrsqrt rd,rb UML_FDRSQRT(block, F64(G_RD(op)), F64(G_RB(op))); // fdrsqrt rd,rb
generate_fp_flags(ppc, block, desc, TRUE);
return TRUE; return TRUE;
case 0x17: /* FSELx */ case 0x17: /* FSELx */
@ -3918,22 +3948,26 @@ static int generate_instruction_3f(powerpc_state *ppc, drcuml_block *block, comp
case 0x1d: /* FMADDx */ case 0x1d: /* FMADDx */
UML_FDMUL(block, FREG(0), F64(G_RA(op)), F64(G_REGC(op))); // fdmul f0,ra,rc UML_FDMUL(block, FREG(0), F64(G_RA(op)), F64(G_REGC(op))); // fdmul f0,ra,rc
UML_FDADD(block, F64(G_RD(op)), FREG(0), F64(G_RB(op))); // fdadd rd,f0,rb UML_FDADD(block, F64(G_RD(op)), FREG(0), F64(G_RB(op))); // fdadd rd,f0,rb
generate_fp_flags(ppc, block, desc, TRUE);
return TRUE; return TRUE;
case 0x1f: /* FNMADDx */ case 0x1f: /* FNMADDx */
UML_FDMUL(block, FREG(0), F64(G_RA(op)), F64(G_REGC(op))); // fdmul f0,ra,rc UML_FDMUL(block, FREG(0), F64(G_RA(op)), F64(G_REGC(op))); // fdmul f0,ra,rc
UML_FDADD(block, FREG(0), FREG(0), F64(G_RB(op))); // fdadd f0,f0,rb UML_FDADD(block, FREG(0), FREG(0), F64(G_RB(op))); // fdadd f0,f0,rb
UML_FDNEG(block, F64(G_RD(op)), FREG(0)); // fdneg rd,f0 UML_FDNEG(block, F64(G_RD(op)), FREG(0)); // fdneg rd,f0
generate_fp_flags(ppc, block, desc, TRUE);
return TRUE; return TRUE;
case 0x1c: /* FMSUBx */ case 0x1c: /* FMSUBx */
UML_FDMUL(block, FREG(0), F64(G_RA(op)), F64(G_REGC(op))); // fdmul f0,ra,rc UML_FDMUL(block, FREG(0), F64(G_RA(op)), F64(G_REGC(op))); // fdmul f0,ra,rc
UML_FDSUB(block, F64(G_RD(op)), FREG(0), F64(G_RB(op))); // fdsub rd,f0,rb UML_FDSUB(block, F64(G_RD(op)), FREG(0), F64(G_RB(op))); // fdsub rd,f0,rb
generate_fp_flags(ppc, block, desc, TRUE);
return TRUE; return TRUE;
case 0x1e: /* FNMSUBx */ case 0x1e: /* FNMSUBx */
UML_FDMUL(block, FREG(0), F64(G_RA(op)), F64(G_REGC(op))); // fdmul f0,ra,rc UML_FDMUL(block, FREG(0), F64(G_RA(op)), F64(G_REGC(op))); // fdmul f0,ra,rc
UML_FDSUB(block, F64(G_RD(op)), F64(G_RB(op)), FREG(0)); // fdsub rd,rb,f0 UML_FDSUB(block, F64(G_RD(op)), F64(G_RB(op)), FREG(0)); // fdsub rd,rb,f0
generate_fp_flags(ppc, block, desc, TRUE);
return TRUE; return TRUE;
} }
} }
@ -3956,6 +3990,7 @@ static int generate_instruction_3f(powerpc_state *ppc, drcuml_block *block, comp
case 0x00c: /* FRSPx */ case 0x00c: /* FRSPx */
UML_FDRNDS(block, F64(G_RD(op)), F64(G_RB(op))); // fdrnds rd,rb UML_FDRNDS(block, F64(G_RD(op)), F64(G_RB(op))); // fdrnds rd,rb
generate_fp_flags(ppc, block, desc, TRUE);
return TRUE; return TRUE;
case 0x00e: /* FCTIWx */ case 0x00e: /* FCTIWx */

View File

@ -1243,6 +1243,7 @@ static int describe_instruction_3b(powerpc_state *ppc, UINT32 op, opcode_desc *d
desc->cycles = 18; /* 603 */ desc->cycles = 18; /* 603 */
else else
desc->cycles = 17; /* ??? */ desc->cycles = 17; /* ??? */
FPSCR_MODIFIED(desc, 4);
return TRUE; return TRUE;
case 0x14: /* FSUBSx */ case 0x14: /* FSUBSx */
@ -1252,6 +1253,7 @@ static int describe_instruction_3b(powerpc_state *ppc, UINT32 op, opcode_desc *d
FPR_MODIFIED(desc, G_RD(op)); FPR_MODIFIED(desc, G_RD(op));
if (op & M_RC) if (op & M_RC)
CR_MODIFIED(desc, 1); CR_MODIFIED(desc, 1);
FPSCR_MODIFIED(desc, 4);
return TRUE; return TRUE;
case 0x19: /* FMULSx - not the same form as FSUB/FADD! */ case 0x19: /* FMULSx - not the same form as FSUB/FADD! */
@ -1260,6 +1262,7 @@ static int describe_instruction_3b(powerpc_state *ppc, UINT32 op, opcode_desc *d
FPR_MODIFIED(desc, G_RD(op)); FPR_MODIFIED(desc, G_RD(op));
if (op & M_RC) if (op & M_RC)
CR_MODIFIED(desc, 1); CR_MODIFIED(desc, 1);
FPSCR_MODIFIED(desc, 4);
return TRUE; return TRUE;
case 0x16: /* FSQRTSx */ case 0x16: /* FSQRTSx */
@ -1268,6 +1271,7 @@ static int describe_instruction_3b(powerpc_state *ppc, UINT32 op, opcode_desc *d
FPR_MODIFIED(desc, G_RD(op)); FPR_MODIFIED(desc, G_RD(op));
if (op & M_RC) if (op & M_RC)
CR_MODIFIED(desc, 1); CR_MODIFIED(desc, 1);
FPSCR_MODIFIED(desc, 4);
return TRUE; return TRUE;
case 0x1c: /* FMSUBSx */ case 0x1c: /* FMSUBSx */
@ -1280,6 +1284,7 @@ static int describe_instruction_3b(powerpc_state *ppc, UINT32 op, opcode_desc *d
FPR_MODIFIED(desc, G_RD(op)); FPR_MODIFIED(desc, G_RD(op));
if (op & M_RC) if (op & M_RC)
CR_MODIFIED(desc, 1); CR_MODIFIED(desc, 1);
FPSCR_MODIFIED(desc, 4);
return TRUE; return TRUE;
} }
@ -1317,6 +1322,7 @@ static int describe_instruction_3f(powerpc_state *ppc, UINT32 op, opcode_desc *d
desc->cycles = 33; /* 603 */ desc->cycles = 33; /* 603 */
else else
desc->cycles = 31; /* ??? */ desc->cycles = 31; /* ??? */
FPSCR_MODIFIED(desc, 4);
return TRUE; return TRUE;
case 0x19: /* FMULx */ case 0x19: /* FMULx */
@ -1326,6 +1332,7 @@ static int describe_instruction_3f(powerpc_state *ppc, UINT32 op, opcode_desc *d
if (op & M_RC) if (op & M_RC)
CR_MODIFIED(desc, 1); CR_MODIFIED(desc, 1);
desc->cycles = 2; /* 601/603 */ desc->cycles = 2; /* 601/603 */
FPSCR_MODIFIED(desc, 4);
return TRUE; return TRUE;
case 0x14: /* FSUBx */ case 0x14: /* FSUBx */
@ -1335,6 +1342,7 @@ static int describe_instruction_3f(powerpc_state *ppc, UINT32 op, opcode_desc *d
FPR_MODIFIED(desc, G_RD(op)); FPR_MODIFIED(desc, G_RD(op));
if (op & M_RC) if (op & M_RC)
CR_MODIFIED(desc, 1); CR_MODIFIED(desc, 1);
FPSCR_MODIFIED(desc, 4);
return TRUE; return TRUE;
case 0x16: /* FSQRTx */ case 0x16: /* FSQRTx */
@ -1343,9 +1351,19 @@ static int describe_instruction_3f(powerpc_state *ppc, UINT32 op, opcode_desc *d
FPR_MODIFIED(desc, G_RD(op)); FPR_MODIFIED(desc, G_RD(op));
if (op & M_RC) if (op & M_RC)
CR_MODIFIED(desc, 1); CR_MODIFIED(desc, 1);
FPSCR_MODIFIED(desc, 4);
return TRUE; return TRUE;
case 0x17: /* FSELx */ case 0x17: /* FSELx */
FPR_USED(desc, G_RA(op));
FPR_USED(desc, G_RB(op));
FPR_USED(desc, G_REGC(op));
FPR_MODIFIED(desc, G_RD(op));
if (op & M_RC)
CR_MODIFIED(desc, 1);
desc->cycles = 2; /* 601/603 */
return TRUE;
case 0x1c: /* FMSUBx */ case 0x1c: /* FMSUBx */
case 0x1d: /* FMADDx */ case 0x1d: /* FMADDx */
case 0x1e: /* FNMSUBx */ case 0x1e: /* FNMSUBx */
@ -1357,6 +1375,7 @@ static int describe_instruction_3f(powerpc_state *ppc, UINT32 op, opcode_desc *d
if (op & M_RC) if (op & M_RC)
CR_MODIFIED(desc, 1); CR_MODIFIED(desc, 1);
desc->cycles = 2; /* 601/603 */ desc->cycles = 2; /* 601/603 */
FPSCR_MODIFIED(desc, 4);
return TRUE; return TRUE;
} }
} }
@ -1379,6 +1398,7 @@ static int describe_instruction_3f(powerpc_state *ppc, UINT32 op, opcode_desc *d
case 0x00c: /* FRSPx */ case 0x00c: /* FRSPx */
case 0x00e: /* FCTIWx */ case 0x00e: /* FCTIWx */
case 0x00f: /* FCTIWZx */ case 0x00f: /* FCTIWZx */
FPSCR_MODIFIED(desc, 4);
case 0x028: /* FNEGx */ case 0x028: /* FNEGx */
case 0x048: /* FMRx */ case 0x048: /* FMRx */
case 0x088: /* FNABSx */ case 0x088: /* FNABSx */