From: Roger Sayle Date: Thu, 13 Feb 2003 03:09:45 +0000 (+0000) Subject: i386.md (UNSPEC_FPATAN): New UNSPEC constant. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=1fb54135beca90d49d3acbe83219311752628852;p=gcc.git i386.md (UNSPEC_FPATAN): New UNSPEC constant. * 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"). * gcc.dg/i386-387-1.c: Add new test for __builtin_atan2. * gcc.dg/i386-387-2.c: Likewise. From-SVN: r62816 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 0623ea4dacb..f8edc1b2a60 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2003-02-12 Roger Sayle + + * 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 * varray.c (element_size): Remove. diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index 9a7173bf703..34905f8ac61 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -109,6 +109,9 @@ (UNSPEC_MFENCE 59) (UNSPEC_LFENCE 60) (UNSPEC_PSADBW 61) + + ; x87 Floating point + (UNSPEC_FPATAN 65) ]) (define_constants @@ -15484,6 +15487,50 @@ "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")]) ;; Block operation instructions diff --git a/gcc/reg-stack.c b/gcc/reg-stack.c index 20cfb46ab17..965aad0b24d 100644 --- a/gcc/reg-stack.c +++ b/gcc/reg-stack.c @@ -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. */ diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index d43d01ec90d..305827bf37b 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2003-02-12 Roger Sayle + + * gcc.dg/i386-387-1.c: Add new test for __builtin_atan2. + * gcc.dg/i386-387-2.c: Likewise. + 2003-02-12 Aldy Hernandez * gcc.dg/ppc-spe.c: Fix formatting. diff --git a/gcc/testsuite/gcc.dg/i386-387-1.c b/gcc/testsuite/gcc.dg/i386-387-1.c index 8fa4cba64a4..f28fd8bbdcf 100644 --- a/gcc/testsuite/gcc.dg/i386-387-1.c +++ b/gcc/testsuite/gcc.dg/i386-387-1.c @@ -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); } diff --git a/gcc/testsuite/gcc.dg/i386-387-2.c b/gcc/testsuite/gcc.dg/i386-387-2.c index 2456ca0c934..c73cb92c5f3 100644 --- a/gcc/testsuite/gcc.dg/i386-387-2.c +++ b/gcc/testsuite/gcc.dg/i386-387-2.c @@ -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); }