From patchwork Mon Dec 19 03:11:23 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jim Wilson X-Patchwork-Id: 88409 Delivered-To: patch@linaro.org Received: by 10.140.20.101 with SMTP id 92csp959429qgi; Sun, 18 Dec 2016 19:12:14 -0800 (PST) X-Received: by 10.99.166.2 with SMTP id t2mr25436158pge.40.1482117134755; Sun, 18 Dec 2016 19:12:14 -0800 (PST) Return-Path: Received: from sourceware.org (server1.sourceware.org. [209.132.180.131]) by mx.google.com with ESMTPS id d6si16814209pgn.154.2016.12.18.19.12.14 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 18 Dec 2016 19:12:14 -0800 (PST) Received-SPF: pass (google.com: domain of gdb-patches-return-135834-patch=linaro.org@sourceware.org designates 209.132.180.131 as permitted sender) client-ip=209.132.180.131; Authentication-Results: mx.google.com; dkim=pass header.i=@sourceware.org; spf=pass (google.com: domain of gdb-patches-return-135834-patch=linaro.org@sourceware.org designates 209.132.180.131 as permitted sender) smtp.mailfrom=gdb-patches-return-135834-patch=linaro.org@sourceware.org; dmarc=fail (p=NONE dis=NONE) header.from=linaro.org DomainKey-Signature: a=rsa-sha1; c=nofws; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:mime-version:from:date:message-id:subject:to :cc:content-type; q=dns; s=default; b=W092Wqd5B4SPG2hNndNg9oRHpG jTv3SmONNpYN42YyWvlizbgAsz39ZABlu7OWartj3x9lUlGDflq+WI26kASdcU8e 4mNSEO0DuwvKl93Qq75tJ6LBd3ilCeu3ntGKanJ3wsypkwXLM8yvYUuiSBpxDEdm LUYOevJnEoEw0IEsM= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:mime-version:from:date:message-id:subject:to :cc:content-type; s=default; bh=xOjIkx4R0uive7R5lF+4B3COvkI=; b= mCt8ne37p3EnFL/QP8MLVMspNnxkaOTy3nlLlNfjoCFycTUE9lFA++PFkFqK0uw+ HkbHlPwmNKwD5mZwYKV3QbMsUZ2IXQgPntKgJHZUMGTMvMFY/qr90Nkx4JcmR9Mu sOlzXgRp3kttDj0kAH2sVUt2C1QICSQCYeYicmUzfx8= Received: (qmail 91703 invoked by alias); 19 Dec 2016 03:12:07 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Delivered-To: mailing list gdb-patches@sourceware.org Received: (qmail 91414 invoked by uid 89); 19 Dec 2016 03:11:36 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.9 required=5.0 tests=AWL, BAYES_00, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.2 spammy=signs, yield, sim_cpu, *cpu X-HELO: mail-yw0-f173.google.com Received: from mail-yw0-f173.google.com (HELO mail-yw0-f173.google.com) (209.85.161.173) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Mon, 19 Dec 2016 03:11:25 +0000 Received: by mail-yw0-f173.google.com with SMTP id t125so59558617ywc.1 for ; Sun, 18 Dec 2016 19:11:25 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:from:date:message-id:subject:to:cc; bh=Hjs4YtdW4xQcmr+HTHdD86iCzBOnfFBreFuA8+lhMv4=; b=ZwRmI0BOdi1jboL/3faeF8jF0fE+ZymF3OOgXqkNRY/2Rro0z/kjk4tIq9S0sXw5yX T06XRlczPg1beWvwR92Jw8B6In6BZlaVvy5AVljATDX3uaQwXSBTU3juPoY+5uh+yg+3 OpuzFewXCyhrUZRL/AvsC+H1dRBAjmdsc95dc0dif815nuKGkz8DhkVp/Escu+7fh3Xv XKNAMDKqcXWCIHdrjVInLvzWfEzC/o8VygMi6kYbepufpOam6mGvqMMkaXn+EuoNt3w+ cXUKt586vgcGx9uCuyVqqIZ4/2ZmfSHESkbD1tnV/K0KEz8/3cPtb6LhCwMUEnd/rbIx ovYQ== X-Gm-Message-State: AKaTC02sv3INgjRESqmS2uu8Q+cwZ/r+BMHlXndFQ5zeG/YEROuUGFDL8w4vorHS33aYPF+FYWmR0bBgt5IaQjSl X-Received: by 10.13.220.197 with SMTP id f188mr11415621ywe.6.1482117084231; Sun, 18 Dec 2016 19:11:24 -0800 (PST) MIME-Version: 1.0 Received: by 10.129.92.4 with HTTP; Sun, 18 Dec 2016 19:11:23 -0800 (PST) From: Jim Wilson Date: Sun, 18 Dec 2016 19:11:23 -0800 Message-ID: Subject: [PATCH] aarch64 sim bug fix for fcmp and infinity To: gdb-patches@sourceware.org Cc: Nick Clifton Debugging another gcc testsuite failure, I see that fcmp can fail when both operands are infinities. The code tries to compute the compare result by subtracting operands, but this can yield NaN when both operands are inifinities. This is fixed by explicitly checking for and handling this case. While writing the tescase, I noticed that qNan and sNan are not handled correctly, but this appears to be broken in more than just the compare instructions, so I just added comments to document the problem and will leave it to a later patch to fix. The new testcase fails without the patch, and works with the patch. Also, the gcc C testsuite unexpected failures drop from 2627 to 2568. Jim 2016-12-18 Jim Wilson sim/aarch64/ * simulator.c (set_flags_for_float_compare): Add code to handle Inf. Add comment to document NaN issue. (set_flags_for_double_compare): Likewise. sim/testsuite/sim/aarch64/ * fcmp.s: New. diff --git a/sim/aarch64/simulator.c b/sim/aarch64/simulator.c index e6406dc..be3d6c7 100644 --- a/sim/aarch64/simulator.c +++ b/sim/aarch64/simulator.c @@ -8468,8 +8468,22 @@ set_flags_for_float_compare (sim_cpu *cpu, float fvalue1, float fvalue2) { uint32_t flags; + /* FIXME: Add exception raising. */ if (isnan (fvalue1) || isnan (fvalue2)) flags = C|V; + else if (isinf (fvalue1) && isinf (fvalue2)) + { + /* Subtracting two infinities may give a NaN. We only need to compare + the signs, which we can get from isinf. */ + int result = isinf (fvalue1) - isinf (fvalue2); + + if (result == 0) + flags = Z|C; + else if (result < 0) + flags = N; + else /* (result > 0). */ + flags = C; + } else { float result = fvalue1 - fvalue2; @@ -8540,8 +8554,22 @@ set_flags_for_double_compare (sim_cpu *cpu, double dval1, double dval2) { uint32_t flags; + /* FIXME: Add exception raising. */ if (isnan (dval1) || isnan (dval2)) flags = C|V; + else if (isinf (dval1) && isinf (dval2)) + { + /* Subtracting two infinities may give a NaN. We only need to compare + the signs, which we can get from isinf. */ + int result = isinf (dval1) - isinf (dval2); + + if (result == 0) + flags = Z|C; + else if (result < 0) + flags = N; + else /* (result > 0). */ + flags = C; + } else { double result = dval1 - dval2; diff --git a/sim/testsuite/sim/aarch64/fcmp.s b/sim/testsuite/sim/aarch64/fcmp.s new file mode 100644 index 0000000..fd826c4 --- /dev/null +++ b/sim/testsuite/sim/aarch64/fcmp.s @@ -0,0 +1,146 @@ +# mach: aarch64 + +# Check the FP compare instructions: fcmps, fcmpzs, fcmpes, fcmpzes, fcmpd, +# fcmpzd, fcmped, fcmpzed. +# For 1 operand compares, check 0, 1, -1, +Inf, -Inf. +# For 2 operand compares, check 1/1, 1/-2, -1/2, +Inf/+Inf, +Inf/-Inf. +# FIXME: Check for qNaN and sNaN when exception raising support added. + +.include "testutils.inc" + + start + fmov s0, wzr + fcmp s0, #0.0 + bne .Lfailure + fcmpe s0, #0.0 + bne .Lfailure + fmov d0, xzr + fcmp d0, #0.0 + bne .Lfailure + fcmpe d0, #0.0 + bne .Lfailure + + fmov s0, #1.0 + fcmp s0, #0.0 + blo .Lfailure + fcmpe s0, #0.0 + blo .Lfailure + fmov d0, #1.0 + fcmp d0, #0.0 + blo .Lfailure + fcmpe d0, #0.0 + blo .Lfailure + + fmov s0, #-1.0 + fcmp s0, #0.0 + bpl .Lfailure + fcmpe s0, #0.0 + bpl .Lfailure + fmov d0, #-1.0 + fcmp d0, #0.0 + bpl .Lfailure + fcmpe d0, #0.0 + bpl .Lfailure + + fmov s0, #1.0 + fmov s1, wzr + fdiv s0, s0, s1 + fcmp s0, #0.0 + blo .Lfailure + fcmpe s0, #0.0 + blo .Lfailure + fmov d0, #1.0 + fmov d1, xzr + fdiv d0, d0, d1 + fcmp d0, #0.0 + blo .Lfailure + fcmpe d0, #0.0 + blo .Lfailure + + fmov s0, #-1.0 + fmov s1, wzr + fdiv s0, s0, s1 + fcmp s0, #0.0 + bpl .Lfailure + fcmpe s0, #0.0 + bpl .Lfailure + fmov d0, #-1.0 + fmov d1, xzr + fdiv d0, d0, d1 + fcmp d0, #0.0 + bpl .Lfailure + fcmpe d0, #0.0 + bpl .Lfailure + + fmov s0, #1.0 + fmov s1, #1.0 + fcmp s0, s1 + bne .Lfailure + fcmpe s0, s1 + bne .Lfailure + fmov d0, #1.0 + fmov d1, #1.0 + fcmp d0, d1 + bne .Lfailure + fcmpe d0, d1 + bne .Lfailure + + fmov s0, #1.0 + fmov s1, #-2.0 + fcmp s0, s1 + blo .Lfailure + fcmpe s0, s1 + blo .Lfailure + fmov d0, #1.0 + fmov d1, #-2.0 + fcmp d0, d1 + blo .Lfailure + fcmpe d0, d1 + blo .Lfailure + + fmov s0, #-1.0 + fmov s1, #2.0 + fcmp s0, s1 + bpl .Lfailure + fcmpe s0, s1 + bpl .Lfailure + fmov d0, #-1.0 + fmov d1, #2.0 + fcmp d0, d1 + bpl .Lfailure + fcmpe d0, d1 + bpl .Lfailure + + fmov s0, #1.0 + fmov s1, wzr + fdiv s0, s0, s1 + fcmp s0, s0 + bne .Lfailure + fcmpe s0, s0 + bne .Lfailure + fmov s1, #-1.0 + fmov s2, wzr + fdiv s1, s1, s2 + fcmp s0, s1 + blo .Lfailure + fcmpe s0, s1 + blo .Lfailure + + fmov d0, #1.0 + fmov d1, xzr + fdiv d0, d0, d1 + fcmp d0, d0 + bne .Lfailure + fcmpe d0, d0 + bne .Lfailure + fmov d1, #-1.0 + fmov d2, xzr + fdiv d1, d1, d2 + fcmp d0, d1 + blo .Lfailure + fcmpe d0, d1 + blo .Lfailure + + pass +.Lfailure: + fail