From patchwork Wed Jul 17 09:29:23 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Uros Bizjak X-Patchwork-Id: 259635 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client CN "localhost", Issuer "www.qmailtoaster.com" (not verified)) by ozlabs.org (Postfix) with ESMTPS id 797AE2C008F for ; Wed, 17 Jul 2013 19:29:38 +1000 (EST) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender :mime-version:in-reply-to:references:date:message-id:subject :from:to:cc:content-type; q=dns; s=default; b=NPLCU1bqb8qg2mPq/x N7Zo4xpN6HqnoebE221zICMu3BJzTQ2rNxbRpKElLB5+Nc4rklnqIMBO0j536YkU Cyy5MGjrGLrL/bUHWyQuTffm+Df7Qtgmnz72H28yLMJQVRK4I2Ejbn1TSci/ILoE xnkrBBvlQjPQcwEm5hZirz9ks= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender :mime-version:in-reply-to:references:date:message-id:subject :from:to:cc:content-type; s=default; bh=mpB3Bg/TSyIwXf9K3wZBLmSe BC4=; b=S5qZPH0aRH8fPec+C0BCH2ANcr/87+Ojns4xCdxFQL4HEnHrF3UC1Ues Xvx25zfm3onxcxD/AlpEMNADqoST3NAWrfJ8NcscxcyX0McpyglPiuCrWeo8uvPm JCHuOoQLCRciqvozhZ7ytXYWSpw8OEAgExc9y7zdIeONnYfbIR8= Received: (qmail 27403 invoked by alias); 17 Jul 2013 09:29:32 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 27386 invoked by uid 89); 17 Jul 2013 09:29:31 -0000 X-Spam-SWARE-Status: No, score=-1.5 required=5.0 tests=AWL, BAYES_50, FREEMAIL_FROM, KHOP_THREADED, RCVD_IN_DNSWL_LOW, RCVD_IN_HOSTKARMA_YE, RDNS_NONE, SPF_PASS autolearn=ham version=3.3.1 X-Spam-User: qpsmtpd, 2 recipients Received: from Unknown (HELO mail-oa0-f47.google.com) (209.85.219.47) by sourceware.org (qpsmtpd/0.84/v0.84-167-ge50287c) with ESMTP; Wed, 17 Jul 2013 09:29:31 +0000 Received: by mail-oa0-f47.google.com with SMTP id m1so2212573oag.20 for ; Wed, 17 Jul 2013 02:29:23 -0700 (PDT) MIME-Version: 1.0 X-Received: by 10.182.246.39 with SMTP id xt7mr1604633obc.18.1374053363409; Wed, 17 Jul 2013 02:29:23 -0700 (PDT) Received: by 10.182.92.202 with HTTP; Wed, 17 Jul 2013 02:29:23 -0700 (PDT) In-Reply-To: <51E65DA2.9050101@net-b.de> References: <51E65DA2.9050101@net-b.de> Date: Wed, 17 Jul 2013 11:29:23 +0200 Message-ID: Subject: Re: [Patch, Fortran] PR35862 - add input I/O rounding support - by setting the CPU rounding mode From: Uros Bizjak To: Tobias Burnus Cc: gcc patches , gfortran , David Edelsohn , Gerald Pfeifer , Eric Botcazou X-Virus-Found: No On Wed, Jul 17, 2013 at 11:02 AM, Tobias Burnus wrote: > As there is again a CPU dependence: > - David, can you have a look at config/fpu-aix.h? > - Eric and Gerald, can you have a look at config/fpu-sysv.h? > - Uros, can you have a look at config/fpu-387.h? Please use attached (untested for fortran) patch for fpu-387.h. Uros. Index: libgfortran/config/fpu-387.h =================================================================== --- libgfortran/config/fpu-387.h (revision 200979) +++ libgfortran/config/fpu-387.h (working copy) @@ -88,7 +88,7 @@ #endif } -/* i387 -- see linux header file for details. */ +/* i387 exceptions -- see linux header file for details. */ #define _FPU_MASK_IM 0x01 #define _FPU_MASK_DM 0x02 #define _FPU_MASK_ZM 0x04 @@ -99,7 +99,18 @@ #define _FPU_EX_ALL 0x3f -void set_fpu (void) +/* i387 rounding modes. */ + +#define _FPU_RC_NEAREST 0x0 +#define _FPU_RC_DOWN 0x400 +#define _FPU_RC_UP 0x800 +#define _FPU_RC_ZERO 0xc00 + +#define _FPU_RC_MASK 0xc00 + + +void +set_fpu (void) { int excepts = 0; unsigned short cw; @@ -164,3 +175,72 @@ return result; } + +void +set_fpu_rounding_mode (int round) +{ + int round_mode; + unsigned short cw; + + switch (round) + { + case GFC_FPE_TONEAREST: + round_mode = _FPU_RC_NEAREST; + break; + case GFC_FPE_UPWARD: + round_mode = _FPU_RC_UP; + break; + case GFC_FPE_DOWNWARD: + round_mode = _FPU_RC_DOWN; + break; + case GFC_FPE_TOWARDZERO: + round_mode = _FPU_RC_ZERO; + break; + default: + return; /* Should be unreachable. */ + } + + __asm__ __volatile__ ("fnstcw\t%0" : "=m" (cw)); + + cw &= ~FPU_RC_MASK; + cw |= round_mode; + + __asm__ __volatile__ ("fldcw\t%0" : : "m" (cw)); + + if (has_sse()) + { + unsigned int cw_sse; + + __asm__ __volatile__ ("%vstmxcsr\t%0" : "=m" (cw_sse)); + + /* The SSE round control bits are shifted by 3 bits. */ + cw_sse &= ~(FPU_RC_MASK << 3); + cw_sse |= round_mode << 3; + + __asm__ __volatile__ ("%vldmxcsr\t%0" : : "m" (cw_sse)); + } +} + +int +get_fpu_rounding_mode (void) +{ + unsigned short cw; + + __asm__ __volatile__ ("fnstcw\t%0" : "=m" (cw)); + + cw &= FPU_RC_MASK; + + switch (cw) + { + case _FPU_RC_NEAREST: + return GFC_FPE_TONEAREST; + case _FPU_RC_UP: + return GFC_FPE_UPWARD; + case _FPU_RC_DOWN: + return GFC_FPE_DOWNWARD; + case _FPU_RC_ZERO: + return GFC_FPE_TOWARDZERO; + default: + return GFC_FPE_INVALID; /* Should be unreachable. */ + } +}