Commit e397ee3382a34c65b0fb93514c3eef5c31715d3c
1 parent
51789c41
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
Showing
5 changed files
with
66 additions
and
26 deletions
target-mips/cpu.h
@@ -203,6 +203,8 @@ struct CPUMIPSState { | @@ -203,6 +203,8 @@ struct CPUMIPSState { | ||
203 | #define CP0C3_MT 2 | 203 | #define CP0C3_MT 2 |
204 | #define CP0C3_SM 1 | 204 | #define CP0C3_SM 1 |
205 | #define CP0C3_TL 0 | 205 | #define CP0C3_TL 0 |
206 | + int32_t CP0_Config6; | ||
207 | + int32_t CP0_Config7; | ||
206 | target_ulong CP0_LLAddr; | 208 | target_ulong CP0_LLAddr; |
207 | target_ulong CP0_WatchLo; | 209 | target_ulong CP0_WatchLo; |
208 | int32_t CP0_WatchHi; | 210 | int32_t CP0_WatchHi; |
target-mips/exec.h
@@ -152,6 +152,7 @@ void invalidate_tlb (CPUState *env, int idx, int use_extra); | @@ -152,6 +152,7 @@ void invalidate_tlb (CPUState *env, int idx, int use_extra); | ||
152 | void cpu_loop_exit(void); | 152 | void cpu_loop_exit(void); |
153 | void do_raise_exception_err (uint32_t exception, int error_code); | 153 | void do_raise_exception_err (uint32_t exception, int error_code); |
154 | void do_raise_exception (uint32_t exception); | 154 | void do_raise_exception (uint32_t exception); |
155 | +void do_raise_exception_direct_err (uint32_t exception, int error_code); | ||
155 | void do_raise_exception_direct (uint32_t exception); | 156 | void do_raise_exception_direct (uint32_t exception); |
156 | 157 | ||
157 | void cpu_dump_state(CPUState *env, FILE *f, | 158 | void cpu_dump_state(CPUState *env, FILE *f, |
target-mips/op.c
@@ -1180,6 +1180,18 @@ void op_mfc0_config3 (void) | @@ -1180,6 +1180,18 @@ void op_mfc0_config3 (void) | ||
1180 | RETURN(); | 1180 | RETURN(); |
1181 | } | 1181 | } |
1182 | 1182 | ||
1183 | +void op_mfc0_config6 (void) | ||
1184 | +{ | ||
1185 | + T0 = env->CP0_Config6; | ||
1186 | + RETURN(); | ||
1187 | +} | ||
1188 | + | ||
1189 | +void op_mfc0_config7 (void) | ||
1190 | +{ | ||
1191 | + T0 = env->CP0_Config7; | ||
1192 | + RETURN(); | ||
1193 | +} | ||
1194 | + | ||
1183 | void op_mfc0_lladdr (void) | 1195 | void op_mfc0_lladdr (void) |
1184 | { | 1196 | { |
1185 | T0 = (int32_t)env->CP0_LLAddr >> 4; | 1197 | T0 = (int32_t)env->CP0_LLAddr >> 4; |
@@ -1653,7 +1665,7 @@ void op_dmtc0_errorepc (void) | @@ -1653,7 +1665,7 @@ void op_dmtc0_errorepc (void) | ||
1653 | void op_cp1_enabled(void) | 1665 | void op_cp1_enabled(void) |
1654 | { | 1666 | { |
1655 | if (!(env->CP0_Status & (1 << CP0St_CU1))) { | 1667 | if (!(env->CP0_Status & (1 << CP0St_CU1))) { |
1656 | - CALL_FROM_TB2(do_raise_exception_err, EXCP_CpU, 1); | 1668 | + CALL_FROM_TB2(do_raise_exception_direct_err, EXCP_CpU, 1); |
1657 | } | 1669 | } |
1658 | RETURN(); | 1670 | RETURN(); |
1659 | } | 1671 | } |
target-mips/op_helper.c
@@ -56,10 +56,15 @@ void do_restore_state (void *pc_ptr) | @@ -56,10 +56,15 @@ void do_restore_state (void *pc_ptr) | ||
56 | cpu_restore_state (tb, env, pc, NULL); | 56 | cpu_restore_state (tb, env, pc, NULL); |
57 | } | 57 | } |
58 | 58 | ||
59 | -void do_raise_exception_direct (uint32_t exception) | 59 | +void do_raise_exception_direct_err (uint32_t exception, int error_code) |
60 | { | 60 | { |
61 | do_restore_state (GETPC ()); | 61 | do_restore_state (GETPC ()); |
62 | - do_raise_exception_err (exception, 0); | 62 | + do_raise_exception_err (exception, error_code); |
63 | +} | ||
64 | + | ||
65 | +void do_raise_exception_direct (uint32_t exception) | ||
66 | +{ | ||
67 | + do_raise_exception_direct_err (exception, 0); | ||
63 | } | 68 | } |
64 | 69 | ||
65 | #define MEMSUFFIX _raw | 70 | #define MEMSUFFIX _raw |
target-mips/translate.c
@@ -829,7 +829,7 @@ static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft, | @@ -829,7 +829,7 @@ static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft, | ||
829 | break; | 829 | break; |
830 | default: | 830 | default: |
831 | MIPS_INVAL("float load/store"); | 831 | MIPS_INVAL("float load/store"); |
832 | - generate_exception_err(ctx, EXCP_CpU, 1); | 832 | + generate_exception(ctx, EXCP_RI); |
833 | return; | 833 | return; |
834 | } | 834 | } |
835 | MIPS_DEBUG("%s %s, %d(%s)", opn, fregnames[ft], offset, regnames[base]); | 835 | 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) | @@ -1932,22 +1932,31 @@ static void gen_mfc0 (DisasContext *ctx, int reg, int sel) | ||
1932 | case 16: | 1932 | case 16: |
1933 | switch (sel) { | 1933 | switch (sel) { |
1934 | case 0: | 1934 | case 0: |
1935 | - gen_op_mfc0_config0(); | 1935 | + gen_op_mfc0_config0(); |
1936 | rn = "Config"; | 1936 | rn = "Config"; |
1937 | break; | 1937 | break; |
1938 | case 1: | 1938 | case 1: |
1939 | - gen_op_mfc0_config1(); | 1939 | + gen_op_mfc0_config1(); |
1940 | rn = "Config1"; | 1940 | rn = "Config1"; |
1941 | break; | 1941 | break; |
1942 | case 2: | 1942 | case 2: |
1943 | - gen_op_mfc0_config2(); | 1943 | + gen_op_mfc0_config2(); |
1944 | rn = "Config2"; | 1944 | rn = "Config2"; |
1945 | break; | 1945 | break; |
1946 | case 3: | 1946 | case 3: |
1947 | - gen_op_mfc0_config3(); | 1947 | + gen_op_mfc0_config3(); |
1948 | rn = "Config3"; | 1948 | rn = "Config3"; |
1949 | break; | 1949 | break; |
1950 | - /* 6,7 are implementation dependent */ | 1950 | + /* 4,5 are reserved */ |
1951 | + /* 6,7 are implementation dependent */ | ||
1952 | + case 6: | ||
1953 | + gen_op_mfc0_config6(); | ||
1954 | + rn = "Config6"; | ||
1955 | + break; | ||
1956 | + case 7: | ||
1957 | + gen_op_mfc0_config7(); | ||
1958 | + rn = "Config7"; | ||
1959 | + break; | ||
1951 | default: | 1960 | default: |
1952 | goto die; | 1961 | goto die; |
1953 | } | 1962 | } |
@@ -2516,28 +2525,37 @@ static void gen_mtc0 (DisasContext *ctx, int reg, int sel) | @@ -2516,28 +2525,37 @@ static void gen_mtc0 (DisasContext *ctx, int reg, int sel) | ||
2516 | case 16: | 2525 | case 16: |
2517 | switch (sel) { | 2526 | switch (sel) { |
2518 | case 0: | 2527 | case 0: |
2519 | - gen_op_mtc0_config0(); | 2528 | + gen_op_mtc0_config0(); |
2520 | rn = "Config"; | 2529 | rn = "Config"; |
2521 | break; | 2530 | break; |
2522 | case 1: | 2531 | case 1: |
2523 | - /* ignored */ | 2532 | + /* ignored, read only */ |
2524 | rn = "Config1"; | 2533 | rn = "Config1"; |
2525 | break; | 2534 | break; |
2526 | case 2: | 2535 | case 2: |
2527 | - gen_op_mtc0_config2(); | 2536 | + gen_op_mtc0_config2(); |
2528 | rn = "Config2"; | 2537 | rn = "Config2"; |
2529 | break; | 2538 | break; |
2530 | case 3: | 2539 | case 3: |
2531 | - /* ignored */ | 2540 | + /* ignored, read only */ |
2532 | rn = "Config3"; | 2541 | rn = "Config3"; |
2533 | break; | 2542 | break; |
2534 | - /* 6,7 are implementation dependent */ | 2543 | + /* 4,5 are reserved */ |
2544 | + /* 6,7 are implementation dependent */ | ||
2545 | + case 6: | ||
2546 | + /* ignored */ | ||
2547 | + rn = "Config6"; | ||
2548 | + break; | ||
2549 | + case 7: | ||
2550 | + /* ignored */ | ||
2551 | + rn = "Config7"; | ||
2552 | + break; | ||
2535 | default: | 2553 | default: |
2536 | rn = "Invalid config selector"; | 2554 | rn = "Invalid config selector"; |
2537 | goto die; | 2555 | goto die; |
2538 | } | 2556 | } |
2539 | - /* Stop translation as we may have switched the execution mode */ | ||
2540 | - ctx->bstate = BS_STOP; | 2557 | + /* Stop translation as we may have switched the execution mode */ |
2558 | + ctx->bstate = BS_STOP; | ||
2541 | break; | 2559 | break; |
2542 | case 17: | 2560 | case 17: |
2543 | switch (sel) { | 2561 | switch (sel) { |
@@ -4140,7 +4158,7 @@ static void gen_compute_branch1 (DisasContext *ctx, uint32_t op, | @@ -4140,7 +4158,7 @@ static void gen_compute_branch1 (DisasContext *ctx, uint32_t op, | ||
4140 | break; | 4158 | break; |
4141 | default: | 4159 | default: |
4142 | MIPS_INVAL("cp1 branch/jump"); | 4160 | MIPS_INVAL("cp1 branch/jump"); |
4143 | - generate_exception_err (ctx, EXCP_RI, 1); | 4161 | + generate_exception (ctx, EXCP_RI); |
4144 | return; | 4162 | return; |
4145 | } | 4163 | } |
4146 | gen_op_set_bcond(); | 4164 | gen_op_set_bcond(); |
@@ -4173,7 +4191,7 @@ static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs) | @@ -4173,7 +4191,7 @@ static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs) | ||
4173 | case OPC_CFC1: | 4191 | case OPC_CFC1: |
4174 | if (fs != 0 && fs != 31) { | 4192 | if (fs != 0 && fs != 31) { |
4175 | MIPS_INVAL("cfc1 freg"); | 4193 | MIPS_INVAL("cfc1 freg"); |
4176 | - generate_exception_err (ctx, EXCP_RI, 1); | 4194 | + generate_exception (ctx, EXCP_RI); |
4177 | return; | 4195 | return; |
4178 | } | 4196 | } |
4179 | GEN_LOAD_IMM_TN(T1, fs); | 4197 | GEN_LOAD_IMM_TN(T1, fs); |
@@ -4184,7 +4202,7 @@ static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs) | @@ -4184,7 +4202,7 @@ static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs) | ||
4184 | case OPC_CTC1: | 4202 | case OPC_CTC1: |
4185 | if (fs != 0 && fs != 31) { | 4203 | if (fs != 0 && fs != 31) { |
4186 | MIPS_INVAL("ctc1 freg"); | 4204 | MIPS_INVAL("ctc1 freg"); |
4187 | - generate_exception_err (ctx, EXCP_RI, 1); | 4205 | + generate_exception (ctx, EXCP_RI); |
4188 | return; | 4206 | return; |
4189 | } | 4207 | } |
4190 | GEN_LOAD_IMM_TN(T1, fs); | 4208 | GEN_LOAD_IMM_TN(T1, fs); |
@@ -4201,7 +4219,7 @@ static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs) | @@ -4201,7 +4219,7 @@ static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs) | ||
4201 | ctx->opcode, ctx->opcode >> 26, ctx->opcode & 0x3F, | 4219 | ctx->opcode, ctx->opcode >> 26, ctx->opcode & 0x3F, |
4202 | ((ctx->opcode >> 16) & 0x1F)); | 4220 | ((ctx->opcode >> 16) & 0x1F)); |
4203 | } | 4221 | } |
4204 | - generate_exception_err (ctx, EXCP_RI, 1); | 4222 | + generate_exception (ctx, EXCP_RI); |
4205 | return; | 4223 | return; |
4206 | } | 4224 | } |
4207 | MIPS_DEBUG("%s %s %s", opn, regnames[rt], fregnames[fs]); | 4225 | 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) | @@ -4219,7 +4237,7 @@ static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs) | ||
4219 | */ | 4237 | */ |
4220 | #define CHECK_FR(ctx, freg) do { \ | 4238 | #define CHECK_FR(ctx, freg) do { \ |
4221 | if (!((ctx)->CP0_Status & (1<<CP0St_FR)) && ((freg) & 1)) { \ | 4239 | if (!((ctx)->CP0_Status & (1<<CP0St_FR)) && ((freg) & 1)) { \ |
4222 | - generate_exception_err (ctx, EXCP_RI, 1); \ | 4240 | + generate_exception (ctx, EXCP_RI); \ |
4223 | return; \ | 4241 | return; \ |
4224 | } \ | 4242 | } \ |
4225 | } while(0) | 4243 | } while(0) |
@@ -4504,7 +4522,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft, int fs, int fd) | @@ -4504,7 +4522,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft, int fs, int fd) | ||
4504 | ctx->opcode, ctx->opcode >> 26, ctx->opcode & 0x3F, | 4522 | ctx->opcode, ctx->opcode >> 26, ctx->opcode & 0x3F, |
4505 | ((ctx->opcode >> 16) & 0x1F)); | 4523 | ((ctx->opcode >> 16) & 0x1F)); |
4506 | } | 4524 | } |
4507 | - generate_exception_err (ctx, EXCP_RI, 1); | 4525 | + generate_exception (ctx, EXCP_RI); |
4508 | return; | 4526 | return; |
4509 | } | 4527 | } |
4510 | if (binary) | 4528 | if (binary) |
@@ -4627,11 +4645,12 @@ static void decode_opc (CPUState *env, DisasContext *ctx) | @@ -4627,11 +4645,12 @@ static void decode_opc (CPUState *env, DisasContext *ctx) | ||
4627 | 4645 | ||
4628 | case OPC_MOVCI: | 4646 | case OPC_MOVCI: |
4629 | if (env->CP0_Config1 & (1 << CP0C1_FP)) { | 4647 | if (env->CP0_Config1 & (1 << CP0C1_FP)) { |
4648 | + save_cpu_state(ctx, 1); | ||
4630 | gen_op_cp1_enabled(); | 4649 | gen_op_cp1_enabled(); |
4631 | gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7, | 4650 | gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7, |
4632 | (ctx->opcode >> 16) & 1); | 4651 | (ctx->opcode >> 16) & 1); |
4633 | } else { | 4652 | } else { |
4634 | - generate_exception(ctx, EXCP_RI); | 4653 | + generate_exception_err(ctx, EXCP_CpU, 1); |
4635 | } | 4654 | } |
4636 | break; | 4655 | break; |
4637 | 4656 | ||
@@ -4905,7 +4924,7 @@ static void decode_opc (CPUState *env, DisasContext *ctx) | @@ -4905,7 +4924,7 @@ static void decode_opc (CPUState *env, DisasContext *ctx) | ||
4905 | gen_farith(ctx, MASK_CP1_FUNC(ctx->opcode), rt, rd, sa); | 4924 | gen_farith(ctx, MASK_CP1_FUNC(ctx->opcode), rt, rd, sa); |
4906 | break; | 4925 | break; |
4907 | default: | 4926 | default: |
4908 | - generate_exception_err(ctx, EXCP_RI, 1); | 4927 | + generate_exception (ctx, EXCP_RI); |
4909 | break; | 4928 | break; |
4910 | } | 4929 | } |
4911 | } else { | 4930 | } else { |
@@ -4925,16 +4944,17 @@ static void decode_opc (CPUState *env, DisasContext *ctx) | @@ -4925,16 +4944,17 @@ static void decode_opc (CPUState *env, DisasContext *ctx) | ||
4925 | 4944 | ||
4926 | case OPC_CP3: | 4945 | case OPC_CP3: |
4927 | if (env->CP0_Config1 & (1 << CP0C1_FP)) { | 4946 | if (env->CP0_Config1 & (1 << CP0C1_FP)) { |
4947 | + save_cpu_state(ctx, 1); | ||
4928 | gen_op_cp1_enabled(); | 4948 | gen_op_cp1_enabled(); |
4929 | op1 = MASK_CP3(ctx->opcode); | 4949 | op1 = MASK_CP3(ctx->opcode); |
4930 | switch (op1) { | 4950 | switch (op1) { |
4931 | /* Not implemented */ | 4951 | /* Not implemented */ |
4932 | default: | 4952 | default: |
4933 | - generate_exception_err(ctx, EXCP_RI, 1); | 4953 | + generate_exception (ctx, EXCP_RI); |
4934 | break; | 4954 | break; |
4935 | } | 4955 | } |
4936 | } else { | 4956 | } else { |
4937 | - generate_exception(ctx, EXCP_RI); | 4957 | + generate_exception_err(ctx, EXCP_CpU, 1); |
4938 | } | 4958 | } |
4939 | break; | 4959 | break; |
4940 | 4960 |