i386.md (expsf2, [...]): New patterns to implement exp, expf and expl built-ins as inline x87 intrinsics.
* config/i386/i386.md (expsf2, expdf2, expxf2): New patterns to implement exp, expf and expl built-ins as inline x87 intrinsics. (UNSPEC_FSCALE, UNSPEC_FRNDINT, UNSPEC_F2XM1): New unspecs to represent x87's fscale, frndint and f2xm1 insns respectively. (*fscale_sfxf3, *fscale_dfxf3, *fscale_xf3): New insn patterns to encode x87's "fscale" instruction followed by a pop. (*frndintxf2): New insn pattern for "frndint". (*f2xm1xf2): New insn pattern for "f2xm1". * reg-stack.c (subst_stack_regs_pat): Handle UNSPEC_FRNDINT and UNSPEC_F2XM1 like UNSPEC_{SIN,COS} and handle UNSPEC_FSCALE like UNSPEC_FPATAN. * gcc.dg/builtins-22.c: New test case. * gcc.dg/i386-387-1.c: Update to test exp. * gcc.dg/i386-387-2.c: Likewise. From-SVN: r67973
This commit is contained in:
parent
84fb201905
commit
9d5b9daeb9
7 changed files with 171 additions and 1 deletions
|
@ -1,3 +1,18 @@
|
|||
2003-06-15 Roger Sayle <roger@eyesopen.com>
|
||||
|
||||
* config/i386/i386.md (expsf2, expdf2, expxf2): New patterns to
|
||||
implement exp, expf and expl built-ins as inline x87 intrinsics.
|
||||
(UNSPEC_FSCALE, UNSPEC_FRNDINT, UNSPEC_F2XM1): New unspecs to
|
||||
represent x87's fscale, frndint and f2xm1 insns respectively.
|
||||
(*fscale_sfxf3, *fscale_dfxf3, *fscale_xf3): New insn patterns
|
||||
to encode x87's "fscale" instruction followed by a pop.
|
||||
(*frndintxf2): New insn pattern for "frndint".
|
||||
(*f2xm1xf2): New insn pattern for "f2xm1".
|
||||
|
||||
* reg-stack.c (subst_stack_regs_pat): Handle UNSPEC_FRNDINT and
|
||||
UNSPEC_F2XM1 like UNSPEC_{SIN,COS} and handle UNSPEC_FSCALE like
|
||||
UNSPEC_FPATAN.
|
||||
|
||||
2003-06-15 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
|
||||
|
||||
* Makefile.in (stagefeedback-start): Use $(SUBDIRS) instead of
|
||||
|
|
|
@ -113,9 +113,12 @@
|
|||
; x87 Floating point
|
||||
(UNSPEC_FPATAN 65)
|
||||
(UNSPEC_FYL2X 66)
|
||||
(UNSPEC_FSCALE 67)
|
||||
(UNSPEC_FRNDINT 68)
|
||||
(UNSPEC_F2XM1 69)
|
||||
|
||||
; REP instruction
|
||||
(UNSPEC_REP 67)
|
||||
(UNSPEC_REP 75)
|
||||
])
|
||||
|
||||
(define_constants
|
||||
|
@ -15725,6 +15728,133 @@
|
|||
temp = standard_80387_constant_rtx (4); /* fldln2 */
|
||||
emit_move_insn (operands[2], temp);
|
||||
})
|
||||
|
||||
(define_insn "*fscale_sfxf3"
|
||||
[(parallel [(set (match_operand:SF 0 "register_operand" "=f")
|
||||
(unspec:SF [(match_operand:XF 2 "register_operand" "0")
|
||||
(match_operand:XF 1 "register_operand" "u")]
|
||||
UNSPEC_FSCALE))
|
||||
(clobber (match_dup 1))])]
|
||||
"! TARGET_NO_FANCY_MATH_387 && TARGET_80387
|
||||
&& flag_unsafe_math_optimizations"
|
||||
"fscale\;fstp\t%y1"
|
||||
[(set_attr "type" "fpspc")
|
||||
(set_attr "mode" "SF")])
|
||||
|
||||
(define_insn "*fscale_dfxf3"
|
||||
[(parallel [(set (match_operand:DF 0 "register_operand" "=f")
|
||||
(unspec:DF [(match_operand:XF 2 "register_operand" "0")
|
||||
(match_operand:XF 1 "register_operand" "u")]
|
||||
UNSPEC_FSCALE))
|
||||
(clobber (match_dup 1))])]
|
||||
"! TARGET_NO_FANCY_MATH_387 && TARGET_80387
|
||||
&& flag_unsafe_math_optimizations"
|
||||
"fscale\;fstp\t%y1"
|
||||
[(set_attr "type" "fpspc")
|
||||
(set_attr "mode" "DF")])
|
||||
|
||||
(define_insn "*fscale_xf3"
|
||||
[(parallel [(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_FSCALE))
|
||||
(clobber (match_dup 1))])]
|
||||
"! TARGET_NO_FANCY_MATH_387 && TARGET_80387
|
||||
&& flag_unsafe_math_optimizations"
|
||||
"fscale\;fstp\t%y1"
|
||||
[(set_attr "type" "fpspc")
|
||||
(set_attr "mode" "XF")])
|
||||
|
||||
(define_insn "*frndintxf2"
|
||||
[(set (match_operand:XF 0 "register_operand" "=f")
|
||||
(unspec:XF [(match_operand:XF 1 "register_operand" "0")]
|
||||
UNSPEC_FRNDINT))]
|
||||
"! TARGET_NO_FANCY_MATH_387 && TARGET_80387
|
||||
&& flag_unsafe_math_optimizations"
|
||||
"frndint"
|
||||
[(set_attr "type" "fpspc")
|
||||
(set_attr "mode" "XF")])
|
||||
|
||||
(define_insn "*f2xm1xf2"
|
||||
[(set (match_operand:XF 0 "register_operand" "=f")
|
||||
(unspec:XF [(match_operand:XF 1 "register_operand" "0")]
|
||||
UNSPEC_F2XM1))]
|
||||
"! TARGET_NO_FANCY_MATH_387 && TARGET_80387
|
||||
&& flag_unsafe_math_optimizations"
|
||||
"f2xm1"
|
||||
[(set_attr "type" "fpspc")
|
||||
(set_attr "mode" "XF")])
|
||||
|
||||
(define_expand "expsf2"
|
||||
[(set (match_dup 2)
|
||||
(float_extend:XF (match_operand:SF 1 "register_operand" "")))
|
||||
(set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
|
||||
(set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
|
||||
(set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
|
||||
(set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
|
||||
(set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
|
||||
(parallel [(set (match_operand:SF 0 "register_operand" "")
|
||||
(unspec:SF [(match_dup 9) (match_dup 5)] UNSPEC_FSCALE))
|
||||
(clobber (match_dup 5))])]
|
||||
"! TARGET_NO_FANCY_MATH_387 && TARGET_80387
|
||||
&& flag_unsafe_math_optimizations"
|
||||
{
|
||||
rtx temp;
|
||||
int i;
|
||||
|
||||
for (i=2; i<10; i++)
|
||||
operands[i] = gen_reg_rtx (XFmode);
|
||||
temp = standard_80387_constant_rtx (5); /* fldl2e */
|
||||
emit_move_insn (operands[3], temp);
|
||||
emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
|
||||
})
|
||||
|
||||
(define_expand "expdf2"
|
||||
[(set (match_dup 2)
|
||||
(float_extend:XF (match_operand:DF 1 "register_operand" "")))
|
||||
(set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
|
||||
(set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
|
||||
(set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
|
||||
(set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
|
||||
(set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
|
||||
(parallel [(set (match_operand:DF 0 "register_operand" "")
|
||||
(unspec:DF [(match_dup 9) (match_dup 5)] UNSPEC_FSCALE))
|
||||
(clobber (match_dup 5))])]
|
||||
"! TARGET_NO_FANCY_MATH_387 && TARGET_80387
|
||||
&& flag_unsafe_math_optimizations"
|
||||
{
|
||||
rtx temp;
|
||||
int i;
|
||||
|
||||
for (i=2; i<10; i++)
|
||||
operands[i] = gen_reg_rtx (XFmode);
|
||||
temp = standard_80387_constant_rtx (5); /* fldl2e */
|
||||
emit_move_insn (operands[3], temp);
|
||||
emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
|
||||
})
|
||||
|
||||
(define_expand "expxf2"
|
||||
[(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
|
||||
(match_dup 2)))
|
||||
(set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
|
||||
(set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
|
||||
(set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
|
||||
(set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
|
||||
(parallel [(set (match_operand:XF 0 "register_operand" "")
|
||||
(unspec:XF [(match_dup 8) (match_dup 4)] UNSPEC_FSCALE))
|
||||
(clobber (match_dup 4))])]
|
||||
"! TARGET_NO_FANCY_MATH_387 && TARGET_80387
|
||||
&& flag_unsafe_math_optimizations"
|
||||
{
|
||||
rtx temp;
|
||||
int i;
|
||||
|
||||
for (i=2; i<9; i++)
|
||||
operands[i] = gen_reg_rtx (XFmode);
|
||||
temp = standard_80387_constant_rtx (5); /* fldl2e */
|
||||
emit_move_insn (operands[2], temp);
|
||||
emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
|
||||
})
|
||||
|
||||
;; Block operation instructions
|
||||
|
||||
|
|
|
@ -1711,6 +1711,8 @@ subst_stack_regs_pat (insn, regstack, pat)
|
|||
{
|
||||
case UNSPEC_SIN:
|
||||
case UNSPEC_COS:
|
||||
case UNSPEC_FRNDINT:
|
||||
case UNSPEC_F2XM1:
|
||||
/* These insns only operate on the top of the stack. */
|
||||
|
||||
src1 = get_true_reg (&XVECEXP (pat_src, 0, 0));
|
||||
|
@ -1734,6 +1736,7 @@ subst_stack_regs_pat (insn, regstack, pat)
|
|||
|
||||
case UNSPEC_FPATAN:
|
||||
case UNSPEC_FYL2X:
|
||||
case UNSPEC_FSCALE:
|
||||
/* These insns operate on the top two stack slots. */
|
||||
|
||||
src1 = get_true_reg (&XVECEXP (pat_src, 0, 0));
|
||||
|
|
|
@ -1,3 +1,9 @@
|
|||
2003-06-15 Roger Sayle <roger@eyesopen.com>
|
||||
|
||||
* gcc.dg/builtins-22.c: New test case.
|
||||
* gcc.dg/i386-387-1.c: Update to test exp.
|
||||
* gcc.dg/i386-387-2.c: Likewise.
|
||||
|
||||
2003-06-13 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
|
||||
|
||||
* gcc.dg/format/asm_fprintf-1.c: Update width/precision checks.
|
||||
|
|
12
gcc/testsuite/gcc.dg/builtins-22.c
Normal file
12
gcc/testsuite/gcc.dg/builtins-22.c
Normal file
|
@ -0,0 +1,12 @@
|
|||
/* Related to PR optimization/10764 */
|
||||
|
||||
/* { dg-do compile } */
|
||||
/* { dg-options "-O2 -ffast-math" } */
|
||||
|
||||
double exp(double x);
|
||||
|
||||
double foo(double x)
|
||||
{
|
||||
return exp(exp(x));
|
||||
}
|
||||
|
|
@ -6,9 +6,11 @@
|
|||
/* { dg-final { scan-assembler "call\t_?sqrt" } } */
|
||||
/* { dg-final { scan-assembler "call\t_?atan2" } } */
|
||||
/* { dg-final { scan-assembler "call\t_?log" } } */
|
||||
/* { dg-final { scan-assembler "call\t_?exp" } } */
|
||||
|
||||
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); }
|
||||
double f5(double x) { return __builtin_log(x); }
|
||||
double f6(double x) { return __builtin_exp(x); }
|
||||
|
|
|
@ -6,9 +6,11 @@
|
|||
/* { dg-final { scan-assembler "fsqrt" } } */
|
||||
/* { dg-final { scan-assembler "fpatan" } } */
|
||||
/* { dg-final { scan-assembler "fyl2x" } } */
|
||||
/* { dg-final { scan-assembler "f2xm1" } } */
|
||||
|
||||
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); }
|
||||
double f5(double x) { return __builtin_log(x); }
|
||||
double f6(double x) { return __builtin_exp(x); }
|
||||
|
|
Loading…
Add table
Reference in a new issue