From 1579a72ec5957297786ba5928e60571f4ab2f844 Mon Sep 17 00:00:00 2001 From: ths Date: Thu, 5 Apr 2007 23:16:25 +0000 Subject: 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 --- target-mips/op.c | 68 +++++++++++++++------ target-mips/translate.c | 155 +++++++++++++++++++++++++----------------------- 2 files changed, 131 insertions(+), 92 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(); } diff --git a/target-mips/translate.c b/target-mips/translate.c index 74bb42d204..816b91e1c5 100644 --- a/target-mips/translate.c +++ b/target-mips/translate.c @@ -1762,7 +1762,7 @@ static void gen_mfc0 (DisasContext *ctx, int reg, int sel) break; default: goto die; - } + } break; case 4: switch (sel) { @@ -1776,7 +1776,7 @@ static void gen_mfc0 (DisasContext *ctx, int reg, int sel) // break; default: goto die; - } + } break; case 5: switch (sel) { @@ -1790,7 +1790,7 @@ static void gen_mfc0 (DisasContext *ctx, int reg, int sel) break; default: goto die; - } + } break; case 6: switch (sel) { @@ -1820,7 +1820,7 @@ static void gen_mfc0 (DisasContext *ctx, int reg, int sel) // break; default: goto die; - } + } break; case 7: switch (sel) { @@ -1830,7 +1830,7 @@ static void gen_mfc0 (DisasContext *ctx, int reg, int sel) break; default: goto die; - } + } break; case 8: switch (sel) { @@ -1861,7 +1861,7 @@ static void gen_mfc0 (DisasContext *ctx, int reg, int sel) break; default: goto die; - } + } break; case 11: switch (sel) { @@ -1914,7 +1914,7 @@ static void gen_mfc0 (DisasContext *ctx, int reg, int sel) break; default: goto die; - } + } break; case 15: switch (sel) { @@ -2521,7 +2521,7 @@ static void gen_mtc0 (DisasContext *ctx, int reg, int sel) break; default: goto die; - } + } break; case 16: switch (sel) { @@ -2955,7 +2955,7 @@ static void gen_dmfc0 (DisasContext *ctx, int reg, int sel) break; default: goto die; - } + } break; case 4: switch (sel) { @@ -4703,83 +4703,92 @@ static void decode_opc (CPUState *env, DisasContext *ctx) } break; case OPC_SPECIAL3: - op1 = MASK_SPECIAL3(ctx->opcode); - switch (op1) { - case OPC_EXT: - case OPC_INS: - gen_bitops(ctx, op1, rt, rs, sa, rd); + op1 = MASK_SPECIAL3(ctx->opcode); + switch (op1) { + case OPC_EXT: + case OPC_INS: + 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; - case OPC_BSHFL: - op2 = MASK_BSHFL(ctx->opcode); - switch (op2) { - case OPC_WSBH: - GEN_LOAD_REG_TN(T1, rt); - gen_op_wsbh(); + case OPC_RDHWR: + switch (rd) { + case 0: + gen_op_rdhwr_cpunum(); break; - case OPC_SEB: - GEN_LOAD_REG_TN(T1, rt); - gen_op_seb(); + case 1: + gen_op_rdhwr_synci_step(); break; - case OPC_SEH: - GEN_LOAD_REG_TN(T1, rt); - gen_op_seh(); + case 2: + gen_op_rdhwr_cc(); break; - default: /* Invalid */ - MIPS_INVAL("bshfl"); - generate_exception(ctx, EXCP_RI); + case 3: + gen_op_rdhwr_ccres(); break; - } - 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; + case 29: #if defined (CONFIG_USER_ONLY) - case 29: - gen_op_tls_value (); - GEN_STORE_TN_REG(rt, T0); - break; + gen_op_tls_value (); +#else + generate_exception(ctx, EXCP_RI); #endif - default: /* Invalid */ - MIPS_INVAL("rdhwr"); - generate_exception(ctx, EXCP_RI); - break; - } - GEN_STORE_TN_REG(rt, T0); - break; + break; + case 30: + /* Implementation dependent */; + gen_op_rdhwr_unimpl30(); + break; + case 31: + /* 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 - case OPC_DEXTM ... OPC_DEXT: - case OPC_DINSM ... OPC_DINS: - gen_bitops(ctx, op1, rt, rs, sa, rd); + case OPC_DEXTM ... OPC_DEXT: + case OPC_DINSM ... OPC_DINS: + gen_bitops(ctx, op1, rt, rs, sa, rd); break; - case OPC_DBSHFL: - op2 = MASK_DBSHFL(ctx->opcode); - switch (op2) { - case OPC_DSBH: - GEN_LOAD_REG_TN(T1, rt); - gen_op_dsbh(); - break; - case OPC_DSHD: - GEN_LOAD_REG_TN(T1, rt); - gen_op_dshd(); - break; + case OPC_DBSHFL: + op2 = MASK_DBSHFL(ctx->opcode); + switch (op2) { + case OPC_DSBH: + GEN_LOAD_REG_TN(T1, rt); + gen_op_dsbh(); + break; + case OPC_DSHD: + GEN_LOAD_REG_TN(T1, rt); + gen_op_dshd(); + break; default: /* Invalid */ MIPS_INVAL("dbshfl"); generate_exception(ctx, EXCP_RI); break; - } - GEN_STORE_TN_REG(rd, T0); + } + GEN_STORE_TN_REG(rd, T0); #endif default: /* Invalid */ MIPS_INVAL("special3"); -- cgit v1.2.3