[40/77] Use scalar_int_mode for extraction_insn fields
authorRichard Sandiford <richard.sandiford@linaro.org>
Wed, 30 Aug 2017 11:14:59 +0000 (11:14 +0000)
committerRichard Sandiford <rsandifo@gcc.gnu.org>
Wed, 30 Aug 2017 11:14:59 +0000 (11:14 +0000)
insv, extv and eztzv modify or read a field in a register or
memory.  The field always has a scalar integer mode, while the
register or memory either has a scalar integer mode or BLKmode.
The mode of the bit position is also a scalar integer.

This patch uses the type system to make that explicit.

2017-08-30  Richard Sandiford  <richard.sandiford@linaro.org>
    Alan Hayward  <alan.hayward@arm.com>
    David Sherwood  <david.sherwood@arm.com>

gcc/
* optabs-query.h (extraction_insn::struct_mode): Change type to
opt_scalar_int_mode and update comment.
(extraction_insn::field_mode): Change type to scalar_int_mode.
(extraction_insn::pos_mode): Likewise.
* combine.c (make_extraction): Update accordingly.
* optabs-query.c (get_traditional_extraction_insn): Likewise.
(get_optab_extraction_insn): Likewise.
* recog.c (simplify_while_replacing): Likewise.
* expmed.c (narrow_bit_field_mem): Change the type of the mode
parameter to opt_scalar_int_mode.

Co-Authored-By: Alan Hayward <alan.hayward@arm.com>
Co-Authored-By: David Sherwood <david.sherwood@arm.com>
From-SVN: r251492

gcc/ChangeLog
gcc/combine.c
gcc/expmed.c
gcc/optabs-query.c
gcc/optabs-query.h
gcc/recog.c

index ac4425102014d3b79d71430a47cc9283be0826ea..be66c5dfcc7c5c14b7df887d72ca6fd8d7eb7c16 100644 (file)
@@ -1,3 +1,18 @@
+2017-08-30  Richard Sandiford  <richard.sandiford@linaro.org>
+           Alan Hayward  <alan.hayward@arm.com>
+           David Sherwood  <david.sherwood@arm.com>
+
+       * optabs-query.h (extraction_insn::struct_mode): Change type to
+       opt_scalar_int_mode and update comment.
+       (extraction_insn::field_mode): Change type to scalar_int_mode.
+       (extraction_insn::pos_mode): Likewise.
+       * combine.c (make_extraction): Update accordingly.
+       * optabs-query.c (get_traditional_extraction_insn): Likewise.
+       (get_optab_extraction_insn): Likewise.
+       * recog.c (simplify_while_replacing): Likewise.
+       * expmed.c (narrow_bit_field_mem): Change the type of the mode
+       parameter to opt_scalar_int_mode.
+
 2017-08-30  Richard Sandiford  <richard.sandiford@linaro.org>
            Alan Hayward  <alan.hayward@arm.com>
            David Sherwood  <david.sherwood@arm.com>
index 930c0e5d277a33561cd5059e4611234e15d66faf..25e68313167d7e901e16c0f8efc3b2b01754cda1 100644 (file)
@@ -7619,7 +7619,7 @@ make_extraction (machine_mode mode, rtx inner, HOST_WIDE_INT pos,
   if (get_best_reg_extraction_insn (&insn, pattern,
                                    GET_MODE_BITSIZE (inner_mode), mode))
     {
-      wanted_inner_reg_mode = insn.struct_mode;
+      wanted_inner_reg_mode = insn.struct_mode.require ();
       pos_mode = insn.pos_mode;
       extraction_mode = insn.field_mode;
     }
index 641bc244a30f1df55b01513f31449f081c74c4d4..dabde4e53ff74f4283a88e7f6a5fa3cba18d67a2 100644 (file)
@@ -411,31 +411,33 @@ flip_storage_order (machine_mode mode, rtx x)
   return result;
 }
 
-/* Adjust bitfield memory MEM so that it points to the first unit of mode
-   MODE that contains a bitfield of size BITSIZE at bit position BITNUM.
-   If MODE is BLKmode, return a reference to every byte in the bitfield.
-   Set *NEW_BITNUM to the bit position of the field within the new memory.  */
+/* If MODE is set, adjust bitfield memory MEM so that it points to the
+   first unit of mode MODE that contains a bitfield of size BITSIZE at
+   bit position BITNUM.  If MODE is not set, return a BLKmode reference
+   to every byte in the bitfield.  Set *NEW_BITNUM to the bit position
+   of the field within the new memory.  */
 
 static rtx
-narrow_bit_field_mem (rtx mem, machine_mode mode,
+narrow_bit_field_mem (rtx mem, opt_scalar_int_mode mode,
                      unsigned HOST_WIDE_INT bitsize,
                      unsigned HOST_WIDE_INT bitnum,
                      unsigned HOST_WIDE_INT *new_bitnum)
 {
-  if (mode == BLKmode)
+  scalar_int_mode imode;
+  if (mode.exists (&imode))
+    {
+      unsigned int unit = GET_MODE_BITSIZE (imode);
+      *new_bitnum = bitnum % unit;
+      HOST_WIDE_INT offset = (bitnum - *new_bitnum) / BITS_PER_UNIT;
+      return adjust_bitfield_address (mem, imode, offset);
+    }
+  else
     {
       *new_bitnum = bitnum % BITS_PER_UNIT;
       HOST_WIDE_INT offset = bitnum / BITS_PER_UNIT;
       HOST_WIDE_INT size = ((*new_bitnum + bitsize + BITS_PER_UNIT - 1)
                            / BITS_PER_UNIT);
-      return adjust_bitfield_address_size (mem, mode, offset, size);
-    }
-  else
-    {
-      unsigned int unit = GET_MODE_BITSIZE (mode);
-      *new_bitnum = bitnum % unit;
-      HOST_WIDE_INT offset = (bitnum - *new_bitnum) / BITS_PER_UNIT;
-      return adjust_bitfield_address (mem, mode, offset);
+      return adjust_bitfield_address_size (mem, BLKmode, offset, size);
     }
 }
 
index 48b1250bda24fda4443aa2f1b343636c6092fc32..b4a4976350d5fa39a03697ddee9770127ea5d49e 100644 (file)
@@ -100,9 +100,14 @@ get_traditional_extraction_insn (extraction_insn *insn,
     pos_mode = word_mode;
 
   insn->icode = icode;
-  insn->field_mode = field_mode;
-  insn->struct_mode = (type == ET_unaligned_mem ? byte_mode : struct_mode);
-  insn->pos_mode = pos_mode;
+  insn->field_mode = as_a <scalar_int_mode> (field_mode);
+  if (type == ET_unaligned_mem)
+    insn->struct_mode = byte_mode;
+  else if (struct_mode == BLKmode)
+    insn->struct_mode = opt_scalar_int_mode ();
+  else
+    insn->struct_mode = as_a <scalar_int_mode> (struct_mode);
+  insn->pos_mode = as_a <scalar_int_mode> (pos_mode);
   return true;
 }
 
@@ -126,12 +131,17 @@ get_optab_extraction_insn (struct extraction_insn *insn,
 
   const struct insn_data_d *data = &insn_data[icode];
 
+  machine_mode pos_mode = data->operand[pos_op].mode;
+  if (pos_mode == VOIDmode)
+    pos_mode = word_mode;
+
   insn->icode = icode;
-  insn->field_mode = mode;
-  insn->struct_mode = (type == ET_unaligned_mem ? BLKmode : mode);
-  insn->pos_mode = data->operand[pos_op].mode;
-  if (insn->pos_mode == VOIDmode)
-    insn->pos_mode = word_mode;
+  insn->field_mode = as_a <scalar_int_mode> (mode);
+  if (type == ET_unaligned_mem)
+    insn->struct_mode = opt_scalar_int_mode ();
+  else
+    insn->struct_mode = insn->field_mode;
+  insn->pos_mode = as_a <scalar_int_mode> (pos_mode);
   return true;
 }
 
index e85a7f11b95905295cc35107ad9538934e22de76..1612fc80a03ef96982e1e3df55f20aaca3cddfc3 100644 (file)
@@ -141,16 +141,17 @@ struct extraction_insn
   enum insn_code icode;
 
   /* The mode that the structure operand should have.  This is byte_mode
-     when using the legacy insv, extv and extzv patterns to access memory.  */
-  machine_mode struct_mode;
+     when using the legacy insv, extv and extzv patterns to access memory.
+     If no mode is given, the structure is a BLKmode memory.  */
+  opt_scalar_int_mode struct_mode;
 
   /* The mode of the field to be inserted or extracted, and by extension
      the mode of the insertion or extraction itself.  */
-  machine_mode field_mode;
+  scalar_int_mode field_mode;
 
   /* The mode of the field's bit position.  This is only important
      when the position is variable rather than constant.  */
-  machine_mode pos_mode;
+  scalar_int_mode pos_mode;
 };
 
 bool get_best_reg_extraction_insn (extraction_insn *,
index 0f9d240931c4faccca4d06526496fbd9dd256e4b..4a54e88f5e8b0c76a99865536592c0f39dad396e 100644 (file)
@@ -663,25 +663,18 @@ simplify_while_replacing (rtx *loc, rtx to, rtx_insn *object,
                                        MEM_ADDR_SPACE (XEXP (x, 0)))
          && !MEM_VOLATILE_P (XEXP (x, 0)))
        {
-         machine_mode wanted_mode = VOIDmode;
          int pos = INTVAL (XEXP (x, 2));
-
+         machine_mode new_mode = is_mode;
          if (GET_CODE (x) == ZERO_EXTRACT && targetm.have_extzv ())
-           {
-             wanted_mode = insn_data[targetm.code_for_extzv].operand[1].mode;
-             if (wanted_mode == VOIDmode)
-               wanted_mode = word_mode;
-           }
+           new_mode = insn_data[targetm.code_for_extzv].operand[1].mode;
          else if (GET_CODE (x) == SIGN_EXTRACT && targetm.have_extv ())
-           {
-             wanted_mode = insn_data[targetm.code_for_extv].operand[1].mode;
-             if (wanted_mode == VOIDmode)
-               wanted_mode = word_mode;
-           }
+           new_mode = insn_data[targetm.code_for_extv].operand[1].mode;
+         scalar_int_mode wanted_mode = (new_mode == VOIDmode
+                                        ? word_mode
+                                        : as_a <scalar_int_mode> (new_mode));
 
          /* If we have a narrower mode, we can do something.  */
-         if (wanted_mode != VOIDmode
-             && GET_MODE_SIZE (wanted_mode) < GET_MODE_SIZE (is_mode))
+         if (GET_MODE_SIZE (wanted_mode) < GET_MODE_SIZE (is_mode))
            {
              int offset = pos / BITS_PER_UNIT;
              rtx newmem;