From patchwork Sat Nov 3 11:16:52 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Sandiford X-Patchwork-Id: 196821 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) by ozlabs.org (Postfix) with SMTP id 702072C00B2 for ; Sat, 3 Nov 2012 22:16:59 +1100 (EST) Comment: DKIM? See http://www.dkim.org DKIM-Signature: v=1; a=rsa-sha1; c=relaxed/relaxed; d=gcc.gnu.org; s=default; x=1352546220; h=Comment: DomainKey-Signature:Received:Received:Received:Received:Received: Received:From:To:Mail-Followup-To:Subject:References:Date: In-Reply-To:Message-ID:User-Agent:MIME-Version:Content-Type: Mailing-List:Precedence:List-Id:List-Unsubscribe:List-Archive: List-Post:List-Help:Sender:Delivered-To; bh=mL+JWRZWDW/7ERSsWT62 B3fgmWM=; b=bl3z0OIrel6bO8jNCSDk7cPx8ZgpeEyrkL/T3hPKPC999ToW06JN EPFWdPv3NeJCDP5d5oWsq8gSxF/R8Js5i7ZPrcONrS351Tms5eq3aK1ry8l9HC2z sRka0Il7i1hhemmrgk13Y8tpfs/DI+3xLxlr/PJuBuJ8UsxXT5pnbrA= Comment: DomainKeys? See http://antispam.yahoo.com/domainkeys DomainKey-Signature: a=rsa-sha1; q=dns; c=nofws; s=default; d=gcc.gnu.org; h=Received:Received:X-SWARE-Spam-Status:X-Spam-Check-By:Received:Received:Received:Received:From:To:Mail-Followup-To:Subject:References:Date:In-Reply-To:Message-ID:User-Agent:MIME-Version:Content-Type:Mailing-List:Precedence:List-Id:List-Unsubscribe:List-Archive:List-Post:List-Help:Sender:Delivered-To; b=B96hDMn6Z7PlUssK0w3hVPE6P0szYhZ9iC83rS745sLn+97uNI6Yh9Mqt58K0k tnif63s7XgtDvnyiCS3vV8bVMKbv+pk1c5EL8R0lnxotqLYzWuQjgPmJ+IEZlrkw CBHqPZmn6erpPa8eAJZCg5FC7rIxFx3/lTm5TG/QZP8sU=; Received: (qmail 2645 invoked by alias); 3 Nov 2012 11:16:56 -0000 Received: (qmail 2636 invoked by uid 22791); 3 Nov 2012 11:16:56 -0000 X-SWARE-Spam-Status: No, hits=-3.6 required=5.0 tests=AWL, BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, DKIM_VALID, FREEMAIL_FROM, KHOP_RCVD_TRUST, KHOP_SPAMHAUS_DROP, NML_ADSP_CUSTOM_MED, RCVD_IN_DNSWL_LOW, RCVD_IN_HOSTKARMA_YE X-Spam-Check-By: sourceware.org Received: from mail-wi0-f169.google.com (HELO mail-wi0-f169.google.com) (209.85.212.169) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Sat, 03 Nov 2012 11:16:50 +0000 Received: by mail-wi0-f169.google.com with SMTP id hq4so1742312wib.2 for ; Sat, 03 Nov 2012 04:16:49 -0700 (PDT) Received: by 10.216.202.218 with SMTP id d68mr1587492weo.153.1351941408996; Sat, 03 Nov 2012 04:16:48 -0700 (PDT) Received: from localhost ([2.26.192.222]) by mx.google.com with ESMTPS id v9sm1939682wif.10.2012.11.03.04.16.47 (version=TLSv1/SSLv3 cipher=OTHER); Sat, 03 Nov 2012 04:16:48 -0700 (PDT) From: Richard Sandiford To: gcc-patches@gcc.gnu.org Mail-Followup-To: gcc-patches@gcc.gnu.org, rdsandiford@googlemail.com Subject: [3/8] Add narrow_bit_field_mem References: <87k3u3eybu.fsf@talisman.home> Date: Sat, 03 Nov 2012 11:16:52 +0000 In-Reply-To: <87k3u3eybu.fsf@talisman.home> (Richard Sandiford's message of "Sat, 03 Nov 2012 11:10:45 +0000") Message-ID: <877gq3ey1n.fsf@talisman.home> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/23.3 (gnu/linux) MIME-Version: 1.0 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org This patch is the return of narrow_bit_field_mem, originally posted as part of the preliminary patches. This time I've used a pointer rather than a reference for the final parameter. (I agree consistency is good.) The new version also takes the size of the field as a parameter and handles BLKmode references. Tested as described in the covering note. OK to install? Richard gcc/ * expmed.c (narrow_bit_field_mem): New function. (store_bit_field_using_insv, store_bit_field_1, store_fixed_bit_field) (extract_bit_field_1): Use it. Index: gcc/expmed.c =================================================================== --- gcc/expmed.c 2012-11-01 19:43:32.376371670 +0000 +++ gcc/expmed.c 2012-11-01 19:54:15.978370095 +0000 @@ -387,6 +387,34 @@ mode_for_extraction (enum extraction_pat return data->operand[opno].mode; } +/* 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. */ + +static rtx +narrow_bit_field_mem (rtx mem, enum machine_mode mode, + unsigned HOST_WIDE_INT bitsize, + unsigned HOST_WIDE_INT bitnum, + unsigned HOST_WIDE_INT *new_bitnum) +{ + if (mode == BLKmode) + { + *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 true if a bitfield of size BITSIZE at bit number BITNUM within a structure of mode STRUCT_MODE represents a lowpart subreg. The subreg offset is then BITNUM / BITS_PER_UNIT. */ @@ -424,11 +452,8 @@ store_bit_field_using_insv (rtx op0, uns return false; if (MEM_P (xop0)) - { - /* Get a reference to the first byte of the field. */ - xop0 = adjust_bitfield_address (xop0, byte_mode, bitnum / BITS_PER_UNIT); - bitnum %= BITS_PER_UNIT; - } + /* Get a reference to the first byte of the field. */ + xop0 = narrow_bit_field_mem (xop0, byte_mode, bitsize, bitnum, &bitnum); else { /* Convert from counting within OP0 to counting in OP_MODE. */ @@ -831,18 +856,15 @@ store_bit_field_1 (rtx str_rtx, unsigned && GET_MODE_BITSIZE (bestmode) > MEM_ALIGN (op0))) { rtx last, tempreg, xop0; - unsigned int unit; - unsigned HOST_WIDE_INT offset, bitpos; + unsigned HOST_WIDE_INT bitpos; last = get_last_insn (); /* Adjust address to point to the containing unit of that mode. Compute the offset as a multiple of this unit, counting in bytes. */ - unit = GET_MODE_BITSIZE (bestmode); - offset = (bitnum / unit) * GET_MODE_SIZE (bestmode); - bitpos = bitnum % unit; - xop0 = adjust_bitfield_address (op0, bestmode, offset); + xop0 = narrow_bit_field_mem (op0, bestmode, bitsize, bitnum, + &bitpos); /* Fetch that unit, store the bitfield in it, then store the unit. */ @@ -975,9 +997,7 @@ store_fixed_bit_field (rtx op0, unsigned return; } - HOST_WIDE_INT bit_offset = bitnum - bitnum % GET_MODE_BITSIZE (mode); - op0 = adjust_bitfield_address (op0, mode, bit_offset / BITS_PER_UNIT); - bitnum -= bit_offset; + op0 = narrow_bit_field_mem (op0, mode, bitsize, bitnum, &bitnum); } mode = GET_MODE (op0); @@ -1246,11 +1266,8 @@ extract_bit_field_using_extv (rtx op0, u return NULL_RTX; if (MEM_P (op0)) - { - /* Get a reference to the first byte of the field. */ - op0 = adjust_bitfield_address (op0, byte_mode, bitnum / BITS_PER_UNIT); - bitnum %= BITS_PER_UNIT; - } + /* Get a reference to the first byte of the field. */ + op0 = narrow_bit_field_mem (op0, byte_mode, bitsize, bitnum, &bitnum); else { /* Convert from counting within OP0 to counting in EXT_MODE. */ @@ -1640,23 +1657,20 @@ extract_bit_field_1 (rtx str_rtx, unsign && !(SLOW_UNALIGNED_ACCESS (bestmode, MEM_ALIGN (op0)) && GET_MODE_BITSIZE (bestmode) > MEM_ALIGN (op0))) { - unsigned HOST_WIDE_INT offset, bitpos; - - /* Compute the offset as a multiple of this unit, - counting in bytes. */ - unsigned int unit = GET_MODE_BITSIZE (bestmode); - offset = (bitnum / unit) * GET_MODE_SIZE (bestmode); - bitpos = bitnum % unit; - - /* Make sure the register is big enough for the whole field. */ - if (bitpos + bitsize <= unit) + unsigned HOST_WIDE_INT bitpos; + rtx xop0 = narrow_bit_field_mem (op0, bestmode, bitsize, bitnum, + &bitpos); + + /* Make sure the register is big enough for the whole field. + (It might not be if bestmode == GET_MODE (op0) and the input + code was invalid.) */ + if (bitpos + bitsize <= GET_MODE_BITSIZE (bestmode)) { - rtx last, result, xop0; + rtx last, result; last = get_last_insn (); /* Fetch it to a register in that size. */ - xop0 = adjust_bitfield_address (op0, bestmode, offset); xop0 = force_reg (bestmode, xop0); result = extract_bit_field_1 (xop0, bitsize, bitpos, unsignedp, packedp, target,