summaryrefslogtreecommitdiff
path: root/gcc/reg-stack.c
diff options
context:
space:
mode:
authorsayle <sayle@138bc75d-0d04-0410-961f-82ee72b054a4>2004-04-06 19:34:33 +0000
committersayle <sayle@138bc75d-0d04-0410-961f-82ee72b054a4>2004-04-06 19:34:33 +0000
commit6b43bae461aeaac39182996987c5ceb7b929b155 (patch)
tree154509061a748c219394d85b40f993c80d2f7670 /gcc/reg-stack.c
parent1e3ce12de37206c6d08350524fb2876a9d191900 (diff)
downloadgcc-6b43bae461aeaac39182996987c5ceb7b929b155.tar.gz
2004-04-06 Uros Bizjak <uros@kss-loka.si>
* builtins.c: Implement support for sincos function. (expand_builtin_mathfn): Remove BUILT_IN_SIN{,F,L} and BUILT_IN_COS{,F,L}. (expand_builtin_mathfn_3): New function. (expand_builtin): Expand BUILT_IN_SIN{,F,L} and BUILT_IN_COS{,F,L} using expand_builtin_mathfn_3 if flag_unsafe_math_optimization is set. * optabs.h (enum optab_index): Add new OTI_sincos. (sincos_optab): Define corresponding macro. * optabs.c (init_optabs): Initialize sincos_optab. (expand_twoval_unop): New function. * genopinit.c (optabs): Implement sincos_optab using sincos?f3 patterns. * reg-stack.c (subst_stack_regs_pat): Handle UNSPEC_SINCOS_COS and UNSPEC_SINCOS_SIN. * config/i386/i386.md (sincosdf3, sincossf3, *sincosextendsfdf3, sincosxf3): New patterns to implement sincos, sincosf and sincosl built-ins as inline x87 intrinsics. Define splits for sindf2, sinsf2, *sinextendsfdf2, sinxf2, cosdf2, cossf2, *cosextendsfdf2 and cosxf2 patterns from corresponding sincos patterns. (sindf2, sinsf2, sinxf2): Rename to *sindf2, *sinsf2, *sinxf2. (cosdf2, cossf2, cosxf2): Rename to *cosdf2, *cossf2, *cosxf2. (UNSPEC_SINCOS_SIN, UNPEC_SINCOS_COS): New unspecs to represent x87's unspec insn. * gcc.dg/builtins-36.c: New test. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@80463 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/reg-stack.c')
-rw-r--r--gcc/reg-stack.c54
1 files changed, 54 insertions, 0 deletions
diff --git a/gcc/reg-stack.c b/gcc/reg-stack.c
index 31ebddb4640..f238267987a 100644
--- a/gcc/reg-stack.c
+++ b/gcc/reg-stack.c
@@ -1768,6 +1768,60 @@ subst_stack_regs_pat (rtx insn, stack regstack, rtx pat)
replace_reg (dest, FIRST_STACK_REG);
break;
+ case UNSPEC_SINCOS_COS:
+ /* These insns operate on the top two stack slots,
+ first part of one input, double output insn. */
+
+ src1 = get_true_reg (&XVECEXP (pat_src, 0, 0));
+
+ emit_swap_insn (insn, regstack, *src1);
+
+ src1_note = find_regno_note (insn, REG_DEAD, REGNO (*src1));
+
+ /* Push the result back onto stack. Empty stack slot
+ will be filled in second part of insn. */
+ if (STACK_REG_P (*dest)) {
+ regstack->reg[regstack->top + 1] = REGNO (*dest);
+ SET_HARD_REG_BIT (regstack->reg_set, REGNO (*dest));
+ replace_reg (dest, FIRST_STACK_REG);
+ }
+
+ if (src1_note)
+ {
+ replace_reg (&XEXP (src1_note, 0), FIRST_STACK_REG);
+ regstack->top--;
+ CLEAR_HARD_REG_BIT (regstack->reg_set, REGNO (*src1));
+ }
+ replace_reg (src1, FIRST_STACK_REG);
+ break;
+
+ case UNSPEC_SINCOS_SIN:
+ src1 = get_true_reg (&XVECEXP (pat_src, 0, 0));
+
+ emit_swap_insn (insn, regstack, *src1);
+
+ src1_note = find_regno_note (insn, REG_DEAD, REGNO (*src1));
+
+ /* Push the result back onto stack. Fill empty slot from
+ first part of insn and fix top of stack pointer. */
+ if (STACK_REG_P (*dest)) {
+ regstack->reg[regstack->top] = REGNO (*dest);
+ SET_HARD_REG_BIT (regstack->reg_set, REGNO (*dest));
+ replace_reg (dest, FIRST_STACK_REG + 1);
+
+ regstack->top++;
+ }
+
+ if (src1_note)
+ {
+ replace_reg (&XEXP (src1_note, 0), FIRST_STACK_REG);
+ regstack->top--;
+ CLEAR_HARD_REG_BIT (regstack->reg_set, REGNO (*src1));
+ }
+
+ replace_reg (src1, FIRST_STACK_REG);
+ break;
+
case UNSPEC_SAHF:
/* (unspec [(unspec [(compare)] UNSPEC_FNSTSW)] UNSPEC_SAHF)
The combination matches the PPRO fcomi instruction. */