Commit d4218d996d2274f4136b8bd22e946bf56f050c9e
1 parent
fcc72045
Fix Sparc lda/ldda/sta/stda asi handling, fault on misaligned register ldd/std a…
…nd illegal cwp on wrpsr (Aurelien Jarno) git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2568 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
3 changed files
with
40 additions
and
2 deletions
target-sparc/cpu.h
... | ... | @@ -269,7 +269,7 @@ void cpu_set_cwp(CPUSPARCState *env1, int new_cwp); |
269 | 269 | env->psrs = (_tmp & PSR_S)? 1 : 0; \ |
270 | 270 | env->psrps = (_tmp & PSR_PS)? 1 : 0; \ |
271 | 271 | env->psret = (_tmp & PSR_ET)? 1 : 0; \ |
272 | - cpu_set_cwp(env, _tmp & PSR_CWP & (NWINDOWS - 1)); \ | |
272 | + cpu_set_cwp(env, _tmp & PSR_CWP); \ | |
273 | 273 | } while (0) |
274 | 274 | |
275 | 275 | #ifdef TARGET_SPARC64 | ... | ... |
target-sparc/op_helper.c
... | ... | @@ -615,6 +615,9 @@ void helper_rett() |
615 | 615 | { |
616 | 616 | unsigned int cwp; |
617 | 617 | |
618 | + if (env->psret == 1) | |
619 | + raise_exception(TT_ILL_INSN); | |
620 | + | |
618 | 621 | env->psret = 1; |
619 | 622 | cwp = (env->cwp + 1) & (NWINDOWS - 1); |
620 | 623 | if (env->wim & (1 << cwp)) { |
... | ... | @@ -655,7 +658,10 @@ void helper_debug() |
655 | 658 | #ifndef TARGET_SPARC64 |
656 | 659 | void do_wrpsr() |
657 | 660 | { |
658 | - PUT_PSR(env, T0); | |
661 | + if ((T0 & PSR_CWP) >= NWINDOWS) | |
662 | + raise_exception(TT_ILL_INSN); | |
663 | + else | |
664 | + PUT_PSR(env, T0); | |
659 | 665 | } |
660 | 666 | |
661 | 667 | void do_rdpsr() | ... | ... |
target-sparc/translate.c
... | ... | @@ -2341,6 +2341,8 @@ static void disas_sparc_insn(DisasContext * dc) |
2341 | 2341 | gen_op_ldst(lduh); |
2342 | 2342 | break; |
2343 | 2343 | case 0x3: /* load double word */ |
2344 | + if (rd & 1) | |
2345 | + goto illegal_insn; | |
2344 | 2346 | gen_op_ldst(ldd); |
2345 | 2347 | gen_movl_T0_reg(rd + 1); |
2346 | 2348 | break; |
... | ... | @@ -2360,6 +2362,8 @@ static void disas_sparc_insn(DisasContext * dc) |
2360 | 2362 | #if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64) |
2361 | 2363 | case 0x10: /* load word alternate */ |
2362 | 2364 | #ifndef TARGET_SPARC64 |
2365 | + if (IS_IMM) | |
2366 | + goto illegal_insn; | |
2363 | 2367 | if (!supervisor(dc)) |
2364 | 2368 | goto priv_insn; |
2365 | 2369 | #endif |
... | ... | @@ -2367,6 +2371,8 @@ static void disas_sparc_insn(DisasContext * dc) |
2367 | 2371 | break; |
2368 | 2372 | case 0x11: /* load unsigned byte alternate */ |
2369 | 2373 | #ifndef TARGET_SPARC64 |
2374 | + if (IS_IMM) | |
2375 | + goto illegal_insn; | |
2370 | 2376 | if (!supervisor(dc)) |
2371 | 2377 | goto priv_insn; |
2372 | 2378 | #endif |
... | ... | @@ -2374,6 +2380,8 @@ static void disas_sparc_insn(DisasContext * dc) |
2374 | 2380 | break; |
2375 | 2381 | case 0x12: /* load unsigned halfword alternate */ |
2376 | 2382 | #ifndef TARGET_SPARC64 |
2383 | + if (IS_IMM) | |
2384 | + goto illegal_insn; | |
2377 | 2385 | if (!supervisor(dc)) |
2378 | 2386 | goto priv_insn; |
2379 | 2387 | #endif |
... | ... | @@ -2381,14 +2389,20 @@ static void disas_sparc_insn(DisasContext * dc) |
2381 | 2389 | break; |
2382 | 2390 | case 0x13: /* load double word alternate */ |
2383 | 2391 | #ifndef TARGET_SPARC64 |
2392 | + if (IS_IMM) | |
2393 | + goto illegal_insn; | |
2384 | 2394 | if (!supervisor(dc)) |
2385 | 2395 | goto priv_insn; |
2386 | 2396 | #endif |
2397 | + if (rd & 1) | |
2398 | + goto illegal_insn; | |
2387 | 2399 | gen_op_ldda(insn, 1, 8, 0); |
2388 | 2400 | gen_movl_T0_reg(rd + 1); |
2389 | 2401 | break; |
2390 | 2402 | case 0x19: /* load signed byte alternate */ |
2391 | 2403 | #ifndef TARGET_SPARC64 |
2404 | + if (IS_IMM) | |
2405 | + goto illegal_insn; | |
2392 | 2406 | if (!supervisor(dc)) |
2393 | 2407 | goto priv_insn; |
2394 | 2408 | #endif |
... | ... | @@ -2396,6 +2410,8 @@ static void disas_sparc_insn(DisasContext * dc) |
2396 | 2410 | break; |
2397 | 2411 | case 0x1a: /* load signed halfword alternate */ |
2398 | 2412 | #ifndef TARGET_SPARC64 |
2413 | + if (IS_IMM) | |
2414 | + goto illegal_insn; | |
2399 | 2415 | if (!supervisor(dc)) |
2400 | 2416 | goto priv_insn; |
2401 | 2417 | #endif |
... | ... | @@ -2403,6 +2419,8 @@ static void disas_sparc_insn(DisasContext * dc) |
2403 | 2419 | break; |
2404 | 2420 | case 0x1d: /* ldstuba -- XXX: should be atomically */ |
2405 | 2421 | #ifndef TARGET_SPARC64 |
2422 | + if (IS_IMM) | |
2423 | + goto illegal_insn; | |
2406 | 2424 | if (!supervisor(dc)) |
2407 | 2425 | goto priv_insn; |
2408 | 2426 | #endif |
... | ... | @@ -2410,6 +2428,8 @@ static void disas_sparc_insn(DisasContext * dc) |
2410 | 2428 | break; |
2411 | 2429 | case 0x1f: /* swap reg with alt. memory. Also atomically */ |
2412 | 2430 | #ifndef TARGET_SPARC64 |
2431 | + if (IS_IMM) | |
2432 | + goto illegal_insn; | |
2413 | 2433 | if (!supervisor(dc)) |
2414 | 2434 | goto priv_insn; |
2415 | 2435 | #endif |
... | ... | @@ -2508,6 +2528,8 @@ static void disas_sparc_insn(DisasContext * dc) |
2508 | 2528 | gen_op_ldst(sth); |
2509 | 2529 | break; |
2510 | 2530 | case 0x7: |
2531 | + if (rd & 1) | |
2532 | + goto illegal_insn; | |
2511 | 2533 | flush_T2(dc); |
2512 | 2534 | gen_movl_reg_T2(rd + 1); |
2513 | 2535 | gen_op_ldst(std); |
... | ... | @@ -2515,6 +2537,8 @@ static void disas_sparc_insn(DisasContext * dc) |
2515 | 2537 | #if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64) |
2516 | 2538 | case 0x14: |
2517 | 2539 | #ifndef TARGET_SPARC64 |
2540 | + if (IS_IMM) | |
2541 | + goto illegal_insn; | |
2518 | 2542 | if (!supervisor(dc)) |
2519 | 2543 | goto priv_insn; |
2520 | 2544 | #endif |
... | ... | @@ -2522,6 +2546,8 @@ static void disas_sparc_insn(DisasContext * dc) |
2522 | 2546 | break; |
2523 | 2547 | case 0x15: |
2524 | 2548 | #ifndef TARGET_SPARC64 |
2549 | + if (IS_IMM) | |
2550 | + goto illegal_insn; | |
2525 | 2551 | if (!supervisor(dc)) |
2526 | 2552 | goto priv_insn; |
2527 | 2553 | #endif |
... | ... | @@ -2529,6 +2555,8 @@ static void disas_sparc_insn(DisasContext * dc) |
2529 | 2555 | break; |
2530 | 2556 | case 0x16: |
2531 | 2557 | #ifndef TARGET_SPARC64 |
2558 | + if (IS_IMM) | |
2559 | + goto illegal_insn; | |
2532 | 2560 | if (!supervisor(dc)) |
2533 | 2561 | goto priv_insn; |
2534 | 2562 | #endif |
... | ... | @@ -2536,9 +2564,13 @@ static void disas_sparc_insn(DisasContext * dc) |
2536 | 2564 | break; |
2537 | 2565 | case 0x17: |
2538 | 2566 | #ifndef TARGET_SPARC64 |
2567 | + if (IS_IMM) | |
2568 | + goto illegal_insn; | |
2539 | 2569 | if (!supervisor(dc)) |
2540 | 2570 | goto priv_insn; |
2541 | 2571 | #endif |
2572 | + if (rd & 1) | |
2573 | + goto illegal_insn; | |
2542 | 2574 | flush_T2(dc); |
2543 | 2575 | gen_movl_reg_T2(rd + 1); |
2544 | 2576 | gen_op_stda(insn, 0, 8, 0); | ... | ... |