@@ -305,16 +305,21 @@ static void gen_left_shift_sar(DisasContext *dc, TCGv_i32 sa)
305
305
tcg_temp_free (tmp );
306
306
}
307
307
308
- static void gen_advance_ccount (DisasContext * dc )
308
+ static void gen_advance_ccount_cond (DisasContext * dc )
309
309
{
310
310
if (dc -> ccount_delta > 0 ) {
311
311
TCGv_i32 tmp = tcg_const_i32 (dc -> ccount_delta );
312
- dc -> ccount_delta = 0 ;
313
312
gen_helper_advance_ccount (cpu_env , tmp );
314
313
tcg_temp_free (tmp );
315
314
}
316
315
}
317
316
317
+ static void gen_advance_ccount (DisasContext * dc )
318
+ {
319
+ gen_advance_ccount_cond (dc );
320
+ dc -> ccount_delta = 0 ;
321
+ }
322
+
318
323
static void reset_used_window (DisasContext * dc )
319
324
{
320
325
dc -> used_window = 0 ;
@@ -491,7 +496,7 @@ static void gen_brcondi(DisasContext *dc, TCGCond cond,
491
496
tcg_temp_free (tmp );
492
497
}
493
498
494
- static void gen_check_sr (DisasContext * dc , uint32_t sr , unsigned access )
499
+ static bool gen_check_sr (DisasContext * dc , uint32_t sr , unsigned access )
495
500
{
496
501
if (!xtensa_option_bits_enabled (dc -> config , sregnames [sr ].opt_bits )) {
497
502
if (sregnames [sr ].name ) {
@@ -500,6 +505,7 @@ static void gen_check_sr(DisasContext *dc, uint32_t sr, unsigned access)
500
505
qemu_log ("SR %d is not implemented\n" , sr );
501
506
}
502
507
gen_exception_cause (dc , ILLEGAL_INSTRUCTION_CAUSE );
508
+ return false;
503
509
} else if (!(sregnames [sr ].access & access )) {
504
510
static const char * const access_text [] = {
505
511
[SR_R ] = "rsr" ,
@@ -510,7 +516,9 @@ static void gen_check_sr(DisasContext *dc, uint32_t sr, unsigned access)
510
516
qemu_log ("SR %s is not available for %s\n" , sregnames [sr ].name ,
511
517
access_text [access ]);
512
518
gen_exception_cause (dc , ILLEGAL_INSTRUCTION_CAUSE );
519
+ return false;
513
520
}
521
+ return true;
514
522
}
515
523
516
524
static void gen_rsr_ccount (DisasContext * dc , TCGv_i32 d , uint32_t sr )
@@ -826,15 +834,27 @@ static void gen_window_check1(DisasContext *dc, unsigned r1)
826
834
}
827
835
if (option_enabled (dc , XTENSA_OPTION_WINDOWED_REGISTER ) &&
828
836
r1 / 4 > dc -> used_window ) {
829
- TCGv_i32 pc = tcg_const_i32 ( dc -> pc );
830
- TCGv_i32 w = tcg_const_i32 ( r1 / 4 );
837
+ int label = gen_new_label ( );
838
+ TCGv_i32 ws = tcg_temp_new_i32 ( );
831
839
832
840
dc -> used_window = r1 / 4 ;
833
- gen_advance_ccount (dc );
834
- gen_helper_window_check (cpu_env , pc , w );
841
+ tcg_gen_deposit_i32 (ws , cpu_SR [WINDOW_START ], cpu_SR [WINDOW_START ],
842
+ dc -> config -> nareg / 4 , dc -> config -> nareg / 4 );
843
+ tcg_gen_shr_i32 (ws , ws , cpu_SR [WINDOW_BASE ]);
844
+ tcg_gen_andi_i32 (ws , ws , (2 << (r1 / 4 )) - 2 );
845
+ tcg_gen_brcondi_i32 (TCG_COND_EQ , ws , 0 , label );
846
+ {
847
+ TCGv_i32 pc = tcg_const_i32 (dc -> pc );
848
+ TCGv_i32 w = tcg_const_i32 (r1 / 4 );
849
+
850
+ gen_advance_ccount_cond (dc );
851
+ gen_helper_window_check (cpu_env , pc , w );
835
852
836
- tcg_temp_free (w );
837
- tcg_temp_free (pc );
853
+ tcg_temp_free (w );
854
+ tcg_temp_free (pc );
855
+ }
856
+ gen_set_label (label );
857
+ tcg_temp_free (ws );
838
858
}
839
859
}
840
860
@@ -1482,9 +1502,9 @@ static void disas_xtensa_insn(CPUXtensaState *env, DisasContext *dc)
1482
1502
break ;
1483
1503
1484
1504
case 6 : /*XSR*/
1485
- {
1505
+ if ( gen_check_sr ( dc , RSR_SR , SR_X )) {
1486
1506
TCGv_i32 tmp = tcg_temp_new_i32 ();
1487
- gen_check_sr ( dc , RSR_SR , SR_X );
1507
+
1488
1508
if (RSR_SR >= 64 ) {
1489
1509
gen_check_privilege (dc );
1490
1510
}
@@ -1707,21 +1727,23 @@ static void disas_xtensa_insn(CPUXtensaState *env, DisasContext *dc)
1707
1727
case 3 : /*RST3*/
1708
1728
switch (OP2 ) {
1709
1729
case 0 : /*RSR*/
1710
- gen_check_sr (dc , RSR_SR , SR_R );
1711
- if (RSR_SR >= 64 ) {
1712
- gen_check_privilege (dc );
1730
+ if (gen_check_sr (dc , RSR_SR , SR_R )) {
1731
+ if (RSR_SR >= 64 ) {
1732
+ gen_check_privilege (dc );
1733
+ }
1734
+ gen_window_check1 (dc , RRR_T );
1735
+ gen_rsr (dc , cpu_R [RRR_T ], RSR_SR );
1713
1736
}
1714
- gen_window_check1 (dc , RRR_T );
1715
- gen_rsr (dc , cpu_R [RRR_T ], RSR_SR );
1716
1737
break ;
1717
1738
1718
1739
case 1 : /*WSR*/
1719
- gen_check_sr (dc , RSR_SR , SR_W );
1720
- if (RSR_SR >= 64 ) {
1721
- gen_check_privilege (dc );
1740
+ if (gen_check_sr (dc , RSR_SR , SR_W )) {
1741
+ if (RSR_SR >= 64 ) {
1742
+ gen_check_privilege (dc );
1743
+ }
1744
+ gen_window_check1 (dc , RRR_T );
1745
+ gen_wsr (dc , RSR_SR , cpu_R [RRR_T ]);
1722
1746
}
1723
- gen_window_check1 (dc , RRR_T );
1724
- gen_wsr (dc , RSR_SR , cpu_R [RRR_T ]);
1725
1747
break ;
1726
1748
1727
1749
case 2 : /*SEXTu*/
@@ -2918,8 +2940,7 @@ void gen_intermediate_code_internal(XtensaCPU *cpu,
2918
2940
2919
2941
gen_tb_start ();
2920
2942
2921
- if (cs -> singlestep_enabled && env -> exception_taken ) {
2922
- env -> exception_taken = 0 ;
2943
+ if (tb -> flags & XTENSA_TBFLAG_EXCEPTION ) {
2923
2944
tcg_gen_movi_i32 (cpu_pc , dc .pc );
2924
2945
gen_exception (& dc , EXCP_DEBUG );
2925
2946
}
0 commit comments