From patchwork Fri Sep 20 22:42:28 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: DJ Delorie X-Patchwork-Id: 276809 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]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id E39BD2C0196 for ; Sat, 21 Sep 2013 08:42:41 +1000 (EST) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :message-id:from:to:subject; q=dns; s=default; b=oBHjHJ+pXlG4T/G LRmp2rjGE9II+xiYmgAeTZk9sibuaKCSIx36/bkos0Rd80wpRzwyUG+l5D5danbB mtEVtV9OEzAPBPubT94HR32IcrvuYonO6YjcuEQMeAtm2DuozqtfbDvjYcLKbBLm U6ff4ozCEgUHk5mmd8F4DBtxg6jU= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :message-id:from:to:subject; s=default; bh=6c1oJZdy8La/kP7OqM8g7 gE7q4k=; b=fCh+U1FJ9L57Yk1bF8gJ6UWRNrvuIArzAVBGNz9MeHDN5fhD5Kct3 CV//VinE58gusa0qHzQ0CX+l+1XYMq+GeSlSuvEXvra+MHr8JuxY2tHmQ01hTpyA 0J4Mho4lEkhhw+NKDwbTXNqTAyfputhXtqy6zzIYejXY5a1vYI5fVo= Received: (qmail 25987 invoked by alias); 20 Sep 2013 22:42:34 -0000 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 Received: (qmail 25977 invoked by uid 89); 20 Sep 2013 22:42:34 -0000 Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Fri, 20 Sep 2013 22:42:34 +0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.7 required=5.0 tests=AWL, BAYES_50, RP_MATCHES_RCVD autolearn=ham version=3.3.2 X-HELO: mx1.redhat.com Received: from int-mx01.intmail.prod.int.phx2.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id r8KMgUBI021078 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Fri, 20 Sep 2013 18:42:30 -0400 Received: from greed.delorie.com (ovpn-113-20.phx2.redhat.com [10.3.113.20]) by int-mx01.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id r8KMgTKH017366 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO) for ; Fri, 20 Sep 2013 18:42:29 -0400 Received: from greed.delorie.com (greed.delorie.com [127.0.0.1]) by greed.delorie.com (8.14.4/8.14.4) with ESMTP id r8KMgSub003094 for ; Fri, 20 Sep 2013 18:42:28 -0400 Received: (from dj@localhost) by greed.delorie.com (8.14.4/8.14.4/Submit) id r8KMgSg7003093; Fri, 20 Sep 2013 18:42:28 -0400 Date: Fri, 20 Sep 2013 18:42:28 -0400 Message-Id: <201309202242.r8KMgSg7003093@greed.delorie.com> From: DJ Delorie To: gcc-patches@gcc.gnu.org Subject: [rl78] various tweaks X-IsSubscribed: yes Mostly whitespace and comment tweaks, with a few random bug fixes. Committed. Note: the net result of our recent batch of patches is an approximately 50% speed improvement :-) * config/rl78/rl78.c: Various whitespace and comment tweaks. (need_to_save): Save bank 0 on interrupts. (characterize_address): Strip far address wrappers. (rl78_as_legitimate_address): Likewise. (transcode_memory_rtx): Likewise. (rl78_peep_movhi_p): Disable this peephole after devirt. (rl78_propogate_register_origins): Forget all origins when a CLOBBER is seen. * config/rl78/rl78-virt.md: Various whitespace tweaks. * config/rl78/rl78-real.md: Various whitespace tweaks. Additional peephole2's. * config/rl78/rl78.md (sel_rb): Disable for G10 just in case. * config/rl78/rl78-expand.md (movqi): Check for subregs of consts. * config/rl78/rl78.h (LINK_SPEC): Pass -gc-sections unless relocating. * config/rl78/constraints.md: Various whitespace and paren tweaks. Index: config/rl78/rl78.h =================================================================== --- config/rl78/rl78.h (revision 202798) +++ config/rl78/rl78.h (working copy) @@ -49,12 +49,13 @@ %{mg10} \ " #undef LINK_SPEC #define LINK_SPEC "\ %{mrelax:-relax} \ +%{!r:--gc-sections} \ " #undef LIB_SPEC #define LIB_SPEC " \ --start-group \ -lc \ Index: config/rl78/constraints.md =================================================================== --- config/rl78/constraints.md (revision 202798) +++ config/rl78/constraints.md (working copy) @@ -59,33 +59,37 @@ (define_constraint "Iv08" "@internal Integer constant equal to 8." (and (match_code "const_int") (match_test "IN_RANGE (ival, 8, 8)"))) + (define_constraint "Iv16" "@internal Integer constant equal to 16." (and (match_code "const_int") (match_test "IN_RANGE (ival, 16, 16)"))) + (define_constraint "Iv24" "@internal Integer constant equal to 24." (and (match_code "const_int") (match_test "IN_RANGE (ival, 24, 24)"))) (define_constraint "Is09" "@internal Integer constant in the range 9 @dots{} 15 (for shifts)." (and (match_code "const_int") (match_test "IN_RANGE (ival, 9, 15)"))) + (define_constraint "Is17" "@internal Integer constant in the range 17 @dots{} 23 (for shifts)." (and (match_code "const_int") (match_test "IN_RANGE (ival, 17, 23)"))) + (define_constraint "Is25" "@internal Integer constant in the range 25 @dots{} 31 (for shifts)." (and (match_code "const_int") (match_test "IN_RANGE (ival, 25, 31)"))) @@ -213,13 +217,13 @@ (ior (match_test "CONSTANT_P (XEXP (op, 0))") (match_test "GET_CODE (XEXP (op, 0)) == PLUS && GET_CODE (XEXP (XEXP (op, 0), 0)) == SYMBOL_REF")) ) ) (define_memory_constraint "Wab" "es:[addr]" - (match_test "rl78_es_addr (op) && satisfies_constraint_Cab (rl78_es_base (op)) + (match_test "(rl78_es_addr (op) && satisfies_constraint_Cab (rl78_es_base (op))) || satisfies_constraint_Cab (op)") ) (define_memory_constraint "Cbc" "word16[BC]" (and (match_code "mem") @@ -231,49 +235,49 @@ (match_test "REGNO (XEXP (XEXP (op, 0), 0)) == BC_REG")) (match_test "uword_operand (XEXP (XEXP (op, 0), 1), VOIDmode)")))) ) ) (define_memory_constraint "Wbc" "es:word16[BC]" - (match_test "rl78_es_addr (op) && satisfies_constraint_Cbc (rl78_es_base (op)) + (match_test "(rl78_es_addr (op) && satisfies_constraint_Cbc (rl78_es_base (op))) || satisfies_constraint_Cbc (op)") ) (define_memory_constraint "Cde" "[DE]" (and (match_code "mem") (and (match_code "reg" "0") (match_test "REGNO (XEXP (op, 0)) == DE_REG"))) ) (define_memory_constraint "Wde" "es:[DE]" - (match_test "rl78_es_addr (op) && satisfies_constraint_Cde (rl78_es_base (op)) + (match_test "(rl78_es_addr (op) && satisfies_constraint_Cde (rl78_es_base (op))) || satisfies_constraint_Cde (op)") ) (define_memory_constraint "Cca" "[AX..HL] for calls" (and (match_code "mem") (and (match_code "reg" "0") (match_test "REGNO (XEXP (op, 0)) <= HL_REG"))) ) (define_memory_constraint "Wca" "es:[AX..HL] for calls" - (match_test "rl78_es_addr (op) && satisfies_constraint_Cca (rl78_es_base (op)) + (match_test "(rl78_es_addr (op) && satisfies_constraint_Cca (rl78_es_base (op))) || satisfies_constraint_Cca (op)") ) (define_memory_constraint "Ccv" "[AX..HL,r8-r31] for calls" (and (match_code "mem") (and (match_code "reg" "0") - (match_test "REGNO (XEXP (op, 0)) < 31"))) + (match_test "REGNO (XEXP (op, 0)) < 32"))) ) (define_memory_constraint "Wcv" - "es:[AX..HL,r8-r23] for calls" - (match_test "rl78_es_addr (op) && satisfies_constraint_Ccv (rl78_es_base (op)) + "es:[AX..HL,r8-r31] for calls" + (match_test "(rl78_es_addr (op) && satisfies_constraint_Ccv (rl78_es_base (op))) || satisfies_constraint_Ccv (op)") ) (define_memory_constraint "Cd2" "word16[DE]" (and (match_code "mem") @@ -285,25 +289,25 @@ (match_test "REGNO (XEXP (XEXP (op, 0), 0)) == DE_REG")) (match_test "uword_operand (XEXP (XEXP (op, 0), 1), VOIDmode)")))) ) ) (define_memory_constraint "Wd2" "es:word16[DE]" - (match_test "rl78_es_addr (op) && satisfies_constraint_Cd2 (rl78_es_base (op)) + (match_test "(rl78_es_addr (op) && satisfies_constraint_Cd2 (rl78_es_base (op))) || satisfies_constraint_Cd2 (op)") ) (define_memory_constraint "Chl" "[HL]" (and (match_code "mem") (and (match_code "reg" "0") (match_test "REGNO (XEXP (op, 0)) == HL_REG"))) ) (define_memory_constraint "Whl" "es:[HL]" - (match_test "rl78_es_addr (op) && satisfies_constraint_Chl (rl78_es_base (op)) + (match_test "(rl78_es_addr (op) && satisfies_constraint_Chl (rl78_es_base (op))) || satisfies_constraint_Chl (op)") ) (define_memory_constraint "Ch1" "byte8[HL]" (and (match_code "mem") @@ -311,24 +315,24 @@ (and (and (match_code "reg" "00") (match_test "REGNO (XEXP (XEXP (op, 0), 0)) == HL_REG")) (match_test "ubyte_operand (XEXP (XEXP (op, 0), 1), VOIDmode)")))) ) (define_memory_constraint "Wh1" "es:byte8[HL]" - (match_test "rl78_es_addr (op) && satisfies_constraint_Ch1 (rl78_es_base (op)) + (match_test "(rl78_es_addr (op) && satisfies_constraint_Ch1 (rl78_es_base (op))) || satisfies_constraint_Ch1 (op)") ) (define_memory_constraint "Chb" "[HL+B]" (and (match_code "mem") (match_test "rl78_hl_b_c_addr_p (XEXP (op, 0))")) ) (define_memory_constraint "Whb" "es:[HL+B]" - (match_test "rl78_es_addr (op) && satisfies_constraint_Chb (rl78_es_base (op)) + (match_test "(rl78_es_addr (op) && satisfies_constraint_Chb (rl78_es_base (op))) || satisfies_constraint_Chb (op)") ) (define_memory_constraint "Cs1" "word8[SP]" (and (match_code "mem") @@ -340,13 +344,13 @@ (match_test "REGNO (XEXP (XEXP (op, 0), 0)) == SP_REG")) (match_test "ubyte_operand (XEXP (XEXP (op, 0), 1), VOIDmode)")))) ) ) (define_memory_constraint "Ws1" "es:word8[SP]" - (match_test "rl78_es_addr (op) && satisfies_constraint_Cs1 (rl78_es_base (op)) + (match_test "(rl78_es_addr (op) && satisfies_constraint_Cs1 (rl78_es_base (op))) || satisfies_constraint_Cs1 (op)") ) (define_memory_constraint "Wfr" "ES/CS far pointer" (and (match_code "mem") Index: config/rl78/rl78-expand.md =================================================================== --- config/rl78/rl78-expand.md (revision 202798) +++ config/rl78/rl78-expand.md (working copy) @@ -40,20 +40,12 @@ if (GET_CODE (operand1) == SUBREG && GET_CODE (XEXP (operand1, 0)) == CONST && GET_CODE (XEXP (XEXP (operand1, 0), 0)) == PLUS && GET_CODE (XEXP (XEXP (XEXP (operand1, 0), 0), 0)) == SYMBOL_REF) FAIL; - /* Similarly for (SUBREG (CONST (PLUS (SYMBOL_REF)))). - cf. g++.dg/abi/packed.C. */ - if (GET_CODE (operand1) == SUBREG - && GET_CODE (XEXP (operand1, 0)) == CONST - && GET_CODE (XEXP (XEXP (operand1, 0), 0)) == PLUS - && GET_CODE (XEXP (XEXP (XEXP (operand1, 0), 0), 0)) == SYMBOL_REF) - FAIL; - if (CONST_INT_P (operand1) && ! IN_RANGE (INTVAL (operand1), (-1 << 8) + 1, (1 << 8) - 1)) FAIL; } ) (define_expand "movhi" Index: config/rl78/rl78.md =================================================================== --- config/rl78/rl78.md (revision 202798) +++ config/rl78/rl78.md (working copy) @@ -139,13 +139,13 @@ pop\t%v0 pop\t%v0 ; %0" ) (define_insn "sel_rb" [(unspec_volatile [(match_operand 0 "immediate_operand" "")] UNS_SET_RB)] - "" + "!TARGET_G10" "sel\trb%u0" ) (define_insn "trampoline_init" [(set (match_operand 0 "register_operand" "=Z08W") (unspec_volatile [(match_operand 1 "register_operand" "Z08W") Index: config/rl78/rl78-real.md =================================================================== --- config/rl78/rl78-real.md (revision 202798) +++ config/rl78/rl78-real.md (working copy) @@ -309,13 +309,13 @@ "rl78_real_insns_ok ()" "@ call\t!!%A1 call\t%A1" ) -(define_insn "cbranchqi4_real_signed" +(define_insn "*cbranchqi4_real_signed" [(set (pc) (if_then_else (match_operator 0 "rl78_cmp_operator_signed" [(match_operand:QI 1 "general_operand" "A,A,A") (match_operand:QI 2 "general_operand" "ISqi,i,v")]) (label_ref (match_operand 3 "" "")) (pc)))] @@ -323,13 +323,12 @@ "@ cmp\t%1, %2 \;xor1 CY,%1.7\;not1 CY\;sk%c0 \;br\t!!%3 cmp\t%1, %2 \;xor1 CY,%1.7\;sk%c0 \;br\t!!%3 cmp\t%1, %2 \;xor1 CY,%1.7\;xor1 CY,%2.7\;sk%c0 \;br\t!!%3" ) - (define_insn "*cbranchqi4_real" [(set (pc) (if_then_else (match_operator 0 "rl78_cmp_operator_real" [(match_operand:QI 1 "general_operand" "Wabvaxbc,a, v,bcdehl") (match_operand:QI 2 "general_operand" "M, irvWabWhlWh1Whb,i,a")]) (label_ref (match_operand 3 "" "")) @@ -339,13 +338,13 @@ cmp0\t%1 \;sk%c0 \;br\t!!%3 cmp\t%1, %2 \;sk%c0 \;br\t!!%3 cmp\t%1, %2 \;sk%c0 \;br\t!!%3 cmp\t%1, %2 \;sk%c0 \;br\t!!%3" ) -(define_insn "cbranchhi4_real_signed" +(define_insn "*cbranchhi4_real_signed" [(set (pc) (if_then_else (match_operator 0 "rl78_cmp_operator_signed" [(match_operand:HI 1 "general_operand" "A,A,A,vR") (match_operand:HI 2 "general_operand" "IShi,i,v,1")]) (label_ref (match_operand 3)) (pc)))] @@ -378,13 +377,13 @@ (pc) (label_ref (match_operand 3 "" ""))))] "rl78_real_insns_ok ()" "cmpw\t%1, %2 \;sk%c0 \;br\t!!%3" ) -(define_insn "cbranchsi4_real_lt" +(define_insn "*cbranchsi4_real_lt" [(set (pc) (if_then_else (lt (match_operand:SI 0 "general_operand" "U,vWabWhlWh1") (const_int 0)) (label_ref (match_operand 1 "" "")) (pc))) (clobber (reg:HI AX_REG)) @@ -392,13 +391,13 @@ "rl78_real_insns_ok ()" "@ mov a, %E0 \;mov1 CY,a.7 \;sknc \;br\t!!%1 mov1 CY,%E0.7 \;sknc \;br\t!!%1" ) -(define_insn "cbranchsi4_real_ge" +(define_insn "*cbranchsi4_real_ge" [(set (pc) (if_then_else (ge (match_operand:SI 0 "general_operand" "U,vWabWhlWh1") (const_int 0)) (label_ref (match_operand 1 "" "")) (pc))) (clobber (reg:HI AX_REG)) @@ -406,13 +405,13 @@ "rl78_real_insns_ok ()" "@ mov a, %E0 \;mov1 CY,a.7 \;skc \;br\t!!%1 mov1 CY,%E0.7 \;skc \;br\t!!%1" ) -(define_insn "cbranchsi4_real_signed" +(define_insn "*cbranchsi4_real_signed" [(set (pc) (if_then_else (match_operator 0 "rl78_cmp_operator_signed" [(match_operand:SI 1 "nonimmediate_operand" "vU,vU,vU") (match_operand:SI 2 "nonmemory_operand" "ISsi,i,v")]) (label_ref (match_operand 3 "" "")) (pc))) @@ -422,13 +421,13 @@ "@ movw ax,%H1 \;cmpw ax, %H2 \;xor1 CY,a.7\;not1 CY\; movw ax,%h1 \;sknz \;cmpw ax, %h2 \;sk%c0 \;br\t!!%3 movw ax,%H1 \;cmpw ax, %H2 \;xor1 CY,a.7\; movw ax,%h1 \;sknz \;cmpw ax, %h2 \;sk%c0 \;br\t!!%3 movw ax,%H1 \;cmpw ax, %H2 \;xor1 CY,a.7\;xor1 CY,%E2.7\;movw ax,%h1 \;sknz \;cmpw ax, %h2 \;sk%c0 \;br\t!!%3" ) -(define_insn "cbranchsi4_real" +(define_insn "*cbranchsi4_real" [(set (pc) (if_then_else (match_operator 0 "rl78_cmp_operator_real" [(match_operand:SI 1 "general_operand" "vUi") (match_operand:SI 2 "general_operand" "iWhlWh1v")]) (label_ref (match_operand 3 "" "")) (pc))) @@ -488,29 +487,65 @@ ;; NOTE: These peepholes are fragile. They rely upon GCC generating ;; a specific sequence on insns, based upon examination of test code. ;; Improvements to GCC or using code other than the test code can result ;; in the peephole not matching and the optimization being missed. (define_peephole2 - [(set (match_operand:QI 1 "register_operand") (reg:QI A_REG)) - (set (match_dup 1) (and:QI (match_dup 1) (match_operand 2 "immediate_operand"))) - (set (pc) (if_then_else (eq (match_dup 1) (const_int 0)) - (label_ref (match_operand 3 "")) + [(set (match_operand:QI 0 "register_operand") (reg:QI A_REG)) + (set (match_dup 0) (and:QI (match_dup 0) (match_operand 1 "immediate_operand"))) + (set (pc) (if_then_else (eq (match_dup 0) (const_int 0)) + (label_ref (match_operand 2 "")) + (pc)))] + "peep2_regno_dead_p (3, REGNO (operands[0])) + && exact_log2 (INTVAL (operands[1])) >= 0" + [(set (pc) (if_then_else (eq (and (reg:QI A_REG) (match_dup 1)) (const_int 0)) + (label_ref (match_dup 2)) (pc)))] - "peep2_regno_dead_p (3, REGNO (operands[1])) - && exact_log2 (INTVAL (operands[2])) >= 0" - [(set (pc) (if_then_else (eq (and (reg:QI A_REG) (match_dup 2)) (const_int 0)) - (label_ref (match_dup 3)) (pc)))] ) (define_peephole2 - [(set (match_operand:QI 1 "register_operand") (reg:QI A_REG)) - (set (match_dup 1) (and:QI (match_dup 1) (match_operand 2 "immediate_operand"))) - (set (pc) (if_then_else (ne (match_dup 1) (const_int 0)) - (label_ref (match_operand 3 "")) + [(set (match_operand:QI 0 "register_operand") (reg:QI A_REG)) + (set (match_dup 0) (and:QI (match_dup 0) (match_operand 1 "immediate_operand"))) + (set (pc) (if_then_else (ne (match_dup 0) (const_int 0)) + (label_ref (match_operand 2 "")) (pc)))] - "peep2_regno_dead_p (3, REGNO (operands[1])) - && exact_log2 (INTVAL (operands[2])) >= 0" - [(set (pc) (if_then_else (ne (and (reg:QI A_REG) (match_dup 2)) (const_int 0)) - (label_ref (match_dup 3)) (pc)))] + "peep2_regno_dead_p (3, REGNO (operands[0])) + && exact_log2 (INTVAL (operands[1])) >= 0" + [(set (pc) (if_then_else (ne (and (reg:QI A_REG) (match_dup 1)) (const_int 0)) + (label_ref (match_dup 2)) + (pc)))] + ) + +;; Eliminate needless register copies. +(define_peephole2 + [(set (match_operand:HI 0 "register_operand") (match_operand:HI 1 "register_operand")) + (set (match_operand:HI 2 "register_operand") (match_dup 0))] + "peep2_regno_dead_p (2, REGNO (operands[0])) + && (REGNO (operands[1]) < 8 || REGNO (operands[2]) < 8)" + [(set (match_dup 2) (match_dup 1))] + ) + +;; Eliminate needless register copying when performing bit manipulations. +(define_peephole2 + [(set (match_operand:QI 0 "register_operand") (reg:QI A_REG)) + (set (match_dup 0) (ior:QI (match_dup 0) (match_operand 1 "immediate_operand"))) + (set (reg:QI A_REG) (match_dup 0))] + "peep2_regno_dead_p (3, REGNO (operands[0]))" + [(set (reg:QI A_REG) (ior:QI (reg:QI A_REG) (match_dup 1)))] + ) + +(define_peephole2 + [(set (match_operand:QI 0 "register_operand") (reg:QI A_REG)) + (set (match_dup 0) (xor:QI (match_dup 0) (match_operand 1 "immediate_operand"))) + (set (reg:QI A_REG) (match_dup 0))] + "peep2_regno_dead_p (3, REGNO (operands[0]))" + [(set (reg:QI A_REG) (xor:QI (reg:QI A_REG) (match_dup 1)))] + ) + +(define_peephole2 + [(set (match_operand:QI 0 "register_operand") (reg:QI A_REG)) + (set (match_dup 0) (and:QI (match_dup 0) (match_operand 1 "immediate_operand"))) + (set (reg:QI A_REG) (match_dup 0))] + "peep2_regno_dead_p (3, REGNO (operands[0]))" + [(set (reg:QI A_REG) (and:QI (reg:QI A_REG) (match_dup 1)))] ) Index: config/rl78/rl78-virt.md =================================================================== --- config/rl78/rl78-virt.md (revision 202798) +++ config/rl78/rl78-virt.md (working copy) @@ -309,13 +309,13 @@ (match_operand 2 "" "")))] "rl78_virt_insns_ok ()" "v.call\t%1" [(set_attr "valloc" "op1")] ) -(define_insn "cbranchqi4_virt_signed" +(define_insn "*cbranchqi4_virt_signed" [(set (pc) (if_then_else (match_operator 0 "rl78_cmp_operator_signed" [(match_operand:QI 1 "general_operand" "vim") (match_operand:QI 2 "nonmemory_operand" "vi")]) (label_ref (match_operand 3 "" "")) (pc)))] @@ -333,13 +333,13 @@ (pc)))] "rl78_virt_insns_ok ()" "v.cmp\t%1, %2\\n\tv.b%c0\t%3" [(set_attr "valloc" "cmp")] ) -(define_insn "cbranchhi4_virt_signed" +(define_insn "*cbranchhi4_virt_signed" [(set (pc) (if_then_else (match_operator 0 "rl78_cmp_operator_signed" [(match_operand:HI 1 "general_operand" "vim") (match_operand:HI 2 "nonmemory_operand" "vi")]) (label_ref (match_operand 3 "" "")) (pc)))] @@ -357,13 +357,13 @@ (pc)))] "rl78_virt_insns_ok ()" "v.cmpw\t%1, %2\\n\tv.b%c0\t%3" [(set_attr "valloc" "cmp")] ) -(define_insn "cbranchsi4_virt" +(define_insn "*cbranchsi4_virt" [(set (pc) (if_then_else (match_operator 0 "rl78_cmp_operator" [(match_operand:SI 1 "general_operand" "vim") (match_operand:SI 2 "nonmemory_operand" "vi")]) (label_ref (match_operand 3 "" "")) (pc))) Index: config/rl78/rl78.c =================================================================== --- config/rl78/rl78.c (revision 202798) +++ config/rl78/rl78.c (working copy) @@ -167,12 +167,15 @@ public: rtl_opt_pass * make_pass_rl78_devirt (gcc::context *ctxt) { return new pass_rl78_devirt (ctxt); } +/* Redundant move elimination pass. Must be run after the basic block + reordering pass for the best effect. */ + static unsigned int move_elim_pass (void) { rtx insn, ninsn, prev = NULL_RTX; for (insn = get_insns (); insn; insn = ninsn) @@ -311,13 +314,14 @@ rl78_option_override (void) init_machine_status = rl78_init_machine_status; if (TARGET_ALLREGS) { int i; - for (i=24; i<32; i++) + + for (i = 24; i < 32; i++) fixed_regs[i] = 0; } } /* Most registers are 8 bits. Some are 16 bits because, for example, gcc doesn't like dealing with $FP as a register pair. This table @@ -439,19 +443,21 @@ rl78_expand_movsi (rtx *operands) { emit_move_insn (op00, op10); emit_move_insn (op02, op12); } } +/* Generate code to move an SImode value. */ void rl78_split_movsi (rtx *operands) { rtx op00, op02, op10, op12; op00 = rl78_subreg (HImode, operands[0], SImode, 0); op02 = rl78_subreg (HImode, operands[0], SImode, 2); + if (GET_CODE (operands[1]) == CONST || GET_CODE (operands[1]) == SYMBOL_REF) { op10 = gen_rtx_ZERO_EXTRACT (HImode, operands[1], GEN_INT (16), GEN_INT (0)); op10 = gen_rtx_CONST (HImode, op10); op12 = gen_rtx_ZERO_EXTRACT (HImode, operands[1], GEN_INT (16), GEN_INT (16)); @@ -478,13 +484,12 @@ rl78_split_movsi (rtx *operands) operands[4] = op10; operands[3] = op02; operands[5] = op12; } } - /* Used by various two-operand expanders which cannot accept all operands in the "far" namespace. Force some such operands into registers so that each pattern has at most one far operand. */ int rl78_force_nonfar_2 (rtx *operands, rtx (*gen)(rtx,rtx)) { @@ -552,12 +557,16 @@ rl78_can_eliminate (const int from ATTRI current function. */ static bool need_to_save (unsigned int regno) { if (is_interrupt_func (cfun->decl)) { + /* We don't know what devirt will need */ + if (regno < 8) + return true; + /* We don't need to save registers that have been reserved for interrupt handlers. */ if (regno > 23) return false; /* If the handler is a non-leaf function then it may call @@ -693,12 +702,16 @@ static bool characterize_address (rtx x, rtx *base, rtx *index, rtx *addend) { *base = NULL_RTX; *index = NULL_RTX; *addend = NULL_RTX; + if (GET_CODE (x) == UNSPEC + && XINT (x, 1) == UNS_ES_ADDR) + x = XVECEXP (x, 0, 1); + if (GET_CODE (x) == REG) { *base = x; return true; } @@ -867,19 +880,23 @@ rl78_is_legitimate_constant (enum machin bool rl78_as_legitimate_address (enum machine_mode mode ATTRIBUTE_UNUSED, rtx x, bool strict ATTRIBUTE_UNUSED, addr_space_t as ATTRIBUTE_UNUSED) { rtx base, index, addend; + bool is_far_addr = false; if (GET_CODE (x) == UNSPEC && XINT (x, 1) == UNS_ES_ADDR) - x = XVECEXP (x, 0, 1); + { + x = XVECEXP (x, 0, 1); + is_far_addr = true; + } if (as == ADDR_SPACE_GENERIC - && GET_MODE (x) == SImode) + && (GET_MODE (x) == SImode || is_far_addr)) return false; if (! characterize_address (x, &base, &index, &addend)) return false; /* We can't extract the high/low portions of a PLUS address @@ -1059,22 +1076,25 @@ rl78_expand_prologue (void) { if (TARGET_G10) { emit_move_insn (gen_rtx_REG (HImode, 0), gen_rtx_REG (HImode, i*2)); F (emit_insn (gen_push (gen_rtx_REG (HImode, 0)))); } - else { - int need_bank = i/4; - if (need_bank != rb) - { - emit_insn (gen_sel_rb (GEN_INT (need_bank))); - rb = need_bank; - } - F (emit_insn (gen_push (gen_rtx_REG (HImode, i*2)))); - } + else + { + int need_bank = i/4; + + if (need_bank != rb) + { + emit_insn (gen_sel_rb (GEN_INT (need_bank))); + rb = need_bank; + } + F (emit_insn (gen_push (gen_rtx_REG (HImode, i*2)))); + } } + if (rb != 0) emit_insn (gen_sel_rb (GEN_INT (0))); if (frame_pointer_needed) { F (emit_move_insn (gen_rtx_REG (HImode, AX_REG), @@ -1672,12 +1692,15 @@ rl78_peep_movhi_p (rtx *operands) int i; rtx m, a; /* (set (op0) (op1)) (set (op2) (op3)) */ + if (! rl78_virt_insns_ok ()) + return false; + #if DEBUG_PEEP fprintf (stderr, "\033[33m"); debug_rtx (operands[0]); debug_rtx (operands[1]); debug_rtx (operands[2]); debug_rtx (operands[3]); @@ -1944,13 +1967,12 @@ get_content_index (rtx loc) return NOT_KNOWN; } /* Return a string describing content INDEX in mode MODE. WARNING: Can return a pointer to a static buffer. */ - static const char * get_content_name (unsigned char index, enum machine_mode mode) { static char buffer [128]; if (index == NOT_KNOWN) @@ -2152,24 +2174,24 @@ insn_ok_now (rtx insn) if (SET_P (pattern)) record_content (SET_DEST (pattern), SET_SRC (pattern)); /* We need to detect far addresses that haven't been converted to es/lo16 format. */ for (i=0; imachine->virt_insns_ok = 1; if (recog (pattern, insn, 0) > -1) { extract_insn (insn); if (constrain_operands (0)) { @@ -2203,28 +2225,28 @@ insn_ok_now (rtx insn) #define FAILED gcc_unreachable () #define MAYBE_OK(insn) if (insn_ok_now (insn)) return; #define MUST_BE_OK(insn) if (insn_ok_now (insn)) return; FAILED #endif /* Registers into which we move the contents of virtual registers. */ -#define X gen_rtx_REG (QImode, 0) -#define A gen_rtx_REG (QImode, 1) -#define C gen_rtx_REG (QImode, 2) -#define B gen_rtx_REG (QImode, 3) -#define E gen_rtx_REG (QImode, 4) -#define D gen_rtx_REG (QImode, 5) -#define L gen_rtx_REG (QImode, 6) -#define H gen_rtx_REG (QImode, 7) - -#define AX gen_rtx_REG (HImode, 0) -#define BC gen_rtx_REG (HImode, 2) -#define DE gen_rtx_REG (HImode, 4) -#define HL gen_rtx_REG (HImode, 6) +#define X gen_rtx_REG (QImode, X_REG) +#define A gen_rtx_REG (QImode, A_REG) +#define C gen_rtx_REG (QImode, C_REG) +#define B gen_rtx_REG (QImode, B_REG) +#define E gen_rtx_REG (QImode, E_REG) +#define D gen_rtx_REG (QImode, D_REG) +#define L gen_rtx_REG (QImode, L_REG) +#define H gen_rtx_REG (QImode, H_REG) + +#define AX gen_rtx_REG (HImode, AX_REG) +#define BC gen_rtx_REG (HImode, BC_REG) +#define DE gen_rtx_REG (HImode, DE_REG) +#define HL gen_rtx_REG (HImode, HL_REG) /* Returns TRUE if R is a virtual register. */ -static bool +static inline bool is_virtual_register (rtx r) { return (GET_CODE (r) == REG && REGNO (r) >= 8 && REGNO (r) < 32); } @@ -2361,12 +2383,13 @@ gen_and_emit_move (rtx to, rtx from, rtx if (before) record_content (to, from); else add_postponed_content_update (to, from); } + return before ? to : from; } /* If M is MEM(REG) or MEM(PLUS(REG,INT)) and REG is virtual then copy it into NEWBASE and return the updated MEM. Otherwise just return M. Any needed insns are emitted before BEFORE. */ @@ -2379,22 +2402,26 @@ transcode_memory_rtx (rtx m, rtx newbase if (! MEM_P (m)) return m; if (GET_MODE (XEXP (m, 0)) == SImode) { + rtx new_m; rtx seg = rl78_hi8 (XEXP (m, 0)); + #if DEBUG_ALLOC fprintf (stderr, "setting ES:\n"); debug_rtx(seg); #endif emit_insn_before (EM (gen_movqi (A, seg)), before); emit_insn_before (EM (gen_movqi_es (A)), before); record_content (A, NULL_RTX); - m = change_address (m, GET_MODE (m), rl78_lo16 (XEXP (m, 0))); + new_m = gen_rtx_MEM (GET_MODE (m), rl78_lo16 (XEXP (m, 0))); + MEM_COPY_ATTRIBUTES (new_m, m); + m = new_m; need_es = 1; } characterize_address (XEXP (m, 0), & base, & index, & addendr); gcc_assert (index == NULL_RTX); @@ -2462,13 +2489,12 @@ transcode_memory_rtx (rtx m, rtx newbase #endif return m; } /* Copy SRC to accumulator (A or AX), placing any generated insns before BEFORE. Returns accumulator RTX. */ - static rtx move_to_acc (int opno, rtx before) { rtx src = OP (opno); enum machine_mode mode = GET_MODE (src); @@ -2497,13 +2523,12 @@ force_into_acc (rtx src, rtx before) emit_insn_before (move, before); record_content (AX, NULL_RTX); } /* Copy accumulator (A or AX) to DEST, placing any generated insns after AFTER. Returns accumulator RTX. */ - static rtx move_from_acc (unsigned int opno, rtx after) { rtx dest = OP (opno); enum machine_mode mode = GET_MODE (dest); @@ -2512,13 +2537,12 @@ move_from_acc (unsigned int opno, rtx af return gen_and_emit_move (dest, mode == QImode ? A : AX, after, false); } /* Copy accumulator (A or AX) to REGNO, placing any generated insns before BEFORE. Returns reg RTX. */ - static rtx move_acc_to_reg (rtx acc, int regno, rtx before) { enum machine_mode mode = GET_MODE (acc); rtx reg; @@ -2526,13 +2550,12 @@ move_acc_to_reg (rtx acc, int regno, rtx return gen_and_emit_move (reg, acc, before, true); } /* Copy SRC to X, placing any generated insns before BEFORE. Returns X RTX. */ - static rtx move_to_x (int opno, rtx before) { rtx src = OP (opno); enum machine_mode mode = GET_MODE (src); rtx reg; @@ -2541,22 +2564,21 @@ move_to_x (int opno, rtx before) mode = recog_data.operand_mode[opno]; reg = (mode == QImode) ? X : AX; if (mode == QImode || ! is_virtual_register (OP (opno))) { OP (opno) = move_to_acc (opno, before); - OP (opno) = move_acc_to_reg (OP(opno), X_REG, before); + OP (opno) = move_acc_to_reg (OP (opno), X_REG, before); return reg; } return gen_and_emit_move (reg, src, before, true); } -/* Copy OP(opno) to H or HL, placing any generated insns before BEFORE. +/* Copy OP (opno) to H or HL, placing any generated insns before BEFORE. Returns H/HL RTX. */ - static rtx move_to_hl (int opno, rtx before) { rtx src = OP (opno); enum machine_mode mode = GET_MODE (src); rtx reg; @@ -2572,15 +2594,14 @@ move_to_hl (int opno, rtx before) return reg; } return gen_and_emit_move (reg, src, before, true); } -/* Copy OP(opno) to E or DE, placing any generated insns before BEFORE. +/* Copy OP (opno) to E or DE, placing any generated insns before BEFORE. Returns E/DE RTX. */ - static rtx move_to_de (int opno, rtx before) { rtx src = OP (opno); enum machine_mode mode = GET_MODE (src); rtx reg; @@ -2799,13 +2820,12 @@ rl78_alloc_physical_registers_op2 (rtx i we have inserted useless insns into the stream. */ MUST_BE_OK (insn); } } } - OP (0) = move_from_acc (0, insn); tmp_id = get_max_insn_count (); saved_op1 = OP (1); if (rtx_equal_p (OP (1), OP (2))) @@ -2835,13 +2855,12 @@ rl78_alloc_physical_registers_op2 (rtx i OP (2) = hl_used ? move_to_de (2, first) : move_to_hl (2, first); MUST_BE_OK (insn); } /* Devirtualize an insn of the form SET (PC) (MEM/REG). */ - static void rl78_alloc_physical_registers_ro1 (rtx insn) { OP (0) = transcode_memory_rtx (OP (0), BC, insn); MAYBE_OK (insn); @@ -2849,31 +2868,30 @@ rl78_alloc_physical_registers_ro1 (rtx i OP (0) = move_to_acc (0, insn); MUST_BE_OK (insn); } /* Devirtualize a compare insn. */ - static void rl78_alloc_physical_registers_cmp (rtx insn) { int tmp_id; rtx saved_op1; rtx prev = prev_nonnote_nondebug_insn (insn); rtx first; OP (1) = transcode_memory_rtx (OP (1), DE, insn); OP (2) = transcode_memory_rtx (OP (2), HL, insn); - /* HI compares have to have OP(1) in AX, but QI + /* HI compares have to have OP (1) in AX, but QI compares do not, so it is worth checking here. */ MAYBE_OK (insn); - /* For an HImode compare, OP(1) must always be in AX. - But if OP(1) is a REG (and not AX), then we can avoid - a reload of OP(1) if we reload OP(2) into AX and invert + /* For an HImode compare, OP (1) must always be in AX. + But if OP (1) is a REG (and not AX), then we can avoid + a reload of OP (1) if we reload OP (2) into AX and invert the comparison. */ if (REG_P (OP (1)) && REGNO (OP (1)) != AX_REG && GET_MODE (OP (1)) == HImode && MEM_P (OP (2))) { @@ -2943,13 +2961,12 @@ rl78_alloc_physical_registers_cmp (rtx i OP (2) = move_to_hl (2, first); MUST_BE_OK (insn); } /* Like op2, but AX = A op X. */ - static void rl78_alloc_physical_registers_umul (rtx insn) { rtx prev = prev_nonnote_nondebug_insn (insn); rtx first; int tmp_id; @@ -3051,12 +3068,13 @@ rl78_alloc_address_registers_macax (rtx OP (op) = transcode_memory_rtx (OP (op), BC, insn); break; } which ++; } } + MUST_BE_OK (insn); } /* Scan all insns and devirtualize them. */ static void rl78_alloc_physical_registers (void) @@ -3173,12 +3191,13 @@ rl78_alloc_physical_registers (void) if (JUMP_P (insn) || CALL_P (insn) || GET_CODE (pattern) == CALL) clear_content_memory (); else process_postponed_content_update (); } + #if DEBUG_ALLOC fprintf (stderr, "\033[0m"); #endif } /* Add REG_DEAD notes using DEAD[reg] for rtx S which is part of INSN. @@ -3541,12 +3560,22 @@ rl78_propogate_register_origins (void) origins[i] = i; age[i] = 0; } } } } + else if (GET_CODE (pat) == CLOBBER) + { + if (REG_P (XEXP (pat, 0))) + { + unsigned int reg = REGNO (XEXP (pat, 0)); + + origins[reg] = reg; + age[reg] = 0; + } + } } } } /* Remove any SETs where the destination is unneeded. */ static void @@ -3690,9 +3719,10 @@ static bool rl78_rtx_costs (rtx x, static enum machine_mode rl78_unwind_word_mode (void) { return HImode; } + struct gcc_target targetm = TARGET_INITIALIZER; #include "gt-rl78.h"