diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 0f63ac8b145..cfdc8610844 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,14 @@ +2003-05-11 Roger Sayle + + * config/i386/i386.md (logsf2, logdf2, logxf2, logdf2): New patterns + to implement log, logf and logl built-ins as inline x87 intrinsics. + (UNSPEC_FYL2X): New unspec to represent x87's "fyl2x" instruction. + (*fyl2x_sfxf3, *fyl2x_dfxf3, *fyl2x_xf3, *fyl2x_tfxf3): New insn + patterns for x87's "fyl2x" instruction, used by log?f2 patterns. + + * reg-stack.c (subst_stack_regs_pat): Handle UNSPEC_FYL2X like + UNSPEC_FPATAN, i.e. replaces two stack operands with single result. + 2003-05-11 Kaveh R. Ghazi * Makefile.in (out_object_file): Don't set -Wno-error for ${cpu}.o. diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index 64d37f60882..ad8909f939b 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -112,6 +112,7 @@ ; x87 Floating point (UNSPEC_FPATAN 65) + (UNSPEC_FYL2X 66) ]) (define_constants @@ -15522,6 +15523,106 @@ "fpatan" [(set_attr "type" "fpspc") (set_attr "mode" "XF")]) + +(define_insn "*fyl2x_sfxf3" + [(set (match_operand:SF 0 "register_operand" "=f") + (unspec:SF [(match_operand:SF 2 "register_operand" "0") + (match_operand:XF 1 "register_operand" "u")] + UNSPEC_FYL2X))] + "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 + && flag_unsafe_math_optimizations" + "fyl2x" + [(set_attr "type" "fpspc") + (set_attr "mode" "SF")]) + +(define_insn "*fyl2x_dfxf3" + [(set (match_operand:DF 0 "register_operand" "=f") + (unspec:DF [(match_operand:DF 2 "register_operand" "0") + (match_operand:XF 1 "register_operand" "u")] + UNSPEC_FYL2X))] + "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 + && flag_unsafe_math_optimizations" + "fyl2x" + [(set_attr "type" "fpspc") + (set_attr "mode" "DF")]) + +(define_insn "*fyl2x_xf3" + [(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_FYL2X))] + "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 + && flag_unsafe_math_optimizations" + "fyl2x" + [(set_attr "type" "fpspc") + (set_attr "mode" "XF")]) + +(define_insn "*fyl2x_tfxf3" + [(set (match_operand:TF 0 "register_operand" "=f") + (unspec:TF [(match_operand:TF 2 "register_operand" "0") + (match_operand:XF 1 "register_operand" "u")] + UNSPEC_FYL2X))] + "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 + && flag_unsafe_math_optimizations" + "fyl2x" + [(set_attr "type" "fpspc") + (set_attr "mode" "XF")]) + +(define_expand "logsf2" + [(set (match_operand:SF 0 "register_operand" "") + (unspec:SF [(match_operand:SF 1 "register_operand" "") + (match_dup 2)] UNSPEC_FYL2X))] + "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 + && flag_unsafe_math_optimizations" +{ + rtx temp; + + operands[2] = gen_reg_rtx (XFmode); + temp = standard_80387_constant_rtx (4); /* fldln2 */ + emit_move_insn (operands[2], temp); +}) + +(define_expand "logdf2" + [(set (match_operand:DF 0 "register_operand" "") + (unspec:DF [(match_operand:DF 1 "register_operand" "") + (match_dup 2)] UNSPEC_FYL2X))] + "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 + && flag_unsafe_math_optimizations" +{ + rtx temp; + + operands[2] = gen_reg_rtx (XFmode); + temp = standard_80387_constant_rtx (4); /* fldln2 */ + emit_move_insn (operands[2], temp); +}) + +(define_expand "logxf2" + [(set (match_operand:XF 0 "register_operand" "") + (unspec:XF [(match_operand:XF 1 "register_operand" "") + (match_dup 2)] UNSPEC_FYL2X))] + "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 + && flag_unsafe_math_optimizations" +{ + rtx temp; + + operands[2] = gen_reg_rtx (XFmode); + temp = standard_80387_constant_rtx (4); /* fldln2 */ + emit_move_insn (operands[2], temp); +}) + +(define_expand "logtf2" + [(set (match_operand:TF 0 "register_operand" "") + (unspec:TF [(match_operand:TF 1 "register_operand" "") + (match_dup 2)] UNSPEC_FYL2X))] + "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 + && flag_unsafe_math_optimizations" +{ + rtx temp; + + operands[2] = gen_reg_rtx (XFmode); + temp = standard_80387_constant_rtx (4); /* fldln2 */ + emit_move_insn (operands[2], temp); +}) ;; Block operation instructions diff --git a/gcc/reg-stack.c b/gcc/reg-stack.c index 525d0669440..75a59e68727 100644 --- a/gcc/reg-stack.c +++ b/gcc/reg-stack.c @@ -1729,6 +1729,7 @@ subst_stack_regs_pat (insn, regstack, pat) break; case UNSPEC_FPATAN: + case UNSPEC_FYL2X: /* These insns operate on the top two stack slots. */ src1 = get_true_reg (&XVECEXP (pat_src, 0, 0)); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 926f01d2f0a..e2a4a06b3ca 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2003-05-11 Roger Sayle + + * gcc.dg/i386-387-1.c: Update to also test log. + * gcc.dg/i386-387-2.c: Likewise. + 2003-05-11 Toon Moene * g77.f-torture/execute/int8421.f: New test. diff --git a/gcc/testsuite/gcc.dg/i386-387-1.c b/gcc/testsuite/gcc.dg/i386-387-1.c index f28fd8bbdcf..07389106f50 100644 --- a/gcc/testsuite/gcc.dg/i386-387-1.c +++ b/gcc/testsuite/gcc.dg/i386-387-1.c @@ -5,8 +5,10 @@ /* { dg-final { scan-assembler "call\t_?cos" } } */ /* { dg-final { scan-assembler "call\t_?sqrt" } } */ /* { dg-final { scan-assembler "call\t_?atan2" } } */ +/* { dg-final { scan-assembler "call\t_?log" } } */ 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); } diff --git a/gcc/testsuite/gcc.dg/i386-387-2.c b/gcc/testsuite/gcc.dg/i386-387-2.c index c73cb92c5f3..3bebc758f2a 100644 --- a/gcc/testsuite/gcc.dg/i386-387-2.c +++ b/gcc/testsuite/gcc.dg/i386-387-2.c @@ -5,8 +5,10 @@ /* { dg-final { scan-assembler "fcos" } } */ /* { dg-final { scan-assembler "fsqrt" } } */ /* { dg-final { scan-assembler "fpatan" } } */ +/* { dg-final { scan-assembler "fyl2x" } } */ 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); }