From patchwork Mon Jul 25 11:20:11 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Georg-Johann Lay X-Patchwork-Id: 106637 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 9FBC6B6F84 for ; Mon, 25 Jul 2011 21:21:27 +1000 (EST) Received: (qmail 22888 invoked by alias); 25 Jul 2011 11:21:26 -0000 Received: (qmail 22879 invoked by uid 22791); 25 Jul 2011 11:21:25 -0000 X-SWARE-Spam-Status: No, hits=-0.7 required=5.0 tests=AWL, BAYES_05, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, RCVD_IN_DNSWL_NONE, TW_RJ X-Spam-Check-By: sourceware.org Received: from mo-p00-ob.rzone.de (HELO mo-p00-ob.rzone.de) (81.169.146.160) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Mon, 25 Jul 2011 11:21:11 +0000 X-RZG-AUTH: :LXoWVUeid/7A29J/hMvvT2k715jHQaJercGObUOFkj18odoYNahU4Q== X-RZG-CLASS-ID: mo00 Received: from [192.168.0.22] (business-188-111-022-002.static.arcor-ip.net [188.111.22.2]) by smtp.strato.de (cohen mo50) (RZmta 26.2) with ESMTPA id z0109en6PAufOL ; Mon, 25 Jul 2011 13:20:11 +0200 (MEST) Message-ID: <4E2D516B.6080507@gjlay.de> Date: Mon, 25 Jul 2011 13:20:11 +0200 From: Georg-Johann Lay User-Agent: Thunderbird 2.0.0.24 (X11/20100302) MIME-Version: 1.0 To: gcc-patches@gcc.gnu.org CC: Denis Chertykov , Eric Weddington , Richard Henderson Subject: [Patch,AVR]: Fix PR39386 (x << x and x >> x) X-IsSubscribed: yes 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 is a fix for pathological, variable shift offset shifts of the form x << x resp. x >> x. Such shifts need a shift register which might overlap with the shift operand. unsigned char shift (unsigned int x) { return x << x; } Without patch, note r24 is part of operand and used in loop: shift: rjmp 2f 1: lsl r24 rol r25 2: dec r24 brpl 1b ret With patch use tmp_reg (R0) as counter: shift: mov r0,r24 rjmp 2f 1: lsl r24 rol r25 2: dec r0 brpl 1b ret Patch as obvious. Increased instruction length is already taken into account because the RO = Rx will be needed if Rx is used afterwards, anyway. Ok to install? Johann PR target/39386 * config/avr/avr.c (out_shift_with_cnt): Use tmp_reg as shift counter for x << x and x >> x shifts. Index: config/avr/avr.c =================================================================== --- config/avr/avr.c (revision 176624) +++ config/avr/avr.c (working copy) @@ -3147,8 +3147,11 @@ out_shift_with_cnt (const char *templ, r } else if (register_operand (operands[2], QImode)) { - if (reg_unused_after (insn, operands[2])) - op[3] = op[2]; + if (reg_unused_after (insn, operands[2]) + && !reg_overlap_mentioned_p (operands[0], operands[2])) + { + op[3] = op[2]; + } else { op[3] = tmp_reg_rtx;