From patchwork Wed Jun 17 10:43:02 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexander Graf X-Patchwork-Id: 485346 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 721C51401DA for ; Wed, 17 Jun 2015 20:56:33 +1000 (AEST) Received: from localhost ([::1]:45658 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Z5B1D-0002nv-Pr for incoming@patchwork.ozlabs.org; Wed, 17 Jun 2015 06:56:31 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:55611) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Z5AoP-0004ak-W1 for qemu-devel@nongnu.org; Wed, 17 Jun 2015 06:43:20 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Z5AoK-0005Yk-VS for qemu-devel@nongnu.org; Wed, 17 Jun 2015 06:43:17 -0400 Received: from cantor2.suse.de ([195.135.220.15]:52319 helo=mx2.suse.de) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Z5AoK-0005Wl-Mj for qemu-devel@nongnu.org; Wed, 17 Jun 2015 06:43:12 -0400 X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay1.suse.de (charybdis-ext.suse.de [195.135.220.254]) by mx2.suse.de (Postfix) with ESMTP id 1EB6B75026; Wed, 17 Jun 2015 10:43:11 +0000 (UTC) From: Alexander Graf To: qemu-devel@nongnu.org Date: Wed, 17 Jun 2015 12:43:02 +0200 Message-Id: <1434537789-63782-20-git-send-email-agraf@suse.de> X-Mailer: git-send-email 1.7.12.4 In-Reply-To: <1434537789-63782-1-git-send-email-agraf@suse.de> References: <1434537789-63782-1-git-send-email-agraf@suse.de> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x (no timestamps) [generic] X-Received-From: 195.135.220.15 Cc: peter.maydell@linaro.org, Aurelien Jarno Subject: [Qemu-devel] [PULL 19/26] target-s390x: PER successful-branching event support X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org From: Aurelien Jarno For the PER successful-branching event support, we can't rely on any QEMU infrastucture. We therefore call an helper in all places where a branch can be taken. We have to pay attention to the branch to next case, as it's still a taken branch. We don't need to care about the cases using goto_tb, as we have disabled them in the previous patch. Signed-off-by: Aurelien Jarno Signed-off-by: Alexander Graf --- target-s390x/helper.h | 1 + target-s390x/misc_helper.c | 11 +++++++++++ target-s390x/translate.c | 39 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 51 insertions(+) diff --git a/target-s390x/helper.h b/target-s390x/helper.h index 7d2fa90..89197cb 100644 --- a/target-s390x/helper.h +++ b/target-s390x/helper.h @@ -117,6 +117,7 @@ DEF_HELPER_FLAGS_2(lurag, TCG_CALL_NO_WG, i64, env, i64) DEF_HELPER_FLAGS_3(stura, TCG_CALL_NO_WG, void, env, i64, i64) DEF_HELPER_FLAGS_3(sturg, TCG_CALL_NO_WG, void, env, i64, i64) DEF_HELPER_1(per_check_exception, void, env) +DEF_HELPER_FLAGS_3(per_branch, TCG_CALL_NO_RWG, void, env, i64, i64) DEF_HELPER_2(xsch, void, env, i64) DEF_HELPER_2(csch, void, env, i64) diff --git a/target-s390x/misc_helper.c b/target-s390x/misc_helper.c index e636464..bc28f9d 100644 --- a/target-s390x/misc_helper.c +++ b/target-s390x/misc_helper.c @@ -608,4 +608,15 @@ void HELPER(per_check_exception)(CPUS390XState *env) cpu_loop_exit(cs); } } + +void HELPER(per_branch)(CPUS390XState *env, uint64_t from, uint64_t to) +{ + if ((env->cregs[9] & PER_CR9_EVENT_BRANCH)) { + if (!(env->cregs[9] & PER_CR9_CONTROL_BRANCH_ADDRESS) + || get_per_in_range(env, to)) { + env->per_address = from; + env->per_perc_atmid = PER_CODE_EVENT_BRANCH | get_per_atmid(env); + } + } +} #endif diff --git a/target-s390x/translate.c b/target-s390x/translate.c index 2013a81..0387806 100644 --- a/target-s390x/translate.c +++ b/target-s390x/translate.c @@ -249,6 +249,38 @@ static void update_psw_addr(DisasContext *s) tcg_gen_movi_i64(psw_addr, s->pc); } +static void per_branch(DisasContext *s, bool to_next) +{ +#ifndef CONFIG_USER_ONLY + if (s->tb->flags & FLAG_MASK_PER) { + TCGv_i64 pc = tcg_const_i64(s->pc); + TCGv_i64 next_pc = to_next ? tcg_const_i64(s->next_pc) : psw_addr; + gen_helper_per_branch(cpu_env, pc, next_pc); + if (to_next) { + tcg_temp_free_i64(next_pc); + } + tcg_temp_free_i64(pc); + } +#endif +} + +static void per_branch_cond(DisasContext *s, TCGCond cond, + TCGv_i64 arg1, TCGv_i64 arg2) +{ +#ifndef CONFIG_USER_ONLY + if (s->tb->flags & FLAG_MASK_PER) { + TCGLabel *lab = gen_new_label(); + tcg_gen_brcond_i64(tcg_invert_cond(cond), arg1, arg2, lab); + + TCGv_i64 pc = tcg_const_i64(s->pc); + gen_helper_per_branch(cpu_env, pc, psw_addr); + tcg_temp_free_i64(pc); + + gen_set_label(lab); + } +#endif +} + static void update_cc_op(DisasContext *s) { if (s->cc_op != CC_OP_DYNAMIC && s->cc_op != CC_OP_STATIC) { @@ -1183,6 +1215,7 @@ static void help_l2_shift(DisasContext *s, DisasFields *f, static ExitStatus help_goto_direct(DisasContext *s, uint64_t dest) { if (dest == s->next_pc) { + per_branch(s, true); return NO_EXIT; } if (use_goto_tb(s, dest)) { @@ -1193,6 +1226,7 @@ static ExitStatus help_goto_direct(DisasContext *s, uint64_t dest) return EXIT_GOTO_TB; } else { tcg_gen_movi_i64(psw_addr, dest); + per_branch(s, false); return EXIT_PC_UPDATED; } } @@ -1212,6 +1246,7 @@ static ExitStatus help_branch(DisasContext *s, DisasCompare *c, if (is_imm) { if (dest == s->next_pc) { /* Branch to next. */ + per_branch(s, true); ret = NO_EXIT; goto egress; } @@ -1227,6 +1262,7 @@ static ExitStatus help_branch(DisasContext *s, DisasCompare *c, } if (c->cond == TCG_COND_ALWAYS) { tcg_gen_mov_i64(psw_addr, cdest); + per_branch(s, false); ret = EXIT_PC_UPDATED; goto egress; } @@ -1297,6 +1333,7 @@ static ExitStatus help_branch(DisasContext *s, DisasCompare *c, if (c->is_64) { tcg_gen_movcond_i64(c->cond, psw_addr, c->u.s64.a, c->u.s64.b, cdest, next); + per_branch_cond(s, c->cond, c->u.s64.a, c->u.s64.b); } else { TCGv_i32 t0 = tcg_temp_new_i32(); TCGv_i64 t1 = tcg_temp_new_i64(); @@ -1305,6 +1342,7 @@ static ExitStatus help_branch(DisasContext *s, DisasCompare *c, tcg_gen_extu_i32_i64(t1, t0); tcg_temp_free_i32(t0); tcg_gen_movcond_i64(TCG_COND_NE, psw_addr, t1, z, cdest, next); + per_branch_cond(s, TCG_COND_NE, t1, z); tcg_temp_free_i64(t1); tcg_temp_free_i64(z); } @@ -1437,6 +1475,7 @@ static ExitStatus op_bas(DisasContext *s, DisasOps *o) tcg_gen_movi_i64(o->out, pc_to_link_info(s, s->next_pc)); if (!TCGV_IS_UNUSED_I64(o->in2)) { tcg_gen_mov_i64(psw_addr, o->in2); + per_branch(s, false); return EXIT_PC_UPDATED; } else { return NO_EXIT;