From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 12144 invoked by alias); 13 Aug 2011 08:34:22 -0000 Received: (qmail 11747 invoked by uid 22791); 13 Aug 2011 08:34:20 -0000 X-SWARE-Spam-Status: No, hits=-2.7 required=5.0 tests=BAYES_00,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FROM,RCVD_IN_DNSWL_LOW X-Spam-Check-By: sourceware.org Received: from mail-iy0-f175.google.com (HELO mail-iy0-f175.google.com) (209.85.210.175) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Sat, 13 Aug 2011 08:34:02 +0000 Received: by iyn15 with SMTP id 15so3548395iyn.34 for ; Sat, 13 Aug 2011 01:34:01 -0700 (PDT) Received: by 10.231.55.2 with SMTP id s2mr3462038ibg.37.1313224440467; Sat, 13 Aug 2011 01:34:00 -0700 (PDT) Received: from pauldell (124-149-34-246.dyn.iinet.net.au [124.149.34.246]) by mx.google.com with ESMTPS id fu7sm2711738ibb.53.2011.08.13.01.33.55 (version=SSLv3 cipher=OTHER); Sat, 13 Aug 2011 01:33:57 -0700 (PDT) Message-ID: <0AF9CC37087647E596AAC5E01031F492@pauldell> From: "Paul Edwards" To: "Ulrich Weigand" Cc: References: <200911041646.nA4Gkx1m032222@d12av02.megacenter.de.ibm.com> In-Reply-To: <200911041646.nA4Gkx1m032222@d12av02.megacenter.de.ibm.com> Subject: Re: i370 port Date: Sat, 13 Aug 2011 08:34: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/msg00264.txt.bz2 Hi Ulrich and group. The i370 port of GCC 3.4.6 is now complete and the result can be downloaded from http://gccmvs.sourceforge.net It can be built using configure/make, and there weren't that many changes that needed to be made to the code to get it to work. However, I have encountered a bug. I get bad code generated for this, because a non-s_operand is getting through: ; Move a block that is less than 256 bytes in length. (define_insn "" [(set (match_operand:BLK 0 "s_operand" "=m") (match_operand:BLK 1 "s_operand" "m")) (use (match_operand 2 "immediate_operand" "I"))] "((unsigned) INTVAL (operands[2]) < 256)" "* { check_label_emit (); mvs_check_page (0, 6, 0); return \"MVC %O0(%c2,%R0),%1\"; }" [(set_attr "length" "6")] ) Here is the bad code: L 9,=F'32880' MVC 9(10,13),0(2) That "9" in the MVC is supposed to be a constant from 0-4095. It can't fit the large value in so has used a register, but then tried to use that register in the instruction. It should have added R13 to R9 and used that as the base register (instead of the 13 you see) I was surprised that an instruction that is marked as s_operand was getting a seemingly non-s_operand given to it, so I added an "S" constraint: ; Move a block that is less than 256 bytes in length. (define_insn "" [(set (match_operand:BLK 0 "s_operand" "=S") (match_operand:BLK 1 "s_operand" "m")) That then gave an actual compiler error instead of generating bad code, which is a step forward: pdos.c: In function `pdosLoadExe': pdos.c:2703: error: unable to generate reloads for: (insn 38 37 41 0 (parallel [ (set (mem/s:BLK (plus:SI (reg/f:SI 13 13) (const_int 32880 [0x8070])) [27 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)) (expr_list:REG_DEAD (reg/v/f:SI 2 2 [orig:27 prog ] [27]) (nil))) pdos.c:2703: internal compiler error: in find_reloads, at reload.c:3690 Please submit a full bug report, with preprocessed source if appropriate. See for instructions. But I am surprised that s_operand and "S" are producing different results. Regardless, I sort of tracked the problem down to this bit of the machine definition: ; ; movstrsi instruction pattern(s). ; block must be less than 16M (24 bits) in length (define_expand "movstrsi" [(set (match_operand:BLK 0 "general_operand" "") (match_operand:BLK 1 "general_operand" "")) (use (match_operand:SI 2 "general_operand" "")) (match_operand 3 "" "")] "" " { rtx op0, op1; op0 = XEXP (operands[0], 0); if (GET_CODE (op0) == REG || (GET_CODE (op0) == PLUS && GET_CODE (XEXP (op0, 0)) == REG && GET_CODE (XEXP (op0, 1)) == CONST_INT && (unsigned) INTVAL (XEXP (op0, 1)) < 4096)) op0 = operands[0]; else op0 = replace_equiv_address (operands[0], copy_to_mode_reg (SImode, op0)); op1 = XEXP (operands[1], 0); if (GET_CODE (op1) == REG || (GET_CODE (op1) == PLUS && GET_CODE (XEXP (op1, 0)) == REG && GET_CODE (XEXP (op1, 1)) == CONST_INT && (unsigned) INTVAL (XEXP (op1, 1)) < 4096)) op1 = operands[1]; else op1 = replace_equiv_address (operands[1], copy_to_mode_reg (SImode, op1)); if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 256) emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, gen_rtx_SET (VOIDmode, op0, op1), gen_rtx_USE (VOIDmode, operands[2])))); So now I am basically wanting to stop this code from doing that emit_insn. I tested putting in a kludge to see if operands[2] was equal to 10 (the length in my test case), and bypassing the emit_insn. That forced it to use a more inefficient move instruction, but that's fine. So I need some way of getting op0 detected as "unsuitable for use in an MVC". I have put in debug and found that GET_CODE(op0) is equal to MEM. I have also found that GET_CODE(XEXP(op0, 0)) is a REG_P, whatever that means (I was just copying things I saw in the s_operand test). Here is the s_operand test for reference: /* Return 1 if OP is a valid S operand for an RS, SI or SS type instruction. OP is the current operation. MODE is the current operation mode. */ int s_operand (register rtx op, enum machine_mode mode) { extern int volatile_ok; register enum rtx_code code = GET_CODE (op); if (CONSTANT_ADDRESS_P (op)) return 1; if (mode == VOIDmode || GET_MODE (op) != mode) return 0; if (code == MEM) { register rtx x = XEXP (op, 0); if (!volatile_ok && op->volatil) return 0; if (REG_P (x) && REG_OK_FOR_BASE_P (x)) return 1; if (GET_CODE (x) == PLUS && REG_P (XEXP (x, 0)) && REG_OK_FOR_BASE_P (XEXP (x, 0)) && GET_CODE (XEXP (x, 1)) == CONST_INT && (unsigned) INTVAL (XEXP (x, 1)) < 4096) return 1; } return 0; } Now because I know that it is MEM and REG_P, I can actually put in a check to detect that and abort it. But that then causes more inefficient code to be generated in other circumstances: < L 2,12(4) < MVC 104(24,13),0(2) --- > LA 4,104(,13) > LA 5,24(0,0) > L 2,12(6) > LR 3,5 > MVCL 4,2 Any idea what can be done? Thanks. Paul.