From e397ee3382a34c65b0fb93514c3eef5c31715d3c Mon Sep 17 00:00:00 2001 From: ths Date: Fri, 23 Mar 2007 00:43:28 +0000 Subject: Fix enough FPU/R2 support to get 24Kf going. git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2528 c046a42c-6fe2-441c-8c8c-71466251a162 --- target-mips/cpu.h | 2 ++ target-mips/exec.h | 1 + target-mips/op.c | 14 ++++++++++- target-mips/op_helper.c | 9 +++++-- target-mips/translate.c | 66 ++++++++++++++++++++++++++++++++----------------- 5 files changed, 66 insertions(+), 26 deletions(-) (limited to 'target-mips') diff --git a/target-mips/cpu.h b/target-mips/cpu.h index 276910aaed..f0f3ab2d73 100644 --- a/target-mips/cpu.h +++ b/target-mips/cpu.h @@ -203,6 +203,8 @@ struct CPUMIPSState { #define CP0C3_MT 2 #define CP0C3_SM 1 #define CP0C3_TL 0 + int32_t CP0_Config6; + int32_t CP0_Config7; target_ulong CP0_LLAddr; target_ulong CP0_WatchLo; int32_t CP0_WatchHi; diff --git a/target-mips/exec.h b/target-mips/exec.h index 877221e561..9816d4246a 100644 --- a/target-mips/exec.h +++ b/target-mips/exec.h @@ -152,6 +152,7 @@ void invalidate_tlb (CPUState *env, int idx, int use_extra); void cpu_loop_exit(void); void do_raise_exception_err (uint32_t exception, int error_code); void do_raise_exception (uint32_t exception); +void do_raise_exception_direct_err (uint32_t exception, int error_code); void do_raise_exception_direct (uint32_t exception); void cpu_dump_state(CPUState *env, FILE *f, diff --git a/target-mips/op.c b/target-mips/op.c index a286cefe5d..f97ec42928 100644 --- a/target-mips/op.c +++ b/target-mips/op.c @@ -1180,6 +1180,18 @@ void op_mfc0_config3 (void) RETURN(); } +void op_mfc0_config6 (void) +{ + T0 = env->CP0_Config6; + RETURN(); +} + +void op_mfc0_config7 (void) +{ + T0 = env->CP0_Config7; + RETURN(); +} + void op_mfc0_lladdr (void) { T0 = (int32_t)env->CP0_LLAddr >> 4; @@ -1653,7 +1665,7 @@ void op_dmtc0_errorepc (void) void op_cp1_enabled(void) { if (!(env->CP0_Status & (1 << CP0St_CU1))) { - CALL_FROM_TB2(do_raise_exception_err, EXCP_CpU, 1); + CALL_FROM_TB2(do_raise_exception_direct_err, EXCP_CpU, 1); } RETURN(); } diff --git a/target-mips/op_helper.c b/target-mips/op_helper.c index a262ea6684..8ab7bf57d4 100644 --- a/target-mips/op_helper.c +++ b/target-mips/op_helper.c @@ -56,10 +56,15 @@ void do_restore_state (void *pc_ptr) cpu_restore_state (tb, env, pc, NULL); } -void do_raise_exception_direct (uint32_t exception) +void do_raise_exception_direct_err (uint32_t exception, int error_code) { do_restore_state (GETPC ()); - do_raise_exception_err (exception, 0); + do_raise_exception_err (exception, error_code); +} + +void do_raise_exception_direct (uint32_t exception) +{ + do_raise_exception_direct_err (exception, 0); } #define MEMSUFFIX _raw diff --git a/target-mips/translate.c b/target-mips/translate.c index 89061db9aa..5cc922b57e 100644 --- a/target-mips/translate.c +++ b/target-mips/translate.c @@ -829,7 +829,7 @@ static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft, break; default: MIPS_INVAL("float load/store"); - generate_exception_err(ctx, EXCP_CpU, 1); + generate_exception(ctx, EXCP_RI); return; } MIPS_DEBUG("%s %s, %d(%s)", opn, fregnames[ft], offset, regnames[base]); @@ -1932,22 +1932,31 @@ static void gen_mfc0 (DisasContext *ctx, int reg, int sel) case 16: switch (sel) { case 0: - gen_op_mfc0_config0(); + gen_op_mfc0_config0(); rn = "Config"; break; case 1: - gen_op_mfc0_config1(); + gen_op_mfc0_config1(); rn = "Config1"; break; case 2: - gen_op_mfc0_config2(); + gen_op_mfc0_config2(); rn = "Config2"; break; case 3: - gen_op_mfc0_config3(); + gen_op_mfc0_config3(); rn = "Config3"; break; - /* 6,7 are implementation dependent */ + /* 4,5 are reserved */ + /* 6,7 are implementation dependent */ + case 6: + gen_op_mfc0_config6(); + rn = "Config6"; + break; + case 7: + gen_op_mfc0_config7(); + rn = "Config7"; + break; default: goto die; } @@ -2516,28 +2525,37 @@ static void gen_mtc0 (DisasContext *ctx, int reg, int sel) case 16: switch (sel) { case 0: - gen_op_mtc0_config0(); + gen_op_mtc0_config0(); rn = "Config"; break; case 1: - /* ignored */ + /* ignored, read only */ rn = "Config1"; break; case 2: - gen_op_mtc0_config2(); + gen_op_mtc0_config2(); rn = "Config2"; break; case 3: - /* ignored */ + /* ignored, read only */ rn = "Config3"; break; - /* 6,7 are implementation dependent */ + /* 4,5 are reserved */ + /* 6,7 are implementation dependent */ + case 6: + /* ignored */ + rn = "Config6"; + break; + case 7: + /* ignored */ + rn = "Config7"; + break; default: rn = "Invalid config selector"; goto die; } - /* Stop translation as we may have switched the execution mode */ - ctx->bstate = BS_STOP; + /* Stop translation as we may have switched the execution mode */ + ctx->bstate = BS_STOP; break; case 17: switch (sel) { @@ -4140,7 +4158,7 @@ static void gen_compute_branch1 (DisasContext *ctx, uint32_t op, break; default: MIPS_INVAL("cp1 branch/jump"); - generate_exception_err (ctx, EXCP_RI, 1); + generate_exception (ctx, EXCP_RI); return; } gen_op_set_bcond(); @@ -4173,7 +4191,7 @@ static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs) case OPC_CFC1: if (fs != 0 && fs != 31) { MIPS_INVAL("cfc1 freg"); - generate_exception_err (ctx, EXCP_RI, 1); + generate_exception (ctx, EXCP_RI); return; } GEN_LOAD_IMM_TN(T1, fs); @@ -4184,7 +4202,7 @@ static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs) case OPC_CTC1: if (fs != 0 && fs != 31) { MIPS_INVAL("ctc1 freg"); - generate_exception_err (ctx, EXCP_RI, 1); + generate_exception (ctx, EXCP_RI); return; } GEN_LOAD_IMM_TN(T1, fs); @@ -4201,7 +4219,7 @@ static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs) ctx->opcode, ctx->opcode >> 26, ctx->opcode & 0x3F, ((ctx->opcode >> 16) & 0x1F)); } - generate_exception_err (ctx, EXCP_RI, 1); + generate_exception (ctx, EXCP_RI); return; } MIPS_DEBUG("%s %s %s", opn, regnames[rt], fregnames[fs]); @@ -4219,7 +4237,7 @@ static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs) */ #define CHECK_FR(ctx, freg) do { \ if (!((ctx)->CP0_Status & (1<opcode, ctx->opcode >> 26, ctx->opcode & 0x3F, ((ctx->opcode >> 16) & 0x1F)); } - generate_exception_err (ctx, EXCP_RI, 1); + generate_exception (ctx, EXCP_RI); return; } if (binary) @@ -4627,11 +4645,12 @@ static void decode_opc (CPUState *env, DisasContext *ctx) case OPC_MOVCI: if (env->CP0_Config1 & (1 << CP0C1_FP)) { + save_cpu_state(ctx, 1); gen_op_cp1_enabled(); gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7, (ctx->opcode >> 16) & 1); } else { - generate_exception(ctx, EXCP_RI); + generate_exception_err(ctx, EXCP_CpU, 1); } break; @@ -4905,7 +4924,7 @@ static void decode_opc (CPUState *env, DisasContext *ctx) gen_farith(ctx, MASK_CP1_FUNC(ctx->opcode), rt, rd, sa); break; default: - generate_exception_err(ctx, EXCP_RI, 1); + generate_exception (ctx, EXCP_RI); break; } } else { @@ -4925,16 +4944,17 @@ static void decode_opc (CPUState *env, DisasContext *ctx) case OPC_CP3: if (env->CP0_Config1 & (1 << CP0C1_FP)) { + save_cpu_state(ctx, 1); gen_op_cp1_enabled(); op1 = MASK_CP3(ctx->opcode); switch (op1) { /* Not implemented */ default: - generate_exception_err(ctx, EXCP_RI, 1); + generate_exception (ctx, EXCP_RI); break; } } else { - generate_exception(ctx, EXCP_RI); + generate_exception_err(ctx, EXCP_CpU, 1); } break; -- cgit v1.2.3