From patchwork Tue Oct 18 18:50:33 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 120492 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [140.186.70.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id E800A1007D1 for ; Wed, 19 Oct 2011 06:27:01 +1100 (EST) Received: from localhost ([::1]:57804 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1RGEn2-0003Z3-GF for incoming@patchwork.ozlabs.org; Tue, 18 Oct 2011 14:53:28 -0400 Received: from eggs.gnu.org ([140.186.70.92]:43849) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1RGElc-0001b3-65 for qemu-devel@nongnu.org; Tue, 18 Oct 2011 14:52:07 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1RGElX-0002Em-5n for qemu-devel@nongnu.org; Tue, 18 Oct 2011 14:51:59 -0400 Received: from mail-ww0-f53.google.com ([74.125.82.53]:33121) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1RGElW-00029l-Gl for qemu-devel@nongnu.org; Tue, 18 Oct 2011 14:51:55 -0400 Received: by mail-ww0-f53.google.com with SMTP id 36so1209775wwi.10 for ; Tue, 18 Oct 2011 11:51:53 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=sender:from:to:cc:subject:date:message-id:x-mailer:in-reply-to :references; bh=qEROOoAQmYmkjCBNzBsNz/fMxxfyHirTydhPQkrnIpg=; b=hkbXpxmls19fEFY5T9M0dgwFmKZJpGGy5KsYZUmKP1ZgQEI5/8OTGNWLHXrMa4p2oF TmvVVpHNH9UUXkXDo+2AeH50GlpzDXlOJUB9AHj4rc/P6IwRzVYCM7TAV17AST1D63y7 1oopmLgR3GMgzTuIRtXcPPFQXUKWYPbpRd7c4= Received: by 10.216.132.215 with SMTP id o65mr1236031wei.104.1318963913817; Tue, 18 Oct 2011 11:51:53 -0700 (PDT) Received: from localhost.localdomain (c-71-227-161-214.hsd1.wa.comcast.net. [71.227.161.214]) by mx.google.com with ESMTPS id 11sm5169602wby.15.2011.10.18.11.51.51 (version=TLSv1/SSLv3 cipher=OTHER); Tue, 18 Oct 2011 11:51:53 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Date: Tue, 18 Oct 2011 11:50:33 -0700 Message-Id: <1318963843-25100-12-git-send-email-rth@twiddle.net> X-Mailer: git-send-email 1.7.6.4 In-Reply-To: <1318963843-25100-1-git-send-email-rth@twiddle.net> References: <1318963843-25100-1-git-send-email-rth@twiddle.net> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6 (newer, 2) X-Received-From: 74.125.82.53 Cc: blauwirbel@gmail.com Subject: [Qemu-devel] [PATCH 11/21] target-sparc: Do exceptions management fully inside the helpers. 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 This reduces the size of the individual translation blocks, since we only emit a single call for each FOP rather than three. In addition, clear_float_exceptions expands inline to a single byte store. Signed-off-by: Richard Henderson --- target-sparc/fop_helper.c | 206 ++++++++++++++++++++++++++++++++------------- target-sparc/helper.h | 2 - target-sparc/translate.c | 29 ------- 3 files changed, 146 insertions(+), 91 deletions(-) diff --git a/target-sparc/fop_helper.c b/target-sparc/fop_helper.c index e652021..c7a2512 100644 --- a/target-sparc/fop_helper.c +++ b/target-sparc/fop_helper.c @@ -23,22 +23,71 @@ #define QT0 (env->qt0) #define QT1 (env->qt1) +static void check_ieee_exceptions(CPUState *env) +{ + target_ulong 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; + } + if (status & float_flag_overflow) { + env->fsr |= FSR_OFC; + } + if (status & float_flag_underflow) { + env->fsr |= FSR_UFC; + } + if (status & float_flag_divbyzero) { + env->fsr |= FSR_DZC; + } + if (status & float_flag_inexact) { + env->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; + helper_raise_exception(env, TT_FP_EXCP); + } else { + /* Accumulate exceptions */ + env->fsr |= (env->fsr & FSR_CEXC_MASK) << 5; + } + } +} + +static inline void clear_float_exceptions(CPUState *env) +{ + set_float_exception_flags(0, &env->fp_status); +} + #define F_HELPER(name, p) void helper_f##name##p(CPUState *env) #define F_BINOP(name) \ - float32 helper_f ## name ## s (CPUState * env, float32 src1,\ + float32 helper_f ## name ## s (CPUState *env, float32 src1, \ float32 src2) \ { \ - return float32_ ## name (src1, src2, &env->fp_status); \ + float32 ret; \ + clear_float_exceptions(env); \ + ret = float32_ ## name (src1, src2, &env->fp_status); \ + check_ieee_exceptions(env); \ + return ret; \ } \ float64 helper_f ## name ## d (CPUState * env, float64 src1,\ float64 src2) \ { \ - return float64_ ## name (src1, src2, &env->fp_status); \ + float64 ret; \ + clear_float_exceptions(env); \ + ret = float64_ ## name (src1, src2, &env->fp_status); \ + check_ieee_exceptions(env); \ + return ret; \ } \ F_HELPER(name, q) \ { \ + clear_float_exceptions(env); \ QT0 = float128_ ## name (QT0, QT1, &env->fp_status); \ + check_ieee_exceptions(env); \ } F_BINOP(add); @@ -49,16 +98,22 @@ F_BINOP(div); float64 helper_fsmuld(CPUState *env, float32 src1, float32 src2) { - return float64_mul(float32_to_float64(src1, &env->fp_status), - float32_to_float64(src2, &env->fp_status), - &env->fp_status); + 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; } void helper_fdmulq(CPUState *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) @@ -81,32 +136,48 @@ F_HELPER(neg, q) /* Integer to float conversion. */ float32 helper_fitos(CPUState *env, int32_t src) { - return int32_to_float32(src, &env->fp_status); + /* 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; } float64 helper_fitod(CPUState *env, int32_t src) { + /* No possible exceptions converting int to double. */ return int32_to_float64(src, &env->fp_status); } void helper_fitoq(CPUState *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(CPUState *env, int64_t src) { - return int64_to_float32(src, &env->fp_status); + float32 ret; + clear_float_exceptions(env); + ret = int64_to_float32(src, &env->fp_status); + check_ieee_exceptions(env); + return ret; } float64 helper_fxtod(CPUState *env, int64_t src) { - return int64_to_float64(src, &env->fp_status); + float64 ret; + clear_float_exceptions(env); + ret = int64_to_float64(src, &env->fp_status); + check_ieee_exceptions(env); + return ret; } void helper_fxtoq(CPUState *env, int64_t src) { + /* No possible exceptions converting long long to long double. */ QT0 = int64_to_float128(src, &env->fp_status); } #endif @@ -115,64 +186,108 @@ void helper_fxtoq(CPUState *env, int64_t src) /* floating point conversion */ float32 helper_fdtos(CPUState *env, float64 src) { - return float64_to_float32(src, &env->fp_status); + float32 ret; + clear_float_exceptions(env); + ret = float64_to_float32(src, &env->fp_status); + check_ieee_exceptions(env); + return ret; } float64 helper_fstod(CPUState *env, float32 src) { - return float32_to_float64(src, &env->fp_status); + float64 ret; + clear_float_exceptions(env); + ret = float32_to_float64(src, &env->fp_status); + check_ieee_exceptions(env); + return ret; } float32 helper_fqtos(CPUState *env) { - return float128_to_float32(QT1, &env->fp_status); + float32 ret; + clear_float_exceptions(env); + ret = float128_to_float32(QT1, &env->fp_status); + check_ieee_exceptions(env); + return ret; } void helper_fstoq(CPUState *env, float32 src) { + clear_float_exceptions(env); QT0 = float32_to_float128(src, &env->fp_status); + check_ieee_exceptions(env); } float64 helper_fqtod(CPUState *env) { - return float128_to_float64(QT1, &env->fp_status); + float64 ret; + clear_float_exceptions(env); + ret = float128_to_float64(QT1, &env->fp_status); + check_ieee_exceptions(env); + return ret; } void helper_fdtoq(CPUState *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(CPUState *env, float32 src) { - return float32_to_int32_round_to_zero(src, &env->fp_status); + int32_t ret; + clear_float_exceptions(env); + ret = float32_to_int32_round_to_zero(src, &env->fp_status); + check_ieee_exceptions(env); + return ret; } int32_t helper_fdtoi(CPUState *env, float64 src) { - return float64_to_int32_round_to_zero(src, &env->fp_status); + int32_t ret; + clear_float_exceptions(env); + ret = float64_to_int32_round_to_zero(src, &env->fp_status); + check_ieee_exceptions(env); + return ret; } int32_t helper_fqtoi(CPUState *env) { - return float128_to_int32_round_to_zero(QT1, &env->fp_status); + int32_t ret; + clear_float_exceptions(env); + ret = float128_to_int32_round_to_zero(QT1, &env->fp_status); + check_ieee_exceptions(env); + return ret; } #ifdef TARGET_SPARC64 int64_t helper_fstox(CPUState *env, float32 src) { - return float32_to_int64_round_to_zero(src, &env->fp_status); + int64_t ret; + clear_float_exceptions(env); + ret = float32_to_int64_round_to_zero(src, &env->fp_status); + check_ieee_exceptions(env); + return ret; } int64_t helper_fdtox(CPUState *env, float64 src) { - return float64_to_int64_round_to_zero(src, &env->fp_status); + int64_t ret; + clear_float_exceptions(env); + ret = float64_to_int64_round_to_zero(src, &env->fp_status); + check_ieee_exceptions(env); + return ret; } int64_t helper_fqtox(CPUState *env) { - return float128_to_int64_round_to_zero(QT1, &env->fp_status); + int64_t ret; + clear_float_exceptions(env); + ret = float128_to_int64_round_to_zero(QT1, &env->fp_status); + check_ieee_exceptions(env); + return ret; } #endif @@ -195,17 +310,27 @@ void helper_fabsq(CPUState *env) float32 helper_fsqrts(CPUState *env, float32 src) { - return float32_sqrt(src, &env->fp_status); + float32 ret; + clear_float_exceptions(env); + ret = float32_sqrt(src, &env->fp_status); + check_ieee_exceptions(env); + return ret; } float64 helper_fsqrtd(CPUState *env, float64 src) { - return float64_sqrt(src, &env->fp_status); + float64 ret; + clear_float_exceptions(env); + ret = float64_sqrt(src, &env->fp_status); + check_ieee_exceptions(env); + return ret; } void helper_fsqrtq(CPUState *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) \ @@ -318,45 +443,6 @@ GEN_FCMP(fcmpeq_fcc3, float128, QT0, QT1, 26, 1); #undef GEN_FCMP_T #undef GEN_FCMP -void helper_check_ieee_exceptions(CPUState *env) -{ - target_ulong 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; - } - if (status & float_flag_overflow) { - env->fsr |= FSR_OFC; - } - if (status & float_flag_underflow) { - env->fsr |= FSR_UFC; - } - if (status & float_flag_divbyzero) { - env->fsr |= FSR_DZC; - } - if (status & float_flag_inexact) { - env->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; - helper_raise_exception(env, TT_FP_EXCP); - } else { - /* Accumulate exceptions */ - env->fsr |= (env->fsr & FSR_CEXC_MASK) << 5; - } - } -} - -void helper_clear_float_exceptions(CPUState *env) -{ - set_float_exception_flags(0, &env->fp_status); -} - static inline void set_fsr(CPUState *env) { int rnd_mode; diff --git a/target-sparc/helper.h b/target-sparc/helper.h index df367a4..6e66574 100644 --- a/target-sparc/helper.h +++ b/target-sparc/helper.h @@ -46,8 +46,6 @@ DEF_HELPER_5(ld_asi, i64, env, tl, int, int, int) DEF_HELPER_5(st_asi, void, env, tl, i64, int, int) #endif DEF_HELPER_2(ldfsr, void, env, i32) -DEF_HELPER_1(check_ieee_exceptions, void, env) -DEF_HELPER_1(clear_float_exceptions, void, env) DEF_HELPER_FLAGS_1(fabss, TCG_CALL_CONST | TCG_CALL_PURE, f32, f32) DEF_HELPER_2(fsqrts, f32, env, f32) DEF_HELPER_2(fsqrtd, f64, env, f64) diff --git a/target-sparc/translate.c b/target-sparc/translate.c index 97a462b..d3f7648 100644 --- a/target-sparc/translate.c +++ b/target-sparc/translate.c @@ -1631,23 +1631,16 @@ static inline void gen_op_clear_ieee_excp_and_FTT(void) tcg_gen_andi_tl(cpu_fsr, cpu_fsr, FSR_FTT_CEXC_NMASK); } -static inline void gen_clear_float_exceptions(void) -{ - gen_helper_clear_float_exceptions(cpu_env); -} - static void gen_fop_FF(DisasContext *dc, int rd, int rs, void (*gen)(TCGv_i32, TCGv_ptr, TCGv_i32)) { TCGv_i32 dst, src; - gen_clear_float_exceptions(); src = gen_load_fpr_F(dc, rs); dst = gen_dest_fpr_F(); gen(dst, cpu_env, src); - gen_helper_check_ieee_exceptions(cpu_env); gen_store_fpr_F(dc, rd, dst); } @@ -1669,14 +1662,12 @@ static void gen_fop_FFF(DisasContext *dc, int rd, int rs1, int rs2, { TCGv_i32 dst, src1, src2; - gen_clear_float_exceptions(); src1 = gen_load_fpr_F(dc, rs1); src2 = gen_load_fpr_F(dc, rs2); dst = gen_dest_fpr_F(); gen(dst, cpu_env, src1, src2); - gen_helper_check_ieee_exceptions(cpu_env); gen_store_fpr_F(dc, rd, dst); } @@ -1701,13 +1692,11 @@ static void gen_fop_DD(DisasContext *dc, int rd, int rs, { TCGv_i64 dst, src; - gen_clear_float_exceptions(); src = gen_load_fpr_D(dc, rs); dst = gen_dest_fpr_D(); gen(dst, cpu_env, src); - gen_helper_check_ieee_exceptions(cpu_env); gen_store_fpr_D(dc, rd, dst); } @@ -1731,14 +1720,12 @@ static void gen_fop_DDD(DisasContext *dc, int rd, int rs1, int rs2, { TCGv_i64 dst, src1, src2; - gen_clear_float_exceptions(); src1 = gen_load_fpr_D(dc, rs1); src2 = gen_load_fpr_D(dc, rs2); dst = gen_dest_fpr_D(); gen(dst, cpu_env, src1, src2); - gen_helper_check_ieee_exceptions(cpu_env); gen_store_fpr_D(dc, rd, dst); } @@ -1761,12 +1748,10 @@ static void gen_ne_fop_DDD(DisasContext *dc, int rd, int rs1, int rs2, static void gen_fop_QQ(DisasContext *dc, int rd, int rs, void (*gen)(TCGv_ptr)) { - gen_clear_float_exceptions(); gen_op_load_fpr_QT1(QFPREG(rs)); gen(cpu_env); - gen_helper_check_ieee_exceptions(cpu_env); gen_op_store_QT0_fpr(QFPREG(rd)); gen_update_fprs_dirty(QFPREG(rd)); } @@ -1787,13 +1772,11 @@ static void gen_ne_fop_QQ(DisasContext *dc, int rd, int rs, static void gen_fop_QQQ(DisasContext *dc, int rd, int rs1, int rs2, void (*gen)(TCGv_ptr)) { - gen_clear_float_exceptions(); gen_op_load_fpr_QT0(QFPREG(rs1)); gen_op_load_fpr_QT1(QFPREG(rs2)); gen(cpu_env); - gen_helper_check_ieee_exceptions(cpu_env); gen_op_store_QT0_fpr(QFPREG(rd)); gen_update_fprs_dirty(QFPREG(rd)); } @@ -1804,14 +1787,12 @@ static void gen_fop_DFF(DisasContext *dc, int rd, int rs1, int rs2, TCGv_i64 dst; TCGv_i32 src1, src2; - gen_clear_float_exceptions(); src1 = gen_load_fpr_F(dc, rs1); src2 = gen_load_fpr_F(dc, rs2); dst = gen_dest_fpr_D(); gen(dst, cpu_env, src1, src2); - gen_helper_check_ieee_exceptions(cpu_env); gen_store_fpr_D(dc, rd, dst); } @@ -1820,13 +1801,11 @@ static void gen_fop_QDD(DisasContext *dc, int rd, int rs1, int rs2, { TCGv_i64 src1, src2; - gen_clear_float_exceptions(); src1 = gen_load_fpr_D(dc, rs1); src2 = gen_load_fpr_D(dc, rs2); gen(cpu_env, src1, src2); - gen_helper_check_ieee_exceptions(cpu_env); gen_op_store_QT0_fpr(QFPREG(rd)); gen_update_fprs_dirty(QFPREG(rd)); } @@ -1838,13 +1817,11 @@ static void gen_fop_DF(DisasContext *dc, int rd, int rs, TCGv_i64 dst; TCGv_i32 src; - gen_clear_float_exceptions(); src = gen_load_fpr_F(dc, rs); dst = gen_dest_fpr_D(); gen(dst, cpu_env, src); - gen_helper_check_ieee_exceptions(cpu_env); gen_store_fpr_D(dc, rd, dst); } #endif @@ -1869,13 +1846,11 @@ static void gen_fop_FD(DisasContext *dc, int rd, int rs, TCGv_i32 dst; TCGv_i64 src; - gen_clear_float_exceptions(); src = gen_load_fpr_D(dc, rs); dst = gen_dest_fpr_F(); gen(dst, cpu_env, src); - gen_helper_check_ieee_exceptions(cpu_env); gen_store_fpr_F(dc, rd, dst); } @@ -1884,13 +1859,11 @@ static void gen_fop_FQ(DisasContext *dc, int rd, int rs, { TCGv_i32 dst; - gen_clear_float_exceptions(); gen_op_load_fpr_QT1(QFPREG(rs)); dst = gen_dest_fpr_F(); gen(dst, cpu_env); - gen_helper_check_ieee_exceptions(cpu_env); gen_store_fpr_F(dc, rd, dst); } @@ -1899,13 +1872,11 @@ static void gen_fop_DQ(DisasContext *dc, int rd, int rs, { TCGv_i64 dst; - gen_clear_float_exceptions(); gen_op_load_fpr_QT1(QFPREG(rs)); dst = gen_dest_fpr_D(); gen(dst, cpu_env); - gen_helper_check_ieee_exceptions(cpu_env); gen_store_fpr_D(dc, rd, dst); }