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: Aurelien Jarno <aurelien@aurel32.net>
Signed-off-by: Richard Henderson <rth@twiddle.net>
This commit is contained in:
Richard Henderson 2017-05-24 13:00:16 -07:00
parent 99e57856f6
commit 06fc03486c
2 changed files with 37 additions and 23 deletions

View file

@ -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)
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)
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;
} }

View file

@ -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)
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)
/* 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);