diff options
author | sayle <sayle@138bc75d-0d04-0410-961f-82ee72b054a4> | 2004-04-06 19:34:33 +0000 |
---|---|---|
committer | sayle <sayle@138bc75d-0d04-0410-961f-82ee72b054a4> | 2004-04-06 19:34:33 +0000 |
commit | 6b43bae461aeaac39182996987c5ceb7b929b155 (patch) | |
tree | 154509061a748c219394d85b40f993c80d2f7670 /gcc/reg-stack.c | |
parent | 1e3ce12de37206c6d08350524fb2876a9d191900 (diff) | |
download | gcc-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.c | 54 |
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. */ |