This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: GCC floating point usage


On Mon, Oct 14, 2002 at 12:37:14PM -0400, David Edelsohn wrote:
> >>>>> Stefan Bylund writes:
> 
> Stefan> Is it possible to somehow instruct GCC to only generate
> Stefan> floating point instructions for C/C++ float/double
> Stefan> operations and not for internal non-floating point
> Stefan> optimizations etc?
> 
> 	If you do not want to use the FPU, then invoke the compiler with
> the -msoft-float PowerPC option.  If the FPRs are present and it is
> efficient to use them, the compiler will use them.

Come now, what he wants is not unreasonable.  "If floating point
operations appeared in the source code, generate hardware floating
point instructions; otherwise, generate only integer-unit
instructions."  I (that is, CodeSourcery) have a customer that needs
precisely this; in fact I posted a patch to implement it for PPC last
fall.  Now seems like a reasonable time to bring the issue back up.

My old patch, against the 3.2 branch, is appended to this message.  It
is not quite suitable for inclusion in its present form - for one
thing, the default is off, which makes sense for the customer I did
the patch for, but not for most users of the RS6000/PPC back end.
Also, it needs checking that it still fits on the mainline.

I recall that this patch was shot down when originally submitted, on
the grounds that the fix should instead modify exp*.c to avoid
generating DImode moves in the first place.  I do not buy this
argument.  It seems to me that exp*.c is correct in believing the
machine description's assertion that it has the ability to do DImode
moves.  The correct fix is therefore to change the machine description
so that it does not make that assertion when inappropriate.  Also,
this patch can be counted on to suppress all DImode floating-point
load/store instructions, whatever part of the compiler might have
generated them; changing exp*.c would not provide any guarantee that
some other pass would not decide to do the same thing.

I am not aware of any other optimization performed by GCC on the
RS6000 that causes floating-point instructions to be executed when the
user wrote purely integer code.  (The floating-point instructions in
the prologue to a varargs function are not executed unless floating
point actual arguments are passed to that function.)

zw

--- config/rs6000/rs6000.h	2002-08-29 18:44:28 -0700
+++ config/rs6000/rs6000.h	2002-10-01 18:27:53 -0700
@@ -222,7 +222,11 @@
 #define MASK_AIX_STRUCT_RET	0x00100000
 #define MASK_AIX_STRUCT_RET_SET	0x00200000
 
-/* The only remaining free bit is 0x00400000. sysv4.h uses
+/* Permit the use of floating point registers for DImode temporaries.
+   Only makes sense in 32-bit mode.  */
+#define MASK_IMPLICIT_FP	0x00400000
+
+/* There are no remaining free bits.  sysv4.h uses
    0x00800000 -> 0x40000000, and 0x80000000 is not available
    because target_flags is signed.  */
 
@@ -246,6 +250,7 @@
 #define TARGET_SCHED_PROLOG	(target_flags & MASK_SCHED_PROLOG)
 #define TARGET_ALTIVEC		(target_flags & MASK_ALTIVEC)
 #define TARGET_AIX_STRUCT_RET	(target_flags & MASK_AIX_STRUCT_RET)
+#define TARGET_IMPLICIT_FP	(target_flags & MASK_IMPLICIT_FP)
 
 #define TARGET_32BIT		(! TARGET_64BIT)
 #define TARGET_HARD_FLOAT	(! TARGET_SOFT_FLOAT)
@@ -370,6 +375,10 @@
 			""},\
   {"no-svr4-struct-return", MASK_AIX_STRUCT_RET | MASK_AIX_STRUCT_RET_SET,\
 			""},\
+  {"implicit-fp",	MASK_IMPLICIT_FP,\
+			N_("Use floating point registers to optimize integer code")},\
+  {"no-implicit-fp",	- MASK_IMPLICIT_FP,\
+			N_("Don't use floating point registers to optimize integer code")},\
   SUBTARGET_SWITCHES							\
   {"",			TARGET_DEFAULT | MASK_SCHED_PROLOG,		\
 			""}}
--- config/rs6000/rs6000.md	2002-09-27 15:51:05 -0700
+++ config/rs6000/rs6000.md	2002-10-01 18:27:57 -0700
@@ -8353,9 +8353,30 @@
   ""
   "{ rs6000_emit_move (operands[0], operands[1], DImode); DONE; }")
 
+;; This movdi pattern handles only DImode floating-point load and
+;; store.  It is used exclusively for optimization, when we are
+;; allowed to use floating point registers for DImode temporaries
+;; (controlled by -m(no-)implicit-fp).
+(define_insn "*movdi_internal32_fpu"
+  [(set (match_operand:DI 0 "nonimmediate_operand" "=f,f,m")
+	(match_operand:DI 1 "input_operand"        "f,m,f"))]
+  "! TARGET_POWERPC64 && TARGET_IMPLICIT_FP
+   && (gpc_reg_operand (operands[0], DImode)
+       || gpc_reg_operand (operands[1], DImode))"
+  "@
+   fmr %0,%1
+   lfd%U1%X1 %0,%1
+   stfd%U0%X0 %1,%0"
+  [(set_attr "type" "fp,fpload,fpstore")
+   (set_attr "length" "*,*,*")])
+
+;; This is the general movdi for 32-bit processors.  It will accept
+;; moves to floating point registers, but only if forced by other
+;; instructions' constraints (for instance, because the fixdfdi
+;; pattern leaves its output in an FPR).
 (define_insn "*movdi_internal32"
-  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,m,f,f,m,r,r,r,r,r")
-	(match_operand:DI 1 "input_operand" "r,m,r,f,m,f,IJK,n,G,H,F"))]
+  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,m,*f,*f,m,r,r,r,r,r")
+	(match_operand:DI 1 "input_operand" "r,m,r,*f,m,*f,IJK,n,G,H,F"))]
   "! TARGET_POWERPC64
    && (gpc_reg_operand (operands[0], DImode)
        || gpc_reg_operand (operands[1], DImode))"


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]