提交 06fc0348 编写于 作者: R Richard Henderson

target/s390x: End the TB after EXECUTE

This split will be required for implementing EXECUTE properly.
Do this now as a separate step to aid comparison of before and
after TB listings.
Reviewed-by: NAurelien Jarno <aurelien@aurel32.net>
Signed-off-by: NRichard Henderson <rth@twiddle.net>
上级 99e57856
...@@ -1234,6 +1234,7 @@ void HELPER(ex)(CPUS390XState *env, uint32_t ilen, uint64_t r1, uint64_t addr) ...@@ -1234,6 +1234,7 @@ void HELPER(ex)(CPUS390XState *env, uint32_t ilen, uint64_t r1, uint64_t addr)
S390CPU *cpu = s390_env_get_cpu(env); S390CPU *cpu = s390_env_get_cpu(env);
uint64_t insn = cpu_lduw_code(env, addr); uint64_t insn = cpu_lduw_code(env, addr);
uint8_t opc = insn >> 8; uint8_t opc = insn >> 8;
uint32_t cc;
/* Or in the contents of R1[56:63]. */ /* Or in the contents of R1[56:63]. */
insn |= r1 & 0xff; insn |= r1 & 0xff;
...@@ -1263,42 +1264,46 @@ void HELPER(ex)(CPUS390XState *env, uint32_t ilen, uint64_t r1, uint64_t addr) ...@@ -1263,42 +1264,46 @@ void HELPER(ex)(CPUS390XState *env, uint32_t ilen, uint64_t r1, uint64_t addr)
b2 = extract64(insn, 28, 4); b2 = extract64(insn, 28, 4);
d1 = extract64(insn, 32, 12); d1 = extract64(insn, 32, 12);
d2 = extract64(insn, 16, 12); d2 = extract64(insn, 16, 12);
cc = env->cc_op;
switch (opc & 0xf) { switch (opc & 0xf) {
case 0x2: case 0x2:
do_helper_mvc(env, l, get_address(env, 0, b1, d1), do_helper_mvc(env, l, get_address(env, 0, b1, d1),
get_address(env, 0, b2, d2), 0); get_address(env, 0, b2, d2), 0);
return; break;
case 0x4: case 0x4:
env->cc_op = do_helper_nc(env, l, get_address(env, 0, b1, d1), cc = do_helper_nc(env, l, get_address(env, 0, b1, d1),
get_address(env, 0, b2, d2), 0); get_address(env, 0, b2, d2), 0);
return; break;
case 0x5: case 0x5:
env->cc_op = do_helper_clc(env, l, get_address(env, 0, b1, d1), cc = do_helper_clc(env, l, get_address(env, 0, b1, d1),
get_address(env, 0, b2, d2), 0); get_address(env, 0, b2, d2), 0);
return; break;
case 0x6: case 0x6:
env->cc_op = do_helper_oc(env, l, get_address(env, 0, b1, d1), cc = do_helper_oc(env, l, get_address(env, 0, b1, d1),
get_address(env, 0, b2, d2), 0); get_address(env, 0, b2, d2), 0);
return; break;
case 0x7: case 0x7:
env->cc_op = do_helper_xc(env, l, get_address(env, 0, b1, d1), cc = do_helper_xc(env, l, get_address(env, 0, b1, d1),
get_address(env, 0, b2, d2), 0); get_address(env, 0, b2, d2), 0);
return; break;
case 0xc: case 0xc:
do_helper_tr(env, l, get_address(env, 0, b1, d1), do_helper_tr(env, l, get_address(env, 0, b1, d1),
get_address(env, 0, b2, d2), 0); get_address(env, 0, b2, d2), 0);
return; break;
case 0xd: case 0xd:
env->cc_op = do_helper_trt(env, l, get_address(env, 0, b1, d1), cc = do_helper_trt(env, l, get_address(env, 0, b1, d1),
get_address(env, 0, b2, d2), 0); get_address(env, 0, b2, d2), 0);
return; break;
default:
goto abort;
} }
} else if (opc == 0x0a) { } else if (opc == 0x0a) {
/* supervisor call */ /* supervisor call */
env->int_svc_code = extract64(insn, 48, 8); env->int_svc_code = extract64(insn, 48, 8);
env->int_svc_ilen = ilen; env->int_svc_ilen = ilen;
helper_exception(env, EXCP_SVC); helper_exception(env, EXCP_SVC);
return; g_assert_not_reached();
} else if (opc == 0xbf) { } else if (opc == 0xbf) {
uint32_t r1, r3, b2, d2; uint32_t r1, r3, b2, d2;
...@@ -1306,10 +1311,15 @@ void HELPER(ex)(CPUS390XState *env, uint32_t ilen, uint64_t r1, uint64_t addr) ...@@ -1306,10 +1311,15 @@ void HELPER(ex)(CPUS390XState *env, uint32_t ilen, uint64_t r1, uint64_t addr)
r3 = extract64(insn, 48, 4); r3 = extract64(insn, 48, 4);
b2 = extract64(insn, 44, 4); b2 = extract64(insn, 44, 4);
d2 = extract64(insn, 32, 12); d2 = extract64(insn, 32, 12);
env->cc_op = helper_icm(env, r1, get_address(env, 0, b2, d2), r3); cc = helper_icm(env, r1, get_address(env, 0, b2, d2), r3);
return; } else {
abort:
cpu_abort(CPU(cpu),
"EXECUTE on instruction prefix 0x%x not implemented\n",
opc);
g_assert_not_reached();
} }
cpu_abort(CPU(cpu), "EXECUTE on instruction prefix 0x%x not implemented\n", env->cc_op = cc;
opc); env->psw.addr += ilen;
} }
...@@ -1168,6 +1168,8 @@ typedef enum { ...@@ -1168,6 +1168,8 @@ typedef enum {
the PC (for whatever reason), so there's no need to do it again on the PC (for whatever reason), so there's no need to do it again on
exiting the TB. */ exiting the TB. */
EXIT_PC_UPDATED, EXIT_PC_UPDATED,
/* We have updated the PC and CC values. */
EXIT_PC_CC_UPDATED,
/* We are exiting the TB, but have neither emitted a goto_tb, nor /* We are exiting the TB, but have neither emitted a goto_tb, nor
updated the PC for the next instruction to be executed. */ updated the PC for the next instruction to be executed. */
EXIT_PC_STALE, EXIT_PC_STALE,
...@@ -2221,7 +2223,7 @@ static ExitStatus op_ex(DisasContext *s, DisasOps *o) ...@@ -2221,7 +2223,7 @@ static ExitStatus op_ex(DisasContext *s, DisasOps *o)
tcg_temp_free_i64(v1); tcg_temp_free_i64(v1);
} }
return NO_EXIT; return EXIT_PC_CC_UPDATED;
} }
static ExitStatus op_fieb(DisasContext *s, DisasOps *o) static ExitStatus op_fieb(DisasContext *s, DisasOps *o)
...@@ -5494,6 +5496,8 @@ void gen_intermediate_code(CPUS390XState *env, struct TranslationBlock *tb) ...@@ -5494,6 +5496,8 @@ void gen_intermediate_code(CPUS390XState *env, struct TranslationBlock *tb)
/* Next TB starts off with CC_OP_DYNAMIC, so make sure the /* Next TB starts off with CC_OP_DYNAMIC, so make sure the
cc op type is in env */ cc op type is in env */
update_cc_op(&dc); update_cc_op(&dc);
/* FALLTHRU */
case EXIT_PC_CC_UPDATED:
/* Exit the TB, either by raising a debug exception or by return. */ /* Exit the TB, either by raising a debug exception or by return. */
if (do_debug) { if (do_debug) {
gen_exception(EXCP_DEBUG); gen_exception(EXCP_DEBUG);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册