From patchwork Fri Feb 17 17:46:36 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Georg-Johann Lay X-Patchwork-Id: 141953 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 5CF64B7433 for ; Sat, 18 Feb 2012 04:47:14 +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=1330105635; h=Comment: DomainKey-Signature:Received:Received:Received:Received: Message-ID:Date:From:User-Agent:MIME-Version:To:CC:Subject: Content-Type:Mailing-List:Precedence:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:Sender:Delivered-To; bh=eSjrd9g DUMymzYYfklW9oDXbuFY=; b=bulX0c2z5F/I+8qNAls1BpV75aXzciBZQgA/7xS mRKxnSZAZN+NXEx2zK+gYpW9fS73DqredVo4PbcqwOWanthe7v4RYQCg8qceghG2 VdjTX/9+0I2VqAsfcFLtIV1pnLeaV4+sfz9153ODPibDCZH2697Tvrg3dy5IpPzT t9/E= 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:X-RZG-AUTH:X-RZG-CLASS-ID:Received:Message-ID:Date:From:User-Agent:MIME-Version:To:CC:Subject:Content-Type:X-IsSubscribed:Mailing-List:Precedence:List-Id:List-Unsubscribe:List-Archive:List-Post:List-Help:Sender:Delivered-To; b=pFywouKI0/BL62EmkXR3y7OOuPtmOW2MQO/svODT4ItZp/BjI42Rbn30PuEziv XjMaNCWij1niz7pKA8pf2Srqnr3av3/SPHZCb/vaXEut+Cwdz96cFK1ENq7dHYhr L1nXUUR7LCJGovcHOAtJSqW8CFtF/3BaFIz6ZJKT78PnQ=; Received: (qmail 23720 invoked by alias); 17 Feb 2012 17:47:10 -0000 Received: (qmail 23711 invoked by uid 22791); 17 Feb 2012 17:47:09 -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; Fri, 17 Feb 2012 17:46:52 +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 (jimi mo4) (RZmta 27.6 AUTH) with ESMTPA id h00ee3o1HGaC5w ; Fri, 17 Feb 2012 18:46:36 +0100 (MET) Message-ID: <4F3E927C.5060802@gjlay.de> Date: Fri, 17 Feb 2012 18:46:36 +0100 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] Fix/hack around spill fail ICE PR52148 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 Spill failure PR52148 occurs for movmem insn that allocates 2 of AVR's 3 pointer registers. Register allocator is at it's limits and the patch tries to cure the situation by replacing (match_operand:HI 0 "register_operand" "x") with explicit (reg:HI REG_X) and similar for Z Register classes "x" and "z" contain only one HI register. This PR and PR50925 show that register allocator has some problems. Even though this patch is not a fix of the root cause, it allows the PR's test case to compile. Anyways, the patch simplifies the backend and replaces an insn with 11(!) operands with an insn with only 2 operands so that the patch is improvement of the backend. The hard registers are already known at expand time so there is no need for match_operands. Passes without regression. Ok for trunk? Johann PR target/52148 * config/avr/avr.md (movmem_): Replace match_operand that match only one single hard register with respective hard reg rtx. (movmemx_): Ditto. * config/avr/avr.c (avr_emit_movmemhi): Adapt expanding to new insn anatomy of movmem[x]_. (avr_out_movmem): Same for printing assembler and operand usage. Index: config/avr/avr.md =================================================================== --- config/avr/avr.md (revision 184269) +++ config/avr/avr.md (working copy) @@ -461,6 +461,9 @@ (define_insn "xload_8" (set_attr "isa" "lpmx,lpm") (set_attr "cc" "none")]) +;; R21:Z : 24-bit source address +;; R22 : 1-4 byte output + ;; "xload_qi_libgcc" ;; "xload_hi_libgcc" ;; "xload_psi_libgcc" @@ -841,24 +844,23 @@ (define_expand "movmemhi" (define_mode_attr MOVMEM_r_d [(QI "r") (HI "wd")]) -;; $0, $4 : & dest (REG_X) -;; $1, $5 : & src (REG_Z) -;; $2 : Address Space -;; $3, $7 : Loop register -;; $6 : Scratch register +;; $0 : Address Space +;; $1, $2 : Loop register +;; R30 : source address +;; R26 : destination address ;; "movmem_qi" ;; "movmem_hi" (define_insn "movmem_" - [(set (mem:BLK (match_operand:HI 0 "register_operand" "x")) - (mem:BLK (match_operand:HI 1 "register_operand" "z"))) - (unspec [(match_operand:QI 2 "const_int_operand" "n")] + [(set (mem:BLK (reg:HI REG_X)) + (mem:BLK (reg:HI REG_Z))) + (unspec [(match_operand:QI 0 "const_int_operand" "n")] UNSPEC_MOVMEM) - (use (match_operand:QIHI 3 "register_operand" "")) - (clobber (match_operand:HI 4 "register_operand" "=0")) - (clobber (match_operand:HI 5 "register_operand" "=1")) - (clobber (match_operand:QI 6 "register_operand" "=&r")) - (clobber (match_operand:QIHI 7 "register_operand" "=3"))] + (use (match_operand:QIHI 1 "register_operand" "")) + (clobber (reg:HI REG_X)) + (clobber (reg:HI REG_Z)) + (clobber (reg:QI LPM_REGNO)) + (clobber (match_operand:QIHI 2 "register_operand" "=1"))] "" { return avr_out_movmem (insn, operands, NULL); @@ -866,26 +868,28 @@ (define_insn "movmem_" [(set_attr "adjust_len" "movmem") (set_attr "cc" "clobber")]) -;; Ditto and -;; $3, $7 : Loop register = R24 -;; $8, $9 : hh8 (& src) = R23 -;; $10 : RAMPZ_ADDR + +;; $0 : Address Space +;; $1 : RAMPZ RAM address +;; R24 : #bytes and loop register +;; R23:Z : 24-bit source address +;; R26 : 16-bit destination address ;; "movmemx_qi" ;; "movmemx_hi" (define_insn "movmemx_" - [(set (mem:BLK (match_operand:HI 0 "register_operand" "x")) - (mem:BLK (lo_sum:PSI (match_operand:QI 8 "register_operand" "r") - (match_operand:HI 1 "register_operand" "z")))) - (unspec [(match_operand:QI 2 "const_int_operand" "n")] + [(set (mem:BLK (reg:HI REG_X)) + (mem:BLK (lo_sum:PSI (reg:QI 23) + (reg:HI REG_Z)))) + (unspec [(match_operand:QI 0 "const_int_operand" "n")] UNSPEC_MOVMEM) - (use (match_operand:QIHI 3 "register_operand" "w")) - (clobber (match_operand:HI 4 "register_operand" "=0")) - (clobber (match_operand:HI 5 "register_operand" "=1")) - (clobber (match_operand:QI 6 "register_operand" "=&r")) - (clobber (match_operand:HI 7 "register_operand" "=3")) - (clobber (match_operand:QI 9 "register_operand" "=8")) - (clobber (mem:QI (match_operand:QI 10 "io_address_operand" "n")))] + (use (reg:QIHI 24)) + (clobber (reg:HI REG_X)) + (clobber (reg:HI REG_Z)) + (clobber (reg:QI LPM_REGNO)) + (clobber (reg:HI 24)) + (clobber (reg:QI 23)) + (clobber (mem:QI (match_operand:QI 1 "io_address_operand" "n")))] "" "%~call __movmemx_" [(set_attr "type" "xcall") Index: config/avr/avr.c =================================================================== --- config/avr/avr.c (revision 184269) +++ config/avr/avr.c (working copy) @@ -9898,7 +9898,7 @@ avr_emit_movmemhi (rtx *xop) HOST_WIDE_INT count; enum machine_mode loop_mode; addr_space_t as = MEM_ADDR_SPACE (xop[1]); - rtx loop_reg, addr0, addr1, a_src, a_dest, insn, xas, reg_x; + rtx loop_reg, addr1, a_src, a_dest, insn, xas; rtx a_hi8 = NULL_RTX; if (avr_mem_flash_p (xop[0])) @@ -9927,7 +9927,7 @@ avr_emit_movmemhi (rtx *xop) } else { - int segment = avr_addrspace[as].segment % avr_current_arch->n_segments; + int segment = avr_addrspace[as].segment; if (segment && avr_current_arch->n_segments > 1) @@ -9954,11 +9954,7 @@ avr_emit_movmemhi (rtx *xop) X = destination address */ emit_move_insn (lpm_addr_reg_rtx, addr1); - addr1 = lpm_addr_reg_rtx; - - reg_x = gen_rtx_REG (HImode, REG_X); - emit_move_insn (reg_x, a_dest); - addr0 = reg_x; + emit_move_insn (gen_rtx_REG (HImode, REG_X), a_dest); /* FIXME: Register allocator does a bad job and might spill address register(s) inside the loop leading to additional move instruction @@ -9973,23 +9969,19 @@ avr_emit_movmemhi (rtx *xop) /* Load instruction ([E]LPM or LD) is known at compile time: Do the copy-loop inline. */ - rtx (*fun) (rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx) + rtx (*fun) (rtx, rtx, rtx) = QImode == loop_mode ? gen_movmem_qi : gen_movmem_hi; - insn = fun (addr0, addr1, xas, loop_reg, - addr0, addr1, tmp_reg_rtx, loop_reg); + insn = fun (xas, loop_reg, loop_reg); } else { - rtx loop_reg16 = gen_rtx_REG (HImode, 24); - rtx r23 = gen_rtx_REG (QImode, 23); - rtx (*fun) (rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx) + rtx (*fun) (rtx, rtx) = QImode == loop_mode ? gen_movmemx_qi : gen_movmemx_hi; - emit_move_insn (r23, a_hi8); + emit_move_insn (gen_rtx_REG (QImode, 23), a_hi8); - insn = fun (addr0, addr1, xas, loop_reg, addr0, addr1, - lpm_reg_rtx, loop_reg16, r23, r23, GEN_INT (avr_addr.rampz)); + insn = fun (xas, GEN_INT (avr_addr.rampz)); } set_mem_addr_space (SET_SRC (XVECEXP (insn, 0, 0)), as); @@ -10000,32 +9992,27 @@ avr_emit_movmemhi (rtx *xop) /* Print assembler for movmem_qi, movmem_hi insns... - $0, $4 : & dest - $1, $5 : & src - $2 : Address Space - $3, $7 : Loop register - $6 : Scratch register - - ...and movmem_qi_elpm, movmem_hi_elpm insns. - - $8, $9 : hh8 (& src) - $10 : RAMPZ_ADDR + $0 : Address Space + $1, $2 : Loop register + Z : Source address + X : Destination address */ const char* -avr_out_movmem (rtx insn ATTRIBUTE_UNUSED, rtx *xop, int *plen) +avr_out_movmem (rtx insn ATTRIBUTE_UNUSED, rtx *op, int *plen) { - addr_space_t as = (addr_space_t) INTVAL (xop[2]); - enum machine_mode loop_mode = GET_MODE (xop[3]); - - bool sbiw_p = test_hard_reg_class (ADDW_REGS, xop[3]); - - gcc_assert (REG_X == REGNO (xop[0]) - && REG_Z == REGNO (xop[1])); + addr_space_t as = (addr_space_t) INTVAL (op[0]); + enum machine_mode loop_mode = GET_MODE (op[1]); + bool sbiw_p = test_hard_reg_class (ADDW_REGS, op[1]); + rtx xop[3]; if (plen) *plen = 0; + xop[0] = op[0]; + xop[1] = op[1]; + xop[2] = tmp_reg_rtx; + /* Loop label */ avr_asm_len ("0:", xop, plen, 0); @@ -10039,16 +10026,16 @@ avr_out_movmem (rtx insn ATTRIBUTE_UNUSE case ADDR_SPACE_GENERIC: - avr_asm_len ("ld %6,%a1+", xop, plen, 1); + avr_asm_len ("ld %2,Z+", xop, plen, 1); break; case ADDR_SPACE_FLASH: if (AVR_HAVE_LPMX) - avr_asm_len ("lpm %6,%a1+", xop, plen, 1); + avr_asm_len ("lpm %2,%Z+", xop, plen, 1); else avr_asm_len ("lpm" CR_TAB - "adiw %1,1", xop, plen, 2); + "adiw r30,1", xop, plen, 2); break; case ADDR_SPACE_FLASH1: @@ -10058,31 +10045,31 @@ avr_out_movmem (rtx insn ATTRIBUTE_UNUSE case ADDR_SPACE_FLASH5: if (AVR_HAVE_ELPMX) - avr_asm_len ("elpm %6,%a1+", xop, plen, 1); + avr_asm_len ("elpm %2,Z+", xop, plen, 1); else avr_asm_len ("elpm" CR_TAB - "adiw %1,1", xop, plen, 2); + "adiw r30,1", xop, plen, 2); break; } /* Store with post-increment */ - avr_asm_len ("st %a0+,%6", xop, plen, 1); + avr_asm_len ("st X+,%2", xop, plen, 1); /* Decrement loop-counter and set Z-flag */ if (QImode == loop_mode) { - avr_asm_len ("dec %3", xop, plen, 1); + avr_asm_len ("dec %1", xop, plen, 1); } else if (sbiw_p) { - avr_asm_len ("sbiw %3,1", xop, plen, 1); + avr_asm_len ("sbiw %1,1", xop, plen, 1); } else { - avr_asm_len ("subi %A3,1" CR_TAB - "sbci %B3,0", xop, plen, 2); + avr_asm_len ("subi %A1,1" CR_TAB + "sbci %B1,0", xop, plen, 2); } /* Loop until zero */