From patchwork Tue Jul 12 19:02:15 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 9226087 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id F2C3560868 for ; Tue, 12 Jul 2016 19:39:05 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id DEC2C2756B for ; Tue, 12 Jul 2016 19:39:05 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id D334927D85; Tue, 12 Jul 2016 19:39:05 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.8 required=2.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_HI,T_DKIM_INVALID autolearn=ham version=3.3.1 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 mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 0A4DB2756B for ; Tue, 12 Jul 2016 19:39:03 +0000 (UTC) Received: from localhost ([::1]:42991 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bN3WH-0005J6-R5 for patchwork-qemu-devel@patchwork.kernel.org; Tue, 12 Jul 2016 15:39:01 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:56571) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bN2xi-0005eT-7v for qemu-devel@nongnu.org; Tue, 12 Jul 2016 15:03:21 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1bN2xe-0002lH-1L for qemu-devel@nongnu.org; Tue, 12 Jul 2016 15:03:17 -0400 Received: from mail-qk0-x243.google.com ([2607:f8b0:400d:c09::243]:34409) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bN2xd-0002lD-Qo for qemu-devel@nongnu.org; Tue, 12 Jul 2016 15:03:13 -0400 Received: by mail-qk0-x243.google.com with SMTP id 82so1525997qko.1 for ; Tue, 12 Jul 2016 12:03:13 -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:in-reply-to:references; bh=q1J4qDS9VkwWOngJfuKwdMBGR8erQQ04YvcRFYUjBAI=; b=AOzPlozPh8M2+vahvXL6qcH8oRp96olyd5LBV/cd7pvF4dzBvG7sPLBtI9scyekwde YwobuNJ56hsmTly6k1FXL39wAChJcKMLqyjiK5XcdnQnqeKidMb4xpsV91T97Ab3GpgJ fAUO8jcuQb74iaxbTonoUJVG81RYYBszrqyd2vyAEZjswkWlMxwVD9DbneKDGnHSeW6/ /z9pwQoZx4SH/WcCE9jn0rUuEmCFiAs4vhg6B6g/EnrWYsGnHG5f7CIQAkPL1l4PTJTO mJbGo4cAM9GwBMOxltsGs+TVzi+GAwE0hHlecv0WPkYUxVQ+r4QhRbPSvx4bSJlclhM4 uTOQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references; bh=q1J4qDS9VkwWOngJfuKwdMBGR8erQQ04YvcRFYUjBAI=; b=PC5wEligWp40sDjD2BrjM8H2PSZXw3Dh//f0kLAM8HQDvTF3Qcxu/cF0OXe0RkNUBI cJ+tLQwB+MwvyG6mTOzmGiVKxPlN5pFNBD9r+1ykmYJdYC8AgZSXbIlKGvbxeuLTk7qg 6Bsx56oaTm+/mCr/tLS1505z8NujoVCAE1joq3QvMBxTCwg7y3IKUg8OdHJn/eivvuZf qBi4s2EYocWIYOJK+NhhPrT/0LTTGT/lR898Np+l1S25GUs6qnLc5gej7iA2y2JW05rL SyWKi+DQd+GMu1jZh0vLGQtb5+8jaI/U2qKVLr8LepSsTcNcdCKADCYsIuKM/Jtb9kGg 2EqQ== X-Gm-Message-State: ALyK8tL4JO4IIWXQwIguMh5vxIDJcwB+hAFQUH3TMT+tEz0yJIKDy/i1UpJL+zU85ZL+yw== X-Received: by 10.55.170.141 with SMTP id t135mr5158323qke.112.1468350193102; Tue, 12 Jul 2016 12:03:13 -0700 (PDT) Received: from bigtime.com (71-37-54-227.tukw.qwest.net. [71.37.54.227]) by smtp.gmail.com with ESMTPSA id u87sm1209716qkl.30.2016.07.12.12.03.12 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 12 Jul 2016 12:03:12 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Date: Tue, 12 Jul 2016 12:02:15 -0700 Message-Id: <1468350138-9736-22-git-send-email-rth@twiddle.net> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1468350138-9736-1-git-send-email-rth@twiddle.net> References: <1468350138-9736-1-git-send-email-rth@twiddle.net> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 2607:f8b0:400d:c09::243 Subject: [Qemu-devel] [PULL 21/24] target-sparc: Use explicit writes to cpu_fsr X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: peter.maydell@linaro.org, mark.cave-ayland@ilande.co.uk Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP By arranging for explicit writes to cpu_fsr after floating point operations, we are able to mark the helpers as not writing to tcg globals, which means that we don't need to invalidate the integer register set across said calls. Tested-by: Mark Cave-Ayland Signed-off-by: Richard Henderson --- target-sparc/fop_helper.c | 223 +++++++++++++++------------------------------- target-sparc/helper.h | 112 +++++++++++------------ target-sparc/translate.c | 76 +++++++++------- 3 files changed, 174 insertions(+), 237 deletions(-) diff --git a/target-sparc/fop_helper.c b/target-sparc/fop_helper.c index 0830643..cdc58ea 100644 --- a/target-sparc/fop_helper.c +++ b/target-sparc/fop_helper.c @@ -24,43 +24,46 @@ #define QT0 (env->qt0) #define QT1 (env->qt1) -static void check_ieee_exceptions(CPUSPARCState *env) +target_ulong helper_check_ieee_exceptions(CPUSPARCState *env) { - target_ulong status; + target_ulong status = get_float_exception_flags(&env->fp_status); + target_ulong fsr = env->fsr; + + if (unlikely(status)) { + /* Keep exception flags clear for next time. */ + set_float_exception_flags(0, &env->fp_status); - status = get_float_exception_flags(&env->fp_status); - if (status) { /* Copy IEEE 754 flags into FSR */ if (status & float_flag_invalid) { - env->fsr |= FSR_NVC; + fsr |= FSR_NVC; } if (status & float_flag_overflow) { - env->fsr |= FSR_OFC; + fsr |= FSR_OFC; } if (status & float_flag_underflow) { - env->fsr |= FSR_UFC; + fsr |= FSR_UFC; } if (status & float_flag_divbyzero) { - env->fsr |= FSR_DZC; + fsr |= FSR_DZC; } if (status & float_flag_inexact) { - env->fsr |= FSR_NXC; + fsr |= FSR_NXC; } - if ((env->fsr & FSR_CEXC_MASK) & ((env->fsr & FSR_TEM_MASK) >> 23)) { - /* Unmasked exception, generate a trap */ - env->fsr |= FSR_FTT_IEEE_EXCP; + if ((fsr & FSR_CEXC_MASK) & ((fsr & FSR_TEM_MASK) >> 23)) { + /* Unmasked exception, generate a trap. Note that while + the helper is marked as NO_WG, we can get away with + writing to cpu state along the exception path, since + TCG generated code will never see the write. */ + env->fsr = fsr | FSR_FTT_IEEE_EXCP; helper_raise_exception(env, TT_FP_EXCP); } else { /* Accumulate exceptions */ - env->fsr |= (env->fsr & FSR_CEXC_MASK) << 5; + fsr |= (fsr & FSR_CEXC_MASK) << 5; } } -} -static inline void clear_float_exceptions(CPUSPARCState *env) -{ - set_float_exception_flags(0, &env->fp_status); + return fsr; } #define F_HELPER(name, p) void helper_f##name##p(CPUSPARCState *env) @@ -69,26 +72,16 @@ static inline void clear_float_exceptions(CPUSPARCState *env) float32 helper_f ## name ## s (CPUSPARCState *env, float32 src1, \ float32 src2) \ { \ - float32 ret; \ - clear_float_exceptions(env); \ - ret = float32_ ## name (src1, src2, &env->fp_status); \ - check_ieee_exceptions(env); \ - return ret; \ + return float32_ ## name (src1, src2, &env->fp_status); \ } \ float64 helper_f ## name ## d (CPUSPARCState * env, float64 src1,\ float64 src2) \ { \ - float64 ret; \ - clear_float_exceptions(env); \ - ret = float64_ ## name (src1, src2, &env->fp_status); \ - check_ieee_exceptions(env); \ - return ret; \ + return float64_ ## name (src1, src2, &env->fp_status); \ } \ F_HELPER(name, q) \ { \ - clear_float_exceptions(env); \ QT0 = float128_ ## name (QT0, QT1, &env->fp_status); \ - check_ieee_exceptions(env); \ } F_BINOP(add); @@ -99,22 +92,16 @@ F_BINOP(div); float64 helper_fsmuld(CPUSPARCState *env, float32 src1, float32 src2) { - float64 ret; - clear_float_exceptions(env); - ret = float64_mul(float32_to_float64(src1, &env->fp_status), - float32_to_float64(src2, &env->fp_status), - &env->fp_status); - check_ieee_exceptions(env); - return ret; + return float64_mul(float32_to_float64(src1, &env->fp_status), + float32_to_float64(src2, &env->fp_status), + &env->fp_status); } void helper_fdmulq(CPUSPARCState *env, float64 src1, float64 src2) { - clear_float_exceptions(env); QT0 = float128_mul(float64_to_float128(src1, &env->fp_status), float64_to_float128(src2, &env->fp_status), &env->fp_status); - check_ieee_exceptions(env); } float32 helper_fnegs(float32 src) @@ -137,48 +124,32 @@ F_HELPER(neg, q) /* Integer to float conversion. */ float32 helper_fitos(CPUSPARCState *env, int32_t src) { - /* Inexact error possible converting int to float. */ - float32 ret; - clear_float_exceptions(env); - ret = int32_to_float32(src, &env->fp_status); - check_ieee_exceptions(env); - return ret; + return int32_to_float32(src, &env->fp_status); } float64 helper_fitod(CPUSPARCState *env, int32_t src) { - /* No possible exceptions converting int to double. */ return int32_to_float64(src, &env->fp_status); } void helper_fitoq(CPUSPARCState *env, int32_t src) { - /* No possible exceptions converting int to long double. */ QT0 = int32_to_float128(src, &env->fp_status); } #ifdef TARGET_SPARC64 float32 helper_fxtos(CPUSPARCState *env, int64_t src) { - float32 ret; - clear_float_exceptions(env); - ret = int64_to_float32(src, &env->fp_status); - check_ieee_exceptions(env); - return ret; + return int64_to_float32(src, &env->fp_status); } float64 helper_fxtod(CPUSPARCState *env, int64_t src) { - float64 ret; - clear_float_exceptions(env); - ret = int64_to_float64(src, &env->fp_status); - check_ieee_exceptions(env); - return ret; + return int64_to_float64(src, &env->fp_status); } void helper_fxtoq(CPUSPARCState *env, int64_t src) { - /* No possible exceptions converting long long to long double. */ QT0 = int64_to_float128(src, &env->fp_status); } #endif @@ -187,108 +158,64 @@ void helper_fxtoq(CPUSPARCState *env, int64_t src) /* floating point conversion */ float32 helper_fdtos(CPUSPARCState *env, float64 src) { - float32 ret; - clear_float_exceptions(env); - ret = float64_to_float32(src, &env->fp_status); - check_ieee_exceptions(env); - return ret; + return float64_to_float32(src, &env->fp_status); } float64 helper_fstod(CPUSPARCState *env, float32 src) { - float64 ret; - clear_float_exceptions(env); - ret = float32_to_float64(src, &env->fp_status); - check_ieee_exceptions(env); - return ret; + return float32_to_float64(src, &env->fp_status); } float32 helper_fqtos(CPUSPARCState *env) { - float32 ret; - clear_float_exceptions(env); - ret = float128_to_float32(QT1, &env->fp_status); - check_ieee_exceptions(env); - return ret; + return float128_to_float32(QT1, &env->fp_status); } void helper_fstoq(CPUSPARCState *env, float32 src) { - clear_float_exceptions(env); QT0 = float32_to_float128(src, &env->fp_status); - check_ieee_exceptions(env); } float64 helper_fqtod(CPUSPARCState *env) { - float64 ret; - clear_float_exceptions(env); - ret = float128_to_float64(QT1, &env->fp_status); - check_ieee_exceptions(env); - return ret; + return float128_to_float64(QT1, &env->fp_status); } void helper_fdtoq(CPUSPARCState *env, float64 src) { - clear_float_exceptions(env); QT0 = float64_to_float128(src, &env->fp_status); - check_ieee_exceptions(env); } /* Float to integer conversion. */ int32_t helper_fstoi(CPUSPARCState *env, float32 src) { - int32_t ret; - clear_float_exceptions(env); - ret = float32_to_int32_round_to_zero(src, &env->fp_status); - check_ieee_exceptions(env); - return ret; + return float32_to_int32_round_to_zero(src, &env->fp_status); } int32_t helper_fdtoi(CPUSPARCState *env, float64 src) { - int32_t ret; - clear_float_exceptions(env); - ret = float64_to_int32_round_to_zero(src, &env->fp_status); - check_ieee_exceptions(env); - return ret; + return float64_to_int32_round_to_zero(src, &env->fp_status); } int32_t helper_fqtoi(CPUSPARCState *env) { - int32_t ret; - clear_float_exceptions(env); - ret = float128_to_int32_round_to_zero(QT1, &env->fp_status); - check_ieee_exceptions(env); - return ret; + return float128_to_int32_round_to_zero(QT1, &env->fp_status); } #ifdef TARGET_SPARC64 int64_t helper_fstox(CPUSPARCState *env, float32 src) { - int64_t ret; - clear_float_exceptions(env); - ret = float32_to_int64_round_to_zero(src, &env->fp_status); - check_ieee_exceptions(env); - return ret; + return float32_to_int64_round_to_zero(src, &env->fp_status); } int64_t helper_fdtox(CPUSPARCState *env, float64 src) { - int64_t ret; - clear_float_exceptions(env); - ret = float64_to_int64_round_to_zero(src, &env->fp_status); - check_ieee_exceptions(env); - return ret; + return float64_to_int64_round_to_zero(src, &env->fp_status); } int64_t helper_fqtox(CPUSPARCState *env) { - int64_t ret; - clear_float_exceptions(env); - ret = float128_to_int64_round_to_zero(QT1, &env->fp_status); - check_ieee_exceptions(env); - return ret; + return float128_to_int64_round_to_zero(QT1, &env->fp_status); } #endif @@ -311,87 +238,79 @@ void helper_fabsq(CPUSPARCState *env) float32 helper_fsqrts(CPUSPARCState *env, float32 src) { - float32 ret; - clear_float_exceptions(env); - ret = float32_sqrt(src, &env->fp_status); - check_ieee_exceptions(env); - return ret; + return float32_sqrt(src, &env->fp_status); } float64 helper_fsqrtd(CPUSPARCState *env, float64 src) { - float64 ret; - clear_float_exceptions(env); - ret = float64_sqrt(src, &env->fp_status); - check_ieee_exceptions(env); - return ret; + return float64_sqrt(src, &env->fp_status); } void helper_fsqrtq(CPUSPARCState *env) { - clear_float_exceptions(env); QT0 = float128_sqrt(QT1, &env->fp_status); - check_ieee_exceptions(env); } #define GEN_FCMP(name, size, reg1, reg2, FS, E) \ - void glue(helper_, name) (CPUSPARCState *env) \ + target_ulong glue(helper_, name) (CPUSPARCState *env) \ { \ int ret; \ - clear_float_exceptions(env); \ + target_ulong fsr; \ if (E) { \ ret = glue(size, _compare)(reg1, reg2, &env->fp_status); \ } else { \ ret = glue(size, _compare_quiet)(reg1, reg2, \ &env->fp_status); \ } \ - check_ieee_exceptions(env); \ + fsr = helper_check_ieee_exceptions(env); \ switch (ret) { \ case float_relation_unordered: \ - env->fsr |= (FSR_FCC1 | FSR_FCC0) << FS; \ - env->fsr |= FSR_NVA; \ + fsr |= (FSR_FCC1 | FSR_FCC0) << FS; \ + fsr |= FSR_NVA; \ break; \ case float_relation_less: \ - env->fsr &= ~(FSR_FCC1) << FS; \ - env->fsr |= FSR_FCC0 << FS; \ + fsr &= ~(FSR_FCC1) << FS; \ + fsr |= FSR_FCC0 << FS; \ break; \ case float_relation_greater: \ - env->fsr &= ~(FSR_FCC0) << FS; \ - env->fsr |= FSR_FCC1 << FS; \ + fsr &= ~(FSR_FCC0) << FS; \ + fsr |= FSR_FCC1 << FS; \ break; \ default: \ - env->fsr &= ~((FSR_FCC1 | FSR_FCC0) << FS); \ + fsr &= ~((FSR_FCC1 | FSR_FCC0) << FS); \ break; \ } \ + return fsr; \ } #define GEN_FCMP_T(name, size, FS, E) \ - void glue(helper_, name)(CPUSPARCState *env, size src1, size src2) \ + target_ulong glue(helper_, name)(CPUSPARCState *env, size src1, size src2)\ { \ int ret; \ - clear_float_exceptions(env); \ + target_ulong fsr; \ if (E) { \ ret = glue(size, _compare)(src1, src2, &env->fp_status); \ } else { \ ret = glue(size, _compare_quiet)(src1, src2, \ &env->fp_status); \ } \ - check_ieee_exceptions(env); \ + fsr = helper_check_ieee_exceptions(env); \ switch (ret) { \ case float_relation_unordered: \ - env->fsr |= (FSR_FCC1 | FSR_FCC0) << FS; \ + fsr |= (FSR_FCC1 | FSR_FCC0) << FS; \ break; \ case float_relation_less: \ - env->fsr &= ~(FSR_FCC1 << FS); \ - env->fsr |= FSR_FCC0 << FS; \ + fsr &= ~(FSR_FCC1 << FS); \ + fsr |= FSR_FCC0 << FS; \ break; \ case float_relation_greater: \ - env->fsr &= ~(FSR_FCC0 << FS); \ - env->fsr |= FSR_FCC1 << FS; \ + fsr &= ~(FSR_FCC0 << FS); \ + fsr |= FSR_FCC1 << FS; \ break; \ default: \ - env->fsr &= ~((FSR_FCC1 | FSR_FCC0) << FS); \ + fsr &= ~((FSR_FCC1 | FSR_FCC0) << FS); \ break; \ } \ + return fsr; \ } GEN_FCMP_T(fcmps, float32, 0, 0); @@ -431,11 +350,11 @@ GEN_FCMP(fcmpeq_fcc3, float128, QT0, QT1, 26, 1); #undef GEN_FCMP_T #undef GEN_FCMP -static inline void set_fsr(CPUSPARCState *env) +static void set_fsr(CPUSPARCState *env, target_ulong fsr) { int rnd_mode; - switch (env->fsr & FSR_RD_MASK) { + switch (fsr & FSR_RD_MASK) { case FSR_RD_NEAREST: rnd_mode = float_round_nearest_even; break; @@ -453,16 +372,20 @@ static inline void set_fsr(CPUSPARCState *env) set_float_rounding_mode(rnd_mode, &env->fp_status); } -void helper_ldfsr(CPUSPARCState *env, uint32_t new_fsr) +target_ulong helper_ldfsr(CPUSPARCState *env, target_ulong old_fsr, + uint32_t new_fsr) { - env->fsr = (new_fsr & FSR_LDFSR_MASK) | (env->fsr & FSR_LDFSR_OLDMASK); - set_fsr(env); + old_fsr = (new_fsr & FSR_LDFSR_MASK) | (old_fsr & FSR_LDFSR_OLDMASK); + set_fsr(env, old_fsr); + return old_fsr; } #ifdef TARGET_SPARC64 -void helper_ldxfsr(CPUSPARCState *env, uint64_t new_fsr) +target_ulong helper_ldxfsr(CPUSPARCState *env, target_ulong old_fsr, + uint64_t new_fsr) { - env->fsr = (new_fsr & FSR_LDXFSR_MASK) | (env->fsr & FSR_LDXFSR_OLDMASK); - set_fsr(env); + old_fsr = (new_fsr & FSR_LDXFSR_MASK) | (old_fsr & FSR_LDXFSR_OLDMASK); + set_fsr(env, old_fsr); + return old_fsr; } #endif diff --git a/target-sparc/helper.h b/target-sparc/helper.h index b506706..caa2a89 100644 --- a/target-sparc/helper.h +++ b/target-sparc/helper.h @@ -49,86 +49,88 @@ DEF_HELPER_FLAGS_3(stqf, TCG_CALL_NO_WG, void, env, tl, int) DEF_HELPER_FLAGS_4(ld_asi, TCG_CALL_NO_WG, i64, env, tl, int, i32) DEF_HELPER_FLAGS_5(st_asi, TCG_CALL_NO_WG, void, env, tl, i64, int, i32) #endif -DEF_HELPER_2(ldfsr, void, env, i32) +DEF_HELPER_FLAGS_1(check_ieee_exceptions, TCG_CALL_NO_WG, tl, env) +DEF_HELPER_FLAGS_3(ldfsr, TCG_CALL_NO_RWG, tl, env, tl, i32) DEF_HELPER_FLAGS_1(fabss, TCG_CALL_NO_RWG_SE, f32, f32) -DEF_HELPER_2(fsqrts, f32, env, f32) -DEF_HELPER_2(fsqrtd, f64, env, f64) -DEF_HELPER_3(fcmps, void, env, f32, f32) -DEF_HELPER_3(fcmpd, void, env, f64, f64) -DEF_HELPER_3(fcmpes, void, env, f32, f32) -DEF_HELPER_3(fcmped, void, env, f64, f64) -DEF_HELPER_1(fsqrtq, void, env) -DEF_HELPER_1(fcmpq, void, env) -DEF_HELPER_1(fcmpeq, void, env) +DEF_HELPER_FLAGS_2(fsqrts, TCG_CALL_NO_RWG, f32, env, f32) +DEF_HELPER_FLAGS_2(fsqrtd, TCG_CALL_NO_RWG, f64, env, f64) +DEF_HELPER_FLAGS_3(fcmps, TCG_CALL_NO_WG, tl, env, f32, f32) +DEF_HELPER_FLAGS_3(fcmpd, TCG_CALL_NO_WG, tl, env, f64, f64) +DEF_HELPER_FLAGS_3(fcmpes, TCG_CALL_NO_WG, tl, env, f32, f32) +DEF_HELPER_FLAGS_3(fcmped, TCG_CALL_NO_WG, tl, env, f64, f64) +DEF_HELPER_FLAGS_1(fsqrtq, TCG_CALL_NO_RWG, void, env) +DEF_HELPER_FLAGS_1(fcmpq, TCG_CALL_NO_WG, tl, env) +DEF_HELPER_FLAGS_1(fcmpeq, TCG_CALL_NO_WG, tl, env) #ifdef TARGET_SPARC64 -DEF_HELPER_2(ldxfsr, void, env, i64) +DEF_HELPER_FLAGS_3(ldxfsr, TCG_CALL_NO_RWG, tl, env, tl, i64) DEF_HELPER_FLAGS_1(fabsd, TCG_CALL_NO_RWG_SE, f64, f64) -DEF_HELPER_3(fcmps_fcc1, void, env, f32, f32) -DEF_HELPER_3(fcmps_fcc2, void, env, f32, f32) -DEF_HELPER_3(fcmps_fcc3, void, env, f32, f32) -DEF_HELPER_3(fcmpd_fcc1, void, env, f64, f64) -DEF_HELPER_3(fcmpd_fcc2, void, env, f64, f64) -DEF_HELPER_3(fcmpd_fcc3, void, env, f64, f64) -DEF_HELPER_3(fcmpes_fcc1, void, env, f32, f32) -DEF_HELPER_3(fcmpes_fcc2, void, env, f32, f32) -DEF_HELPER_3(fcmpes_fcc3, void, env, f32, f32) -DEF_HELPER_3(fcmped_fcc1, void, env, f64, f64) -DEF_HELPER_3(fcmped_fcc2, void, env, f64, f64) -DEF_HELPER_3(fcmped_fcc3, void, env, f64, f64) +DEF_HELPER_FLAGS_3(fcmps_fcc1, TCG_CALL_NO_WG, tl, env, f32, f32) +DEF_HELPER_FLAGS_3(fcmps_fcc2, TCG_CALL_NO_WG, tl, env, f32, f32) +DEF_HELPER_FLAGS_3(fcmps_fcc3, TCG_CALL_NO_WG, tl, env, f32, f32) +DEF_HELPER_FLAGS_3(fcmpd_fcc1, TCG_CALL_NO_WG, tl, env, f64, f64) +DEF_HELPER_FLAGS_3(fcmpd_fcc2, TCG_CALL_NO_WG, tl, env, f64, f64) +DEF_HELPER_FLAGS_3(fcmpd_fcc3, TCG_CALL_NO_WG, tl, env, f64, f64) +DEF_HELPER_FLAGS_3(fcmpes_fcc1, TCG_CALL_NO_WG, tl, env, f32, f32) +DEF_HELPER_FLAGS_3(fcmpes_fcc2, TCG_CALL_NO_WG, tl, env, f32, f32) +DEF_HELPER_FLAGS_3(fcmpes_fcc3, TCG_CALL_NO_WG, tl, env, f32, f32) +DEF_HELPER_FLAGS_3(fcmped_fcc1, TCG_CALL_NO_WG, tl, env, f64, f64) +DEF_HELPER_FLAGS_3(fcmped_fcc2, TCG_CALL_NO_WG, tl, env, f64, f64) +DEF_HELPER_FLAGS_3(fcmped_fcc3, TCG_CALL_NO_WG, tl, env, f64, f64) DEF_HELPER_FLAGS_1(fabsq, TCG_CALL_NO_RWG, void, env) -DEF_HELPER_1(fcmpq_fcc1, void, env) -DEF_HELPER_1(fcmpq_fcc2, void, env) -DEF_HELPER_1(fcmpq_fcc3, void, env) -DEF_HELPER_1(fcmpeq_fcc1, void, env) -DEF_HELPER_1(fcmpeq_fcc2, void, env) -DEF_HELPER_1(fcmpeq_fcc3, void, env) +DEF_HELPER_FLAGS_1(fcmpq_fcc1, TCG_CALL_NO_WG, tl, env) +DEF_HELPER_FLAGS_1(fcmpq_fcc2, TCG_CALL_NO_WG, tl, env) +DEF_HELPER_FLAGS_1(fcmpq_fcc3, TCG_CALL_NO_WG, tl, env) +DEF_HELPER_FLAGS_1(fcmpeq_fcc1, TCG_CALL_NO_WG, tl, env) +DEF_HELPER_FLAGS_1(fcmpeq_fcc2, TCG_CALL_NO_WG, tl, env) +DEF_HELPER_FLAGS_1(fcmpeq_fcc3, TCG_CALL_NO_WG, tl, env) #endif DEF_HELPER_2(raise_exception, noreturn, env, int) -#define F_HELPER_0_1(name) DEF_HELPER_1(f ## name, void, env) +#define F_HELPER_0_1(name) \ + DEF_HELPER_FLAGS_1(f ## name, TCG_CALL_NO_RWG, void, env) -DEF_HELPER_3(faddd, f64, env, f64, f64) -DEF_HELPER_3(fsubd, f64, env, f64, f64) -DEF_HELPER_3(fmuld, f64, env, f64, f64) -DEF_HELPER_3(fdivd, f64, env, f64, f64) +DEF_HELPER_FLAGS_3(faddd, TCG_CALL_NO_RWG, f64, env, f64, f64) +DEF_HELPER_FLAGS_3(fsubd, TCG_CALL_NO_RWG, f64, env, f64, f64) +DEF_HELPER_FLAGS_3(fmuld, TCG_CALL_NO_RWG, f64, env, f64, f64) +DEF_HELPER_FLAGS_3(fdivd, TCG_CALL_NO_RWG, f64, env, f64, f64) F_HELPER_0_1(addq) F_HELPER_0_1(subq) F_HELPER_0_1(mulq) F_HELPER_0_1(divq) -DEF_HELPER_3(fadds, f32, env, f32, f32) -DEF_HELPER_3(fsubs, f32, env, f32, f32) -DEF_HELPER_3(fmuls, f32, env, f32, f32) -DEF_HELPER_3(fdivs, f32, env, f32, f32) +DEF_HELPER_FLAGS_3(fadds, TCG_CALL_NO_RWG, f32, env, f32, f32) +DEF_HELPER_FLAGS_3(fsubs, TCG_CALL_NO_RWG, f32, env, f32, f32) +DEF_HELPER_FLAGS_3(fmuls, TCG_CALL_NO_RWG, f32, env, f32, f32) +DEF_HELPER_FLAGS_3(fdivs, TCG_CALL_NO_RWG, f32, env, f32, f32) -DEF_HELPER_3(fsmuld, f64, env, f32, f32) -DEF_HELPER_3(fdmulq, void, env, f64, f64) +DEF_HELPER_FLAGS_3(fsmuld, TCG_CALL_NO_RWG, f64, env, f32, f32) +DEF_HELPER_FLAGS_3(fdmulq, TCG_CALL_NO_RWG, void, env, f64, f64) DEF_HELPER_FLAGS_1(fnegs, TCG_CALL_NO_RWG_SE, f32, f32) DEF_HELPER_FLAGS_2(fitod, TCG_CALL_NO_RWG_SE, f64, env, s32) DEF_HELPER_FLAGS_2(fitoq, TCG_CALL_NO_RWG, void, env, s32) -DEF_HELPER_2(fitos, f32, env, s32) +DEF_HELPER_FLAGS_2(fitos, TCG_CALL_NO_RWG, f32, env, s32) #ifdef TARGET_SPARC64 DEF_HELPER_FLAGS_1(fnegd, TCG_CALL_NO_RWG_SE, f64, f64) DEF_HELPER_FLAGS_1(fnegq, TCG_CALL_NO_RWG, void, env) -DEF_HELPER_2(fxtos, f32, env, s64) -DEF_HELPER_2(fxtod, f64, env, s64) +DEF_HELPER_FLAGS_2(fxtos, TCG_CALL_NO_RWG, f32, env, s64) +DEF_HELPER_FLAGS_2(fxtod, TCG_CALL_NO_RWG, f64, env, s64) DEF_HELPER_FLAGS_2(fxtoq, TCG_CALL_NO_RWG, void, env, s64) #endif -DEF_HELPER_2(fdtos, f32, env, f64) -DEF_HELPER_2(fstod, f64, env, f32) -DEF_HELPER_1(fqtos, f32, env) -DEF_HELPER_2(fstoq, void, env, f32) -DEF_HELPER_1(fqtod, f64, env) -DEF_HELPER_2(fdtoq, void, env, f64) -DEF_HELPER_2(fstoi, s32, env, f32) -DEF_HELPER_2(fdtoi, s32, env, f64) -DEF_HELPER_1(fqtoi, s32, env) +DEF_HELPER_FLAGS_2(fdtos, TCG_CALL_NO_RWG, f32, env, f64) +DEF_HELPER_FLAGS_2(fstod, TCG_CALL_NO_RWG, f64, env, f32) +DEF_HELPER_FLAGS_1(fqtos, TCG_CALL_NO_RWG, f32, env) +DEF_HELPER_FLAGS_2(fstoq, TCG_CALL_NO_RWG, void, env, f32) +DEF_HELPER_FLAGS_1(fqtod, TCG_CALL_NO_RWG, f64, env) +DEF_HELPER_FLAGS_2(fdtoq, TCG_CALL_NO_RWG, void, env, f64) +DEF_HELPER_FLAGS_2(fstoi, TCG_CALL_NO_RWG, s32, env, f32) +DEF_HELPER_FLAGS_2(fdtoi, TCG_CALL_NO_RWG, s32, env, f64) +DEF_HELPER_FLAGS_1(fqtoi, TCG_CALL_NO_RWG, s32, env) #ifdef TARGET_SPARC64 -DEF_HELPER_2(fstox, s64, env, f32) -DEF_HELPER_2(fdtox, s64, env, f64) -DEF_HELPER_1(fqtox, s64, env) +DEF_HELPER_FLAGS_2(fstox, TCG_CALL_NO_RWG, s64, env, f32) +DEF_HELPER_FLAGS_2(fdtox, TCG_CALL_NO_RWG, s64, env, f64) +DEF_HELPER_FLAGS_1(fqtox, TCG_CALL_NO_RWG, s64, env) DEF_HELPER_FLAGS_2(fpmerge, TCG_CALL_NO_RWG_SE, i64, i64, i64) DEF_HELPER_FLAGS_2(fmul8x16, TCG_CALL_NO_RWG_SE, i64, i64, i64) diff --git a/target-sparc/translate.c b/target-sparc/translate.c index 2cf9f83..ed0853a 100644 --- a/target-sparc/translate.c +++ b/target-sparc/translate.c @@ -1518,16 +1518,16 @@ static inline void gen_op_fcmps(int fccno, TCGv_i32 r_rs1, TCGv_i32 r_rs2) { switch (fccno) { case 0: - gen_helper_fcmps(cpu_env, r_rs1, r_rs2); + gen_helper_fcmps(cpu_fsr, cpu_env, r_rs1, r_rs2); break; case 1: - gen_helper_fcmps_fcc1(cpu_env, r_rs1, r_rs2); + gen_helper_fcmps_fcc1(cpu_fsr, cpu_env, r_rs1, r_rs2); break; case 2: - gen_helper_fcmps_fcc2(cpu_env, r_rs1, r_rs2); + gen_helper_fcmps_fcc2(cpu_fsr, cpu_env, r_rs1, r_rs2); break; case 3: - gen_helper_fcmps_fcc3(cpu_env, r_rs1, r_rs2); + gen_helper_fcmps_fcc3(cpu_fsr, cpu_env, r_rs1, r_rs2); break; } } @@ -1536,16 +1536,16 @@ static inline void gen_op_fcmpd(int fccno, TCGv_i64 r_rs1, TCGv_i64 r_rs2) { switch (fccno) { case 0: - gen_helper_fcmpd(cpu_env, r_rs1, r_rs2); + gen_helper_fcmpd(cpu_fsr, cpu_env, r_rs1, r_rs2); break; case 1: - gen_helper_fcmpd_fcc1(cpu_env, r_rs1, r_rs2); + gen_helper_fcmpd_fcc1(cpu_fsr, cpu_env, r_rs1, r_rs2); break; case 2: - gen_helper_fcmpd_fcc2(cpu_env, r_rs1, r_rs2); + gen_helper_fcmpd_fcc2(cpu_fsr, cpu_env, r_rs1, r_rs2); break; case 3: - gen_helper_fcmpd_fcc3(cpu_env, r_rs1, r_rs2); + gen_helper_fcmpd_fcc3(cpu_fsr, cpu_env, r_rs1, r_rs2); break; } } @@ -1554,16 +1554,16 @@ static inline void gen_op_fcmpq(int fccno) { switch (fccno) { case 0: - gen_helper_fcmpq(cpu_env); + gen_helper_fcmpq(cpu_fsr, cpu_env); break; case 1: - gen_helper_fcmpq_fcc1(cpu_env); + gen_helper_fcmpq_fcc1(cpu_fsr, cpu_env); break; case 2: - gen_helper_fcmpq_fcc2(cpu_env); + gen_helper_fcmpq_fcc2(cpu_fsr, cpu_env); break; case 3: - gen_helper_fcmpq_fcc3(cpu_env); + gen_helper_fcmpq_fcc3(cpu_fsr, cpu_env); break; } } @@ -1572,16 +1572,16 @@ static inline void gen_op_fcmpes(int fccno, TCGv_i32 r_rs1, TCGv_i32 r_rs2) { switch (fccno) { case 0: - gen_helper_fcmpes(cpu_env, r_rs1, r_rs2); + gen_helper_fcmpes(cpu_fsr, cpu_env, r_rs1, r_rs2); break; case 1: - gen_helper_fcmpes_fcc1(cpu_env, r_rs1, r_rs2); + gen_helper_fcmpes_fcc1(cpu_fsr, cpu_env, r_rs1, r_rs2); break; case 2: - gen_helper_fcmpes_fcc2(cpu_env, r_rs1, r_rs2); + gen_helper_fcmpes_fcc2(cpu_fsr, cpu_env, r_rs1, r_rs2); break; case 3: - gen_helper_fcmpes_fcc3(cpu_env, r_rs1, r_rs2); + gen_helper_fcmpes_fcc3(cpu_fsr, cpu_env, r_rs1, r_rs2); break; } } @@ -1590,16 +1590,16 @@ static inline void gen_op_fcmped(int fccno, TCGv_i64 r_rs1, TCGv_i64 r_rs2) { switch (fccno) { case 0: - gen_helper_fcmped(cpu_env, r_rs1, r_rs2); + gen_helper_fcmped(cpu_fsr, cpu_env, r_rs1, r_rs2); break; case 1: - gen_helper_fcmped_fcc1(cpu_env, r_rs1, r_rs2); + gen_helper_fcmped_fcc1(cpu_fsr, cpu_env, r_rs1, r_rs2); break; case 2: - gen_helper_fcmped_fcc2(cpu_env, r_rs1, r_rs2); + gen_helper_fcmped_fcc2(cpu_fsr, cpu_env, r_rs1, r_rs2); break; case 3: - gen_helper_fcmped_fcc3(cpu_env, r_rs1, r_rs2); + gen_helper_fcmped_fcc3(cpu_fsr, cpu_env, r_rs1, r_rs2); break; } } @@ -1608,16 +1608,16 @@ static inline void gen_op_fcmpeq(int fccno) { switch (fccno) { case 0: - gen_helper_fcmpeq(cpu_env); + gen_helper_fcmpeq(cpu_fsr, cpu_env); break; case 1: - gen_helper_fcmpeq_fcc1(cpu_env); + gen_helper_fcmpeq_fcc1(cpu_fsr, cpu_env); break; case 2: - gen_helper_fcmpeq_fcc2(cpu_env); + gen_helper_fcmpeq_fcc2(cpu_fsr, cpu_env); break; case 3: - gen_helper_fcmpeq_fcc3(cpu_env); + gen_helper_fcmpeq_fcc3(cpu_fsr, cpu_env); break; } } @@ -1626,32 +1626,32 @@ static inline void gen_op_fcmpeq(int fccno) static inline void gen_op_fcmps(int fccno, TCGv r_rs1, TCGv r_rs2) { - gen_helper_fcmps(cpu_env, r_rs1, r_rs2); + gen_helper_fcmps(cpu_fsr, cpu_env, r_rs1, r_rs2); } static inline void gen_op_fcmpd(int fccno, TCGv_i64 r_rs1, TCGv_i64 r_rs2) { - gen_helper_fcmpd(cpu_env, r_rs1, r_rs2); + gen_helper_fcmpd(cpu_fsr, cpu_env, r_rs1, r_rs2); } static inline void gen_op_fcmpq(int fccno) { - gen_helper_fcmpq(cpu_env); + gen_helper_fcmpq(cpu_fsr, cpu_env); } static inline void gen_op_fcmpes(int fccno, TCGv r_rs1, TCGv r_rs2) { - gen_helper_fcmpes(cpu_env, r_rs1, r_rs2); + gen_helper_fcmpes(cpu_fsr, cpu_env, r_rs1, r_rs2); } static inline void gen_op_fcmped(int fccno, TCGv_i64 r_rs1, TCGv_i64 r_rs2) { - gen_helper_fcmped(cpu_env, r_rs1, r_rs2); + gen_helper_fcmped(cpu_fsr, cpu_env, r_rs1, r_rs2); } static inline void gen_op_fcmpeq(int fccno) { - gen_helper_fcmpeq(cpu_env); + gen_helper_fcmpeq(cpu_fsr, cpu_env); } #endif @@ -1687,6 +1687,7 @@ static inline void gen_fop_FF(DisasContext *dc, int rd, int rs, dst = gen_dest_fpr_F(dc); gen(dst, cpu_env, src); + gen_helper_check_ieee_exceptions(cpu_fsr, cpu_env); gen_store_fpr_F(dc, rd, dst); } @@ -1714,6 +1715,7 @@ static inline void gen_fop_FFF(DisasContext *dc, int rd, int rs1, int rs2, dst = gen_dest_fpr_F(dc); gen(dst, cpu_env, src1, src2); + gen_helper_check_ieee_exceptions(cpu_fsr, cpu_env); gen_store_fpr_F(dc, rd, dst); } @@ -1743,6 +1745,7 @@ static inline void gen_fop_DD(DisasContext *dc, int rd, int rs, dst = gen_dest_fpr_D(dc, rd); gen(dst, cpu_env, src); + gen_helper_check_ieee_exceptions(cpu_fsr, cpu_env); gen_store_fpr_D(dc, rd, dst); } @@ -1772,6 +1775,7 @@ static inline void gen_fop_DDD(DisasContext *dc, int rd, int rs1, int rs2, dst = gen_dest_fpr_D(dc, rd); gen(dst, cpu_env, src1, src2); + gen_helper_check_ieee_exceptions(cpu_fsr, cpu_env); gen_store_fpr_D(dc, rd, dst); } @@ -1827,6 +1831,7 @@ static inline void gen_fop_QQ(DisasContext *dc, int rd, int rs, gen_op_load_fpr_QT1(QFPREG(rs)); gen(cpu_env); + gen_helper_check_ieee_exceptions(cpu_fsr, cpu_env); gen_op_store_QT0_fpr(QFPREG(rd)); gen_update_fprs_dirty(QFPREG(rd)); @@ -1852,6 +1857,7 @@ static inline void gen_fop_QQQ(DisasContext *dc, int rd, int rs1, int rs2, gen_op_load_fpr_QT1(QFPREG(rs2)); gen(cpu_env); + gen_helper_check_ieee_exceptions(cpu_fsr, cpu_env); gen_op_store_QT0_fpr(QFPREG(rd)); gen_update_fprs_dirty(QFPREG(rd)); @@ -1868,6 +1874,7 @@ static inline void gen_fop_DFF(DisasContext *dc, int rd, int rs1, int rs2, dst = gen_dest_fpr_D(dc, rd); gen(dst, cpu_env, src1, src2); + gen_helper_check_ieee_exceptions(cpu_fsr, cpu_env); gen_store_fpr_D(dc, rd, dst); } @@ -1881,6 +1888,7 @@ static inline void gen_fop_QDD(DisasContext *dc, int rd, int rs1, int rs2, src2 = gen_load_fpr_D(dc, rs2); gen(cpu_env, src1, src2); + gen_helper_check_ieee_exceptions(cpu_fsr, cpu_env); gen_op_store_QT0_fpr(QFPREG(rd)); gen_update_fprs_dirty(QFPREG(rd)); @@ -1897,6 +1905,7 @@ static inline void gen_fop_DF(DisasContext *dc, int rd, int rs, dst = gen_dest_fpr_D(dc, rd); gen(dst, cpu_env, src); + gen_helper_check_ieee_exceptions(cpu_fsr, cpu_env); gen_store_fpr_D(dc, rd, dst); } @@ -1926,6 +1935,7 @@ static inline void gen_fop_FD(DisasContext *dc, int rd, int rs, dst = gen_dest_fpr_F(dc); gen(dst, cpu_env, src); + gen_helper_check_ieee_exceptions(cpu_fsr, cpu_env); gen_store_fpr_F(dc, rd, dst); } @@ -1939,6 +1949,7 @@ static inline void gen_fop_FQ(DisasContext *dc, int rd, int rs, dst = gen_dest_fpr_F(dc); gen(dst, cpu_env); + gen_helper_check_ieee_exceptions(cpu_fsr, cpu_env); gen_store_fpr_F(dc, rd, dst); } @@ -1952,6 +1963,7 @@ static inline void gen_fop_DQ(DisasContext *dc, int rd, int rs, dst = gen_dest_fpr_D(dc, rd); gen(dst, cpu_env); + gen_helper_check_ieee_exceptions(cpu_fsr, cpu_env); gen_store_fpr_D(dc, rd, dst); } @@ -5280,7 +5292,7 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn) if (rd == 1) { TCGv_i64 t64 = tcg_temp_new_i64(); tcg_gen_qemu_ld64(t64, cpu_addr, dc->mem_idx); - gen_helper_ldxfsr(cpu_env, t64); + gen_helper_ldxfsr(cpu_fsr, cpu_env, cpu_fsr, t64); tcg_temp_free_i64(t64); break; } @@ -5289,7 +5301,7 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn) t0 = get_temp_tl(dc); tcg_gen_qemu_ld32u(t0, cpu_addr, dc->mem_idx); tcg_gen_trunc_tl_i32(cpu_dst_32, t0); - gen_helper_ldfsr(cpu_env, cpu_dst_32); + gen_helper_ldfsr(cpu_fsr, cpu_env, cpu_fsr, cpu_dst_32); break; case 0x22: /* ldqf, load quad fpreg */ {