[PATCH] pow and atan2 builtin functions (part 3)

Roger Sayle roger@www.eyesopen.com
Thu Feb 13 03:28:00 GMT 2003


On Tue, 11 Feb 2003, Richard Henderson wrote:
> On Mon, Feb 10, 2003 at 08:07:21PM -0700, Roger Sayle wrote:
> > + 	      case UNSPEC_FLDLG2:
> > + 	      case UNSPEC_FLDLN2:
> > + 	      case UNSPEC_FLDL2E:
> > + 	      case UNSPEC_FLDL2T:
> > + 	      case UNSPEC_FLDPI:
>
> These I don't like.  I'd rather we matched the exact XFmode
> value in standard_80387_constant_p.  See also the note about
> these being slower than a load from memory on some targets.
>
> The rest of it's ok.


Many thanks.  I've commited the rest of this patch, without the hunk
above that adds support for 0-arity UNSPEC instructions, and without
the unused UNSPEC constants in i386.md (i.e. only adding UNSPEC_FPATAN).

I'll investigate the approach to mathematical constants you suggest,
modifying to standard_80387_constant_p to recognize the appropriate
XF mode values.  Using a table of REALs in i386.c, its possible to
ensure that define_expand patterns in i386.md use precisely the values
that'll get recognized by standard_80387_constant_p.

For reference, I've included the main patch as commited below.
Re-bootstrapped and regression tested following my usual protocol.

Many thanks once again.


2003-02-12  Roger Sayle  <roger@eyesopen.com>

	* config/i386/i386.md (UNSPEC_FPATAN): New UNSPEC constant.
	(atan2sf3, atan2df3, atan2xf3, atan2tf3): New patterns.

	* reg-stack.c (subst_stack_regs_pat): Add support for binary
	UNSPEC instructions (e.g. "fpatan").


Index: reg-stack.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/reg-stack.c,v
retrieving revision 1.120
diff -c -3 -p -r1.120 reg-stack.c
*** reg-stack.c	6 Jan 2003 20:02:56 -0000	1.120
--- reg-stack.c	12 Feb 2003 20:33:53 -0000
***************
*** 1,6 ****
  /* Register to Stack convert for GNU compiler.
!    Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998,
!    1999, 2000, 2001, 2002 Free Software Foundation, Inc.

     This file is part of GCC.

--- 1,6 ----
  /* Register to Stack convert for GNU compiler.
!    Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
!    2000, 2001, 2002, 2003 Free Software Foundation, Inc.

     This file is part of GCC.

*************** subst_stack_regs_pat (insn, regstack, pa
*** 1724,1729 ****
--- 1724,1796 ----
  		  }

  		replace_reg (src1, FIRST_STACK_REG);
+ 		break;
+
+ 	      case UNSPEC_FPATAN:
+ 		/* These insns operate on the top two stack slots.  */
+
+ 		src1 = get_true_reg (&XVECEXP (pat_src, 0, 0));
+ 		src2 = get_true_reg (&XVECEXP (pat_src, 0, 1));
+
+ 		src1_note = find_regno_note (insn, REG_DEAD, REGNO (*src1));
+ 		src2_note = find_regno_note (insn, REG_DEAD, REGNO (*src2));
+
+ 		{
+ 		  struct stack_def temp_stack;
+ 		  int regno, j, k, temp;
+
+  		  temp_stack = *regstack;
+
+ 		  /* Place operand 1 at the top of stack.  */
+ 		  regno = get_hard_regnum (&temp_stack, *src1);
+ 		  if (regno < 0)
+ 		    abort ();
+ 		  if (regno != FIRST_STACK_REG)
+ 		    {
+ 		      k = temp_stack.top - (regno - FIRST_STACK_REG);
+ 		      j = temp_stack.top;
+
+ 		      temp = temp_stack.reg[k];
+ 		      temp_stack.reg[k] = temp_stack.reg[j];
+ 		      temp_stack.reg[j] = temp;
+ 		    }
+
+ 		  /* Place operand 2 next on the stack.  */
+ 		  regno = get_hard_regnum (&temp_stack, *src2);
+ 		  if (regno < 0)
+ 		    abort ();
+ 		  if (regno != FIRST_STACK_REG + 1)
+ 		    {
+ 		      k = temp_stack.top - (regno - FIRST_STACK_REG);
+ 		      j = temp_stack.top - 1;
+
+ 		      temp = temp_stack.reg[k];
+ 		      temp_stack.reg[k] = temp_stack.reg[j];
+ 		      temp_stack.reg[j] = temp;
+ 		    }
+
+ 		  change_stack (insn, regstack, &temp_stack, EMIT_BEFORE);
+ 		}
+
+ 		replace_reg (src1, FIRST_STACK_REG);
+ 		replace_reg (src2, FIRST_STACK_REG + 1);
+
+ 		if (src1_note)
+ 		  replace_reg (&XEXP (src1_note, 0), FIRST_STACK_REG);
+ 		if (src2_note)
+ 		  replace_reg (&XEXP (src2_note, 0), FIRST_STACK_REG + 1);
+
+ 		/* Pop both input operands from the stack.  */
+ 		CLEAR_HARD_REG_BIT (regstack->reg_set,
+ 				    regstack->reg[regstack->top]);
+ 		CLEAR_HARD_REG_BIT (regstack->reg_set,
+ 				    regstack->reg[regstack->top - 1]);
+ 		regstack->top -= 2;
+
+ 		/* Push the result back onto the stack.  */
+ 		regstack->reg[++regstack->top] = REGNO (*dest);
+ 		SET_HARD_REG_BIT (regstack->reg_set, REGNO (*dest));
+ 		replace_reg (dest, FIRST_STACK_REG);
  		break;

  	      case UNSPEC_SAHF:
Index: config/i386/i386.md
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/i386/i386.md,v
retrieving revision 1.433
diff -c -3 -p -r1.433 i386.md
*** config/i386/i386.md	11 Feb 2003 19:44:46 -0000	1.433
--- config/i386/i386.md	12 Feb 2003 20:34:01 -0000
***************
*** 109,114 ****
--- 109,117 ----
     (UNSPEC_MFENCE		59)
     (UNSPEC_LFENCE		60)
     (UNSPEC_PSADBW		61)
+
+    ; x87 Floating point
+    (UNSPEC_FPATAN		65)
    ])

  (define_constants
***************
*** 15482,15487 ****
--- 15485,15534 ----
    "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
     && flag_unsafe_math_optimizations"
    "fcos"
+   [(set_attr "type" "fpspc")
+    (set_attr "mode" "XF")])
+
+ (define_insn "atan2df3"
+   [(set (match_operand:DF 0 "register_operand" "=f")
+ 	(unspec:DF [(match_operand:DF 2 "register_operand" "0")
+ 		    (match_operand:DF 1 "register_operand" "u")]
+ 	 UNSPEC_FPATAN))]
+   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
+    && flag_unsafe_math_optimizations"
+   "fpatan"
+   [(set_attr "type" "fpspc")
+    (set_attr "mode" "DF")])
+
+ (define_insn "atan2sf3"
+   [(set (match_operand:SF 0 "register_operand" "=f")
+ 	(unspec:SF [(match_operand:SF 2 "register_operand" "0")
+ 		    (match_operand:SF 1 "register_operand" "u")]
+ 	 UNSPEC_FPATAN))]
+   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
+    && flag_unsafe_math_optimizations"
+   "fpatan"
+   [(set_attr "type" "fpspc")
+    (set_attr "mode" "SF")])
+
+ (define_insn "atan2xf3"
+   [(set (match_operand:XF 0 "register_operand" "=f")
+ 	(unspec:XF [(match_operand:XF 2 "register_operand" "0")
+ 		    (match_operand:XF 1 "register_operand" "u")]
+ 	 UNSPEC_FPATAN))]
+   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
+    && flag_unsafe_math_optimizations"
+   "fpatan"
+   [(set_attr "type" "fpspc")
+    (set_attr "mode" "XF")])
+
+ (define_insn "atan2tf3"
+   [(set (match_operand:TF 0 "register_operand" "=f")
+ 	(unspec:TF [(match_operand:TF 2 "register_operand" "0")
+ 		    (match_operand:TF 1 "register_operand" "u")]
+ 	 UNSPEC_FPATAN))]
+   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
+    && flag_unsafe_math_optimizations"
+   "fpatan"
    [(set_attr "type" "fpspc")
     (set_attr "mode" "XF")])


Roger
--



More information about the Gcc-patches mailing list