Commit 823029f909b3666660418387d48ea6a207f23f26
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
Showing
5 changed files
with
104 additions
and
94 deletions
cpu-exec.c
| ... | ... | @@ -202,8 +202,8 @@ static inline TranslationBlock *tb_find_fast(void) |
| 202 | 202 | cs_base = 0; |
| 203 | 203 | pc = env->pc; |
| 204 | 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 | 207 | pc = env->pc; |
| 208 | 208 | #elif defined(TARGET_ALPHA) |
| 209 | 209 | flags = env->ps; | ... | ... |
target-sh4/cpu.h
| ... | ... | @@ -46,16 +46,16 @@ |
| 46 | 46 | #define FPSCR_SZ (1 << 20) |
| 47 | 47 | #define FPSCR_PR (1 << 19) |
| 48 | 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 | 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 | 60 | /* XXXXX The structure could be made more compact */ |
| 61 | 61 | typedef struct tlb_t { | ... | ... |
target-sh4/op.c
| ... | ... | @@ -19,16 +19,6 @@ |
| 19 | 19 | */ |
| 20 | 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 | 22 | static inline void set_t(void) |
| 33 | 23 | { |
| 34 | 24 | env->sr |= SR_T; |
| ... | ... | @@ -110,28 +100,37 @@ void OPPROTO op_not_T0(void) |
| 110 | 100 | void OPPROTO op_bf_s(void) |
| 111 | 101 | { |
| 112 | 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 | 106 | RETURN(); |
| 115 | 107 | } |
| 116 | 108 | |
| 117 | 109 | void OPPROTO op_bt_s(void) |
| 118 | 110 | { |
| 119 | 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 | 122 | RETURN(); |
| 122 | 123 | } |
| 123 | 124 | |
| 124 | 125 | void OPPROTO op_bra(void) |
| 125 | 126 | { |
| 126 | 127 | env->delayed_pc = PARAM1; |
| 127 | - set_flag(DELAY_SLOT); | |
| 128 | 128 | RETURN(); |
| 129 | 129 | } |
| 130 | 130 | |
| 131 | 131 | void OPPROTO op_braf_T0(void) |
| 132 | 132 | { |
| 133 | 133 | env->delayed_pc = PARAM1 + T0; |
| 134 | - set_flag(DELAY_SLOT); | |
| 135 | 134 | RETURN(); |
| 136 | 135 | } |
| 137 | 136 | |
| ... | ... | @@ -139,7 +138,6 @@ void OPPROTO op_bsr(void) |
| 139 | 138 | { |
| 140 | 139 | env->pr = PARAM1; |
| 141 | 140 | env->delayed_pc = PARAM2; |
| 142 | - set_flag(DELAY_SLOT); | |
| 143 | 141 | RETURN(); |
| 144 | 142 | } |
| 145 | 143 | |
| ... | ... | @@ -147,7 +145,6 @@ void OPPROTO op_bsrf_T0(void) |
| 147 | 145 | { |
| 148 | 146 | env->pr = PARAM1; |
| 149 | 147 | env->delayed_pc = PARAM1 + T0; |
| 150 | - set_flag(DELAY_SLOT); | |
| 151 | 148 | RETURN(); |
| 152 | 149 | } |
| 153 | 150 | |
| ... | ... | @@ -155,26 +152,12 @@ void OPPROTO op_jsr_T0(void) |
| 155 | 152 | { |
| 156 | 153 | env->pr = PARAM1; |
| 157 | 154 | env->delayed_pc = T0; |
| 158 | - set_flag(DELAY_SLOT); | |
| 159 | 155 | RETURN(); |
| 160 | 156 | } |
| 161 | 157 | |
| 162 | 158 | void OPPROTO op_rts(void) |
| 163 | 159 | { |
| 164 | 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 | 161 | RETURN(); |
| 179 | 162 | } |
| 180 | 163 | |
| ... | ... | @@ -242,7 +225,6 @@ void OPPROTO op_rte(void) |
| 242 | 225 | { |
| 243 | 226 | env->sr = env->ssr; |
| 244 | 227 | env->delayed_pc = env->spc; |
| 245 | - set_flag(DELAY_SLOT); | |
| 246 | 228 | RETURN(); |
| 247 | 229 | } |
| 248 | 230 | |
| ... | ... | @@ -458,7 +440,6 @@ void OPPROTO op_cmp_pz_T0(void) |
| 458 | 440 | void OPPROTO op_jmp_T0(void) |
| 459 | 441 | { |
| 460 | 442 | env->delayed_pc = T0; |
| 461 | - set_flag(DELAY_SLOT); | |
| 462 | 443 | RETURN(); |
| 463 | 444 | } |
| 464 | 445 | |
| ... | ... | @@ -993,11 +974,10 @@ void OPPROTO op_jT(void) |
| 993 | 974 | |
| 994 | 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 | 981 | RETURN(); |
| 1002 | 982 | } |
| 1003 | 983 | ... | ... |
target-sh4/translate.c
| ... | ... | @@ -57,11 +57,21 @@ typedef struct DisasContext { |
| 57 | 57 | uint32_t fpscr; |
| 58 | 58 | uint16_t opcode; |
| 59 | 59 | uint32_t flags; |
| 60 | + int bstate; | |
| 60 | 61 | int memidx; |
| 61 | 62 | uint32_t delayed_pc; |
| 62 | 63 | int singlestep_enabled; |
| 63 | 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 | 75 | #ifdef CONFIG_USER_ONLY |
| 66 | 76 | |
| 67 | 77 | #define GEN_OP_LD(width, reg) \ |
| ... | ... | @@ -176,15 +186,6 @@ static void gen_goto_tb(DisasContext * ctx, int n, target_ulong dest) |
| 176 | 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 | 189 | static void gen_jump(DisasContext * ctx) |
| 189 | 190 | { |
| 190 | 191 | if (ctx->delayed_pc == (uint32_t) - 1) { |
| ... | ... | @@ -220,7 +221,7 @@ static void gen_delayed_conditional_jump(DisasContext * ctx) |
| 220 | 221 | |
| 221 | 222 | l1 = gen_new_label(); |
| 222 | 223 | gen_op_jdelayed(l1); |
| 223 | - gen_goto_tb(ctx, 1, ctx->pc); | |
| 224 | + gen_goto_tb(ctx, 1, ctx->pc + 2); | |
| 224 | 225 | gen_set_label(l1); |
| 225 | 226 | gen_jump(ctx); |
| 226 | 227 | } |
| ... | ... | @@ -248,10 +249,10 @@ static void gen_delayed_conditional_jump(DisasContext * ctx) |
| 248 | 249 | |
| 249 | 250 | #define CHECK_NOT_DELAY_SLOT \ |
| 250 | 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 | 253 | return;} |
| 253 | 254 | |
| 254 | -void decode_opc(DisasContext * ctx) | |
| 255 | +void _decode_opc(DisasContext * ctx) | |
| 255 | 256 | { |
| 256 | 257 | #if 0 |
| 257 | 258 | fprintf(stderr, "Translating opcode 0x%04x\n", ctx->opcode); |
| ... | ... | @@ -290,11 +291,11 @@ void decode_opc(DisasContext * ctx) |
| 290 | 291 | return; |
| 291 | 292 | case 0xfbfb: /* frchg */ |
| 292 | 293 | gen_op_frchg(); |
| 293 | - ctx->flags |= MODE_CHANGE; | |
| 294 | + ctx->bstate = BS_STOP; | |
| 294 | 295 | return; |
| 295 | 296 | case 0xf3fb: /* fschg */ |
| 296 | 297 | gen_op_fschg(); |
| 297 | - ctx->flags |= MODE_CHANGE; | |
| 298 | + ctx->bstate = BS_STOP; | |
| 298 | 299 | return; |
| 299 | 300 | case 0x0009: /* nop */ |
| 300 | 301 | return; |
| ... | ... | @@ -805,7 +806,7 @@ void decode_opc(DisasContext * ctx) |
| 805 | 806 | CHECK_NOT_DELAY_SLOT |
| 806 | 807 | gen_conditional_jump(ctx, ctx->pc + 2, |
| 807 | 808 | ctx->pc + 4 + B7_0s * 2); |
| 808 | - ctx->flags |= BRANCH_CONDITIONAL; | |
| 809 | + ctx->bstate = BS_BRANCH; | |
| 809 | 810 | return; |
| 810 | 811 | case 0x8f00: /* bf/s label */ |
| 811 | 812 | CHECK_NOT_DELAY_SLOT |
| ... | ... | @@ -816,7 +817,7 @@ void decode_opc(DisasContext * ctx) |
| 816 | 817 | CHECK_NOT_DELAY_SLOT |
| 817 | 818 | gen_conditional_jump(ctx, ctx->pc + 4 + B7_0s * 2, |
| 818 | 819 | ctx->pc + 2); |
| 819 | - ctx->flags |= BRANCH_CONDITIONAL; | |
| 820 | + ctx->bstate = BS_BRANCH; | |
| 820 | 821 | return; |
| 821 | 822 | case 0x8d00: /* bt/s label */ |
| 822 | 823 | CHECK_NOT_DELAY_SLOT |
| ... | ... | @@ -908,7 +909,7 @@ void decode_opc(DisasContext * ctx) |
| 908 | 909 | case 0xc300: /* trapa #imm */ |
| 909 | 910 | CHECK_NOT_DELAY_SLOT gen_op_movl_imm_PC(ctx->pc); |
| 910 | 911 | gen_op_trapa(B7_0); |
| 911 | - ctx->flags |= BRANCH; | |
| 912 | + ctx->bstate = BS_BRANCH; | |
| 912 | 913 | return; |
| 913 | 914 | case 0xc800: /* tst #imm,R0 */ |
| 914 | 915 | gen_op_tst_imm_rN(B7_0, REG(0)); |
| ... | ... | @@ -1012,8 +1013,8 @@ void decode_opc(DisasContext * ctx) |
| 1012 | 1013 | gen_op_movl_rN_T1 (REG(B11_8)); \ |
| 1013 | 1014 | gen_op_stl_T0_T1 (ctx); \ |
| 1014 | 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 | 1018 | LDST(gbr, 0x401e, 0x4017, ldc, 0x0012, 0x4013, stc,) |
| 1018 | 1019 | LDST(vbr, 0x402e, 0x4027, ldc, 0x0022, 0x4023, stc,) |
| 1019 | 1020 | LDST(ssr, 0x403e, 0x4037, ldc, 0x0032, 0x4033, stc,) |
| ... | ... | @@ -1023,8 +1024,8 @@ void decode_opc(DisasContext * ctx) |
| 1023 | 1024 | LDST(macl, 0x401a, 0x4016, lds, 0x001a, 0x4012, sts,) |
| 1024 | 1025 | LDST(pr, 0x402a, 0x4026, lds, 0x002a, 0x4022, sts,) |
| 1025 | 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 | 1029 | case 0x00c3: /* movca.l R0,@Rm */ |
| 1029 | 1030 | gen_op_movl_rN_T0(REG(0)); |
| 1030 | 1031 | gen_op_movl_rN_T1(REG(B11_8)); |
| ... | ... | @@ -1141,7 +1142,28 @@ void decode_opc(DisasContext * ctx) |
| 1141 | 1142 | fprintf(stderr, "unknown instruction 0x%04x at pc 0x%08x\n", |
| 1142 | 1143 | ctx->opcode, ctx->pc); |
| 1143 | 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 | 1169 | static inline int |
| ... | ... | @@ -1151,7 +1173,6 @@ gen_intermediate_code_internal(CPUState * env, TranslationBlock * tb, |
| 1151 | 1173 | DisasContext ctx; |
| 1152 | 1174 | target_ulong pc_start; |
| 1153 | 1175 | static uint16_t *gen_opc_end; |
| 1154 | - uint32_t old_flags; | |
| 1155 | 1176 | int i, ii; |
| 1156 | 1177 | |
| 1157 | 1178 | pc_start = tb->pc; |
| ... | ... | @@ -1159,14 +1180,14 @@ gen_intermediate_code_internal(CPUState * env, TranslationBlock * tb, |
| 1159 | 1180 | gen_opc_end = gen_opc_buf + OPC_MAX_SIZE; |
| 1160 | 1181 | gen_opparam_ptr = gen_opparam_buf; |
| 1161 | 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 | 1185 | ctx.sr = env->sr; |
| 1165 | 1186 | ctx.fpscr = env->fpscr; |
| 1166 | 1187 | ctx.memidx = (env->sr & SR_MD) ? 1 : 0; |
| 1167 | 1188 | /* We don't know if the delayed pc came from a dynamic or static branch, |
| 1168 | 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 | 1191 | ctx.tb = tb; |
| 1171 | 1192 | ctx.singlestep_enabled = env->singlestep_enabled; |
| 1172 | 1193 | nb_gen_labels = 0; |
| ... | ... | @@ -1180,18 +1201,14 @@ gen_intermediate_code_internal(CPUState * env, TranslationBlock * tb, |
| 1180 | 1201 | #endif |
| 1181 | 1202 | |
| 1182 | 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 | 1205 | if (env->nb_breakpoints > 0) { |
| 1189 | 1206 | for (i = 0; i < env->nb_breakpoints; i++) { |
| 1190 | 1207 | if (ctx.pc == env->breakpoints[i]) { |
| 1191 | 1208 | /* We have hit a breakpoint - make sure PC is up-to-date */ |
| 1192 | 1209 | gen_op_movl_imm_PC(ctx.pc); |
| 1193 | 1210 | gen_op_debug(); |
| 1194 | - ctx.flags |= BRANCH_EXCEPTION; | |
| 1211 | + ctx.bstate = BS_EXCP; | |
| 1195 | 1212 | break; |
| 1196 | 1213 | } |
| 1197 | 1214 | } |
| ... | ... | @@ -1204,6 +1221,7 @@ gen_intermediate_code_internal(CPUState * env, TranslationBlock * tb, |
| 1204 | 1221 | gen_opc_instr_start[ii++] = 0; |
| 1205 | 1222 | } |
| 1206 | 1223 | gen_opc_pc[ii] = ctx.pc; |
| 1224 | + gen_opc_hflags[ii] = ctx.flags; | |
| 1207 | 1225 | gen_opc_instr_start[ii] = 1; |
| 1208 | 1226 | } |
| 1209 | 1227 | #if 0 |
| ... | ... | @@ -1221,21 +1239,30 @@ gen_intermediate_code_internal(CPUState * env, TranslationBlock * tb, |
| 1221 | 1239 | break; |
| 1222 | 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 | 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 | 1266 | *gen_opc_ptr = INDEX_op_end; |
| 1240 | 1267 | if (search_pc) { |
| 1241 | 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 | 53 | #elif defined(TARGET_SPARC) |
| 54 | 54 | target_ulong gen_opc_npc[OPC_BUF_SIZE]; |
| 55 | 55 | target_ulong gen_opc_jump_pc[2]; |
| 56 | -#elif defined(TARGET_MIPS) | |
| 56 | +#elif defined(TARGET_MIPS) || defined(TARGET_SH4) | |
| 57 | 57 | uint32_t gen_opc_hflags[OPC_BUF_SIZE]; |
| 58 | 58 | #endif |
| 59 | 59 | |
| ... | ... | @@ -298,6 +298,9 @@ int cpu_restore_state(TranslationBlock *tb, |
| 298 | 298 | env->hflags |= gen_opc_hflags[j]; |
| 299 | 299 | #elif defined(TARGET_ALPHA) |
| 300 | 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 | 304 | #endif |
| 302 | 305 | return 0; |
| 303 | 306 | } | ... | ... |