From patchwork Wed Apr 23 02:32:22 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sandra Loosemore X-Patchwork-Id: 341690 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.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 887891400DF for ; Wed, 23 Apr 2014 12:33:18 +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 :message-id:date:from:mime-version:to:cc:subject:content-type; q=dns; s=default; b=aS7bGxfIyP47FAxmX2micun2TOEPi7CPq8iZWZoDcKi cmF1jevxsW5k6Dml7tqT9pStJmSCOBVVb7GA1FXTagslckOMweNj5f7EwYbWVaV9 QQKsAhYteZKri/ezcpEc3RIRkMTgNEtl885eXAkHTTIgJpZJ8rCWv2sNrUSSY1jQ = 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 :message-id:date:from:mime-version:to:cc:subject:content-type; s=default; bh=m5UyS6Lh5mrUHyq6nENWcbMl3NQ=; b=ODePOl9Nm3uAskBee ZpneLNji5fyZljOqzuigrjzr3nXtOCp0XNFK0lR9YRN2kilJ5m45+MLBXEvl4yKR Gb5O/71Xon7rwPjH6S0FXw80Dsk3ItYPu1300/fGq2Bk6MjQoRxPmp3px2+gAki7 r+9+VBoUKG3Aczx8aeBElzK260= Received: (qmail 3747 invoked by alias); 23 Apr 2014 02:33:09 -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 3702 invoked by uid 89); 23 Apr 2014 02:33:03 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.8 required=5.0 tests=AWL, BAYES_00 autolearn=ham version=3.3.2 X-HELO: relay1.mentorg.com Received: from relay1.mentorg.com (HELO relay1.mentorg.com) (192.94.38.131) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Wed, 23 Apr 2014 02:32:36 +0000 Received: from svr-orw-fem-01.mgc.mentorg.com ([147.34.98.93]) by relay1.mentorg.com with esmtp id 1WcmzA-0004Yg-4M from Sandra_Loosemore@mentor.com for gcc-patches@gcc.gnu.org; Tue, 22 Apr 2014 19:32:32 -0700 Received: from SVR-ORW-FEM-06.mgc.mentorg.com ([147.34.97.120]) by svr-orw-fem-01.mgc.mentorg.com over TLS secured channel with Microsoft SMTPSVC(6.0.3790.4675); Tue, 22 Apr 2014 19:32:31 -0700 Received: from [IPv6:::1] (147.34.91.1) by SVR-ORW-FEM-06.mgc.mentorg.com (147.34.97.120) with Microsoft SMTP Server id 14.2.247.3; Tue, 22 Apr 2014 19:32:31 -0700 Message-ID: <53572636.8010100@codesourcery.com> Date: Tue, 22 Apr 2014 20:32:22 -0600 From: Sandra Loosemore User-Agent: Mozilla/5.0 (X11; Linux i686; rv:17.0) Gecko/20130329 Thunderbird/17.0.5 MIME-Version: 1.0 To: GCC Patches CC: Chung-Lin Tang Subject: [patch, nios2] support for custom round instructions Altera requested us to extend the set of custom floating-point instructions supported by the Nios II back end to include a round instruction, with semantics matching the __builtin_lroundf function. The basic machinery for this is already in place for the existing custom instructions, so much of this patch is cut-and-paste. The one new complication is that GCC doesn't use an inline expansion for this builtin unless -fno-math-errno is also specified, so I made the back end check for that as well as documenting the limitation. Some of the other custom instructions already have similar restrictions requiring -ffinite-math-only, etc., so that part was also just following current practice and building on existing framework, just adding a new flag. I've checked this in. -Sandra Index: gcc/config/nios2/nios2.md =================================================================== --- gcc/config/nios2/nios2.md (revision 209669) +++ gcc/config/nios2/nios2.md (working copy) @@ -70,6 +70,7 @@ UNSPEC_FATAN UNSPEC_FEXP UNSPEC_FLOG + UNSPEC_ROUND UNSPEC_LOAD_GOT_REGISTER UNSPEC_PIC_SYM UNSPEC_PIC_CALL_SYM @@ -585,6 +586,13 @@ { return nios2_fpu_insn_asm (n2fpu_fix); } [(set_attr "type" "custom")]) +(define_insn "lroundsfsi2" + [(set (match_operand:SI 0 "register_operand" "=r") + (unspec:SI [(match_operand:SF 1 "general_operand" "r")] UNSPEC_ROUND))] + "nios2_fpu_insn_enabled (n2fpu_round)" + { return nios2_fpu_insn_asm (n2fpu_round); } + [(set_attr "type" "custom")]) + (define_insn "extendsfdf2" [(set (match_operand:DF 0 "register_operand" "=r") (float_extend:DF (match_operand:SF 1 "general_operand" "r")))] Index: gcc/config/nios2/nios2.opt =================================================================== --- gcc/config/nios2/nios2.opt (revision 209669) +++ gcc/config/nios2/nios2.opt (working copy) @@ -529,3 +529,13 @@ Do not use the fwrx custom instruction mcustom-fwrx= Target Report RejectNegative Joined UInteger Var(nios2_custom_fwrx) Init(-1) Integer id (N) of fwrx custom instruction + +mno-custom-round +Target Report RejectNegative Var(nios2_custom_round, -1) +Do not use the round custom instruction + +mcustom-round= +Target Report RejectNegative Joined UInteger Var(nios2_custom_round) Init(-1) +Integer id (N) of round custom instruction + + Index: gcc/config/nios2/nios2-opts.h =================================================================== --- gcc/config/nios2/nios2-opts.h (revision 209669) +++ gcc/config/nios2/nios2-opts.h (working copy) @@ -42,7 +42,7 @@ along with GCC; see the file COPYING3. \ N2FPU_CODE(floatis) N2FPU_CODE(floatus) \ N2FPU_CODE(floatid) N2FPU_CODE(floatud) \ - N2FPU_CODE(fixsi) N2FPU_CODE(fixsu) \ + N2FPU_CODE(round) N2FPU_CODE(fixsi) N2FPU_CODE(fixsu) \ N2FPU_CODE(fixdi) N2FPU_CODE(fixdu) \ N2FPU_CODE(fextsd) N2FPU_CODE(ftruncds) \ \ Index: gcc/config/nios2/nios2.c =================================================================== --- gcc/config/nios2/nios2.c (revision 209669) +++ gcc/config/nios2/nios2.c (working copy) @@ -192,6 +192,7 @@ struct nios2_fpu_insn_info #define N2F_DFREQ 0x2 #define N2F_UNSAFE 0x4 #define N2F_FINITE 0x8 +#define N2F_NO_ERRNO 0x10 unsigned int flags; enum insn_code icode; enum nios2_ftcode ftcode; @@ -274,6 +275,7 @@ struct nios2_fpu_insn_info nios2_fpu_ins N2FPU_INSN_DEF_BASE (floatus, 2, 0, floatunssisf2, (SF, UI)), N2FPU_INSN_DEF_BASE (floatid, 2, 0, floatsidf2, (DF, SI)), N2FPU_INSN_DEF_BASE (floatud, 2, 0, floatunssidf2, (DF, UI)), + N2FPU_INSN_DEF_BASE (round, 2, N2F_NO_ERRNO, lroundsfsi2, (SI, SF)), N2FPU_INSN_DEF_BASE (fixsi, 2, 0, fix_truncsfsi2, (SI, SF)), N2FPU_INSN_DEF_BASE (fixsu, 2, 0, fixuns_truncsfsi2, (UI, SF)), N2FPU_INSN_DEF_BASE (fixdi, 2, 0, fix_truncdfsi2, (SI, DF)), @@ -298,6 +300,7 @@ struct nios2_fpu_insn_info nios2_fpu_ins #define N2FPU_FTCODE(code) (N2FPU(code).ftcode) #define N2FPU_FINITE_P(code) (N2FPU(code).flags & N2F_FINITE) #define N2FPU_UNSAFE_P(code) (N2FPU(code).flags & N2F_UNSAFE) +#define N2FPU_NO_ERRNO_P(code) (N2FPU(code).flags & N2F_NO_ERRNO) #define N2FPU_DOUBLE_P(code) (N2FPU(code).flags & N2F_DF) #define N2FPU_DOUBLE_REQUIRED_P(code) (N2FPU(code).flags & N2F_DFREQ) @@ -844,6 +847,15 @@ nios2_custom_check_insns (void) warning (0, "switch %<-mcustom-%s%> has no effect unless " "-ffinite-math-only is specified", N2FPU_NAME (i)); + /* Warn if the user is trying to use a custom rounding instruction + that won't get used without -fno-math-errno. See + expand_builtin_int_roundingfn_2 () in builtins.c. */ + if (flag_errno_math) + for (i = 0; i < ARRAY_SIZE (nios2_fpu_insn); i++) + if (N2FPU_ENABLED_P (i) && N2FPU_NO_ERRNO_P (i)) + warning (0, "switch %<-mcustom-%s%> has no effect unless " + "-fno-math-errno is specified", N2FPU_NAME (i)); + if (errors || custom_code_conflict) fatal_error ("conflicting use of -mcustom switches, target attributes, " "and/or __builtin_custom_ functions"); Index: gcc/doc/invoke.texi =================================================================== --- gcc/doc/invoke.texi (revision 209669) +++ gcc/doc/invoke.texi (working copy) @@ -18485,6 +18485,12 @@ Conversion from double precision to sing Conversion from floating point to signed or unsigned integer types, with truncation towards zero. +@item @samp{round} +Conversion from single-precision floating point to signed integer, +rounding to the nearest integer and ties away from zero. +This corresponds to the @code{__builtin_lroundf} function when +@option{-fno-math-errno} is used. + @item @samp{floatis}, @samp{floatus}, @samp{floatid}, @samp{floatud} Conversion from signed or unsigned integer types to floating-point types. Index: gcc/testsuite/gcc.target/nios2/custom-fp-conversion.c =================================================================== --- gcc/testsuite/gcc.target/nios2/custom-fp-conversion.c (revision 209669) +++ gcc/testsuite/gcc.target/nios2/custom-fp-conversion.c (working copy) @@ -1,10 +1,11 @@ /* Test generation of conversion custom instructions. */ /* { dg-do compile } */ -/* { dg-options "-O1 -ffinite-math-only -funsafe-math-optimizations" } */ +/* { dg-options "-O1 -ffinite-math-only -funsafe-math-optimizations -fno-math-errno" } */ /* -O1 in the options is significant. Without it FP operations may not be - optimized to custom instructions. */ + optimized to custom instructions. Also, -fno-math-errno is required + to inline lroundf. */ #include #include @@ -25,6 +26,8 @@ #pragma GCC target ("custom-floatud=107") #pragma GCC target ("custom-floatus=108") #pragma GCC target ("custom-ftruncds=109") +#pragma GCC target ("custom-round=110") + typedef struct data { double fextsd; @@ -37,6 +40,7 @@ typedef struct data { double floatud; float floatus; float ftruncds; + int round; } data_t; void @@ -52,6 +56,7 @@ custom_fp (int i, unsigned u, float f, d out->floatud = (double) u; out->floatus = (float) u; out->ftruncds = (float) d; + out->round = lroundf (f); } /* { dg-final { scan-assembler "custom\\t100, .* # fextsd .*" } } */ @@ -64,3 +69,4 @@ custom_fp (int i, unsigned u, float f, d /* { dg-final { scan-assembler "custom\\t107, .* # floatud .*" } } */ /* { dg-final { scan-assembler "custom\\t108, .* # floatus .*" } } */ /* { dg-final { scan-assembler "custom\\t109, .* # ftruncds .*" } } */ +/* { dg-final { scan-assembler "custom\\t110, .* # round .*" } } */