From patchwork Mon Oct 10 13:27: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: 118740 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 717F6B708F for ; Tue, 11 Oct 2011 00:28:01 +1100 (EST) Received: (qmail 7604 invoked by alias); 10 Oct 2011 13:27:57 -0000 Received: (qmail 7591 invoked by uid 22791); 10 Oct 2011 13:27:55 -0000 X-SWARE-Spam-Status: No, hits=-1.5 required=5.0 tests=AWL, BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, RCVD_IN_DNSWL_NONE X-Spam-Check-By: sourceware.org Received: from mo-p00-ob.rzone.de (HELO mo-p00-ob.rzone.de) (81.169.146.161) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Mon, 10 Oct 2011 13:27:40 +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 (klopstock mo19) (RZmta 26.10 AUTH) with ESMTPA id C00e80n9ADKP0G ; Mon, 10 Oct 2011 15:27:12 +0200 (MEST) Message-ID: <4E92F2AF.3000405@gjlay.de> Date: Mon, 10 Oct 2011 15:27: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 Subject: [Patch,AVR]: Reuse __tablejump2__ 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 patch does better re-usage of __tablejump2__ from libgcc so that switch/case statements with jump tables become smaller because the sequence needs 6 to 9 words compared to 2 when JMPing to __tablejump2__. Moreover, __tablejump2__ does no more rely in the content of EIND (by using EIJMP) and uses RET instead. The insn conditions of tablejump insns now are the same as in avr_output_addr_vec_elt. Ok for trunk? Johann * config/avr/avr.md (*tablejump_rjmp): Change insn condition to !AVR_HAVE_JMP_CALL. (*tablejump_lib): Change insn condition to AVR_HAVE_JMP_CALL. (*tablejump_enh, *tablejump): Remove insns. * config/avr/libgcc.S (__tablejump__): Use RET instead of EIND + EIJM for indirect jump. Use LPM Z+ where available. Index: config/avr/libgcc.S =================================================================== --- config/avr/libgcc.S (revision 179744) +++ config/avr/libgcc.S (working copy) @@ -821,13 +821,17 @@ ENDF __tablejump2__ DEFUN __tablejump__ #if defined (__AVR_HAVE_LPMX__) +#if defined (__AVR_HAVE_EIJMP_EICALL__) + lpm __tmp_reg__, Z+ + push __tmp_reg__ + lpm __tmp_reg__, Z + push __tmp_reg__ + push __zero_reg__ + ret +#else lpm __tmp_reg__, Z+ lpm r31, Z mov r30, __tmp_reg__ - -#if defined (__AVR_HAVE_EIJMP_EICALL__) - eijmp -#else ijmp #endif Index: config/avr/avr.md =================================================================== --- config/avr/avr.md (revision 179744) +++ config/avr/avr.md (working copy) @@ -3719,62 +3719,36 @@ (define_insn "*indirect_jump_avr6" (set_attr "cc" "none")]) ;; table jump +;; For entries in jump table see avr_output_addr_vec_elt. -;; Table made from "rjmp" instructions for <=8K devices. +;; Table made from "rjmp .L" instructions for <= 8K devices. (define_insn "*tablejump_rjmp" - [(set (pc) (unspec:HI [(match_operand:HI 0 "register_operand" "!z,*r")] - UNSPEC_INDEX_JMP)) + [(set (pc) + (unspec:HI [(match_operand:HI 0 "register_operand" "!z,*r")] + UNSPEC_INDEX_JMP)) (use (label_ref (match_operand 1 "" ""))) (clobber (match_dup 0))] - "(!AVR_HAVE_JMP_CALL) && (!AVR_HAVE_EIJMP_EICALL)" + "!AVR_HAVE_JMP_CALL" "@ ijmp push %A0\;push %B0\;ret" [(set_attr "length" "1,3") (set_attr "cc" "none,none")]) -;; Not a prologue, but similar idea - move the common piece of code to libgcc. +;; Move the common piece of code to libgcc. +;; Table made from ".word gs(.L)" addresses for > 8K devices. +;; Read jump address from table and perform indirect jump. (define_insn "*tablejump_lib" - [(set (pc) (unspec:HI [(match_operand:HI 0 "register_operand" "z")] - UNSPEC_INDEX_JMP)) + [(set (pc) + (unspec:HI [(match_operand:HI 0 "register_operand" "z")] + UNSPEC_INDEX_JMP)) (use (label_ref (match_operand 1 "" ""))) (clobber (match_dup 0))] - "AVR_HAVE_JMP_CALL && TARGET_CALL_PROLOGUES" - "%~jmp __tablejump2__" + "AVR_HAVE_JMP_CALL" + "jmp __tablejump2__" [(set_attr "length" "2") (set_attr "cc" "clobber")]) -(define_insn "*tablejump_enh" - [(set (pc) (unspec:HI [(match_operand:HI 0 "register_operand" "z")] - UNSPEC_INDEX_JMP)) - (use (label_ref (match_operand 1 "" ""))) - (clobber (match_dup 0))] - "AVR_HAVE_JMP_CALL && AVR_HAVE_LPMX" - "lsl r30 - rol r31 - lpm __tmp_reg__,Z+ - lpm r31,Z - mov r30,__tmp_reg__ - %!ijmp" - [(set_attr "length" "6") - (set_attr "cc" "clobber")]) - -(define_insn "*tablejump" - [(set (pc) (unspec:HI [(match_operand:HI 0 "register_operand" "z")] - UNSPEC_INDEX_JMP)) - (use (label_ref (match_operand 1 "" ""))) - (clobber (match_dup 0))] - "AVR_HAVE_JMP_CALL && !AVR_HAVE_EIJMP_EICALL" - "lsl r30 - rol r31 - lpm - inc r30 - push r0 - lpm - push r0 - ret" - [(set_attr "length" "8") - (set_attr "cc" "clobber")]) (define_expand "casesi" [(set (match_dup 6)