From patchwork Sun Apr 19 18:45:19 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Uros Bizjak X-Patchwork-Id: 1272994 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=2620:52:3:1:0:246e:9693:128c; helo=sourceware.org; envelope-from=gcc-patches-bounces@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=gcc.gnu.org Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.a=rsa-sha256 header.s=default header.b=k84b0kZL; dkim-atps=neutral Received: from sourceware.org (server2.sourceware.org [IPv6:2620:52:3:1:0:246e:9693:128c]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 494zKw2Kyhz9sR4 for ; Mon, 20 Apr 2020 04:45:37 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id C82FB385C426; Sun, 19 Apr 2020 18:45:34 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org C82FB385C426 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1587321934; bh=IEALq4P8bPZoAETzZhpMEqDM9m1u3niVGLQ2vDQDGpw=; h=Date:Subject:To:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:Cc:From; b=k84b0kZLvQpQxYl6TBm9SD0IfwwPa/VgetzKMvCA9CDhhgwN2c3tJxUZXC9EayWtN iBEAWED83Y9KemWoD+pmJy7dQqvkSPCmapuWghFkMtS92rtATwMZUt4i5aj7/gi5I6 Bnlv/OTxDYkbJI2+/rvOmCPojAwpJGiwgjs4+7wc= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mail-il1-x12e.google.com (mail-il1-x12e.google.com [IPv6:2607:f8b0:4864:20::12e]) by sourceware.org (Postfix) with ESMTPS id 9ECCF3858D31 for ; Sun, 19 Apr 2020 18:45:31 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 9ECCF3858D31 Received: by mail-il1-x12e.google.com with SMTP id x2so6166242ilp.13 for ; Sun, 19 Apr 2020 11:45:31 -0700 (PDT) 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=IEALq4P8bPZoAETzZhpMEqDM9m1u3niVGLQ2vDQDGpw=; b=qHLZskFjzG8ROMEhxhaZz9XLeR7FRm3kchRgjLM1JlFb+Mp6q/8s96G2F00rgRnXXg Pp96ntHWjL+Ujbj3vHuHfG/8kqFycM0QaeItaNFInjTFhSByw3e2AXMKhqPszdOJMUjF myWJjWPuyNahs1YlEqokRAiAhsxuaFD98Z35HeLjlMtFRPwDFawrvGFIy5dfGfiE7uuJ 7ydSJNZIHiQwy3i23YA5FEXnw5wRbSpt+ZyD8Je+GUC6fksY6uh8nAl7SEncOkTWWK84 8LLaEJVsvwG84E4lzI6oDbCwA7/bGoWzbN3YKcQyyVaJmNd+o+qIIgjcqN9IHjubPj5E N8mA== X-Gm-Message-State: AGi0PuaHHD8jQnQMw2wuy/BOgtWQDYrMGGGhLynJqz/5gcP/ZQfr3ajP gFnW+JyuszWBoh0IQ4DXUhi6xkMqjSatdNRNa4UZs1K7 X-Google-Smtp-Source: APiQypKlpq6BD5CJoq82fcCgYaPZqoiNP2UD650UG4VTBgzs5HgrDLHHySpamNgLB5dKn9b7wCrIt2WQSFKdYel39nA= X-Received: by 2002:a92:d484:: with SMTP id p4mr12124834ilg.307.1587321930905; Sun, 19 Apr 2020 11:45:30 -0700 (PDT) MIME-Version: 1.0 Date: Sun, 19 Apr 2020 20:45:19 +0200 Message-ID: Subject: [RFA PATCH]: i386: Use generic division to generate INVALID and DIVZERO exceptions To: "gcc-patches@gcc.gnu.org" X-Spam-Status: No, score=-20.8 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_FROM, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) 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: Uros Bizjak via Gcc-patches From: Uros Bizjak Reply-To: Uros Bizjak Cc: Jakub Jelinek , Richard Biener Errors-To: gcc-patches-bounces@gcc.gnu.org Sender: "Gcc-patches" This patch implements the idea from glibc, where generic division operations instead of assembly are used where appropriate. --commit-- i386: Use generic division to generate INVALID and DIVZERO exceptions Introduce math_force_eval to evaluate generic division to generate INVALID and DIVZERO exceptions. libgcc/ChangeLog: 2020-04-19 Uroš Bizjak * config/i386/sfp-exceptions.c (math_force_eval): New define. (__sfp_handle_exceptions): Use math_force_eval to evaluete generic division to generate INVALID and DIVZERO exceptions. libatomic/ChangeLog: 2020-04-19 Uroš Bizjak * config/x86/fenv.c (math_force_eval): New define. (__atomic_feraiseexcept): Use math_force_eval to evaluete generic division to generate INVALID and DIVZERO exceptions. libgfortran/ChangeLog: 2020-04-19 Uroš Bizjak * config/fpu-387.h (_math_force_eval): New define. (local_feraiseexcept): Use math_force_eval to evaluete generic division to generate INVALID and DIVZERO exceptions. --/commit-- The patch was bootstrapped and regression tested on x86_64-linux-gnu {,-m32}. Also, as part of glibc's patch evaluation, I have extensively tested it to check that it really generates only correct exceptions for both, x87 and SSE math. Additionally, the patch improves code for DIVZERO exception, as we can now use FDIVRP mnemonic. This mnemonic has its own share of confusion (see e.g. SYSV386_COMPAT macro definition) and its use in asm should be avoided. --/commit message-- The patch looks safe to me, but I'd like to ask RMs for approval. Uros. diff --git a/libatomic/config/x86/fenv.c b/libatomic/config/x86/fenv.c index d7b1bbe5ea1..be1db42245c 100644 --- a/libatomic/config/x86/fenv.c +++ b/libatomic/config/x86/fenv.c @@ -47,6 +47,12 @@ struct fenv unsigned short int __unused5; }; +#ifdef __SSE_MATH__ +# define math_force_eval(x) asm volatile ("" : : "x" (x)); +#else +# define math_force_eval(x) asm volatile ("" : : "f" (x)); +#endif + /* Raise the supported floating-point exceptions from EXCEPTS. Other bits in EXCEPTS are ignored. */ @@ -56,12 +62,7 @@ __atomic_feraiseexcept (int excepts) if (excepts & FE_INVALID) { float f = 0.0f; -#ifdef __SSE_MATH__ - asm volatile ("%vdivss\t{%0, %d0|%d0, %0}" : "+x" (f)); -#else - asm volatile ("fdiv\t{%y0, %0|%0, %y0}" : "+t" (f)); - /* No need for fwait, exception is triggered by emitted fstp. */ -#endif + math_force_eval (f / f); } if (excepts & FE_DENORM) { @@ -74,12 +75,7 @@ __atomic_feraiseexcept (int excepts) if (excepts & FE_DIVBYZERO) { float f = 1.0f, g = 0.0f; -#ifdef __SSE_MATH__ - asm volatile ("%vdivss\t{%1, %d0|%d0, %1}" : "+x" (f) : "xm" (g)); -#else - asm volatile ("fdivs\t%1" : "+t" (f) : "m" (g)); - /* No need for fwait, exception is triggered by emitted fstp. */ -#endif + math_force_eval (f / g); } if (excepts & FE_OVERFLOW) { diff --git a/libgcc/config/i386/sfp-exceptions.c b/libgcc/config/i386/sfp-exceptions.c index 31a24ced704..57047ab1d07 100644 --- a/libgcc/config/i386/sfp-exceptions.c +++ b/libgcc/config/i386/sfp-exceptions.c @@ -41,18 +41,19 @@ struct fenv unsigned short int __unused5; }; +#ifdef __SSE_MATH__ +# define math_force_eval(x) asm volatile ("" : : "x" (x)); +#else +# define math_force_eval(x) asm volatile ("" : : "f" (x)); +#endif + void __sfp_handle_exceptions (int _fex) { if (_fex & FP_EX_INVALID) { float f = 0.0f; -#ifdef __SSE_MATH__ - asm volatile ("%vdivss\t{%0, %d0|%d0, %0}" : "+x" (f)); -#else - asm volatile ("fdiv\t{%y0, %0|%0, %y0}" : "+t" (f)); - /* No need for fwait, exception is triggered by emitted fstp. */ -#endif + math_force_eval (f / f); } if (_fex & FP_EX_DENORM) { @@ -65,12 +66,7 @@ __sfp_handle_exceptions (int _fex) if (_fex & FP_EX_DIVZERO) { float f = 1.0f, g = 0.0f; -#ifdef __SSE_MATH__ - asm volatile ("%vdivss\t{%1, %d0|%d0, %1}" : "+x" (f) : "xm" (g)); -#else - asm volatile ("fdivs\t%1" : "+t" (f) : "m" (g)); - /* No need for fwait, exception is triggered by emitted fstp. */ -#endif + math_force_eval (f / g); } if (_fex & FP_EX_OVERFLOW) { diff --git a/libgfortran/config/fpu-387.h b/libgfortran/config/fpu-387.h index 13be2045b72..08c994f69da 100644 --- a/libgfortran/config/fpu-387.h +++ b/libgfortran/config/fpu-387.h @@ -91,6 +91,11 @@ my_fenv_t; _Static_assert (sizeof(my_fenv_t) <= (size_t) GFC_FPE_STATE_BUFFER_SIZE, "GFC_FPE_STATE_BUFFER_SIZE is too small"); +#ifdef __SSE_MATH__ +# define _math_force_eval(x) __asm__ __volatile__ ("" : : "x" (x)); +#else +# define _math_force_eval(x) __asm__ __volatile__ ("" : : "f" (x)); +#endif /* Raise the supported floating-point exceptions from EXCEPTS. Other bits in EXCEPTS are ignored. Code originally borrowed from @@ -102,12 +107,7 @@ local_feraiseexcept (int excepts) if (excepts & _FPU_MASK_IM) { float f = 0.0f; -#ifdef __SSE_MATH__ - __asm__ __volatile__ ("%vdivss\t{%0, %d0|%d0, %0}" : "+x" (f)); -#else - __asm__ __volatile__ ("fdiv\t{%y0, %0|%0, %y0}" : "+t" (f)); - /* No need for fwait, exception is triggered by emitted fstp. */ -#endif + _math_force_eval (f / f); } if (excepts & _FPU_MASK_DM) { @@ -120,12 +120,7 @@ local_feraiseexcept (int excepts) if (excepts & _FPU_MASK_ZM) { float f = 1.0f, g = 0.0f; -#ifdef __SSE_MATH__ - __asm__ __volatile__ ("%vdivss\t{%1, %d0|%d0, %1}" : "+x" (f) : "xm" (g)); -#else - __asm__ __volatile__ ("fdivs\t%1" : "+t" (f) : "m" (g)); - /* No need for fwait, exception is triggered by emitted fstp. */ -#endif + _math_force_eval (f / g); } if (excepts & _FPU_MASK_OM) {