OSDN Git Service

* config/i386/i386.md (UNSPEC_FPATAN): New UNSPEC constant.
authorsayle <sayle@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 13 Feb 2003 03:09:45 +0000 (03:09 +0000)
committersayle <sayle@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 13 Feb 2003 03:09:45 +0000 (03:09 +0000)
(atan2sf3, atan2df3, atan2xf3, atan2tf3): New patterns.

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

* gcc.dg/i386-387-1.c: Add new test for __builtin_atan2.
* gcc.dg/i386-387-2.c: Likewise.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@62816 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/config/i386/i386.md
gcc/reg-stack.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/i386-387-1.c
gcc/testsuite/gcc.dg/i386-387-2.c

index 0623ea4..f8edc1b 100644 (file)
@@ -1,3 +1,11 @@
+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").
+
 2003-02-12  Mike Stump  <mrs@apple.com>
 
        * varray.c (element_size): Remove.
index 9a7173b..34905f8 100644 (file)
    (UNSPEC_MFENCE              59)
    (UNSPEC_LFENCE              60)
    (UNSPEC_PSADBW              61)
+
+   ; x87 Floating point
+   (UNSPEC_FPATAN              65)
   ])
 
 (define_constants
   "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")])
 \f
 ;; Block operation instructions
 
index 20cfb46..965aad0 100644 (file)
@@ -1,6 +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.
+   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+   2000, 2001, 2002, 2003 Free Software Foundation, Inc.
 
    This file is part of GCC.
 
@@ -1726,6 +1726,73 @@ subst_stack_regs_pat (insn, regstack, pat)
                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:
                /* (unspec [(unspec [(compare)] UNSPEC_FNSTSW)] UNSPEC_SAHF)
                   The combination matches the PPRO fcomi instruction.  */
index d43d01e..305827b 100644 (file)
@@ -1,3 +1,8 @@
+2003-02-12  Roger Sayle  <roger@eyesopen.com>
+
+       * gcc.dg/i386-387-1.c: Add new test for __builtin_atan2.
+       * gcc.dg/i386-387-2.c: Likewise.
+
 2003-02-12  Aldy Hernandez  <aldyh@redhat.com>
 
         * gcc.dg/ppc-spe.c: Fix formatting.
index 8fa4cba..f28fd8b 100644 (file)
@@ -4,7 +4,9 @@
 /* { dg-final { scan-assembler "call\t_?sin" } } */
 /* { dg-final { scan-assembler "call\t_?cos" } } */
 /* { dg-final { scan-assembler "call\t_?sqrt" } } */
+/* { dg-final { scan-assembler "call\t_?atan2" } } */
 
 double f1(double x) { return __builtin_sin(x); }
 double f2(double x) { return __builtin_cos(x); }
 double f3(double x) { return __builtin_sqrt(x); }
+double f4(double x, double y) { return __builtin_atan2(x,y); }
index 2456ca0..c73cb92 100644 (file)
@@ -4,7 +4,9 @@
 /* { dg-final { scan-assembler "fsin" } } */
 /* { dg-final { scan-assembler "fcos" } } */
 /* { dg-final { scan-assembler "fsqrt" } } */
+/* { dg-final { scan-assembler "fpatan" } } */
 
 double f1(double x) { return __builtin_sin(x); }
 double f2(double x) { return __builtin_cos(x); }
 double f3(double x) { return __builtin_sqrt(x); }
+double f4(double x, double y) { return __builtin_atan2(x,y); }