public inbox for gcc@gcc.gnu.org
 help / color / mirror / Atom feed
* Patch to add missing PPC instruction
@ 2001-12-17 12:54 degger
  2001-12-17 13:11 ` David Edelsohn
  0 siblings, 1 reply; 3+ messages in thread
From: degger @ 2001-12-17 12:54 UTC (permalink / raw)
  To: gcc-patches; +Cc: gcc

[-- Attachment #1: Type: TEXT/plain, Size: 933 bytes --]

Hija,

the attached patch is supposed to add the the fres instruction
and necessary computation code to the rs6000 backend.

fres is a "floating point single precision reciprocal" mnemonic
which is available on at least the 7400 and 7410 (haven't heard
back from Dale which other CPUs have it, but they can be added later)
which is faster than a single precision divide and spares the storage
for the 1.0, a register and the necessary load instructions to get them
into memory.

This has boostrapped on powerpc-linux-gnu and passed the testsuite
without regressions.

--
Servus,
       Daniel

2001-12-17  Daniel Egger  <degger@fhm.edu>

	* config/rs6000/rs6000.md: Add missing fres mnemonic
	(floating point single precision reciprocal) to the 7400
	definition and emit it.

	* config/rs6000/rs6000.c (one_fp_constant): Add helper function
	to check for a float 1.0 constant...
	* config/rs6000/rs6000.h: ... and declare it here.



[-- Attachment #2: rs6000.diff --]
[-- Type: TEXT/plain, Size: 3090 bytes --]

Index: gcc/config/rs6000/rs6000.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/rs6000.c,v
retrieving revision 1.263
diff -u -r1.263 rs6000.c
--- rs6000.c	2001/12/17 16:25:12	1.263
+++ rs6000.c	2001/12/17 18:29:25
@@ -1167,6 +1167,15 @@
   return GET_MODE_CLASS (mode) == MODE_FLOAT && op == CONST0_RTX (mode);
 }
 
+/* Return 1 if the operand is 1.0.  */
+int
+one_fp_constant (op, mode)
+     rtx op;
+     enum machine_mode mode;
+{
+  return GET_MODE_CLASS (mode) == MODE_FLOAT && op == CONST1_RTX (mode);
+}
+
 /* Return 1 if the operand is in volatile memory.  Note that during
    the RTL generation phase, memory_operand does not return TRUE for
    volatile memory references.  So this function allows us to
Index: gcc/config/rs6000/rs6000.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/rs6000.h,v
retrieving revision 1.160
diff -u -r1.160 rs6000.h
--- rs6000.h	2001/12/17 15:05:38	1.160
+++ rs6000.h	2001/12/17 18:29:30
@@ -2804,6 +2804,7 @@
   {"got_no_const_operand", {SYMBOL_REF, LABEL_REF}},			   \
   {"easy_fp_constant", {CONST_DOUBLE}},					   \
   {"zero_fp_constant", {CONST_DOUBLE}},					   \
+  {"one_fp_constant", {CONST_DOUBLE}},					   \
   {"reg_or_mem_operand", {SUBREG, MEM, REG}},				   \
   {"lwa_operand", {SUBREG, MEM, REG}},					   \
   {"volatile_mem_operand", {MEM}},					   \
Index: gcc/config/rs6000/rs6000.md
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/rs6000.md,v
retrieving revision 1.147
diff -u -r1.147 rs6000.md
--- rs6000.md	2001/12/14 02:43:26	1.147
+++ rs6000.md	2001/12/17 18:29:38
@@ -37,7 +37,7 @@
 \f
 ;; Define an insn type attribute.  This is used in function unit delay
 ;; computations.
-(define_attr "type" "integer,load,store,fpload,fpstore,vecload,vecstore,imul,imul2,imul3,lmul,idiv,ldiv,branch,compare,cr_logical,delayed_compare,fpcompare,mtjmpr,fp,dmul,sdiv,ddiv,ssqrt,dsqrt,jmpreg,vecsimple,veccomplex,veccmp,vecperm,vecfloat,altivec"
+(define_attr "type" "integer,load,store,fpload,fpstore,vecload,vecstore,imul,imul2,imul3,lmul,idiv,ldiv,branch,compare,cr_logical,delayed_compare,fpcompare,mtjmpr,fp,dmul,srec,sdiv,ddiv,ssqrt,dsqrt,jmpreg,vecsimple,veccomplex,veccmp,vecperm,vecfloat,altivec"
   (const_string "integer"))
 
 ;; Length (in bytes).
@@ -653,6 +653,11 @@
   17 17)
 
 (define_function_unit "fpu" 1 0
+  (and (eq_attr "type" "srec")
+       (eq_attr "cpu" "ppc7400"))
+  10 10)
+
+(define_function_unit "fpu" 1 0
   (and (eq_attr "type" "sdiv")
        (eq_attr "cpu" "ppc7450"))
   21 21)
@@ -4914,6 +4919,14 @@
 		(match_operand:SF 2 "gpc_reg_operand" "")))]
   "TARGET_HARD_FLOAT"
   "")
+
+(define_insn ""
+  [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
+	(div:SF (match_operand:SF 1 "one_fp_constant" "F")
+		(match_operand:SF 2 "gpc_reg_operand" "f")))]
+  "TARGET_POWERPC && TARGET_HARD_FLOAT"
+  "fres %0,%2"
+  [(set_attr "type" "srec")])
 
 (define_insn ""
   [(set (match_operand:SF 0 "gpc_reg_operand" "=f")

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

* Re: Patch to add missing PPC instruction
  2001-12-17 12:54 Patch to add missing PPC instruction degger
@ 2001-12-17 13:11 ` David Edelsohn
  2001-12-17 13:31   ` degger
  0 siblings, 1 reply; 3+ messages in thread
From: David Edelsohn @ 2001-12-17 13:11 UTC (permalink / raw)
  To: degger; +Cc: gcc-patches, gcc

>>>>> degger  writes:

degger> the attached patch is supposed to add the the fres instruction
degger> and necessary computation code to the rs6000 backend.

degger> fres is a "floating point single precision reciprocal" mnemonic
degger> which is available on at least the 7400 and 7410 (haven't heard
degger> back from Dale which other CPUs have it, but they can be added later)
degger> which is faster than a single precision divide and spares the storage
degger> for the 1.0, a register and the necessary load instructions to get them
degger> into memory.

degger> This has boostrapped on powerpc-linux-gnu and passed the testsuite
degger> without regressions.

	fres is floating-point reciprocal ESTIMATE Single, not a
single-precision reciprocal.  It is accurate to one part in either 256 or
4096, not IEEE 754 Single Precision accuracy.  It is part of the PowerPC
optional instructions for graphics.

	The instruction is meant as an estimate starting point for a
Newton-Raphson approximation algorithm.  It does not do what you are
assuming and this patch is rejected.

David

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

* Re: Patch to add missing PPC instruction
  2001-12-17 13:11 ` David Edelsohn
@ 2001-12-17 13:31   ` degger
  0 siblings, 0 replies; 3+ messages in thread
From: degger @ 2001-12-17 13:31 UTC (permalink / raw)
  To: dje; +Cc: gcc-patches, gcc

On 17 Dec, David Edelsohn wrote:

> 	fres is floating-point reciprocal ESTIMATE Single, not a
> single-precision reciprocal.

Right, I got that wrong.

> It is accurate to one part in either 256 or 4096, 

According to the PPC Programming Environment manual page 8-88,
the error is less or equal to 1/256.

> not IEEE 754 Single Precision accuracy. 

A candidate for -ffast-math? I originally meant it that way but forgot
about it between the time I wrote the patch and sent it here 
(>4 months).

For some applications (those who are using single precision arithmetics)
it might actually be enough to such an unaccurate reciprocal but I
definitely see your point when you say it's not acceptable to be used in 
general.

--
Servus,
       Daniel

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

end of thread, other threads:[~2001-12-17 21:28 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2001-12-17 12:54 Patch to add missing PPC instruction degger
2001-12-17 13:11 ` David Edelsohn
2001-12-17 13:31   ` degger

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).