aboutsummaryrefslogtreecommitdiff
path: root/gcc/config
diff options
context:
space:
mode:
authorUros Bizjak <uros@kss-loka.si>2004-05-07 07:38:21 +0200
committerUros Bizjak <uros@gcc.gnu.org>2004-05-07 07:38:21 +0200
commitc2fcfa4ff8921c33ee899529ac170da8a1628c7c (patch)
tree471a2c68d2c2564dfb50adb742590b68eb2cd647 /gcc/config
parent61af3d861bbc083c5eede0039a1a2d780b7a3124 (diff)
downloadgcc-c2fcfa4ff8921c33ee899529ac170da8a1628c7c.zip
gcc-c2fcfa4ff8921c33ee899529ac170da8a1628c7c.tar.gz
gcc-c2fcfa4ff8921c33ee899529ac170da8a1628c7c.tar.bz2
optabs.h (enum optab_index): Add new OTI_log1p.
* optabs.h (enum optab_index): Add new OTI_log1p. (log1p_optab): Define corresponding macro. * optabs.c (init_optabs): Initialize log1p_optab. * genopinit.c (optabs): Implement log1p_optab using log1p?f2 patterns. * builtins.c (expand_builtin_mathfn): Handle BUILT_IN_LOG1P{,F,L} using log1p_optab. (expand_builtin): Expand BUILT_IN_LOG1P{,F,L} using expand_builtin_mathfn if flag_unsafe_math_optimizations is set. * reg-stack.c (subst_stack_regs_pat): Handle UNSPEC_FYL2XP1. * config/i386/i386.c (ix86_emit_i387_log1p): New function. * config/i386/i386-protos.h (ix86_emit_i387_log1p): Prototype here. * config/i386/i386.md (UNSPEC_FYL2XP1): New unspec to represent x87's fyl2xp1 instruction. (*fyl2x_xf3): Rename insn definition to fyl2x_xf3. (fyl2xp1_xf3): New pattern to implement fyl2xp1 x87 instruction. (log1psf2, log1pdf2, log1pxf2): New expanders to implement log1pf, log1p and log1pl built-ins as inline x87 intrinsics. * testsuite/gcc.dg/builtins-33.c: Also check log1p*. From-SVN: r81606
Diffstat (limited to 'gcc/config')
-rw-r--r--gcc/config/i386/i386-protos.h2
-rw-r--r--gcc/config/i386/i386.c30
-rw-r--r--gcc/config/i386/i386.md55
3 files changed, 86 insertions, 1 deletions
diff --git a/gcc/config/i386/i386-protos.h b/gcc/config/i386/i386-protos.h
index 636d50b..42771f9 100644
--- a/gcc/config/i386/i386-protos.h
+++ b/gcc/config/i386/i386-protos.h
@@ -184,6 +184,8 @@ extern void x86_function_profiler (FILE *, int);
extern void x86_emit_floatuns (rtx [2]);
extern void ix86_emit_fp_unordered_jump (rtx);
+extern void ix86_emit_i387_log1p (rtx, rtx);
+
extern enum rtx_code ix86_reverse_condition (enum rtx_code, enum machine_mode);
#ifdef TREE_CODE
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index a561d4f..0a45e3e 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -15949,4 +15949,34 @@ ix86_emit_fp_unordered_jump (rtx label)
emit_jump_insn (temp);
}
+/* Output code to perform a log1p XFmode calculation. */
+
+void ix86_emit_i387_log1p (rtx op0, rtx op1)
+{
+ rtx label1 = gen_label_rtx ();
+ rtx label2 = gen_label_rtx ();
+
+ rtx tmp = gen_reg_rtx (XFmode);
+ rtx tmp2 = gen_reg_rtx (XFmode);
+
+ emit_insn (gen_absxf2 (tmp, op1));
+ emit_insn (gen_cmpxf (tmp,
+ CONST_DOUBLE_FROM_REAL_VALUE (
+ REAL_VALUE_ATOF ("0.29289321881345247561810596348408353", XFmode),
+ XFmode)));
+ emit_jump_insn (gen_bge (label1));
+
+ emit_move_insn (tmp2, standard_80387_constant_rtx (4)); /* fldln2 */
+ emit_insn (gen_fyl2xp1_xf3 (op0, tmp2, op1));
+ emit_jump (label2);
+
+ emit_label (label1);
+ emit_move_insn (tmp, CONST1_RTX (XFmode));
+ emit_insn (gen_addxf3 (tmp, op1, tmp));
+ emit_move_insn (tmp2, standard_80387_constant_rtx (4)); /* fldln2 */
+ emit_insn (gen_fyl2x_xf3 (op0, tmp2, tmp));
+
+ emit_label (label2);
+}
+
#include "gt-i386.h"
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index ea61cc7..b136679 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -117,6 +117,7 @@
; x87 Floating point
(UNSPEC_FPATAN 65)
(UNSPEC_FYL2X 66)
+ (UNSPEC_FYL2XP1 67)
(UNSPEC_FRNDINT 68)
(UNSPEC_F2XM1 69)
@@ -15628,7 +15629,7 @@
emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
})
-(define_insn "*fyl2x_xf3"
+(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")]
@@ -15808,6 +15809,58 @@
emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
})
+(define_insn "fyl2xp1_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_FYL2XP1))
+ (clobber (match_scratch:XF 3 "=1"))]
+ "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
+ && flag_unsafe_math_optimizations"
+ "fyl2xp1"
+ [(set_attr "type" "fpspc")
+ (set_attr "mode" "XF")])
+
+(define_expand "log1psf2"
+ [(use (match_operand:XF 0 "register_operand" ""))
+ (use (match_operand:XF 1 "register_operand" ""))]
+ "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
+ && flag_unsafe_math_optimizations"
+{
+ rtx op0 = gen_reg_rtx (XFmode);
+ rtx op1 = gen_reg_rtx (XFmode);
+
+ emit_insn (gen_extendsfxf2 (op1, operands[1]));
+ ix86_emit_i387_log1p (op0, op1);
+ emit_insn (gen_truncxfsf2_noop (operands[0], op0));
+ DONE;
+})
+
+(define_expand "log1pdf2"
+ [(use (match_operand:XF 0 "register_operand" ""))
+ (use (match_operand:XF 1 "register_operand" ""))]
+ "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
+ && flag_unsafe_math_optimizations"
+{
+ rtx op0 = gen_reg_rtx (XFmode);
+ rtx op1 = gen_reg_rtx (XFmode);
+
+ emit_insn (gen_extenddfxf2 (op1, operands[1]));
+ ix86_emit_i387_log1p (op0, op1);
+ emit_insn (gen_truncxfdf2_noop (operands[0], op0));
+ DONE;
+})
+
+(define_expand "log1pxf2"
+ [(use (match_operand:XF 0 "register_operand" ""))
+ (use (match_operand:XF 1 "register_operand" ""))]
+ "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
+ && flag_unsafe_math_optimizations"
+{
+ ix86_emit_i387_log1p (operands[0], operands[1]);
+ DONE;
+})
+
(define_insn "*fxtractxf3"
[(set (match_operand:XF 0 "register_operand" "=f")
(unspec:XF [(match_operand:XF 2 "register_operand" "0")]