aboutsummaryrefslogtreecommitdiff
path: root/gcc/reg-stack.c
diff options
context:
space:
mode:
authorRoger Sayle <roger@eyesopen.com>2003-02-13 03:09:45 +0000
committerRoger Sayle <sayle@gcc.gnu.org>2003-02-13 03:09:45 +0000
commit1fb54135beca90d49d3acbe83219311752628852 (patch)
tree8f99b3141ffc1aa0b1386cc2ac0dbd502301b142 /gcc/reg-stack.c
parentc4ebd83df2c1b00b1f5e9c50ffa8da9cb350b4d9 (diff)
downloadgcc-1fb54135beca90d49d3acbe83219311752628852.zip
gcc-1fb54135beca90d49d3acbe83219311752628852.tar.gz
gcc-1fb54135beca90d49d3acbe83219311752628852.tar.bz2
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
Diffstat (limited to 'gcc/reg-stack.c')
-rw-r--r--gcc/reg-stack.c71
1 files changed, 69 insertions, 2 deletions
diff --git a/gcc/reg-stack.c b/gcc/reg-stack.c
index 20cfb46..965aad0 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. */