nios2.md (UNSPEC_ROUND): New.
authorSandra Loosemore <sandra@codesourcery.com>
Wed, 23 Apr 2014 02:14:42 +0000 (22:14 -0400)
committerSandra Loosemore <sandra@gcc.gnu.org>
Wed, 23 Apr 2014 02:14:42 +0000 (22:14 -0400)
2014-04-22  Sandra Loosemore  <sandra@codesourcery.com>

gcc/
* config/nios2/nios2.md (UNSPEC_ROUND): New.
(lroundsfsi2): New.
* config/nios2/nios2.opt (mno-custom-round, mcustom-round=): New.
* config/nios2/nios2-opts.h (N2FPU_ALL_CODES): Add round.
* config/nios2/nios2.c (N2F_NO_ERRNO): Define.
(nios2_fpu_insn): Add entry for round.
(N2FPU_NO_ERRNO_P): Define.
(nios2_custom_check_insns): Add check for N2F_NO_ERRNO and
flag_errno_math.
* doc/invoke.texi (Nios II Options): Document -mcustom-round.

gcc/testsuite/
* gcc.target/nios2/custom-fp-conversion.c: Adjust to test that
lroundf generates custom round instruction, too.

From-SVN: r209670

gcc/ChangeLog
gcc/config/nios2/nios2-opts.h
gcc/config/nios2/nios2.c
gcc/config/nios2/nios2.md
gcc/config/nios2/nios2.opt
gcc/doc/invoke.texi
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/nios2/custom-fp-conversion.c

index 8f84b6a180c28751dbdd7aff599a5fa2360e0897..38d19bdf7147461038bfb8fb1e10aa661450208a 100644 (file)
@@ -1,3 +1,16 @@
+2014-04-22  Sandra Loosemore  <sandra@codesourcery.com>
+
+       * config/nios2/nios2.md (UNSPEC_ROUND): New.
+       (lroundsfsi2): New.
+       * config/nios2/nios2.opt (mno-custom-round, mcustom-round=): New.
+       * config/nios2/nios2-opts.h (N2FPU_ALL_CODES): Add round.
+       * config/nios2/nios2.c (N2F_NO_ERRNO): Define.
+       (nios2_fpu_insn): Add entry for round.
+       (N2FPU_NO_ERRNO_P): Define.
+       (nios2_custom_check_insns): Add check for N2F_NO_ERRNO and
+       flag_errno_math.
+       * doc/invoke.texi (Nios II Options): Document -mcustom-round.
+
 2014-04-22  Richard Henderson  <rth@redhat.com>
 
        * config/aarch64/aarch64 (addti3, subti3): New expanders.
index 95dbad14521e47019709164dc09b3a68ca868a73..c33f2e5a4e2d2c358e5bfd310293ef1e9687bc08 100644 (file)
@@ -42,7 +42,7 @@ along with GCC; see the file COPYING3.  If not see
                                                                        \
   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 cdd2e6bc98bfdeab20455f49e70d217dc1b70d4f..548a8d2747120f507468946c12eaee623d5d08d0 100644 (file)
@@ -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_insn[] =
     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_insn[] =
 #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 929d61e1f13b8614fb5f7e86cec34fdf5ced4105..e3a803c59b56d7c43a0bdf331cbdf5a83681cd7d 100644 (file)
@@ -70,6 +70,7 @@
   UNSPEC_FATAN
   UNSPEC_FEXP
   UNSPEC_FLOG
+  UNSPEC_ROUND
   UNSPEC_LOAD_GOT_REGISTER
   UNSPEC_PIC_SYM
   UNSPEC_PIC_CALL_SYM
   { return nios2_fpu_insn_asm (n2fpu_fix<f><i>); }
   [(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 4ca8e90b7796018cb7a0209f7cdcde32fa31df4e..95aac5c665b8883647a4e6de2ad565b2f5968f19 100644 (file)
@@ -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 8004da86f4f50b7126c28af30669b3055244121e..7d039098c4dffe232ab47d4ac28388908182bc30 100644 (file)
@@ -18485,6 +18485,12 @@ Conversion from double precision to single precision.
 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 9d0ef96d93a261b9caaba6676e650bbb8f0a1e2c..78b0e34592d850ee8ec92efd256f24ab01697650 100644 (file)
@@ -1,3 +1,8 @@
+2014-04-22  Sandra Loosemore  <sandra@codesourcery.com>
+
+       * gcc.target/nios2/custom-fp-conversion.c: Adjust to test that
+       lroundf generates custom round instruction, too.
+
 2014-04-22  Tobias Burnus  <burnus@net-b.de>
 
        PR fortran/60881
index 20b2159960e7d93f922c88b62c346acb3f02f88b..c110b1ad2f4dab7dec08c3c5478919abe9ec3010 100644 (file)
@@ -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 <stdio.h> 
 #include <math.h>
@@ -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, double d, data_t *out)
   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, double d, data_t *out)
 /* { 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 .*" } } */