Commit 3ddf0b5cde7c741258487710c40f7318fdcd0f18
1 parent
c92843b5
Disable 64-bit instructions on 32-bit CPU, by Aurelien Jarno.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3146 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
4 changed files
with
32 additions
and
24 deletions
target-mips/helper.c
| @@ -369,7 +369,8 @@ void do_interrupt (CPUState *env) | @@ -369,7 +369,8 @@ void do_interrupt (CPUState *env) | ||
| 369 | } | 369 | } |
| 370 | enter_debug_mode: | 370 | enter_debug_mode: |
| 371 | env->hflags |= MIPS_HFLAG_DM; | 371 | env->hflags |= MIPS_HFLAG_DM; |
| 372 | - env->hflags |= MIPS_HFLAG_64; | 372 | + if ((env->CP0_Config0 & (0x3 << CP0C0_AT))) |
| 373 | + env->hflags |= MIPS_HFLAG_64; | ||
| 373 | env->hflags &= ~MIPS_HFLAG_UM; | 374 | env->hflags &= ~MIPS_HFLAG_UM; |
| 374 | /* EJTAG probe trap enable is not implemented... */ | 375 | /* EJTAG probe trap enable is not implemented... */ |
| 375 | if (!(env->CP0_Status & (1 << CP0St_EXL))) | 376 | if (!(env->CP0_Status & (1 << CP0St_EXL))) |
| @@ -395,7 +396,8 @@ void do_interrupt (CPUState *env) | @@ -395,7 +396,8 @@ void do_interrupt (CPUState *env) | ||
| 395 | env->CP0_ErrorEPC = env->PC; | 396 | env->CP0_ErrorEPC = env->PC; |
| 396 | } | 397 | } |
| 397 | env->CP0_Status |= (1 << CP0St_ERL) | (1 << CP0St_BEV); | 398 | env->CP0_Status |= (1 << CP0St_ERL) | (1 << CP0St_BEV); |
| 398 | - env->hflags |= MIPS_HFLAG_64; | 399 | + if ((env->CP0_Config0 & (0x3 << CP0C0_AT))) |
| 400 | + env->hflags |= MIPS_HFLAG_64; | ||
| 399 | env->hflags &= ~MIPS_HFLAG_UM; | 401 | env->hflags &= ~MIPS_HFLAG_UM; |
| 400 | if (!(env->CP0_Status & (1 << CP0St_EXL))) | 402 | if (!(env->CP0_Status & (1 << CP0St_EXL))) |
| 401 | env->CP0_Cause &= ~(1 << CP0Ca_BD); | 403 | env->CP0_Cause &= ~(1 << CP0Ca_BD); |
| @@ -494,7 +496,8 @@ void do_interrupt (CPUState *env) | @@ -494,7 +496,8 @@ void do_interrupt (CPUState *env) | ||
| 494 | env->CP0_Cause &= ~(1 << CP0Ca_BD); | 496 | env->CP0_Cause &= ~(1 << CP0Ca_BD); |
| 495 | } | 497 | } |
| 496 | env->CP0_Status |= (1 << CP0St_EXL); | 498 | env->CP0_Status |= (1 << CP0St_EXL); |
| 497 | - env->hflags |= MIPS_HFLAG_64; | 499 | + if ((env->CP0_Config0 & (0x3 << CP0C0_AT))) |
| 500 | + env->hflags |= MIPS_HFLAG_64; | ||
| 498 | env->hflags &= ~MIPS_HFLAG_UM; | 501 | env->hflags &= ~MIPS_HFLAG_UM; |
| 499 | } | 502 | } |
| 500 | env->hflags &= ~MIPS_HFLAG_BMASK; | 503 | env->hflags &= ~MIPS_HFLAG_BMASK; |
target-mips/op.c
| @@ -1358,9 +1358,10 @@ void op_mtc0_status (void) | @@ -1358,9 +1358,10 @@ void op_mtc0_status (void) | ||
| 1358 | (val & (1 << CP0St_UM))) | 1358 | (val & (1 << CP0St_UM))) |
| 1359 | env->hflags |= MIPS_HFLAG_UM; | 1359 | env->hflags |= MIPS_HFLAG_UM; |
| 1360 | #ifdef TARGET_MIPS64 | 1360 | #ifdef TARGET_MIPS64 |
| 1361 | - if ((env->hflags & MIPS_HFLAG_UM) && | 1361 | + if (!(env->CP0_Config0 & (0x3 << CP0C0_AT)) || |
| 1362 | + ((env->hflags & MIPS_HFLAG_UM) && | ||
| 1362 | !(val & (1 << CP0St_PX)) && | 1363 | !(val & (1 << CP0St_PX)) && |
| 1363 | - !(val & (1 << CP0St_UX))) | 1364 | + !(val & (1 << CP0St_UX)))) |
| 1364 | env->hflags &= ~MIPS_HFLAG_64; | 1365 | env->hflags &= ~MIPS_HFLAG_64; |
| 1365 | #endif | 1366 | #endif |
| 1366 | if (val & (1 << CP0St_CU1)) | 1367 | if (val & (1 << CP0St_CU1)) |
| @@ -2318,9 +2319,10 @@ void op_eret (void) | @@ -2318,9 +2319,10 @@ void op_eret (void) | ||
| 2318 | (env->CP0_Status & (1 << CP0St_UM))) | 2319 | (env->CP0_Status & (1 << CP0St_UM))) |
| 2319 | env->hflags |= MIPS_HFLAG_UM; | 2320 | env->hflags |= MIPS_HFLAG_UM; |
| 2320 | #ifdef TARGET_MIPS64 | 2321 | #ifdef TARGET_MIPS64 |
| 2321 | - if ((env->hflags & MIPS_HFLAG_UM) && | 2322 | + if (!(env->CP0_Config0 & (0x3 << CP0C0_AT)) || |
| 2323 | + ((env->hflags & MIPS_HFLAG_UM) && | ||
| 2322 | !(env->CP0_Status & (1 << CP0St_PX)) && | 2324 | !(env->CP0_Status & (1 << CP0St_PX)) && |
| 2323 | - !(env->CP0_Status & (1 << CP0St_UX))) | 2325 | + !(env->CP0_Status & (1 << CP0St_UX)))) |
| 2324 | env->hflags &= ~MIPS_HFLAG_64; | 2326 | env->hflags &= ~MIPS_HFLAG_64; |
| 2325 | #endif | 2327 | #endif |
| 2326 | if (loglevel & CPU_LOG_EXEC) | 2328 | if (loglevel & CPU_LOG_EXEC) |
| @@ -2341,9 +2343,10 @@ void op_deret (void) | @@ -2341,9 +2343,10 @@ void op_deret (void) | ||
| 2341 | (env->CP0_Status & (1 << CP0St_UM))) | 2343 | (env->CP0_Status & (1 << CP0St_UM))) |
| 2342 | env->hflags |= MIPS_HFLAG_UM; | 2344 | env->hflags |= MIPS_HFLAG_UM; |
| 2343 | #ifdef TARGET_MIPS64 | 2345 | #ifdef TARGET_MIPS64 |
| 2344 | - if ((env->hflags & MIPS_HFLAG_UM) && | 2346 | + if (!(env->CP0_Config0 & (0x3 << CP0C0_AT)) || |
| 2347 | + ((env->hflags & MIPS_HFLAG_UM) && | ||
| 2345 | !(env->CP0_Status & (1 << CP0St_PX)) && | 2348 | !(env->CP0_Status & (1 << CP0St_PX)) && |
| 2346 | - !(env->CP0_Status & (1 << CP0St_UX))) | 2349 | + !(env->CP0_Status & (1 << CP0St_UX)))) |
| 2347 | env->hflags &= ~MIPS_HFLAG_64; | 2350 | env->hflags &= ~MIPS_HFLAG_64; |
| 2348 | #endif | 2351 | #endif |
| 2349 | if (loglevel & CPU_LOG_EXEC) | 2352 | if (loglevel & CPU_LOG_EXEC) |
target-mips/translate.c
| @@ -2225,6 +2225,8 @@ static void gen_mfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) | @@ -2225,6 +2225,8 @@ static void gen_mfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) | ||
| 2225 | switch (sel) { | 2225 | switch (sel) { |
| 2226 | case 0: | 2226 | case 0: |
| 2227 | #ifdef TARGET_MIPS64 | 2227 | #ifdef TARGET_MIPS64 |
| 2228 | + if (!(ctx->hflags & MIPS_HFLAG_64)) | ||
| 2229 | + goto die; | ||
| 2228 | gen_op_mfc0_xcontext(); | 2230 | gen_op_mfc0_xcontext(); |
| 2229 | rn = "XContext"; | 2231 | rn = "XContext"; |
| 2230 | break; | 2232 | break; |
| @@ -2781,6 +2783,8 @@ static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) | @@ -2781,6 +2783,8 @@ static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) | ||
| 2781 | switch (sel) { | 2783 | switch (sel) { |
| 2782 | case 0: | 2784 | case 0: |
| 2783 | #ifdef TARGET_MIPS64 | 2785 | #ifdef TARGET_MIPS64 |
| 2786 | + if (!(ctx->hflags & MIPS_HFLAG_64)) | ||
| 2787 | + goto die; | ||
| 2784 | gen_op_mtc0_xcontext(); | 2788 | gen_op_mtc0_xcontext(); |
| 2785 | rn = "XContext"; | 2789 | rn = "XContext"; |
| 2786 | break; | 2790 | break; |
| @@ -3331,11 +3335,9 @@ static void gen_dmfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) | @@ -3331,11 +3335,9 @@ static void gen_dmfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) | ||
| 3331 | case 20: | 3335 | case 20: |
| 3332 | switch (sel) { | 3336 | switch (sel) { |
| 3333 | case 0: | 3337 | case 0: |
| 3334 | -#ifdef TARGET_MIPS64 | ||
| 3335 | gen_op_dmfc0_xcontext(); | 3338 | gen_op_dmfc0_xcontext(); |
| 3336 | rn = "XContext"; | 3339 | rn = "XContext"; |
| 3337 | break; | 3340 | break; |
| 3338 | -#endif | ||
| 3339 | default: | 3341 | default: |
| 3340 | goto die; | 3342 | goto die; |
| 3341 | } | 3343 | } |
| @@ -3878,11 +3880,9 @@ static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) | @@ -3878,11 +3880,9 @@ static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) | ||
| 3878 | case 20: | 3880 | case 20: |
| 3879 | switch (sel) { | 3881 | switch (sel) { |
| 3880 | case 0: | 3882 | case 0: |
| 3881 | -#ifdef TARGET_MIPS64 | ||
| 3882 | gen_op_mtc0_xcontext(); | 3883 | gen_op_mtc0_xcontext(); |
| 3883 | rn = "XContext"; | 3884 | rn = "XContext"; |
| 3884 | break; | 3885 | break; |
| 3885 | -#endif | ||
| 3886 | default: | 3886 | default: |
| 3887 | goto die; | 3887 | goto die; |
| 3888 | } | 3888 | } |
| @@ -4107,6 +4107,8 @@ static void gen_cp0 (CPUState *env, DisasContext *ctx, uint32_t opc, int rt, int | @@ -4107,6 +4107,8 @@ static void gen_cp0 (CPUState *env, DisasContext *ctx, uint32_t opc, int rt, int | ||
| 4107 | break; | 4107 | break; |
| 4108 | #ifdef TARGET_MIPS64 | 4108 | #ifdef TARGET_MIPS64 |
| 4109 | case OPC_DMFC0: | 4109 | case OPC_DMFC0: |
| 4110 | + if (!(ctx->hflags & MIPS_HFLAG_64)) | ||
| 4111 | + generate_exception(ctx, EXCP_RI); | ||
| 4110 | if (rt == 0) { | 4112 | if (rt == 0) { |
| 4111 | /* Treat as NOP */ | 4113 | /* Treat as NOP */ |
| 4112 | return; | 4114 | return; |
| @@ -4116,6 +4118,8 @@ static void gen_cp0 (CPUState *env, DisasContext *ctx, uint32_t opc, int rt, int | @@ -4116,6 +4118,8 @@ static void gen_cp0 (CPUState *env, DisasContext *ctx, uint32_t opc, int rt, int | ||
| 4116 | opn = "dmfc0"; | 4118 | opn = "dmfc0"; |
| 4117 | break; | 4119 | break; |
| 4118 | case OPC_DMTC0: | 4120 | case OPC_DMTC0: |
| 4121 | + if (!(ctx->hflags & MIPS_HFLAG_64)) | ||
| 4122 | + generate_exception(ctx, EXCP_RI); | ||
| 4119 | GEN_LOAD_REG_TN(T0, rt); | 4123 | GEN_LOAD_REG_TN(T0, rt); |
| 4120 | gen_dmtc0(env,ctx, rd, ctx->opcode & 0x7); | 4124 | gen_dmtc0(env,ctx, rd, ctx->opcode & 0x7); |
| 4121 | opn = "dmtc0"; | 4125 | opn = "dmtc0"; |
| @@ -6183,11 +6187,7 @@ void cpu_reset (CPUMIPSState *env) | @@ -6183,11 +6187,7 @@ void cpu_reset (CPUMIPSState *env) | ||
| 6183 | } else { | 6187 | } else { |
| 6184 | env->CP0_ErrorEPC = env->PC; | 6188 | env->CP0_ErrorEPC = env->PC; |
| 6185 | } | 6189 | } |
| 6186 | -#ifdef TARGET_MIPS64 | ||
| 6187 | - env->hflags = MIPS_HFLAG_64; | ||
| 6188 | -#else | ||
| 6189 | env->hflags = 0; | 6190 | env->hflags = 0; |
| 6190 | -#endif | ||
| 6191 | env->PC = (int32_t)0xBFC00000; | 6191 | env->PC = (int32_t)0xBFC00000; |
| 6192 | env->CP0_Wired = 0; | 6192 | env->CP0_Wired = 0; |
| 6193 | /* SMP not implemented */ | 6193 | /* SMP not implemented */ |
target-mips/translate_init.c
| @@ -86,7 +86,6 @@ static mips_def_t mips_defs[] = | @@ -86,7 +86,6 @@ static mips_def_t mips_defs[] = | ||
| 86 | .SYNCI_Step = 32, | 86 | .SYNCI_Step = 32, |
| 87 | .CCRes = 2, | 87 | .CCRes = 2, |
| 88 | .Status_rw_bitmask = 0x3278FF17, | 88 | .Status_rw_bitmask = 0x3278FF17, |
| 89 | - .SEGBITS = 32, | ||
| 90 | }, | 89 | }, |
| 91 | { | 90 | { |
| 92 | .name = "4KEcR1", | 91 | .name = "4KEcR1", |
| @@ -100,7 +99,6 @@ static mips_def_t mips_defs[] = | @@ -100,7 +99,6 @@ static mips_def_t mips_defs[] = | ||
| 100 | .SYNCI_Step = 32, | 99 | .SYNCI_Step = 32, |
| 101 | .CCRes = 2, | 100 | .CCRes = 2, |
| 102 | .Status_rw_bitmask = 0x3278FF17, | 101 | .Status_rw_bitmask = 0x3278FF17, |
| 103 | - .SEGBITS = 32, | ||
| 104 | }, | 102 | }, |
| 105 | { | 103 | { |
| 106 | .name = "4KEc", | 104 | .name = "4KEc", |
| @@ -114,7 +112,6 @@ static mips_def_t mips_defs[] = | @@ -114,7 +112,6 @@ static mips_def_t mips_defs[] = | ||
| 114 | .SYNCI_Step = 32, | 112 | .SYNCI_Step = 32, |
| 115 | .CCRes = 2, | 113 | .CCRes = 2, |
| 116 | .Status_rw_bitmask = 0x3278FF17, | 114 | .Status_rw_bitmask = 0x3278FF17, |
| 117 | - .SEGBITS = 32, | ||
| 118 | }, | 115 | }, |
| 119 | { | 116 | { |
| 120 | .name = "24Kc", | 117 | .name = "24Kc", |
| @@ -128,7 +125,6 @@ static mips_def_t mips_defs[] = | @@ -128,7 +125,6 @@ static mips_def_t mips_defs[] = | ||
| 128 | .SYNCI_Step = 32, | 125 | .SYNCI_Step = 32, |
| 129 | .CCRes = 2, | 126 | .CCRes = 2, |
| 130 | .Status_rw_bitmask = 0x3278FF17, | 127 | .Status_rw_bitmask = 0x3278FF17, |
| 131 | - .SEGBITS = 32, | ||
| 132 | }, | 128 | }, |
| 133 | { | 129 | { |
| 134 | .name = "24Kf", | 130 | .name = "24Kf", |
| @@ -144,7 +140,6 @@ static mips_def_t mips_defs[] = | @@ -144,7 +140,6 @@ static mips_def_t mips_defs[] = | ||
| 144 | .Status_rw_bitmask = 0x3678FF17, | 140 | .Status_rw_bitmask = 0x3678FF17, |
| 145 | .CP1_fcr0 = (1 << FCR0_F64) | (1 << FCR0_L) | (1 << FCR0_W) | | 141 | .CP1_fcr0 = (1 << FCR0_F64) | (1 << FCR0_L) | (1 << FCR0_W) | |
| 146 | (1 << FCR0_D) | (1 << FCR0_S) | (0x93 << FCR0_PRID), | 142 | (1 << FCR0_D) | (1 << FCR0_S) | (0x93 << FCR0_PRID), |
| 147 | - .SEGBITS = 32, | ||
| 148 | }, | 143 | }, |
| 149 | #ifdef TARGET_MIPS64 | 144 | #ifdef TARGET_MIPS64 |
| 150 | { | 145 | { |
| @@ -293,8 +288,15 @@ int cpu_mips_register (CPUMIPSState *env, mips_def_t *def) | @@ -293,8 +288,15 @@ int cpu_mips_register (CPUMIPSState *env, mips_def_t *def) | ||
| 293 | env->Status_rw_bitmask = def->Status_rw_bitmask; | 288 | env->Status_rw_bitmask = def->Status_rw_bitmask; |
| 294 | env->fcr0 = def->CP1_fcr0; | 289 | env->fcr0 = def->CP1_fcr0; |
| 295 | #ifdef TARGET_MIPS64 | 290 | #ifdef TARGET_MIPS64 |
| 296 | - env->SEGBITS = def->SEGBITS; | ||
| 297 | - env->SEGMask = (3ULL << 62) | ((1ULL << def->SEGBITS) - 1); | 291 | + if ((env->CP0_Config0 & (0x3 << CP0C0_AT))) |
| 292 | + { | ||
| 293 | + env->hflags |= MIPS_HFLAG_64; | ||
| 294 | + env->SEGBITS = def->SEGBITS; | ||
| 295 | + env->SEGMask = (3ULL << 62) | ((1ULL << def->SEGBITS) - 1); | ||
| 296 | + } else { | ||
| 297 | + env->SEGBITS = 32; | ||
| 298 | + env->SEGMask = 0xFFFFFFFF; | ||
| 299 | + } | ||
| 298 | #endif | 300 | #endif |
| 299 | #ifdef CONFIG_USER_ONLY | 301 | #ifdef CONFIG_USER_ONLY |
| 300 | if (env->CP0_Config1 & (1 << CP0C1_FP)) | 302 | if (env->CP0_Config1 & (1 << CP0C1_FP)) |