Commit 4b3686faeefab6279f6d395fcf56ea5405d040da
1 parent
85c4adf6
PowerPC merge
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@861 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
6 changed files
with
274 additions
and
150 deletions
target-ppc/exec.h
... | ... | @@ -135,6 +135,8 @@ void do_sraw(void); |
135 | 135 | |
136 | 136 | void do_fctiw (void); |
137 | 137 | void do_fctiwz (void); |
138 | +void do_fnmadd (void); | |
139 | +void do_fnmsub (void); | |
138 | 140 | void do_fnmadds (void); |
139 | 141 | void do_fnmsubs (void); |
140 | 142 | void do_fsqrt (void); |
... | ... | @@ -147,7 +149,11 @@ void do_fcmpo (void); |
147 | 149 | void do_fabs (void); |
148 | 150 | void do_fnabs (void); |
149 | 151 | |
152 | +void do_check_reservation (void); | |
150 | 153 | void do_icbi (void); |
154 | +void do_store_sr (uint32_t srnum); | |
155 | +void do_store_ibat (int ul, int nr); | |
156 | +void do_store_dbat (int ul, int nr); | |
151 | 157 | void do_tlbia (void); |
152 | 158 | void do_tlbie (void); |
153 | 159 | ... | ... |
target-ppc/helper.c
... | ... | @@ -28,9 +28,6 @@ |
28 | 28 | //#define DEBUG_EXCEPTIONS |
29 | 29 | |
30 | 30 | extern FILE *stdout, *stderr; |
31 | -void abort (void); | |
32 | - | |
33 | -/*****************************************************************************/ | |
34 | 31 | |
35 | 32 | /*****************************************************************************/ |
36 | 33 | /* PPC MMU emulation */ |
... | ... | @@ -365,7 +362,8 @@ int get_physical_address (CPUState *env, uint32_t *physical, int *prot, |
365 | 362 | fprintf(logfile, "%s\n", __func__); |
366 | 363 | } |
367 | 364 | |
368 | - if ((access_type == ACCESS_CODE && msr_ir == 0) || msr_dr == 0) { | |
365 | + if ((access_type == ACCESS_CODE && msr_ir == 0) || | |
366 | + (access_type != ACCESS_CODE && msr_dr == 0)) { | |
369 | 367 | /* No address translation */ |
370 | 368 | *physical = address & ~0xFFF; |
371 | 369 | *prot = PAGE_READ | PAGE_WRITE; |
... | ... | @@ -441,12 +439,15 @@ void tlb_fill(unsigned long addr, int is_write, int is_user, void *retaddr) |
441 | 439 | index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1); |
442 | 440 | tlb_addrr = env->tlb_read[is_user][index].address; |
443 | 441 | tlb_addrw = env->tlb_write[is_user][index].address; |
444 | -#if 0 | |
445 | - printf("%s 1 %p %p idx=%d addr=0x%08lx tbl_addr=0x%08lx 0x%08lx " | |
442 | +#if 1 | |
443 | + if (loglevel) { | |
444 | + fprintf(logfile, | |
445 | + "%s 1 %p %p idx=%d addr=0x%08lx tbl_addr=0x%08lx 0x%08lx " | |
446 | 446 | "(0x%08lx 0x%08lx)\n", __func__, env, |
447 | 447 | &env->tlb_read[is_user][index], index, addr, |
448 | 448 | tlb_addrr, tlb_addrw, addr & TARGET_PAGE_MASK, |
449 | 449 | tlb_addrr & (TARGET_PAGE_MASK | TLB_INVALID_MASK)); |
450 | + } | |
450 | 451 | #endif |
451 | 452 | } |
452 | 453 | ret = cpu_ppc_handle_mmu_fault(env, addr, is_write, is_user, 1); |
... | ... | @@ -631,11 +632,14 @@ uint32_t _load_msr (CPUState *env) |
631 | 632 | |
632 | 633 | void _store_msr (CPUState *env, uint32_t value) |
633 | 634 | { |
635 | +#if 0 // TRY | |
634 | 636 | if (((value >> MSR_IR) & 0x01) != msr_ir || |
635 | - ((value >> MSR_DR) & 0x01) != msr_dr) { | |
637 | + ((value >> MSR_DR) & 0x01) != msr_dr) | |
638 | + { | |
636 | 639 | /* Flush all tlb when changing translation mode or privilege level */ |
637 | 640 | tlb_flush(env, 1); |
638 | 641 | } |
642 | +#endif | |
639 | 643 | msr_pow = (value >> MSR_POW) & 0x03; |
640 | 644 | msr_ile = (value >> MSR_ILE) & 0x01; |
641 | 645 | msr_ee = (value >> MSR_EE) & 0x01; |
... | ... | @@ -699,13 +703,8 @@ void do_interrupt (CPUState *env) |
699 | 703 | goto store_next; |
700 | 704 | case EXCP_MACHINE_CHECK: |
701 | 705 | if (msr_me == 0) { |
702 | - printf("Machine check exception while not allowed !\n"); | |
703 | - if (loglevel) { | |
704 | - fprintf(logfile, | |
705 | - "Machine check exception while not allowed !\n"); | |
706 | + cpu_abort(env, "Machine check exception while not allowed\n"); | |
706 | 707 | } |
707 | - abort(); | |
708 | - } | |
709 | 708 | msr_me = 0; |
710 | 709 | break; |
711 | 710 | case EXCP_DSI: |
... | ... | @@ -801,7 +800,7 @@ void do_interrupt (CPUState *env) |
801 | 800 | env->fpscr[7] |= 0x4; |
802 | 801 | break; |
803 | 802 | case EXCP_INVAL: |
804 | - printf("Invalid instruction at 0x%08x\n", env->nip); | |
803 | + // printf("Invalid instruction at 0x%08x\n", env->nip); | |
805 | 804 | msr |= 0x00080000; |
806 | 805 | break; |
807 | 806 | case EXCP_PRIV: | ... | ... |
target-ppc/op.c
... | ... | @@ -242,10 +242,7 @@ PPC_OP(load_srin) |
242 | 242 | |
243 | 243 | PPC_OP(store_srin) |
244 | 244 | { |
245 | -#if defined (DEBUG_OP) | |
246 | - dump_store_sr(T1 >> 28); | |
247 | -#endif | |
248 | - regs->sr[T1 >> 28] = T0; | |
245 | + do_store_sr(T1 >> 28); | |
249 | 246 | RETURN(); |
250 | 247 | } |
251 | 248 | |
... | ... | @@ -402,10 +399,7 @@ PPC_OP(load_ibat) |
402 | 399 | |
403 | 400 | PPC_OP(store_ibat) |
404 | 401 | { |
405 | -#if defined (DEBUG_OP) | |
406 | - dump_store_ibat(PARAM(1), PARAM(2)); | |
407 | -#endif | |
408 | - regs->IBAT[PARAM(1)][PARAM(2)] = T0; | |
402 | + do_store_ibat(PARAM(1), PARAM(2)); | |
409 | 403 | } |
410 | 404 | |
411 | 405 | PPC_OP(load_dbat) |
... | ... | @@ -415,10 +409,7 @@ PPC_OP(load_dbat) |
415 | 409 | |
416 | 410 | PPC_OP(store_dbat) |
417 | 411 | { |
418 | -#if defined (DEBUG_OP) | |
419 | - dump_store_dbat(PARAM(1), PARAM(2)); | |
420 | -#endif | |
421 | - regs->DBAT[PARAM(1)][PARAM(2)] = T0; | |
412 | + do_store_dbat(PARAM(1), PARAM(2)); | |
422 | 413 | } |
423 | 414 | |
424 | 415 | /* FPSCR */ |
... | ... | @@ -1344,9 +1335,7 @@ PPC_OP(fmsubs) |
1344 | 1335 | /* fnmadd - fnmadd. - fnmadds - fnmadds. */ |
1345 | 1336 | PPC_OP(fnmadd) |
1346 | 1337 | { |
1347 | - FT0 *= FT1; | |
1348 | - FT0 += FT2; | |
1349 | - FT0 = -FT0; | |
1338 | + do_fnmadd(); | |
1350 | 1339 | RETURN(); |
1351 | 1340 | } |
1352 | 1341 | |
... | ... | @@ -1360,9 +1349,7 @@ PPC_OP(fnmadds) |
1360 | 1349 | /* fnmsub - fnmsub. */ |
1361 | 1350 | PPC_OP(fnmsub) |
1362 | 1351 | { |
1363 | - FT0 *= FT1; | |
1364 | - FT0 -= FT2; | |
1365 | - FT0 = -FT0; | |
1352 | + do_fnmsub(); | |
1366 | 1353 | RETURN(); |
1367 | 1354 | } |
1368 | 1355 | |
... | ... | @@ -1444,11 +1431,22 @@ PPC_OP(fneg) |
1444 | 1431 | #include "op_mem.h" |
1445 | 1432 | #endif |
1446 | 1433 | |
1434 | +/* Special op to check and maybe clear reservation */ | |
1435 | +PPC_OP(check_reservation) | |
1436 | +{ | |
1437 | + do_check_reservation(); | |
1438 | + RETURN(); | |
1439 | +} | |
1440 | + | |
1447 | 1441 | /* Return from interrupt */ |
1448 | 1442 | PPC_OP(rfi) |
1449 | 1443 | { |
1450 | 1444 | regs->nip = regs->spr[SRR0] & ~0x00000003; |
1445 | +#if 1 // TRY | |
1446 | + T0 = regs->spr[SRR1] & ~0xFFF00000; | |
1447 | +#else | |
1451 | 1448 | T0 = regs->spr[SRR1] & ~0xFFFF0000; |
1449 | +#endif | |
1452 | 1450 | do_store_msr(); |
1453 | 1451 | #if defined (DEBUG_OP) |
1454 | 1452 | dump_rfi(); | ... | ... |
target-ppc/op_helper.c
... | ... | @@ -127,11 +127,14 @@ void do_load_msr (void) |
127 | 127 | |
128 | 128 | void do_store_msr (void) |
129 | 129 | { |
130 | +#if 1 // TRY | |
130 | 131 | if (((T0 >> MSR_IR) & 0x01) != msr_ir || |
131 | - ((T0 >> MSR_DR) & 0x01) != msr_dr) { | |
132 | - /* Flush all tlb when changing translation mode or privilege level */ | |
132 | + ((T0 >> MSR_DR) & 0x01) != msr_dr || | |
133 | + ((T0 >> MSR_PR) & 0x01) != msr_pr) | |
134 | + { | |
133 | 135 | do_tlbia(); |
134 | 136 | } |
137 | +#endif | |
135 | 138 | msr_pow = (T0 >> MSR_POW) & 0x03; |
136 | 139 | msr_ile = (T0 >> MSR_ILE) & 0x01; |
137 | 140 | msr_ee = (T0 >> MSR_EE) & 0x01; |
... | ... | @@ -157,14 +160,18 @@ void do_sraw (void) |
157 | 160 | xer_ca = 0; |
158 | 161 | if (T1 & 0x20) { |
159 | 162 | ret = (-1) * (T0 >> 31); |
160 | - if (ret < 0) | |
163 | + if (ret < 0 && (T0 & ~0x80000000) != 0) | |
161 | 164 | xer_ca = 1; |
165 | +#if 1 // TRY | |
166 | + } else if (T1 == 0) { | |
167 | + ret = T0; | |
168 | +#endif | |
162 | 169 | } else { |
163 | 170 | ret = (int32_t)T0 >> (T1 & 0x1f); |
164 | 171 | if (ret < 0 && ((int32_t)T0 & ((1 << T1) - 1)) != 0) |
165 | 172 | xer_ca = 1; |
166 | 173 | } |
167 | - (int32_t)T0 = ret; | |
174 | + T0 = ret; | |
168 | 175 | } |
169 | 176 | |
170 | 177 | /* Floating point operations helpers */ |
... | ... | @@ -267,14 +274,24 @@ void do_fctiwz (void) |
267 | 274 | fesetround(cround); |
268 | 275 | } |
269 | 276 | |
277 | +void do_fnmadd (void) | |
278 | +{ | |
279 | + FT0 = -((FT0 * FT1) + FT2); | |
280 | +} | |
281 | + | |
282 | +void do_fnmsub (void) | |
283 | +{ | |
284 | + FT0 = -((FT0 * FT1) - FT2); | |
285 | +} | |
286 | + | |
270 | 287 | void do_fnmadds (void) |
271 | 288 | { |
272 | - FTS0 = -((FTS0 * FTS1) + FTS2); | |
289 | + FT0 = -((FTS0 * FTS1) + FTS2); | |
273 | 290 | } |
274 | 291 | |
275 | 292 | void do_fnmsubs (void) |
276 | 293 | { |
277 | - FTS0 = -((FTS0 * FTS1) - FTS2); | |
294 | + FT0 = -((FTS0 * FTS1) - FTS2); | |
278 | 295 | } |
279 | 296 | |
280 | 297 | void do_fsqrt (void) |
... | ... | @@ -307,7 +324,6 @@ void do_fsel (void) |
307 | 324 | |
308 | 325 | void do_fcmpu (void) |
309 | 326 | { |
310 | - env->fpscr[4] &= ~0x1; | |
311 | 327 | if (isnan(FT0) || isnan(FT1)) { |
312 | 328 | T0 = 0x01; |
313 | 329 | env->fpscr[4] |= 0x1; |
... | ... | @@ -319,7 +335,7 @@ void do_fcmpu (void) |
319 | 335 | } else { |
320 | 336 | T0 = 0x02; |
321 | 337 | } |
322 | - env->fpscr[3] |= T0; | |
338 | + env->fpscr[3] = T0; | |
323 | 339 | } |
324 | 340 | |
325 | 341 | void do_fcmpo (void) |
... | ... | @@ -343,7 +359,7 @@ void do_fcmpo (void) |
343 | 359 | } else { |
344 | 360 | T0 = 0x02; |
345 | 361 | } |
346 | - env->fpscr[3] |= T0; | |
362 | + env->fpscr[3] = T0; | |
347 | 363 | } |
348 | 364 | |
349 | 365 | void do_fabs (void) |
... | ... | @@ -359,6 +375,12 @@ void do_fnabs (void) |
359 | 375 | /* Instruction cache invalidation helper */ |
360 | 376 | #define ICACHE_LINE_SIZE 32 |
361 | 377 | |
378 | +void do_check_reservation (void) | |
379 | +{ | |
380 | + if ((env->reserve & ~(ICACHE_LINE_SIZE - 1)) == T0) | |
381 | + env->reserve = -1; | |
382 | +} | |
383 | + | |
362 | 384 | void do_icbi (void) |
363 | 385 | { |
364 | 386 | /* Invalidate one cache line */ |
... | ... | @@ -377,6 +399,69 @@ void do_tlbie (void) |
377 | 399 | tlb_flush_page(env, T0); |
378 | 400 | } |
379 | 401 | |
402 | +void do_store_sr (uint32_t srnum) | |
403 | +{ | |
404 | +#if defined (DEBUG_OP) | |
405 | + dump_store_sr(srnum); | |
406 | +#endif | |
407 | +#if 0 // TRY | |
408 | + { | |
409 | + uint32_t base, page; | |
410 | + | |
411 | + base = srnum << 28; | |
412 | + for (page = base; page != base + 0x100000000; page += 0x1000) | |
413 | + tlb_flush_page(env, page); | |
414 | + } | |
415 | +#else | |
416 | + tlb_flush(env, 1); | |
417 | +#endif | |
418 | + env->sr[srnum] = T0; | |
419 | +} | |
420 | + | |
421 | +/* For BATs, we may not invalidate any TLBs if the change is only on | |
422 | + * protection bits for user mode. | |
423 | + */ | |
424 | +void do_store_ibat (int ul, int nr) | |
425 | +{ | |
426 | +#if defined (DEBUG_OP) | |
427 | + dump_store_ibat(ul, nr); | |
428 | +#endif | |
429 | +#if 0 // TRY | |
430 | + { | |
431 | + uint32_t base, length, page; | |
432 | + | |
433 | + base = env->IBAT[0][nr]; | |
434 | + length = (((base >> 2) & 0x000007FF) + 1) << 17; | |
435 | + base &= 0xFFFC0000; | |
436 | + for (page = base; page != base + length; page += 0x1000) | |
437 | + tlb_flush_page(env, page); | |
438 | + } | |
439 | +#else | |
440 | + tlb_flush(env, 1); | |
441 | +#endif | |
442 | + env->IBAT[ul][nr] = T0; | |
443 | +} | |
444 | + | |
445 | +void do_store_dbat (int ul, int nr) | |
446 | +{ | |
447 | +#if defined (DEBUG_OP) | |
448 | + dump_store_dbat(ul, nr); | |
449 | +#endif | |
450 | +#if 0 // TRY | |
451 | + { | |
452 | + uint32_t base, length, page; | |
453 | + base = env->DBAT[0][nr]; | |
454 | + length = (((base >> 2) & 0x000007FF) + 1) << 17; | |
455 | + base &= 0xFFFC0000; | |
456 | + for (page = base; page != base + length; page += 0x1000) | |
457 | + tlb_flush_page(env, page); | |
458 | + } | |
459 | +#else | |
460 | + tlb_flush(env, 1); | |
461 | +#endif | |
462 | + env->DBAT[ul][nr] = T0; | |
463 | +} | |
464 | + | |
380 | 465 | /*****************************************************************************/ |
381 | 466 | /* Special helpers for debug */ |
382 | 467 | extern FILE *stdout; |
... | ... | @@ -389,7 +474,7 @@ void dump_state (void) |
389 | 474 | void dump_rfi (void) |
390 | 475 | { |
391 | 476 | #if 0 |
392 | - printf("Return from interrupt %d => 0x%08x\n", pos, env->nip); | |
477 | + printf("Return from interrupt => 0x%08x\n", env->nip); | |
393 | 478 | // cpu_ppc_dump_state(env, stdout, 0); |
394 | 479 | #endif |
395 | 480 | } | ... | ... |
target-ppc/op_template.h
... | ... | @@ -175,10 +175,7 @@ void OPPROTO glue(op_load_sr, REG)(void) |
175 | 175 | |
176 | 176 | void OPPROTO glue(op_store_sr, REG)(void) |
177 | 177 | { |
178 | -#if defined (DEBUG_OP) | |
179 | - dump_store_sr(REG); | |
180 | -#endif | |
181 | - env->sr[REG] = T0; | |
178 | + do_store_sr(REG); | |
182 | 179 | RETURN(); |
183 | 180 | } |
184 | 181 | #endif | ... | ... |
target-ppc/translate.c
... | ... | @@ -28,8 +28,6 @@ |
28 | 28 | #include "disas.h" |
29 | 29 | |
30 | 30 | //#define DO_SINGLE_STEP |
31 | -//#define DO_STEP_FLUSH | |
32 | -//#define DEBUG_DISAS | |
33 | 31 | //#define PPC_DEBUG_DISAS |
34 | 32 | |
35 | 33 | enum { |
... | ... | @@ -639,7 +637,7 @@ GEN_HANDLER(xori, 0x1A, 0xFF, 0xFF, 0x00000000, PPC_INTEGER) |
639 | 637 | } |
640 | 638 | gen_op_load_gpr_T0(rS(ctx->opcode)); |
641 | 639 | if (uimm != 0) |
642 | - gen_op_xori(UIMM(ctx->opcode)); | |
640 | + gen_op_xori(uimm); | |
643 | 641 | gen_op_store_T0_gpr(rA(ctx->opcode)); |
644 | 642 | } |
645 | 643 | |
... | ... | @@ -654,7 +652,7 @@ GEN_HANDLER(xoris, 0x1B, 0xFF, 0xFF, 0x00000000, PPC_INTEGER) |
654 | 652 | } |
655 | 653 | gen_op_load_gpr_T0(rS(ctx->opcode)); |
656 | 654 | if (uimm != 0) |
657 | - gen_op_xori(UIMM(ctx->opcode) << 16); | |
655 | + gen_op_xori(uimm << 16); | |
658 | 656 | gen_op_store_T0_gpr(rA(ctx->opcode)); |
659 | 657 | } |
660 | 658 | |
... | ... | @@ -682,25 +680,29 @@ GEN_HANDLER(rlwinm, 0x15, 0xFF, 0xFF, 0x00000000, PPC_INTEGER) |
682 | 680 | mb = MB(ctx->opcode); |
683 | 681 | me = ME(ctx->opcode); |
684 | 682 | gen_op_load_gpr_T0(rS(ctx->opcode)); |
683 | +#if 1 // TRY | |
684 | + if (sh == 0) { | |
685 | + gen_op_andi_(MASK(mb, me)); | |
686 | + goto store; | |
687 | + } | |
688 | +#endif | |
685 | 689 | if (mb == 0) { |
686 | 690 | if (me == 31) { |
687 | 691 | gen_op_rotlwi(sh); |
688 | 692 | goto store; |
693 | +#if 0 | |
689 | 694 | } else if (me == (31 - sh)) { |
690 | 695 | gen_op_slwi(sh); |
691 | 696 | goto store; |
692 | - } else if (sh == 0) { | |
693 | - gen_op_andi_(MASK(0, me)); | |
694 | - goto store; | |
697 | +#endif | |
695 | 698 | } |
696 | 699 | } else if (me == 31) { |
700 | +#if 0 | |
697 | 701 | if (sh == (32 - mb)) { |
698 | 702 | gen_op_srwi(mb); |
699 | 703 | goto store; |
700 | - } else if (sh == 0) { | |
701 | - gen_op_andi_(MASK(mb, 31)); | |
702 | - goto store; | |
703 | 704 | } |
705 | +#endif | |
704 | 706 | } |
705 | 707 | gen_op_rlwinm(sh, MASK(mb, me)); |
706 | 708 | store: |
... | ... | @@ -1268,12 +1270,16 @@ GEN_HANDLER(lswx, 0x1F, 0x15, 0x10, 0x00000001, PPC_INTEGER) |
1268 | 1270 | /* stswi */ |
1269 | 1271 | GEN_HANDLER(stswi, 0x1F, 0x15, 0x16, 0x00000001, PPC_INTEGER) |
1270 | 1272 | { |
1273 | + int nb = NB(ctx->opcode); | |
1274 | + | |
1271 | 1275 | if (rA(ctx->opcode) == 0) { |
1272 | 1276 | gen_op_set_T0(0); |
1273 | 1277 | } else { |
1274 | 1278 | gen_op_load_gpr_T0(rA(ctx->opcode)); |
1275 | 1279 | } |
1276 | - gen_op_set_T1(NB(ctx->opcode)); | |
1280 | + if (nb == 0) | |
1281 | + nb = 32; | |
1282 | + gen_op_set_T1(nb); | |
1277 | 1283 | op_ldsts(stsw, rS(ctx->opcode)); |
1278 | 1284 | } |
1279 | 1285 | |
... | ... | @@ -1931,7 +1937,6 @@ GEN_HANDLER(mftb, 0x1F, 0x13, 0x0B, 0x00000001, PPC_MISC) |
1931 | 1937 | /* We need to update the time base before reading it */ |
1932 | 1938 | switch (sprn) { |
1933 | 1939 | case V_TBL: |
1934 | - /* TBL is still in T0 */ | |
1935 | 1940 | gen_op_load_tbl(); |
1936 | 1941 | break; |
1937 | 1942 | case V_TBU: |
... | ... | @@ -2007,135 +2012,135 @@ GEN_HANDLER(mtspr, 0x1F, 0x13, 0x0E, 0x00000001, PPC_MISC) |
2007 | 2012 | break; |
2008 | 2013 | case IBAT0U: |
2009 | 2014 | gen_op_store_ibat(0, 0); |
2010 | - gen_op_tlbia(); | |
2015 | + RET_MTMSR(ctx); | |
2011 | 2016 | break; |
2012 | 2017 | case IBAT1U: |
2013 | 2018 | gen_op_store_ibat(0, 1); |
2014 | - gen_op_tlbia(); | |
2019 | + RET_MTMSR(ctx); | |
2015 | 2020 | break; |
2016 | 2021 | case IBAT2U: |
2017 | 2022 | gen_op_store_ibat(0, 2); |
2018 | - gen_op_tlbia(); | |
2023 | + RET_MTMSR(ctx); | |
2019 | 2024 | break; |
2020 | 2025 | case IBAT3U: |
2021 | 2026 | gen_op_store_ibat(0, 3); |
2022 | - gen_op_tlbia(); | |
2027 | + RET_MTMSR(ctx); | |
2023 | 2028 | break; |
2024 | 2029 | case IBAT4U: |
2025 | 2030 | gen_op_store_ibat(0, 4); |
2026 | - gen_op_tlbia(); | |
2031 | + RET_MTMSR(ctx); | |
2027 | 2032 | break; |
2028 | 2033 | case IBAT5U: |
2029 | 2034 | gen_op_store_ibat(0, 5); |
2030 | - gen_op_tlbia(); | |
2035 | + RET_MTMSR(ctx); | |
2031 | 2036 | break; |
2032 | 2037 | case IBAT6U: |
2033 | 2038 | gen_op_store_ibat(0, 6); |
2034 | - gen_op_tlbia(); | |
2039 | + RET_MTMSR(ctx); | |
2035 | 2040 | break; |
2036 | 2041 | case IBAT7U: |
2037 | 2042 | gen_op_store_ibat(0, 7); |
2038 | - gen_op_tlbia(); | |
2043 | + RET_MTMSR(ctx); | |
2039 | 2044 | break; |
2040 | 2045 | case IBAT0L: |
2041 | 2046 | gen_op_store_ibat(1, 0); |
2042 | - gen_op_tlbia(); | |
2047 | + RET_MTMSR(ctx); | |
2043 | 2048 | break; |
2044 | 2049 | case IBAT1L: |
2045 | 2050 | gen_op_store_ibat(1, 1); |
2046 | - gen_op_tlbia(); | |
2051 | + RET_MTMSR(ctx); | |
2047 | 2052 | break; |
2048 | 2053 | case IBAT2L: |
2049 | 2054 | gen_op_store_ibat(1, 2); |
2050 | - gen_op_tlbia(); | |
2055 | + RET_MTMSR(ctx); | |
2051 | 2056 | break; |
2052 | 2057 | case IBAT3L: |
2053 | 2058 | gen_op_store_ibat(1, 3); |
2054 | - gen_op_tlbia(); | |
2059 | + RET_MTMSR(ctx); | |
2055 | 2060 | break; |
2056 | 2061 | case IBAT4L: |
2057 | 2062 | gen_op_store_ibat(1, 4); |
2058 | - gen_op_tlbia(); | |
2063 | + RET_MTMSR(ctx); | |
2059 | 2064 | break; |
2060 | 2065 | case IBAT5L: |
2061 | 2066 | gen_op_store_ibat(1, 5); |
2062 | - gen_op_tlbia(); | |
2067 | + RET_MTMSR(ctx); | |
2063 | 2068 | break; |
2064 | 2069 | case IBAT6L: |
2065 | 2070 | gen_op_store_ibat(1, 6); |
2066 | - gen_op_tlbia(); | |
2071 | + RET_MTMSR(ctx); | |
2067 | 2072 | break; |
2068 | 2073 | case IBAT7L: |
2069 | 2074 | gen_op_store_ibat(1, 7); |
2070 | - gen_op_tlbia(); | |
2075 | + RET_MTMSR(ctx); | |
2071 | 2076 | break; |
2072 | 2077 | case DBAT0U: |
2073 | 2078 | gen_op_store_dbat(0, 0); |
2074 | - gen_op_tlbia(); | |
2079 | + RET_MTMSR(ctx); | |
2075 | 2080 | break; |
2076 | 2081 | case DBAT1U: |
2077 | 2082 | gen_op_store_dbat(0, 1); |
2078 | - gen_op_tlbia(); | |
2083 | + RET_MTMSR(ctx); | |
2079 | 2084 | break; |
2080 | 2085 | case DBAT2U: |
2081 | 2086 | gen_op_store_dbat(0, 2); |
2082 | - gen_op_tlbia(); | |
2087 | + RET_MTMSR(ctx); | |
2083 | 2088 | break; |
2084 | 2089 | case DBAT3U: |
2085 | 2090 | gen_op_store_dbat(0, 3); |
2086 | - gen_op_tlbia(); | |
2091 | + RET_MTMSR(ctx); | |
2087 | 2092 | break; |
2088 | 2093 | case DBAT4U: |
2089 | 2094 | gen_op_store_dbat(0, 4); |
2090 | - gen_op_tlbia(); | |
2095 | + RET_MTMSR(ctx); | |
2091 | 2096 | break; |
2092 | 2097 | case DBAT5U: |
2093 | 2098 | gen_op_store_dbat(0, 5); |
2094 | - gen_op_tlbia(); | |
2099 | + RET_MTMSR(ctx); | |
2095 | 2100 | break; |
2096 | 2101 | case DBAT6U: |
2097 | 2102 | gen_op_store_dbat(0, 6); |
2098 | - gen_op_tlbia(); | |
2103 | + RET_MTMSR(ctx); | |
2099 | 2104 | break; |
2100 | 2105 | case DBAT7U: |
2101 | 2106 | gen_op_store_dbat(0, 7); |
2102 | - gen_op_tlbia(); | |
2107 | + RET_MTMSR(ctx); | |
2103 | 2108 | break; |
2104 | 2109 | case DBAT0L: |
2105 | 2110 | gen_op_store_dbat(1, 0); |
2106 | - gen_op_tlbia(); | |
2111 | + RET_MTMSR(ctx); | |
2107 | 2112 | break; |
2108 | 2113 | case DBAT1L: |
2109 | 2114 | gen_op_store_dbat(1, 1); |
2110 | - gen_op_tlbia(); | |
2115 | + RET_MTMSR(ctx); | |
2111 | 2116 | break; |
2112 | 2117 | case DBAT2L: |
2113 | 2118 | gen_op_store_dbat(1, 2); |
2114 | - gen_op_tlbia(); | |
2119 | + RET_MTMSR(ctx); | |
2115 | 2120 | break; |
2116 | 2121 | case DBAT3L: |
2117 | 2122 | gen_op_store_dbat(1, 3); |
2118 | - gen_op_tlbia(); | |
2123 | + RET_MTMSR(ctx); | |
2119 | 2124 | break; |
2120 | 2125 | case DBAT4L: |
2121 | 2126 | gen_op_store_dbat(1, 4); |
2122 | - gen_op_tlbia(); | |
2127 | + RET_MTMSR(ctx); | |
2123 | 2128 | break; |
2124 | 2129 | case DBAT5L: |
2125 | 2130 | gen_op_store_dbat(1, 5); |
2126 | - gen_op_tlbia(); | |
2131 | + RET_MTMSR(ctx); | |
2127 | 2132 | break; |
2128 | 2133 | case DBAT6L: |
2129 | 2134 | gen_op_store_dbat(1, 6); |
2130 | - gen_op_tlbia(); | |
2135 | + RET_MTMSR(ctx); | |
2131 | 2136 | break; |
2132 | 2137 | case DBAT7L: |
2133 | 2138 | gen_op_store_dbat(1, 7); |
2134 | - gen_op_tlbia(); | |
2139 | + RET_MTMSR(ctx); | |
2135 | 2140 | break; |
2136 | 2141 | case SDR1: |
2137 | 2142 | gen_op_store_sdr1(); |
2138 | - gen_op_tlbia(); | |
2143 | + RET_MTMSR(ctx); | |
2139 | 2144 | break; |
2140 | 2145 | case O_TBL: |
2141 | 2146 | gen_op_store_tbl(); |
... | ... | @@ -2146,6 +2151,11 @@ GEN_HANDLER(mtspr, 0x1F, 0x13, 0x0E, 0x00000001, PPC_MISC) |
2146 | 2151 | case DECR: |
2147 | 2152 | gen_op_store_decr(); |
2148 | 2153 | break; |
2154 | +#if 0 | |
2155 | + case HID0: | |
2156 | + gen_op_store_hid0(); | |
2157 | + break; | |
2158 | +#endif | |
2149 | 2159 | default: |
2150 | 2160 | gen_op_store_spr(sprn); |
2151 | 2161 | break; |
... | ... | @@ -2236,6 +2246,7 @@ GEN_HANDLER(dcbz, 0x1F, 0x16, 0x1F, 0x03E00001, PPC_CACHE) |
2236 | 2246 | gen_op_add(); |
2237 | 2247 | } |
2238 | 2248 | op_dcbz(); |
2249 | + gen_op_check_reservation(); | |
2239 | 2250 | } |
2240 | 2251 | |
2241 | 2252 | /* icbi */ |
... | ... | @@ -2302,10 +2313,6 @@ GEN_HANDLER(mtsr, 0x1F, 0x12, 0x06, 0x0010F801, PPC_SEGMENT) |
2302 | 2313 | } |
2303 | 2314 | gen_op_load_gpr_T0(rS(ctx->opcode)); |
2304 | 2315 | gen_op_store_sr(SR(ctx->opcode)); |
2305 | -#if 0 | |
2306 | - gen_op_tlbia(); | |
2307 | - RET_MTMSR(ctx); | |
2308 | -#endif | |
2309 | 2316 | #endif |
2310 | 2317 | } |
2311 | 2318 | |
... | ... | @@ -2322,7 +2329,6 @@ GEN_HANDLER(mtsrin, 0x1F, 0x12, 0x07, 0x001F0001, PPC_SEGMENT) |
2322 | 2329 | gen_op_load_gpr_T0(rS(ctx->opcode)); |
2323 | 2330 | gen_op_load_gpr_T1(rB(ctx->opcode)); |
2324 | 2331 | gen_op_store_srin(); |
2325 | - gen_op_tlbia(); | |
2326 | 2332 | #endif |
2327 | 2333 | } |
2328 | 2334 | |
... | ... | @@ -2341,6 +2347,7 @@ GEN_HANDLER(tlbia, 0x1F, 0x12, 0x0B, 0x03FFFC01, PPC_MEM_OPT) |
2341 | 2347 | return; |
2342 | 2348 | } |
2343 | 2349 | gen_op_tlbia(); |
2350 | + RET_MTMSR(ctx); | |
2344 | 2351 | #endif |
2345 | 2352 | } |
2346 | 2353 | |
... | ... | @@ -2356,6 +2363,7 @@ GEN_HANDLER(tlbie, 0x1F, 0x12, 0x09, 0x03FF0001, PPC_MEM) |
2356 | 2363 | } |
2357 | 2364 | gen_op_load_gpr_T0(rB(ctx->opcode)); |
2358 | 2365 | gen_op_tlbie(); |
2366 | + RET_MTMSR(ctx); | |
2359 | 2367 | #endif |
2360 | 2368 | } |
2361 | 2369 | |
... | ... | @@ -2372,6 +2380,7 @@ GEN_HANDLER(tlbsync, 0x1F, 0x16, 0x11, 0x03FFF801, PPC_MEM) |
2372 | 2380 | /* This has no effect: it should ensure that all previous |
2373 | 2381 | * tlbie have completed |
2374 | 2382 | */ |
2383 | + RET_MTMSR(ctx); | |
2375 | 2384 | #endif |
2376 | 2385 | } |
2377 | 2386 | |
... | ... | @@ -2692,59 +2701,78 @@ static void init_spr_rights (uint32_t pvr) |
2692 | 2701 | spr_set_rights(DBAT3U, SPR_SR | SPR_SW); |
2693 | 2702 | /* DBAT3L (SPR 543) */ |
2694 | 2703 | spr_set_rights(DBAT3L, SPR_SR | SPR_SW); |
2695 | - /* DABR (SPR 1013) */ | |
2696 | - spr_set_rights(DABR, SPR_SR | SPR_SW); | |
2697 | 2704 | /* FPECR (SPR 1022) */ |
2698 | 2705 | spr_set_rights(FPECR, SPR_SR | SPR_SW); |
2699 | - /* PIR (SPR 1023) */ | |
2706 | + /* Special registers for PPC 604 */ | |
2707 | + if ((pvr & 0xFFFF0000) == 0x00040000) { | |
2708 | + /* IABR */ | |
2709 | + spr_set_rights(IABR , SPR_SR | SPR_SW); | |
2710 | + /* DABR (SPR 1013) */ | |
2711 | + spr_set_rights(DABR, SPR_SR | SPR_SW); | |
2712 | + /* HID0 */ | |
2713 | + spr_set_rights(HID0, SPR_SR | SPR_SW); | |
2714 | + /* PIR */ | |
2700 | 2715 | spr_set_rights(PIR, SPR_SR | SPR_SW); |
2716 | + /* PMC1 */ | |
2717 | + spr_set_rights(PMC1, SPR_SR | SPR_SW); | |
2718 | + /* PMC2 */ | |
2719 | + spr_set_rights(PMC2, SPR_SR | SPR_SW); | |
2720 | + /* MMCR0 */ | |
2721 | + spr_set_rights(MMCR0, SPR_SR | SPR_SW); | |
2722 | + /* SIA */ | |
2723 | + spr_set_rights(SIA, SPR_SR | SPR_SW); | |
2724 | + /* SDA */ | |
2725 | + spr_set_rights(SDA, SPR_SR | SPR_SW); | |
2726 | + } | |
2701 | 2727 | /* Special registers for MPC740/745/750/755 (aka G3) & IBM 750 */ |
2702 | 2728 | if ((pvr & 0xFFFF0000) == 0x00080000 || |
2703 | 2729 | (pvr & 0xFFFF0000) == 0x70000000) { |
2704 | 2730 | /* HID0 */ |
2705 | - spr_set_rights(SPR_ENCODE(1008), SPR_SR | SPR_SW); | |
2731 | + spr_set_rights(HID0, SPR_SR | SPR_SW); | |
2706 | 2732 | /* HID1 */ |
2707 | - spr_set_rights(SPR_ENCODE(1009), SPR_SR | SPR_SW); | |
2733 | + spr_set_rights(HID1, SPR_SR | SPR_SW); | |
2708 | 2734 | /* IABR */ |
2709 | - spr_set_rights(SPR_ENCODE(1010), SPR_SR | SPR_SW); | |
2735 | + spr_set_rights(IABR, SPR_SR | SPR_SW); | |
2710 | 2736 | /* ICTC */ |
2711 | - spr_set_rights(SPR_ENCODE(1019), SPR_SR | SPR_SW); | |
2737 | + spr_set_rights(ICTC, SPR_SR | SPR_SW); | |
2712 | 2738 | /* L2CR */ |
2713 | - spr_set_rights(SPR_ENCODE(1017), SPR_SR | SPR_SW); | |
2739 | + spr_set_rights(L2CR, SPR_SR | SPR_SW); | |
2714 | 2740 | /* MMCR0 */ |
2715 | - spr_set_rights(SPR_ENCODE(952), SPR_SR | SPR_SW); | |
2741 | + spr_set_rights(MMCR0, SPR_SR | SPR_SW); | |
2716 | 2742 | /* MMCR1 */ |
2717 | - spr_set_rights(SPR_ENCODE(956), SPR_SR | SPR_SW); | |
2743 | + spr_set_rights(MMCR1, SPR_SR | SPR_SW); | |
2718 | 2744 | /* PMC1 */ |
2719 | - spr_set_rights(SPR_ENCODE(953), SPR_SR | SPR_SW); | |
2745 | + spr_set_rights(PMC1, SPR_SR | SPR_SW); | |
2720 | 2746 | /* PMC2 */ |
2721 | - spr_set_rights(SPR_ENCODE(954), SPR_SR | SPR_SW); | |
2747 | + spr_set_rights(PMC2, SPR_SR | SPR_SW); | |
2722 | 2748 | /* PMC3 */ |
2723 | - spr_set_rights(SPR_ENCODE(957), SPR_SR | SPR_SW); | |
2749 | + spr_set_rights(PMC3, SPR_SR | SPR_SW); | |
2724 | 2750 | /* PMC4 */ |
2725 | - spr_set_rights(SPR_ENCODE(958), SPR_SR | SPR_SW); | |
2751 | + spr_set_rights(PMC4, SPR_SR | SPR_SW); | |
2726 | 2752 | /* SIA */ |
2727 | - spr_set_rights(SPR_ENCODE(955), SPR_SR | SPR_SW); | |
2753 | + spr_set_rights(SIA, SPR_SR | SPR_SW); | |
2754 | + /* SDA */ | |
2755 | + spr_set_rights(SDA, SPR_SR | SPR_SW); | |
2728 | 2756 | /* THRM1 */ |
2729 | - spr_set_rights(SPR_ENCODE(1020), SPR_SR | SPR_SW); | |
2757 | + spr_set_rights(THRM1, SPR_SR | SPR_SW); | |
2730 | 2758 | /* THRM2 */ |
2731 | - spr_set_rights(SPR_ENCODE(1021), SPR_SR | SPR_SW); | |
2759 | + spr_set_rights(THRM2, SPR_SR | SPR_SW); | |
2732 | 2760 | /* THRM3 */ |
2733 | - spr_set_rights(SPR_ENCODE(1022), SPR_SR | SPR_SW); | |
2761 | + spr_set_rights(THRM3, SPR_SR | SPR_SW); | |
2734 | 2762 | /* UMMCR0 */ |
2735 | - spr_set_rights(SPR_ENCODE(936), SPR_UR | SPR_UW); | |
2763 | + spr_set_rights(UMMCR0, SPR_UR | SPR_UW); | |
2736 | 2764 | /* UMMCR1 */ |
2737 | - spr_set_rights(SPR_ENCODE(940), SPR_UR | SPR_UW); | |
2765 | + spr_set_rights(UMMCR1, SPR_UR | SPR_UW); | |
2738 | 2766 | /* UPMC1 */ |
2739 | - spr_set_rights(SPR_ENCODE(937), SPR_UR | SPR_UW); | |
2767 | + spr_set_rights(UPMC1, SPR_UR | SPR_UW); | |
2740 | 2768 | /* UPMC2 */ |
2741 | - spr_set_rights(SPR_ENCODE(938), SPR_UR | SPR_UW); | |
2769 | + spr_set_rights(UPMC2, SPR_UR | SPR_UW); | |
2742 | 2770 | /* UPMC3 */ |
2743 | - spr_set_rights(SPR_ENCODE(941), SPR_UR | SPR_UW); | |
2771 | + spr_set_rights(UPMC3, SPR_UR | SPR_UW); | |
2744 | 2772 | /* UPMC4 */ |
2745 | - spr_set_rights(SPR_ENCODE(942), SPR_UR | SPR_UW); | |
2773 | + spr_set_rights(UPMC4, SPR_UR | SPR_UW); | |
2746 | 2774 | /* USIA */ |
2747 | - spr_set_rights(SPR_ENCODE(939), SPR_UR | SPR_UW); | |
2775 | + spr_set_rights(USIA, SPR_UR | SPR_UW); | |
2748 | 2776 | } |
2749 | 2777 | /* MPC755 has special registers */ |
2750 | 2778 | if (pvr == 0x00083100) { |
... | ... | @@ -2789,23 +2817,23 @@ static void init_spr_rights (uint32_t pvr) |
2789 | 2817 | /* DBAT7L */ |
2790 | 2818 | spr_set_rights(DBAT7L, SPR_SR | SPR_SW); |
2791 | 2819 | /* DMISS */ |
2792 | - spr_set_rights(SPR_ENCODE(976), SPR_SR | SPR_SW); | |
2820 | + spr_set_rights(DMISS, SPR_SR | SPR_SW); | |
2793 | 2821 | /* DCMP */ |
2794 | - spr_set_rights(SPR_ENCODE(977), SPR_SR | SPR_SW); | |
2822 | + spr_set_rights(DCMP, SPR_SR | SPR_SW); | |
2795 | 2823 | /* DHASH1 */ |
2796 | - spr_set_rights(SPR_ENCODE(978), SPR_SR | SPR_SW); | |
2824 | + spr_set_rights(DHASH1, SPR_SR | SPR_SW); | |
2797 | 2825 | /* DHASH2 */ |
2798 | - spr_set_rights(SPR_ENCODE(979), SPR_SR | SPR_SW); | |
2826 | + spr_set_rights(DHASH2, SPR_SR | SPR_SW); | |
2799 | 2827 | /* IMISS */ |
2800 | - spr_set_rights(SPR_ENCODE(980), SPR_SR | SPR_SW); | |
2828 | + spr_set_rights(IMISS, SPR_SR | SPR_SW); | |
2801 | 2829 | /* ICMP */ |
2802 | - spr_set_rights(SPR_ENCODE(981), SPR_SR | SPR_SW); | |
2830 | + spr_set_rights(ICMP, SPR_SR | SPR_SW); | |
2803 | 2831 | /* RPA */ |
2804 | - spr_set_rights(SPR_ENCODE(982), SPR_SR | SPR_SW); | |
2832 | + spr_set_rights(RPA, SPR_SR | SPR_SW); | |
2805 | 2833 | /* HID2 */ |
2806 | - spr_set_rights(SPR_ENCODE(1011), SPR_SR | SPR_SW); | |
2834 | + spr_set_rights(HID2, SPR_SR | SPR_SW); | |
2807 | 2835 | /* L2PM */ |
2808 | - spr_set_rights(SPR_ENCODE(1016), SPR_SR | SPR_SW); | |
2836 | + spr_set_rights(L2PM, SPR_SR | SPR_SW); | |
2809 | 2837 | } |
2810 | 2838 | } |
2811 | 2839 | |
... | ... | @@ -2941,10 +2969,9 @@ CPUPPCState *cpu_ppc_init(void) |
2941 | 2969 | |
2942 | 2970 | cpu_exec_init(); |
2943 | 2971 | |
2944 | - env = malloc(sizeof(CPUPPCState)); | |
2972 | + env = qemu_mallocz(sizeof(CPUPPCState)); | |
2945 | 2973 | if (!env) |
2946 | 2974 | return NULL; |
2947 | - memset(env, 0, sizeof(CPUPPCState)); | |
2948 | 2975 | #if !defined(CONFIG_USER_ONLY) && defined (USE_OPEN_FIRMWARE) |
2949 | 2976 | setup_machine(env, 0); |
2950 | 2977 | #else |
... | ... | @@ -2953,22 +2980,34 @@ CPUPPCState *cpu_ppc_init(void) |
2953 | 2980 | // env->spr[PVR] = 0x00083100; /* MPC755 (G3 embedded) */ |
2954 | 2981 | // env->spr[PVR] = 0x00070100; /* IBM 750FX */ |
2955 | 2982 | #endif |
2956 | - if (create_ppc_proc(ppc_opcodes, env->spr[PVR]) < 0) | |
2957 | - return NULL; | |
2958 | - init_spr_rights(env->spr[PVR]); | |
2959 | 2983 | tlb_flush(env, 1); |
2960 | 2984 | #if defined (DO_SINGLE_STEP) |
2961 | 2985 | /* Single step trace mode */ |
2962 | 2986 | msr_se = 1; |
2963 | 2987 | #endif |
2988 | + msr_fp = 1; /* Allow floating point exceptions */ | |
2989 | + msr_me = 1; /* Allow machine check exceptions */ | |
2964 | 2990 | #if defined(CONFIG_USER_ONLY) |
2965 | 2991 | msr_pr = 1; |
2992 | + cpu_ppc_register(env, 0x00080000); | |
2993 | +#else | |
2994 | + env->nip = 0xFFFFFFFC; | |
2966 | 2995 | #endif |
2967 | 2996 | env->access_type = ACCESS_INT; |
2968 | 2997 | |
2969 | 2998 | return env; |
2970 | 2999 | } |
2971 | 3000 | |
3001 | +int cpu_ppc_register (CPUPPCState *env, uint32_t pvr) | |
3002 | +{ | |
3003 | + env->spr[PVR] = pvr; | |
3004 | + if (create_ppc_proc(ppc_opcodes, env->spr[PVR]) < 0) | |
3005 | + return -1; | |
3006 | + init_spr_rights(env->spr[PVR]); | |
3007 | + | |
3008 | + return 0; | |
3009 | +} | |
3010 | + | |
2972 | 3011 | void cpu_ppc_close(CPUPPCState *env) |
2973 | 3012 | { |
2974 | 3013 | /* Should also remove all opcode tables... */ |
... | ... | @@ -3047,26 +3086,26 @@ int gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb, |
3047 | 3086 | } |
3048 | 3087 | } |
3049 | 3088 | /* Is opcode *REALLY* valid ? */ |
3050 | - if ((ctx.opcode & handler->inval) != 0) { | |
3051 | - if (loglevel > 0) { | |
3052 | 3089 | if (handler->handler == &gen_invalid) { |
3090 | + if (loglevel > 0) { | |
3053 | 3091 | fprintf(logfile, "invalid/unsupported opcode: " |
3054 | - "%02x -%02x - %02x (%08x) 0x%08x\n", | |
3092 | + "%02x - %02x - %02x (%08x) 0x%08x %d\n", | |
3055 | 3093 | opc1(ctx.opcode), opc2(ctx.opcode), |
3056 | - opc3(ctx.opcode), ctx.opcode, ctx.nip - 4); | |
3094 | + opc3(ctx.opcode), ctx.opcode, ctx.nip - 4, msr_ir); | |
3095 | + } else { | |
3096 | + printf("invalid/unsupported opcode: " | |
3097 | + "%02x - %02x - %02x (%08x) 0x%08x %d\n", | |
3098 | + opc1(ctx.opcode), opc2(ctx.opcode), | |
3099 | + opc3(ctx.opcode), ctx.opcode, ctx.nip - 4, msr_ir); | |
3100 | + } | |
3057 | 3101 | } else { |
3102 | + if ((ctx.opcode & handler->inval) != 0) { | |
3103 | + if (loglevel > 0) { | |
3058 | 3104 | fprintf(logfile, "invalid bits: %08x for opcode: " |
3059 | 3105 | "%02x -%02x - %02x (0x%08x) (0x%08x)\n", |
3060 | 3106 | ctx.opcode & handler->inval, opc1(ctx.opcode), |
3061 | 3107 | opc2(ctx.opcode), opc3(ctx.opcode), |
3062 | 3108 | ctx.opcode, ctx.nip - 4); |
3063 | - } | |
3064 | - } else { | |
3065 | - if (handler->handler == &gen_invalid) { | |
3066 | - printf("invalid/unsupported opcode: " | |
3067 | - "%02x -%02x - %02x (%08x) 0x%08x\n", | |
3068 | - opc1(ctx.opcode), opc2(ctx.opcode), | |
3069 | - opc3(ctx.opcode), ctx.opcode, ctx.nip - 4); | |
3070 | 3109 | } else { |
3071 | 3110 | printf("invalid bits: %08x for opcode: " |
3072 | 3111 | "%02x -%02x - %02x (0x%08x) (0x%08x)\n", |
... | ... | @@ -3074,11 +3113,11 @@ int gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb, |
3074 | 3113 | opc2(ctx.opcode), opc3(ctx.opcode), |
3075 | 3114 | ctx.opcode, ctx.nip - 4); |
3076 | 3115 | } |
3116 | + RET_INVAL(ctxp); | |
3117 | + break; | |
3077 | 3118 | } |
3078 | - (*gen_invalid)(&ctx); | |
3079 | - } else { | |
3080 | - (*(handler->handler))(&ctx); | |
3081 | 3119 | } |
3120 | + (*(handler->handler))(&ctx); | |
3082 | 3121 | /* Check trace mode exceptions */ |
3083 | 3122 | if ((msr_be && ctx.exception == EXCP_BRANCH) || |
3084 | 3123 | /* Check in single step trace mode |
... | ... | @@ -3126,7 +3165,6 @@ int gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb, |
3126 | 3165 | } else { |
3127 | 3166 | tb->size = ctx.nip - pc_start; |
3128 | 3167 | } |
3129 | - env->access_type = ACCESS_INT; | |
3130 | 3168 | #ifdef DEBUG_DISAS |
3131 | 3169 | if (loglevel & CPU_LOG_TB_CPU) { |
3132 | 3170 | fprintf(logfile, "---------------- excp: %04x\n", ctx.exception); |
... | ... | @@ -3143,6 +3181,7 @@ int gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb, |
3143 | 3181 | fprintf(logfile, "\n"); |
3144 | 3182 | } |
3145 | 3183 | #endif |
3184 | + env->access_type = ACCESS_INT; | |
3146 | 3185 | |
3147 | 3186 | return 0; |
3148 | 3187 | } | ... | ... |