From patchwork Fri Apr 18 14:50:31 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tom Musta X-Patchwork-Id: 340349 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 4B4EF1400EF for ; Sat, 19 Apr 2014 01:08:07 +1000 (EST) Received: from localhost ([::1]:38443 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1WbAOa-0002UT-L9 for incoming@patchwork.ozlabs.org; Fri, 18 Apr 2014 11:08:04 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:44086) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1WbA8n-0006WP-Nq for qemu-devel@nongnu.org; Fri, 18 Apr 2014 10:52:01 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1WbA8a-0000b4-G0 for qemu-devel@nongnu.org; Fri, 18 Apr 2014 10:51:45 -0400 Received: from mail-qc0-x232.google.com ([2607:f8b0:400d:c01::232]:54720) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1WbA8a-0000Z5-1z; Fri, 18 Apr 2014 10:51:32 -0400 Received: by mail-qc0-f178.google.com with SMTP id i8so1753489qcq.37 for ; Fri, 18 Apr 2014 07:51:31 -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=jzY11EnfUZxK+cbWW318FwNMLi5Q6A9oGQRkx3dXN7U=; b=jZm+OGpGdaz7DjAEceZm4a66rwgcoAclEBbw6pqR/emL8BlQjOUypdtI+P1oLrBfCx 2ou2wFPdVyffIrGT1cF7l6Z5lhKP4FF2K3kpuTMFSPmQfUqyFMBiEaWWRn+1COWu9mDP xRU+o5N1bxhWC2tKb4ieaCy6q1D8vyV1BxM6sVqO0L7FCx9iLB6b7HlYfgn6skbVLnqr Mny3lfDivtY9GqG9ZDc1yfVhXRus7GCpc4MM5+JzjHISq+xBJSgCtRKcSwY8ROuGqwo1 d10Yd/rIfBRg92r4k2xd9xK5goktkoYHWlfD9H9rojnfFjLqyRNfCkG7XrwVOFT+5/7A UvYQ== X-Received: by 10.140.25.104 with SMTP id 95mr24459304qgs.39.1397832691345; Fri, 18 Apr 2014 07:51:31 -0700 (PDT) Received: from tmusta-sc.rchland.ibm.com (rchp4.rochester.ibm.com. [129.42.161.36]) by mx.google.com with ESMTPSA id u59sm37020178qga.8.2014.04.18.07.51.29 for (version=TLSv1.1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Fri, 18 Apr 2014 07:51:30 -0700 (PDT) From: Tom Musta To: qemu-devel@nongnu.org Date: Fri, 18 Apr 2014 09:50:31 -0500 Message-Id: <1397832641-10254-28-git-send-email-tommusta@gmail.com> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: <1397832641-10254-1-git-send-email-tommusta@gmail.com> References: <1397832641-10254-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:c01::232 Cc: Tom Musta , qemu-ppc@nongnu.org Subject: [Qemu-devel] [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 --- 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 ff00cd4..d2031b8 100644 --- a/target-ppc/dfp_helper.c +++ b/target-ppc/dfp_helper.c @@ -386,6 +386,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) \ { \ @@ -710,3 +727,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); \ + dfp_run_post_processors(&dfp, QUA_PPs, ARRAY_SIZE(QUA_PPs)); \ + \ + 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)