From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 22911 invoked by alias); 18 Oct 2011 23:11:07 -0000 Received: (qmail 22901 invoked by uid 22791); 18 Oct 2011 23:11:06 -0000 X-SWARE-Spam-Status: No, hits=-6.6 required=5.0 tests=AWL,BAYES_00,RCVD_IN_DNSWL_HI,RP_MATCHES_RCVD,SPF_HELO_PASS,TW_RQ X-Spam-Check-By: sourceware.org Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Tue, 18 Oct 2011 23:10:48 +0000 Received: from int-mx02.intmail.prod.int.phx2.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id p9INAlmB017939 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Tue, 18 Oct 2011 19:10:48 -0400 Received: from anchor.twiddle.net (vpn-238-70.phx2.redhat.com [10.3.238.70]) by int-mx02.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id p9INAjVD002973; Tue, 18 Oct 2011 19:10:46 -0400 Message-ID: <4E9E0775.3020303@redhat.com> Date: Wed, 19 Oct 2011 05:22:00 -0000 From: Richard Henderson User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:7.0) Gecko/20110927 Thunderbird/7.0 MIME-Version: 1.0 To: "Paulo J. Matos" CC: gcc@gcc.gnu.org Subject: Re: Expanding instructions with condition codes inter-deps References: In-Reply-To: Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit X-IsSubscribed: yes Mailing-List: contact gcc-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-owner@gcc.gnu.org X-SW-Source: 2011-10/txt/msg00303.txt.bz2 On 10/17/2011 03:50 AM, Paulo J. Matos wrote: > Hi, > > To negate a double word (HImode) register, I used to take the instruction all the way to assembly generation and then expand into three assembly instructions like so: > xor %t0, #ffff ; invert bits in top word of op0 > nadd %b0, #0 ; negate bottom bits of op0 > addc %t0, #0 ; add carry to top bits of op0 > > The interesting thing about this sequence is that the carry added to the top bits of op0, is the carry generated by the previous instruction. > > If I instead of taking the neghi rule all the way to assembly, and instead expand it I get: > (define_expand "neghi2" > [(set (match_operand:HI 0 "register_operand") > (neg:HI (match_operand:HI 1 "general_operand"))) > (clobber (reg:CC RCC))] > "" > { > rtx op0_low = gen_lowpart(QImode, operands[0]); > rtx op0_high = gen_highpart(QImode, operands[0]); > emit_move_insn(operands[0], operands[1]); > emit_insn(gen_xorqi3(op0_high, op0_high, GEN_INT(-1))); > emit_insn(gen_negqi2(op0_low, op0_low)); > emit_insn(gen_addc_internal(op0_high, op0_high, const0_rtx)); > DONE; > }) > > > addc_internal looks like: > (define_insn "addc_internal" > [(set (match_operand:QI 0 "nonimmediate_operand" "=c") > (plus:QI > (plus:QI > (ltu:QI (reg:CC RCC) (const_int 0)) > (match_operand:QI 1 "nonimmediate_operand" "%0")) > (match_operand:QI 2 "general_operand" "cwmi"))) > (clobber (reg:CC RCC))] > "" > "addc\\t%0,%f2") > > > The problem is that GCC sometimes moves nadd and addc around. The thing that's almost certainly missing is that the NAND pattern must SET your flags register, not simply clobber it. Otherwise the dependency between the ADDC and the NAND will never be created properly. > (for example, it would be ok to output negqi2, xorqi3 and > addc_internal since xorqi3 only sets N and Z, not the Carry bit) For that you'd have to model all of the flags bits independently. I don't believe any target has found that level of complexity to be worth the trouble. So, almost certainly, you don't. r~