Commit d4218d996d2274f4136b8bd22e946bf56f050c9e

Authored by blueswir1
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
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);
... ...