aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Sandiford <richard.sandiford@linaro.org>2017-08-30 11:14:59 +0000
committerRichard Sandiford <rsandifo@gcc.gnu.org>2017-08-30 11:14:59 +0000
commit5602f58c633e51b03b5f18bbd65924b4b842d075 (patch)
treed8955268a1ac99ffbf94233ae93e5a60a4f5595a /gcc
parentae9270466ed530df375bcaf6b3d834dbef6e3965 (diff)
downloadgcc-5602f58c633e51b03b5f18bbd65924b4b842d075.zip
gcc-5602f58c633e51b03b5f18bbd65924b4b842d075.tar.gz
gcc-5602f58c633e51b03b5f18bbd65924b4b842d075.tar.bz2
[40/77] Use scalar_int_mode for extraction_insn fields
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog15
-rw-r--r--gcc/combine.c2
-rw-r--r--gcc/expmed.c30
-rw-r--r--gcc/optabs-query.c26
-rw-r--r--gcc/optabs-query.h9
-rw-r--r--gcc/recog.c21
6 files changed, 62 insertions, 41 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index ac44251..be66c5d 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -2,6 +2,21 @@
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>
+
* machmode.h (bit_field_mode_iterator::next_mode): Take a pointer
to a scalar_int_mode instead of a machine_mode.
(bit_field_mode_iterator::m_mode): Change type to opt_scalar_int_mode.
diff --git a/gcc/combine.c b/gcc/combine.c
index 930c0e5..25e6831 100644
--- a/gcc/combine.c
+++ b/gcc/combine.c
@@ -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;
}
diff --git a/gcc/expmed.c b/gcc/expmed.c
index 641bc24..dabde4e 100644
--- a/gcc/expmed.c
+++ b/gcc/expmed.c
@@ -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);
}
}
diff --git a/gcc/optabs-query.c b/gcc/optabs-query.c
index 48b1250..b4a4976 100644
--- a/gcc/optabs-query.c
+++ b/gcc/optabs-query.c
@@ -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;
}
diff --git a/gcc/optabs-query.h b/gcc/optabs-query.h
index e85a7f1..1612fc8 100644
--- a/gcc/optabs-query.h
+++ b/gcc/optabs-query.h
@@ -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 *,
diff --git a/gcc/recog.c b/gcc/recog.c
index 0f9d240..4a54e88 100644
--- a/gcc/recog.c
+++ b/gcc/recog.c
@@ -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;