From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 28007 invoked by alias); 18 Aug 2011 12:15:56 -0000 Received: (qmail 27992 invoked by uid 22791); 18 Aug 2011 12:15:52 -0000 X-SWARE-Spam-Status: No, hits=-1.8 required=5.0 tests=AWL,BAYES_00,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FROM,RCVD_IN_DNSWL_LOW X-Spam-Check-By: sourceware.org Received: from mail-gx0-f175.google.com (HELO mail-gx0-f175.google.com) (209.85.161.175) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Thu, 18 Aug 2011 12:15:32 +0000 Received: by gxk3 with SMTP id 3so1454043gxk.20 for ; Thu, 18 Aug 2011 05:15:31 -0700 (PDT) Received: by 10.236.200.195 with SMTP id z43mr3478779yhn.127.1313669731633; Thu, 18 Aug 2011 05:15:31 -0700 (PDT) Received: from pauldell (124-149-34-246.dyn.iinet.net.au [124.149.34.246]) by mx.google.com with ESMTPS id z29sm783255yhn.30.2011.08.18.05.15.27 (version=SSLv3 cipher=OTHER); Thu, 18 Aug 2011 05:15:29 -0700 (PDT) Message-ID: <9CD7A89FEE9D40BE924CE83E9C6273A6@pauldell> From: "Paul Edwards" To: "Ulrich Weigand" Cc: References: <201108161325.p7GDPt4c004257@d06av02.portsmouth.uk.ibm.com> In-Reply-To: <201108161325.p7GDPt4c004257@d06av02.portsmouth.uk.ibm.com> Subject: Re: i370 port Date: Thu, 18 Aug 2011 12:15:00 -0000 MIME-Version: 1.0 Content-Type: text/plain; format=flowed; charset="iso-8859-1"; reply-type=original Content-Transfer-Encoding: 7bit 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-08/txt/msg00336.txt.bz2 Hi Ulrich. I put in the following debug: op0 = find_replacement (&XEXP (in, 0)); op1 = find_replacement (&XEXP (in, 1)); /* Since constraint checking is strict, commutativity won't be checked, so we need to do that here to avoid spurious failure if the add instruction is two-address and the second operand of the add is the same as the reload reg, which is frequently the case. If the insn would be A = B + A, rearrange it so it will be A = A + B as constrain_operands expects. */ fprintf(stderr, "REGNO(out) is %d\n", REGNO(out)); fprintf(stderr, " REG in 1 is %d\n", REGNO(XEXP(in,1))); if (GET_CODE (XEXP (in, 1)) == REG && REGNO (out) == REGNO (XEXP (in, 1))) tem = op0, op0 = op1, op1 = tem; And it produced this output (for exactly the same code I showed you previously): C:\devel\pdos\s370>\devel\gcc\gcc\gccmvs -da -DUSE_MEMMGR -Os -DS390 -S -I . -I ../pdpclib pdos.c REGNO(out) is 3 REG in 1 is 32880 REGNO(out) is 2 REG in 1 is 32880 REGNO(out) is 2 REG in 1 is 32880 REGNO(out) is 2 REG in 1 is 112 REGNO(out) is 3 REG in 1 is 32880 REGNO(out) is 4 REG in 1 is 112 REGNO(out) is 2 REG in 1 is 112 which looks to me like it is not seeing a register, only a constant, so cannot perform a swap. Let me know if that is not the debugging required. Thanks. Paul. -----Original Message----- From: Ulrich Weigand Sent: Tuesday, August 16, 2011 11:25 PM To: Paul Edwards Cc: gcc@gcc.gnu.org Subject: Re: i370 port Paul Edwards wrote: > >> Unfortunately it's not quite right, seemingly not loading R9 properly: > >> > >> LR 9,13 > >> AR 9,13 > >> MVC 0(10,9),0(2) > > > That's weird. What does the reload dump (.greg) say? > > I have trimmed the code down to a reasonably small size so that I > could provide the .greg file (below) from the "-da" option. I don't > know how to read it so I don't know if I've provided everything > required. > > Here is the current problematic generated code: > > * Function pdosLoadExe code > L 2,4(11) > MVC 88(4,13),=A(LC0) > ST 2,92(13) > LA 1,88(,13) > L 15,=V(PRINTF) > BALR 14,15 > LR 3,13 <========= probably wrong > AR 3,13 <========= else this is wrong > MVC 0(10,3),0(2) Reload decides on the following actions: > Reloads for insn # 38 > Reload 0: reload_in (SI) = (const_int 32880 [0x8070]) > ADDR_REGS, RELOAD_FOR_INPUT_ADDRESS (opnum = 0) > reload_in_reg: (const_int 32880 [0x8070]) > reload_reg_rtx: (reg:SI 3 3) > Reload 1: reload_in (SI) = (plus:SI (reg/f:SI 13 13) > (const_int 32880 > [0x8070])) > ADDR_REGS, RELOAD_FOR_INPUT (opnum = 0) > reload_in_reg: (plus:SI (reg/f:SI 13 13) > (const_int 32880 > [0x8070])) > reload_reg_rtx: (reg:SI 3 3) That is, first: load the constant 32880 into register 3, and second: using that reloaded constant, compute the sum of register 13 plus 32880 and load the result also into register 3. Then, use that register for addressing. This leads to the following generated code: > (insn 271 37 273 0 (set (reg:SI 3 3) > (const_int 32880 [0x8070])) 15 {movsi} (nil) > (nil)) Load constant into register 3. > (insn 273 271 274 0 (set (reg:SI 3 3) > (reg/f:SI 13 13)) 15 {movsi} (nil) > (nil)) > > (insn 274 273 38 0 (set (reg:SI 3 3) > (plus:SI (reg:SI 3 3) > (reg:SI 3 3))) 41 {addsi3} (nil) > (expr_list:REG_EQUIV (plus:SI (reg/f:SI 13 13) > (reg:SI 3 3)) > (nil))) Compute the sum. Note that this code is wrong. > (insn 38 274 41 0 (parallel [ > (set (mem/s:BLK (reg:SI 3 3) [6 srchprog+0 S10 A64]) > (mem:BLK (reg/v/f:SI 2 2 [orig:27 prog ] [27]) [0 S10 > A8])) > (use (const_int 10 [0xa])) > ]) 25 {*i370.md:1623} (insn_list 37 (nil)) > (nil)) Use register 3 for adressing. The wrong code comes in when generating the sum (insns 273/274). I would have expected this to be a simple addsi3 instruction, along the lines of (set (reg:SI 3 3) (plus:SI (reg:SI 3 3) (reg:SI 13 13))) Note that the incoming pattern: (set (reg:SI 3 3) (plus:SI (reg:SI 13 13) (reg:SI 3 3))) cannot be immediately resolved, since addsi3 requires the first operand of the plus to match the result. However, this could have been fixed by just swapping the operands. Instead, the code attempts to create the match by reloading the first operand (reg 13) into the output (reg 3) -- this is bogus, since it thereby clobbers the *second* input operand, which happens to match the output. The code that generates these insns is in reload1.c:gen_reload /* We need to compute the sum of a register or a MEM and another register, constant, or MEM, and put it into the reload register. The best possible way of doing this is if the machine has a three-operand ADD insn that accepts the required operands. The simplest approach is to try to generate such an insn and see if it is recognized and matches its constraints. If so, it can be used. It might be better not to actually emit the insn unless it is valid, but we need to pass the insn as an operand to `recog' and `extract_insn' and it is simpler to emit and then delete the insn if not valid than to dummy things up. */ rtx op0, op1, tem, insn; int code; op0 = find_replacement (&XEXP (in, 0)); op1 = find_replacement (&XEXP (in, 1)); /* Since constraint checking is strict, commutativity won't be checked, so we need to do that here to avoid spurious failure if the add instruction is two-address and the second operand of the add is the same as the reload reg, which is frequently the case. If the insn would be A = B + A, rearrange it so it will be A = A + B as constrain_operands expects. */ if (GET_CODE (XEXP (in, 1)) == REG && REGNO (out) == REGNO (XEXP (in, 1))) tem = op0, op0 = op1, op1 = tem; if (op0 != XEXP (in, 0) || op1 != XEXP (in, 1)) in = gen_rtx_PLUS (GET_MODE (in), op0, op1); insn = emit_insn (gen_rtx_SET (VOIDmode, out, in)); code = recog_memoized (insn); Note how this actually performs the check whether to swap operands for commutativity. Can you debug this and find out why this doesn't work in your case? Bye, Ulrich -- Dr. Ulrich Weigand GNU Toolchain for Linux on System z and Cell BE Ulrich.Weigand@de.ibm.com