From patchwork Mon Apr 21 20:55:11 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tom Musta X-Patchwork-Id: 341092 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 15943140078 for ; Tue, 22 Apr 2014 13:18:57 +1000 (EST) Received: from localhost ([::1]:51490 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1WcLPB-00080L-V6 for incoming@patchwork.ozlabs.org; Mon, 21 Apr 2014 17:05:33 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:51442) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1WcLGa-0005Hx-3j for qemu-devel@nongnu.org; Mon, 21 Apr 2014 16:56:54 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1WcLGM-00069O-18 for qemu-devel@nongnu.org; Mon, 21 Apr 2014 16:56:40 -0400 Received: from mail-qg0-x22f.google.com ([2607:f8b0:400d:c04::22f]:64007) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1WcLGL-00067d-KQ; Mon, 21 Apr 2014 16:56:25 -0400 Received: by mail-qg0-f47.google.com with SMTP id e89so738143qgf.6 for ; Mon, 21 Apr 2014 13:56:25 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=CwqohlHLPHwHIOCH2X07oUQnRYEgfd0ob8Jr6cMv6uE=; b=l7Kpcci36hyGtWmn/2Y+qCt4v3ONlYTlkE+1DDxs02xx5hOLb//nGAUeBImPYfpI09 SOVM+gIODFhnnePnbSMEiVY0Hp/KK3wqNapz0smZHC8QtGwN/bUOXJombYsM8QOl5f7S pg33ZfjuTl6dyVzvbrTCFb4Fah0CYM6sgcXoEMW1sKxSbYw6ipGjsizDGi7UvrfyvvDN HupiNtpA5kxpuRs4vMM83lCsX7pi+79RocyO/fpyiJkyii5+VFw6Yzb5O2Tm7s1UORxB YRHu/xsqvs0dAted5/if3hWGWZSKTC8Il6wuhAEMrOztaxV+WIRdGlYC0UmgdvyF4PLg KmOA== X-Received: by 10.140.96.51 with SMTP id j48mr47017151qge.24.1398113785202; Mon, 21 Apr 2014 13:56:25 -0700 (PDT) Received: from tmusta-sc.rchland.ibm.com (rchp4.rochester.ibm.com. [129.42.161.36]) by mx.google.com with ESMTPSA id g7sm75183676qaf.14.2014.04.21.13.56.23 for (version=TLSv1.1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Mon, 21 Apr 2014 13:56:24 -0700 (PDT) From: Tom Musta To: qemu-devel@nongnu.org Date: Mon, 21 Apr 2014 15:55:11 -0500 Message-Id: <1398113721-15782-28-git-send-email-tommusta@gmail.com> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: <1398113721-15782-1-git-send-email-tommusta@gmail.com> References: <1398113721-15782-1-git-send-email-tommusta@gmail.com> X-detected-operating-system: by eggs.gnu.org: Error: Malformed IPv6 address (bad octet value). X-Received-From: 2607:f8b0:400d:c04::22f Cc: Tom Musta , qemu-ppc@nongnu.org Subject: [Qemu-devel] [V2 PATCH 27/37] target-ppc: Introduce DFP Reround 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 Add emulation of the PowerPC Decimal Floating Point Reround instructions drrnd[q][.]. Signed-off-by: Tom Musta --- V2: Modified post processor handling per Richard Henderson's review. target-ppc/dfp_helper.c | 97 +++++++++++++++++++++++++++++++++++++++++++++++ target-ppc/helper.h | 2 + target-ppc/translate.c | 4 ++ 3 files changed, 103 insertions(+), 0 deletions(-) diff --git a/target-ppc/dfp_helper.c b/target-ppc/dfp_helper.c index 37024b0..dd67ad2 100644 --- a/target-ppc/dfp_helper.c +++ b/target-ppc/dfp_helper.c @@ -374,6 +374,23 @@ static inline void dfp_makeQNaN(decNumber *dn) dn->bits |= DECNAN; } +static inline int dfp_get_digit(decNumber *dn, int n) +{ + assert(DECDPUN == 3); + int unit = n / DECDPUN; + int dig = n % DECDPUN; + switch (dig) { + case 0: + return dn->lsu[unit] % 10; + case 1: + return (dn->lsu[unit] / 10) % 10; + case 2: + return dn->lsu[unit] / 100; + default: + assert(0); + } +} + #define DFP_HELPER_TAB(op, dnop, postprocs, size) \ void helper_##op(CPUPPCState *env, uint64_t *t, uint64_t *a, uint64_t *b) \ { \ @@ -700,3 +717,83 @@ void helper_##op(CPUPPCState *env, uint64_t *t, uint64_t *a, \ DFP_HELPER_QUA(dqua, 64) DFP_HELPER_QUA(dquaq, 128) + +static void _dfp_reround(uint8_t rmc, int32_t ref_sig, int32_t xmax, + struct PPC_DFP *dfp) +{ + int msd_orig, msd_rslt; + + if (unlikely((ref_sig == 0) || (dfp->b.digits <= ref_sig))) { + dfp->t = dfp->b; + if (decNumberIsSNaN(&dfp->b)) { + dfp_makeQNaN(&dfp->t); + dfp_set_FPSCR_flag(dfp, FP_VX | FP_VXSNAN, FPSCR_VE); + } + return; + } + + /* Reround is equivalent to quantizing b with 1**E(n) where */ + /* n = exp(b) + numDigits(b) - reference_significance. */ + + decNumberFromUInt32(&dfp->a, 1); + dfp->a.exponent = dfp->b.exponent + dfp->b.digits - ref_sig; + + if (unlikely(dfp->a.exponent > xmax)) { + dfp->t.digits = 0; + dfp->t.bits &= ~DECNEG; + dfp_makeQNaN(&dfp->t); + dfp_set_FPSCR_flag(dfp, FP_VX | FP_VXCVI, FPSCR_VE); + return; + } + + dfp_quantize(rmc, dfp); + + msd_orig = dfp_get_digit(&dfp->b, dfp->b.digits-1); + msd_rslt = dfp_get_digit(&dfp->t, dfp->t.digits-1); + + /* If the quantization resulted in rounding up to the next magnitude, */ + /* then we need to shift the significand and adjust the exponent. */ + + if (unlikely((msd_orig == 9) && (msd_rslt == 1))) { + + decNumber negone; + + decNumberFromInt32(&negone, -1); + decNumberShift(&dfp->t, &dfp->t, &negone, &dfp->context); + dfp->t.exponent++; + + if (unlikely(dfp->t.exponent > xmax)) { + dfp_makeQNaN(&dfp->t); + dfp->t.digits = 0; + dfp_set_FPSCR_flag(dfp, FP_VX | FP_VXCVI, FP_VE); + /* Inhibit XX in this case */ + decContextClearStatus(&dfp->context, DEC_Inexact); + } + } +} + +#define DFP_HELPER_RRND(op, size) \ +void helper_##op(CPUPPCState *env, uint64_t *t, uint64_t *a, \ + uint64_t *b, uint32_t rmc) \ +{ \ + struct PPC_DFP dfp; \ + int32_t ref_sig = *a & 0x3F; \ + int32_t xmax = ((size) == 64) ? 369 : 6111; \ + \ + dfp_prepare_decimal##size(&dfp, 0, b, env); \ + \ + _dfp_reround(rmc, ref_sig, xmax, &dfp); \ + decimal##size##FromNumber((decimal##size *)dfp.t64, &dfp.t, \ + &dfp.context); \ + QUA_PPs(&dfp); \ + \ + if (size == 64) { \ + t[0] = dfp.t64[0]; \ + } else if (size == 128) { \ + t[0] = dfp.t64[HI_IDX]; \ + t[1] = dfp.t64[LO_IDX]; \ + } \ +} + +DFP_HELPER_RRND(drrnd, 64) +DFP_HELPER_RRND(drrndq, 128) diff --git a/target-ppc/helper.h b/target-ppc/helper.h index 81b29e5..b63affb 100644 --- a/target-ppc/helper.h +++ b/target-ppc/helper.h @@ -642,4 +642,6 @@ DEF_HELPER_5(dquai, void, env, fprp, fprp, i32, i32) DEF_HELPER_5(dquaiq, void, env, fprp, fprp, i32, i32) DEF_HELPER_5(dqua, void, env, fprp, fprp, fprp, i32) DEF_HELPER_5(dquaq, void, env, fprp, fprp, fprp, i32) +DEF_HELPER_5(drrnd, void, env, fprp, fprp, fprp, i32) +DEF_HELPER_5(drrndq, void, env, fprp, fprp, fprp, i32) #include "exec/def-helper.h" diff --git a/target-ppc/translate.c b/target-ppc/translate.c index 5af35d7..3738012 100644 --- a/target-ppc/translate.c +++ b/target-ppc/translate.c @@ -8380,6 +8380,8 @@ GEN_DFP_T_B_U32_U32_Rc(dquai, SIMM5, RMC) GEN_DFP_T_B_U32_U32_Rc(dquaiq, SIMM5, RMC) GEN_DFP_T_A_B_I32_Rc(dqua, RMC) GEN_DFP_T_A_B_I32_Rc(dquaq, RMC) +GEN_DFP_T_A_B_I32_Rc(drrnd, RMC) +GEN_DFP_T_A_B_I32_Rc(drrndq, RMC) /*** SPE extension ***/ /* Register moves */ @@ -11331,6 +11333,8 @@ GEN_DFP_TE_T_B_RMC_Rc(dquai, 0x03, 0x02), GEN_DFP_TE_Tp_Bp_RMC_Rc(dquaiq, 0x03, 0x02), GEN_DFP_T_A_B_RMC_Rc(dqua, 0x03, 0x00), GEN_DFP_Tp_Ap_Bp_RMC_Rc(dquaq, 0x03, 0x00), +GEN_DFP_T_A_B_RMC_Rc(drrnd, 0x03, 0x01), +GEN_DFP_Tp_A_Bp_RMC_Rc(drrndq, 0x03, 0x01), #undef GEN_SPE #define GEN_SPE(name0, name1, opc2, opc3, inval0, inval1, type) \ GEN_OPCODE_DUAL(name0##_##name1, 0x04, opc2, opc3, inval0, inval1, type, PPC_NONE)