From 5602f58c633e51b03b5f18bbd65924b4b842d075 Mon Sep 17 00:00:00 2001 From: Richard Sandiford Date: Wed, 30 Aug 2017 11:14:59 +0000 Subject: [PATCH] [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 Alan Hayward David Sherwood 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 Co-Authored-By: David Sherwood From-SVN: r251492 --- gcc/ChangeLog | 15 +++++++++++++++ gcc/combine.c | 2 +- gcc/expmed.c | 30 ++++++++++++++++-------------- gcc/optabs-query.c | 26 ++++++++++++++++++-------- gcc/optabs-query.h | 9 +++++---- gcc/recog.c | 21 +++++++-------------- 6 files changed, 62 insertions(+), 41 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index ac442510201..be66c5dfcc7 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,18 @@ +2017-08-30 Richard Sandiford + Alan Hayward + David Sherwood + + * 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 Alan Hayward David Sherwood diff --git a/gcc/combine.c b/gcc/combine.c index 930c0e5d277..25e68313167 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 641bc244a30..dabde4e53ff 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 48b1250bda2..b4a4976350d 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 (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 (struct_mode); + insn->pos_mode = as_a (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 (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 (pos_mode); return true; } diff --git a/gcc/optabs-query.h b/gcc/optabs-query.h index e85a7f11b95..1612fc80a03 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 0f9d240931c..4a54e88f5e8 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 (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; -- 2.30.2