expmed.c (sdiv_pow2_cheap, [...]): Change type to bool.
authorRoger Sayle <roger@eyesopen.com>
Mon, 9 Aug 2004 22:36:39 +0000 (22:36 +0000)
committerRoger Sayle <sayle@gcc.gnu.org>
Mon, 9 Aug 2004 22:36:39 +0000 (22:36 +0000)
* expmed.c (sdiv_pow2_cheap, smod_pow2_cheap): Change type to bool.
(init_expmed): Fix potential overrun problem with "all.reg".
(expand_sdiv2_pow2): Add an alternate implementation for signed
division, if the target provides a suitable conditional move insn.

From-SVN: r85728

gcc/ChangeLog
gcc/expmed.c

index ee1cbd78caca8b935f0acc4b0174f89c6ca19582..34ba3413887129620b22eb784ceafac789fb4a44 100644 (file)
@@ -1,3 +1,10 @@
+2004-08-09  Roger Sayle  <roger@eyesopen.com>
+
+       * expmed.c (sdiv_pow2_cheap, smod_pow2_cheap): Change type to bool.
+       (init_expmed): Fix potential overrun problem with "all.reg".
+       (expand_sdiv2_pow2): Add an alternate implementation for signed
+       division, if the target provides a suitable conditional move insn.
+
 2004-08-09  Paul Brook  <paul@codesourcery.com>
        Richard Henderson  <rth@redhat.com>
 
index cdbbd1779586aa2207c5f338ea4b1a10ed16257c..735fe987fc16ebdc448f7020e5822303defc8903 100644 (file)
@@ -59,8 +59,8 @@ static rtx expand_sdiv_pow2 (enum machine_mode, rtx, HOST_WIDE_INT);
    Usually, this will mean that the MD file will emit non-branch
    sequences.  */
 
-static int sdiv_pow2_cheap[NUM_MACHINE_MODES];
-static int smod_pow2_cheap[NUM_MACHINE_MODES];
+static bool sdiv_pow2_cheap[NUM_MACHINE_MODES];
+static bool smod_pow2_cheap[NUM_MACHINE_MODES];
 
 #ifndef SLOW_UNALIGNED_ACCESS
 #define SLOW_UNALIGNED_ACCESS(MODE, ALIGN) STRICT_ALIGNMENT
@@ -109,7 +109,7 @@ init_expmed (void)
 {
   struct
   {
-    struct rtx_def reg;
+    struct rtx_def reg;                rtunion reg_fld[2];
     struct rtx_def plus;       rtunion plus_fld1;
     struct rtx_def neg;
     struct rtx_def udiv;       rtunion udiv_fld1;
@@ -3194,6 +3194,31 @@ expand_sdiv_pow2 (enum machine_mode mode, rtx op0, HOST_WIDE_INT d)
       return expand_shift (RSHIFT_EXPR, mode, temp, shift, NULL_RTX, 0);
     }
 
+#ifdef HAVE_conditional_move
+  if (BRANCH_COST >= 2)
+    {
+      rtx temp2;
+
+      start_sequence ();
+      temp2 = copy_to_mode_reg (mode, op0);
+      temp = expand_binop (mode, add_optab, temp2, GEN_INT (d-1),
+                          NULL_RTX, 0, OPTAB_LIB_WIDEN);
+      temp = force_reg (mode, temp);
+
+      /* Construct "temp2 = (temp2 < 0) ? temp : temp2".  */
+      temp2 = emit_conditional_move (temp2, LT, temp2, const0_rtx,
+                                    mode, temp, temp2, mode, 0);
+      if (temp2)
+       {
+         rtx seq = get_insns ();
+         end_sequence ();
+         emit_insn (seq);
+         return expand_shift (RSHIFT_EXPR, mode, temp2, shift, NULL_RTX, 0);
+       }
+      end_sequence ();
+    }
+#endif
+
   if (BRANCH_COST >= 2)
     {
       int ushift = GET_MODE_BITSIZE (mode) - logd;