OSDN Git Service

* combine.c (make_extraction): If no mode is specified for
authorlaw <law@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 15 Sep 1998 22:47:10 +0000 (22:47 +0000)
committerlaw <law@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 15 Sep 1998 22:47:10 +0000 (22:47 +0000)
        an operand of insv, extv, or extzv, default it to word_mode.
        (simplify_comparison): Similarly.
        * expmed.c (store_bit_field): Similarly.
        (extract_bit_field): Similarly.
        * function.c (fixup_var_regs_1): Similarly.
        * recog.c (validate_replace_rtx_1): Similarly.
        * mips.md (extv, extzv, insv expanders): Default modes for most
        operands.  Handle TARGET_64BIT.
        (movdi_uld, movdi_usd): New patterns.

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

gcc/ChangeLog
gcc/combine.c
gcc/config/mips/mips.md
gcc/expmed.c
gcc/function.c
gcc/recog.c

index d791d77..a4f4e38 100644 (file)
@@ -1,5 +1,16 @@
 Tue Sep 15 22:59:52 1998  Jeffrey A Law  (law@cygnus.com)
 
+       * combine.c (make_extraction): If no mode is specified for
+       an operand of insv, extv, or extzv, default it to word_mode.
+       (simplify_comparison): Similarly.
+       * expmed.c (store_bit_field): Similarly.
+       (extract_bit_field): Similarly.
+       * function.c (fixup_var_regs_1): Similarly.
+       * recog.c (validate_replace_rtx_1): Similarly.
+       * mips.md (extv, extzv, insv expanders): Default modes for most
+       operands.  Handle TARGET_64BIT.
+       (movdi_uld, movdi_usd): New patterns.
+
        * pa.c (emit_move_sequence): Do not replace a pseudo with its
        equivalent memory location unless we have been provided a scratch
        register.  Similarly do not call find_replacement unless a
index 8f0ea65..024cb51 100644 (file)
@@ -5605,27 +5605,45 @@ make_extraction (mode, inner, pos, pos_rtx, len,
 #ifdef HAVE_insv
   if (in_dest)
     {
-      wanted_inner_reg_mode = insn_operand_mode[(int) CODE_FOR_insv][0];
-      pos_mode = insn_operand_mode[(int) CODE_FOR_insv][2];
-      extraction_mode = insn_operand_mode[(int) CODE_FOR_insv][3];
+      wanted_inner_reg_mode
+       = (insn_operand_mode[(int) CODE_FOR_insv][0] == VOIDmode
+          ? word_mode
+          : insn_operand_mode[(int) CODE_FOR_insv][0]);
+      pos_mode = (insn_operand_mode[(int) CODE_FOR_insv][2] == VOIDmode
+                 ? word_mode : insn_operand_mode[(int) CODE_FOR_insv][2]);
+      extraction_mode = (insn_operand_mode[(int) CODE_FOR_insv][3] == VOIDmode
+                        ? word_mode
+                        : insn_operand_mode[(int) CODE_FOR_insv][3]);
     }
 #endif
 
 #ifdef HAVE_extzv
   if (! in_dest && unsignedp)
     {
-      wanted_inner_reg_mode = insn_operand_mode[(int) CODE_FOR_extzv][1];
-      pos_mode = insn_operand_mode[(int) CODE_FOR_extzv][3];
-      extraction_mode = insn_operand_mode[(int) CODE_FOR_extzv][0];
+      wanted_inner_reg_mode
+       = (insn_operand_mode[(int) CODE_FOR_extzv][1] == VOIDmode
+          ? word_mode
+          : insn_operand_mode[(int) CODE_FOR_extzv][1]);
+      pos_mode = (insn_operand_mode[(int) CODE_FOR_extzv][3] == VOIDmode
+                 ? word_mode : insn_operand_mode[(int) CODE_FOR_extzv][3]);
+      extraction_mode = (insn_operand_mode[(int) CODE_FOR_extzv][0] == VOIDmode
+                        ? word_mode
+                        : insn_operand_mode[(int) CODE_FOR_extzv][0]);
     }
 #endif
 
 #ifdef HAVE_extv
   if (! in_dest && ! unsignedp)
     {
-      wanted_inner_reg_mode = insn_operand_mode[(int) CODE_FOR_extv][1];
-      pos_mode = insn_operand_mode[(int) CODE_FOR_extv][3];
-      extraction_mode = insn_operand_mode[(int) CODE_FOR_extv][0];
+      wanted_inner_reg_mode
+       = (insn_operand_mode[(int) CODE_FOR_extv][1] == VOIDmode
+          ? word_mode
+          : insn_operand_mode[(int) CODE_FOR_extv][1]);
+      pos_mode = (insn_operand_mode[(int) CODE_FOR_extv][3] == VOIDmode
+                 ? word_mode : insn_operand_mode[(int) CODE_FOR_extv][3]);
+      extraction_mode = (insn_operand_mode[(int) CODE_FOR_extv][0] == VOIDmode
+                        ? word_mode
+                        : insn_operand_mode[(int) CODE_FOR_extv][0]);
     }
 #endif
 
@@ -9762,12 +9780,16 @@ simplify_comparison (code, pop0, pop1)
              && (i = exact_log2 (INTVAL (XEXP (op0, 0)))) >= 0)
            {
              if (BITS_BIG_ENDIAN)
+               {
 #ifdef HAVE_extzv
-               i = (GET_MODE_BITSIZE
-                    (insn_operand_mode[(int) CODE_FOR_extzv][1]) - 1 - i);
+                 mode = insn_operand_mode[(int) CODE_FOR_extzv][1];
+                 if (mode == VOIDmode)
+                   mode = word_mode;
+                 i = (GET_MODE_BITSIZE (mode) - 1 - i);
 #else
-               i = BITS_PER_WORD - 1 - i;
+                 i = BITS_PER_WORD - 1 - i;
 #endif
+               }
 
              op0 = XEXP (op0, 2);
              op1 = GEN_INT (i);
index 4172c41..17bd10f 100644 (file)
@@ -4224,24 +4224,30 @@ move\\t%0,%z4\\n\\
 
 ;; Bit field extract patterns which use lwl/lwr.
 
-;; ??? There should be DImode variants for 64 bit code, but the current
-;; bitfield scheme can't handle that.  We would need to add new optabs
-;; in order to make that work.
-
 ;; ??? There could be HImode variants for the ulh/ulhu/ush macros.
 ;; It isn't clear whether this will give better code.
 
+;; Only specify the mode operand 1, the rest are assumed to be word_mode.
 (define_expand "extv"
-  [(set (match_operand:SI 0 "register_operand" "")
-       (sign_extract:SI (match_operand:QI 1 "memory_operand" "")
-                        (match_operand:SI 2 "immediate_operand" "")
-                        (match_operand:SI 3 "immediate_operand" "")))]
+  [(set (match_operand 0 "register_operand" "")
+       (sign_extract (match_operand:QI 1 "memory_operand" "")
+                     (match_operand 2 "immediate_operand" "")
+                     (match_operand 3 "immediate_operand" "")))]
   "!TARGET_MIPS16"
   "
 {
-  /* If this isn't a 32 bit field, and it doesn't start on a byte boundary
-     then fail.  */
-  if (INTVAL (operands[2]) != 32 || (INTVAL (operands[3]) % 8) != 0)
+  /* If the field does not start on a byte boundary, then fail.  */
+  if (INTVAL (operands[3]) % 8 != 0) 
+    FAIL;
+
+  /* MIPS I and MIPS II can only handle a 32bit field.  */
+  if (!TARGET_64BIT && INTVAL (operands[2]) != 32)
+    FAIL;
+
+  /* MIPS III and MIPS IV can handle both 32bit and 64bit fields.  */
+  if (TARGET_64BIT
+      && INTVAL (operands[2]) != 64
+      && INTVAL (operands[2]) != 32)
     FAIL;
 
   /* This can happen for a 64 bit target, when extracting a value from
@@ -4253,22 +4259,43 @@ move\\t%0,%z4\\n\\
   /* Change the mode to BLKmode for aliasing purposes.  */
   operands[1] = change_address (operands[1], BLKmode, XEXP (operands[1], 0));
 
-  /* Otherwise, emit a lwl/lwr pair to load the value.  */
-  emit_insn (gen_movsi_ulw (operands[0], operands[1]));
+  /* Otherwise, emit a l[wd]l/l[wd]r pair to load the value.  */
+  if (INTVAL (operands[2]) == 64)
+    emit_insn (gen_movdi_uld (operands[0], operands[1]));
+  else
+    {
+      if (TARGET_64BIT)
+       {
+         operands[0] = gen_lowpart (SImode, operands[0]);
+         if (operands[0] == NULL_RTX)
+           FAIL;
+       }
+      emit_insn (gen_movsi_ulw (operands[0], operands[1]));
+    }
   DONE;
 }")
 
+;; Only specify the mode operand 1, the rest are assumed to be word_mode.
 (define_expand "extzv"
-  [(set (match_operand:SI 0 "register_operand" "")
-       (zero_extract:SI (match_operand:QI 1 "memory_operand" "")
-                        (match_operand:SI 2 "immediate_operand" "")
-                        (match_operand:SI 3 "immediate_operand" "")))]
+  [(set (match_operand 0 "register_operand" "")
+       (zero_extract (match_operand:QI 1 "memory_operand" "")
+                     (match_operand 2 "immediate_operand" "")
+                     (match_operand 3 "immediate_operand" "")))]
   "!TARGET_MIPS16"
   "
 {
-  /* If this isn't a 32 bit field, and it doesn't start on a byte boundary
-     then fail.  */
-  if (INTVAL (operands[2]) != 32 || (INTVAL (operands[3]) % 8) != 0)
+  /* If the field does not start on a byte boundary, then fail.  */
+  if (INTVAL (operands[3]) % 8 != 0) 
+    FAIL;
+
+  /* MIPS I and MIPS II can only handle a 32bit field.  */
+  if (!TARGET_64BIT && INTVAL (operands[2]) != 32)
+    FAIL;
+
+  /* MIPS III and MIPS IV can handle both 32bit and 64bit fields.  */
+  if (TARGET_64BIT
+      && INTVAL (operands[2]) != 64
+      && INTVAL (operands[2]) != 32)
     FAIL;
 
   /* This can happen for a 64 bit target, when extracting a value from
@@ -4281,21 +4308,42 @@ move\\t%0,%z4\\n\\
   operands[1] = change_address (operands[1], BLKmode, XEXP (operands[1], 0));
 
   /* Otherwise, emit a lwl/lwr pair to load the value.  */
-  emit_insn (gen_movsi_ulw (operands[0], operands[1]));
+  if (INTVAL (operands[2]) == 64)
+    emit_insn (gen_movdi_uld (operands[0], operands[1]));
+  else
+    {
+      if (TARGET_64BIT)
+       {
+         operands[0] = gen_lowpart (SImode, operands[0]);
+         if (operands[0] == NULL_RTX)
+           FAIL;
+       }
+      emit_insn (gen_movsi_ulw (operands[0], operands[1]));
+    }
   DONE;
 }")
 
+;; Only specify the mode operands 0, the rest are assumed to be word_mode.
 (define_expand "insv"
-  [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "")
-                        (match_operand:SI 1 "immediate_operand" "")
-                        (match_operand:SI 2 "immediate_operand" ""))
-       (match_operand:SI 3 "register_operand" ""))]
+  [(set (zero_extract (match_operand:QI 0 "memory_operand" "")
+                     (match_operand 1 "immediate_operand" "")
+                     (match_operand 2 "immediate_operand" ""))
+       (match_operand 3 "register_operand" ""))]
   "!TARGET_MIPS16"
   "
 {
-  /* If this isn't a 32 bit field, and it doesn't start on a byte boundary
-     then fail.  */
-  if (INTVAL (operands[1]) != 32 || (INTVAL (operands[2]) % 8) != 0)
+  /* If the field does not start on a byte boundary, then fail.  */
+  if (INTVAL (operands[2]) % 8 != 0) 
+    FAIL;
+
+  /* MIPS I and MIPS II can only handle a 32bit field.  */
+  if (!TARGET_64BIT && INTVAL (operands[1]) != 32)
+    FAIL;
+
+  /* MIPS III and MIPS IV can handle both 32bit and 64bit fields.  */
+  if (TARGET_64BIT
+      && INTVAL (operands[1]) != 64
+      && INTVAL (operands[1]) != 32)
     FAIL;
 
   /* This can happen for a 64 bit target, when storing into a 32 bit union
@@ -4307,8 +4355,19 @@ move\\t%0,%z4\\n\\
   /* Change the mode to BLKmode for aliasing purposes.  */
   operands[0] = change_address (operands[0], BLKmode, XEXP (operands[0], 0));
 
-  /* Otherwise, emit a swl/swr pair to load the value.  */
-  emit_insn (gen_movsi_usw (operands[0], operands[3]));
+  /* Otherwise, emit a s[wd]l/s[wd]r pair to load the value.  */
+  if (INTVAL (operands[1]) == 64)
+    emit_insn (gen_movdi_usd (operands[0], operands[3]));
+  else
+    {
+      if (TARGET_64BIT)
+       {
+         operands[3] = gen_lowpart (SImode, operands[3]);
+         if (operands[3] == NULL_RTX)
+           FAIL;
+       }
+      emit_insn (gen_movsi_usw (operands[0], operands[3]));
+    }
   DONE;
 }")
 
@@ -4369,6 +4428,65 @@ move\\t%0,%z4\\n\\
    (set_attr "mode"    "SI")
    (set_attr "length"  "2,4")])
 
+;; Bit field extract patterns which use ldl/ldr.
+
+;; unaligned double word moves generated by the bit field patterns
+
+(define_insn "movdi_uld"
+  [(set (match_operand:DI 0 "register_operand" "=&d,&d")
+       (unspec:DI [(match_operand:BLK 1 "general_operand" "R,o")] 0))]
+  ""
+  "*
+{
+  rtx offset = const0_rtx;
+  rtx addr = XEXP (operands[1], 0);
+  rtx mem_addr = eliminate_constant_term (addr, &offset);
+  char *ret;
+
+  if (TARGET_STATS)
+    mips_count_memory_refs (operands[1], 2);
+
+  /* The stack/frame pointers are always aligned, so we can convert
+     to the faster lw if we are referencing an aligned stack location.  */
+
+  if ((INTVAL (offset) & 7) == 0
+      && (mem_addr == stack_pointer_rtx || mem_addr == frame_pointer_rtx))
+    ret = \"ld\\t%0,%1\";
+  else
+    ret = \"uld\\t%0,%1\";
+
+  return mips_fill_delay_slot (ret, DELAY_LOAD, operands, insn);
+}"
+  [(set_attr "type"    "load,load")
+   (set_attr "mode"    "SI")
+   (set_attr "length"  "2,4")])
+
+(define_insn "movdi_usd"
+  [(set (match_operand:BLK 0 "memory_operand" "=R,o")
+       (unspec:BLK [(match_operand:DI 1 "reg_or_0_operand" "dJ,dJ")] 1))]
+  ""
+  "*
+{
+  rtx offset = const0_rtx;
+  rtx addr = XEXP (operands[0], 0);
+  rtx mem_addr = eliminate_constant_term (addr, &offset);
+
+  if (TARGET_STATS)
+    mips_count_memory_refs (operands[0], 2);
+
+  /* The stack/frame pointers are always aligned, so we can convert
+     to the faster sw if we are referencing an aligned stack location.  */
+
+  if ((INTVAL (offset) & 7) == 0
+      && (mem_addr == stack_pointer_rtx || mem_addr == frame_pointer_rtx))
+    return \"sd\\t%1,%0\";
+
+  return \"usd\\t%z1,%0\";
+}"
+  [(set_attr "type"    "store")
+   (set_attr "mode"    "SI")
+   (set_attr "length"  "2,4")])
+
 ;; These two patterns support loading addresses with two instructions instead
 ;; of using the macro instruction la.
 
index c6efd62..730d904 100644 (file)
@@ -211,10 +211,10 @@ negate_rtx (mode, x)
 /* ??? Note that there are two different ideas here for how
    to determine the size to count bits within, for a register.
    One is BITS_PER_WORD, and the other is the size of operand 3
-   of the insv pattern.  (The latter assumes that an n-bit machine
-   will be able to insert bit fields up to n bits wide.)
-   It isn't certain that either of these is right.
-   extract_bit_field has the same quandary.  */
+   of the insv pattern.
+
+   If operand 3 of the insv pattern is VOIDmode, then we will use BITS_PER_WORD
+   else, we use the mode of operand 3.  */
 
 rtx
 store_bit_field (str_rtx, bitsize, bitnum, fieldmode, value, align, total_size)
@@ -230,6 +230,14 @@ store_bit_field (str_rtx, bitsize, bitnum, fieldmode, value, align, total_size)
   register int offset = bitnum / unit;
   register int bitpos = bitnum % unit;
   register rtx op0 = str_rtx;
+#ifdef HAVE_insv
+  int insv_bitsize;
+
+  if (insn_operand_mode[(int) CODE_FOR_insv][3] == VOIDmode)
+    insv_bitsize = GET_MODE_BITSIZE (word_mode);
+  else
+    insv_bitsize = GET_MODE_BITSIZE (insn_operand_mode[(int) CODE_FOR_insv][3]);
+#endif
 
   if (GET_CODE (str_rtx) == MEM && ! MEM_IN_STRUCT_P (str_rtx))
     abort ();
@@ -400,21 +408,22 @@ store_bit_field (str_rtx, bitsize, bitnum, fieldmode, value, align, total_size)
       && GET_MODE (value) != BLKmode
       && !(bitsize == 1 && GET_CODE (value) == CONST_INT)
       /* Ensure insv's size is wide enough for this field.  */
-      && (GET_MODE_BITSIZE (insn_operand_mode[(int) CODE_FOR_insv][3])
-         >= bitsize)
+      && (insv_bitsize >= bitsize)
       && ! ((GET_CODE (op0) == REG || GET_CODE (op0) == SUBREG)
-           && (bitsize + bitpos
-               > GET_MODE_BITSIZE (insn_operand_mode[(int) CODE_FOR_insv][3]))))
+           && (bitsize + bitpos > insv_bitsize)))
     {
       int xbitpos = bitpos;
       rtx value1;
       rtx xop0 = op0;
       rtx last = get_last_insn ();
       rtx pat;
-      enum machine_mode maxmode
-       = insn_operand_mode[(int) CODE_FOR_insv][3];
-
+      enum machine_mode maxmode;
       int save_volatile_ok = volatile_ok;
+
+      maxmode = insn_operand_mode[(int) CODE_FOR_insv][3];
+      if (maxmode == VOIDmode)
+       maxmode = word_mode;
+
       volatile_ok = 1;
 
       /* If this machine's insv can only insert into a register, copy OP0
@@ -894,6 +903,27 @@ extract_bit_field (str_rtx, bitsize, bitnum, unsignedp,
   register rtx op0 = str_rtx;
   rtx spec_target = target;
   rtx spec_target_subreg = 0;
+#ifdef HAVE_extv
+  int extv_bitsize;
+#endif
+#ifdef HAVE_extzv
+  int extzv_bitsize;
+#endif
+
+#ifdef HAVE_extv
+  if (insn_operand_mode[(int) CODE_FOR_extv][0] == VOIDmode)
+    extv_bitsize = GET_MODE_BITSIZE (word_mode);
+  else
+    extv_bitsize = GET_MODE_BITSIZE (insn_operand_mode[(int) CODE_FOR_extv][0]);
+#endif
+
+#ifdef HAVE_extzv
+  if (insn_operand_mode[(int) CODE_FOR_extzv][0] == VOIDmode)
+    extzv_bitsize = GET_MODE_BITSIZE (word_mode);
+  else
+    extzv_bitsize
+      = GET_MODE_BITSIZE (insn_operand_mode[(int) CODE_FOR_extzv][0]);
+#endif
 
   /* Discount the part of the structure before the desired byte.
      We need to know how many bytes are safe to reference after it.  */
@@ -1073,11 +1103,9 @@ extract_bit_field (str_rtx, bitsize, bitnum, unsignedp,
     {
 #ifdef HAVE_extzv
       if (HAVE_extzv
-         && (GET_MODE_BITSIZE (insn_operand_mode[(int) CODE_FOR_extzv][0])
-             >= bitsize)
+         && (extzv_bitsize >= bitsize)
          && ! ((GET_CODE (op0) == REG || GET_CODE (op0) == SUBREG)
-               && (bitsize + bitpos
-                   > GET_MODE_BITSIZE (insn_operand_mode[(int) CODE_FOR_extzv][0]))))
+               && (bitsize + bitpos > extzv_bitsize)))
        {
          int xbitpos = bitpos, xoffset = offset;
          rtx bitsize_rtx, bitpos_rtx;
@@ -1087,8 +1115,11 @@ extract_bit_field (str_rtx, bitsize, bitnum, unsignedp,
          rtx xspec_target = spec_target;
          rtx xspec_target_subreg = spec_target_subreg;
          rtx pat;
-         enum machine_mode maxmode
-           = insn_operand_mode[(int) CODE_FOR_extzv][0];
+         enum machine_mode maxmode;
+
+         maxmode = insn_operand_mode[(int) CODE_FOR_extzv][0];
+         if (maxmode == VOIDmode)
+           maxmode = word_mode;
 
          if (GET_CODE (xop0) == MEM)
            {
@@ -1213,11 +1244,9 @@ extract_bit_field (str_rtx, bitsize, bitnum, unsignedp,
     {
 #ifdef HAVE_extv
       if (HAVE_extv
-         && (GET_MODE_BITSIZE (insn_operand_mode[(int) CODE_FOR_extv][0])
-             >= bitsize)
+         && (extv_bitsize >= bitsize)
          && ! ((GET_CODE (op0) == REG || GET_CODE (op0) == SUBREG)
-               && (bitsize + bitpos
-                   > GET_MODE_BITSIZE (insn_operand_mode[(int) CODE_FOR_extv][0]))))
+               && (bitsize + bitpos > extv_bitsize)))
        {
          int xbitpos = bitpos, xoffset = offset;
          rtx bitsize_rtx, bitpos_rtx;
@@ -1226,8 +1255,11 @@ extract_bit_field (str_rtx, bitsize, bitnum, unsignedp,
          rtx xspec_target = spec_target;
          rtx xspec_target_subreg = spec_target_subreg;
          rtx pat;
-         enum machine_mode maxmode
-           = insn_operand_mode[(int) CODE_FOR_extv][0];
+         enum machine_mode maxmode;
+
+         maxmode = insn_operand_mode[(int) CODE_FOR_extv][0];
+         if (maxmode == VOIDmode)
+           maxmode = word_mode;
 
          if (GET_CODE (xop0) == MEM)
            {
index a5f8f05..c75648d 100644 (file)
@@ -1975,11 +1975,19 @@ fixup_var_refs_1 (var, promoted_mode, loc, insn, replacements)
 
 #ifdef HAVE_extzv
              if (GET_CODE (x) == ZERO_EXTRACT)
-               wanted_mode = insn_operand_mode[(int) CODE_FOR_extzv][1];
+               {
+                 wanted_mode = insn_operand_mode[(int) CODE_FOR_extzv][1];
+                 if (wanted_mode == VOIDmode)
+                   wanted_mode = word_mode;
+               }
 #endif
 #ifdef HAVE_extv
              if (GET_CODE (x) == SIGN_EXTRACT)
-               wanted_mode = insn_operand_mode[(int) CODE_FOR_extv][1];
+               {
+                 wanted_mode = insn_operand_mode[(int) CODE_FOR_extv][1];
+                 if (wanted_mode == VOIDmode)
+                   wanted_mode = word_mode;
+               }
 #endif
              /* If we have a narrower mode, we can do something.  */
              if (wanted_mode != VOIDmode
@@ -2168,11 +2176,14 @@ fixup_var_refs_1 (var, promoted_mode, loc, insn, replacements)
                && ! mode_dependent_address_p (XEXP (tem, 0))
                && ! MEM_VOLATILE_P (tem))
              {
-               enum machine_mode wanted_mode
-                 = insn_operand_mode[(int) CODE_FOR_insv][0];
+               enum machine_mode wanted_mode;
                enum machine_mode is_mode = GET_MODE (tem);
                HOST_WIDE_INT pos = INTVAL (XEXP (outerdest, 2));
 
+               wanted_mode = insn_operand_mode[(int) CODE_FOR_insv][0];
+               if (wanted_mode == VOIDmode)
+                 wanted_mode = word_mode;
+
                /* If we have a narrower mode, we can do something.  */
                if (GET_MODE_SIZE (wanted_mode) < GET_MODE_SIZE (is_mode))
                  {
index d472df0..9f6a1ea 100644 (file)
@@ -484,11 +484,19 @@ validate_replace_rtx_1 (loc, from, to, object)
 
 #ifdef HAVE_extzv
          if (code == ZERO_EXTRACT)
-           wanted_mode = insn_operand_mode[(int) CODE_FOR_extzv][1];
+           {
+             wanted_mode = insn_operand_mode[(int) CODE_FOR_extzv][1];
+             if (wanted_mode == VOIDmode)
+               wanted_mode = word_mode;
+           }
 #endif
 #ifdef HAVE_extv
          if (code == SIGN_EXTRACT)
-           wanted_mode = insn_operand_mode[(int) CODE_FOR_extv][1];
+           {
+             wanted_mode = insn_operand_mode[(int) CODE_FOR_extv][1];
+             if (wanted_mode == VOIDmode)
+               wanted_mode = word_mode;
+           }
 #endif
 
          /* If we have a narrower mode, we can do something.  */