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
This commit is contained in:
Roger Sayle 2003-02-13 03:09:45 +00:00 committed by Roger Sayle
parent c4ebd83df2
commit 1fb54135be
6 changed files with 133 additions and 2 deletions

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

View File

@ -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

View 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. */

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

View 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); }

View 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); }