* optabs.h (enum optab_index): Add new OTI_signbit.
authoruros <uros@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 21 Jul 2007 21:45:06 +0000 (21:45 +0000)
committeruros <uros@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 21 Jul 2007 21:45:06 +0000 (21:45 +0000)
        (signbit_optab): Define corresponding macro.
        (enum insn_code signbit_optab[]): Remove array.
        * optabs.c (init_optabs): Initialize signbit_optab using init_optab.
        (expand_copysign_absneg): If back end provides signbit insn, use it
        instead of bit operations on floating point argument.
        * builtins.c (enum insn_code signbit_optab[]): Remove array.
        (expand_builtin_signbit): Check signbit_optab->handlers[].insn_code for
        availability of signbit insn.

        * config/i386/i386.md (signbit<mode>2): New insn pattern to implement
        signbitf, signbit and signbitl built-ins as inline x87 intrinsics when
        SSE mode is not active.
        (isinf<mode>2): Disable for mfpmath=sse,387.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@126813 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/builtins.c
gcc/config/i386/i386.md
gcc/optabs.c
gcc/optabs.h

index 92579ec..5d4982d 100644 (file)
@@ -1,3 +1,20 @@
+2007-07-21  Uros Bizjak  <ubizjak@gmail.com>
+
+       * optabs.h (enum optab_index): Add new OTI_signbit.
+       (signbit_optab): Define corresponding macro.
+       (enum insn_code signbit_optab[]): Remove array.
+       * optabs.c (init_optabs): Initialize signbit_optab using init_optab.
+       (expand_copysign_absneg): If back end provides signbit insn, use it
+       instead of bit operations on floating point argument.
+       * builtins.c (enum insn_code signbit_optab[]): Remove array.
+       (expand_builtin_signbit): Check signbit_optab->handlers[].insn_code for
+       availability of signbit insn.
+
+       * config/i386/i386.md (signbit<mode>2): New insn pattern to implement
+       signbitf, signbit and signbitl built-ins as inline x87 intrinsics when
+       SSE mode is not active.
+       (isinf<mode>2): Disable for mfpmath=sse,387.
+
 2007-07-22  Ben Elliston  <bje@au.ibm.com>
 
        * regclass.c (invalid_mode_change_p): Attach ATTRIBUTE_UNUSED to
 2007-07-16  Paul Brook  <paul@codesourcery.com>
 
        PR target/32753
-       gcc/
        * config/arm/cirrus.md (cirrus_arm_movsi_insn): Remove dead insn.
        (cirrus_thumb2_movsi_insn): Ditto.
 
        offsets->locals_base to avoid negative stack size.
        (thumb1_expand_prologue): Assert on negative stack size.
 
-2007-04-19  Sebastian Pop  <sebpop@gmail.com>
+2007-06-19  Sebastian Pop  <sebpop@gmail.com>
 
        PR tree-optimization/32367
        * tree-chrec.h (build_polynomial_chrec): Verify that the left hand side 
        float constant.
        (_m_to_float): Use C89 compatible assignment.
 
-2007-04-20  Martin Michlmayr  <tbm@cyrius.com>
+2007-05-20  Martin Michlmayr  <tbm@cyrius.com>
 
        PR target/32007
        * config/arm/lib1funcs.asm: Define __ARM_ARCH__ on v2/v3 machines.
        size never inline functions increasing caller size.
        (cgraph_early_inlining): Inline for size when optimizing for size.
 
-2007-04-18  Bernd Schmidt  <bernd.schmidt@analog.com>
+2007-05-04  Bernd Schmidt  <bernd.schmidt@analog.com>
 
        * config/bfin/bfin.md (<optab>di3): Now a define_expand which expands
        logical operations piecewise.
index d0e5db9..a2e4be8 100644 (file)
@@ -240,11 +240,6 @@ static tree do_mpfr_remquo (tree, tree, tree);
 static tree do_mpfr_lgamma_r (tree, tree, tree);
 #endif
 
-/* This array records the insn_code of insns to imlement the signbit
-   function.  */
-enum insn_code signbit_optab[NUM_MACHINE_MODES];
-
-
 /* Return true if NODE should be considered for inline expansion regardless
    of the optimization level.  This means whenever a function is invoked with
    its "internal" name, which normally contains the prefix "__builtin".  */
@@ -5725,7 +5720,7 @@ expand_builtin_signbit (tree exp, rtx target)
   HOST_WIDE_INT hi, lo;
   tree arg;
   int word, bitpos;
-  enum insn_code signbit_insn_code;
+  enum insn_code icode;
   rtx temp;
 
   if (!validate_arglist (exp, REAL_TYPE, VOID_TYPE))
@@ -5743,11 +5738,11 @@ expand_builtin_signbit (tree exp, rtx target)
 
   /* Check if the back end provides an insn that handles signbit for the
      argument's mode. */
-  signbit_insn_code = signbit_optab [(int) fmode];
-  if (signbit_insn_code != CODE_FOR_nothing)
+  icode = signbit_optab->handlers [(int) fmode].insn_code;
+  if (icode != CODE_FOR_nothing)
     {
       target = gen_reg_rtx (TYPE_MODE (TREE_TYPE (exp)));
-      emit_unop_insn (signbit_insn_code, target, temp, UNKNOWN);
+      emit_unop_insn (icode, target, temp, UNKNOWN);
       return target;
     }
 
index e258447..0377735 100644 (file)
    (use (match_operand:X87MODEF 1 "register_operand" ""))]
   "TARGET_USE_FANCY_MATH_387
    && TARGET_C99_FUNCTIONS
-   && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
-       || TARGET_MIX_SSE_I387)"
+   && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
 {
   rtx mask = GEN_INT (0x45);
   rtx val = GEN_INT (0x05);
   DONE;
 })
 
+(define_expand "signbit<mode>2"
+  [(use (match_operand:SI 0 "register_operand" ""))
+   (use (match_operand:X87MODEF 1 "register_operand" ""))]
+  "TARGET_USE_FANCY_MATH_387
+   && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
+{
+  rtx mask = GEN_INT (0x0200);
+
+  rtx scratch = gen_reg_rtx (HImode);
+
+  emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
+  emit_insn (gen_andsi3 (operands[0], gen_lowpart (SImode, scratch), mask));
+  DONE;
+})
 \f
 ;; Block operation instructions
 
index 95b2ec9..c754544 100644 (file)
@@ -3112,63 +3112,79 @@ expand_copysign_absneg (enum machine_mode mode, rtx op0, rtx op1, rtx target,
                        int bitpos, bool op0_is_abs)
 {
   enum machine_mode imode;
-  HOST_WIDE_INT hi, lo;
-  int word;
-  rtx label;
+  int icode;
+  rtx sign, label;
 
   if (target == op1)
     target = NULL_RTX;
 
-  if (!op0_is_abs)
+  /* Check if the back end provides an insn that handles signbit for the
+     argument's mode. */
+  icode = (int) signbit_optab->handlers [(int) mode].insn_code;
+  if (icode != CODE_FOR_nothing)
     {
-      op0 = expand_unop (mode, abs_optab, op0, target, 0);
-      if (op0 == NULL)
-       return NULL_RTX;
-      target = op0;
+      imode = insn_data[icode].operand[0].mode;
+      sign = gen_reg_rtx (imode);
+      emit_unop_insn (icode, sign, op1, UNKNOWN);
     }
   else
     {
-      if (target == NULL_RTX)
-        target = copy_to_reg (op0);
+      HOST_WIDE_INT hi, lo;
+
+      if (GET_MODE_SIZE (mode) <= UNITS_PER_WORD)
+       {
+         imode = int_mode_for_mode (mode);
+         if (imode == BLKmode)
+           return NULL_RTX;
+         op1 = gen_lowpart (imode, op1);
+       }
       else
-       emit_move_insn (target, op0);
-    }
+       {
+         int word;
 
-  if (GET_MODE_SIZE (mode) <= UNITS_PER_WORD)
-    {
-      imode = int_mode_for_mode (mode);
-      if (imode == BLKmode)
-       return NULL_RTX;
-      op1 = gen_lowpart (imode, op1);
-    }
-  else
-    {
-      imode = word_mode;
-      if (FLOAT_WORDS_BIG_ENDIAN)
-       word = (GET_MODE_BITSIZE (mode) - bitpos) / BITS_PER_WORD;
+         imode = word_mode;
+         if (FLOAT_WORDS_BIG_ENDIAN)
+           word = (GET_MODE_BITSIZE (mode) - bitpos) / BITS_PER_WORD;
+         else
+           word = bitpos / BITS_PER_WORD;
+         bitpos = bitpos % BITS_PER_WORD;
+         op1 = operand_subword_force (op1, word, mode);
+       }
+
+      if (bitpos < HOST_BITS_PER_WIDE_INT)
+       {
+         hi = 0;
+         lo = (HOST_WIDE_INT) 1 << bitpos;
+       }
       else
-       word = bitpos / BITS_PER_WORD;
-      bitpos = bitpos % BITS_PER_WORD;
-      op1 = operand_subword_force (op1, word, mode);
+       {
+         hi = (HOST_WIDE_INT) 1 << (bitpos - HOST_BITS_PER_WIDE_INT);
+         lo = 0;
+       }
+
+      sign = gen_reg_rtx (imode);
+      sign = expand_binop (imode, and_optab, op1,
+                          immed_double_const (lo, hi, imode),
+                          NULL_RTX, 1, OPTAB_LIB_WIDEN);
     }
 
-  if (bitpos < HOST_BITS_PER_WIDE_INT)
+  if (!op0_is_abs)
     {
-      hi = 0;
-      lo = (HOST_WIDE_INT) 1 << bitpos;
+      op0 = expand_unop (mode, abs_optab, op0, target, 0);
+      if (op0 == NULL)
+       return NULL_RTX;
+      target = op0;
     }
   else
     {
-      hi = (HOST_WIDE_INT) 1 << (bitpos - HOST_BITS_PER_WIDE_INT);
-      lo = 0;
+      if (target == NULL_RTX)
+        target = copy_to_reg (op0);
+      else
+       emit_move_insn (target, op0);
     }
 
-  op1 = expand_binop (imode, and_optab, op1,
-                     immed_double_const (lo, hi, imode),
-                     NULL_RTX, 1, OPTAB_LIB_WIDEN);
-
   label = gen_label_rtx ();
-  emit_cmp_and_jump_insns (op1, const0_rtx, EQ, NULL_RTX, imode, 1, label);
+  emit_cmp_and_jump_insns (sign, const0_rtx, EQ, NULL_RTX, imode, 1, label);
 
   if (GET_CODE (op0) == CONST_DOUBLE)
     op0 = simplify_unary_operation (NEG, mode, op0, mode);
@@ -5585,6 +5601,7 @@ init_optabs (void)
   tan_optab = init_optab (UNKNOWN);
   atan_optab = init_optab (UNKNOWN);
   copysign_optab = init_optab (UNKNOWN);
+  signbit_optab = init_optab (UNKNOWN);
 
   isinf_optab = init_optab (UNKNOWN);
 
@@ -5655,7 +5672,6 @@ init_optabs (void)
   for (i = 0; i < NUM_MACHINE_MODES; i++)
     {
       movmem_optab[i] = CODE_FOR_nothing;
-      signbit_optab[i] = CODE_FOR_nothing;
       cmpstr_optab[i] = CODE_FOR_nothing;
       cmpstrn_optab[i] = CODE_FOR_nothing;
       cmpmem_optab[i] = CODE_FOR_nothing;
index aed7a54..d8917ab 100644 (file)
@@ -219,7 +219,8 @@ enum optab_index
   OTI_atan,
   /* Copy sign */
   OTI_copysign,
-
+  /* Signbit */
+  OTI_signbit,
   /* Test for infinite value */
   OTI_isinf,
 
@@ -409,7 +410,7 @@ extern GTY(()) optab optab_table[OTI_MAX];
 #define tan_optab (optab_table[OTI_tan])
 #define atan_optab (optab_table[OTI_atan])
 #define copysign_optab (optab_table[OTI_copysign])
-
+#define signbit_optab (optab_table[OTI_signbit])
 #define isinf_optab (optab_table[OTI_isinf])
 
 #define cmp_optab (optab_table[OTI_cmp])
@@ -553,9 +554,6 @@ extern enum insn_code vcondu_gen_code[NUM_MACHINE_MODES];
 /* This array records the insn_code of insns to perform block moves.  */
 extern enum insn_code movmem_optab[NUM_MACHINE_MODES];
 
-/* This array records the insn_code of insns to implement the signbit function.  */
-extern enum insn_code signbit_optab[NUM_MACHINE_MODES];
-
 /* This array records the insn_code of insns to perform block sets.  */
 extern enum insn_code setmem_optab[NUM_MACHINE_MODES];