* expmed.c (mode_for_extraction): New function.
authorzack <zack@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 22 Aug 2001 00:33:33 +0000 (00:33 +0000)
committerzack <zack@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 22 Aug 2001 00:33:33 +0000 (00:33 +0000)
(store_bit_field, extract_bit_field): Use it.
* expr.h: Prototype it and provide an enum for its first argument.

* combine.c, function.c, recog.c: Don't include insn-codes.h.
Use mode_for_extraction rather than testing HAVE_insv/extv/extzv
and digging through the insn_data tables.
* Makefile.in: Update dependencies.

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

gcc/ChangeLog
gcc/Makefile.in
gcc/combine.c
gcc/expmed.c
gcc/expr.h
gcc/function.c
gcc/recog.c

index 11a3364..f07bea4 100644 (file)
@@ -1,3 +1,14 @@
+2001-08-21  Zack Weinberg  <zackw@panix.com>
+
+       * expmed.c (mode_for_extraction): New function.
+       (store_bit_field, extract_bit_field): Use it.
+       * expr.h: Prototype it and provide an enum for its first argument.
+
+       * combine.c, function.c, recog.c: Don't include insn-codes.h.
+       Use mode_for_extraction rather than testing HAVE_insv/extv/extzv
+       and digging through the insn_data tables.
+       * Makefile.in: Update dependencies.
+
 2001-08-22  Neil Booth  <neil@daikokuya.demon.co.uk>
 
        * cppfiles.c (stack_include_file): line-map.c now handles include
index 478a10c..22861cc 100644 (file)
@@ -1380,7 +1380,7 @@ varasm.o : varasm.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(RTL_H) flags.h \
    output.h c-pragma.h toplev.h xcoffout.h debug.h $(GGC_H) $(TM_P_H) \
    $(HASHTAB_H) $(TARGET_H)
 function.o : function.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(TREE_H) flags.h \
-   function.h insn-codes.h $(EXPR_H) libfuncs.h $(REGS_H) hard-reg-set.h \
+   function.h $(EXPR_H) libfuncs.h $(REGS_H) hard-reg-set.h \
    insn-config.h $(RECOG_H) output.h toplev.h except.h hash.h $(GGC_H) $(TM_P_H)
 stmt.o : stmt.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(TREE_H) flags.h function.h  \
    insn-config.h hard-reg-set.h $(EXPR_H) libfuncs.h except.h \
@@ -1490,7 +1490,7 @@ flow.o : flow.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(TREE_H) flags.h insn-config.h
 dominance.o : dominance.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) hard-reg-set.h \
    $(BASIC_BLOCK_H)
 combine.o : combine.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) flags.h function.h \
-   insn-config.h insn-codes.h $(INSN_ATTR_H) $(REGS_H) $(EXPR_H) \
+   insn-config.h $(INSN_ATTR_H) $(REGS_H) $(EXPR_H) \
    $(BASIC_BLOCK_H) $(RECOG_H) real.h hard-reg-set.h toplev.h $(TM_P_H)
 regclass.o : regclass.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) hard-reg-set.h flags.h \
    $(BASIC_BLOCK_H) $(REGS_H) insn-config.h $(RECOG_H) reload.h real.h \
@@ -1545,7 +1545,7 @@ final.o : final.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(TREE_H) flags.h intl.h \
    toplev.h reload.h dwarf2out.h $(BASIC_BLOCK_H) $(TM_P_H) $(TARGET_H)
 recog.o : recog.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) function.h $(BASIC_BLOCK_H) \
    $(REGS_H) $(RECOG_H) $(EXPR_H) hard-reg-set.h flags.h insn-config.h \
-   $(INSN_ATTR_H) insn-codes.h real.h toplev.h output.h reload.h $(TM_P_H)
+   $(INSN_ATTR_H) real.h toplev.h output.h reload.h $(TM_P_H)
 reg-stack.o : reg-stack.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(TREE_H) $(RECOG_H) \
    $(REGS_H) hard-reg-set.h flags.h insn-config.h toplev.h reload.h \
    varray.h function.h $(TM_P_H)
index b453396..5c6dcbc 100644 (file)
@@ -83,7 +83,6 @@ Boston, MA 02111-1307, USA.  */
 #include "hard-reg-set.h"
 #include "basic-block.h"
 #include "insn-config.h"
-#include "insn-codes.h"
 #include "function.h"
 /* Include expr.h after insn-config.h so we get HAVE_conditional_move.  */
 #include "expr.h"
@@ -6004,59 +6003,28 @@ make_extraction (mode, inner, pos, pos_rtx, len,
 
   /* Get the mode to use should INNER not be a MEM, the mode for the position,
      and the mode for the result.  */
-#ifdef HAVE_insv
-  if (in_dest)
+  if (in_dest && mode_for_extraction(EP_insv, -1) != MAX_MACHINE_MODE)
     {
-      wanted_inner_reg_mode
-       = insn_data[(int) CODE_FOR_insv].operand[0].mode;
-      if (wanted_inner_reg_mode == VOIDmode)
-       wanted_inner_reg_mode = word_mode;
-
-      pos_mode = insn_data[(int) CODE_FOR_insv].operand[2].mode;
-      if (pos_mode == VOIDmode)
-       pos_mode = word_mode;
-
-      extraction_mode = insn_data[(int) CODE_FOR_insv].operand[3].mode;
-      if (extraction_mode == VOIDmode)
-       extraction_mode = word_mode;
+      wanted_inner_reg_mode = mode_for_extraction (EP_insv, 0);
+      pos_mode = mode_for_extraction (EP_insv, 2);
+      extraction_mode = mode_for_extraction (EP_insv, 3);
     }
-#endif
 
-#ifdef HAVE_extzv
-  if (! in_dest && unsignedp)
+  if (! in_dest && unsignedp
+      && mode_for_extraction (EP_extzv, -1) != MAX_MACHINE_MODE)
     {
-      wanted_inner_reg_mode
-       = insn_data[(int) CODE_FOR_extzv].operand[1].mode;
-      if (wanted_inner_reg_mode == VOIDmode)
-       wanted_inner_reg_mode = word_mode;
-
-      pos_mode = insn_data[(int) CODE_FOR_extzv].operand[3].mode;
-      if (pos_mode == VOIDmode)
-       pos_mode = word_mode;
-
-      extraction_mode = insn_data[(int) CODE_FOR_extzv].operand[0].mode;
-      if (extraction_mode == VOIDmode)
-       extraction_mode = word_mode;
+      wanted_inner_reg_mode = mode_for_extraction (EP_extzv, 1);
+      pos_mode = mode_for_extraction (EP_extzv, 3);
+      extraction_mode = mode_for_extraction (EP_extzv, 0);
     }
-#endif
 
-#ifdef HAVE_extv
-  if (! in_dest && ! unsignedp)
+  if (! in_dest && ! unsignedp
+      && mode_for_extraction (EP_extv, -1) != MAX_MACHINE_MODE)
     {
-      wanted_inner_reg_mode
-       = insn_data[(int) CODE_FOR_extv].operand[1].mode;
-      if (wanted_inner_reg_mode == VOIDmode)
-       wanted_inner_reg_mode = word_mode;
-
-      pos_mode = insn_data[(int) CODE_FOR_extv].operand[3].mode;
-      if (pos_mode == VOIDmode)
-       pos_mode = word_mode;
-
-      extraction_mode = insn_data[(int) CODE_FOR_extv].operand[0].mode;
-      if (extraction_mode == VOIDmode)
-       extraction_mode = word_mode;
+      wanted_inner_reg_mode = mode_for_extraction (EP_extv, 1);
+      pos_mode = mode_for_extraction (EP_extv, 3);
+      extraction_mode = mode_for_extraction (EP_extv, 0);
     }
-#endif
 
   /* Never narrow an object, since that might not be safe.  */
 
@@ -10235,14 +10203,15 @@ simplify_comparison (code, pop0, pop1)
            {
              if (BITS_BIG_ENDIAN)
                {
-#ifdef HAVE_extzv
-                 mode = insn_data[(int) CODE_FOR_extzv].operand[1].mode;
-                 if (mode == VOIDmode)
-                   mode = word_mode;
-                 i = (GET_MODE_BITSIZE (mode) - 1 - i);
-#else
-                 i = BITS_PER_WORD - 1 - i;
-#endif
+                 enum machine_mode new_mode
+                   = mode_for_extraction (EP_extzv, 1);
+                 if (new_mode == MAX_MACHINE_MODE)
+                   i = BITS_PER_WORD - 1 - i;
+                 else
+                   {
+                     mode = new_mode;
+                     i = (GET_MODE_BITSIZE (mode) - 1 - i);
+                   }
                }
 
              op0 = XEXP (op0, 2);
index 830ef9e..e3918d8 100644 (file)
@@ -203,6 +203,61 @@ negate_rtx (mode, x)
 
   return result;
 }
+
+/* Report on the availability of insv/extv/extzv and the desired mode
+   of each of their operands.  Returns MAX_MACHINE_MODE if HAVE_foo
+   is false; else the mode of the specified operand.  If OPNO is -1,
+   all the caller cares about is whether the insn is available.  */
+enum machine_mode
+mode_for_extraction (pattern, opno)
+     enum extraction_pattern pattern;
+     int opno;
+{
+  const struct insn_data *data;
+
+  switch (pattern)
+    {
+    case EP_insv:
+#ifdef HAVE_insv
+      if (HAVE_insv)
+       {
+         data = &insn_data[CODE_FOR_insv];
+         break;
+       }
+#endif
+      return MAX_MACHINE_MODE;
+
+    case EP_extv:
+#ifdef HAVE_extv
+      if (HAVE_extv)
+       {
+         data = &insn_data[CODE_FOR_extv];
+         break;
+       }
+#endif
+      return MAX_MACHINE_MODE;
+
+    case EP_extzv:
+#ifdef HAVE_extzv
+      if (HAVE_extzv)
+       {
+         data = &insn_data[CODE_FOR_extzv];
+         break;
+       }
+#endif
+      return MAX_MACHINE_MODE;
+    }
+
+  if (opno == -1)
+    return VOIDmode;
+
+  /* Everyone who uses this function used to follow it with
+     if (result == VOIDmode) result = word_mode; */
+  if (data->operand[opno].mode == VOIDmode)
+    return word_mode;
+  return data->operand[opno].mode;
+}
+
 \f
 /* Generate code to store value from rtx VALUE
    into a bit-field within structure STR_RTX
@@ -234,15 +289,13 @@ store_bit_field (str_rtx, bitsize, bitnum, fieldmode, value, align, total_size)
   unsigned HOST_WIDE_INT offset = bitnum / unit;
   unsigned HOST_WIDE_INT bitpos = bitnum % unit;
   register rtx op0 = str_rtx;
-#ifdef HAVE_insv
+
   unsigned HOST_WIDE_INT insv_bitsize;
   enum machine_mode op_mode;
 
-  op_mode = insn_data[(int) CODE_FOR_insv].operand[3].mode;
-  if (op_mode == VOIDmode)
-    op_mode = word_mode;
-  insv_bitsize = GET_MODE_BITSIZE (op_mode);
-#endif
+  op_mode = mode_for_extraction (EP_insv, 3);
+  if (op_mode != MAX_MACHINE_MODE)
+    insv_bitsize = GET_MODE_BITSIZE (op_mode);
 
   /* It is wrong to have align==0, since every object is aligned at
      least at a bit boundary.  This usually means a bug elsewhere.  */
@@ -475,8 +528,7 @@ store_bit_field (str_rtx, bitsize, bitnum, fieldmode, value, align, total_size)
   /* Now OFFSET is nonzero only if OP0 is memory
      and is therefore always measured in bytes.  */
 
-#ifdef HAVE_insv
-  if (HAVE_insv
+  if (op_mode != MAX_MACHINE_MODE
       && GET_MODE (value) != BLKmode
       && !(bitsize == 1 && GET_CODE (value) == CONST_INT)
       /* Ensure insv's size is wide enough for this field.  */
@@ -617,7 +669,6 @@ store_bit_field (str_rtx, bitsize, bitnum, fieldmode, value, align, total_size)
     }
   else
     insv_loses:
-#endif
     /* Insv is not available; store using shifts and boolean ops.  */
     store_fixed_bit_field (op0, offset, bitsize, bitpos, value, align);
   return value;
@@ -981,28 +1032,18 @@ extract_bit_field (str_rtx, bitsize, bitnum, unsignedp,
   rtx spec_target = target;
   rtx spec_target_subreg = 0;
   enum machine_mode int_mode;
-#ifdef HAVE_extv
   unsigned HOST_WIDE_INT extv_bitsize;
   enum machine_mode extv_mode;
-#endif
-#ifdef HAVE_extzv
   unsigned HOST_WIDE_INT extzv_bitsize;
   enum machine_mode extzv_mode;
-#endif
 
-#ifdef HAVE_extv
-  extv_mode = insn_data[(int) CODE_FOR_extv].operand[0].mode;
-  if (extv_mode == VOIDmode)
-    extv_mode = word_mode;
-  extv_bitsize = GET_MODE_BITSIZE (extv_mode);
-#endif
+  extv_mode = mode_for_extraction (EP_extv, 0);
+  if (extv_mode != MAX_MACHINE_MODE)
+    extv_bitsize = GET_MODE_BITSIZE (extv_mode);
 
-#ifdef HAVE_extzv
-  extzv_mode = insn_data[(int) CODE_FOR_extzv].operand[0].mode;
-  if (extzv_mode == VOIDmode)
-    extzv_mode = word_mode;
-  extzv_bitsize = GET_MODE_BITSIZE (extzv_mode);
-#endif
+  extzv_mode = mode_for_extraction (EP_extzv, 0);
+  if (extzv_mode != MAX_MACHINE_MODE)
+    extzv_bitsize = GET_MODE_BITSIZE (extzv_mode);
 
   /* Discount the part of the structure before the desired byte.
      We need to know how many bytes are safe to reference after it.  */
@@ -1236,8 +1277,7 @@ extract_bit_field (str_rtx, bitsize, bitnum, unsignedp,
 
   if (unsignedp)
     {
-#ifdef HAVE_extzv
-      if (HAVE_extzv
+      if (extzv_mode != MAX_MACHINE_MODE
          && (extzv_bitsize >= bitsize)
          && ! ((GET_CODE (op0) == REG || GET_CODE (op0) == SUBREG)
                && (bitsize + bitpos > extzv_bitsize)))
@@ -1369,14 +1409,12 @@ extract_bit_field (str_rtx, bitsize, bitnum, unsignedp,
        }
       else
         extzv_loses:
-#endif
       target = extract_fixed_bit_field (int_mode, op0, offset, bitsize, 
                                        bitpos, target, 1, align);
     }
   else
     {
-#ifdef HAVE_extv
-      if (HAVE_extv
+      if (extv_mode != MAX_MACHINE_MODE
          && (extv_bitsize >= bitsize)
          && ! ((GET_CODE (op0) == REG || GET_CODE (op0) == SUBREG)
                && (bitsize + bitpos > extv_bitsize)))
@@ -1503,7 +1541,6 @@ extract_bit_field (str_rtx, bitsize, bitnum, unsignedp,
        } 
       else
        extv_loses:
-#endif
       target = extract_fixed_bit_field (int_mode, op0, offset, bitsize, 
                                        bitpos, target, 0, align);
     }
@@ -2000,7 +2037,8 @@ expand_shift (code, mode, shifted, amount, target, unsignedp)
             that is in range, try a rotate in the opposite direction.  */
 
          if (temp == 0 && GET_CODE (op1) == CONST_INT
-             && INTVAL (op1) > 0 && INTVAL (op1) < GET_MODE_BITSIZE (mode))
+             && INTVAL (op1) > 0
+             && (unsigned int) INTVAL (op1) < GET_MODE_BITSIZE (mode))
            temp = expand_binop (mode,
                                 left ? rotr_optab : rotl_optab,
                                 shifted, 
index 22e537d..9bf2adb 100644 (file)
@@ -715,6 +715,14 @@ extern rtx hard_libcall_value PARAMS ((enum machine_mode));
    of STACK_BOUNDARY / BITS_PER_UNIT.  */
 extern rtx round_push PARAMS ((rtx));
 
+/* Return the mode desired by operand N of a particular bitfield
+   insert/extract insn, or MAX_MACHINE_MODE if no such insn is
+   available.  */
+
+enum extraction_pattern { EP_insv, EP_extv, EP_extzv };
+extern enum machine_mode
+mode_for_extraction PARAMS ((enum extraction_pattern, int));
+
 extern rtx store_bit_field PARAMS ((rtx, unsigned HOST_WIDE_INT,
                                    unsigned HOST_WIDE_INT,
                                    enum machine_mode, rtx,
index 6c8a937..93add2a 100644 (file)
@@ -50,7 +50,6 @@ Boston, MA 02111-1307, USA.  */
 #include "regs.h"
 #include "hard-reg-set.h"
 #include "insn-config.h"
-#include "insn-codes.h"
 #include "recog.h"
 #include "output.h"
 #include "basic-block.h"
@@ -2064,23 +2063,21 @@ fixup_var_refs_1 (var, promoted_mode, loc, insn, replacements)
              enum machine_mode is_mode = GET_MODE (tem);
              HOST_WIDE_INT pos = INTVAL (XEXP (x, 2));
 
-#ifdef HAVE_extzv
              if (GET_CODE (x) == ZERO_EXTRACT)
                {
-                 wanted_mode
-                   = insn_data[(int) CODE_FOR_extzv].operand[1].mode;
-                 if (wanted_mode == VOIDmode)
-                   wanted_mode = word_mode;
+                 enum machine_mode new_mode
+                   = mode_for_extraction (EP_extzv, 1);
+                 if (new_mode != MAX_MACHINE_MODE)
+                   wanted_mode = new_mode;
                }
-#endif
-#ifdef HAVE_extv
-             if (GET_CODE (x) == SIGN_EXTRACT)
+             else if (GET_CODE (x) == SIGN_EXTRACT)
                {
-                 wanted_mode = insn_data[(int) CODE_FOR_extv].operand[1].mode;
-                 if (wanted_mode == VOIDmode)
-                   wanted_mode = word_mode;
+                 enum machine_mode new_mode
+                   = mode_for_extraction (EP_extv, 1);
+                 if (new_mode != MAX_MACHINE_MODE)
+                   wanted_mode = new_mode;
                }
-#endif
+
              /* If we have a narrower mode, we can do something.  */
              if (wanted_mode != VOIDmode
                  && GET_MODE_SIZE (wanted_mode) < GET_MODE_SIZE (is_mode))
@@ -2215,9 +2212,7 @@ fixup_var_refs_1 (var, promoted_mode, loc, insn, replacements)
       {
        rtx dest = SET_DEST (x);
        rtx src = SET_SRC (x);
-#ifdef HAVE_insv
        rtx outerdest = dest;
-#endif
 
        while (GET_CODE (dest) == SUBREG || GET_CODE (dest) == STRICT_LOW_PART
               || GET_CODE (dest) == SIGN_EXTRACT
@@ -2236,8 +2231,8 @@ fixup_var_refs_1 (var, promoted_mode, loc, insn, replacements)
        /* We will need to rerecognize this insn.  */
        INSN_CODE (insn) = -1;
 
-#ifdef HAVE_insv
-       if (GET_CODE (outerdest) == ZERO_EXTRACT && dest == var)
+       if (GET_CODE (outerdest) == ZERO_EXTRACT && dest == var
+           && mode_for_extraction (EP_insv, -1) != MAX_MACHINE_MODE)
          {
            /* Since this case will return, ensure we fixup all the
               operands here.  */
@@ -2268,9 +2263,7 @@ fixup_var_refs_1 (var, promoted_mode, loc, insn, replacements)
                enum machine_mode is_mode = GET_MODE (tem);
                HOST_WIDE_INT pos = INTVAL (XEXP (outerdest, 2));
 
-               wanted_mode = insn_data[(int) CODE_FOR_insv].operand[0].mode;
-               if (wanted_mode == VOIDmode)
-                 wanted_mode = word_mode;
+               wanted_mode = mode_for_extraction (EP_insv, 0);
 
                /* If we have a narrower mode, we can do something.  */
                if (GET_MODE_SIZE (wanted_mode) < GET_MODE_SIZE (is_mode))
@@ -2311,7 +2304,6 @@ fixup_var_refs_1 (var, promoted_mode, loc, insn, replacements)
            XEXP (outerdest, 0) = tem1;
            return;
          }
-#endif
 
        /* STRICT_LOW_PART is a no-op on memory references
           and it can cause combinations to be unrecognizable,
index f2e046f..3ec2eeb 100644 (file)
@@ -30,7 +30,6 @@ Boston, MA 02111-1307, USA.  */
 #include "recog.h"
 #include "regs.h"
 #include "expr.h"
-#include "insn-codes.h"
 #include "function.h"
 #include "flags.h"
 #include "real.h"
@@ -566,22 +565,20 @@ validate_replace_rtx_1 (loc, from, to, object)
          enum machine_mode is_mode = GET_MODE (XEXP (x, 0));
          int pos = INTVAL (XEXP (x, 2));
 
-#ifdef HAVE_extzv
-         if (code == ZERO_EXTRACT)
+         if (GET_CODE (x) == ZERO_EXTRACT)
            {
-             wanted_mode = insn_data[(int) CODE_FOR_extzv].operand[1].mode;
-             if (wanted_mode == VOIDmode)
-               wanted_mode = word_mode;
+             enum machine_mode new_mode
+               = mode_for_extraction (EP_extzv, 1);
+             if (new_mode != MAX_MACHINE_MODE)
+               wanted_mode = new_mode;
            }
-#endif
-#ifdef HAVE_extv
-         if (code == SIGN_EXTRACT)
+         else if (GET_CODE (x) == SIGN_EXTRACT)
            {
-             wanted_mode = insn_data[(int) CODE_FOR_extv].operand[1].mode;
-             if (wanted_mode == VOIDmode)
-               wanted_mode = word_mode;
+             enum machine_mode new_mode
+               = mode_for_extraction (EP_extv, 1);
+             if (new_mode != MAX_MACHINE_MODE)
+               wanted_mode = new_mode;
            }
-#endif
 
          /* If we have a narrower mode, we can do something.  */
          if (wanted_mode != VOIDmode