diff options
Diffstat (limited to 'target-mips/op.c')
-rw-r--r-- | target-mips/op.c | 68 |
1 files changed, 49 insertions, 19 deletions
diff --git a/target-mips/op.c b/target-mips/op.c index db430a7ee4..d09b8da2df 100644 --- a/target-mips/op.c +++ b/target-mips/op.c @@ -336,7 +336,7 @@ void op_addo (void) T0 = (int32_t)T0 + (int32_t)T1; if (((tmp ^ T1 ^ (-1)) & (T0 ^ T1)) >> 31) { /* operands of same sign, result different sign */ - CALL_FROM_TB1(do_raise_exception_direct, EXCP_OVERFLOW); + CALL_FROM_TB1(do_raise_exception, EXCP_OVERFLOW); } T0 = (int32_t)T0; RETURN(); @@ -356,7 +356,7 @@ void op_subo (void) T0 = (int32_t)T0 - (int32_t)T1; if (((tmp ^ T1) & (tmp ^ T0)) >> 31) { /* operands of different sign, first operand and result different sign */ - CALL_FROM_TB1(do_raise_exception_direct, EXCP_OVERFLOW); + CALL_FROM_TB1(do_raise_exception, EXCP_OVERFLOW); } T0 = (int32_t)T0; RETURN(); @@ -402,7 +402,7 @@ void op_daddo (void) T0 += T1; if (((tmp ^ T1 ^ (-1)) & (T0 ^ T1)) >> 63) { /* operands of same sign, result different sign */ - CALL_FROM_TB1(do_raise_exception_direct, EXCP_OVERFLOW); + CALL_FROM_TB1(do_raise_exception, EXCP_OVERFLOW); } RETURN(); } @@ -421,7 +421,7 @@ void op_dsubo (void) T0 = (int64_t)T0 - (int64_t)T1; if (((tmp ^ T1) & (tmp ^ T0)) >> 63) { /* operands of different sign, first operand and result different sign */ - CALL_FROM_TB1(do_raise_exception_direct, EXCP_OVERFLOW); + CALL_FROM_TB1(do_raise_exception, EXCP_OVERFLOW); } RETURN(); } @@ -1650,7 +1650,7 @@ void op_cp0_enabled(void) { if (!(env->CP0_Status & (1 << CP0St_CU0)) && (env->hflags & MIPS_HFLAG_UM)) { - CALL_FROM_TB2(do_raise_exception_direct_err, EXCP_CpU, 0); + CALL_FROM_TB2(do_raise_exception_err, EXCP_CpU, 0); } RETURN(); } @@ -1658,7 +1658,7 @@ void op_cp0_enabled(void) void op_cp1_enabled(void) { if (!(env->CP0_Status & (1 << CP0St_CU1))) { - CALL_FROM_TB2(do_raise_exception_direct_err, EXCP_CpU, 1); + CALL_FROM_TB2(do_raise_exception_err, EXCP_CpU, 1); } RETURN(); } @@ -2063,7 +2063,7 @@ void op_ei (void) void op_trap (void) { if (T0) { - CALL_FROM_TB1(do_raise_exception_direct, EXCP_TRAP); + CALL_FROM_TB1(do_raise_exception, EXCP_TRAP); } RETURN(); } @@ -2116,37 +2116,67 @@ void op_deret (void) void op_rdhwr_cpunum(void) { - if (env->CP0_HWREna & (1 << 0)) - T0 = env->CP0_EBase & 0x2ff; + if (!(env->hflags & MIPS_HFLAG_UM) || + (env->CP0_HWREna & (1 << 0)) || + (env->CP0_Status & (1 << CP0St_CU0))) + T0 = env->CP0_EBase & 0x3ff; else - CALL_FROM_TB1(do_raise_exception_direct, EXCP_RI); + CALL_FROM_TB1(do_raise_exception, EXCP_RI); RETURN(); } void op_rdhwr_synci_step(void) { - if (env->CP0_HWREna & (1 << 1)) - T0 = env->SYNCI_Step; + if (!(env->hflags & MIPS_HFLAG_UM) || + (env->CP0_HWREna & (1 << 1)) || + (env->CP0_Status & (1 << CP0St_CU0))) + T0 = env->SYNCI_Step; else - CALL_FROM_TB1(do_raise_exception_direct, EXCP_RI); + CALL_FROM_TB1(do_raise_exception, EXCP_RI); RETURN(); } void op_rdhwr_cc(void) { - if (env->CP0_HWREna & (1 << 2)) - T0 = env->CP0_Count; + if (!(env->hflags & MIPS_HFLAG_UM) || + (env->CP0_HWREna & (1 << 2)) || + (env->CP0_Status & (1 << CP0St_CU0))) + T0 = env->CP0_Count; else - CALL_FROM_TB1(do_raise_exception_direct, EXCP_RI); + CALL_FROM_TB1(do_raise_exception, EXCP_RI); RETURN(); } void op_rdhwr_ccres(void) { - if (env->CP0_HWREna & (1 << 3)) - T0 = env->CCRes; + if (!(env->hflags & MIPS_HFLAG_UM) || + (env->CP0_HWREna & (1 << 3)) || + (env->CP0_Status & (1 << CP0St_CU0))) + T0 = env->CCRes; else - CALL_FROM_TB1(do_raise_exception_direct, EXCP_RI); + CALL_FROM_TB1(do_raise_exception, EXCP_RI); + RETURN(); +} + +void op_rdhwr_unimpl30(void) +{ + if (!(env->hflags & MIPS_HFLAG_UM) || + (env->CP0_HWREna & (1 << 30)) || + (env->CP0_Status & (1 << CP0St_CU0))) + T0 = 0; + else + CALL_FROM_TB1(do_raise_exception, EXCP_RI); + RETURN(); +} + +void op_rdhwr_unimpl31(void) +{ + if (!(env->hflags & MIPS_HFLAG_UM) || + (env->CP0_HWREna & (1 << 31)) || + (env->CP0_Status & (1 << CP0St_CU0))) + T0 = 0; + else + CALL_FROM_TB1(do_raise_exception, EXCP_RI); RETURN(); } |