From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 50160 invoked by alias); 1 Nov 2019 13:22:00 -0000 Mailing-List: contact gcc-help-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-help-owner@gcc.gnu.org Received: (qmail 50017 invoked by uid 89); 1 Nov 2019 13:22:00 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-1.9 required=5.0 tests=AWL,BAYES_00,KAM_NUMSUBJECT,RCVD_IN_DNSWL_LOW autolearn=ham version=3.3.1 spammy=__mulsi3, H*r:sk:mailout, H*RU:sk:mailout, HContent-Transfer-Encoding:8bit X-HELO: mailout-lvl1-04.surftown.com Received: from mailout-lvl1-04.surftown.com (HELO mailout-lvl1-04.surftown.com) (212.97.134.87) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Fri, 01 Nov 2019 13:21:58 +0000 Received: from surftown.com (mail.surftown.com [212.97.133.57]) by mailout-lvl1-04.surftown.com (Postfix) with ESMTP id ADE6E1000F6 for ; Fri, 1 Nov 2019 14:21:56 +0100 (CET) Received: from [10.1.1.138] (unknown [185.113.97.212]) (Authenticated sender: mti-1@tillenius.com) by mail.surftown.com (Postfix) with ESMTPA id 9C769E0D6C for ; Fri, 1 Nov 2019 14:21:55 +0100 (CET) Subject: Re: Non-optimal code generated for H8 To: gcc-help@gcc.gnu.org References: <5b46f0b2-6ded-784c-00ff-fe592819b397@tillenius.com> <13ffbba6-2b7b-f3b3-9b7a-20923b8271cc@redhat.com> <430a442f-7513-9288-e607-9b3fe91819ff@tillenius.com> From: Mikael Tillenius Message-ID: <5e453707-4b58-f160-96c8-71ac5a02eba7@tillenius.com> Date: Fri, 01 Nov 2019 13:22:00 -0000 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Thunderbird/68.2.0 MIME-Version: 1.0 In-Reply-To: <430a442f-7513-9288-e607-9b3fe91819ff@tillenius.com> Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 8bit X-IsSubscribed: yes X-SW-Source: 2019-11/txt/msg00002.txt.bz2 Ok, I have looked more into the problem. For now I have a decent work around in my code using "volatile" and an almost working patch for GCC. I am not sure if I have time to work more on the GCC patch right now. But just to sum up, here is what I found so far. Given the code struct s {     char a, b;     char c[11]; } x[2]; void test(int n) {     struct s *sp = &x[n];     sp->a = 1;     sp->b = 1; } For plain H8/300 (no specific options) and H8S (-ms) GCC does not find a suitable multiplication instruction and instead generates a call to __mulhi3/__mulsi3. For some reason CSE is not able to do its work so the pointer value is recalculated for each access. H8300 has no multiplication instruction. H8S has only a 16x16 => 32 bit multiplication (mulxu.w).     stm.l    er4-er5,@-er7     mov.w    r0,r4     extu.l    er4     sub.l    er1,er1     add.b    #13,r1l     mov.l    er4,er0     jsr    @___mulsi3     mov.b    #1,r5l     mov.b    r5l,@(_x,er0)     sub.l    er1,er1     add.b    #13,r1l     mov.l    er4,er0     jsr    @___mulsi3     mov.b    r5l,@(_x+1,er0)     ldm.l    @er7+,er4-er5     rts For H8/300H in 16-bit mode (-mh -mn) and H8SX (-mx) GCC finds the appropriate instructions and CSE does its work. Only one mulxu.w/mulu.l is generated and the pointer value is reused. If I add a suitable multiplication insn that generates the call to __mulsi3 for H8S GCC will use it and CSE will work. "b" and "e" are new constraints that require r0 and r1. The problem is that this insn collides with the already exsiting insn for H8SX. (define_insn "mulsi3"   [(set (match_operand:SI 0 "register_operand" "=b")         (mult:SI (match_operand:SI 1 "register_operand" "%0")          (match_operand:SI 2 "register_operand" "e")))]   "TARGET_H8300S"   "jsr\\t@___mulsi3"   [(set_attr "length" "2")    (set_attr "cc" "set_zn")]) ---     extu.l    er0     sub.l    er1,er1     add.b    #13,r1l     jsr    @___mulsi3     add.l    #_x,er0     mov.b    #1,r2l     mov.b    r2l,@er0     mov.b    r2l,@(1,er0)     rts If I also add the following I get almost perfect code. "small_operand" is a new predicate that requires a 16-bit value. (define_insn "*mulhisi3"   [(set (match_operand:SI 0 "register_operand" "=r")     (mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand" "%0"))          (match_operand:SI 2 "small_operand" "")))]   "TARGET_H8300H || TARGET_H8300S"   "mov.w\\t%T2,%e0\;mulxs.w\\t%e0,%S0"   [(set_attr "length" "2")    (set_attr "cc" "none_0hit")]) ---     mov.w    #13,e0     mulxs.w    e0,er0     add.l    #_x,er0     mov.b    #1,r2l     mov.b    r2l,@er0     mov.b    r2l,@(1,er0)     rts Thanks for the help. /Mikael