From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 126988 invoked by alias); 9 Dec 2016 13:19:30 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Received: (qmail 126970 invoked by uid 89); 9 Dec 2016 13:19:30 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-4.9 required=5.0 tests=BAYES_00,RP_MATCHES_RCVD,SPF_PASS autolearn=ham version=3.3.2 spammy= X-HELO: foss.arm.com Received: from foss.arm.com (HELO foss.arm.com) (217.140.101.70) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Fri, 09 Dec 2016 13:19:22 +0000 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.72.51.249]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id BA050707; Fri, 9 Dec 2016 05:19:20 -0800 (PST) Received: from localhost (e105548-lin.manchester.arm.com [10.45.32.67]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 63FA33F477 for ; Fri, 9 Dec 2016 05:19:20 -0800 (PST) From: Richard Sandiford To: gcc-patches@gcc.gnu.org Mail-Followup-To: gcc-patches@gcc.gnu.org, richard.sandiford@arm.com Subject: [40/67] Use scalar_int_mode for extraction_insn fields References: <87h96dp8u6.fsf@e105548-lin.cambridge.arm.com> Date: Fri, 09 Dec 2016 13:19:00 -0000 In-Reply-To: <87h96dp8u6.fsf@e105548-lin.cambridge.arm.com> (Richard Sandiford's message of "Fri, 09 Dec 2016 12:48:01 +0000") Message-ID: <87oa0li6jt.fsf@e105548-lin.cambridge.arm.com> User-Agent: Gnus/5.130012 (Ma Gnus v0.12) Emacs/24.3 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain X-SW-Source: 2016-12/txt/msg00812.txt.bz2 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. gcc/ 2016-11-24 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): Chane the type of the mode parameter to opt_scalar_int_mode. diff --git a/gcc/combine.c b/gcc/combine.c index 0f25782..449f371 100644 --- a/gcc/combine.c +++ b/gcc/combine.c @@ -7608,7 +7608,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; pos_mode = insn.pos_mode; extraction_mode = insn.field_mode; } diff --git a/gcc/expmed.c b/gcc/expmed.c index 0b2e61a..71e1fa8 100644 --- a/gcc/expmed.c +++ b/gcc/expmed.c @@ -409,31 +409,32 @@ 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) + if (mode.exists ()) + { + 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); + } + 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 e664587..6541f07 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 840dc79..58fbf13 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 317ec29..906a5b0 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;