Commit 823029f909b3666660418387d48ea6a207f23f26

Authored by ths
1 parent a36e69dd

SH4 delay slot code update, by Magnus Damm.


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3761 c046a42c-6fe2-441c-8c8c-71466251a162
cpu-exec.c
@@ -202,8 +202,8 @@ static inline TranslationBlock *tb_find_fast(void) @@ -202,8 +202,8 @@ static inline TranslationBlock *tb_find_fast(void)
202 cs_base = 0; 202 cs_base = 0;
203 pc = env->pc; 203 pc = env->pc;
204 #elif defined(TARGET_SH4) 204 #elif defined(TARGET_SH4)
205 - flags = env->sr & (SR_MD | SR_RB);  
206 - cs_base = 0; /* XXXXX */ 205 + flags = env->flags;
  206 + cs_base = 0;
207 pc = env->pc; 207 pc = env->pc;
208 #elif defined(TARGET_ALPHA) 208 #elif defined(TARGET_ALPHA)
209 flags = env->ps; 209 flags = env->ps;
target-sh4/cpu.h
@@ -46,16 +46,16 @@ @@ -46,16 +46,16 @@
46 #define FPSCR_SZ (1 << 20) 46 #define FPSCR_SZ (1 << 20)
47 #define FPSCR_PR (1 << 19) 47 #define FPSCR_PR (1 << 19)
48 #define FPSCR_DN (1 << 18) 48 #define FPSCR_DN (1 << 18)
49 -  
50 -#define DELAY_SLOT (1 << 0) /* Must be the same as SR_T. */  
51 -/* This flag is set if the next insn is a delay slot for a conditional jump.  
52 - The dynamic value of the DELAY_SLOT determines whether the jup is taken. */ 49 +#define DELAY_SLOT (1 << 0)
53 #define DELAY_SLOT_CONDITIONAL (1 << 1) 50 #define DELAY_SLOT_CONDITIONAL (1 << 1)
54 -/* Those are used in contexts only */  
55 -#define BRANCH (1 << 2)  
56 -#define BRANCH_CONDITIONAL (1 << 3)  
57 -#define MODE_CHANGE (1 << 4) /* Potential MD|RB change */  
58 -#define BRANCH_EXCEPTION (1 << 5) /* Branch after exception */ 51 +#define DELAY_SLOT_TRUE (1 << 2)
  52 +#define DELAY_SLOT_CLEARME (1 << 3)
  53 +/* The dynamic value of the DELAY_SLOT_TRUE flag determines whether the jump
  54 + * after the delay slot should be taken or not. It is calculated from SR_T.
  55 + *
  56 + * It is unclear if it is permitted to modify the SR_T flag in a delay slot.
  57 + * The use of DELAY_SLOT_TRUE flag makes us accept such SR_T modification.
  58 + */
59 59
60 /* XXXXX The structure could be made more compact */ 60 /* XXXXX The structure could be made more compact */
61 typedef struct tlb_t { 61 typedef struct tlb_t {
target-sh4/op.c
@@ -19,16 +19,6 @@ @@ -19,16 +19,6 @@
19 */ 19 */
20 #include "exec.h" 20 #include "exec.h"
21 21
22 -static inline void set_flag(uint32_t flag)  
23 -{  
24 - env->flags |= flag;  
25 -}  
26 -  
27 -static inline void clr_flag(uint32_t flag)  
28 -{  
29 - env->flags &= ~flag;  
30 -}  
31 -  
32 static inline void set_t(void) 22 static inline void set_t(void)
33 { 23 {
34 env->sr |= SR_T; 24 env->sr |= SR_T;
@@ -110,28 +100,37 @@ void OPPROTO op_not_T0(void) @@ -110,28 +100,37 @@ void OPPROTO op_not_T0(void)
110 void OPPROTO op_bf_s(void) 100 void OPPROTO op_bf_s(void)
111 { 101 {
112 env->delayed_pc = PARAM1; 102 env->delayed_pc = PARAM1;
113 - set_flag(DELAY_SLOT_CONDITIONAL | ((~env->sr) & SR_T)); 103 + if (!(env->sr & SR_T)) {
  104 + env->flags |= DELAY_SLOT_TRUE;
  105 + }
114 RETURN(); 106 RETURN();
115 } 107 }
116 108
117 void OPPROTO op_bt_s(void) 109 void OPPROTO op_bt_s(void)
118 { 110 {
119 env->delayed_pc = PARAM1; 111 env->delayed_pc = PARAM1;
120 - set_flag(DELAY_SLOT_CONDITIONAL | (env->sr & SR_T)); 112 + if (env->sr & SR_T) {
  113 + env->flags |= DELAY_SLOT_TRUE;
  114 + }
  115 + RETURN();
  116 +}
  117 +
  118 +void OPPROTO op_store_flags(void)
  119 +{
  120 + env->flags &= DELAY_SLOT_TRUE;
  121 + env->flags |= PARAM1;
121 RETURN(); 122 RETURN();
122 } 123 }
123 124
124 void OPPROTO op_bra(void) 125 void OPPROTO op_bra(void)
125 { 126 {
126 env->delayed_pc = PARAM1; 127 env->delayed_pc = PARAM1;
127 - set_flag(DELAY_SLOT);  
128 RETURN(); 128 RETURN();
129 } 129 }
130 130
131 void OPPROTO op_braf_T0(void) 131 void OPPROTO op_braf_T0(void)
132 { 132 {
133 env->delayed_pc = PARAM1 + T0; 133 env->delayed_pc = PARAM1 + T0;
134 - set_flag(DELAY_SLOT);  
135 RETURN(); 134 RETURN();
136 } 135 }
137 136
@@ -139,7 +138,6 @@ void OPPROTO op_bsr(void) @@ -139,7 +138,6 @@ void OPPROTO op_bsr(void)
139 { 138 {
140 env->pr = PARAM1; 139 env->pr = PARAM1;
141 env->delayed_pc = PARAM2; 140 env->delayed_pc = PARAM2;
142 - set_flag(DELAY_SLOT);  
143 RETURN(); 141 RETURN();
144 } 142 }
145 143
@@ -147,7 +145,6 @@ void OPPROTO op_bsrf_T0(void) @@ -147,7 +145,6 @@ void OPPROTO op_bsrf_T0(void)
147 { 145 {
148 env->pr = PARAM1; 146 env->pr = PARAM1;
149 env->delayed_pc = PARAM1 + T0; 147 env->delayed_pc = PARAM1 + T0;
150 - set_flag(DELAY_SLOT);  
151 RETURN(); 148 RETURN();
152 } 149 }
153 150
@@ -155,26 +152,12 @@ void OPPROTO op_jsr_T0(void) @@ -155,26 +152,12 @@ void OPPROTO op_jsr_T0(void)
155 { 152 {
156 env->pr = PARAM1; 153 env->pr = PARAM1;
157 env->delayed_pc = T0; 154 env->delayed_pc = T0;
158 - set_flag(DELAY_SLOT);  
159 RETURN(); 155 RETURN();
160 } 156 }
161 157
162 void OPPROTO op_rts(void) 158 void OPPROTO op_rts(void)
163 { 159 {
164 env->delayed_pc = env->pr; 160 env->delayed_pc = env->pr;
165 - set_flag(DELAY_SLOT);  
166 - RETURN();  
167 -}  
168 -  
169 -void OPPROTO op_clr_delay_slot(void)  
170 -{  
171 - clr_flag(DELAY_SLOT);  
172 - RETURN();  
173 -}  
174 -  
175 -void OPPROTO op_clr_delay_slot_conditional(void)  
176 -{  
177 - clr_flag(DELAY_SLOT_CONDITIONAL);  
178 RETURN(); 161 RETURN();
179 } 162 }
180 163
@@ -242,7 +225,6 @@ void OPPROTO op_rte(void) @@ -242,7 +225,6 @@ void OPPROTO op_rte(void)
242 { 225 {
243 env->sr = env->ssr; 226 env->sr = env->ssr;
244 env->delayed_pc = env->spc; 227 env->delayed_pc = env->spc;
245 - set_flag(DELAY_SLOT);  
246 RETURN(); 228 RETURN();
247 } 229 }
248 230
@@ -458,7 +440,6 @@ void OPPROTO op_cmp_pz_T0(void) @@ -458,7 +440,6 @@ void OPPROTO op_cmp_pz_T0(void)
458 void OPPROTO op_jmp_T0(void) 440 void OPPROTO op_jmp_T0(void)
459 { 441 {
460 env->delayed_pc = T0; 442 env->delayed_pc = T0;
461 - set_flag(DELAY_SLOT);  
462 RETURN(); 443 RETURN();
463 } 444 }
464 445
@@ -993,11 +974,10 @@ void OPPROTO op_jT(void) @@ -993,11 +974,10 @@ void OPPROTO op_jT(void)
993 974
994 void OPPROTO op_jdelayed(void) 975 void OPPROTO op_jdelayed(void)
995 { 976 {
996 - uint32_t flags;  
997 - flags = env->flags;  
998 - env->flags &= ~(DELAY_SLOT | DELAY_SLOT_CONDITIONAL);  
999 - if (flags & DELAY_SLOT)  
1000 - GOTO_LABEL_PARAM(1); 977 + if (env->flags & DELAY_SLOT_TRUE) {
  978 + env->flags &= ~DELAY_SLOT_TRUE;
  979 + GOTO_LABEL_PARAM(1);
  980 + }
1001 RETURN(); 981 RETURN();
1002 } 982 }
1003 983
target-sh4/translate.c
@@ -57,11 +57,21 @@ typedef struct DisasContext { @@ -57,11 +57,21 @@ typedef struct DisasContext {
57 uint32_t fpscr; 57 uint32_t fpscr;
58 uint16_t opcode; 58 uint16_t opcode;
59 uint32_t flags; 59 uint32_t flags;
  60 + int bstate;
60 int memidx; 61 int memidx;
61 uint32_t delayed_pc; 62 uint32_t delayed_pc;
62 int singlestep_enabled; 63 int singlestep_enabled;
63 } DisasContext; 64 } DisasContext;
64 65
  66 +enum {
  67 + BS_NONE = 0, /* We go out of the TB without reaching a branch or an
  68 + * exception condition
  69 + */
  70 + BS_STOP = 1, /* We want to stop translation for any reason */
  71 + BS_BRANCH = 2, /* We reached a branch condition */
  72 + BS_EXCP = 3, /* We reached an exception condition */
  73 +};
  74 +
65 #ifdef CONFIG_USER_ONLY 75 #ifdef CONFIG_USER_ONLY
66 76
67 #define GEN_OP_LD(width, reg) \ 77 #define GEN_OP_LD(width, reg) \
@@ -176,15 +186,6 @@ static void gen_goto_tb(DisasContext * ctx, int n, target_ulong dest) @@ -176,15 +186,6 @@ static void gen_goto_tb(DisasContext * ctx, int n, target_ulong dest)
176 gen_op_exit_tb(); 186 gen_op_exit_tb();
177 } 187 }
178 188
179 -/* Jump to pc after an exception */  
180 -static void gen_jump_exception(DisasContext * ctx)  
181 -{  
182 - gen_op_movl_imm_T0(0);  
183 - if (ctx->singlestep_enabled)  
184 - gen_op_debug();  
185 - gen_op_exit_tb();  
186 -}  
187 -  
188 static void gen_jump(DisasContext * ctx) 189 static void gen_jump(DisasContext * ctx)
189 { 190 {
190 if (ctx->delayed_pc == (uint32_t) - 1) { 191 if (ctx->delayed_pc == (uint32_t) - 1) {
@@ -220,7 +221,7 @@ static void gen_delayed_conditional_jump(DisasContext * ctx) @@ -220,7 +221,7 @@ static void gen_delayed_conditional_jump(DisasContext * ctx)
220 221
221 l1 = gen_new_label(); 222 l1 = gen_new_label();
222 gen_op_jdelayed(l1); 223 gen_op_jdelayed(l1);
223 - gen_goto_tb(ctx, 1, ctx->pc); 224 + gen_goto_tb(ctx, 1, ctx->pc + 2);
224 gen_set_label(l1); 225 gen_set_label(l1);
225 gen_jump(ctx); 226 gen_jump(ctx);
226 } 227 }
@@ -248,10 +249,10 @@ static void gen_delayed_conditional_jump(DisasContext * ctx) @@ -248,10 +249,10 @@ static void gen_delayed_conditional_jump(DisasContext * ctx)
248 249
249 #define CHECK_NOT_DELAY_SLOT \ 250 #define CHECK_NOT_DELAY_SLOT \
250 if (ctx->flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL)) \ 251 if (ctx->flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL)) \
251 - {gen_op_raise_slot_illegal_instruction (); ctx->flags |= BRANCH_EXCEPTION; \ 252 + {gen_op_raise_slot_illegal_instruction (); ctx->bstate = BS_EXCP; \
252 return;} 253 return;}
253 254
254 -void decode_opc(DisasContext * ctx) 255 +void _decode_opc(DisasContext * ctx)
255 { 256 {
256 #if 0 257 #if 0
257 fprintf(stderr, "Translating opcode 0x%04x\n", ctx->opcode); 258 fprintf(stderr, "Translating opcode 0x%04x\n", ctx->opcode);
@@ -290,11 +291,11 @@ void decode_opc(DisasContext * ctx) @@ -290,11 +291,11 @@ void decode_opc(DisasContext * ctx)
290 return; 291 return;
291 case 0xfbfb: /* frchg */ 292 case 0xfbfb: /* frchg */
292 gen_op_frchg(); 293 gen_op_frchg();
293 - ctx->flags |= MODE_CHANGE; 294 + ctx->bstate = BS_STOP;
294 return; 295 return;
295 case 0xf3fb: /* fschg */ 296 case 0xf3fb: /* fschg */
296 gen_op_fschg(); 297 gen_op_fschg();
297 - ctx->flags |= MODE_CHANGE; 298 + ctx->bstate = BS_STOP;
298 return; 299 return;
299 case 0x0009: /* nop */ 300 case 0x0009: /* nop */
300 return; 301 return;
@@ -805,7 +806,7 @@ void decode_opc(DisasContext * ctx) @@ -805,7 +806,7 @@ void decode_opc(DisasContext * ctx)
805 CHECK_NOT_DELAY_SLOT 806 CHECK_NOT_DELAY_SLOT
806 gen_conditional_jump(ctx, ctx->pc + 2, 807 gen_conditional_jump(ctx, ctx->pc + 2,
807 ctx->pc + 4 + B7_0s * 2); 808 ctx->pc + 4 + B7_0s * 2);
808 - ctx->flags |= BRANCH_CONDITIONAL; 809 + ctx->bstate = BS_BRANCH;
809 return; 810 return;
810 case 0x8f00: /* bf/s label */ 811 case 0x8f00: /* bf/s label */
811 CHECK_NOT_DELAY_SLOT 812 CHECK_NOT_DELAY_SLOT
@@ -816,7 +817,7 @@ void decode_opc(DisasContext * ctx) @@ -816,7 +817,7 @@ void decode_opc(DisasContext * ctx)
816 CHECK_NOT_DELAY_SLOT 817 CHECK_NOT_DELAY_SLOT
817 gen_conditional_jump(ctx, ctx->pc + 4 + B7_0s * 2, 818 gen_conditional_jump(ctx, ctx->pc + 4 + B7_0s * 2,
818 ctx->pc + 2); 819 ctx->pc + 2);
819 - ctx->flags |= BRANCH_CONDITIONAL; 820 + ctx->bstate = BS_BRANCH;
820 return; 821 return;
821 case 0x8d00: /* bt/s label */ 822 case 0x8d00: /* bt/s label */
822 CHECK_NOT_DELAY_SLOT 823 CHECK_NOT_DELAY_SLOT
@@ -908,7 +909,7 @@ void decode_opc(DisasContext * ctx) @@ -908,7 +909,7 @@ void decode_opc(DisasContext * ctx)
908 case 0xc300: /* trapa #imm */ 909 case 0xc300: /* trapa #imm */
909 CHECK_NOT_DELAY_SLOT gen_op_movl_imm_PC(ctx->pc); 910 CHECK_NOT_DELAY_SLOT gen_op_movl_imm_PC(ctx->pc);
910 gen_op_trapa(B7_0); 911 gen_op_trapa(B7_0);
911 - ctx->flags |= BRANCH; 912 + ctx->bstate = BS_BRANCH;
912 return; 913 return;
913 case 0xc800: /* tst #imm,R0 */ 914 case 0xc800: /* tst #imm,R0 */
914 gen_op_tst_imm_rN(B7_0, REG(0)); 915 gen_op_tst_imm_rN(B7_0, REG(0));
@@ -1012,8 +1013,8 @@ void decode_opc(DisasContext * ctx) @@ -1012,8 +1013,8 @@ void decode_opc(DisasContext * ctx)
1012 gen_op_movl_rN_T1 (REG(B11_8)); \ 1013 gen_op_movl_rN_T1 (REG(B11_8)); \
1013 gen_op_stl_T0_T1 (ctx); \ 1014 gen_op_stl_T0_T1 (ctx); \
1014 return; 1015 return;
1015 - LDST(sr, 0x400e, 0x4007, ldc, 0x0002, 0x4003, stc, ctx->flags |=  
1016 - MODE_CHANGE;) 1016 + LDST(sr, 0x400e, 0x4007, ldc, 0x0002, 0x4003, stc, ctx->bstate =
  1017 + BS_STOP;)
1017 LDST(gbr, 0x401e, 0x4017, ldc, 0x0012, 0x4013, stc,) 1018 LDST(gbr, 0x401e, 0x4017, ldc, 0x0012, 0x4013, stc,)
1018 LDST(vbr, 0x402e, 0x4027, ldc, 0x0022, 0x4023, stc,) 1019 LDST(vbr, 0x402e, 0x4027, ldc, 0x0022, 0x4023, stc,)
1019 LDST(ssr, 0x403e, 0x4037, ldc, 0x0032, 0x4033, stc,) 1020 LDST(ssr, 0x403e, 0x4037, ldc, 0x0032, 0x4033, stc,)
@@ -1023,8 +1024,8 @@ void decode_opc(DisasContext * ctx) @@ -1023,8 +1024,8 @@ void decode_opc(DisasContext * ctx)
1023 LDST(macl, 0x401a, 0x4016, lds, 0x001a, 0x4012, sts,) 1024 LDST(macl, 0x401a, 0x4016, lds, 0x001a, 0x4012, sts,)
1024 LDST(pr, 0x402a, 0x4026, lds, 0x002a, 0x4022, sts,) 1025 LDST(pr, 0x402a, 0x4026, lds, 0x002a, 0x4022, sts,)
1025 LDST(fpul, 0x405a, 0x4056, lds, 0x005a, 0x4052, sts,) 1026 LDST(fpul, 0x405a, 0x4056, lds, 0x005a, 0x4052, sts,)
1026 - LDST(fpscr, 0x406a, 0x4066, lds, 0x006a, 0x4062, sts, ctx->flags |=  
1027 - MODE_CHANGE;) 1027 + LDST(fpscr, 0x406a, 0x4066, lds, 0x006a, 0x4062, sts, ctx->bstate =
  1028 + BS_STOP;)
1028 case 0x00c3: /* movca.l R0,@Rm */ 1029 case 0x00c3: /* movca.l R0,@Rm */
1029 gen_op_movl_rN_T0(REG(0)); 1030 gen_op_movl_rN_T0(REG(0));
1030 gen_op_movl_rN_T1(REG(B11_8)); 1031 gen_op_movl_rN_T1(REG(B11_8));
@@ -1141,7 +1142,28 @@ void decode_opc(DisasContext * ctx) @@ -1141,7 +1142,28 @@ void decode_opc(DisasContext * ctx)
1141 fprintf(stderr, "unknown instruction 0x%04x at pc 0x%08x\n", 1142 fprintf(stderr, "unknown instruction 0x%04x at pc 0x%08x\n",
1142 ctx->opcode, ctx->pc); 1143 ctx->opcode, ctx->pc);
1143 gen_op_raise_illegal_instruction(); 1144 gen_op_raise_illegal_instruction();
1144 - ctx->flags |= BRANCH_EXCEPTION; 1145 + ctx->bstate = BS_EXCP;
  1146 +}
  1147 +
  1148 +void decode_opc(DisasContext * ctx)
  1149 +{
  1150 + uint32_t old_flags = ctx->flags;
  1151 +
  1152 + _decode_opc(ctx);
  1153 +
  1154 + if (old_flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL)) {
  1155 + if (ctx->flags & DELAY_SLOT_CLEARME) {
  1156 + gen_op_store_flags(0);
  1157 + }
  1158 + ctx->flags = 0;
  1159 + ctx->bstate = BS_BRANCH;
  1160 + if (old_flags & DELAY_SLOT_CONDITIONAL) {
  1161 + gen_delayed_conditional_jump(ctx);
  1162 + } else if (old_flags & DELAY_SLOT) {
  1163 + gen_jump(ctx);
  1164 + }
  1165 +
  1166 + }
1145 } 1167 }
1146 1168
1147 static inline int 1169 static inline int
@@ -1151,7 +1173,6 @@ gen_intermediate_code_internal(CPUState * env, TranslationBlock * tb, @@ -1151,7 +1173,6 @@ gen_intermediate_code_internal(CPUState * env, TranslationBlock * tb,
1151 DisasContext ctx; 1173 DisasContext ctx;
1152 target_ulong pc_start; 1174 target_ulong pc_start;
1153 static uint16_t *gen_opc_end; 1175 static uint16_t *gen_opc_end;
1154 - uint32_t old_flags;  
1155 int i, ii; 1176 int i, ii;
1156 1177
1157 pc_start = tb->pc; 1178 pc_start = tb->pc;
@@ -1159,14 +1180,14 @@ gen_intermediate_code_internal(CPUState * env, TranslationBlock * tb, @@ -1159,14 +1180,14 @@ gen_intermediate_code_internal(CPUState * env, TranslationBlock * tb,
1159 gen_opc_end = gen_opc_buf + OPC_MAX_SIZE; 1180 gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
1160 gen_opparam_ptr = gen_opparam_buf; 1181 gen_opparam_ptr = gen_opparam_buf;
1161 ctx.pc = pc_start; 1182 ctx.pc = pc_start;
1162 - ctx.flags = env->flags;  
1163 - old_flags = 0; 1183 + ctx.flags = (uint32_t)tb->flags;
  1184 + ctx.bstate = BS_NONE;
1164 ctx.sr = env->sr; 1185 ctx.sr = env->sr;
1165 ctx.fpscr = env->fpscr; 1186 ctx.fpscr = env->fpscr;
1166 ctx.memidx = (env->sr & SR_MD) ? 1 : 0; 1187 ctx.memidx = (env->sr & SR_MD) ? 1 : 0;
1167 /* We don't know if the delayed pc came from a dynamic or static branch, 1188 /* We don't know if the delayed pc came from a dynamic or static branch,
1168 so assume it is a dynamic branch. */ 1189 so assume it is a dynamic branch. */
1169 - ctx.delayed_pc = -1; 1190 + ctx.delayed_pc = -1; /* use delayed pc from env pointer */
1170 ctx.tb = tb; 1191 ctx.tb = tb;
1171 ctx.singlestep_enabled = env->singlestep_enabled; 1192 ctx.singlestep_enabled = env->singlestep_enabled;
1172 nb_gen_labels = 0; 1193 nb_gen_labels = 0;
@@ -1180,18 +1201,14 @@ gen_intermediate_code_internal(CPUState * env, TranslationBlock * tb, @@ -1180,18 +1201,14 @@ gen_intermediate_code_internal(CPUState * env, TranslationBlock * tb,
1180 #endif 1201 #endif
1181 1202
1182 ii = -1; 1203 ii = -1;
1183 - while ((old_flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL)) == 0 &&  
1184 - (ctx.flags & (BRANCH | BRANCH_CONDITIONAL | MODE_CHANGE |  
1185 - BRANCH_EXCEPTION)) == 0 &&  
1186 - gen_opc_ptr < gen_opc_end && ctx.sr == env->sr) {  
1187 - old_flags = ctx.flags; 1204 + while (ctx.bstate == BS_NONE && gen_opc_ptr < gen_opc_end) {
1188 if (env->nb_breakpoints > 0) { 1205 if (env->nb_breakpoints > 0) {
1189 for (i = 0; i < env->nb_breakpoints; i++) { 1206 for (i = 0; i < env->nb_breakpoints; i++) {
1190 if (ctx.pc == env->breakpoints[i]) { 1207 if (ctx.pc == env->breakpoints[i]) {
1191 /* We have hit a breakpoint - make sure PC is up-to-date */ 1208 /* We have hit a breakpoint - make sure PC is up-to-date */
1192 gen_op_movl_imm_PC(ctx.pc); 1209 gen_op_movl_imm_PC(ctx.pc);
1193 gen_op_debug(); 1210 gen_op_debug();
1194 - ctx.flags |= BRANCH_EXCEPTION; 1211 + ctx.bstate = BS_EXCP;
1195 break; 1212 break;
1196 } 1213 }
1197 } 1214 }
@@ -1204,6 +1221,7 @@ gen_intermediate_code_internal(CPUState * env, TranslationBlock * tb, @@ -1204,6 +1221,7 @@ gen_intermediate_code_internal(CPUState * env, TranslationBlock * tb,
1204 gen_opc_instr_start[ii++] = 0; 1221 gen_opc_instr_start[ii++] = 0;
1205 } 1222 }
1206 gen_opc_pc[ii] = ctx.pc; 1223 gen_opc_pc[ii] = ctx.pc;
  1224 + gen_opc_hflags[ii] = ctx.flags;
1207 gen_opc_instr_start[ii] = 1; 1225 gen_opc_instr_start[ii] = 1;
1208 } 1226 }
1209 #if 0 1227 #if 0
@@ -1221,21 +1239,30 @@ gen_intermediate_code_internal(CPUState * env, TranslationBlock * tb, @@ -1221,21 +1239,30 @@ gen_intermediate_code_internal(CPUState * env, TranslationBlock * tb,
1221 break; 1239 break;
1222 #endif 1240 #endif
1223 } 1241 }
1224 -  
1225 - if (old_flags & DELAY_SLOT_CONDITIONAL) {  
1226 - gen_delayed_conditional_jump(&ctx);  
1227 - } else if (old_flags & DELAY_SLOT) {  
1228 - gen_op_clr_delay_slot();  
1229 - gen_jump(&ctx);  
1230 - } else if (ctx.flags & BRANCH_EXCEPTION) {  
1231 - gen_jump_exception(&ctx);  
1232 - } else if ((ctx.flags & (BRANCH | BRANCH_CONDITIONAL)) == 0) {  
1233 - gen_goto_tb(&ctx, 0, ctx.pc);  
1234 - }  
1235 -  
1236 if (env->singlestep_enabled) { 1242 if (env->singlestep_enabled) {
1237 - gen_op_debug(); 1243 + gen_op_debug();
  1244 + } else {
  1245 + switch (ctx.bstate) {
  1246 + case BS_STOP:
  1247 + /* gen_op_interrupt_restart(); */
  1248 + /* fall through */
  1249 + case BS_NONE:
  1250 + if (ctx.flags) {
  1251 + gen_op_store_flags(ctx.flags | DELAY_SLOT_CLEARME);
  1252 + }
  1253 + gen_goto_tb(&ctx, 0, ctx.pc);
  1254 + break;
  1255 + case BS_EXCP:
  1256 + /* gen_op_interrupt_restart(); */
  1257 + gen_op_movl_imm_T0(0);
  1258 + gen_op_exit_tb();
  1259 + break;
  1260 + case BS_BRANCH:
  1261 + default:
  1262 + break;
  1263 + }
1238 } 1264 }
  1265 +
1239 *gen_opc_ptr = INDEX_op_end; 1266 *gen_opc_ptr = INDEX_op_end;
1240 if (search_pc) { 1267 if (search_pc) {
1241 i = gen_opc_ptr - gen_opc_buf; 1268 i = gen_opc_ptr - gen_opc_buf;
translate-all.c
@@ -53,7 +53,7 @@ uint8_t gen_opc_cc_op[OPC_BUF_SIZE]; @@ -53,7 +53,7 @@ uint8_t gen_opc_cc_op[OPC_BUF_SIZE];
53 #elif defined(TARGET_SPARC) 53 #elif defined(TARGET_SPARC)
54 target_ulong gen_opc_npc[OPC_BUF_SIZE]; 54 target_ulong gen_opc_npc[OPC_BUF_SIZE];
55 target_ulong gen_opc_jump_pc[2]; 55 target_ulong gen_opc_jump_pc[2];
56 -#elif defined(TARGET_MIPS) 56 +#elif defined(TARGET_MIPS) || defined(TARGET_SH4)
57 uint32_t gen_opc_hflags[OPC_BUF_SIZE]; 57 uint32_t gen_opc_hflags[OPC_BUF_SIZE];
58 #endif 58 #endif
59 59
@@ -298,6 +298,9 @@ int cpu_restore_state(TranslationBlock *tb, @@ -298,6 +298,9 @@ int cpu_restore_state(TranslationBlock *tb,
298 env->hflags |= gen_opc_hflags[j]; 298 env->hflags |= gen_opc_hflags[j];
299 #elif defined(TARGET_ALPHA) 299 #elif defined(TARGET_ALPHA)
300 env->pc = gen_opc_pc[j]; 300 env->pc = gen_opc_pc[j];
  301 +#elif defined(TARGET_SH4)
  302 + env->pc = gen_opc_pc[j];
  303 + env->flags = gen_opc_hflags[j];
301 #endif 304 #endif
302 return 0; 305 return 0;
303 } 306 }