From patchwork Fri Mar 23 15:22:34 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 148464 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)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 034B9B6EEF for ; Sat, 24 Mar 2012 02:59:25 +1100 (EST) Received: from localhost ([::1]:52277 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SB6LE-0005VB-2Y for incoming@patchwork.ozlabs.org; Fri, 23 Mar 2012 11:23:48 -0400 Received: from eggs.gnu.org ([208.118.235.92]:39049) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SB6KT-0003VZ-3n for qemu-devel@nongnu.org; Fri, 23 Mar 2012 11:23:07 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1SB6KM-0000P5-D0 for qemu-devel@nongnu.org; Fri, 23 Mar 2012 11:23:00 -0400 Received: from mail-yw0-f45.google.com ([209.85.213.45]:38900) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SB6KM-0000Og-5r for qemu-devel@nongnu.org; Fri, 23 Mar 2012 11:22:54 -0400 Received: by yhoo21 with SMTP id o21so3440588yho.4 for ; Fri, 23 Mar 2012 08:22:52 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=sender:from:to:cc:subject:date:message-id:x-mailer:in-reply-to :references; bh=O3VmLj5UdoksYK400IoUBi9ODdC+SjJqhpRxhrW7I18=; b=saKLfislEjpYZf/PWXsubkja5vRk73iD7RuOps3gE7JtfBKwIauAqFRmVW4aK7pbcr eZS+0V9iXeZF8WIBvRF0RkBV6A4pPxmerVXIYQK/d8AXjtzva6tc1aQJrW//scKrAqeF OF2ABiBuXq5HVL6JQzJQKser8iYUtWVjAZCxdj3sIcFK0LMMVOsiZXGYg+BsEndW3LlV sfswqcWC6w2sce9UUTWKX1Dn+hs0BozDF6K3kIb7q7JbM23Tvv3jMUTCyaDt1EKZlB+a RlnyW3h7k18o7i4CfaM69W3keRA2taVDyskva1lkCjAeb19Nyp0D77+zcoYq33HeOx7R xs3Q== Received: by 10.68.218.228 with SMTP id pj4mr30451469pbc.167.1332516172171; Fri, 23 Mar 2012 08:22:52 -0700 (PDT) Received: from anchor.twiddle.home.com ([173.160.232.49]) by mx.google.com with ESMTPS id l1sm6020974pbe.54.2012.03.23.08.22.51 (version=TLSv1/SSLv3 cipher=OTHER); Fri, 23 Mar 2012 08:22:51 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Date: Fri, 23 Mar 2012 08:22:34 -0700 Message-Id: <1332516160-17784-4-git-send-email-rth@twiddle.net> X-Mailer: git-send-email 1.7.7.6 In-Reply-To: <1332516160-17784-1-git-send-email-rth@twiddle.net> References: <1332516160-17784-1-git-send-email-rth@twiddle.net> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 209.85.213.45 Cc: blauwirbel@gmail.com Subject: [Qemu-devel] [PATCH 3/9] target-alpha: Move exception helpers to helper.c. 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 Signed-off-by: Richard Henderson --- target-alpha/cpu.h | 3 ++ target-alpha/helper.c | 39 ++++++++++++++++++++++++ target-alpha/helper.h | 2 +- target-alpha/op_helper.c | 73 ++++++++++++---------------------------------- target-alpha/translate.c | 2 +- 5 files changed, 63 insertions(+), 56 deletions(-) diff --git a/target-alpha/cpu.h b/target-alpha/cpu.h index 48c0fdc..c7787f6 100644 --- a/target-alpha/cpu.h +++ b/target-alpha/cpu.h @@ -434,6 +434,9 @@ int cpu_alpha_handle_mmu_fault (CPUAlphaState *env, uint64_t address, int rw, int mmu_idx); #define cpu_handle_mmu_fault cpu_alpha_handle_mmu_fault void do_interrupt (CPUAlphaState *env); +void do_restore_state(CPUAlphaState *, void *retaddr); +void QEMU_NORETURN dynamic_excp(CPUAlphaState *, void *, int, int); +void QEMU_NORETURN arith_excp(CPUAlphaState *, void *, int, uint64_t); uint64_t cpu_alpha_load_fpcr (CPUAlphaState *env); void cpu_alpha_store_fpcr (CPUAlphaState *env, uint64_t val); diff --git a/target-alpha/helper.c b/target-alpha/helper.c index 3f2e7c3..584457f 100644 --- a/target-alpha/helper.c +++ b/target-alpha/helper.c @@ -23,6 +23,7 @@ #include "cpu.h" #include "softfloat.h" +#include "helper.h" uint64_t cpu_alpha_load_fpcr (CPUAlphaState *env) { @@ -484,3 +485,41 @@ void cpu_dump_state (CPUAlphaState *env, FILE *f, fprintf_function cpu_fprintf, } cpu_fprintf(f, "\n"); } + +void do_restore_state(CPUAlphaState *env, void *retaddr) +{ + uintptr_t pc = (uintptr_t)retaddr; + if (pc) { + TranslationBlock *tb = tb_find_pc(pc); + if (tb) { + cpu_restore_state(tb, env, pc); + } + } +} + +/* This should only be called from translate, via gen_excp. + We expect that ENV->PC has already been updated. */ +void QEMU_NORETURN helper_excp(CPUAlphaState *env, int excp, int error) +{ + env->exception_index = excp; + env->error_code = error; + cpu_loop_exit(env); +} + +/* This may be called from any of the helpers to set up EXCEPTION_INDEX. */ +void QEMU_NORETURN dynamic_excp(CPUAlphaState *env, void *retaddr, + int excp, int error) +{ + env->exception_index = excp; + env->error_code = error; + do_restore_state(env, retaddr); + cpu_loop_exit(env); +} + +void QEMU_NORETURN arith_excp(CPUAlphaState *env, void *retaddr, + int exc, uint64_t mask) +{ + env->trap_arg0 = exc; + env->trap_arg1 = mask; + dynamic_excp(env, retaddr, EXCP_ARITH, 0); +} diff --git a/target-alpha/helper.h b/target-alpha/helper.h index b693cee..91a9e39 100644 --- a/target-alpha/helper.h +++ b/target-alpha/helper.h @@ -1,6 +1,6 @@ #include "def-helper.h" -DEF_HELPER_2(excp, void, int, int) +DEF_HELPER_3(excp, void, env, int, int) DEF_HELPER_FLAGS_0(load_pcc, TCG_CALL_CONST | TCG_CALL_PURE, i64) DEF_HELPER_2(addqv, i64, i64, i64) diff --git a/target-alpha/op_helper.c b/target-alpha/op_helper.c index eab7a82..af5fa82 100644 --- a/target-alpha/op_helper.c +++ b/target-alpha/op_helper.c @@ -30,43 +30,6 @@ /*****************************************************************************/ /* Exceptions processing helpers */ -/* This should only be called from translate, via gen_excp. - We expect that ENV->PC has already been updated. */ -void QEMU_NORETURN helper_excp(int excp, int error) -{ - env->exception_index = excp; - env->error_code = error; - cpu_loop_exit(env); -} - -static void do_restore_state(void *retaddr) -{ - unsigned long pc = (unsigned long)retaddr; - - if (pc) { - TranslationBlock *tb = tb_find_pc(pc); - if (tb) { - cpu_restore_state(tb, env, pc); - } - } -} - -/* This may be called from any of the helpers to set up EXCEPTION_INDEX. */ -static void QEMU_NORETURN dynamic_excp(int excp, int error) -{ - env->exception_index = excp; - env->error_code = error; - do_restore_state(GETPC()); - cpu_loop_exit(env); -} - -static void QEMU_NORETURN arith_excp(int exc, uint64_t mask) -{ - env->trap_arg0 = exc; - env->trap_arg1 = mask; - dynamic_excp(EXCP_ARITH, 0); -} - uint64_t helper_load_pcc (void) { #ifndef CONFIG_USER_ONLY @@ -97,7 +60,7 @@ uint64_t helper_addqv (uint64_t op1, uint64_t op2) uint64_t tmp = op1; op1 += op2; if (unlikely((tmp ^ op2 ^ (-1ULL)) & (tmp ^ op1) & (1ULL << 63))) { - arith_excp(EXC_M_IOV, 0); + arith_excp(env, GETPC(), EXC_M_IOV, 0); } return op1; } @@ -107,7 +70,7 @@ uint64_t helper_addlv (uint64_t op1, uint64_t op2) uint64_t tmp = op1; op1 = (uint32_t)(op1 + op2); if (unlikely((tmp ^ op2 ^ (-1UL)) & (tmp ^ op1) & (1UL << 31))) { - arith_excp(EXC_M_IOV, 0); + arith_excp(env, GETPC(), EXC_M_IOV, 0); } return op1; } @@ -117,7 +80,7 @@ uint64_t helper_subqv (uint64_t op1, uint64_t op2) uint64_t res; res = op1 - op2; if (unlikely((op1 ^ op2) & (res ^ op1) & (1ULL << 63))) { - arith_excp(EXC_M_IOV, 0); + arith_excp(env, GETPC(), EXC_M_IOV, 0); } return res; } @@ -127,7 +90,7 @@ uint64_t helper_sublv (uint64_t op1, uint64_t op2) uint32_t res; res = op1 - op2; if (unlikely((op1 ^ op2) & (res ^ op1) & (1UL << 31))) { - arith_excp(EXC_M_IOV, 0); + arith_excp(env, GETPC(), EXC_M_IOV, 0); } return res; } @@ -137,7 +100,7 @@ uint64_t helper_mullv (uint64_t op1, uint64_t op2) int64_t res = (int64_t)op1 * (int64_t)op2; if (unlikely((int32_t)res != res)) { - arith_excp(EXC_M_IOV, 0); + arith_excp(env, GETPC(), EXC_M_IOV, 0); } return (int64_t)((int32_t)res); } @@ -149,7 +112,7 @@ uint64_t helper_mulqv (uint64_t op1, uint64_t op2) muls64(&tl, &th, op1, op2); /* If th != 0 && th != -1, then we had an overflow */ if (unlikely((th + 1) > 1)) { - arith_excp(EXC_M_IOV, 0); + arith_excp(env, GETPC(), EXC_M_IOV, 0); } return tl; } @@ -200,7 +163,7 @@ void helper_fp_exc_raise(uint32_t exc, uint32_t regno) hw_exc |= EXC_M_INE; } - arith_excp(hw_exc, 1ull << regno); + arith_excp(env, GETPC(), hw_exc, 1ull << regno); } } @@ -230,7 +193,7 @@ uint64_t helper_ieee_input(uint64_t val) if (env->fpcr_dnz) { val &= 1ull << 63; } else { - arith_excp(EXC_M_UNF, 0); + arith_excp(env, GETPC(), EXC_M_UNF, 0); } } } else if (exp == 0x7ff) { @@ -238,7 +201,7 @@ uint64_t helper_ieee_input(uint64_t val) /* ??? I'm not sure these exception bit flags are correct. I do know that the Linux kernel, at least, doesn't rely on them and just emulates the insn to figure out what exception to use. */ - arith_excp(frac ? EXC_M_INV : EXC_M_FOV, 0); + arith_excp(env, GETPC(), frac ? EXC_M_INV : EXC_M_FOV, 0); } return val; } @@ -255,12 +218,12 @@ uint64_t helper_ieee_input_cmp(uint64_t val) if (env->fpcr_dnz) { val &= 1ull << 63; } else { - arith_excp(EXC_M_UNF, 0); + arith_excp(env, GETPC(), EXC_M_UNF, 0); } } } else if (exp == 0x7ff && frac) { /* NaN. */ - arith_excp(EXC_M_INV, 0); + arith_excp(env, GETPC(), EXC_M_INV, 0); } return val; } @@ -323,7 +286,7 @@ static inline float32 f_to_float32(uint64_t a) if (unlikely(!exp && mant_sig)) { /* Reserved operands / Dirty zero */ - dynamic_excp(EXCP_OPCDEC, 0); + dynamic_excp(env, GETPC(), EXCP_OPCDEC, 0); } if (exp < 3) { @@ -453,7 +416,7 @@ static inline float64 g_to_float64(uint64_t a) if (!exp && mant_sig) { /* Reserved operands / Dirty zero */ - dynamic_excp(EXCP_OPCDEC, 0); + dynamic_excp(env, GETPC(), EXCP_OPCDEC, 0); } if (exp < 3) { @@ -1085,7 +1048,7 @@ static void QEMU_NORETURN do_unaligned_access(target_ulong addr, int is_write, uint64_t pc; uint32_t insn; - do_restore_state(retaddr); + do_restore_state(env, retaddr); pc = env->pc; insn = ldl_code(pc); @@ -1093,7 +1056,9 @@ static void QEMU_NORETURN do_unaligned_access(target_ulong addr, int is_write, env->trap_arg0 = addr; env->trap_arg1 = insn >> 26; /* opcode */ env->trap_arg2 = (insn >> 21) & 31; /* dest regno */ - helper_excp(EXCP_UNALIGN, 0); + env->exception_index = EXCP_UNALIGN; + env->error_code = 0; + cpu_loop_exit(env); } void QEMU_NORETURN cpu_unassigned_access(CPUAlphaState *env1, @@ -1103,7 +1068,7 @@ void QEMU_NORETURN cpu_unassigned_access(CPUAlphaState *env1, env = env1; env->trap_arg0 = addr; env->trap_arg1 = is_write; - dynamic_excp(EXCP_MCHK, 0); + dynamic_excp(env1, GETPC(), EXCP_MCHK, 0); } #include "softmmu_exec.h" @@ -1137,7 +1102,7 @@ void tlb_fill(CPUAlphaState *env1, target_ulong addr, int is_write, int mmu_idx, env = env1; ret = cpu_alpha_handle_mmu_fault(env, addr, is_write, mmu_idx); if (unlikely(ret != 0)) { - do_restore_state(retaddr); + do_restore_state(env, retaddr); /* Exception index and error code are already set */ cpu_loop_exit(env); } diff --git a/target-alpha/translate.c b/target-alpha/translate.c index 2c24619..0c06b55 100644 --- a/target-alpha/translate.c +++ b/target-alpha/translate.c @@ -149,7 +149,7 @@ static void gen_excp_1(int exception, int error_code) tmp1 = tcg_const_i32(exception); tmp2 = tcg_const_i32(error_code); - gen_helper_excp(tmp1, tmp2); + gen_helper_excp(cpu_env, tmp1, tmp2); tcg_temp_free_i32(tmp2); tcg_temp_free_i32(tmp1); }