提交 1579a72e 编写于 作者: T ths

Fix RDHWR handling. Code formatting. Don't use *_direct versions to raise

exceptions.


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2611 c046a42c-6fe2-441c-8c8c-71466251a162
上级 f7cfb2a1
...@@ -336,7 +336,7 @@ void op_addo (void) ...@@ -336,7 +336,7 @@ void op_addo (void)
T0 = (int32_t)T0 + (int32_t)T1; T0 = (int32_t)T0 + (int32_t)T1;
if (((tmp ^ T1 ^ (-1)) & (T0 ^ T1)) >> 31) { if (((tmp ^ T1 ^ (-1)) & (T0 ^ T1)) >> 31) {
/* operands of same sign, result different sign */ /* 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; T0 = (int32_t)T0;
RETURN(); RETURN();
...@@ -356,7 +356,7 @@ void op_subo (void) ...@@ -356,7 +356,7 @@ void op_subo (void)
T0 = (int32_t)T0 - (int32_t)T1; T0 = (int32_t)T0 - (int32_t)T1;
if (((tmp ^ T1) & (tmp ^ T0)) >> 31) { if (((tmp ^ T1) & (tmp ^ T0)) >> 31) {
/* operands of different sign, first operand and result different sign */ /* 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; T0 = (int32_t)T0;
RETURN(); RETURN();
...@@ -402,7 +402,7 @@ void op_daddo (void) ...@@ -402,7 +402,7 @@ void op_daddo (void)
T0 += T1; T0 += T1;
if (((tmp ^ T1 ^ (-1)) & (T0 ^ T1)) >> 63) { if (((tmp ^ T1 ^ (-1)) & (T0 ^ T1)) >> 63) {
/* operands of same sign, result different sign */ /* 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(); RETURN();
} }
...@@ -421,7 +421,7 @@ void op_dsubo (void) ...@@ -421,7 +421,7 @@ void op_dsubo (void)
T0 = (int64_t)T0 - (int64_t)T1; T0 = (int64_t)T0 - (int64_t)T1;
if (((tmp ^ T1) & (tmp ^ T0)) >> 63) { if (((tmp ^ T1) & (tmp ^ T0)) >> 63) {
/* operands of different sign, first operand and result different sign */ /* 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(); RETURN();
} }
...@@ -1650,7 +1650,7 @@ void op_cp0_enabled(void) ...@@ -1650,7 +1650,7 @@ void op_cp0_enabled(void)
{ {
if (!(env->CP0_Status & (1 << CP0St_CU0)) && if (!(env->CP0_Status & (1 << CP0St_CU0)) &&
(env->hflags & MIPS_HFLAG_UM)) { (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(); RETURN();
} }
...@@ -1658,7 +1658,7 @@ void op_cp0_enabled(void) ...@@ -1658,7 +1658,7 @@ void op_cp0_enabled(void)
void op_cp1_enabled(void) void op_cp1_enabled(void)
{ {
if (!(env->CP0_Status & (1 << CP0St_CU1))) { 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(); RETURN();
} }
...@@ -2063,7 +2063,7 @@ void op_ei (void) ...@@ -2063,7 +2063,7 @@ void op_ei (void)
void op_trap (void) void op_trap (void)
{ {
if (T0) { if (T0) {
CALL_FROM_TB1(do_raise_exception_direct, EXCP_TRAP); CALL_FROM_TB1(do_raise_exception, EXCP_TRAP);
} }
RETURN(); RETURN();
} }
...@@ -2116,37 +2116,67 @@ void op_deret (void) ...@@ -2116,37 +2116,67 @@ void op_deret (void)
void op_rdhwr_cpunum(void) void op_rdhwr_cpunum(void)
{ {
if (env->CP0_HWREna & (1 << 0)) if (!(env->hflags & MIPS_HFLAG_UM) ||
T0 = env->CP0_EBase & 0x2ff; (env->CP0_HWREna & (1 << 0)) ||
(env->CP0_Status & (1 << CP0St_CU0)))
T0 = env->CP0_EBase & 0x3ff;
else else
CALL_FROM_TB1(do_raise_exception_direct, EXCP_RI); CALL_FROM_TB1(do_raise_exception, EXCP_RI);
RETURN(); RETURN();
} }
void op_rdhwr_synci_step(void) void op_rdhwr_synci_step(void)
{ {
if (env->CP0_HWREna & (1 << 1)) if (!(env->hflags & MIPS_HFLAG_UM) ||
T0 = env->SYNCI_Step; (env->CP0_HWREna & (1 << 1)) ||
(env->CP0_Status & (1 << CP0St_CU0)))
T0 = env->SYNCI_Step;
else else
CALL_FROM_TB1(do_raise_exception_direct, EXCP_RI); CALL_FROM_TB1(do_raise_exception, EXCP_RI);
RETURN(); RETURN();
} }
void op_rdhwr_cc(void) void op_rdhwr_cc(void)
{ {
if (env->CP0_HWREna & (1 << 2)) if (!(env->hflags & MIPS_HFLAG_UM) ||
T0 = env->CP0_Count; (env->CP0_HWREna & (1 << 2)) ||
(env->CP0_Status & (1 << CP0St_CU0)))
T0 = env->CP0_Count;
else else
CALL_FROM_TB1(do_raise_exception_direct, EXCP_RI); CALL_FROM_TB1(do_raise_exception, EXCP_RI);
RETURN(); RETURN();
} }
void op_rdhwr_ccres(void) void op_rdhwr_ccres(void)
{ {
if (env->CP0_HWREna & (1 << 3)) if (!(env->hflags & MIPS_HFLAG_UM) ||
T0 = env->CCRes; (env->CP0_HWREna & (1 << 3)) ||
(env->CP0_Status & (1 << CP0St_CU0)))
T0 = env->CCRes;
else 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(); RETURN();
} }
......
...@@ -1762,7 +1762,7 @@ static void gen_mfc0 (DisasContext *ctx, int reg, int sel) ...@@ -1762,7 +1762,7 @@ static void gen_mfc0 (DisasContext *ctx, int reg, int sel)
break; break;
default: default:
goto die; goto die;
} }
break; break;
case 4: case 4:
switch (sel) { switch (sel) {
...@@ -1776,7 +1776,7 @@ static void gen_mfc0 (DisasContext *ctx, int reg, int sel) ...@@ -1776,7 +1776,7 @@ static void gen_mfc0 (DisasContext *ctx, int reg, int sel)
// break; // break;
default: default:
goto die; goto die;
} }
break; break;
case 5: case 5:
switch (sel) { switch (sel) {
...@@ -1790,7 +1790,7 @@ static void gen_mfc0 (DisasContext *ctx, int reg, int sel) ...@@ -1790,7 +1790,7 @@ static void gen_mfc0 (DisasContext *ctx, int reg, int sel)
break; break;
default: default:
goto die; goto die;
} }
break; break;
case 6: case 6:
switch (sel) { switch (sel) {
...@@ -1820,7 +1820,7 @@ static void gen_mfc0 (DisasContext *ctx, int reg, int sel) ...@@ -1820,7 +1820,7 @@ static void gen_mfc0 (DisasContext *ctx, int reg, int sel)
// break; // break;
default: default:
goto die; goto die;
} }
break; break;
case 7: case 7:
switch (sel) { switch (sel) {
...@@ -1830,7 +1830,7 @@ static void gen_mfc0 (DisasContext *ctx, int reg, int sel) ...@@ -1830,7 +1830,7 @@ static void gen_mfc0 (DisasContext *ctx, int reg, int sel)
break; break;
default: default:
goto die; goto die;
} }
break; break;
case 8: case 8:
switch (sel) { switch (sel) {
...@@ -1861,7 +1861,7 @@ static void gen_mfc0 (DisasContext *ctx, int reg, int sel) ...@@ -1861,7 +1861,7 @@ static void gen_mfc0 (DisasContext *ctx, int reg, int sel)
break; break;
default: default:
goto die; goto die;
} }
break; break;
case 11: case 11:
switch (sel) { switch (sel) {
...@@ -1914,7 +1914,7 @@ static void gen_mfc0 (DisasContext *ctx, int reg, int sel) ...@@ -1914,7 +1914,7 @@ static void gen_mfc0 (DisasContext *ctx, int reg, int sel)
break; break;
default: default:
goto die; goto die;
} }
break; break;
case 15: case 15:
switch (sel) { switch (sel) {
...@@ -2521,7 +2521,7 @@ static void gen_mtc0 (DisasContext *ctx, int reg, int sel) ...@@ -2521,7 +2521,7 @@ static void gen_mtc0 (DisasContext *ctx, int reg, int sel)
break; break;
default: default:
goto die; goto die;
} }
break; break;
case 16: case 16:
switch (sel) { switch (sel) {
...@@ -2955,7 +2955,7 @@ static void gen_dmfc0 (DisasContext *ctx, int reg, int sel) ...@@ -2955,7 +2955,7 @@ static void gen_dmfc0 (DisasContext *ctx, int reg, int sel)
break; break;
default: default:
goto die; goto die;
} }
break; break;
case 4: case 4:
switch (sel) { switch (sel) {
...@@ -4703,83 +4703,92 @@ static void decode_opc (CPUState *env, DisasContext *ctx) ...@@ -4703,83 +4703,92 @@ static void decode_opc (CPUState *env, DisasContext *ctx)
} }
break; break;
case OPC_SPECIAL3: case OPC_SPECIAL3:
op1 = MASK_SPECIAL3(ctx->opcode); op1 = MASK_SPECIAL3(ctx->opcode);
switch (op1) { switch (op1) {
case OPC_EXT: case OPC_EXT:
case OPC_INS: case OPC_INS:
gen_bitops(ctx, op1, rt, rs, sa, rd); gen_bitops(ctx, op1, rt, rs, sa, rd);
break;
case OPC_BSHFL:
op2 = MASK_BSHFL(ctx->opcode);
switch (op2) {
case OPC_WSBH:
GEN_LOAD_REG_TN(T1, rt);
gen_op_wsbh();
break;
case OPC_SEB:
GEN_LOAD_REG_TN(T1, rt);
gen_op_seb();
break;
case OPC_SEH:
GEN_LOAD_REG_TN(T1, rt);
gen_op_seh();
break;
default: /* Invalid */
MIPS_INVAL("bshfl");
generate_exception(ctx, EXCP_RI);
break;
}
GEN_STORE_TN_REG(rd, T0);
break; break;
case OPC_BSHFL: case OPC_RDHWR:
op2 = MASK_BSHFL(ctx->opcode); switch (rd) {
switch (op2) { case 0:
case OPC_WSBH: gen_op_rdhwr_cpunum();
GEN_LOAD_REG_TN(T1, rt);
gen_op_wsbh();
break; break;
case OPC_SEB: case 1:
GEN_LOAD_REG_TN(T1, rt); gen_op_rdhwr_synci_step();
gen_op_seb();
break; break;
case OPC_SEH: case 2:
GEN_LOAD_REG_TN(T1, rt); gen_op_rdhwr_cc();
gen_op_seh();
break; break;
default: /* Invalid */ case 3:
MIPS_INVAL("bshfl"); gen_op_rdhwr_ccres();
generate_exception(ctx, EXCP_RI);
break; break;
} case 29:
GEN_STORE_TN_REG(rd, T0);
break;
case OPC_RDHWR:
switch (rd) {
case 0:
gen_op_rdhwr_cpunum();
break;
case 1:
gen_op_rdhwr_synci_step();
break;
case 2:
gen_op_rdhwr_cc();
break;
case 3:
gen_op_rdhwr_ccres();
break;
#if defined (CONFIG_USER_ONLY) #if defined (CONFIG_USER_ONLY)
case 29: gen_op_tls_value ();
gen_op_tls_value (); #else
GEN_STORE_TN_REG(rt, T0); generate_exception(ctx, EXCP_RI);
break;
#endif #endif
default: /* Invalid */ break;
MIPS_INVAL("rdhwr"); case 30:
generate_exception(ctx, EXCP_RI); /* Implementation dependent */;
break; gen_op_rdhwr_unimpl30();
} break;
GEN_STORE_TN_REG(rt, T0); case 31:
break; /* Implementation dependent */;
gen_op_rdhwr_unimpl31();
break;
default: /* Invalid */
MIPS_INVAL("rdhwr");
generate_exception(ctx, EXCP_RI);
break;
}
GEN_STORE_TN_REG(rt, T0);
break;
#ifdef TARGET_MIPS64 #ifdef TARGET_MIPS64
case OPC_DEXTM ... OPC_DEXT: case OPC_DEXTM ... OPC_DEXT:
case OPC_DINSM ... OPC_DINS: case OPC_DINSM ... OPC_DINS:
gen_bitops(ctx, op1, rt, rs, sa, rd); gen_bitops(ctx, op1, rt, rs, sa, rd);
break; break;
case OPC_DBSHFL: case OPC_DBSHFL:
op2 = MASK_DBSHFL(ctx->opcode); op2 = MASK_DBSHFL(ctx->opcode);
switch (op2) { switch (op2) {
case OPC_DSBH: case OPC_DSBH:
GEN_LOAD_REG_TN(T1, rt); GEN_LOAD_REG_TN(T1, rt);
gen_op_dsbh(); gen_op_dsbh();
break; break;
case OPC_DSHD: case OPC_DSHD:
GEN_LOAD_REG_TN(T1, rt); GEN_LOAD_REG_TN(T1, rt);
gen_op_dshd(); gen_op_dshd();
break; break;
default: /* Invalid */ default: /* Invalid */
MIPS_INVAL("dbshfl"); MIPS_INVAL("dbshfl");
generate_exception(ctx, EXCP_RI); generate_exception(ctx, EXCP_RI);
break; break;
} }
GEN_STORE_TN_REG(rd, T0); GEN_STORE_TN_REG(rd, T0);
#endif #endif
default: /* Invalid */ default: /* Invalid */
MIPS_INVAL("special3"); MIPS_INVAL("special3");
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册