[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PULL v2 31/70] target/s390x: Fix some helper_ex problems
From: |
Richard Henderson |
Subject: |
[Qemu-devel] [PULL v2 31/70] target/s390x: Fix some helper_ex problems |
Date: |
Tue, 6 Jun 2017 17:30:40 -0700 |
(1) The OR of the low bits or R1 into INSN were not being done
consistently; it was forgotten along all but the SVC path.
(2) The setting of ILEN was wrong on SVC path for EXRL.
(3) The data load for ICM read too much.
Fix these by consolidating data load at the beginning, using
get_ilen to control the number of bytes loaded, and ORing in
the byte from R1. Use extract64 from the full aligned insn
to extract arguments.
Pass in ILEN rather than RET as the more natural way to give
the required data along the SVC path.
Modify ENV->CC_OP directly rather than include it in the
functional interface.
Reviewed-by: Aurelien Jarno <address@hidden>
Signed-off-by: Richard Henderson <address@hidden>
---
target/s390x/helper.h | 2 +-
target/s390x/mem_helper.c | 135 +++++++++++++++++++++++++---------------------
target/s390x/translate.c | 8 +--
3 files changed, 78 insertions(+), 67 deletions(-)
diff --git a/target/s390x/helper.h b/target/s390x/helper.h
index ea35834..3819409 100644
--- a/target/s390x/helper.h
+++ b/target/s390x/helper.h
@@ -14,7 +14,7 @@ DEF_HELPER_4(srst, i64, env, i64, i64, i64)
DEF_HELPER_4(clst, i64, env, i64, i64, i64)
DEF_HELPER_FLAGS_4(mvpg, TCG_CALL_NO_WG, i32, env, i64, i64, i64)
DEF_HELPER_4(mvst, i64, env, i64, i64, i64)
-DEF_HELPER_5(ex, i32, env, i32, i64, i64, i64)
+DEF_HELPER_4(ex, void, env, i32, i64, i64)
DEF_HELPER_FLAGS_4(stam, TCG_CALL_NO_WG, void, env, i32, i64, i32)
DEF_HELPER_FLAGS_4(lam, TCG_CALL_NO_WG, void, env, i32, i64, i32)
DEF_HELPER_4(mvcle, i32, env, i32, i64, i32)
diff --git a/target/s390x/mem_helper.c b/target/s390x/mem_helper.c
index a73d486..fa03129 100644
--- a/target/s390x/mem_helper.c
+++ b/target/s390x/mem_helper.c
@@ -1245,76 +1245,87 @@ uint64_t HELPER(lra)(CPUS390XState *env, uint64_t addr)
in other words: tricky...
currently implemented by interpreting the cases it is most commonly used.
*/
-uint32_t HELPER(ex)(CPUS390XState *env, uint32_t cc, uint64_t v1,
- uint64_t addr, uint64_t ret)
+void HELPER(ex)(CPUS390XState *env, uint32_t ilen, uint64_t r1, uint64_t addr)
{
S390CPU *cpu = s390_env_get_cpu(env);
- uint16_t insn = cpu_lduw_code(env, addr);
-
- HELPER_LOG("%s: v1 0x%lx addr 0x%lx insn 0x%x\n", __func__, v1, addr,
- insn);
- if ((insn & 0xf0ff) == 0xd000) {
- uint32_t l, insn2, b1, b2, d1, d2;
-
- l = v1 & 0xff;
- insn2 = cpu_ldl_code(env, addr + 2);
- b1 = (insn2 >> 28) & 0xf;
- b2 = (insn2 >> 12) & 0xf;
- d1 = (insn2 >> 16) & 0xfff;
- d2 = insn2 & 0xfff;
- switch (insn & 0xf00) {
- case 0x200:
+ uint64_t insn = cpu_lduw_code(env, addr);
+ uint8_t opc = insn >> 8;
+
+ /* Or in the contents of R1[56:63]. */
+ insn |= r1 & 0xff;
+
+ /* Load the rest of the instruction. */
+ insn <<= 48;
+ switch (get_ilen(opc)) {
+ case 2:
+ break;
+ case 4:
+ insn |= (uint64_t)cpu_lduw_code(env, addr + 2) << 32;
+ break;
+ case 6:
+ insn |= (uint64_t)(uint32_t)cpu_ldl_code(env, addr + 2) << 16;
+ break;
+ default:
+ g_assert_not_reached();
+ }
+
+ HELPER_LOG("%s: addr 0x%lx insn 0x%" PRIx64 "\n", __func__, addr, insn);
+
+ if ((opc & 0xf0) == 0xd0) {
+ uint32_t l, b1, b2, d1, d2;
+
+ l = extract64(insn, 48, 8);
+ b1 = extract64(insn, 44, 4);
+ b2 = extract64(insn, 28, 4);
+ d1 = extract64(insn, 32, 12);
+ d2 = extract64(insn, 16, 12);
+ switch (opc & 0xf) {
+ case 0x2:
do_helper_mvc(env, l, get_address(env, 0, b1, d1),
get_address(env, 0, b2, d2), 0);
- break;
- case 0x400:
- cc = do_helper_nc(env, l, get_address(env, 0, b1, d1),
- get_address(env, 0, b2, d2), 0);
- break;
- case 0x500:
- cc = do_helper_clc(env, l, get_address(env, 0, b1, d1),
- get_address(env, 0, b2, d2), 0);
- break;
- case 0x600:
- cc = do_helper_oc(env, l, get_address(env, 0, b1, d1),
- get_address(env, 0, b2, d2), 0);
- break;
- case 0x700:
- cc = do_helper_xc(env, l, get_address(env, 0, b1, d1),
- get_address(env, 0, b2, d2), 0);
- break;
- case 0xc00:
+ return;
+ case 0x4:
+ env->cc_op = do_helper_nc(env, l, get_address(env, 0, b1, d1),
+ get_address(env, 0, b2, d2), 0);
+ return;
+ case 0x5:
+ env->cc_op = do_helper_clc(env, l, get_address(env, 0, b1, d1),
+ get_address(env, 0, b2, d2), 0);
+ return;
+ case 0x6:
+ env->cc_op = do_helper_oc(env, l, get_address(env, 0, b1, d1),
+ get_address(env, 0, b2, d2), 0);
+ return;
+ case 0x7:
+ env->cc_op = do_helper_xc(env, l, get_address(env, 0, b1, d1),
+ get_address(env, 0, b2, d2), 0);
+ return;
+ case 0xc:
do_helper_tr(env, l, get_address(env, 0, b1, d1),
get_address(env, 0, b2, d2), 0);
- return cc;
- case 0xd00:
- cc = do_helper_trt(env, l, get_address(env, 0, b1, d1),
- get_address(env, 0, b2, d2), 0);
- break;
- default:
- goto abort;
+ return;
+ case 0xd:
+ env->cc_op = do_helper_trt(env, l, get_address(env, 0, b1, d1),
+ get_address(env, 0, b2, d2), 0);
+ return;
}
- } else if ((insn & 0xff00) == 0x0a00) {
+ } else if (opc == 0x0a) {
/* supervisor call */
- HELPER_LOG("%s: svc %ld via execute\n", __func__, (insn | v1) & 0xff);
- env->psw.addr = ret - 4;
- env->int_svc_code = (insn | v1) & 0xff;
- env->int_svc_ilen = 4;
+ env->int_svc_code = extract64(insn, 48, 8);
+ env->int_svc_ilen = ilen;
helper_exception(env, EXCP_SVC);
- } else if ((insn & 0xff00) == 0xbf00) {
- uint32_t insn2, r1, r3, b2, d2;
-
- insn2 = cpu_ldl_code(env, addr + 2);
- r1 = (insn2 >> 20) & 0xf;
- r3 = (insn2 >> 16) & 0xf;
- b2 = (insn2 >> 12) & 0xf;
- d2 = insn2 & 0xfff;
- cc = helper_icm(env, r1, get_address(env, 0, b2, d2), r3);
- } else {
- abort:
- cpu_abort(CPU(cpu),
- "EXECUTE on instruction prefix 0x%x not implemented\n",
- insn);
+ return;
+ } else if (opc == 0xbf) {
+ uint32_t r1, r3, b2, d2;
+
+ r1 = extract64(insn, 52, 4);
+ r3 = extract64(insn, 48, 4);
+ b2 = extract64(insn, 44, 4);
+ d2 = extract64(insn, 32, 12);
+ env->cc_op = helper_icm(env, r1, get_address(env, 0, b2, d2), r3);
+ return;
}
- return cc;
+
+ cpu_abort(CPU(cpu), "EXECUTE on instruction prefix 0x%x not implemented\n",
+ opc);
}
diff --git a/target/s390x/translate.c b/target/s390x/translate.c
index e99fbd9..c1162a1 100644
--- a/target/s390x/translate.c
+++ b/target/s390x/translate.c
@@ -2164,14 +2164,14 @@ static ExitStatus op_ex(DisasContext *s, DisasOps *o)
MVC inside of memcpy, which needs a helper call anyway. So
perhaps this doesn't bear thinking about any further. */
- TCGv_i64 tmp;
+ TCGv_i32 ilen;
update_psw_addr(s);
gen_op_calc_cc(s);
- tmp = tcg_const_i64(s->next_pc);
- gen_helper_ex(cc_op, cpu_env, cc_op, o->in1, o->in2, tmp);
- tcg_temp_free_i64(tmp);
+ ilen = tcg_const_i32(s->next_pc - s->pc);
+ gen_helper_ex(cpu_env, ilen, o->in1, o->in2);
+ tcg_temp_free_i32(ilen);
return NO_EXIT;
}
--
2.9.4
- [Qemu-devel] [PULL v2 22/70] target/s390x: Use unwind data for helper_tre, (continued)
- [Qemu-devel] [PULL v2 22/70] target/s390x: Use unwind data for helper_tre, Richard Henderson, 2017/06/06
- [Qemu-devel] [PULL v2 23/70] target/s390x: Use unwind data for helper_trt, Richard Henderson, 2017/06/06
- [Qemu-devel] [PULL v2 24/70] target/s390x: Use unwind data for helper_lctlg, Richard Henderson, 2017/06/06
- [Qemu-devel] [PULL v2 25/70] target/s390x: Use unwind data for helper_lctl, Richard Henderson, 2017/06/06
- [Qemu-devel] [PULL v2 26/70] target/s390x: Use unwind data for helper_stctl, Richard Henderson, 2017/06/06
- [Qemu-devel] [PULL v2 27/70] target/s390x: Use unwind data for helper_testblock, Richard Henderson, 2017/06/06
- [Qemu-devel] [PULL v2 28/70] target/s390x: Use unwind data for helper_tprot, Richard Henderson, 2017/06/06
- [Qemu-devel] [PULL v2 30/70] target/s390x: Use unwind data for helper_mvcs/mvcp, Richard Henderson, 2017/06/06
- [Qemu-devel] [PULL v2 32/70] target/s390x: Fix EXECUTE with R1==0, Richard Henderson, 2017/06/06
- [Qemu-devel] [PULL v2 29/70] target/s390x: Use unwind data for helper_lra, Richard Henderson, 2017/06/06
- [Qemu-devel] [PULL v2 31/70] target/s390x: Fix some helper_ex problems,
Richard Henderson <=
- [Qemu-devel] [PULL v2 34/70] target/s390x: Implement CSPG, Richard Henderson, 2017/06/06
- [Qemu-devel] [PULL v2 33/70] target/s390x: Use atomic operations for COMPARE SWAP PURGE, Richard Henderson, 2017/06/06
- [Qemu-devel] [PULL v2 36/70] target/s390x: End the TB after EXECUTE, Richard Henderson, 2017/06/06
- [Qemu-devel] [PULL v2 37/70] target/s390x: Implement EXECUTE via new TranslationBlock, Richard Henderson, 2017/06/06
- [Qemu-devel] [PULL v2 35/70] target/s390x: Save current ilen during translation, Richard Henderson, 2017/06/06
- [Qemu-devel] [PULL v2 38/70] target/s390x: Re-implement a few EXECUTE target insns directly, Richard Henderson, 2017/06/06
- [Qemu-devel] [PULL v2 40/70] target/s390x: remove dead code in translate.c, Richard Henderson, 2017/06/06
- [Qemu-devel] [PULL v2 41/70] target/s390x: remove some Linux assumptions from IPTE, Richard Henderson, 2017/06/06
- [Qemu-devel] [PULL v2 39/70] target/s390x/cpu_models: Allow some additional feature bits for the "qemu" CPU, Richard Henderson, 2017/06/06
- [Qemu-devel] [PULL v2 43/70] target/s390x: implement TEST AND SET, Richard Henderson, 2017/06/06