From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:46256) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YzXCt-0003T5-Vx for qemu-devel@nongnu.org; Mon, 01 Jun 2015 17:25:17 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1YzXCs-0008LR-Fy for qemu-devel@nongnu.org; Mon, 01 Jun 2015 17:25:15 -0400 Received: from hall.aurel32.net ([2001:bc8:30d7:101::1]:56102) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YzXCs-00087a-58 for qemu-devel@nongnu.org; Mon, 01 Jun 2015 17:25:14 -0400 From: Aurelien Jarno Date: Mon, 1 Jun 2015 23:24:56 +0200 Message-Id: <1433193897-24110-13-git-send-email-aurelien@aurel32.net> In-Reply-To: <1433193897-24110-1-git-send-email-aurelien@aurel32.net> References: <1433193897-24110-1-git-send-email-aurelien@aurel32.net> Subject: [Qemu-devel] [PATCH 12/13] target-s390x: implement load-and-trap facility List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: Alexander Graf , Aurelien Jarno , Richard Henderson At the same time move the trap code from op_ct into gen_trap and use it for all new functions. The value needs to be stored back to register before the exception, but also before the brcond (as we don't use temp locals). That's why we can't use wout helper. Cc: Alexander Graf Cc: Richard Henderson Signed-off-by: Aurelien Jarno --- target-s390x/insn-data.def | 10 ++++++ target-s390x/translate.c | 80 ++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 81 insertions(+), 9 deletions(-) diff --git a/target-s390x/insn-data.def b/target-s390x/insn-data.def index b0ee9bc..2484387 100644 --- a/target-s390x/insn-data.def +++ b/target-s390x/insn-data.def @@ -389,6 +389,9 @@ C(0xb302, LTEBR, RRE, Z, 0, e2, 0, cond_e1e2, mov2, f32) C(0xb312, LTDBR, RRE, Z, 0, f2_o, 0, f1, mov2, f64) C(0xb342, LTXBR, RRE, Z, 0, x2_o, 0, x1, movx, f128) +/* LOAD AND TRAP */ + C(0xe39f, LAT, RXY_a, LAT, 0, m2_32u, r1, 0, lat, 0) + C(0xe385, LGAT, RXY_a, LAT, 0, a2, r1, 0, lgat, 0) /* LOAD BYTE */ C(0xb926, LBR, RRE, EI, 0, r2_8s, 0, r1_32, mov2, 0) C(0xb906, LGBR, RRE, EI, 0, r2_8s, 0, r1, mov2, 0) @@ -414,9 +417,13 @@ /* LOAD HALFWORD RELATIVE LONG */ C(0xc405, LHRL, RIL_b, GIE, 0, ri2, new, r1_32, ld16s, 0) C(0xc404, LGHRL, RIL_b, GIE, 0, ri2, r1, 0, ld16s, 0) +/* LOAG HIGH AND TRAP */ + C(0xe3c8, LFHAT, RXY_a, LAT, 0, m2_32u, r1, 0, lfhat, 0) /* LOAD LOGICAL */ C(0xb916, LLGFR, RRE, Z, 0, r2_32u, 0, r1, mov2, 0) C(0xe316, LLGF, RXY_a, Z, 0, a2, r1, 0, ld32u, 0) +/* LOAD LOGICAL AND TRAP */ + C(0xe39d, LLGFAT, RXY_a, LAT, 0, a2, r1, 0, llgfat, 0) /* LOAD LOGICAL RELATIVE LONG */ C(0xc40e, LLGFRL, RIL_b, GIE, 0, ri2, r1, 0, ld32u, 0) /* LOAD LOGICAL CHARACTER */ @@ -442,6 +449,9 @@ /* LOAD LOGICAL THIRTY ONE BITS */ C(0xb917, LLGTR, RRE, Z, 0, r2_o, r1, 0, llgt, 0) C(0xe317, LLGT, RXY_a, Z, 0, m2_32u, r1, 0, llgt, 0) +/* LOAD LOGICAL THIRTY ONE BITS AND TRAP */ + C(0xe39c, LLGTAT, RXY_a, LAT, 0, m2_32u, r1, 0, llgtat, 0) + /* LOAD FPR FROM GR */ C(0xb3c1, LDGR, RRE, FPRGR, 0, r2_o, 0, f1, mov2, 0) /* LOAD GR FROM FPR */ diff --git a/target-s390x/translate.c b/target-s390x/translate.c index b792dae..5522f94 100644 --- a/target-s390x/translate.c +++ b/target-s390x/translate.c @@ -323,6 +323,20 @@ static inline void gen_illegal_opcode(DisasContext *s) gen_program_exception(s, PGM_OPERATION); } +static inline void gen_trap(DisasContext *s) +{ + TCGv_i32 t; + + /* Set DXC to 0xff. */ + t = tcg_temp_new_i32(); + tcg_gen_ld_i32(t, cpu_env, offsetof(CPUS390XState, fpc)); + tcg_gen_ori_i32(t, t, 0xff00); + tcg_gen_st_i32(t, cpu_env, offsetof(CPUS390XState, fpc)); + tcg_temp_free_i32(t); + + gen_program_exception(s, PGM_DATA); +} + #ifndef CONFIG_USER_ONLY static void check_privileged(DisasContext *s) { @@ -1120,6 +1134,7 @@ typedef enum DisasFacility { FAC_HW, /* high-word */ FAC_IEEEE_SIM, /* IEEE exception sumilation */ FAC_MIE, /* miscellaneous-instruction-extensions */ + FAC_LAT, /* load-and-trap */ FAC_LOC, /* load/store on condition */ FAC_LD, /* long displacement */ FAC_PC, /* population count */ @@ -1968,7 +1983,6 @@ static ExitStatus op_ct(DisasContext *s, DisasOps *o) { int m3 = get_field(s->fields, m3); TCGLabel *lab = gen_new_label(); - TCGv_i32 t; TCGCond c; c = tcg_invert_cond(ltgt_cond[m3]); @@ -1977,15 +1991,8 @@ static ExitStatus op_ct(DisasContext *s, DisasOps *o) } tcg_gen_brcond_i64(c, o->in1, o->in2, lab); - /* Set DXC to 0xff. */ - t = tcg_temp_new_i32(); - tcg_gen_ld_i32(t, cpu_env, offsetof(CPUS390XState, fpc)); - tcg_gen_ori_i32(t, t, 0xff00); - tcg_gen_st_i32(t, cpu_env, offsetof(CPUS390XState, fpc)); - tcg_temp_free_i32(t); - /* Trap. */ - gen_program_exception(s, PGM_DATA); + gen_trap(s); gen_set_label(lab); return NO_EXIT; @@ -2351,6 +2358,61 @@ static ExitStatus op_ld64(DisasContext *s, DisasOps *o) return NO_EXIT; } +static ExitStatus op_lat(DisasContext *s, DisasOps *o) +{ + TCGLabel *lab = gen_new_label(); + store_reg32_i64(get_field(s->fields, r1), o->in2); + /* The value is stored even in case of trap. */ + tcg_gen_brcondi_i64(TCG_COND_NE, o->in2, 0, lab); + gen_trap(s); + gen_set_label(lab); + return NO_EXIT; +} + +static ExitStatus op_lgat(DisasContext *s, DisasOps *o) +{ + TCGLabel *lab = gen_new_label(); + tcg_gen_qemu_ld64(o->out, o->in2, get_mem_index(s)); + /* The value is stored even in case of trap. */ + tcg_gen_brcondi_i64(TCG_COND_NE, o->out, 0, lab); + gen_trap(s); + gen_set_label(lab); + return NO_EXIT; +} + +static ExitStatus op_lfhat(DisasContext *s, DisasOps *o) +{ + TCGLabel *lab = gen_new_label(); + store_reg32h_i64(get_field(s->fields, r1), o->in2); + /* The value is stored even in case of trap. */ + tcg_gen_brcondi_i64(TCG_COND_NE, o->in2, 0, lab); + gen_trap(s); + gen_set_label(lab); + return NO_EXIT; +} + +static ExitStatus op_llgfat(DisasContext *s, DisasOps *o) +{ + TCGLabel *lab = gen_new_label(); + tcg_gen_qemu_ld32u(o->out, o->in2, get_mem_index(s)); + /* The value is stored even in case of trap. */ + tcg_gen_brcondi_i64(TCG_COND_NE, o->out, 0, lab); + gen_trap(s); + gen_set_label(lab); + return NO_EXIT; +} + +static ExitStatus op_llgtat(DisasContext *s, DisasOps *o) +{ + TCGLabel *lab = gen_new_label(); + tcg_gen_andi_i64(o->out, o->in2, 0x7fffffff); + /* The value is stored even in case of trap. */ + tcg_gen_brcondi_i64(TCG_COND_NE, o->out, 0, lab); + gen_trap(s); + gen_set_label(lab); + return NO_EXIT; +} + static ExitStatus op_loc(DisasContext *s, DisasOps *o) { DisasCompare c; -- 2.1.4