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