From patchwork Wed Aug 23 02:15:04 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Keith Packard X-Patchwork-Id: 136623 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:a7d1:0:b0:3f2:4152:657d with SMTP id p17csp191941vqm; Tue, 22 Aug 2023 19:16:03 -0700 (PDT) X-Google-Smtp-Source: AGHT+IEhGBK+ad+IsbXce0rUqDV3CcT9URvPhavbs/NlPx730Elid5BEobwtFVIuEfyTGanYTeWE X-Received: by 2002:a17:907:60c6:b0:9a1:7919:d3cb with SMTP id hv6-20020a17090760c600b009a17919d3cbmr9048635ejc.49.1692756963596; Tue, 22 Aug 2023 19:16:03 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1692756963; cv=none; d=google.com; s=arc-20160816; b=X/RYjcgDP1YXdVVgaaiiwjEhXG3bz6IdcQ/jzexRctQQtbt8VVm2SYzH7Y6o0U8ze1 IoePeSS6a++zWeq5tigaMvwKHJRPoFZdxmC8PaVE6z+IHxEGE6SWhCLIedZwee9t2JCW 9xrCuyH7fCvijZlC9wK7VAst8wOJydN+IypPM3PTMIcwYgijQ4Xd9k5uLzArKxwvOHxH sUQrEnOTKUaJPPYxmFkNubarnvkqNGNZtF39BijBkNjT6YhZFjad7MEkjoILENXtA5PQ 7nYOGyZdBJhyBkennEFCm2qPmX+77CVFVeKTnsXSTI6bHNErlDhRIumPfZ+zAXchK0RC MmmQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:reply-to:from:list-subscribe:list-help:list-post :list-archive:list-unsubscribe:list-id:precedence :content-transfer-encoding:mime-version:message-id:date:subject:cc :to:dmarc-filter:delivered-to:dkim-signature:dkim-filter; bh=XXy7KJRiNKqVrHvZGxG2vzUN486umlD/R9c9G8eaihk=; fh=fTi9MQnFroaE5vtJRmC5+6whoEOwKYrKNaKYL+hHrA8=; b=ab3XMhNLG6NGPP7Ji9uCr5BaEIPKtY+418lXgbR6SzH4i89VkbOwKmLWOt3dQLNaxY Thv22aQHpSQRAZBeUrnBk4JVZg6ZdOLOWt0X8vsqGFtWyp0xnbqpf6w9qcrVnCsgBgtZ AcIfTK4dCQqMK6MvBKwH4rUldH1GBUZGQ56lnDzbMWGVRrNrGJrbDDB8GKF3TFdu6G6G 6apufUJcAdrs3wVYapGDXsFoI0MF47RHbLZ6FM1513daZgYSF+WMTmikKAolXvT1GByn ovOuz4Zj3sRCktquk0d00R5IP3uAiObyX7iaipyhvvmU2v5OHnxaa4Shu5udcXb2fusO 7fqg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gcc.gnu.org header.s=default header.b=IrdABUdH; spf=pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 8.43.85.97 as permitted sender) smtp.mailfrom="gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=gnu.org Received: from server2.sourceware.org (ip-8-43-85-97.sourceware.org. [8.43.85.97]) by mx.google.com with ESMTPS id s19-20020a1709062ed300b0099b49483261si8498175eji.311.2023.08.22.19.16.03 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 22 Aug 2023 19:16:03 -0700 (PDT) Received-SPF: pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 8.43.85.97 as permitted sender) client-ip=8.43.85.97; Authentication-Results: mx.google.com; dkim=pass header.i=@gcc.gnu.org header.s=default header.b=IrdABUdH; spf=pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 8.43.85.97 as permitted sender) smtp.mailfrom="gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=gnu.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 75F893857C41 for ; Wed, 23 Aug 2023 02:16:02 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 75F893857C41 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1692756962; bh=XXy7KJRiNKqVrHvZGxG2vzUN486umlD/R9c9G8eaihk=; h=To:Cc:Subject:Date:List-Id:List-Unsubscribe:List-Archive: List-Post:List-Help:List-Subscribe:From:Reply-To:From; b=IrdABUdHxuU/Dtzjng0G+/Q9mh4hDw0jtQ12O/5dYTCXW6lbId2TFrrhNTv1zwGtq eTG2ntIWYXZp+41zXiTkvtISmxlJTcnJASAhVTZ363WDRS+KTSjylfNSoypCnnC/dJ dEZhiCrtvrgyB4gz22KOPqmgEx/BBXiLusimk9qo= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from elaine.keithp.com (home.keithp.com [63.227.221.253]) by sourceware.org (Postfix) with ESMTPS id 302AC3857C41 for ; Wed, 23 Aug 2023 02:15:08 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 302AC3857C41 Received: from localhost (localhost [127.0.0.1]) by elaine.keithp.com (Postfix) with ESMTP id 13A2B3F20CF9 for ; Tue, 22 Aug 2023 19:15:07 -0700 (PDT) X-Virus-Scanned: Debian amavis at keithp.com Received: from elaine.keithp.com ([127.0.0.1]) by localhost (elaine.keithp.com [127.0.0.1]) (amavis, port 10024) with LMTP id TBhtYyuY6Qyv; Tue, 22 Aug 2023 19:15:06 -0700 (PDT) Received: from keithp.com (koto.keithp.com [192.168.11.2]) by elaine.keithp.com (Postfix) with ESMTPSA id 0A23E3F2069A; Tue, 22 Aug 2023 19:15:06 -0700 (PDT) Received: by keithp.com (Postfix, from userid 1000) id BE7561E601EE; Tue, 22 Aug 2023 19:15:05 -0700 (PDT) To: gcc-patches@gcc.gnu.org Cc: Keith Packard Subject: [PATCH] libgcc/m68k: Fixes for soft float Date: Tue, 22 Aug 2023 19:15:04 -0700 Message-Id: <20230823021504.3864764-1-keithp@keithp.com> X-Mailer: git-send-email 2.40.1 MIME-Version: 1.0 X-Spam-Status: No, score=-10.7 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Keith Packard via Gcc-patches From: Keith Packard Reply-To: Keith Packard Errors-To: gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org Sender: "Gcc-patches" X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1774984325842454702 X-GMAIL-MSGID: 1774984325842454702 Check for non-zero denorm in __adddf3. Need to check both the upper and lower 32-bit chunks of a 64-bit float for a non-zero value when checking to see if the value is -0. Fix __addsf3 when the sum exponent is exactly 0xff to ensure that produces infinity and not nan. Handle converting NaN/inf values between formats. Handle underflow and overflow when truncating. Write a replacement for __fixxfsi so that it does not raise extra exceptions during an extra conversion from long double to double. Signed-off-by: Keith Packard --- libgcc/config/m68k/fpgnulib.c | 161 +++++++++++++++++++++++++++------- libgcc/config/m68k/lb1sf68.S | 7 +- 2 files changed, 134 insertions(+), 34 deletions(-) diff --git a/libgcc/config/m68k/fpgnulib.c b/libgcc/config/m68k/fpgnulib.c index fe41edf26aa..5b53778e986 100644 --- a/libgcc/config/m68k/fpgnulib.c +++ b/libgcc/config/m68k/fpgnulib.c @@ -54,6 +54,7 @@ #define SIGNBIT 0x80000000L #define HIDDEN (1L << 23L) #define SIGN(fp) ((fp) & SIGNBIT) +#define EXPMASK 0xFFL #define EXP(fp) (((fp) >> 23L) & 0xFF) #define MANT(fp) (((fp) & 0x7FFFFFL) | HIDDEN) #define PACK(s,e,m) ((s) | ((e) << 23L) | (m)) @@ -262,6 +263,9 @@ __extendsfdf2 (float a1) mant &= ~HIDDEN; } exp = exp - EXCESS + EXCESSD; + /* Handle inf and NaN */ + if (exp == EXPMASK - EXCESS + EXCESSD) + exp = EXPDMASK; dl.l.upper |= exp << 20; dl.l.upper |= mant >> 3; dl.l.lower = mant << 29; @@ -295,40 +299,52 @@ __truncdfsf2 (double a1) /* shift double mantissa 6 bits so we can round */ sticky |= mant & ((1 << 6) - 1); mant >>= 6; - - /* Check for underflow and denormals. */ - if (exp <= 0) + if (exp == EXPDMASK - EXCESSD + EXCESS) + { + exp = EXPMASK; + mant = mant >> 1 | (mant & 1) | !!sticky; + } + else { - if (exp < -24) + /* Check for underflow and denormals. */ + if (exp <= 0) { - sticky |= mant; - mant = 0; + if (exp < -24) + { + sticky |= mant; + mant = 0; + } + else + { + sticky |= mant & ((1 << (1 - exp)) - 1); + mant >>= 1 - exp; + } + exp = 0; } - else + + /* now round */ + shift = 1; + if ((mant & 1) && (sticky || (mant & 2))) { - sticky |= mant & ((1 << (1 - exp)) - 1); - mant >>= 1 - exp; - } - exp = 0; - } - - /* now round */ - shift = 1; - if ((mant & 1) && (sticky || (mant & 2))) - { - int rounding = exp ? 2 : 1; + int rounding = exp ? 2 : 1; - mant += 1; + mant += 1; - /* did the round overflow? */ - if (mant >= (HIDDEN << rounding)) + /* did the round overflow? */ + if (mant >= (HIDDEN << rounding)) + { + exp++; + shift = rounding; + } + } + /* shift down */ + mant >>= shift; + if (exp >= EXPMASK) { - exp++; - shift = rounding; + exp = EXPMASK; + mant = 0; } } - /* shift down */ - mant >>= shift; mant &= ~HIDDEN; @@ -432,6 +448,30 @@ __extenddfxf2 (double d) } exp = EXPD (dl) - EXCESSD + EXCESSX; + /* Check for underflow and denormals. */ + if (exp < 0) + { + if (exp < -53) + { + ldl.l.middle = 0; + ldl.l.lower = 0; + } + else if (exp < -30) + { + ldl.l.lower = (ldl.l.middle & MANTXMASK) >> ((1 - exp) - 32); + ldl.l.middle &= ~MANTXMASK; + } + else + { + ldl.l.lower >>= 1 - exp; + ldl.l.lower |= (ldl.l.middle & MANTXMASK) << (32 - (1 - exp)); + ldl.l.middle = (ldl.l.middle & ~MANTXMASK) | (ldl.l.middle & MANTXMASK >> (1 - exp)); + } + exp = 0; + } + /* Handle inf and NaN */ + if (exp == EXPDMASK - EXCESSD + EXCESSX) + exp = EXPXMASK; ldl.l.upper |= exp << 16; ldl.l.middle = HIDDENX; /* 31-20: # mantissa bits in ldl.l.middle - # mantissa bits in dl.l.upper */ @@ -464,9 +504,38 @@ __truncxfdf2 (long double ld) } exp = EXPX (ldl) - EXCESSX + EXCESSD; - /* ??? quick and dirty: keep `exp' sane */ - if (exp >= EXPDMASK) - exp = EXPDMASK - 1; + /* Check for underflow and denormals. */ + if (exp <= 0) + { + if (exp < -53) + { + ldl.l.middle = 0; + ldl.l.lower = 0; + } + else if (exp < -30) + { + ldl.l.lower = (ldl.l.middle & MANTXMASK) >> ((1 - exp) - 32); + ldl.l.middle &= ~MANTXMASK; + } + else + { + ldl.l.lower >>= 1 - exp; + ldl.l.lower |= (ldl.l.middle & MANTXMASK) << (32 - (1 - exp)); + ldl.l.middle = (ldl.l.middle & ~MANTXMASK) | (ldl.l.middle & MANTXMASK >> (1 - exp)); + } + exp = 0; + } + else if (exp == EXPXMASK - EXCESSX + EXCESSD) + { + exp = EXPDMASK; + ldl.l.middle |= ldl.l.lower; + } + else if (exp >= EXPDMASK) + { + exp = EXPDMASK; + ldl.l.middle = 0; + ldl.l.lower = 0; + } dl.l.upper |= exp << (32 - (EXPDBITS + 1)); /* +1-1: add one for sign bit, but take one off for explicit-integer-bit */ dl.l.upper |= (ldl.l.middle & MANTXMASK) >> (EXPDBITS + 1 - 1); @@ -511,10 +580,40 @@ __floatunsixf (unsigned long l) /* convert a long double to an int */ long -__fixxfsi (long double ld) +__fixxfsi (long double a) { - long foo = __fixdfsi ((double) ld); - return foo; + union long_double_long ldl; + long exp; + long l; + + ldl.ld = a; + + exp = EXPX(ldl); + if (exp == 0 && ldl.l.middle == 0 && ldl.l.lower == 0) + return 0; + + exp = exp - EXCESSX - 63; + + if (exp > 0) + { + /* Return largest integer. */ + return SIGNX (ldl) ? 0x80000000L : 0x7fffffffL; + } + + if (exp <= -64) + return 0; + + if (exp <= -32) + { + ldl.l.lower = ldl.l.middle >> (-exp - 32); + } + else if (exp < 0) + { + ldl.l.lower = ldl.l.lower >> -exp; + ldl.l.lower |= ldl.l.middle << (32 + exp); + } + + return SIGNX(ldl) ? -ldl.l.lower : ldl.l.lower; } /* The remaining provide crude math support by working in double precision. */ diff --git a/libgcc/config/m68k/lb1sf68.S b/libgcc/config/m68k/lb1sf68.S index 8ba85c53656..736a9a7872f 100644 --- a/libgcc/config/m68k/lb1sf68.S +++ b/libgcc/config/m68k/lb1sf68.S @@ -1383,6 +1383,8 @@ Ladddf$a: bge 2f | movel d0,d0 | check for zero, since we don't ' bne Ladddf$ret | want to return -0 by mistake + movel d1,d1 | + bne Ladddf$ret | bclr IMM (31),d7 | bra Ladddf$ret | 2: @@ -2090,8 +2092,7 @@ Ldivdf$a$nf: | If a is INFINITY we have to check b cmpl d7,d2 | compare b with INFINITY bge Ld$inop | if b is NaN or INFINITY return NaN - tstl d3 | - bne Ld$inop | + movl a0,d7 | restore sign bit to d7 bra Ld$overflow | else return overflow | If a number is denormalized we put an exponent of 1 but do not put the @@ -2936,7 +2937,7 @@ Laddsf$4: #else cmpl IMM (0xff),d2 #endif - bhi 1f + bge 1f bclr IMM (FLT_MANT_DIG-1),d0 #ifndef __mcoldfire__ lslw IMM (7),d2