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
target-mips/exec.h
... | ... | @@ -152,6 +152,7 @@ void invalidate_tlb (CPUState *env, int idx, int use_extra); |
152 | 152 | void cpu_loop_exit(void); |
153 | 153 | void do_raise_exception_err (uint32_t exception, int error_code); |
154 | 154 | void do_raise_exception (uint32_t exception); |
155 | +void do_raise_exception_direct_err (uint32_t exception, int error_code); | |
155 | 156 | void do_raise_exception_direct (uint32_t exception); |
156 | 157 | |
157 | 158 | void cpu_dump_state(CPUState *env, FILE *f, | ... | ... |
target-mips/op.c
... | ... | @@ -1180,6 +1180,18 @@ void op_mfc0_config3 (void) |
1180 | 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 | 1195 | void op_mfc0_lladdr (void) |
1184 | 1196 | { |
1185 | 1197 | T0 = (int32_t)env->CP0_LLAddr >> 4; |
... | ... | @@ -1653,7 +1665,7 @@ void op_dmtc0_errorepc (void) |
1653 | 1665 | void op_cp1_enabled(void) |
1654 | 1666 | { |
1655 | 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 | 1670 | RETURN(); |
1659 | 1671 | } | ... | ... |
target-mips/op_helper.c
... | ... | @@ -56,10 +56,15 @@ void do_restore_state (void *pc_ptr) |
56 | 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 | 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 | 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 | 829 | break; |
830 | 830 | default: |
831 | 831 | MIPS_INVAL("float load/store"); |
832 | - generate_exception_err(ctx, EXCP_CpU, 1); | |
832 | + generate_exception(ctx, EXCP_RI); | |
833 | 833 | return; |
834 | 834 | } |
835 | 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 | 1932 | case 16: |
1933 | 1933 | switch (sel) { |
1934 | 1934 | case 0: |
1935 | - gen_op_mfc0_config0(); | |
1935 | + gen_op_mfc0_config0(); | |
1936 | 1936 | rn = "Config"; |
1937 | 1937 | break; |
1938 | 1938 | case 1: |
1939 | - gen_op_mfc0_config1(); | |
1939 | + gen_op_mfc0_config1(); | |
1940 | 1940 | rn = "Config1"; |
1941 | 1941 | break; |
1942 | 1942 | case 2: |
1943 | - gen_op_mfc0_config2(); | |
1943 | + gen_op_mfc0_config2(); | |
1944 | 1944 | rn = "Config2"; |
1945 | 1945 | break; |
1946 | 1946 | case 3: |
1947 | - gen_op_mfc0_config3(); | |
1947 | + gen_op_mfc0_config3(); | |
1948 | 1948 | rn = "Config3"; |
1949 | 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 | 1960 | default: |
1952 | 1961 | goto die; |
1953 | 1962 | } |
... | ... | @@ -2516,28 +2525,37 @@ static void gen_mtc0 (DisasContext *ctx, int reg, int sel) |
2516 | 2525 | case 16: |
2517 | 2526 | switch (sel) { |
2518 | 2527 | case 0: |
2519 | - gen_op_mtc0_config0(); | |
2528 | + gen_op_mtc0_config0(); | |
2520 | 2529 | rn = "Config"; |
2521 | 2530 | break; |
2522 | 2531 | case 1: |
2523 | - /* ignored */ | |
2532 | + /* ignored, read only */ | |
2524 | 2533 | rn = "Config1"; |
2525 | 2534 | break; |
2526 | 2535 | case 2: |
2527 | - gen_op_mtc0_config2(); | |
2536 | + gen_op_mtc0_config2(); | |
2528 | 2537 | rn = "Config2"; |
2529 | 2538 | break; |
2530 | 2539 | case 3: |
2531 | - /* ignored */ | |
2540 | + /* ignored, read only */ | |
2532 | 2541 | rn = "Config3"; |
2533 | 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 | 2553 | default: |
2536 | 2554 | rn = "Invalid config selector"; |
2537 | 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 | 2559 | break; |
2542 | 2560 | case 17: |
2543 | 2561 | switch (sel) { |
... | ... | @@ -4140,7 +4158,7 @@ static void gen_compute_branch1 (DisasContext *ctx, uint32_t op, |
4140 | 4158 | break; |
4141 | 4159 | default: |
4142 | 4160 | MIPS_INVAL("cp1 branch/jump"); |
4143 | - generate_exception_err (ctx, EXCP_RI, 1); | |
4161 | + generate_exception (ctx, EXCP_RI); | |
4144 | 4162 | return; |
4145 | 4163 | } |
4146 | 4164 | gen_op_set_bcond(); |
... | ... | @@ -4173,7 +4191,7 @@ static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs) |
4173 | 4191 | case OPC_CFC1: |
4174 | 4192 | if (fs != 0 && fs != 31) { |
4175 | 4193 | MIPS_INVAL("cfc1 freg"); |
4176 | - generate_exception_err (ctx, EXCP_RI, 1); | |
4194 | + generate_exception (ctx, EXCP_RI); | |
4177 | 4195 | return; |
4178 | 4196 | } |
4179 | 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 | 4202 | case OPC_CTC1: |
4185 | 4203 | if (fs != 0 && fs != 31) { |
4186 | 4204 | MIPS_INVAL("ctc1 freg"); |
4187 | - generate_exception_err (ctx, EXCP_RI, 1); | |
4205 | + generate_exception (ctx, EXCP_RI); | |
4188 | 4206 | return; |
4189 | 4207 | } |
4190 | 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 | 4219 | ctx->opcode, ctx->opcode >> 26, ctx->opcode & 0x3F, |
4202 | 4220 | ((ctx->opcode >> 16) & 0x1F)); |
4203 | 4221 | } |
4204 | - generate_exception_err (ctx, EXCP_RI, 1); | |
4222 | + generate_exception (ctx, EXCP_RI); | |
4205 | 4223 | return; |
4206 | 4224 | } |
4207 | 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 | 4237 | */ |
4220 | 4238 | #define CHECK_FR(ctx, freg) do { \ |
4221 | 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 | 4241 | return; \ |
4224 | 4242 | } \ |
4225 | 4243 | } while(0) |
... | ... | @@ -4504,7 +4522,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft, int fs, int fd) |
4504 | 4522 | ctx->opcode, ctx->opcode >> 26, ctx->opcode & 0x3F, |
4505 | 4523 | ((ctx->opcode >> 16) & 0x1F)); |
4506 | 4524 | } |
4507 | - generate_exception_err (ctx, EXCP_RI, 1); | |
4525 | + generate_exception (ctx, EXCP_RI); | |
4508 | 4526 | return; |
4509 | 4527 | } |
4510 | 4528 | if (binary) |
... | ... | @@ -4627,11 +4645,12 @@ static void decode_opc (CPUState *env, DisasContext *ctx) |
4627 | 4645 | |
4628 | 4646 | case OPC_MOVCI: |
4629 | 4647 | if (env->CP0_Config1 & (1 << CP0C1_FP)) { |
4648 | + save_cpu_state(ctx, 1); | |
4630 | 4649 | gen_op_cp1_enabled(); |
4631 | 4650 | gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7, |
4632 | 4651 | (ctx->opcode >> 16) & 1); |
4633 | 4652 | } else { |
4634 | - generate_exception(ctx, EXCP_RI); | |
4653 | + generate_exception_err(ctx, EXCP_CpU, 1); | |
4635 | 4654 | } |
4636 | 4655 | break; |
4637 | 4656 | |
... | ... | @@ -4905,7 +4924,7 @@ static void decode_opc (CPUState *env, DisasContext *ctx) |
4905 | 4924 | gen_farith(ctx, MASK_CP1_FUNC(ctx->opcode), rt, rd, sa); |
4906 | 4925 | break; |
4907 | 4926 | default: |
4908 | - generate_exception_err(ctx, EXCP_RI, 1); | |
4927 | + generate_exception (ctx, EXCP_RI); | |
4909 | 4928 | break; |
4910 | 4929 | } |
4911 | 4930 | } else { |
... | ... | @@ -4925,16 +4944,17 @@ static void decode_opc (CPUState *env, DisasContext *ctx) |
4925 | 4944 | |
4926 | 4945 | case OPC_CP3: |
4927 | 4946 | if (env->CP0_Config1 & (1 << CP0C1_FP)) { |
4947 | + save_cpu_state(ctx, 1); | |
4928 | 4948 | gen_op_cp1_enabled(); |
4929 | 4949 | op1 = MASK_CP3(ctx->opcode); |
4930 | 4950 | switch (op1) { |
4931 | 4951 | /* Not implemented */ |
4932 | 4952 | default: |
4933 | - generate_exception_err(ctx, EXCP_RI, 1); | |
4953 | + generate_exception (ctx, EXCP_RI); | |
4934 | 4954 | break; |
4935 | 4955 | } |
4936 | 4956 | } else { |
4937 | - generate_exception(ctx, EXCP_RI); | |
4957 | + generate_exception_err(ctx, EXCP_CpU, 1); | |
4938 | 4958 | } |
4939 | 4959 | break; |
4940 | 4960 | ... | ... |