Commit 5e755519 authored by ths's avatar ths
Browse files

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
parent acf930aa
......@@ -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; \
......
......@@ -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) {
......
This diff is collapsed.
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment