public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [RFC PATCH, i386]: Option to select default 80387 precision control
@ 2007-04-02 10:25 Uros Bizjak
  2007-04-02 10:32 ` Richard Guenther
  0 siblings, 1 reply; 6+ messages in thread
From: Uros Bizjak @ 2007-04-02 10:25 UTC (permalink / raw)
  To: GCC Patches

[-- Attachment #1: Type: text/plain, Size: 1277 bytes --]

Hello!

This patch enables setting of default 80387 precision control at link
time. When executable is built, the gcc driver links correct object
file, and there the PC field of 80387 is set to selected precision
(similar to ifort's -pcX flag) when executable is started.

This patch speeds up iterative FP operations (division, sqrt...) when
80 bit precision is not needed.

Patch was bootstrapped on i686-pc-linux-gnu and manually checked via
debugger that really affects the computations. I have to bootstrap
this patch on x86_64 to check that everything is OK there, too. OK for
mainline, if it passes?

2007-04-02  Uros Bizjak  <ubizjak@gmail.com>

	* config.gcc (i[34567]86-*-linux*): Add i386/t-crtpc to tm-file.
	(x86_64-*-linux*): Ditto.

	* config/i386/i386.opt (mpc): New option.
	* config/i386/i386.c (overrride_options): Handle
	ix87_precision_string.

        * config/i386/crtprec.c: New file.
	* config/i386/t-crtpc: Ditto.

	* config/i386/linux.h (ENDFILE_SPEC): Add handling of -mpcN options.
	* config/i386/linux64.h (ENDFILE_SPEC): Ditto.

	* config/i386/t-linux64 (EXTRA_MULTILIB_PARTS): Add
	crtprec32.o, crtprec64.o and crtprec80.o.

libgcc/ChangeLog:

	* config.host (i[34567]86-*-linux*): Add i386/t-crtpc to tm-file.
	(x86_64-*-linux*): Ditto.

Uros.

[-- Attachment #2: i386-prec.diff --]
[-- Type: application/octet-stream, Size: 9583 bytes --]

Index: libgcc/config.host
===================================================================
--- libgcc/config.host	(revision 123415)
+++ libgcc/config.host	(working copy)
@@ -328,12 +328,12 @@
 i[34567]86-*-coff*)
 	;;
 i[34567]86-*-linux* | i[34567]86-*-kfreebsd*-gnu | i[34567]86-*-knetbsd*-gnu)
-	extra_parts="$extra_parts crtfastmath.o"
-	tmake_file="${tmake_file} i386/t-crtfm"
+	extra_parts="$extra_parts crtprec32.o crtprec64.o crtprec80.o crtfastmath.o"
+	tmake_file="${tmake_file} i386/t-crtpc i386/t-crtfm"
 	;;
 x86_64-*-linux* | x86_64-*-kfreebsd*-gnu | x86_64-*-knetbsd*-gnu)
-	extra_parts="$extra_parts crtfastmath.o"
-	tmake_file="${tmake_file} i386/t-crtfm"
+	extra_parts="$extra_parts crtprec32.o crtprec64.o crtprec80.o crtfastmath.o"
+	tmake_file="${tmake_file} i386/t-crtpc i386/t-crtfm"
 	;;
 i[34567]86-*-gnu*)
 	;;
Index: libgcc/config/i386/t-crtpc
===================================================================
--- libgcc/config/i386/t-crtpc	(revision 0)
+++ libgcc/config/i386/t-crtpc	(revision 0)
@@ -0,0 +1,8 @@
+crtprec32.o: $(gcc_srcdir)/config/i386/crtprec.c
+	$(gcc_compile) -D__PREC=32 -c $<
+
+crtprec64.o: $(gcc_srcdir)/config/i386/crtprec.c
+	$(gcc_compile) -D__PREC=64 -c $<
+
+crtprec80.o: $(gcc_srcdir)/config/i386/crtprec.c
+	$(gcc_compile) -D__PREC=80 -c $<
Index: gcc/doc/invoke.texi
===================================================================
--- gcc/doc/invoke.texi	(revision 123415)
+++ gcc/doc/invoke.texi	(working copy)
@@ -548,7 +548,7 @@
 -mthreads  -mno-align-stringops  -minline-all-stringops @gol
 -mpush-args  -maccumulate-outgoing-args  -m128bit-long-double @gol
 -m96bit-long-double  -mregparm=@var{num}  -msseregparm @gol
--mstackrealign @gol
+-mpc32 -mpc64 -mpc80 mstackrealign @gol
 -momit-leaf-frame-pointer  -mno-red-zone -mno-tls-direct-seg-refs @gol
 -mcmodel=@var{code-model} @gol
 -m32  -m64 -mlarge-data-threshold=@var{num}}
@@ -10018,6 +10018,21 @@
 modules with the same value, including any libraries.  This includes
 the system libraries and startup modules.
 
+@item -mpc32
+@opindex mpc32
+Set 80387 floating-point precision to 32 bits. This option rounds the
+significand to 24 bits (single precision).
+
+@item -mpc64
+@opindex mpc64
+Set 80387 floating-point precision to 64 bits. This option rounds the
+significand to 53 bits (double precision).
+
+@item -mpc80
+@opindex mpc80
+Set 80387 floating-point precision to 80 bits. This option rounds the
+significand to 64 bits (extended double precision).
+
 @item -mstackrealign
 @opindex mstackrealign
 Realign the stack at entry.  On the Intel x86, the
Index: gcc/config.gcc
===================================================================
--- gcc/config.gcc	(revision 123415)
+++ gcc/config.gcc	(working copy)
@@ -1147,7 +1147,7 @@
 	i[34567]86-*-knetbsd*-gnu) tm_file="${tm_file} i386/linux.h knetbsd-gnu.h i386/knetbsd-gnu.h" ;;
 	i[34567]86-*-kfreebsd*-gnu) tm_file="${tm_file} i386/linux.h kfreebsd-gnu.h i386/kfreebsd-gnu.h" ;;
 	esac
-	tmake_file="${tmake_file} i386/t-crtstuff i386/t-crtfm t-dfprules"
+	tmake_file="${tmake_file} i386/t-crtstuff i386/t-crtpc i386/t-crtfm t-dfprules"
 	;;
 x86_64-*-linux* | x86_64-*-kfreebsd*-gnu | x86_64-*-knetbsd*-gnu)
 	tm_file="${tm_file} i386/unix.h i386/att.h dbxelf.h elfos.h svr4.h linux.h \
@@ -1156,7 +1156,7 @@
 	x86_64-*-kfreebsd*-gnu) tm_file="${tm_file} kfreebsd-gnu.h" ;;
 	x86_64-*-knetbsd*-gnu) tm_file="${tm_file} knetbsd-gnu.h" ;;
 	esac
-	tmake_file="${tmake_file} i386/t-linux64 i386/t-crtfm t-dfprules"
+	tmake_file="${tmake_file} i386/t-linux64 i386/t-crtpc i386/t-crtfm t-dfprules"
 	;;
 i[34567]86-*-gnu*)
 	;;
Index: gcc/config/i386/linux.h
===================================================================
--- gcc/config/i386/linux.h	(revision 123415)
+++ gcc/config/i386/linux.h	(working copy)
@@ -121,6 +121,9 @@
 #undef  ENDFILE_SPEC
 #define ENDFILE_SPEC \
   "%{ffast-math|funsafe-math-optimizations:crtfastmath.o%s} \
+   %{mpc32:crtprec32.o%s} \
+   %{mpc64:crtprec64.o%s} \
+   %{mpc80:crtprec80.o%s} \
    %{shared|pie:crtendS.o%s;:crtend.o%s} crtn.o%s"
 
 /* A C statement (sans semicolon) to output to the stdio stream
Index: gcc/config/i386/t-crtpc
===================================================================
--- gcc/config/i386/t-crtpc	(revision 0)
+++ gcc/config/i386/t-crtpc	(revision 0)
@@ -0,0 +1,16 @@
+EXTRA_PARTS += crtprec32.o crtprec64.o crtprec80.o
+
+$(T)crtprec32.o: $(srcdir)/config/i386/crtprec.c $(GCC_PASSES)
+	$(GCC_FOR_TARGET) $(LIBGCC2_CFLAGS) -D__PREC=32 -c \
+		$(srcdir)/config/i386/crtprec.c \
+		-o $(T)crtprec32$(objext)
+
+$(T)crtprec64.o: $(srcdir)/config/i386/crtprec.c $(GCC_PASSES)
+	$(GCC_FOR_TARGET) $(LIBGCC2_CFLAGS) -D__PREC=64 -c \
+		$(srcdir)/config/i386/crtprec.c \
+		-o $(T)crtprec64$(objext)
+
+$(T)crtprec80.o: $(srcdir)/config/i386/crtprec.c $(GCC_PASSES)
+	$(GCC_FOR_TARGET) $(LIBGCC2_CFLAGS) -D__PREC=80 -c \
+		$(srcdir)/config/i386/crtprec.c \
+		-o $(T)crtprec80$(objext)
Index: gcc/config/i386/crtprec.c
===================================================================
--- gcc/config/i386/crtprec.c	(revision 0)
+++ gcc/config/i386/crtprec.c	(revision 0)
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2007 Free Software Foundation, Inc.
+ *
+ * This file is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ * 
+ * In addition to the permissions in the GNU General Public License, the
+ * Free Software Foundation gives you unlimited permission to link the
+ * compiled version of this file with other programs, and to distribute
+ * those programs without any restriction coming from the use of this
+ * file.  (The General Public License restrictions do apply in other
+ * respects; for example, they cover modification of the file, and
+ * distribution when not linked into another program.)
+ * 
+ * This file is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING.  If not, write to
+ * the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ * 
+ *    As a special exception, if you link this library with files
+ *    compiled with GCC to produce an executable, this does not cause
+ *    the resulting executable to be covered by the GNU General Public License.
+ *    This exception does not however invalidate any other reasons why
+ *    the executable file might be covered by the GNU General Public License.
+ */
+
+#if __PREC == 32
+ #define X87CW		(0 << 8)	/* Single precision (24 bits) */
+#elif __PREC == 64
+ #define X87CW		(2 << 8)	/* Double precision (53 bits) */
+#elif __PREC == 80
+ #define X87CW		(3 << 8)	/* Extended precision (64 bits) */
+#else
+ #error "Wrong precision requested."
+#endif
+
+#define X87CW_PCMASK	(3 << 8)
+
+static void __attribute__((constructor))
+set_precision (void)
+{
+  unsigned short int cwd;
+
+  asm volatile ("fstcw\t%0" : "=m" (cwd));
+
+  cwd &= ~X87CW_PCMASK;
+  cwd |= X87CW;
+
+  asm volatile ("fldcw\t%0" : : "m" (cwd));
+}
Index: gcc/config/i386/i386.opt
===================================================================
--- gcc/config/i386/i386.opt	(revision 123415)
+++ gcc/config/i386/i386.opt	(working copy)
@@ -103,6 +103,10 @@
 Target Report Mask(FLOAT_RETURNS)
 Return values of functions in FPU registers
 
+mpc
+Target RejectNegative Report Joined Var(ix87_precision_string)
+Enables control of 80387 floating-point significand precision
+
 mfpmath=
 Target RejectNegative Joined Var(ix86_fpmath_string)
 Generate floating point mathematics using given instruction set
Index: gcc/config/i386/linux64.h
===================================================================
--- gcc/config/i386/linux64.h	(revision 123415)
+++ gcc/config/i386/linux64.h	(working copy)
@@ -78,6 +78,9 @@
 #undef  ENDFILE_SPEC
 #define ENDFILE_SPEC \
   "%{ffast-math|funsafe-math-optimizations:crtfastmath.o%s} \
+   %{mpc32:crtprec32.o%s} \
+   %{mpc64:crtprec64.o%s} \
+   %{mpc80:crtprec80.o%s} \
    %{shared|pie:crtendS.o%s;:crtend.o%s} crtn.o%s"
 
 #if TARGET_64BIT_DEFAULT
Index: gcc/config/i386/t-linux64
===================================================================
--- gcc/config/i386/t-linux64	(revision 123415)
+++ gcc/config/i386/t-linux64	(working copy)
@@ -12,7 +12,8 @@
 INSTALL_LIBGCC = install-multilib
 
 EXTRA_MULTILIB_PARTS=crtbegin.o crtend.o crtbeginS.o crtendS.o \
-		     crtbeginT.o crtfastmath.o
+		     crtbeginT.o crtprec32.o crtprec64.o crtprec80.o \
+		     crtfastmath.o
 
 # The pushl in CTOR initialization interferes with frame pointer elimination.
 # crtend*.o cannot be compiled without -fno-asynchronous-unwind-tables,
Index: gcc/config/i386/i386.c
===================================================================
--- gcc/config/i386/i386.c	(revision 123415)
+++ gcc/config/i386/i386.c	(working copy)
@@ -2095,6 +2095,13 @@
 	       ix86_tls_dialect_string);
     }
 
+  if (ix87_precision_string)
+    {
+      i = atoi (ix87_precision_string);
+      if (i != 32 && i != 64 && i != 80)
+	error ("pc%d is not valid precision setting (32, 64 or 80)", i);
+    }
+
   /* Keep nonleaf frame pointers.  */
   if (flag_omit_frame_pointer)
     target_flags &= ~MASK_OMIT_LEAF_FRAME_POINTER;

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2007-04-03  9:56 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2007-04-02 10:25 [RFC PATCH, i386]: Option to select default 80387 precision control Uros Bizjak
2007-04-02 10:32 ` Richard Guenther
2007-04-03  7:44   ` [PATCH, " Uros Bizjak
2007-04-03  9:25     ` Dave Korn
2007-04-03  9:37     ` Jakub Jelinek
2007-04-03  9:56       ` Uros Bizjak

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).