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 |