mirror of
https://github.com/izzy2lost/xemu.git
synced 2026-07-06 00:20:22 -07:00
Don't check the FPU state for each FPU instruction, use hflags to
handle this per-tb. git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2896 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
+5
-3
@@ -258,9 +258,11 @@ struct CPUMIPSState {
|
||||
#define MIPS_HFLAG_TMASK 0x007F
|
||||
#define MIPS_HFLAG_MODE 0x001F /* execution modes */
|
||||
#define MIPS_HFLAG_UM 0x0001 /* user mode */
|
||||
#define MIPS_HFLAG_DM 0x0008 /* Debug mode */
|
||||
#define MIPS_HFLAG_SM 0x0010 /* Supervisor mode */
|
||||
#define MIPS_HFLAG_64 0x0020 /* 64-bit instructions enabled */
|
||||
#define MIPS_HFLAG_DM 0x0002 /* Debug mode */
|
||||
#define MIPS_HFLAG_SM 0x0004 /* Supervisor mode */
|
||||
#define MIPS_HFLAG_64 0x0008 /* 64-bit instructions enabled */
|
||||
#define MIPS_HFLAG_FPU 0x0010 /* FPU enabled */
|
||||
#define MIPS_HFLAG_F64 0x0020 /* 64-bit FPU enabled */
|
||||
#define MIPS_HFLAG_RE 0x0040 /* Reversed endianness */
|
||||
/* If translation is interrupted between the branch instruction and
|
||||
* the delay slot, record what type of branch it is so that we can
|
||||
|
||||
@@ -49,7 +49,7 @@ OP_WSTORE_FREG(WT2, WT2_fpr, FREG)
|
||||
#define OP_DLOAD_FREG(treg, tregname, FREG) \
|
||||
void glue(glue(op_load_fpr_,tregname), FREG) (void) \
|
||||
{ \
|
||||
if (env->CP0_Status & (1 << CP0St_FR)) \
|
||||
if (env->hflags & MIPS_HFLAG_F64) \
|
||||
treg = env->fpr[FREG].fd; \
|
||||
else \
|
||||
treg = (uint64_t)(env->fpr[FREG | 1].fs[FP_ENDIAN_IDX]) << 32 | \
|
||||
@@ -60,7 +60,7 @@ OP_WSTORE_FREG(WT2, WT2_fpr, FREG)
|
||||
#define OP_DSTORE_FREG(treg, tregname, FREG) \
|
||||
void glue(glue(op_store_fpr_,tregname), FREG) (void) \
|
||||
{ \
|
||||
if (env->CP0_Status & (1 << CP0St_FR)) \
|
||||
if (env->hflags & MIPS_HFLAG_F64) \
|
||||
env->fpr[FREG].fd = treg; \
|
||||
else { \
|
||||
env->fpr[FREG | 1].fs[FP_ENDIAN_IDX] = treg >> 32; \
|
||||
|
||||
+9
-37
@@ -1349,8 +1349,7 @@ void op_mtc0_status (void)
|
||||
uint32_t val, old;
|
||||
uint32_t mask = env->Status_rw_bitmask;
|
||||
|
||||
/* No reverse endianness, no MDMX/DSP, no 64bit ops
|
||||
implemented. */
|
||||
/* No reverse endianness, no MDMX/DSP implemented. */
|
||||
val = T0 & mask;
|
||||
old = env->CP0_Status;
|
||||
if (!(val & (1 << CP0St_EXL)) &&
|
||||
@@ -1364,6 +1363,14 @@ void op_mtc0_status (void)
|
||||
!(val & (1 << CP0St_UX)))
|
||||
env->hflags &= ~MIPS_HFLAG_64;
|
||||
#endif
|
||||
if (val & (1 << CP0St_CU1))
|
||||
env->hflags |= MIPS_HFLAG_FPU;
|
||||
else
|
||||
env->hflags &= ~MIPS_HFLAG_FPU;
|
||||
if (val & (1 << CP0St_FR))
|
||||
env->hflags |= MIPS_HFLAG_F64;
|
||||
else
|
||||
env->hflags &= ~MIPS_HFLAG_F64;
|
||||
env->CP0_Status = (env->CP0_Status & ~mask) | val;
|
||||
if (loglevel & CPU_LOG_EXEC)
|
||||
CALL_FROM_TB2(do_mtc0_status_debug, old, val);
|
||||
@@ -1606,41 +1613,6 @@ void op_cp0_enabled(void)
|
||||
RETURN();
|
||||
}
|
||||
|
||||
void op_cp1_enabled(void)
|
||||
{
|
||||
if (!(env->CP0_Status & (1 << CP0St_CU1))) {
|
||||
CALL_FROM_TB2(do_raise_exception_err, EXCP_CpU, 1);
|
||||
}
|
||||
RETURN();
|
||||
}
|
||||
|
||||
void op_cp1_64bitmode(void)
|
||||
{
|
||||
if (!(env->CP0_Status & (1 << CP0St_FR))) {
|
||||
CALL_FROM_TB1(do_raise_exception, EXCP_RI);
|
||||
}
|
||||
RETURN();
|
||||
}
|
||||
|
||||
/*
|
||||
* Verify if floating point register is valid; an operation is not defined
|
||||
* if bit 0 of any register specification is set and the FR bit in the
|
||||
* Status register equals zero, since the register numbers specify an
|
||||
* even-odd pair of adjacent coprocessor general registers. When the FR bit
|
||||
* in the Status register equals one, both even and odd register numbers
|
||||
* are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
|
||||
*
|
||||
* Multiple 64 bit wide registers can be checked by calling
|
||||
* gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
|
||||
*/
|
||||
void op_cp1_registers(void)
|
||||
{
|
||||
if (!(env->CP0_Status & (1 << CP0St_FR)) && (PARAM1 & 1)) {
|
||||
CALL_FROM_TB1(do_raise_exception, EXCP_RI);
|
||||
}
|
||||
RETURN();
|
||||
}
|
||||
|
||||
void op_cfc1 (void)
|
||||
{
|
||||
switch (T1) {
|
||||
|
||||
+110
-84
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user